style(format): format
This commit is contained in:
parent
f4090ede9d
commit
88b6b27465
@ -2,8 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from deepagents.backends.protocol import BackendProtocol, EditResult, WriteResult
|
||||
from deepagents.backends.utils import FileInfo, GrepMatch
|
||||
@ -29,7 +28,7 @@ class MinIOBackend(BackendProtocol):
|
||||
def __init__(
|
||||
self,
|
||||
bucket_name: str = "chat-attachments",
|
||||
minio_client: Optional[MinIOClient] = None,
|
||||
minio_client: MinIOClient | None = None,
|
||||
):
|
||||
self.bucket_name = bucket_name
|
||||
self._client = minio_client
|
||||
@ -51,7 +50,7 @@ class MinIOBackend(BackendProtocol):
|
||||
"""
|
||||
return path.lstrip("/")
|
||||
|
||||
def _parse_path(self, path: str) -> tuple[Optional[str], Optional[str]]:
|
||||
def _parse_path(self, path: str) -> tuple[str | None, str | None]:
|
||||
"""解析路径,提取 thread_id 和 filename。
|
||||
|
||||
支持两种格式:
|
||||
@ -203,7 +202,7 @@ class MinIOBackend(BackendProtocol):
|
||||
# 添加行号
|
||||
start = max(0, offset)
|
||||
end = start + limit
|
||||
numbered_lines = [f"{i+1}:{line}" for i, line in enumerate(lines[start:end], start + 1)]
|
||||
numbered_lines = [f"{i + 1}:{line}" for i, line in enumerate(lines[start:end], start + 1)]
|
||||
return "\n".join(numbered_lines)
|
||||
except Exception as e:
|
||||
logger.error(f"MinIOBackend.read failed for {file_path}: {e}")
|
||||
@ -288,8 +287,8 @@ class MinIOBackend(BackendProtocol):
|
||||
def grep_raw(
|
||||
self,
|
||||
pattern: str,
|
||||
path: Optional[str] = None,
|
||||
glob: Optional[str] = None,
|
||||
path: str | None = None,
|
||||
glob: str | None = None,
|
||||
) -> list[GrepMatch] | str:
|
||||
"""搜索文件内容。
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ class AttachmentMiddleware(AgentMiddleware[AttachmentState]):
|
||||
# 尝试从输入中获取 attachments(LangGraph 会将输入 state 合并)
|
||||
if not attachments:
|
||||
# 检查是否有其他方式传递的附件
|
||||
logger.info(f"AttachmentMiddleware: checking for attachments in other locations...")
|
||||
logger.info("AttachmentMiddleware: checking for attachments in other locations...")
|
||||
# 输入可能直接在 state 中
|
||||
logger.info(f"AttachmentMiddleware: state type = {type(request.state)}")
|
||||
|
||||
@ -97,21 +97,23 @@ class AttachmentMiddleware(AgentMiddleware[AttachmentState]):
|
||||
thread_id = None
|
||||
|
||||
# 0. 尝试从 request.runtime 获取(LangChain runtime)
|
||||
if hasattr(request, 'runtime') and request.runtime:
|
||||
if hasattr(request, "runtime") and request.runtime:
|
||||
runtime = request.runtime
|
||||
logger.info(f"AttachmentMiddleware: runtime type = {type(runtime)}")
|
||||
logger.info(f"AttachmentMiddleware: runtime attrs = {[a for a in dir(runtime) if not a.startswith('_')]}")
|
||||
logger.info(
|
||||
f"AttachmentMiddleware: runtime attrs = {[a for a in dir(runtime) if not a.startswith('_')]}"
|
||||
)
|
||||
|
||||
# 检查 runtime.context
|
||||
if hasattr(runtime, 'context') and runtime.context:
|
||||
if hasattr(runtime, "context") and runtime.context:
|
||||
ctx = runtime.context
|
||||
logger.info(f"AttachmentMiddleware: runtime.context type = {type(ctx)}")
|
||||
# 如果是 Pydantic 模型,使用 model_dump()
|
||||
if hasattr(ctx, 'model_dump'):
|
||||
if hasattr(ctx, "model_dump"):
|
||||
ctx_dict = ctx.model_dump()
|
||||
logger.info(f"AttachmentMiddleware: runtime.context keys = {list(ctx_dict.keys())}")
|
||||
thread_id = ctx_dict.get("thread_id")
|
||||
elif hasattr(ctx, '__dict__'):
|
||||
elif hasattr(ctx, "__dict__"):
|
||||
logger.info(f"AttachmentMiddleware: runtime.context __dict__ = {ctx.__dict__}")
|
||||
thread_id = ctx.__dict__.get("thread_id")
|
||||
elif isinstance(ctx, dict):
|
||||
@ -120,13 +122,13 @@ class AttachmentMiddleware(AgentMiddleware[AttachmentState]):
|
||||
|
||||
# 如果还没有 thread_id,检查 runtime 其他属性
|
||||
if not thread_id:
|
||||
for attr in ['state', 'config', 'configurable']:
|
||||
for attr in ["state", "config", "configurable"]:
|
||||
if hasattr(runtime, attr):
|
||||
val = getattr(runtime, attr)
|
||||
logger.info(f"AttachmentMiddleware: runtime.{attr} = {type(val)}")
|
||||
if isinstance(val, dict):
|
||||
thread_id = val.get("thread_id")
|
||||
elif hasattr(val, 'get'):
|
||||
elif hasattr(val, "get"):
|
||||
thread_id = val.get("thread_id")
|
||||
if thread_id:
|
||||
break
|
||||
@ -147,8 +149,8 @@ class AttachmentMiddleware(AgentMiddleware[AttachmentState]):
|
||||
if input_context is not None:
|
||||
if isinstance(input_context, dict):
|
||||
thread_id = input_context.get("thread_id")
|
||||
elif hasattr(input_context, 'thread_id'):
|
||||
thread_id = getattr(input_context, 'thread_id', None)
|
||||
elif hasattr(input_context, "thread_id"):
|
||||
thread_id = getattr(input_context, "thread_id", None)
|
||||
|
||||
logger.info(f"AttachmentMiddleware: thread_id = {thread_id}")
|
||||
logger.info(f"AttachmentMiddleware: has config = {hasattr(request, 'config')}")
|
||||
|
||||
@ -147,7 +147,7 @@ def _offload_tool_result(msg: ToolMessage, threshold: int, token_counter: TokenC
|
||||
|
||||
# 构建文件头部信息
|
||||
header_lines = [
|
||||
f"=== Tool Invocation ===",
|
||||
"=== Tool Invocation ===",
|
||||
f"Tool: {tool_name}",
|
||||
f"Tool Call ID: {tool_call_id}",
|
||||
"=" * 40,
|
||||
|
||||
@ -35,8 +35,8 @@ class MySQLSecurityChecker:
|
||||
return False
|
||||
|
||||
# 移除SQL注释(-- 和 /* */)后再验证
|
||||
sql_clean = re.sub(r'--.*$', '', sql, flags=re.MULTILINE)
|
||||
sql_clean = re.sub(r'/\*.*?\*/', '', sql_clean)
|
||||
sql_clean = re.sub(r"--.*$", "", sql, flags=re.MULTILINE)
|
||||
sql_clean = re.sub(r"/\*.*?\*/", "", sql_clean)
|
||||
sql_upper = sql_clean.strip().upper()
|
||||
|
||||
# 检查是否是允许的操作
|
||||
|
||||
@ -140,7 +140,7 @@ class DeepAgent(BaseAgent):
|
||||
PatchToolCallsMiddleware(),
|
||||
summary_middleware,
|
||||
],
|
||||
general_purpose_agent=True
|
||||
general_purpose_agent=True,
|
||||
)
|
||||
|
||||
# 使用 create_deep_agent 创建深度智能体
|
||||
|
||||
@ -11,7 +11,6 @@ from src.agents.common.toolkits.mysql import get_mysql_tools
|
||||
from src.services.mcp_service import get_mcp_server_names, get_tools_from_all_servers
|
||||
from src.utils import logger
|
||||
|
||||
|
||||
PROMPT = """你的任务是根据用户的指令,使用数据库工具和图表绘制工具,构建 SQL 查询报告。
|
||||
你需要根据用户的指令,生成相应的 SQL 查询,并将查询结果以报表的形式返回给用户。
|
||||
在生成报表时,你可以调用工具生成图表,以更直观地展示数据。
|
||||
@ -22,9 +21,11 @@ PROMPT = """你的任务是根据用户的指令,使用数据库工具和图
|
||||
3. 必要时,使用网络检索相关工具补充信息。
|
||||
"""
|
||||
|
||||
|
||||
@dataclass(kw_only=True)
|
||||
class ReporterContext(BaseContext):
|
||||
"""覆盖 BaseContext,定义数据库报表助手智能体的可配置参数"""
|
||||
|
||||
# 覆盖 system_prompt,提供更具体的默认值
|
||||
system_prompt: Annotated[str, {"__template_metadata__": {"kind": "prompt"}}] = field(
|
||||
default=PROMPT,
|
||||
|
||||
@ -112,7 +112,6 @@
|
||||
/>
|
||||
|
||||
<div class="message-input-wrapper">
|
||||
|
||||
<!-- 加载状态:加载消息 -->
|
||||
<div v-if="isLoadingMessages" class="chat-loading">
|
||||
<div class="loading-spinner"></div>
|
||||
|
||||
@ -78,16 +78,8 @@
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<FolderOpen
|
||||
v-if="expanded"
|
||||
:size="18"
|
||||
class="folder-icon open"
|
||||
/>
|
||||
<Folder
|
||||
v-else
|
||||
:size="18"
|
||||
class="folder-icon"
|
||||
/>
|
||||
<FolderOpen v-if="expanded" :size="18" class="folder-icon open" />
|
||||
<Folder v-else :size="18" class="folder-icon" />
|
||||
</template>
|
||||
</template>
|
||||
<template #title="{ data }">
|
||||
@ -146,16 +138,8 @@
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<FolderOpen
|
||||
v-if="expanded"
|
||||
:size="18"
|
||||
class="folder-icon open"
|
||||
/>
|
||||
<Folder
|
||||
v-else
|
||||
:size="18"
|
||||
class="folder-icon"
|
||||
/>
|
||||
<FolderOpen v-if="expanded" :size="18" class="folder-icon open" />
|
||||
<Folder v-else :size="18" class="folder-icon" />
|
||||
</template>
|
||||
</template>
|
||||
<template #title="{ data }">
|
||||
@ -250,7 +234,17 @@
|
||||
|
||||
<script setup>
|
||||
import { computed, ref, onMounted, onUpdated, nextTick } from 'vue'
|
||||
import { Download, X, Plus, Info, FolderCode, RefreshCw, Folder, FolderOpen, Trash2 } from 'lucide-vue-next'
|
||||
import {
|
||||
Download,
|
||||
X,
|
||||
Plus,
|
||||
Info,
|
||||
FolderCode,
|
||||
RefreshCw,
|
||||
Folder,
|
||||
FolderOpen,
|
||||
Trash2
|
||||
} from 'lucide-vue-next'
|
||||
import {
|
||||
CheckCircleOutlined,
|
||||
SyncOutlined,
|
||||
@ -425,16 +419,16 @@ const buildTreeData = (filesList) => {
|
||||
// User asked for "last 5 chars".
|
||||
// If we treat the whole thing as a string:
|
||||
if (part.length > 5) {
|
||||
nameEnd = part.slice(-5)
|
||||
nameStart = part.slice(0, -5)
|
||||
nameEnd = part.slice(-5)
|
||||
nameStart = part.slice(0, -5)
|
||||
} else {
|
||||
nameStart = part
|
||||
nameEnd = ''
|
||||
nameStart = part
|
||||
nameEnd = ''
|
||||
}
|
||||
} else {
|
||||
if (part.length > 5) {
|
||||
nameEnd = part.slice(-5)
|
||||
nameStart = part.slice(0, -5)
|
||||
if (part.length > 5) {
|
||||
nameEnd = part.slice(-5)
|
||||
nameStart = part.slice(0, -5)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1084,7 +1078,8 @@ const stopResize = () => {
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
color: var(--gray-800);
|
||||
line-height: 28px;
|
||||
|
||||
@ -25,7 +25,9 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const toolCallName = computed(() => props.toolCall.name || props.toolCall.function?.name || 'edit_file')
|
||||
const toolCallName = computed(
|
||||
() => props.toolCall.name || props.toolCall.function?.name || 'edit_file'
|
||||
)
|
||||
|
||||
const parsedArgs = computed(() => {
|
||||
const args = props.toolCall.args || props.toolCall.function?.arguments
|
||||
|
||||
Loading…
Reference in New Issue
Block a user