- 引入AgentTeamOrchestrator支持多agent协同任务执行 - 增加第三方swarms库依赖并配置git协议替换以改善包管理 - 扩展DelegationManager支持团队任务调度和进度跟踪 - 实现中文bigram分词算法提升中文任务检索准确性 - 调整A2AClient和DelegationManager超时时间从30秒增至600秒 - 优化AgentRunResult状态判断逻辑增加有意义摘要检测 - 修改Dockerfile配置npm仓库镜像地址和git协议映射 - 更新CLI命令行接口支持网关端口配置传递 - 调整提供者超时配置机制增强请求稳定性 - 移除过时的support_group字段简化agent描述符结构 - 增强错误处理和进度事件报告机制改进用户体验
62 lines
2.4 KiB
Python
62 lines
2.4 KiB
Python
"""Direct OpenAI-compatible provider — bypasses LiteLLM."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
import json_repair
|
|
from openai import AsyncOpenAI
|
|
|
|
from nanobot.providers.base import LLMProvider, LLMResponse, ToolCallRequest
|
|
|
|
|
|
class CustomProvider(LLMProvider):
|
|
|
|
def __init__(
|
|
self,
|
|
api_key: str = "no-key",
|
|
api_base: str = "http://localhost:8000/v1",
|
|
default_model: str = "default",
|
|
request_timeout_seconds: float | None = None,
|
|
):
|
|
super().__init__(api_key, api_base, request_timeout_seconds=request_timeout_seconds)
|
|
self.default_model = default_model
|
|
self._client = AsyncOpenAI(
|
|
api_key=api_key,
|
|
base_url=api_base,
|
|
timeout=self.request_timeout_seconds,
|
|
)
|
|
|
|
async def chat(self, messages: list[dict[str, Any]], tools: list[dict[str, Any]] | None = None,
|
|
model: str | None = None, max_tokens: int = 4096, temperature: float = 0.7) -> LLMResponse:
|
|
kwargs: dict[str, Any] = {
|
|
"model": model or self.default_model,
|
|
"messages": self._sanitize_empty_content(messages),
|
|
"max_tokens": max(1, max_tokens),
|
|
"temperature": temperature,
|
|
}
|
|
if tools:
|
|
kwargs.update(tools=tools, tool_choice="auto")
|
|
try:
|
|
return self._parse(await self._client.chat.completions.create(**kwargs))
|
|
except Exception as e:
|
|
return LLMResponse(content=f"Error: {e}", finish_reason="error")
|
|
|
|
def _parse(self, response: Any) -> LLMResponse:
|
|
choice = response.choices[0]
|
|
msg = choice.message
|
|
tool_calls = [
|
|
ToolCallRequest(id=tc.id, name=tc.function.name,
|
|
arguments=json_repair.loads(tc.function.arguments) if isinstance(tc.function.arguments, str) else tc.function.arguments)
|
|
for tc in (msg.tool_calls or [])
|
|
]
|
|
u = response.usage
|
|
return LLMResponse(
|
|
content=msg.content, tool_calls=tool_calls, finish_reason=choice.finish_reason or "stop",
|
|
usage={"prompt_tokens": u.prompt_tokens, "completion_tokens": u.completion_tokens, "total_tokens": u.total_tokens} if u else {},
|
|
reasoning_content=getattr(msg, "reasoning_content", None) or None,
|
|
)
|
|
|
|
def get_default_model(self) -> str:
|
|
return self.default_model
|