2025-05-24 11:29:45 +08:00
|
|
|
|
from datetime import datetime, timezone, UTC
|
2025-05-16 23:46:25 +08:00
|
|
|
|
import asyncio
|
2025-07-02 02:38:36 +08:00
|
|
|
|
import os
|
|
|
|
|
|
import traceback
|
2025-04-02 13:00:25 +08:00
|
|
|
|
|
2025-07-02 02:38:36 +08:00
|
|
|
|
from src import config
|
2025-08-31 00:34:26 +08:00
|
|
|
|
from src.utils import get_docker_safe_url
|
2025-07-02 02:38:36 +08:00
|
|
|
|
from src.models import get_custom_model
|
2025-08-31 00:34:26 +08:00
|
|
|
|
from src.agents.common.base import BaseAgent
|
2025-03-29 17:33:09 +08:00
|
|
|
|
from langchain_core.language_models import BaseChatModel
|
2025-03-25 05:40:07 +08:00
|
|
|
|
from langchain_core.runnables import RunnableConfig
|
|
|
|
|
|
from langchain_core.messages import AIMessageChunk, ToolMessage
|
2025-07-02 02:38:36 +08:00
|
|
|
|
from pydantic import SecretStr
|
2025-03-25 05:40:07 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-03-29 17:33:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-04-02 00:00:04 +08:00
|
|
|
|
def load_chat_model(fully_specified_name: str, **kwargs) -> BaseChatModel:
|
2025-07-02 02:38:36 +08:00
|
|
|
|
"""
|
|
|
|
|
|
Load a chat model from a fully specified name.
|
2025-03-29 17:33:09 +08:00
|
|
|
|
"""
|
|
|
|
|
|
provider, model = fully_specified_name.split("/", maxsplit=1)
|
2025-04-02 00:00:04 +08:00
|
|
|
|
|
2025-07-02 02:38:36 +08:00
|
|
|
|
if provider == "custom":
|
|
|
|
|
|
from langchain_openai import ChatOpenAI
|
|
|
|
|
|
model_info = get_custom_model(model)
|
|
|
|
|
|
api_key = model_info.get("api_key") or "custom_model"
|
|
|
|
|
|
base_url = get_docker_safe_url(model_info["api_base"])
|
|
|
|
|
|
model_name = model_info.get("name") or "custom_model"
|
|
|
|
|
|
return ChatOpenAI(
|
|
|
|
|
|
model=model_name,
|
|
|
|
|
|
api_key=SecretStr(api_key),
|
|
|
|
|
|
base_url=base_url,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
model_info = config.model_names.get(provider, {})
|
|
|
|
|
|
api_key = os.getenv(model_info["env"][0], model_info["env"][0])
|
|
|
|
|
|
base_url = get_docker_safe_url(model_info["base_url"])
|
|
|
|
|
|
|
|
|
|
|
|
if provider in ["deepseek", "dashscope"]:
|
|
|
|
|
|
from langchain_deepseek import ChatDeepSeek
|
|
|
|
|
|
return ChatDeepSeek(
|
|
|
|
|
|
model=model,
|
|
|
|
|
|
api_key=SecretStr(api_key),
|
|
|
|
|
|
base_url=base_url,
|
|
|
|
|
|
api_base=base_url,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
elif provider == "together":
|
|
|
|
|
|
from langchain_together import ChatTogether
|
|
|
|
|
|
return ChatTogether(
|
|
|
|
|
|
model=model,
|
|
|
|
|
|
api_key=SecretStr(api_key),
|
|
|
|
|
|
base_url=base_url,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
try: # 其他模型,默认使用OpenAIBase, like openai, zhipuai
|
|
|
|
|
|
from langchain_openai import ChatOpenAI
|
|
|
|
|
|
return ChatOpenAI(
|
|
|
|
|
|
model=model,
|
|
|
|
|
|
api_key=SecretStr(api_key),
|
|
|
|
|
|
base_url=base_url,
|
|
|
|
|
|
)
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
raise ValueError(f"Model provider {provider} load failed, {e} \n {traceback.format_exc()}")
|
|
|
|
|
|
|
2025-03-29 17:33:09 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-07-02 02:38:36 +08:00
|
|
|
|
async def agent_cli(agent: BaseAgent, config: RunnableConfig | None = None):
|
2025-03-25 05:40:07 +08:00
|
|
|
|
config = config or {}
|
|
|
|
|
|
if "configurable" not in config:
|
|
|
|
|
|
config["configurable"] = {}
|
|
|
|
|
|
|
|
|
|
|
|
while True:
|
|
|
|
|
|
user_input = input("\nUser: ")
|
|
|
|
|
|
if user_input.lower() in ["quit", "exit", "q"]:
|
|
|
|
|
|
print("Goodbye!")
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
stream_flag = False
|
2025-05-16 23:46:25 +08:00
|
|
|
|
async for msg, metadata in agent.stream_messages([{"role": "user", "content": user_input}], config):
|
2025-03-25 05:40:07 +08:00
|
|
|
|
if isinstance(msg, AIMessageChunk):
|
|
|
|
|
|
content = msg.content or msg.tool_calls
|
|
|
|
|
|
|
|
|
|
|
|
if not content:
|
2025-05-23 15:30:14 +08:00
|
|
|
|
if stream_flag:
|
2025-03-25 05:40:07 +08:00
|
|
|
|
print()
|
|
|
|
|
|
stream_flag = False
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
2025-05-23 15:30:14 +08:00
|
|
|
|
if not stream_flag and content:
|
2025-03-25 05:40:07 +08:00
|
|
|
|
print(f"AI: {content}", end="", flush=True)
|
|
|
|
|
|
stream_flag = True
|
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
|
|
elif content:
|
|
|
|
|
|
print(f"{content}", end="", flush=True)
|
|
|
|
|
|
|
|
|
|
|
|
if isinstance(msg, ToolMessage):
|
|
|
|
|
|
print(f"Tool: {msg.content}")
|
2025-04-02 13:00:25 +08:00
|
|
|
|
|
|
|
|
|
|
def get_cur_time_with_utc():
|
2025-05-24 11:29:45 +08:00
|
|
|
|
return datetime.now(tz=UTC).isoformat()
|
2025-04-02 13:00:25 +08:00
|
|
|
|
|