Compare commits
50 Commits
989735e89f
...
2964326cb8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2964326cb8 | ||
|
|
ed34ff9ee9 | ||
|
|
a9044c6d2e | ||
|
|
7d22f0b34d | ||
|
|
788bb0089f | ||
|
|
b6976cc8bf | ||
|
|
f67d18e13f | ||
|
|
6813a48a99 | ||
|
|
4d75075406 | ||
|
|
675d7d3e12 | ||
|
|
4625ddf5a9 | ||
|
|
5b7522eff2 | ||
|
|
aae1742b37 | ||
|
|
d1e31953b0 | ||
|
|
513dda8bbb | ||
|
|
b23412b84b | ||
|
|
c4a0ce1162 | ||
|
|
ab6b68268e | ||
|
|
845815866e | ||
|
|
76e742e7b3 | ||
|
|
738a904a6f | ||
|
|
213e541697 | ||
|
|
44db634cbb | ||
|
|
89a9d81892 | ||
|
|
dc2e8a39e3 | ||
|
|
2bc071645f | ||
|
|
52a700e0db | ||
|
|
7214adcf8e | ||
|
|
dc52ddb8cc | ||
|
|
0c9c36cc54 | ||
|
|
6b6fad9c1c | ||
|
|
d0b619f4f1 | ||
|
|
6300eea61d | ||
|
|
becd36da9d | ||
|
|
18bf296aa0 | ||
|
|
85519da5a5 | ||
|
|
e987cb6f6b | ||
|
|
e713a0a903 | ||
|
|
f9839b9bc4 | ||
|
|
2adc8fc5e3 | ||
|
|
4b3cab0cc7 | ||
|
|
cc99ba67ac | ||
|
|
d2e6af5974 | ||
|
|
63e6178149 | ||
|
|
83f42ef7d4 | ||
|
|
dab429dafd | ||
|
|
543b4757c7 | ||
|
|
a25e54f2c3 | ||
|
|
2047f11504 | ||
|
|
2a87c6b296 |
@ -4,7 +4,9 @@
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Annotated, Literal, cast
|
from typing import Annotated, cast
|
||||||
|
import mimetypes
|
||||||
|
import warnings
|
||||||
|
|
||||||
from langchain.tools import ToolRuntime
|
from langchain.tools import ToolRuntime
|
||||||
from langchain_core.messages import ToolMessage
|
from langchain_core.messages import ToolMessage
|
||||||
@ -15,19 +17,24 @@ from deepagents.backends import StateBackend
|
|||||||
from deepagents.backends.composite import CompositeBackend
|
from deepagents.backends.composite import CompositeBackend
|
||||||
from deepagents.backends.protocol import (
|
from deepagents.backends.protocol import (
|
||||||
BACKEND_TYPES,
|
BACKEND_TYPES,
|
||||||
|
ReadResult,
|
||||||
)
|
)
|
||||||
|
from deepagents.backends.utils import _get_file_type, validate_path
|
||||||
|
from langchain_core.messages.content import ContentBlock
|
||||||
from deepagents.middleware.filesystem import (
|
from deepagents.middleware.filesystem import (
|
||||||
DEFAULT_READ_OFFSET,
|
DEFAULT_READ_OFFSET,
|
||||||
DEFAULT_READ_LIMIT,
|
DEFAULT_READ_LIMIT,
|
||||||
IMAGE_EXTENSIONS,
|
|
||||||
IMAGE_MEDIA_TYPES,
|
|
||||||
FilesystemMiddleware,
|
FilesystemMiddleware,
|
||||||
FilesystemState,
|
FilesystemState,
|
||||||
|
READ_FILE_TOOL_DESCRIPTION,
|
||||||
|
READ_FILE_TRUNCATION_MSG,
|
||||||
|
NUM_CHARS_PER_TOKEN,
|
||||||
|
ReadFileSchema,
|
||||||
|
check_empty_content,
|
||||||
|
format_content_with_line_numbers,
|
||||||
)
|
)
|
||||||
|
|
||||||
from langgraph.types import Command
|
from langgraph.types import Command
|
||||||
import base64
|
|
||||||
from langchain_core.messages.content import create_image_block
|
|
||||||
|
|
||||||
|
|
||||||
# SKILL.md 文件的行数限制(设置为较大的值以完整读取)
|
# SKILL.md 文件的行数限制(设置为较大的值以完整读取)
|
||||||
@ -44,10 +51,62 @@ class CustomFilesystemMiddleware(FilesystemMiddleware):
|
|||||||
@override
|
@override
|
||||||
def _create_read_file_tool(self) -> BaseTool:
|
def _create_read_file_tool(self) -> BaseTool:
|
||||||
"""创建自定义的 read_file 工具,支持 SKILL.md 完整读取。"""
|
"""创建自定义的 read_file 工具,支持 SKILL.md 完整读取。"""
|
||||||
# 从父类获取工具描述
|
tool_description = self._custom_tool_descriptions.get("read_file") or READ_FILE_TOOL_DESCRIPTION
|
||||||
tool_description = self._custom_tool_descriptions.get("read_file") or self._get_read_file_description()
|
|
||||||
token_limit = self._tool_token_limit_before_evict
|
token_limit = self._tool_token_limit_before_evict
|
||||||
|
|
||||||
|
def _truncate(content: str, file_path: str, limit: int) -> str:
|
||||||
|
lines = content.splitlines(keepends=True)
|
||||||
|
if len(lines) > limit:
|
||||||
|
lines = lines[:limit]
|
||||||
|
content = "".join(lines)
|
||||||
|
|
||||||
|
if token_limit and len(content) >= NUM_CHARS_PER_TOKEN * token_limit:
|
||||||
|
truncation_msg = READ_FILE_TRUNCATION_MSG.format(file_path=file_path)
|
||||||
|
max_content_length = NUM_CHARS_PER_TOKEN * token_limit - len(truncation_msg)
|
||||||
|
content = content[:max_content_length] + truncation_msg
|
||||||
|
|
||||||
|
return content
|
||||||
|
|
||||||
|
def _handle_read_result(
|
||||||
|
read_result: ReadResult | str,
|
||||||
|
validated_path: str,
|
||||||
|
tool_call_id: str | None,
|
||||||
|
offset: int,
|
||||||
|
limit: int,
|
||||||
|
) -> ToolMessage | str:
|
||||||
|
if isinstance(read_result, str):
|
||||||
|
warnings.warn(
|
||||||
|
"Returning a plain `str` from `backend.read()` is deprecated. ",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
return _truncate(read_result, validated_path, limit)
|
||||||
|
|
||||||
|
if read_result.error:
|
||||||
|
return f"Error: {read_result.error}"
|
||||||
|
|
||||||
|
if read_result.file_data is None:
|
||||||
|
return f"Error: no data returned for '{validated_path}'"
|
||||||
|
|
||||||
|
file_type = _get_file_type(validated_path)
|
||||||
|
content = read_result.file_data["content"]
|
||||||
|
|
||||||
|
if file_type != "text":
|
||||||
|
mime_type = mimetypes.guess_type("file" + Path(validated_path).suffix)[0] or "application/octet-stream"
|
||||||
|
return ToolMessage(
|
||||||
|
content_blocks=cast("list[ContentBlock]", [{"type": file_type, "base64": content, "mime_type": mime_type}]),
|
||||||
|
name="read_file",
|
||||||
|
tool_call_id=tool_call_id,
|
||||||
|
additional_kwargs={"read_file_path": validated_path, "read_file_media_type": mime_type},
|
||||||
|
)
|
||||||
|
|
||||||
|
empty_msg = check_empty_content(content)
|
||||||
|
if empty_msg:
|
||||||
|
return empty_msg
|
||||||
|
|
||||||
|
content = format_content_with_line_numbers(content, start_line=offset + 1)
|
||||||
|
return _truncate(content, validated_path, limit)
|
||||||
|
|
||||||
def sync_read_file(
|
def sync_read_file(
|
||||||
file_path: Annotated[str, "Absolute path to the file to read. Must be absolute, not relative."],
|
file_path: Annotated[str, "Absolute path to the file to read. Must be absolute, not relative."],
|
||||||
runtime: ToolRuntime[None, FilesystemState],
|
runtime: ToolRuntime[None, FilesystemState],
|
||||||
@ -55,57 +114,18 @@ class CustomFilesystemMiddleware(FilesystemMiddleware):
|
|||||||
limit: Annotated[int, "Maximum number of lines to read. Use for pagination of large files."] = DEFAULT_READ_LIMIT,
|
limit: Annotated[int, "Maximum number of lines to read. Use for pagination of large files."] = DEFAULT_READ_LIMIT,
|
||||||
) -> ToolMessage | str:
|
) -> ToolMessage | str:
|
||||||
"""Synchronous wrapper for read_file tool with SKILL.md special handling."""
|
"""Synchronous wrapper for read_file tool with SKILL.md special handling."""
|
||||||
from deepagents.backends.utils import validate_path
|
|
||||||
from deepagents.middleware.filesystem import READ_FILE_TRUNCATION_MSG, NUM_CHARS_PER_TOKEN
|
|
||||||
|
|
||||||
resolved_backend = self._get_backend(runtime)
|
resolved_backend = self._get_backend(runtime)
|
||||||
try:
|
try:
|
||||||
validated_path = validate_path(file_path)
|
validated_path = validate_path(file_path)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
return f"Error: {e}"
|
return f"Error: {e}"
|
||||||
|
|
||||||
ext = Path(validated_path).suffix.lower()
|
|
||||||
# 处理图片文件
|
|
||||||
if ext in IMAGE_EXTENSIONS:
|
|
||||||
responses = resolved_backend.download_files([validated_path])
|
|
||||||
if responses and responses[0].content is not None:
|
|
||||||
media_type = IMAGE_MEDIA_TYPES.get(ext, "image/png")
|
|
||||||
image_b64 = base64.standard_b64encode(responses[0].content).decode("utf-8")
|
|
||||||
return ToolMessage(
|
|
||||||
content_blocks=[create_image_block(base64=image_b64, mime_type=media_type)],
|
|
||||||
name="read_file",
|
|
||||||
tool_call_id=runtime.tool_call_id,
|
|
||||||
additional_kwargs={
|
|
||||||
"read_file_path": validated_path,
|
|
||||||
"read_file_media_type": media_type,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if responses and responses[0].error:
|
|
||||||
return f"Error reading image: {responses[0].error}"
|
|
||||||
return "Error reading image: unknown error"
|
|
||||||
|
|
||||||
# 如果是 SKILL.md 文件,使用大限制读取完整内容
|
# 如果是 SKILL.md 文件,使用大限制读取完整内容
|
||||||
if validated_path.endswith("SKILL.md") or validated_path.endswith("/SKILL.md"):
|
if validated_path.endswith("SKILL.md") or validated_path.endswith("/SKILL.md"):
|
||||||
actual_limit = SKILL_MD_READ_LIMIT
|
limit = SKILL_MD_READ_LIMIT
|
||||||
else:
|
|
||||||
actual_limit = limit
|
|
||||||
|
|
||||||
result = resolved_backend.read(validated_path, offset=offset, limit=actual_limit)
|
read_result = resolved_backend.read(validated_path, offset=offset, limit=limit)
|
||||||
|
return _handle_read_result(read_result, validated_path, runtime.tool_call_id, offset, limit)
|
||||||
lines = result.splitlines(keepends=True)
|
|
||||||
if len(lines) > actual_limit:
|
|
||||||
lines = lines[:actual_limit]
|
|
||||||
result = "".join(lines)
|
|
||||||
|
|
||||||
# Check if result exceeds token threshold and truncate if necessary
|
|
||||||
if token_limit and len(result) >= NUM_CHARS_PER_TOKEN * token_limit:
|
|
||||||
# Calculate truncation message length to ensure final result stays under threshold
|
|
||||||
truncation_msg = READ_FILE_TRUNCATION_MSG.format(file_path=validated_path)
|
|
||||||
max_content_length = NUM_CHARS_PER_TOKEN * token_limit - len(truncation_msg)
|
|
||||||
result = result[:max_content_length]
|
|
||||||
result += truncation_msg
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
async def async_read_file(
|
async def async_read_file(
|
||||||
file_path: Annotated[str, "Absolute path to the file to read. Must be absolute, not relative."],
|
file_path: Annotated[str, "Absolute path to the file to read. Must be absolute, not relative."],
|
||||||
@ -114,66 +134,28 @@ class CustomFilesystemMiddleware(FilesystemMiddleware):
|
|||||||
limit: Annotated[int, "Maximum number of lines to read. Use for pagination of large files."] = DEFAULT_READ_LIMIT,
|
limit: Annotated[int, "Maximum number of lines to read. Use for pagination of large files."] = DEFAULT_READ_LIMIT,
|
||||||
) -> ToolMessage | str:
|
) -> ToolMessage | str:
|
||||||
"""Asynchronous wrapper for read_file tool with SKILL.md special handling."""
|
"""Asynchronous wrapper for read_file tool with SKILL.md special handling."""
|
||||||
from deepagents.backends.utils import validate_path
|
|
||||||
from deepagents.middleware.filesystem import READ_FILE_TRUNCATION_MSG, NUM_CHARS_PER_TOKEN
|
|
||||||
|
|
||||||
resolved_backend = self._get_backend(runtime)
|
resolved_backend = self._get_backend(runtime)
|
||||||
try:
|
try:
|
||||||
validated_path = validate_path(file_path)
|
validated_path = validate_path(file_path)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
return f"Error: {e}"
|
return f"Error: {e}"
|
||||||
|
|
||||||
ext = Path(validated_path).suffix.lower()
|
|
||||||
# 处理图片文件
|
|
||||||
if ext in IMAGE_EXTENSIONS:
|
|
||||||
responses = await resolved_backend.adownload_files([validated_path])
|
|
||||||
if responses and responses[0].content is not None:
|
|
||||||
media_type = IMAGE_MEDIA_TYPES.get(ext, "image/png")
|
|
||||||
image_b64 = base64.standard_b64encode(responses[0].content).decode("utf-8")
|
|
||||||
return ToolMessage(
|
|
||||||
content_blocks=[create_image_block(base64=image_b64, mime_type=media_type)],
|
|
||||||
name="read_file",
|
|
||||||
tool_call_id=runtime.tool_call_id,
|
|
||||||
additional_kwargs={
|
|
||||||
"read_file_path": validated_path,
|
|
||||||
"read_file_media_type": media_type,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if responses and responses[0].error:
|
|
||||||
return f"Error reading image: {responses[0].error}"
|
|
||||||
return "Error reading image: unknown error"
|
|
||||||
|
|
||||||
# 如果是 SKILL.md 文件,使用大限制读取完整内容
|
# 如果是 SKILL.md 文件,使用大限制读取完整内容
|
||||||
if validated_path.endswith("SKILL.md") or validated_path.endswith("/SKILL.md"):
|
if validated_path.endswith("SKILL.md") or validated_path.endswith("/SKILL.md"):
|
||||||
actual_limit = SKILL_MD_READ_LIMIT
|
limit = SKILL_MD_READ_LIMIT
|
||||||
else:
|
|
||||||
actual_limit = limit
|
|
||||||
|
|
||||||
result = await resolved_backend.aread(validated_path, offset=offset, limit=actual_limit)
|
read_result = await resolved_backend.aread(validated_path, offset=offset, limit=limit)
|
||||||
|
return _handle_read_result(read_result, validated_path, runtime.tool_call_id, offset, limit)
|
||||||
lines = result.splitlines(keepends=True)
|
|
||||||
if len(lines) > actual_limit:
|
|
||||||
lines = lines[:actual_limit]
|
|
||||||
result = "".join(lines)
|
|
||||||
|
|
||||||
# Check if result exceeds token threshold and truncate if necessary
|
|
||||||
if token_limit and len(result) >= NUM_CHARS_PER_TOKEN * token_limit:
|
|
||||||
# Calculate truncation message length to ensure final result stays under threshold
|
|
||||||
truncation_msg = READ_FILE_TRUNCATION_MSG.format(file_path=validated_path)
|
|
||||||
max_content_length = NUM_CHARS_PER_TOKEN * token_limit - len(truncation_msg)
|
|
||||||
result = result[:max_content_length]
|
|
||||||
result += truncation_msg
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
return StructuredTool.from_function(
|
return StructuredTool.from_function(
|
||||||
name="read_file",
|
name="read_file",
|
||||||
description=tool_description,
|
description=tool_description,
|
||||||
func=sync_read_file,
|
func=sync_read_file,
|
||||||
coroutine=async_read_file,
|
coroutine=async_read_file,
|
||||||
|
infer_schema=False,
|
||||||
|
args_schema=ReadFileSchema,
|
||||||
)
|
)
|
||||||
|
|
||||||
def _get_read_file_description(self) -> str:
|
def _get_read_file_description(self) -> str:
|
||||||
"""获取 read_file 工具的描述,添加 SKILL.md 完整读取的说明。"""
|
"""获取 read_file 工具的描述,添加 SKILL.md 完整读取的说明。"""
|
||||||
from deepagents.middleware.filesystem import READ_FILE_TOOL_DESCRIPTION
|
|
||||||
return READ_FILE_TOOL_DESCRIPTION
|
return READ_FILE_TOOL_DESCRIPTION
|
||||||
|
|||||||
@ -407,19 +407,22 @@ def create_custom_cli_agent(
|
|||||||
# Use LocalShellBackend for filesystem + shell execution
|
# Use LocalShellBackend for filesystem + shell execution
|
||||||
backend = LocalShellBackend(
|
backend = LocalShellBackend(
|
||||||
root_dir=workspace_root,
|
root_dir=workspace_root,
|
||||||
|
virtual_mode=True,
|
||||||
inherit_env=True,
|
inherit_env=True,
|
||||||
env=final_shell_env,
|
env=final_shell_env,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# No shell access - use plain FilesystemBackend
|
# No shell access - use plain FilesystemBackend
|
||||||
backend = FilesystemBackend(root_dir=workspace_root)
|
backend = FilesystemBackend(root_dir=workspace_root, virtual_mode=True)
|
||||||
|
|
||||||
# Set up composite backend with routing (参考新版本实现)
|
# Set up composite backend with routing (参考新版本实现)
|
||||||
large_results_backend = FilesystemBackend(
|
large_results_backend = FilesystemBackend(
|
||||||
root_dir=tempfile.mkdtemp(prefix="deepagents_large_results_"),
|
root_dir=tempfile.mkdtemp(prefix="deepagents_large_results_"),
|
||||||
|
virtual_mode=True,
|
||||||
)
|
)
|
||||||
conversation_history_backend = FilesystemBackend(
|
conversation_history_backend = FilesystemBackend(
|
||||||
root_dir=tempfile.mkdtemp(prefix="deepagents_conversation_history_"),
|
root_dir=tempfile.mkdtemp(prefix="deepagents_conversation_history_"),
|
||||||
|
virtual_mode=True,
|
||||||
)
|
)
|
||||||
composite_backend = CompositeBackend(
|
composite_backend = CompositeBackend(
|
||||||
default=backend,
|
default=backend,
|
||||||
@ -435,7 +438,7 @@ def create_custom_cli_agent(
|
|||||||
|
|
||||||
agent_middleware.append(
|
agent_middleware.append(
|
||||||
CustomSkillsMiddleware(
|
CustomSkillsMiddleware(
|
||||||
backend=FilesystemBackend(root_dir=workspace_root),
|
backend=FilesystemBackend(root_dir=workspace_root, virtual_mode=True),
|
||||||
sources=skills_sources,
|
sources=skills_sources,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
from ast import Str
|
|
||||||
from langchain.agents.middleware import AgentState, AgentMiddleware, ModelRequest, ModelResponse
|
from langchain.agents.middleware import AgentState, AgentMiddleware, ModelRequest, ModelResponse
|
||||||
from langchain_core.messages import convert_to_openai_messages
|
from langchain_core.messages import convert_to_openai_messages
|
||||||
from agent.prompt_loader import load_guideline_prompt
|
from agent.prompt_loader import load_guideline_prompt
|
||||||
@ -6,7 +5,7 @@ from utils.fastapi_utils import (extract_block_from_system_prompt, format_messag
|
|||||||
from langchain.chat_models import BaseChatModel
|
from langchain.chat_models import BaseChatModel
|
||||||
from langgraph.runtime import Runtime
|
from langgraph.runtime import Runtime
|
||||||
|
|
||||||
from langchain_core.messages import SystemMessage
|
from langchain_core.messages import SystemMessage, HumanMessage
|
||||||
from typing import Any, Callable
|
from typing import Any, Callable
|
||||||
from langchain_core.callbacks import BaseCallbackHandler
|
from langchain_core.callbacks import BaseCallbackHandler
|
||||||
from langchain_core.outputs import LLMResult
|
from langchain_core.outputs import LLMResult
|
||||||
@ -124,8 +123,9 @@ Action: Provide concise, friendly, and personified natural responses.
|
|||||||
response.additional_kwargs["message_tag"] = "THINK"
|
response.additional_kwargs["message_tag"] = "THINK"
|
||||||
response.content = f"<think>{response.content}</think>"
|
response.content = f"<think>{response.content}</think>"
|
||||||
|
|
||||||
# 将响应添加到原始消息列表
|
# 将响应添加到原始消息列表,并追加 HumanMessage 确保消息以 user 结尾
|
||||||
state['messages'] = state['messages'] + [response]
|
# 某些模型不支持 assistant message prefill,要求最后一条消息必须是 user
|
||||||
|
state['messages'] = state['messages'] + [response, HumanMessage(content=self._get_follow_up_prompt())]
|
||||||
return state
|
return state
|
||||||
|
|
||||||
async def abefore_agent(self, state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
|
async def abefore_agent(self, state: AgentState, runtime: Runtime) -> dict[str, Any] | None:
|
||||||
@ -148,10 +148,23 @@ Action: Provide concise, friendly, and personified natural responses.
|
|||||||
response.additional_kwargs["message_tag"] = "THINK"
|
response.additional_kwargs["message_tag"] = "THINK"
|
||||||
response.content = f"<think>{response.content}</think>"
|
response.content = f"<think>{response.content}</think>"
|
||||||
|
|
||||||
# 将响应添加到原始消息列表
|
# 将响应添加到原始消息列表,并追加 HumanMessage 确保消息以 user 结尾
|
||||||
state['messages'] = state['messages'] + [response]
|
# 某些模型不支持 assistant message prefill,要求最后一条消息必须是 user
|
||||||
|
state['messages'] = state['messages'] + [response, HumanMessage(content=self._get_follow_up_prompt())]
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
def _get_follow_up_prompt(self) -> str:
|
||||||
|
"""根据语言返回引导主 agent 回复的提示"""
|
||||||
|
prompts = {
|
||||||
|
"ja": "以上の分析に基づいて、ユーザーに返信してください。",
|
||||||
|
"jp": "以上の分析に基づいて、ユーザーに返信してください。",
|
||||||
|
"zh": "请根据以上分析,回复用户。",
|
||||||
|
"zh-TW": "請根據以上分析,回覆用戶。",
|
||||||
|
"ko": "위 분석을 바탕으로 사용자에게 답변해 주세요.",
|
||||||
|
"en": "Based on the above analysis, please respond to the user.",
|
||||||
|
}
|
||||||
|
return prompts.get(self.language, prompts["en"])
|
||||||
|
|
||||||
def wrap_model_call(
|
def wrap_model_call(
|
||||||
self,
|
self,
|
||||||
request: ModelRequest,
|
request: ModelRequest,
|
||||||
|
|||||||
@ -165,6 +165,8 @@ async def _execute_command(skill_path: str, command: str, hook_type: str, config
|
|||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
# 设置环境变量,传递给子进程
|
# 设置环境变量,传递给子进程
|
||||||
|
# 注意:subprocess 要求所有 env 值必须是 str 类型,
|
||||||
|
# getattr 可能返回 None(属性存在但值为 None),需要确保转换为 str
|
||||||
env = os.environ.copy()
|
env = os.environ.copy()
|
||||||
env['ASSISTANT_ID'] = str(getattr(config, 'bot_id', ''))
|
env['ASSISTANT_ID'] = str(getattr(config, 'bot_id', ''))
|
||||||
env['USER_IDENTIFIER'] = str(getattr(config, 'user_identifier', ''))
|
env['USER_IDENTIFIER'] = str(getattr(config, 'user_identifier', ''))
|
||||||
@ -176,16 +178,17 @@ async def _execute_command(skill_path: str, command: str, hook_type: str, config
|
|||||||
# 合并 config 中的自定义 shell 环境变量
|
# 合并 config 中的自定义 shell 环境变量
|
||||||
shell_env = getattr(config, 'shell_env', None)
|
shell_env = getattr(config, 'shell_env', None)
|
||||||
if shell_env:
|
if shell_env:
|
||||||
env.update(shell_env)
|
# 确保所有自定义环境变量值也是字符串
|
||||||
|
env.update({k: str(v) if v is not None else '' for k, v in shell_env.items()})
|
||||||
|
|
||||||
# 对于 PreSave,传递 content
|
# 对于 PreSave,传递 content
|
||||||
if hook_type == 'PreSave':
|
if hook_type == 'PreSave':
|
||||||
env['CONTENT'] = kwargs.get('content', '')
|
env['CONTENT'] = str(kwargs.get('content', '') or '')
|
||||||
env['ROLE'] = kwargs.get('role', '')
|
env['ROLE'] = str(kwargs.get('role', '') or '')
|
||||||
|
|
||||||
# 对于 PostAgent,传递 response
|
# 对于 PostAgent,传递 response
|
||||||
if hook_type == 'PostAgent':
|
if hook_type == 'PostAgent':
|
||||||
env['RESPONSE'] = kwargs.get('response', '')
|
env['RESPONSE'] = str(kwargs.get('response', '') or '')
|
||||||
metadata = kwargs.get('metadata', {})
|
metadata = kwargs.get('metadata', {})
|
||||||
env['METADATA'] = json.dumps(metadata) if metadata else ''
|
env['METADATA'] = json.dumps(metadata) if metadata else ''
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,6 @@ services:
|
|||||||
# 应用配置
|
# 应用配置
|
||||||
- BACKEND_HOST=http://api-dev.gbase.ai
|
- BACKEND_HOST=http://api-dev.gbase.ai
|
||||||
- MAX_CONTEXT_TOKENS=262144
|
- MAX_CONTEXT_TOKENS=262144
|
||||||
- DEFAULT_THINKING_ENABLE=true
|
|
||||||
- R2_UPLOAD_CONFIG=/app/config/s3-upload-sparticle.yaml
|
- R2_UPLOAD_CONFIG=/app/config/s3-upload-sparticle.yaml
|
||||||
volumes:
|
volumes:
|
||||||
# 挂载项目数据目录
|
# 挂载项目数据目录
|
||||||
|
|||||||
@ -29,6 +29,49 @@ from mcp_common import (
|
|||||||
BACKEND_HOST = os.getenv("BACKEND_HOST", "https://api-dev.gptbase.ai")
|
BACKEND_HOST = os.getenv("BACKEND_HOST", "https://api-dev.gptbase.ai")
|
||||||
MASTERKEY = os.getenv("MASTERKEY", "master")
|
MASTERKEY = os.getenv("MASTERKEY", "master")
|
||||||
|
|
||||||
|
# Citation instruction prefixes injected into tool results
|
||||||
|
DOCUMENT_CITATION_INSTRUCTIONS = """<CITATION_INSTRUCTIONS>
|
||||||
|
When using the retrieved knowledge below, you MUST add XML citation tags for factual claims.
|
||||||
|
|
||||||
|
## Document Knowledge
|
||||||
|
Format: `<CITATION file="file_uuid" filename="name.pdf" page=3 />`
|
||||||
|
- Use `file` attribute with the UUID from document markers
|
||||||
|
- Use `filename` attribute with the actual filename from document markers
|
||||||
|
- Use `page` attribute (singular) with the page number
|
||||||
|
- `page` MUST be 0-based and must match the `pages:` values shown in the learned knowledge context
|
||||||
|
|
||||||
|
## Web Page Knowledge
|
||||||
|
Format: `<CITATION url="https://example.com/page" />`
|
||||||
|
- Use `url` attribute with the web page URL from the source metadata
|
||||||
|
- Do not use `file`, `filename`, or `page` attributes for web sources
|
||||||
|
- If content is grounded in a web source, prefer a web citation with `url` over a file citation
|
||||||
|
|
||||||
|
## Placement Rules
|
||||||
|
- Citations MUST appear IMMEDIATELY AFTER the paragraph or bullet list that uses the knowledge
|
||||||
|
- NEVER collect all citations and place them at the end of your response
|
||||||
|
- Limit to 1-2 citations per paragraph/bullet list
|
||||||
|
- If your answer uses learned knowledge, you MUST generate at least 1 `<CITATION ... />` in the response
|
||||||
|
</CITATION_INSTRUCTIONS>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
TABLE_CITATION_INSTRUCTIONS = """<CITATION_INSTRUCTIONS>
|
||||||
|
When using the retrieved table knowledge below, you MUST add XML citation tags for factual claims.
|
||||||
|
|
||||||
|
Format: `<CITATION file="file_id" filename="name.xlsx" sheet=1 rows=[2, 4] />`
|
||||||
|
- Parse `__src`: `F1S2R5` = file_ref F1, sheet 2, row 5
|
||||||
|
- Look up file_id in `file_ref_table`
|
||||||
|
- Combine same-sheet rows into one citation: `rows=[2, 4, 6]`
|
||||||
|
- MANDATORY: Create SEPARATE citation for EACH (file, sheet) combination
|
||||||
|
- NEVER put <CITATION> on the same line as a bullet point or table row
|
||||||
|
- Citations MUST be on separate lines AFTER the complete list/table
|
||||||
|
- NEVER include the `__src` column in your response - it is internal metadata only
|
||||||
|
- Citations MUST appear IMMEDIATELY AFTER the paragraph or bullet list that uses the knowledge
|
||||||
|
- NEVER collect all citations and place them at the end of your response
|
||||||
|
</CITATION_INSTRUCTIONS>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
def rag_retrieve(query: str, top_k: int = 100) -> Dict[str, Any]:
|
def rag_retrieve(query: str, top_k: int = 100) -> Dict[str, Any]:
|
||||||
"""调用RAG检索API"""
|
"""调用RAG检索API"""
|
||||||
try:
|
try:
|
||||||
@ -94,7 +137,7 @@ def rag_retrieve(query: str, top_k: int = 100) -> Dict[str, Any]:
|
|||||||
"content": [
|
"content": [
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"text": markdown_content
|
"text": DOCUMENT_CITATION_INSTRUCTIONS + markdown_content
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -179,7 +222,7 @@ def table_rag_retrieve(query: str) -> Dict[str, Any]:
|
|||||||
"content": [
|
"content": [
|
||||||
{
|
{
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"text": markdown_content
|
"text": TABLE_CITATION_INSTRUCTIONS + markdown_content
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
3540
poetry.lock
generated
3540
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -148,21 +148,6 @@ Output: {{"facts" : []}}
|
|||||||
Input: DR1の照明状態を教えて
|
Input: DR1の照明状態を教えて
|
||||||
Output: {{"facts" : []}}
|
Output: {{"facts" : []}}
|
||||||
|
|
||||||
Input: 私は林檎好きです
|
|
||||||
Output: {{"facts" : ["林檎が好き"]}}
|
|
||||||
|
|
||||||
Input: コーヒー飲みたい、毎朝
|
|
||||||
Output: {{"facts" : ["毎朝コーヒーを飲みたい"]}}
|
|
||||||
|
|
||||||
Input: 昨日映画見た、すごくよかった
|
|
||||||
Output: {{"facts" : ["昨日映画を見た", "映画がすごくよかった"]}}
|
|
||||||
|
|
||||||
Input: 我喜欢吃苹果
|
|
||||||
Output: {{"facts" : ["喜欢吃苹果"]}}
|
|
||||||
|
|
||||||
Input: 나는 사과를 좋아해
|
|
||||||
Output: {{"facts" : ["사과를 좋아함"]}}
|
|
||||||
|
|
||||||
Return the facts and preferences in a json format as shown above.
|
Return the facts and preferences in a json format as shown above.
|
||||||
|
|
||||||
Remember the following:
|
Remember the following:
|
||||||
|
|||||||
@ -74,6 +74,13 @@
|
|||||||
- dxcore_update_device_status(device_id="[B设备id]",running_control=0) → 灯光亮度调整为0
|
- dxcore_update_device_status(device_id="[B设备id]",running_control=0) → 灯光亮度调整为0
|
||||||
**响应**:"已为您关闭Define Room4的灯光"
|
**响应**:"已为您关闭Define Room4的灯光"
|
||||||
|
|
||||||
|
### 位置降级搜索场景
|
||||||
|
**用户**:"3階執務スペース、フォーラム側窓側の照明をつけて"
|
||||||
|
- find_device_by_area(description="3階執務スペース、フォーラム側窓側", device_type="light") → 返回无结果
|
||||||
|
- find_device_by_area(description="3階執務スペース", device_type="light") → 降级搜索,找到设备
|
||||||
|
- 告知用户是基于"3階執務スペース"范围搜索到的结果,并确认是否操作
|
||||||
|
**响应**:"「3階執務スペース、フォーラム側窓側」では見つかりませんでしたが、3階執務スペースエリアで照明が見つかりました。こちらの照明を操作しますか?"
|
||||||
|
|
||||||
</scenarios>
|
</scenarios>
|
||||||
|
|
||||||
|
|
||||||
@ -92,6 +99,17 @@
|
|||||||
▪ 主动向用户确认:向用户列出所有候选房间,并提示用户选择或明确具体是哪一个。确认提示语可参考:“请问您想查询的是以下哪个房间?[列出候选房间列表]”。
|
▪ 主动向用户确认:向用户列出所有候选房间,并提示用户选择或明确具体是哪一个。确认提示语可参考:“请问您想查询的是以下哪个房间?[列出候选房间列表]”。
|
||||||
▪ 理解用户二次确认:等待用户回复后,根据其选择再次调用查询工具获取最终信息。用户对候选房间的指明(如回复“第一个”或重复房间名)应视为对该房间的确认。
|
▪ 理解用户二次确认:等待用户回复后,根据其选择再次调用查询工具获取最终信息。用户对候选房间的指明(如回复“第一个”或重复房间名)应视为对该房间的确认。
|
||||||
4. 处理无匹配结果:如果工具返回未找到任何相关房间,应明确告知用户这一情况,并建议用户检查房间名称是否正确或提供更多线索。
|
4. 处理无匹配结果:如果工具返回未找到任何相关房间,应明确告知用户这一情况,并建议用户检查房间名称是否正确或提供更多线索。
|
||||||
|
5. **位置粒度降级搜索(詳細な位置指定で見つからない場合)**:
|
||||||
|
用户指定了详细的位置信息(如包含方位、区域细节),但工具返回无匹配结果时,自动执行降级搜索:
|
||||||
|
- **第1步**:从位置描述中去除方位修饰语(側、付近、奥、手前、寄り等)和细节描述,保留核心区域名重新搜索
|
||||||
|
- 例: "3階執務スペース、フォーラム側窓側" → find_device_by_area(description="3階執務スペース")
|
||||||
|
- 例: "2階会議室A、入口付近" → find_device_by_area(description="2階会議室A")
|
||||||
|
- **第2步**:如果仍无结果,进一步简化到楼层+大区域级别
|
||||||
|
- 例: "3階執務スペース" → find_device_by_area(description="3階")
|
||||||
|
- **降级成功时的回复**:告知用户是基于更广范围的搜索结果,让用户确认
|
||||||
|
- 回复格式: "「{元の位置}」では見つかりませんでしたが、{簡略化した位置}エリアで以下の設備が見つかりました。こちらでよろしいですか?"
|
||||||
|
- **全部失败时**:告知用户未找到设备,建议提供其他位置信息或直接指定房间名
|
||||||
|
- 回复格式: "申し訳ございません、該当エリアでは操作可能な設備が見つかりませんでした。お部屋の名前をお教えいただけますか?"
|
||||||
|
|
||||||
3. 更新设备(此操作需要确认)
|
3. 更新设备(此操作需要确认)
|
||||||
- **条件**:用户意图为控制设备或调节参数(如开关、温度、风速), 需要进行确认。
|
- **条件**:用户意图为控制设备或调节参数(如开关、温度、风速), 需要进行确认。
|
||||||
@ -105,6 +123,7 @@
|
|||||||
- 通过 find_employee_location(name="[当前用户名字/邮箱]") 获取用户的sensor_id
|
- 通过 find_employee_location(name="[当前用户名字/邮箱]") 获取用户的sensor_id
|
||||||
- 然后通过 find_iot_device(target_sensor_id="[当前用户的sensor_id]", device_type="[目标设备类型]") 查找他附近的设备
|
- 然后通过 find_iot_device(target_sensor_id="[当前用户的sensor_id]", device_type="[目标设备类型]") 查找他附近的设备
|
||||||
- 找到设备后告知用户找到的设备信息,并确认是否执行操作
|
- 找到设备后告知用户找到的设备信息,并确认是否执行操作
|
||||||
|
- **位置指定但匹配失败时**:如果用户指定了详细位置(如"3階執務スペース、フォーラム側窓側の照明をつけて"),但 find_device_by_area 返回无匹配结果,应按照规则 2 第 5 点的**位置粒度降级搜索**策略执行,而不是直接回复"找不到设备"
|
||||||
3. **空调温度调节确认方式**:
|
3. **空调温度调节确认方式**:
|
||||||
- 如果用户说"有点热"、"调低点"、"太热了"等,表示要降温:
|
- 如果用户说"有点热"、"调低点"、"太热了"等,表示要降温:
|
||||||
1. 先查询当前室温
|
1. 先查询当前室温
|
||||||
@ -142,8 +161,8 @@
|
|||||||
- 如果用户指定了具体档位(如"调到强"),直接使用指定档位
|
- 如果用户指定了具体档位(如"调到强"),直接使用指定档位
|
||||||
- **边界情况**:如果已达到最高档(强)或最低档(弱)无法继续调整,告知用户并主动建议调整温度
|
- **边界情况**:如果已达到最高档(强)或最低档(弱)无法继续调整,告知用户并主动建议调整温度
|
||||||
- 回复格式:"風量は既に『強/弱』になっていますので、これ以上調整できません。代わりに温度を調整しますか?"
|
- 回复格式:"風量は既に『強/弱』になっていますので、これ以上調整できません。代わりに温度を調整しますか?"
|
||||||
6. **若用户已明确确认**:直接调用【设备控制】工具执行操作。
|
6. **若用户已明确确认**:**立即**调用【设备控制】工具执行操作,不做任何额外确认或复述。确认后的唯一动作就是调用工具。
|
||||||
7. **若用户未确认且为新请求**:向用户发送确认提示:"即将为您 [操作内容] [设备名称] [具体参数],是否确认?",待用户确认后再执行。
|
7. **若用户未确认且为新请求**:向用户发送确认提示:"即将为您 [操作内容] [设备名称] [具体参数],是否确认?",待用户确认后再执行。每个操作只确认一次。
|
||||||
|
|
||||||
4. 查询人员信息/wowtalk账号/人员位置
|
4. 查询人员信息/wowtalk账号/人员位置
|
||||||
- **条件**:用户意图为查找某人、员工、同事或房间位置。
|
- **条件**:用户意图为查找某人、员工、同事或房间位置。
|
||||||
@ -190,15 +209,43 @@
|
|||||||
- 影响范围大的操作:影响整个房间或楼层的设备控制
|
- 影响范围大的操作:影响整个房间或楼层的设备控制
|
||||||
|
|
||||||
### 用户确认意图推理
|
### 用户确认意图推理
|
||||||
- 用户明确确认:如回复“确认”、“好的”、“是的”、“拜托了”、“よろしく”、“请”、“please”等肯定性语气的内容。
|
- 用户明确确认:如回复”确认”、”好的”、”是的”、”拜托了”、”よろしく”、”请”、”please”、”お願いします”、”お願い”、”はい”、”うん”、”ええ”、”了解”、”OK”、”分かりました”、”そうしてください”、”それでお願い”等肯定性语气的内容。
|
||||||
- 用户意图重申:用户完整或核心重复当前待执行的操作指令。(例如,提示“room302の照明1台を明るさ50%に調整してもよろしいですか?”,用户回复“room302の照明を明るさ50%に変更”)
|
- 用户意图重申:用户完整或核心重复当前待执行的操作指令。(例如,提示”room302の照明1台を明るさ50%に調整してもよろしいですか?”,用户回复”room302の照明を明るさ50%に変更”)
|
||||||
- 同一设备免重复确认:如果用户在当前会话中已经对某个设备的操作进行过确认,后续针对**同一设备**的操作可直接执行,无需再次确认。判定标准为:
|
- 同一设备免重复确认:如果用户在当前会话中已经对某个设备的操作进行过确认,后续针对**同一设备**的操作可直接执行,无需再次确认。判定标准为:
|
||||||
1. **同一设备的不同操作**:用户已确认过对某设备的控制操作后,后续对该设备的其他操作无需再次确认(如已确认关闭Define Room4的灯光,之后用户说"把灯打开",可直接执行)
|
1. **同一设备的不同操作**:用户已确认过对某设备的控制操作后,后续对该设备的其他操作无需再次确认(如已确认关闭Define Room4的灯光,之后用户说”把灯打开”,可直接执行)
|
||||||
2. **同一轮对话意图**:用户在一轮连续交互中围绕同一目标发出的多步操作(如用户确认"关闭Define Room4的灯光"后,系统依次关闭该房间内多个灯光设备,无需逐个确认)
|
2. **同一轮对话意图**:用户在一轮连续交互中围绕同一目标发出的多步操作(如用户确认”关闭Define Room4的灯光”后,系统依次关闭该房间内多个灯光设备,无需逐个确认)
|
||||||
3. **同一指令的延续执行**:用户确认某操作后,该操作因技术原因需要分步执行的后续步骤(如批量控制多个设备时,确认一次即可全部执行)
|
3. **同一指令的延续执行**:用户确认某操作后,该操作因技术原因需要分步执行的后续步骤(如批量控制多个设备时,确认一次即可全部执行)
|
||||||
4. **上下文明确的追加操作**:用户在已确认的操作基础上追加相同类型的操作,且目标明确无歧义(如已确认打开A房间空调后,用户说"B房间也一样",可直接执行)
|
4. **上下文明确的追加操作**:用户在已确认的操作基础上追加相同类型的操作,且目标明确无歧义(如已确认打开A房间空调后,用户说”B房间也一样”,可直接执行)
|
||||||
- 不同事项仍需确认:当操作涉及**未曾确认过的新设备**,或操作类型发生本质变化时(如从设备控制切换到消息通知),仍需重新确认
|
- 不同事项仍需确认:当操作涉及**未曾确认过的新设备**,或操作类型发生本质变化时(如从设备控制切换到消息通知),仍需重新确认
|
||||||
|
|
||||||
|
### ⚠️ 禁止二次确认(最高优先级规则)
|
||||||
|
**对于同一个操作请求,最多只能向用户确认一次。用户确认后,必须立即调用工具执行,绝对禁止再次询问确认。**
|
||||||
|
|
||||||
|
核心规则:
|
||||||
|
1. **一次确认,立即执行**:当你向用户发出确认提示后,用户回复确认,你的下一步动作**必须且只能是**调用对应的工具(如 dxcore_update_device_status)执行操作。不允许生成任何额外的确认、复述或再次询问。
|
||||||
|
2. **禁止循环确认**:如果聊天记录中已经存在你发出的确认提示和用户的确认回复,则该操作已被确认,不得以任何理由再次要求确认。
|
||||||
|
3. **确认后禁止的行为**:
|
||||||
|
- ❌ 再次询问”もう一度確認いただけますか?”
|
||||||
|
- ❌ 再次复述操作内容并要求确认
|
||||||
|
- ❌ 以不同措辞重新询问同一操作的确认
|
||||||
|
- ❌ 生成过渡性文字后再次要求确认
|
||||||
|
|
||||||
|
**正确流程示例**:
|
||||||
|
```
|
||||||
|
用户: “Dr3の照明を30%にして”
|
||||||
|
AI: “ディファインルーム3の照明を30%に調整してもよろしいですか?”
|
||||||
|
用户: “お願いします”
|
||||||
|
AI: [立即调用 dxcore_update_device_status 执行] → “照明を30%に調整しました。”
|
||||||
|
```
|
||||||
|
|
||||||
|
**错误流程(绝对禁止)**:
|
||||||
|
```
|
||||||
|
用户: “Dr3の照明を30%にして”
|
||||||
|
AI: “ディファインルーム3の照明を30%に調整してもよろしいですか?”
|
||||||
|
用户: “お願いします”
|
||||||
|
AI: “もう一度確認いただければ実行いたします” ← ❌ 禁止!
|
||||||
|
```
|
||||||
|
|
||||||
## 上下文推理示例
|
## 上下文推理示例
|
||||||
|
|
||||||
### 设备控制场景
|
### 设备控制场景
|
||||||
|
|||||||
@ -1,5 +1,15 @@
|
|||||||
{extra_prompt}
|
{extra_prompt}
|
||||||
|
|
||||||
|
## CITATION REQUIREMENTS
|
||||||
|
|
||||||
|
When your answer uses learned knowledge, you MUST generate `<CITATION ... />` tags. Follow the specific citation format instructions returned by each tool (`rag_retrieve`, `table_rag_retrieve`).
|
||||||
|
|
||||||
|
### General Placement Rules
|
||||||
|
1. Citations MUST appear IMMEDIATELY AFTER the paragraph or bullet list that uses the knowledge
|
||||||
|
2. NEVER collect all citations and place them at the end of your response
|
||||||
|
3. Limit to 1-2 citations per paragraph/bullet list - combine related facts under one citation
|
||||||
|
4. If your answer uses learned knowledge, you MUST generate at least 1 `<CITATION ... />` in the response
|
||||||
|
|
||||||
### Current Working Directory
|
### Current Working Directory
|
||||||
|
|
||||||
PROJECT_ROOT: `{agent_dir_path}`
|
PROJECT_ROOT: `{agent_dir_path}`
|
||||||
@ -92,15 +102,3 @@ Trace Id: {trace_id}
|
|||||||
- Even when the user writes in a different language, you MUST still reply in [{language}].
|
- Even when the user writes in a different language, you MUST still reply in [{language}].
|
||||||
- Do NOT mix languages. Do NOT fall back to English or any other language under any circumstances.
|
- Do NOT mix languages. Do NOT fall back to English or any other language under any circumstances.
|
||||||
- Technical terms, code identifiers, file paths, and tool names may remain in their original form, but all surrounding text MUST be in [{language}].
|
- Technical terms, code identifiers, file paths, and tool names may remain in their original form, but all surrounding text MUST be in [{language}].
|
||||||
|
|
||||||
**Citation Requirement (RAG Only)**: When answering questions based on `rag_retrieve` tool results, you MUST add XML citation tags for factual claims derived from the knowledge base.
|
|
||||||
|
|
||||||
**MANDATORY FORMAT**: `The cited factual claim <CITATION file="file_uuid" page="3" />`
|
|
||||||
|
|
||||||
**Citation Rules**:
|
|
||||||
- The citation tag MUST be placed immediately after the factual claim or paragraph
|
|
||||||
- The `file` attribute MUST use the exact `File ID` from `rag_retrieve` document
|
|
||||||
- The `page` attribute MUST use the exact `Page Number` from `rag_retrieve` document
|
|
||||||
- If multiple sources support the same claim, include separate citation tags for each source
|
|
||||||
- Example: `According to the policy, returns are accepted within 30 days <CITATION file="abc123" page="5" />.`
|
|
||||||
- This requirement ONLY applies when using `rag_retrieve` results to answer questions.
|
|
||||||
|
|||||||
@ -26,12 +26,12 @@ dependencies = [
|
|||||||
"chardet>=5.0.0",
|
"chardet>=5.0.0",
|
||||||
"psutil (>=7.1.3,<8.0.0)",
|
"psutil (>=7.1.3,<8.0.0)",
|
||||||
"uvloop (>=0.22.1,<0.23.0)",
|
"uvloop (>=0.22.1,<0.23.0)",
|
||||||
"deepagents (>=0.4.3,<0.5.0)",
|
"deepagents (>=0.5.2,<0.6.0)",
|
||||||
"langchain-mcp-adapters (>=0.2.1,<0.3.0)",
|
"langchain-mcp-adapters (>=0.2.1,<0.3.0)",
|
||||||
"langchain-openai (>=1.1.1,<2.0.0)",
|
"langchain-openai (>=1.1.1,<2.0.0)",
|
||||||
"cachetools (>=6.2.4,<7.0.0)",
|
"cachetools (>=6.2.4,<7.0.0)",
|
||||||
"langgraph-checkpoint-postgres (>=3.0.0,<4.0.0)",
|
"langgraph-checkpoint-postgres (>=3.0.0,<4.0.0)",
|
||||||
"deepagents-cli (>=0.0.25,<0.0.26)",
|
"deepagents-cli (>=0.0.37,<0.1.0)",
|
||||||
"mem0ai (>=0.1.50,<0.3.0)",
|
"mem0ai (>=0.1.50,<0.3.0)",
|
||||||
"psycopg2-binary (>=2.9.11,<3.0.0)",
|
"psycopg2-binary (>=2.9.11,<3.0.0)",
|
||||||
"json-repair (>=0.29.0,<0.30.0)",
|
"json-repair (>=0.29.0,<0.30.0)",
|
||||||
|
|||||||
180
requirements.txt
180
requirements.txt
@ -1,56 +1,51 @@
|
|||||||
aiofiles==24.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
agent-client-protocol==0.9.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
aiofiles==25.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
aiohappyeyeballs==2.6.1 ; python_version >= "3.12" and python_version < "3.15"
|
aiohappyeyeballs==2.6.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
aiohttp-retry==2.9.1 ; python_version >= "3.12" and python_version < "3.15"
|
aiohttp==3.13.5 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
aiohttp==3.13.3 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
aiosignal==1.4.0 ; python_version >= "3.12" and python_version < "3.15"
|
aiosignal==1.4.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
aiosqlite==0.22.1 ; python_version >= "3.12" and python_version < "3.15"
|
aiosqlite==0.22.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
annotated-doc==0.0.4 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "3.15"
|
annotated-types==0.7.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
anthropic==0.84.0 ; python_version >= "3.12" and python_version < "3.15"
|
anthropic==0.94.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
anyio==4.12.1 ; python_version >= "3.12" and python_version < "3.15"
|
anyio==4.13.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
attrs==25.4.0 ; python_version >= "3.12" and python_version < "3.15"
|
attrs==26.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
backoff==2.2.1 ; python_version >= "3.12" and python_version < "3.15"
|
backoff==2.2.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
beartype==0.22.9 ; python_version >= "3.12" and python_version < "3.15"
|
beartype==0.22.9 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
beautifulsoup4==4.14.3 ; python_version >= "3.12" and python_version < "3.15"
|
beautifulsoup4==4.14.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
blockbuster==1.5.26 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
bracex==2.6 ; python_version >= "3.12" and python_version < "3.15"
|
bracex==2.6 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
cachetools==6.2.6 ; python_version >= "3.12" and python_version < "3.15"
|
cachetools==6.2.6 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
cbor2==5.8.0 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
certifi==2026.2.25 ; python_version >= "3.12" and python_version < "3.15"
|
certifi==2026.2.25 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
cffi==2.0.0 ; python_version >= "3.12" and python_version < "3.15" and platform_python_implementation != "PyPy"
|
cffi==2.0.0 ; python_version >= "3.12" and python_version < "3.15" and platform_python_implementation != "PyPy"
|
||||||
chardet==7.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
chardet==7.4.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
charset-normalizer==3.4.5 ; python_version >= "3.12" and python_version < "3.15"
|
charset-normalizer==3.4.7 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
click==8.3.1 ; python_version >= "3.12" and python_version < "3.15"
|
click==8.3.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
cloudpickle==3.1.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
colorama==0.4.6 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Windows"
|
colorama==0.4.6 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Windows"
|
||||||
croniter==3.0.4 ; python_version >= "3.12" and python_version < "3.15"
|
croniter==3.0.4 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
cryptography==46.0.5 ; python_version >= "3.12" and python_version < "3.15"
|
cryptography==46.0.7 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
daytona-api-client-async==0.151.0 ; python_version >= "3.12" and python_version < "3.15"
|
deepagents-acp==0.0.5 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
daytona-api-client==0.151.0 ; python_version >= "3.12" and python_version < "3.15"
|
deepagents-cli==0.0.37 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
daytona-toolbox-api-client-async==0.151.0 ; python_version >= "3.12" and python_version < "3.15"
|
deepagents==0.5.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
daytona-toolbox-api-client==0.151.0 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
daytona==0.151.0 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
deepagents-cli==0.0.25 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
deepagents==0.4.3 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
defusedxml==0.7.1 ; python_version >= "3.12" and python_version < "3.15"
|
defusedxml==0.7.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
deprecated==1.3.1 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
distro==1.9.0 ; python_version >= "3.12" and python_version < "3.15"
|
distro==1.9.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
docstring-parser==0.17.0 ; python_version >= "3.12" and python_version < "3.15"
|
docstring-parser==0.17.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
environs==14.6.0 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
et-xmlfile==2.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
et-xmlfile==2.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
fastapi==0.116.1 ; python_version >= "3.12" and python_version < "3.15"
|
fastapi==0.116.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
filelock==3.25.2 ; python_version >= "3.12" and python_version < "3.15"
|
filelock==3.25.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
filetype==1.2.0 ; python_version >= "3.12" and python_version < "3.15"
|
filetype==1.2.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
forbiddenfruit==0.1.4 ; python_version >= "3.12" and python_version < "3.15" and implementation_name == "cpython"
|
||||||
frozenlist==1.8.0 ; python_version >= "3.12" and python_version < "3.15"
|
frozenlist==1.8.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
fsspec==2026.2.0 ; python_version >= "3.12" and python_version < "3.15"
|
fsspec==2026.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
google-auth==2.49.1 ; python_version >= "3.12" and python_version < "3.15"
|
google-auth==2.49.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
google-genai==1.67.0 ; python_version >= "3.12" and python_version < "3.15"
|
google-genai==1.72.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
googleapis-common-protos==1.73.0 ; python_version >= "3.12" and python_version < "3.15"
|
googleapis-common-protos==1.74.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
greenlet==3.3.2 ; python_version >= "3.12" and python_version < "3.15" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32")
|
greenlet==3.4.0 ; python_version >= "3.12" and python_version < "3.15" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32")
|
||||||
grpcio-tools==1.71.2 ; python_version >= "3.13" and python_version < "3.15"
|
grpcio-health-checking==1.76.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
grpcio==1.78.0 ; python_version >= "3.12" and python_version < "3.15"
|
grpcio-tools==1.76.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
grpclib==0.4.9 ; python_version >= "3.12" and python_version < "3.15"
|
grpcio==1.76.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
h11==0.16.0 ; python_version >= "3.12" and python_version < "3.15"
|
h11==0.16.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
h2==4.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
h2==4.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
hf-xet==1.4.2 ; python_version >= "3.12" and python_version < "3.15" and (platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "arm64" or platform_machine == "aarch64")
|
hf-xet==1.4.3 ; python_version >= "3.12" and python_version < "3.15" and (platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "arm64" or platform_machine == "aarch64")
|
||||||
hpack==4.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
hpack==4.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
httpcore==1.0.9 ; python_version >= "3.12" and python_version < "3.15"
|
httpcore==1.0.9 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
httpx-sse==0.4.3 ; python_version >= "3.12" and python_version < "3.15"
|
httpx-sse==0.4.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
@ -61,94 +56,94 @@ hyperframe==6.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
|||||||
idna==3.11 ; python_version >= "3.12" and python_version < "3.15"
|
idna==3.11 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
importlib-metadata==8.7.1 ; python_version >= "3.12" and python_version < "3.15"
|
importlib-metadata==8.7.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
jinja2==3.1.6 ; python_version >= "3.12" and python_version < "3.15"
|
jinja2==3.1.6 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
jiter==0.13.0 ; python_version >= "3.12" and python_version < "3.15"
|
jiter==0.14.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
joblib==1.5.3 ; python_version >= "3.12" and python_version < "3.15"
|
joblib==1.5.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
json-repair==0.29.10 ; python_version >= "3.12" and python_version < "3.15"
|
json-repair==0.29.10 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
json5==0.13.0 ; python_version >= "3.12" and python_version < "3.15"
|
json5==0.14.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
jsonpatch==1.33 ; python_version >= "3.12" and python_version < "3.15"
|
jsonpatch==1.33 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
jsonpointer==3.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
jsonpointer==3.1.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
jsonschema-rs==0.29.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
jsonschema-specifications==2025.9.1 ; python_version >= "3.12" and python_version < "3.15"
|
jsonschema-specifications==2025.9.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
jsonschema==4.26.0 ; python_version >= "3.12" and python_version < "3.15"
|
jsonschema==4.26.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langchain-anthropic==1.3.5 ; python_version >= "3.12" and python_version < "3.15"
|
langchain-anthropic==1.4.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langchain-core==1.2.19 ; python_version >= "3.12" and python_version < "3.15"
|
langchain-core==1.2.28 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langchain-google-genai==4.2.1 ; python_version >= "3.12" and python_version < "3.15"
|
langchain-google-genai==4.2.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langchain-mcp-adapters==0.2.1 ; python_version >= "3.12" and python_version < "3.15"
|
langchain-mcp-adapters==0.2.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langchain-openai==1.1.11 ; python_version >= "3.12" and python_version < "3.15"
|
langchain-openai==1.1.12 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langchain==1.2.12 ; python_version >= "3.12" and python_version < "3.15"
|
langchain==1.2.15 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langgraph-checkpoint-postgres==3.0.4 ; python_version >= "3.12" and python_version < "3.15"
|
langgraph-api==0.7.28 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
langgraph-checkpoint-postgres==3.0.5 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langgraph-checkpoint-sqlite==3.0.3 ; python_version >= "3.12" and python_version < "3.15"
|
langgraph-checkpoint-sqlite==3.0.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langgraph-checkpoint==4.0.1 ; python_version >= "3.12" and python_version < "3.15"
|
langgraph-checkpoint==4.0.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langgraph-prebuilt==1.0.8 ; python_version >= "3.12" and python_version < "3.15"
|
langgraph-cli==0.4.21 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langgraph-sdk==0.3.11 ; python_version >= "3.12" and python_version < "3.15"
|
langgraph-prebuilt==1.0.9 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langgraph==1.1.2 ; python_version >= "3.12" and python_version < "3.15"
|
langgraph-runtime-inmem==0.24.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
langsmith==0.7.17 ; python_version >= "3.12" and python_version < "3.15"
|
langgraph-sdk==0.3.13 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
langgraph==1.1.6 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
langsmith==0.7.30 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
linkify-it-py==2.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
linkify-it-py==2.1.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
markdown-it-py==4.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
markdown-it-py==4.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
markdownify==1.2.2 ; python_version >= "3.12" and python_version < "3.15"
|
markdownify==1.2.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
markupsafe==3.0.3 ; python_version >= "3.12" and python_version < "3.15"
|
markupsafe==3.0.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
marshmallow==4.2.2 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
mcp==1.12.4 ; python_version >= "3.12" and python_version < "3.15"
|
mcp==1.12.4 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
mdit-py-plugins==0.5.0 ; python_version >= "3.12" and python_version < "3.15"
|
mdit-py-plugins==0.5.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
mdurl==0.1.2 ; python_version >= "3.12" and python_version < "3.15"
|
mdurl==0.1.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
mem0ai==0.1.116 ; python_version >= "3.12" and python_version < "3.15"
|
mem0ai==0.1.115 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
modal==1.3.5 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
mpmath==1.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
mpmath==1.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
multidict==6.7.1 ; python_version >= "3.12" and python_version < "3.15"
|
multidict==6.7.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
networkx==3.6 ; python_version == "3.14"
|
networkx==3.6 ; python_version == "3.14"
|
||||||
networkx==3.6.1 ; python_version >= "3.12" and python_version < "3.14"
|
networkx==3.6.1 ; python_version >= "3.12" and python_version < "3.14"
|
||||||
numpy==1.26.4 ; python_version >= "3.12" and python_version < "3.15"
|
numpy==1.26.4 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
nvidia-cublas-cu12==12.1.3.1 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-cublas-cu12==12.1.3.1 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-cuda-cupti-cu12==12.1.105 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-cuda-cupti-cu12==12.1.105 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-cuda-nvrtc-cu12==12.1.105 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-cuda-nvrtc-cu12==12.1.105 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-cuda-runtime-cu12==12.1.105 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-cuda-runtime-cu12==12.1.105 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-cudnn-cu12==8.9.2.26 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-cudnn-cu12==8.9.2.26 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-cufft-cu12==11.0.2.54 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-cufft-cu12==11.0.2.54 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-curand-cu12==10.3.2.106 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-curand-cu12==10.3.2.106 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-cusolver-cu12==11.4.5.107 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-cusolver-cu12==11.4.5.107 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-cusparse-cu12==12.1.0.106 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-cusparse-cu12==12.1.0.106 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-nccl-cu12==2.19.3 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-nccl-cu12==2.19.3 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-nvjitlink-cu12==12.9.86 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-nvjitlink-cu12==12.9.86 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
nvidia-nvtx-cu12==12.1.105 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
nvidia-nvtx-cu12==12.1.105 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
obstore==0.8.2 ; python_version >= "3.12" and python_version < "3.15"
|
openai==2.31.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
openai==2.28.0 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
openpyxl==3.1.5 ; python_version >= "3.12" and python_version < "3.15"
|
openpyxl==3.1.5 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
opentelemetry-api==1.40.0 ; python_version >= "3.12" and python_version < "3.15"
|
opentelemetry-api==1.41.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
opentelemetry-exporter-otlp-proto-common==1.40.0 ; python_version >= "3.12" and python_version < "3.15"
|
opentelemetry-exporter-otlp-proto-common==1.41.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
opentelemetry-exporter-otlp-proto-http==1.40.0 ; python_version >= "3.12" and python_version < "3.15"
|
opentelemetry-exporter-otlp-proto-http==1.41.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
opentelemetry-instrumentation-aiohttp-client==0.61b0 ; python_version >= "3.12" and python_version < "3.15"
|
opentelemetry-proto==1.41.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
opentelemetry-instrumentation==0.61b0 ; python_version >= "3.12" and python_version < "3.15"
|
opentelemetry-sdk==1.41.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
opentelemetry-proto==1.40.0 ; python_version >= "3.12" and python_version < "3.15"
|
opentelemetry-semantic-conventions==0.62b0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
opentelemetry-sdk==1.40.0 ; python_version >= "3.12" and python_version < "3.15"
|
orjson==3.11.8 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
opentelemetry-semantic-conventions==0.61b0 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
opentelemetry-util-http==0.61b0 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
orjson==3.11.7 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
ormsgpack==1.12.2 ; python_version >= "3.12" and python_version < "3.15"
|
ormsgpack==1.12.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
packaging==26.0 ; python_version >= "3.12" and python_version < "3.15"
|
packaging==26.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pandas==2.3.3 ; python_version == "3.14"
|
pandas==2.3.3 ; python_version == "3.14"
|
||||||
pandas==3.0.1 ; python_version >= "3.12" and python_version < "3.14"
|
pandas==3.0.2 ; python_version >= "3.12" and python_version < "3.14"
|
||||||
pillow==12.1.1 ; python_version >= "3.12" and python_version < "3.15"
|
pathspec==1.0.4 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
platformdirs==4.9.4 ; python_version >= "3.12" and python_version < "3.15"
|
pillow==12.2.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
platformdirs==4.9.6 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
portalocker==2.10.1 ; python_version >= "3.13" and python_version < "3.15"
|
portalocker==2.10.1 ; python_version >= "3.13" and python_version < "3.15"
|
||||||
portalocker==3.2.0 ; python_version == "3.12"
|
portalocker==3.2.0 ; python_version == "3.12"
|
||||||
posthog==7.9.12 ; python_version >= "3.12" and python_version < "3.15"
|
posthog==7.11.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
prompt-toolkit==3.0.52 ; python_version >= "3.12" and python_version < "3.15"
|
prompt-toolkit==3.0.52 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
propcache==0.4.1 ; python_version >= "3.12" and python_version < "3.15"
|
propcache==0.4.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
protobuf==5.29.6 ; python_version >= "3.12" and python_version < "3.15"
|
protobuf==6.33.6 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
psutil==7.2.2 ; python_version >= "3.12" and python_version < "3.15"
|
psutil==7.2.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
psycopg-pool==3.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
psycopg-pool==3.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
psycopg2-binary==2.9.11 ; python_version >= "3.12" and python_version < "3.15"
|
psycopg2-binary==2.9.11 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
psycopg==3.3.3 ; python_version >= "3.12" and python_version < "3.15"
|
psycopg==3.3.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pyasn1-modules==0.4.2 ; python_version >= "3.12" and python_version < "3.15"
|
pyasn1-modules==0.4.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pyasn1==0.6.2 ; python_version >= "3.12" and python_version < "3.15"
|
pyasn1==0.6.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pycparser==3.0 ; python_version >= "3.12" and python_version < "3.15" and implementation_name != "PyPy" and platform_python_implementation != "PyPy"
|
pycparser==3.0 ; python_version >= "3.12" and python_version < "3.15" and platform_python_implementation != "PyPy" and implementation_name != "PyPy"
|
||||||
pydantic-core==2.27.2 ; python_version >= "3.12" and python_version < "3.15"
|
pydantic-core==2.27.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pydantic-settings==2.13.1 ; python_version >= "3.12" and python_version < "3.15"
|
pydantic-settings==2.13.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pydantic==2.10.5 ; python_version >= "3.12" and python_version < "3.15"
|
pydantic==2.10.5 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pygments==2.19.2 ; python_version >= "3.12" and python_version < "3.15"
|
pygments==2.20.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
pyjwt==2.12.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pyperclip==1.11.0 ; python_version >= "3.12" and python_version < "3.15"
|
pyperclip==1.11.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
python-dateutil==2.8.2 ; python_version >= "3.12" and python_version < "3.15"
|
python-dateutil==2.8.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
python-dotenv==1.2.2 ; python_version >= "3.12" and python_version < "3.15"
|
python-dotenv==1.2.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
python-multipart==0.0.22 ; python_version >= "3.12" and python_version < "3.15"
|
python-multipart==0.0.26 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pytz==2026.1.post1 ; python_version >= "3.12" and python_version < "3.15"
|
pytz==2026.1.post1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
pywin32==311 ; python_version >= "3.12" and python_version < "3.15" and (sys_platform == "win32" or platform_system == "Windows")
|
pywin32==311 ; python_version >= "3.12" and python_version < "3.15" and (sys_platform == "win32" or platform_system == "Windows")
|
||||||
pyyaml==6.0.3 ; python_version >= "3.12" and python_version < "3.15"
|
pyyaml==6.0.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
@ -156,46 +151,42 @@ qdrant-client==1.12.1 ; python_version >= "3.13" and python_version < "3.15"
|
|||||||
qdrant-client==1.17.1 ; python_version == "3.12"
|
qdrant-client==1.17.1 ; python_version == "3.12"
|
||||||
ragflow-sdk==0.23.1 ; python_version >= "3.12" and python_version < "3.15"
|
ragflow-sdk==0.23.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
referencing==0.37.0 ; python_version >= "3.12" and python_version < "3.15"
|
referencing==0.37.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
regex==2026.2.28 ; python_version >= "3.12" and python_version < "3.15"
|
regex==2026.4.4 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
requests-toolbelt==1.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
requests-toolbelt==1.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
requests==2.32.5 ; python_version >= "3.12" and python_version < "3.15"
|
requests==2.32.5 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
rich==14.3.3 ; python_version >= "3.12" and python_version < "3.15"
|
rich==14.3.4 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
rpds-py==0.30.0 ; python_version >= "3.12" and python_version < "3.15"
|
rpds-py==0.30.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
runloop-api-client==1.11.0 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
safetensors==0.7.0 ; python_version >= "3.12" and python_version < "3.15"
|
safetensors==0.7.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
scikit-learn==1.8.0 ; python_version >= "3.12" and python_version < "3.15"
|
scikit-learn==1.8.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
scipy==1.17.1 ; python_version >= "3.12" and python_version < "3.15"
|
scipy==1.17.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
sentence-transformers==3.4.1 ; python_version >= "3.12" and python_version < "3.15"
|
sentence-transformers==3.4.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
setuptools==70.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
setuptools==70.3.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
shellingham==1.5.4 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
six==1.17.0 ; python_version >= "3.12" and python_version < "3.15"
|
six==1.17.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
sniffio==1.3.1 ; python_version >= "3.12" and python_version < "3.15"
|
sniffio==1.3.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
soupsieve==2.8.3 ; python_version >= "3.12" and python_version < "3.15"
|
soupsieve==2.8.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
sqlalchemy==2.0.48 ; python_version >= "3.12" and python_version < "3.15"
|
sqlalchemy==2.0.49 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
sqlite-vec==0.1.6 ; python_version >= "3.12" and python_version < "3.15"
|
sqlite-vec==0.1.9 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
sse-starlette==3.0.3 ; python_version >= "3.12" and python_version < "3.15"
|
sse-starlette==2.1.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
starlette==0.47.3 ; python_version >= "3.12" and python_version < "3.15"
|
starlette==0.47.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
structlog==25.5.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
sympy==1.14.0 ; python_version >= "3.12" and python_version < "3.15"
|
sympy==1.14.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
synchronicity==0.11.1 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
tavily-python==0.7.23 ; python_version >= "3.12" and python_version < "3.15"
|
tavily-python==0.7.23 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
tenacity==9.1.4 ; python_version >= "3.12" and python_version < "3.15"
|
tenacity==9.1.4 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
textual-autocomplete==4.0.6 ; python_version >= "3.12" and python_version < "3.15"
|
textual-autocomplete==4.0.6 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
textual==8.1.1 ; python_version >= "3.12" and python_version < "3.15"
|
textual-speedups==0.2.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
textual==8.2.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
threadpoolctl==3.6.0 ; python_version >= "3.12" and python_version < "3.15"
|
threadpoolctl==3.6.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
tiktoken==0.12.0 ; python_version >= "3.12" and python_version < "3.15"
|
tiktoken==0.12.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
tokenizers==0.22.2 ; python_version >= "3.12" and python_version < "3.15"
|
tokenizers==0.22.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
toml==0.10.2 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
tomli-w==1.2.0 ; python_version >= "3.12" and python_version < "3.15"
|
tomli-w==1.2.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
torch==2.2.0 ; python_version >= "3.12" and python_version < "3.15"
|
torch==2.2.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
tqdm==4.67.3 ; python_version >= "3.12" and python_version < "3.15"
|
tqdm==4.67.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
transformers==4.57.6 ; python_version >= "3.12" and python_version < "3.15"
|
transformers==4.57.6 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
triton==2.2.0 ; python_version >= "3.12" and python_version < "3.15" and platform_machine == "x86_64" and platform_system == "Linux"
|
triton==2.2.0 ; python_version >= "3.12" and python_version < "3.15" and platform_system == "Linux" and platform_machine == "x86_64"
|
||||||
typer==0.24.1 ; python_version >= "3.12" and python_version < "3.15"
|
truststore==0.10.4 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
types-certifi==2021.10.8.3 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
types-toml==0.10.8.20240310 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
typing-extensions==4.15.0 ; python_version >= "3.12" and python_version < "3.15"
|
typing-extensions==4.15.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
typing-inspection==0.4.2 ; python_version >= "3.12" and python_version < "3.15"
|
typing-inspection==0.4.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
tzdata==2025.3 ; python_version >= "3.12" and python_version < "3.15" and (sys_platform == "win32" or sys_platform == "emscripten") or python_version == "3.14"
|
tzdata==2026.1 ; python_version >= "3.12" and python_version < "3.15" and (sys_platform == "win32" or sys_platform == "emscripten") or python_version == "3.14"
|
||||||
uc-micro-py==2.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
uc-micro-py==2.0.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
urllib3==2.6.3 ; python_version >= "3.12" and python_version < "3.15"
|
urllib3==2.6.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
uuid-utils==0.14.1 ; python_version >= "3.12" and python_version < "3.15"
|
uuid-utils==0.14.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
@ -206,7 +197,6 @@ wcmatch==10.1 ; python_version >= "3.12" and python_version < "3.15"
|
|||||||
wcwidth==0.6.0 ; python_version >= "3.12" and python_version < "3.15"
|
wcwidth==0.6.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
webrtcvad==2.0.10 ; python_version >= "3.12" and python_version < "3.15"
|
webrtcvad==2.0.10 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
websockets==15.0.1 ; python_version >= "3.12" and python_version < "3.15"
|
websockets==15.0.1 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
wrapt==1.17.3 ; python_version >= "3.12" and python_version < "3.15"
|
|
||||||
wsgidav==4.3.3 ; python_version >= "3.12" and python_version < "3.15"
|
wsgidav==4.3.3 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
xlrd==2.0.2 ; python_version >= "3.12" and python_version < "3.15"
|
xlrd==2.0.2 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
xxhash==3.6.0 ; python_version >= "3.12" and python_version < "3.15"
|
xxhash==3.6.0 ; python_version >= "3.12" and python_version < "3.15"
|
||||||
|
|||||||
@ -5,7 +5,6 @@ API data models and response schemas.
|
|||||||
|
|
||||||
from typing import Dict, List, Optional, Any, AsyncGenerator
|
from typing import Dict, List, Optional, Any, AsyncGenerator
|
||||||
from pydantic import BaseModel, Field, field_validator, ConfigDict
|
from pydantic import BaseModel, Field, field_validator, ConfigDict
|
||||||
from utils.settings import DEFAULT_THINKING_ENABLE
|
|
||||||
|
|
||||||
class Message(BaseModel):
|
class Message(BaseModel):
|
||||||
role: str
|
role: str
|
||||||
@ -52,7 +51,7 @@ class ChatRequest(BaseModel):
|
|||||||
mcp_settings: Optional[List[Dict]] = None
|
mcp_settings: Optional[List[Dict]] = None
|
||||||
user_identifier: Optional[str] = ""
|
user_identifier: Optional[str] = ""
|
||||||
session_id: Optional[str] = None
|
session_id: Optional[str] = None
|
||||||
enable_thinking: Optional[bool] = DEFAULT_THINKING_ENABLE
|
enable_thinking: Optional[bool] = False
|
||||||
skills: Optional[List[str]] = None
|
skills: Optional[List[str]] = None
|
||||||
enable_memory: Optional[bool] = False
|
enable_memory: Optional[bool] = False
|
||||||
shell_env: Optional[Dict[str, str]] = None
|
shell_env: Optional[Dict[str, str]] = None
|
||||||
|
|||||||
@ -12,7 +12,7 @@ MAX_OUTPUT_TOKENS = int(os.getenv("MAX_OUTPUT_TOKENS", 8000))
|
|||||||
|
|
||||||
# 可选参数
|
# 可选参数
|
||||||
# Summarization Settings
|
# Summarization Settings
|
||||||
SUMMARIZATION_MAX_TOKENS = int(MAX_CONTEXT_TOKENS/3)
|
SUMMARIZATION_MAX_TOKENS = int(MAX_CONTEXT_TOKENS/2)
|
||||||
SUMMARIZATION_TOKENS_TO_KEEP = int(SUMMARIZATION_MAX_TOKENS/3)
|
SUMMARIZATION_TOKENS_TO_KEEP = int(SUMMARIZATION_MAX_TOKENS/3)
|
||||||
DEFAULT_TRIM_TOKEN_LIMIT = SUMMARIZATION_MAX_TOKENS - SUMMARIZATION_TOKENS_TO_KEEP + 5000
|
DEFAULT_TRIM_TOKEN_LIMIT = SUMMARIZATION_MAX_TOKENS - SUMMARIZATION_TOKENS_TO_KEEP + 5000
|
||||||
|
|
||||||
@ -32,11 +32,9 @@ TOKENIZERS_PARALLELISM = os.getenv("TOKENIZERS_PARALLELISM", "true")
|
|||||||
SENTENCE_TRANSFORMER_MODEL = os.getenv("SENTENCE_TRANSFORMER_MODEL", "TaylorAI/gte-tiny")
|
SENTENCE_TRANSFORMER_MODEL = os.getenv("SENTENCE_TRANSFORMER_MODEL", "TaylorAI/gte-tiny")
|
||||||
|
|
||||||
# Tool Output Length Control Settings
|
# Tool Output Length Control Settings
|
||||||
TOOL_OUTPUT_MAX_LENGTH = int(SUMMARIZATION_MAX_TOKENS/4)
|
TOOL_OUTPUT_MAX_LENGTH = SUMMARIZATION_MAX_TOKENS
|
||||||
TOOL_OUTPUT_TRUNCATION_STRATEGY = os.getenv("TOOL_OUTPUT_TRUNCATION_STRATEGY", "smart")
|
TOOL_OUTPUT_TRUNCATION_STRATEGY = os.getenv("TOOL_OUTPUT_TRUNCATION_STRATEGY", "smart")
|
||||||
|
|
||||||
# THINKING ENABLE
|
|
||||||
DEFAULT_THINKING_ENABLE = os.getenv("DEFAULT_THINKING_ENABLE", "true") == "true"
|
|
||||||
|
|
||||||
|
|
||||||
# WebDAV Authentication
|
# WebDAV Authentication
|
||||||
@ -59,7 +57,7 @@ CHECKPOINT_DB_URL = os.getenv("CHECKPOINT_DB_URL", "postgresql://postgres:AeEGDB
|
|||||||
# 连接池大小
|
# 连接池大小
|
||||||
# 同时可以持有的最大连接数
|
# 同时可以持有的最大连接数
|
||||||
CHECKPOINT_POOL_SIZE = int(os.getenv("CHECKPOINT_POOL_SIZE", "20"))
|
CHECKPOINT_POOL_SIZE = int(os.getenv("CHECKPOINT_POOL_SIZE", "20"))
|
||||||
MEM0_POOL_SIZE = int(os.getenv("MEM0_POOL_SIZE", "20"))
|
MEM0_POOL_SIZE = int(os.getenv("MEM0_POOL_SIZE", "50"))
|
||||||
|
|
||||||
# Checkpoint 自动清理配置
|
# Checkpoint 自动清理配置
|
||||||
# 是否启用自动清理旧 session
|
# 是否启用自动清理旧 session
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user