Initial commit: Meeting Room v0.1.0
Multi-agent discussion framework: - Custom/AutoGen/CrewAI backends - Multi-provider API (role→model binding) - Tools system (files, web, commands) - Markdown scenarios with YAML frontmatter - Workspace init (meeting-room init) - Session save (--save)
This commit is contained in:
96
meeting_room/api_client.py
Normal file
96
meeting_room/api_client.py
Normal file
@@ -0,0 +1,96 @@
|
||||
"""Universal API client supporting multiple OpenAI-compatible providers."""
|
||||
|
||||
import httpx
|
||||
import json
|
||||
|
||||
|
||||
PROVIDERS = {}
|
||||
|
||||
|
||||
def init_providers(config: dict):
|
||||
global PROVIDERS
|
||||
PROVIDERS = config.get("providers", {})
|
||||
|
||||
|
||||
def _get_client(provider_name: str) -> httpx.Client:
|
||||
p = PROVIDERS.get(provider_name)
|
||||
if not p:
|
||||
raise ValueError(f"Unknown provider: {provider_name}")
|
||||
return httpx.Client(
|
||||
base_url=p["base_url"],
|
||||
headers={"Authorization": f"Bearer {p['api_key']}"},
|
||||
timeout=120.0,
|
||||
)
|
||||
|
||||
|
||||
def chat(
|
||||
provider: str,
|
||||
model: str,
|
||||
messages: list[dict],
|
||||
temperature: float = 0.7,
|
||||
tools: list[dict] | None = None,
|
||||
) -> dict:
|
||||
client = _get_client(provider)
|
||||
payload = {
|
||||
"model": model,
|
||||
"messages": messages,
|
||||
"temperature": temperature,
|
||||
}
|
||||
if tools:
|
||||
payload["tools"] = tools
|
||||
payload["tool_choice"] = "auto"
|
||||
|
||||
resp = client.post("/chat/completions", json=payload)
|
||||
resp.raise_for_status()
|
||||
data = resp.json()
|
||||
message = data["choices"][0]["message"]
|
||||
|
||||
result = {
|
||||
"content": message.get("content") or "",
|
||||
"tool_calls": None,
|
||||
}
|
||||
|
||||
if message.get("tool_calls"):
|
||||
result["tool_calls"] = []
|
||||
for tc in message["tool_calls"]:
|
||||
result["tool_calls"].append({
|
||||
"id": tc["id"],
|
||||
"name": tc["function"]["name"],
|
||||
"arguments": tc["function"]["arguments"],
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def chat_stream(
|
||||
provider: str,
|
||||
model: str,
|
||||
messages: list[dict],
|
||||
temperature: float = 0.7,
|
||||
) -> str:
|
||||
client = _get_client(provider)
|
||||
payload = {
|
||||
"model": model,
|
||||
"messages": messages,
|
||||
"temperature": temperature,
|
||||
"stream": True,
|
||||
}
|
||||
full_text = ""
|
||||
with client.stream("POST", "/chat/completions", json=payload) as resp:
|
||||
resp.raise_for_status()
|
||||
for line in resp.iter_lines():
|
||||
if not line or not line.startswith("data: "):
|
||||
continue
|
||||
data = line[6:]
|
||||
if data == "[DONE]":
|
||||
break
|
||||
try:
|
||||
chunk = json.loads(data)
|
||||
delta = chunk["choices"][0]["delta"]
|
||||
if "content" in delta and delta["content"]:
|
||||
print(delta["content"], end="", flush=True)
|
||||
full_text += delta["content"]
|
||||
except (json.JSONDecodeError, KeyError, IndexError):
|
||||
continue
|
||||
print()
|
||||
return full_text
|
||||
Reference in New Issue
Block a user