feat: persist photos and enrich conversation history
This commit is contained in:
@@ -4,6 +4,7 @@ from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Awaitable
|
||||
from time import monotonic
|
||||
from typing import Any
|
||||
from uuid import uuid4
|
||||
|
||||
@@ -503,12 +504,45 @@ class PromptBrain(BaseBrain):
|
||||
await params.result_callback(result)
|
||||
|
||||
async def call_tool(params: FunctionCallParams) -> None:
|
||||
invocation_id = f"tool_{uuid4().hex[:20]}"
|
||||
started_at = monotonic()
|
||||
await self._emit_trace(
|
||||
"tool_started",
|
||||
invocationId=invocation_id,
|
||||
toolId=tool.id,
|
||||
toolName=tool.name,
|
||||
functionName=tool.function_name,
|
||||
toolType=tool.type,
|
||||
)
|
||||
try:
|
||||
result = await self._tools.execute(tool, dict(params.arguments or {}))
|
||||
if result["updated_variables"]:
|
||||
self._refresh_prompt()
|
||||
await self._emit_trace(
|
||||
"tool_completed" if result.get("status") == "ok" else "tool_failed",
|
||||
invocationId=invocation_id,
|
||||
toolId=tool.id,
|
||||
toolName=tool.name,
|
||||
functionName=tool.function_name,
|
||||
toolType=tool.type,
|
||||
status=str(result.get("status") or "unknown"),
|
||||
durationMs=max(0, round((monotonic() - started_at) * 1000)),
|
||||
updatedVariables=list(result.get("updated_variables") or []),
|
||||
resultKeys=sorted(str(name) for name in result if name != "data"),
|
||||
)
|
||||
await return_result(params, result)
|
||||
except (ToolExecutionError, ValueError) as exc:
|
||||
await self._emit_trace(
|
||||
"tool_failed",
|
||||
invocationId=invocation_id,
|
||||
toolId=tool.id,
|
||||
toolName=tool.name,
|
||||
functionName=tool.function_name,
|
||||
toolType=tool.type,
|
||||
status="error",
|
||||
durationMs=max(0, round((monotonic() - started_at) * 1000)),
|
||||
error=str(exc)[:2048],
|
||||
)
|
||||
await return_result(
|
||||
params,
|
||||
{"status": "error", "message": f"工具调用失败: {exc}"},
|
||||
@@ -522,6 +556,26 @@ class PromptBrain(BaseBrain):
|
||||
)
|
||||
return schema, call_tool
|
||||
|
||||
async def _emit_trace(self, event: str, **details: Any) -> None:
|
||||
runtime = self._runtime
|
||||
if runtime is None:
|
||||
return
|
||||
try:
|
||||
await runtime.queue_frame(
|
||||
OutputTransportMessageUrgentFrame(
|
||||
message={
|
||||
"type": "workflow-event",
|
||||
"eventId": f"wfe_{uuid4().hex[:20]}",
|
||||
"event": event,
|
||||
"timestamp": time_now_iso8601(),
|
||||
"sessionId": runtime.session_id,
|
||||
**details,
|
||||
}
|
||||
)
|
||||
)
|
||||
except Exception as exc: # noqa: BLE001 - trace must not alter execution
|
||||
logger.warning(f"发送 Prompt 工具轨迹失败,不影响当前调用: {exc}")
|
||||
|
||||
def _make_end_call_tool(self, tool, runtime: BrainRuntime):
|
||||
config = (tool.definition or {}).get("config") or {}
|
||||
message_type = str(config.get("message_type") or "none")
|
||||
|
||||
Reference in New Issue
Block a user