Version: 0.9.50.dev.260428
后端: 1. 工具执行结果协议升级为结构化 ToolExecutionResult——execute/tool_runtime、ToolRegistry、stream extra 与 timeline 持久化统一改为透传 observation_text / summary / argument_view / result_view,不再只回写纯文本结果;context_tools、upsert_task_class 与旧 schedule/web 工具通过兼容包装接入新协议 2. 日程写工具注册继续收口——place / move / swap / batch_move / unplace / queue_apply_head_move 从 registry 内联实现下沉为独立 handler,降低注册表内参数解析与业务逻辑混写 3. 工具结果展示基础能力补齐——新增 execution_result / schedule_operation_handlers 公共件,为日程操作结果、参数本地化展示、blocked/failed/done 状态统一建模 前端: 4. AssistantPanel 接入结构化工具卡片渲染——新增 ToolCardRenderer,tool_call / tool_result 支持 argument_view / result_view 展示;schedule_completed 恢复为时间线内的占位卡片块,避免排程卡片脱离原消息顺序 5. 时间线类型与渲染收敛——schedule_agent.ts 补齐 ToolView 协议,AssistantPanel 改为按块渲染 tool / schedule_card / business_card,并移除旧 demo/prototype 路由与页面,收束正式面板代码路径 仓库: 6. AGENTS.md 新增协作约束——禁止擅自回滚、覆盖或删除用户/其他代理产生的工作区改动
This commit is contained in:
@@ -21,7 +21,7 @@ func appendToolCallResultHistory(
|
||||
conversationContext *newagentmodel.ConversationContext,
|
||||
toolName string,
|
||||
args map[string]any,
|
||||
result string,
|
||||
result newagenttools.ToolExecutionResult,
|
||||
) {
|
||||
if conversationContext == nil {
|
||||
return
|
||||
@@ -50,7 +50,7 @@ func appendToolCallResultHistory(
|
||||
})
|
||||
conversationContext.AppendHistory(&schema.Message{
|
||||
Role: schema.Tool,
|
||||
Content: result,
|
||||
Content: result.ObservationText,
|
||||
ToolCallID: toolCallID,
|
||||
ToolName: toolName,
|
||||
})
|
||||
@@ -98,16 +98,9 @@ func executeToolCall(
|
||||
return fmt.Errorf("连续 %d 次调用临时禁用工具,终止执行: %s",
|
||||
flowState.ConsecutiveCorrections, toolName)
|
||||
}
|
||||
blockedResult := buildTemporarilyDisabledToolResult(toolName)
|
||||
_ = emitter.EmitToolCallResult(
|
||||
executeStatusBlockID,
|
||||
executeStageName,
|
||||
toolName,
|
||||
"blocked",
|
||||
blockedResult,
|
||||
buildToolArgumentsPreviewCN(toolCall.Arguments),
|
||||
false,
|
||||
)
|
||||
blockedText := buildTemporarilyDisabledToolResult(toolName)
|
||||
blockedResult := newagenttools.BlockedResult(toolName, toolCall.Arguments, blockedText, "tool_temporarily_disabled", blockedText)
|
||||
emitToolCallResultEvent(emitter, executeStatusBlockID, executeStageName, blockedResult, toolCall.Arguments)
|
||||
appendToolCallResultHistory(conversationContext, toolName, toolCall.Arguments, blockedResult)
|
||||
newagentshared.AppendLLMCorrectionWithHint(
|
||||
conversationContext,
|
||||
@@ -165,16 +158,9 @@ func executeToolCall(
|
||||
}
|
||||
|
||||
if shouldForceFeasibilityNegotiation(flowState, registry, toolName) {
|
||||
blockedResult := buildInfeasibleBlockedResult(flowState)
|
||||
_ = emitter.EmitToolCallResult(
|
||||
executeStatusBlockID,
|
||||
executeStageName,
|
||||
toolName,
|
||||
"blocked",
|
||||
blockedResult,
|
||||
buildToolArgumentsPreviewCN(toolCall.Arguments),
|
||||
false,
|
||||
)
|
||||
blockedText := buildInfeasibleBlockedResult(flowState)
|
||||
blockedResult := newagenttools.BlockedResult(toolName, toolCall.Arguments, blockedText, "health_negotiation_required", blockedText)
|
||||
emitToolCallResultEvent(emitter, executeStatusBlockID, executeStageName, blockedResult, toolCall.Arguments)
|
||||
appendToolCallResultHistory(conversationContext, toolName, toolCall.Arguments, blockedResult)
|
||||
return nil
|
||||
}
|
||||
@@ -187,9 +173,10 @@ func executeToolCall(
|
||||
toolCall.Arguments["_user_id"] = flowState.UserID
|
||||
}
|
||||
result := registry.Execute(scheduleState, toolName, toolCall.Arguments)
|
||||
updateHealthSnapshotV2(flowState, toolName, result)
|
||||
updateTaskClassUpsertSnapshot(flowState, toolName, result)
|
||||
updateActiveToolDomainSnapshot(flowState, toolName, result)
|
||||
result = newagenttools.EnsureToolResultDefaults(result, toolCall.Arguments)
|
||||
updateHealthSnapshotV2(flowState, toolName, result.ObservationText)
|
||||
updateTaskClassUpsertSnapshot(flowState, toolName, result.ObservationText)
|
||||
updateActiveToolDomainSnapshot(flowState, toolName, result.ObservationText)
|
||||
afterDigest := summarizeScheduleStateForDebug(scheduleState)
|
||||
log.Printf(
|
||||
"[DEBUG] execute tool chat=%s round=%d tool=%s args=%s before=%s after=%s result_preview=%.200s",
|
||||
@@ -199,17 +186,9 @@ func executeToolCall(
|
||||
marshalArgsForDebug(toolCall.Arguments),
|
||||
beforeDigest,
|
||||
afterDigest,
|
||||
flattenForLog(result),
|
||||
)
|
||||
_ = emitter.EmitToolCallResult(
|
||||
executeStatusBlockID,
|
||||
executeStageName,
|
||||
toolName,
|
||||
resolveToolEventResultStatus(result),
|
||||
buildToolEventResultSummary(result),
|
||||
buildToolArgumentsPreviewCN(toolCall.Arguments),
|
||||
false,
|
||||
flattenForLog(result.ObservationText),
|
||||
)
|
||||
emitToolCallResultEvent(emitter, executeStatusBlockID, executeStageName, result, toolCall.Arguments)
|
||||
|
||||
appendToolCallResultHistory(conversationContext, toolName, toolCall.Arguments, result)
|
||||
|
||||
@@ -301,32 +280,18 @@ func executePendingTool(
|
||||
}
|
||||
flowState := runtimeState.EnsureCommonState()
|
||||
if registry.IsToolTemporarilyDisabled(pending.ToolName) {
|
||||
blockedResult := buildTemporarilyDisabledToolResult(pending.ToolName)
|
||||
_ = emitter.EmitToolCallResult(
|
||||
executeStatusBlockID,
|
||||
executeStageName,
|
||||
pending.ToolName,
|
||||
"blocked",
|
||||
blockedResult,
|
||||
buildToolArgumentsPreviewCN(args),
|
||||
false,
|
||||
)
|
||||
blockedText := buildTemporarilyDisabledToolResult(pending.ToolName)
|
||||
blockedResult := newagenttools.BlockedResult(pending.ToolName, args, blockedText, "tool_temporarily_disabled", blockedText)
|
||||
emitToolCallResultEvent(emitter, executeStatusBlockID, executeStageName, blockedResult, args)
|
||||
appendToolCallResultHistory(conversationContext, pending.ToolName, args, blockedResult)
|
||||
runtimeState.PendingConfirmTool = nil
|
||||
return nil
|
||||
}
|
||||
|
||||
if shouldForceFeasibilityNegotiation(flowState, registry, pending.ToolName) {
|
||||
blockedResult := buildInfeasibleBlockedResult(flowState)
|
||||
_ = emitter.EmitToolCallResult(
|
||||
executeStatusBlockID,
|
||||
executeStageName,
|
||||
pending.ToolName,
|
||||
"blocked",
|
||||
blockedResult,
|
||||
buildToolArgumentsPreviewCN(args),
|
||||
false,
|
||||
)
|
||||
blockedText := buildInfeasibleBlockedResult(flowState)
|
||||
blockedResult := newagenttools.BlockedResult(pending.ToolName, args, blockedText, "health_negotiation_required", blockedText)
|
||||
emitToolCallResultEvent(emitter, executeStatusBlockID, executeStageName, blockedResult, args)
|
||||
appendToolCallResultHistory(conversationContext, pending.ToolName, args, blockedResult)
|
||||
runtimeState.PendingConfirmTool = nil
|
||||
return nil
|
||||
@@ -340,9 +305,10 @@ func executePendingTool(
|
||||
args["_user_id"] = flowState.UserID
|
||||
}
|
||||
result := registry.Execute(scheduleState, pending.ToolName, args)
|
||||
updateHealthSnapshotV2(flowState, pending.ToolName, result)
|
||||
updateTaskClassUpsertSnapshot(flowState, pending.ToolName, result)
|
||||
updateActiveToolDomainSnapshot(flowState, pending.ToolName, result)
|
||||
result = newagenttools.EnsureToolResultDefaults(result, args)
|
||||
updateHealthSnapshotV2(flowState, pending.ToolName, result.ObservationText)
|
||||
updateTaskClassUpsertSnapshot(flowState, pending.ToolName, result.ObservationText)
|
||||
updateActiveToolDomainSnapshot(flowState, pending.ToolName, result.ObservationText)
|
||||
afterDigest := summarizeScheduleStateForDebug(scheduleState)
|
||||
log.Printf(
|
||||
"[DEBUG] execute pending tool chat=%s round=%d tool=%s args=%s before=%s after=%s result_preview=%.200s",
|
||||
@@ -352,17 +318,9 @@ func executePendingTool(
|
||||
marshalArgsForDebug(args),
|
||||
beforeDigest,
|
||||
afterDigest,
|
||||
flattenForLog(result),
|
||||
)
|
||||
_ = emitter.EmitToolCallResult(
|
||||
executeStatusBlockID,
|
||||
executeStageName,
|
||||
pending.ToolName,
|
||||
resolveToolEventResultStatus(result),
|
||||
buildToolEventResultSummary(result),
|
||||
buildToolArgumentsPreviewCN(args),
|
||||
false,
|
||||
flattenForLog(result.ObservationText),
|
||||
)
|
||||
emitToolCallResultEvent(emitter, executeStatusBlockID, executeStageName, result, args)
|
||||
|
||||
appendToolCallResultHistory(conversationContext, pending.ToolName, args, result)
|
||||
|
||||
@@ -434,3 +392,27 @@ func buildExecuteNormalizedSpeakTail(streamed, normalized string) string {
|
||||
}
|
||||
return normalized[len(streamed):]
|
||||
}
|
||||
|
||||
func emitToolCallResultEvent(
|
||||
emitter *newagentstream.ChunkEmitter,
|
||||
blockID string,
|
||||
stage string,
|
||||
result newagenttools.ToolExecutionResult,
|
||||
args map[string]any,
|
||||
) {
|
||||
if emitter == nil {
|
||||
return
|
||||
}
|
||||
result = newagenttools.EnsureToolResultDefaults(result, args)
|
||||
_ = emitter.EmitToolCallResult(
|
||||
blockID,
|
||||
stage,
|
||||
result.Tool,
|
||||
result.Status,
|
||||
result.Summary,
|
||||
result.ArgumentsPreview,
|
||||
newagenttools.ToolArgumentViewToMap(result.ArgumentView),
|
||||
newagenttools.ToolDisplayViewToMap(result.ResultView),
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user