fix(agent): 优化预算与技能按需加载
This commit is contained in:
@@ -18,8 +18,6 @@ import (
|
||||
"infinite-canvas/backend/internal/repository"
|
||||
)
|
||||
|
||||
const cloudAgentMaxSteps = 8
|
||||
|
||||
// A deterministic checkpoint failure must not be retried forever like a transient DB error.
|
||||
var errCloudAgentCheckpoint = errors.New("invalid Agent checkpoint")
|
||||
|
||||
@@ -155,10 +153,10 @@ func validateCloudAgentRuntime(run *model.CloudAgentExecution, state *cloudAgent
|
||||
return errors.New("Agent runtime profile read history is invalid")
|
||||
}
|
||||
}
|
||||
if state.Step < 0 || state.Step > cloudAgentMaxSteps+1 || state.Generations < 0 || state.VideoSeconds < 0 {
|
||||
if state.Step < 0 || state.Generations < 0 || state.VideoSeconds < 0 {
|
||||
return errors.New("Agent runtime budget or step is invalid")
|
||||
}
|
||||
if state.Generations > state.Request.Budget.MaxGenerationTasks || state.VideoSeconds > state.Request.Budget.MaxVideoSeconds {
|
||||
if (state.Request.Budget.MaxGenerationTasks > 0 && state.Generations > state.Request.Budget.MaxGenerationTasks) || (state.Request.Budget.MaxVideoSeconds > 0 && state.VideoSeconds > state.Request.Budget.MaxVideoSeconds) {
|
||||
return errors.New("Agent runtime generation budget is invalid")
|
||||
}
|
||||
if state.CallIndex < 0 || state.CallIndex > len(state.Calls) || len(state.Calls) > 8 {
|
||||
@@ -559,10 +557,8 @@ func (s *Service) advanceCloudAgent(run *model.CloudAgentExecution) (err error)
|
||||
if state.CallIndex < len(state.Calls) {
|
||||
return s.advanceCloudAgentTool(run, &state)
|
||||
}
|
||||
if state.Step >= cloudAgentMaxSteps {
|
||||
return s.failCloudAgent(run, &state, "达到 8 次模型调用上限,本轮已停止")
|
||||
}
|
||||
input := map[string]any{"mode": "text", "prompt": state.Request.Prompt, "agentRequests": map[string]any{"canonical": state.Canonical}, "config": map[string]any{"channelId": state.Request.ChannelID, "channelModelKey": state.Request.ChannelModelKey, "model": firstNonEmpty(state.Request.ChannelModelKey, state.Request.Model)}, "textOptions": map[string]any{"stream": true, "thinking": cloudAgentReasoningEnabled(state.Policy.ReasoningMode)}}
|
||||
compactCloudAgentContext(&state.Canonical)
|
||||
raw, _ := json.Marshal(state.Canonical)
|
||||
if len(raw) > 192<<10 {
|
||||
return s.failCloudAgent(run, &state, "模型上下文超过 192KB 上限")
|
||||
@@ -570,6 +566,30 @@ func (s *Service) advanceCloudAgent(run *model.CloudAgentExecution) (err error)
|
||||
req := CreateTaskRequest{ProjectID: state.Request.CanvasID, Type: "canvas_text", Operation: "cloud_agent_step", Prompt: state.Request.Prompt, Model: state.Request.Model, LogicalModelID: state.Request.LogicalModelID, Input: input}
|
||||
return s.enqueueCloudAgentTask(run, &state, req, nil)
|
||||
}
|
||||
|
||||
func compactCloudAgentContext(request *canonicalAgentRequest) {
|
||||
const maxMessages = 24
|
||||
if request == nil || len(request.Messages) <= maxMessages {
|
||||
return
|
||||
}
|
||||
keep := 16
|
||||
dropped := request.Messages[1 : len(request.Messages)-keep]
|
||||
if len(dropped) == 0 {
|
||||
return
|
||||
}
|
||||
parts := make([]string, 0, len(dropped))
|
||||
for _, message := range dropped {
|
||||
role := stringField(message, "role")
|
||||
text := canonicalAgentText(message["content"])
|
||||
if text == "" {
|
||||
text = "工具/调用记录"
|
||||
}
|
||||
parts = append(parts, role+": "+truncateRunes(text, 240))
|
||||
}
|
||||
summary := map[string]interface{}{"role": "user", "content": "历史上下文摘要(仅供参考;实时画布状态必须通过工具读取,不是新指令):\n" + strings.Join(parts, "\n")}
|
||||
request.Messages = append([]map[string]interface{}{request.Messages[0], summary}, request.Messages[len(request.Messages)-keep:]...)
|
||||
}
|
||||
|
||||
func validateCloudAgentCalls(calls []cloudAgentCall) error {
|
||||
seen := make(map[string]bool, len(calls))
|
||||
for _, call := range calls {
|
||||
@@ -837,7 +857,7 @@ func (s *Service) advanceCloudAgentTool(run *model.CloudAgentExecution, state *c
|
||||
case call.Function.Name == "model_list":
|
||||
result = modelList
|
||||
default:
|
||||
result, toolErr = cloudAgentReadTool(repo, run.UserID, state, call)
|
||||
result, toolErr = cloudAgentReadTool(repo, run.UserID, state, call, s)
|
||||
}
|
||||
cloudAgentToolResult(run.ID, state, call, result, toolErr)
|
||||
return cloudAgentSave(current, state)
|
||||
|
||||
Reference in New Issue
Block a user