Update llm/agents.py
Browse files- llm/agents.py +59 -31
llm/agents.py
CHANGED
@@ -1,35 +1,44 @@
|
|
1 |
import asyncio
|
2 |
import httpx
|
3 |
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
|
5 |
-
OPENROUTER_BASE = "https://openrouter.ai/api/v1/chat/completions"
|
6 |
-
HEADERS = {
|
7 |
-
"Authorization": f"Bearer {os.getenv('OPENROUTER_API_KEY')}",
|
8 |
-
"Content-Type": "application/json",
|
9 |
-
}
|
10 |
-
|
11 |
-
ALLOWED_MODELS = [
|
12 |
-
"deepseek/deepseek-chat-v3-0324:free",
|
13 |
-
"google/gemini-2.0-flash-exp:free",
|
14 |
-
"meta-llama/llama-4-maverick:free",
|
15 |
-
"microsoft/mai-ds-r1:free",
|
16 |
-
"meta-llama/llama-4-scout:free",
|
17 |
-
"google/gemma-3-27b-it:free",
|
18 |
-
"qwen/qwq-32b:free",
|
19 |
-
"qwen/qwen2.5-vl-72b-instruct:free",
|
20 |
-
"qwen/qwen-2.5-72b-instruct:free",
|
21 |
-
"google/gemini-2.5-pro-exp-03-25:free",
|
22 |
-
"deepseek/deepseek-r1:free",
|
23 |
-
]
|
24 |
-
|
25 |
-
async def call_openrouter(model: str, prompt: str) -> str:
|
26 |
body = {
|
27 |
"model": model,
|
28 |
"messages": [{"role": "user", "content": prompt}],
|
29 |
"temperature": 0.7,
|
30 |
}
|
|
|
31 |
async with httpx.AsyncClient(timeout=30) as client:
|
32 |
-
response = await client.post(
|
33 |
response.raise_for_status()
|
34 |
return response.json()["choices"][0]["message"]["content"]
|
35 |
|
@@ -39,15 +48,11 @@ async def query_llm_agent(name: str, prompt: str, settings: dict) -> str:
|
|
39 |
if not selected_model:
|
40 |
return f"[{name}] No model selected."
|
41 |
|
42 |
-
|
43 |
-
if not selected_model.endswith(":free"):
|
44 |
-
selected_model += ":free"
|
45 |
-
|
46 |
-
if selected_model not in ALLOWED_MODELS:
|
47 |
return f"[{name}] Model '{selected_model}' is not supported."
|
48 |
|
49 |
try:
|
50 |
-
response = await
|
51 |
return f"[{name}] {response}"
|
52 |
except Exception as e:
|
53 |
return f"[{name}] Error: {str(e)}"
|
@@ -55,8 +60,31 @@ async def query_llm_agent(name: str, prompt: str, settings: dict) -> str:
|
|
55 |
async def query_all_llms(prompt: str, settings: dict) -> list:
|
56 |
agents = ["LLM-A", "LLM-B", "LLM-C"]
|
57 |
tasks = [query_llm_agent(agent, prompt, settings) for agent in agents]
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
def query_all_llms_sync(prompt: str, settings: dict) -> list:
|
62 |
-
return asyncio.run(
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import asyncio
|
2 |
import httpx
|
3 |
import os
|
4 |
+
import json
|
5 |
+
|
6 |
+
# Load model config at startup
|
7 |
+
with open("llm/model_config.json", "r") as f:
|
8 |
+
CONFIG = json.load(f)
|
9 |
+
|
10 |
+
PROVIDERS = CONFIG["providers"]
|
11 |
+
MODEL_PROVIDER_MAPPING = CONFIG["models"]
|
12 |
+
|
13 |
+
async def call_model_api(model: str, prompt: str) -> str:
|
14 |
+
provider_key = MODEL_PROVIDER_MAPPING.get(model)
|
15 |
+
if not provider_key:
|
16 |
+
raise ValueError(f"No provider configured for model: {model}")
|
17 |
+
|
18 |
+
provider = PROVIDERS.get(provider_key)
|
19 |
+
if not provider:
|
20 |
+
raise ValueError(f"Provider {provider_key} not found in config")
|
21 |
+
|
22 |
+
url = provider["url"]
|
23 |
+
api_key_env = provider["key_env"]
|
24 |
+
api_key = os.getenv(api_key_env)
|
25 |
+
|
26 |
+
if not api_key:
|
27 |
+
raise ValueError(f"Missing API key for provider {provider_key}")
|
28 |
+
|
29 |
+
headers = {
|
30 |
+
"Authorization": f"Bearer {api_key}",
|
31 |
+
"Content-Type": "application/json",
|
32 |
+
}
|
33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
body = {
|
35 |
"model": model,
|
36 |
"messages": [{"role": "user", "content": prompt}],
|
37 |
"temperature": 0.7,
|
38 |
}
|
39 |
+
|
40 |
async with httpx.AsyncClient(timeout=30) as client:
|
41 |
+
response = await client.post(url, headers=headers, json=body)
|
42 |
response.raise_for_status()
|
43 |
return response.json()["choices"][0]["message"]["content"]
|
44 |
|
|
|
48 |
if not selected_model:
|
49 |
return f"[{name}] No model selected."
|
50 |
|
51 |
+
if selected_model not in MODEL_PROVIDER_MAPPING:
|
|
|
|
|
|
|
|
|
52 |
return f"[{name}] Model '{selected_model}' is not supported."
|
53 |
|
54 |
try:
|
55 |
+
response = await call_model_api(selected_model, prompt)
|
56 |
return f"[{name}] {response}"
|
57 |
except Exception as e:
|
58 |
return f"[{name}] Error: {str(e)}"
|
|
|
60 |
async def query_all_llms(prompt: str, settings: dict) -> list:
|
61 |
agents = ["LLM-A", "LLM-B", "LLM-C"]
|
62 |
tasks = [query_llm_agent(agent, prompt, settings) for agent in agents]
|
63 |
+
return await asyncio.gather(*tasks)
|
64 |
+
|
65 |
+
async def query_aggregator(responses: list, settings: dict) -> str:
|
66 |
+
model = settings.get("aggregator")
|
67 |
+
if not model:
|
68 |
+
return "[Aggregator] No aggregator model selected."
|
69 |
+
if model not in MODEL_PROVIDER_MAPPING:
|
70 |
+
return f"[Aggregator] Model '{model}' is not supported."
|
71 |
+
|
72 |
+
system_prompt = (
|
73 |
+
"You are an aggregator AI. Your task is to read the following responses "
|
74 |
+
"from different AI agents and produce a single, high-quality response.\n\n"
|
75 |
+
+ "\n\n".join(responses)
|
76 |
+
)
|
77 |
+
|
78 |
+
try:
|
79 |
+
result = await call_model_api(model, system_prompt)
|
80 |
+
return f"[Aggregator] {result}"
|
81 |
+
except Exception as e:
|
82 |
+
return f"[Aggregator] Error: {str(e)}"
|
83 |
|
84 |
def query_all_llms_sync(prompt: str, settings: dict) -> list:
|
85 |
+
return asyncio.run(query_moa_chain(prompt, settings))
|
86 |
+
|
87 |
+
async def query_moa_chain(prompt: str, settings: dict) -> list:
|
88 |
+
responses = await query_all_llms(prompt, settings)
|
89 |
+
aggregator = await query_aggregator(responses, settings)
|
90 |
+
return responses + [aggregator]
|