Claude commited on
Switch from Ollama to OpenRouter for LLM inference
Browse filesReplace local Ollama calls with OpenRouter API (OpenAI-compatible).
Configurable via OPENROUTER_API_KEY and LLM_MODEL env vars.
Default model: mistralai/mistral-7b-instruct.
https://claude.ai/code/session_015z3yZxNNfXF63JuQDuPbEG
- .env.example +2 -0
- .gitignore +4 -0
- app/llm.py +14 -10
- docker-compose.yml +2 -3
.env.example
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
OPENROUTER_API_KEY=sk-or-v1-your-key-here
|
| 2 |
+
LLM_MODEL=mistralai/mistral-7b-instruct
|
.gitignore
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
.env
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.pyc
|
| 4 |
+
chroma_data/
|
app/llm.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
| 1 |
-
"""LLM interaction via
|
| 2 |
|
| 3 |
import os
|
| 4 |
import httpx
|
| 5 |
|
| 6 |
-
|
| 7 |
-
|
|
|
|
| 8 |
TIMEOUT = 120.0
|
| 9 |
|
| 10 |
|
|
@@ -89,22 +90,25 @@ def build_system_prompt(mode: str, topic: str, phase: int, rag_context: list[str
|
|
| 89 |
|
| 90 |
|
| 91 |
async def chat(system_prompt: str, messages: list[dict]) -> str:
|
| 92 |
-
"""Send chat to
|
| 93 |
-
|
| 94 |
-
|
| 95 |
|
| 96 |
async with httpx.AsyncClient(timeout=TIMEOUT) as client:
|
| 97 |
response = await client.post(
|
| 98 |
-
f"{
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
json={
|
| 100 |
"model": MODEL,
|
| 101 |
-
"messages":
|
| 102 |
-
"stream": False,
|
| 103 |
},
|
| 104 |
)
|
| 105 |
response.raise_for_status()
|
| 106 |
data = response.json()
|
| 107 |
-
return data["message"]["content"]
|
| 108 |
|
| 109 |
|
| 110 |
async def analyze_session(messages: list[dict]) -> dict:
|
|
|
|
| 1 |
+
"""LLM interaction via OpenRouter (OpenAI-compatible API)."""
|
| 2 |
|
| 3 |
import os
|
| 4 |
import httpx
|
| 5 |
|
| 6 |
+
OPENROUTER_API_KEY = os.environ.get("OPENROUTER_API_KEY", "")
|
| 7 |
+
OPENROUTER_BASE_URL = "https://openrouter.ai/api/v1"
|
| 8 |
+
MODEL = os.environ.get("LLM_MODEL", "mistralai/mistral-7b-instruct")
|
| 9 |
TIMEOUT = 120.0
|
| 10 |
|
| 11 |
|
|
|
|
| 90 |
|
| 91 |
|
| 92 |
async def chat(system_prompt: str, messages: list[dict]) -> str:
|
| 93 |
+
"""Send chat to OpenRouter and return assistant response."""
|
| 94 |
+
api_messages = [{"role": "system", "content": system_prompt}]
|
| 95 |
+
api_messages.extend(messages)
|
| 96 |
|
| 97 |
async with httpx.AsyncClient(timeout=TIMEOUT) as client:
|
| 98 |
response = await client.post(
|
| 99 |
+
f"{OPENROUTER_BASE_URL}/chat/completions",
|
| 100 |
+
headers={
|
| 101 |
+
"Authorization": f"Bearer {OPENROUTER_API_KEY}",
|
| 102 |
+
"Content-Type": "application/json",
|
| 103 |
+
},
|
| 104 |
json={
|
| 105 |
"model": MODEL,
|
| 106 |
+
"messages": api_messages,
|
|
|
|
| 107 |
},
|
| 108 |
)
|
| 109 |
response.raise_for_status()
|
| 110 |
data = response.json()
|
| 111 |
+
return data["choices"][0]["message"]["content"]
|
| 112 |
|
| 113 |
|
| 114 |
async def analyze_session(messages: list[dict]) -> dict:
|
docker-compose.yml
CHANGED
|
@@ -7,9 +7,8 @@ services:
|
|
| 7 |
- ./corpus:/app/corpus
|
| 8 |
- chroma-data:/app/chroma_data
|
| 9 |
environment:
|
| 10 |
-
-
|
| 11 |
-
|
| 12 |
-
- "host.docker.internal:host-gateway"
|
| 13 |
restart: unless-stopped
|
| 14 |
|
| 15 |
volumes:
|
|
|
|
| 7 |
- ./corpus:/app/corpus
|
| 8 |
- chroma-data:/app/chroma_data
|
| 9 |
environment:
|
| 10 |
+
- OPENROUTER_API_KEY=${OPENROUTER_API_KEY}
|
| 11 |
+
- LLM_MODEL=${LLM_MODEL:-mistralai/mistral-7b-instruct}
|
|
|
|
| 12 |
restart: unless-stopped
|
| 13 |
|
| 14 |
volumes:
|