Runtime 工具观察只做长度收口,脱敏只留给审计写入

- 各工具构造 `AgentRuntimeToolObservation` 时不再调用 `sanitize_agent_runtime_text` / `redact_agent_runtime_project_paths`,改为只做长度上限的 `truncate_agent_runtime_text`
- 保留 `append_agent_db_record` / 事件 / `append_patchset_audit` 等审计写入处的脱敏
- `agent.action_history` 读取的账本仍按写入侧口径脱敏,读取路径不再二次脱敏
- 委派(`agent.delegate` / `agent.spawn_isolated`)与 `agent.schedule_ready` 的结果明细原样进回执
- 去掉因参数失去用途的 `root` 形参:`canvas_durable_result_reconciliation_observation`、`rejected`、`error_observation`、`error_observation_with_revision_advance`
This commit is contained in:
2026-10-01 18:54:11 +08:00
parent cf6ed72f34
commit f8ba46fa4f
15 changed files with 229 additions and 291 deletions
@@ -25,7 +25,7 @@ pub(crate) fn observe_agent_runtime_action_history(
tool: "agent.action_history".to_string(),
status: "failed".to_string(),
summary: "读取当前 Agent 的动作历史失败".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
},
}
}
@@ -319,7 +319,7 @@ pub(in crate::agent) fn read_agent_runtime_action_history(
run_id: run_id.clone(),
tool: record_tool,
execution_mode: record_execution_mode.or(fallback.execution_mode),
status: sanitize_agent_runtime_text(record_status, 40),
status: truncate_agent_runtime_text(record_status, 40),
input_summary: agent_db_record_text(record, "inputSummary")
.and_then(|value| agent_runtime_action_receipt_safe_text(root, value, 160, None))
.or(fallback.input_summary),
@@ -376,7 +376,7 @@ pub(in crate::agent) fn read_agent_runtime_action_history(
for item in items.iter_mut() {
item.safe_detail = None;
item.detail_unavailable = true;
item.summary = sanitize_agent_runtime_text(&item.summary, 100);
item.summary = truncate_agent_runtime_text(&item.summary, 100);
item.input_summary = None;
}
}
@@ -17,7 +17,7 @@ pub(in crate::agent) fn observe_agent_runtime_cocos_editor_execute(
return AgentRuntimeToolObservation {
tool: "cocos.editor.execute".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("cocos.editor.execute 输入无效:{error}"),
240,
),
@@ -60,11 +60,11 @@ pub(in crate::agent) fn observe_agent_runtime_cocos_editor_execute(
"failed"
}
.to_string(),
summary: redact_agent_runtime_project_paths(root, &error.to_string(), 240),
summary: truncate_agent_runtime_text(&error.to_string(), 240),
detail: Some(
serde_json::json!({
"codeChars": input.code.chars().count(),
"error": redact_agent_runtime_project_paths(root, &error.to_string(), 500),
"error": truncate_agent_runtime_text(&error.to_string(), 500),
})
.to_string(),
),
@@ -173,7 +173,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_output_read(
return AgentRuntimeToolObservation {
tool: "command.output_read".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("command.output_read 输入无效:{error}"),
240,
),
@@ -204,7 +204,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_output_read(
tool: "command.output_read".to_string(),
status: "failed".to_string(),
summary: "command.output_read 无法验证源命令身份".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -220,7 +220,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_output_read(
tool: "command.output_read".to_string(),
status: "failed".to_string(),
summary: "command.output_read 读取输出 sidecar 失败".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -273,7 +273,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_output_read(
tool: "command.output_read".to_string(),
status: "failed".to_string(),
summary: "command.output_read 无法序列化分页结果".to_string(),
detail: Some(sanitize_agent_runtime_text(&error.to_string(), 240)),
detail: Some(truncate_agent_runtime_text(&error.to_string(), 240)),
};
}
};
@@ -306,7 +306,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_output_read(
tool: "command.output_read".to_string(),
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: "command.output_read 已读取输出,但安全审计无法落盘".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
let end_line = page
@@ -369,7 +369,7 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
return AgentRuntimeToolObservation {
tool: "command.exec".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("command.exec 输入无效:{error}"),
240,
),
@@ -389,7 +389,7 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
return AgentRuntimeToolObservation {
tool: "command.exec".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -403,7 +403,7 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
tool: "command.exec".to_string(),
status: "failed".to_string(),
summary: "command.exec 无法取得项目执行锁".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 240)),
detail: Some(truncate_agent_runtime_text(&error, 240)),
};
}
};
@@ -440,11 +440,7 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
tool: "command.exec".to_string(),
status: "failed".to_string(),
summary: "command.exec 沙箱预检失败,命令未执行".to_string(),
detail: Some(redact_agent_runtime_project_paths(
root,
error.message(),
500,
)),
detail: Some(truncate_agent_runtime_text(error.message(), 500)),
};
}
};
@@ -457,11 +453,7 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
tool: "command.exec".to_string(),
status: "failed".to_string(),
summary: "command.exec 沙箱启动闸门准备失败,命令未执行".to_string(),
detail: Some(redact_agent_runtime_project_paths(
root,
error.message(),
500,
)),
detail: Some(truncate_agent_runtime_text(error.message(), 500)),
};
}
};
@@ -588,7 +580,7 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
let gate_error = gate_result.err().map(|gate_error| {
format!(
" · verificationGateError={}",
redact_agent_runtime_project_paths(root, &gate_error, 300)
truncate_agent_runtime_text(&gate_error, 300)
)
});
return AgentRuntimeToolObservation {
@@ -606,7 +598,7 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
},
detail: Some(format!(
"revisionAdvanced={revision_advanced} · verificationEligible={verification_eligible} · {}{}",
redact_agent_runtime_project_paths(root, &error, 500),
truncate_agent_runtime_text(&error, 500),
gate_error.unwrap_or_default(),
)),
};
@@ -616,14 +608,13 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
tool: "command.exec".to_string(),
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: "command.exec 已返回,但验证凭证无法完整落盘".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
match result {
Ok(command) => {
let output_tail = redact_agent_runtime_project_paths_preserving_tail(
root,
let output_tail = truncate_agent_runtime_text_preserving_tail(
&command.output,
AGENT_RUNTIME_TOOL_OBSERVATION_MAX_CHARS,
);
@@ -700,7 +691,7 @@ pub(in crate::agent) async fn observe_agent_runtime_command_exec(
},
detail: Some(format!(
"revisionAdvanced={revision_advanced} · verificationEligible={verification_eligible} · {}",
redact_agent_runtime_project_paths(root, error.message(), 500)
truncate_agent_runtime_text(error.message(), 500)
)),
}
}
@@ -756,7 +747,7 @@ pub(crate) fn observe_agent_runtime_limited_command(
tool: "command.run_limited".to_string(),
status: "failed".to_string(),
summary: "无法核对 game.static_smoke 的当前 run 身份".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
}
@@ -767,7 +758,7 @@ pub(crate) fn observe_agent_runtime_limited_command(
tool: "command.run_limited".to_string(),
status: "failed".to_string(),
summary: "game.static_smoke 无法取得项目验证锁".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 240)),
detail: Some(truncate_agent_runtime_text(&error, 240)),
};
}
};
@@ -783,7 +774,7 @@ pub(crate) fn observe_agent_runtime_limited_command(
tool: "command.run_limited".to_string(),
status: "failed".to_string(),
summary: "game.static_smoke 无法清除旧验证凭证".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -814,7 +805,7 @@ pub(crate) fn observe_agent_runtime_limited_command(
tool: "command.run_limited".to_string(),
status: "failed".to_string(),
summary: "game.static_smoke 结果无法形成有效验证凭证".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
match result {
@@ -822,17 +813,13 @@ pub(crate) fn observe_agent_runtime_limited_command(
tool: "command.run_limited".to_string(),
status: "ok".to_string(),
summary: format!("{} 已完成", command.command_id),
detail: Some(redact_agent_runtime_project_paths(
root,
&command.output,
500,
)),
detail: Some(truncate_agent_runtime_text(&command.output, 500)),
},
Err(error) => AgentRuntimeToolObservation {
tool: "command.run_limited".to_string(),
status: "failed".to_string(),
summary: "game.static_smoke 执行失败".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
},
}
}
@@ -883,7 +870,7 @@ pub(crate) async fn observe_agent_runtime_project_verify(
tool: "project.verify".to_string(),
status: "failed".to_string(),
summary: "project.verify 无法取得项目验证锁".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 240)),
detail: Some(truncate_agent_runtime_text(&error, 240)),
};
}
};
@@ -980,13 +967,12 @@ pub(crate) async fn observe_agent_runtime_project_verify(
} else {
"project.verify 结果无法形成有效验证凭证".to_string()
},
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
match result {
Ok(verification) => {
let output_tail = redact_agent_runtime_project_paths_preserving_tail(
root,
let output_tail = truncate_agent_runtime_text_preserving_tail(
&verification.output,
AGENT_RUNTIME_TOOL_OBSERVATION_MAX_CHARS,
);
@@ -1039,10 +1025,9 @@ pub(crate) async fn observe_agent_runtime_project_verify(
summary: if needs_reconciliation {
"project.verify 执行或审计结果不完整,需要人工核对".to_string()
} else {
redact_agent_runtime_project_paths(root, &error, 240)
truncate_agent_runtime_text(&error, 240)
},
detail: needs_reconciliation
.then(|| redact_agent_runtime_project_paths(root, &error, 500)),
detail: needs_reconciliation.then(|| truncate_agent_runtime_text(&error, 500)),
}
}
}
@@ -1077,7 +1062,7 @@ pub(crate) async fn observe_agent_runtime_project_bootstrap(
tool: "project.bootstrap".to_string(),
status: "failed".to_string(),
summary: "project.bootstrap 无法取得项目执行锁".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 240)),
detail: Some(truncate_agent_runtime_text(&error, 240)),
}
}
};
@@ -1097,7 +1082,7 @@ pub(crate) async fn observe_agent_runtime_project_bootstrap(
tool: "project.bootstrap".to_string(),
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: "project.bootstrap 已安装,但审计记录无法落盘".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
AgentRuntimeToolObservation {
@@ -1120,7 +1105,7 @@ pub(crate) async fn observe_agent_runtime_project_bootstrap(
Err(error) => AgentRuntimeToolObservation {
tool: "project.bootstrap".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -73,7 +73,7 @@ pub(in crate::agent) fn observe_agent_runtime_memory_write(
return AgentRuntimeToolObservation {
tool: "memory.write".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -102,7 +102,7 @@ pub(in crate::agent) fn observe_agent_runtime_memory_write(
return AgentRuntimeToolObservation {
tool: "memory.write".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -113,7 +113,7 @@ pub(in crate::agent) fn observe_agent_runtime_memory_write(
return AgentRuntimeToolObservation {
tool: "memory.write".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -213,7 +213,7 @@ pub(in crate::agent) fn observe_agent_runtime_memory_write(
Err(error) => AgentRuntimeToolObservation {
tool: "memory.write".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -418,7 +418,7 @@ pub(in crate::agent) async fn observe_agent_runtime_account_asset_library(
Err(error) => AgentRuntimeToolObservation {
tool: "asset.library.list".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 300),
summary: truncate_agent_runtime_text(&error, 300),
detail: None,
},
}
@@ -555,7 +555,7 @@ pub(in crate::agent) async fn observe_agent_runtime_asset_import(
"source": source,
})
})),
Err(error) => failures.push(redact_agent_runtime_project_paths(root, &error, 360)),
Err(error) => failures.push(truncate_agent_runtime_text(&error, 360)),
}
}
if !local_paths.is_empty() {
@@ -568,7 +568,7 @@ pub(in crate::agent) async fn observe_agent_runtime_asset_import(
"source": "local",
})
})),
Err(error) => failures.push(redact_agent_runtime_project_paths(root, &error, 360)),
Err(error) => failures.push(truncate_agent_runtime_text(&error, 360)),
}
}
if !imported.is_empty() {
@@ -667,7 +667,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_search(
"已搜索项目:{match_count} 个匹配(扫描 {scanned_files} 个文本文件)"
),
detail: Some(truncate_agent_runtime_text(
sanitize_prompt_context(&lines.join("\n")).as_str(),
&lines.join("\n"),
AGENT_RUNTIME_FILE_CONTEXT_MAX_CHARS,
)),
}
@@ -675,7 +675,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_search(
Err(error) => AgentRuntimeToolObservation {
tool: "project.search".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -853,7 +853,7 @@ pub(in crate::agent) fn search_agent_runtime_project(
"{}:{}: {}",
relative_path,
line_index + 1,
sanitize_agent_runtime_text(line.trim(), 320)
truncate_agent_runtime_text(line.trim(), 320)
));
if matches.len() >= max_results {
truncated = true;
@@ -21,7 +21,7 @@ pub(in crate::agent) fn observe_agent_runtime_blackboard_write(
return AgentRuntimeToolObservation {
tool: "blackboard.write".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -32,7 +32,7 @@ pub(in crate::agent) fn observe_agent_runtime_blackboard_write(
return AgentRuntimeToolObservation {
tool: "blackboard.write".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -49,8 +49,8 @@ pub(in crate::agent) fn observe_agent_runtime_blackboard_write(
} else {
title_input.trim()
};
let title = sanitize_agent_runtime_text(title_text, 80);
let content = truncate_agent_runtime_text(sanitize_prompt_context(&content).as_str(), 1_200);
let title = truncate_agent_runtime_text(title_text, 80);
let content = truncate_agent_runtime_text(&content, 1_200);
let entry = format!("\n\n## Agent {agent_id} - {title}\n\n{content}\n");
let result = append_markdown_entry(
&root.join(PROJECT_BLACKBOARD_MEMORY_PATH),
@@ -79,7 +79,7 @@ pub(in crate::agent) fn observe_agent_runtime_blackboard_write(
Err(error) => AgentRuntimeToolObservation {
tool: "blackboard.write".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -98,7 +98,7 @@ pub(crate) fn observe_agent_runtime_agent_message(
return AgentRuntimeToolObservation {
tool: "agent.message".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -118,7 +118,7 @@ pub(crate) fn observe_agent_runtime_agent_message(
return AgentRuntimeToolObservation {
tool: "agent.message".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -129,11 +129,11 @@ pub(crate) fn observe_agent_runtime_agent_message(
return AgentRuntimeToolObservation {
tool: "agent.message".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
let content = truncate_agent_runtime_text(sanitize_prompt_context(&content).as_str(), 1_200);
let content = truncate_agent_runtime_text(&content, 1_200);
let message = format!(
prompt_text!("runtime.directed_message_context"),
agent_id = agent_id,
@@ -199,7 +199,7 @@ pub(crate) fn observe_agent_runtime_agent_message(
Err(error) => AgentRuntimeToolObservation {
tool: "agent.message".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -312,7 +312,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -463,7 +463,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
}
}
@@ -474,7 +474,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -533,7 +533,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -565,7 +565,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -597,7 +597,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail,
};
}
@@ -621,7 +621,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -648,7 +648,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -661,7 +661,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -675,7 +675,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -716,7 +716,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
delegation_id,
existing.status,
existing.phase,
sanitize_agent_runtime_text(&existing.task, 180)
truncate_agent_runtime_text(&existing.task, 180)
)),
};
}
@@ -738,7 +738,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -751,8 +751,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
.unwrap_or(existing.current_action.as_str());
// 摘要给人看,明细给回执解析:两者不能共用一次截断,否则一行摘要
// 的长度会决定结构化载荷能不能被父 run 解析。
let result_detail = redact_agent_runtime_project_paths(
root,
let result_detail = truncate_agent_runtime_text(
result_detail,
static_delegate_result_detail_max_chars(result_detail, 240),
);
@@ -775,7 +774,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -793,7 +792,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -810,7 +809,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
delegation_id,
existing.status,
existing.phase,
sanitize_agent_runtime_text(&existing.task, 180)
truncate_agent_runtime_text(&existing.task, 180)
)),
};
}
@@ -819,7 +818,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -839,7 +838,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -880,7 +879,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -906,7 +905,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -949,7 +948,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1025,8 +1024,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
.as_deref()
.or(existing.error.as_deref())
.unwrap_or(error.as_str());
let result_detail = redact_agent_runtime_project_paths(
root,
let result_detail = truncate_agent_runtime_text(
result_detail,
static_delegate_result_detail_max_chars(result_detail, 240),
);
@@ -1077,11 +1075,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(
root,
&ready_error,
240,
),
summary: truncate_agent_runtime_text(&ready_error, 240),
detail: None,
};
}
@@ -1098,7 +1092,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
delegation_id,
existing.status,
existing.phase,
sanitize_agent_runtime_text(&error, 180)
truncate_agent_runtime_text(&error, 180)
)),
};
}
@@ -1115,7 +1109,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
delegation_id,
existing.status,
existing.phase,
sanitize_agent_runtime_text(&error, 180)
truncate_agent_runtime_text(&error, 180)
)),
};
}
@@ -1126,11 +1120,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
return AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(
root,
&suppression_error,
240,
),
summary: truncate_agent_runtime_text(&suppression_error, 240),
detail: None,
};
}
@@ -1139,7 +1129,7 @@ pub(crate) fn observe_agent_runtime_agent_delegate_at_locked(
AgentRuntimeToolObservation {
tool: "agent.delegate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
}
}
@@ -1171,8 +1161,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(
root,
summary: truncate_agent_runtime_text(
&format!("无法核对动态隔离父 Run Profile binding,已拒绝创建 child:{error}"),
240,
),
@@ -1191,8 +1180,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(
root,
summary: truncate_agent_runtime_text(
&format!(
"无法核对动态隔离 root Run Profile binding,已拒绝创建 child:{error}"
),
@@ -1222,8 +1210,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(
root,
summary: truncate_agent_runtime_text(
&format!("无法核对动态隔离父 Run task journal,已拒绝创建 child:{error}"),
240,
),
@@ -1251,7 +1238,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("agent.spawn_isolated 输入无效:{error}"),
240,
),
@@ -1298,7 +1285,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1316,7 +1303,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1330,7 +1317,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1344,7 +1331,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1364,7 +1351,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1389,7 +1376,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1434,7 +1421,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1444,7 +1431,7 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
return AgentRuntimeToolObservation {
tool: "agent.spawn_isolated".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -1455,6 +1442,6 @@ pub(crate) fn observe_agent_runtime_agent_spawn_isolated(
summary: format!("已启动 {} 个动态隔离子 Agent", request.children.len()),
detail: serde_json::to_string(&detail)
.ok()
.map(|value| redact_agent_runtime_project_paths(root, &value, 3_600)),
.map(|value| truncate_agent_runtime_text(&value, 3_600)),
}
}
@@ -76,17 +76,13 @@ fn observe_agent_runtime_editor_execute(
"needs-reconciliation" => format!("{editor} 执行结果待人工核对,禁止自动重发"),
_ => format!("{editor} 编辑器执行失败"),
},
detail: Some(redact_agent_runtime_project_paths(
root,
&response.to_string(),
32_000,
)),
detail: Some(truncate_agent_runtime_text(&response.to_string(), 32_000)),
}
}
Err(error) => AgentRuntimeToolObservation {
tool: tool.to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 480),
summary: truncate_agent_runtime_text(&error, 480),
detail: None,
},
}
@@ -49,7 +49,7 @@ pub(in crate::agent) fn agent_role_project_path_mutation_block(
tool: tool.to_string(),
status: "blocked".to_string(),
summary: "无法核对 autonomous owner 写入边界".to_string(),
detail: Some(sanitize_agent_runtime_text(&error, 240)),
detail: Some(truncate_agent_runtime_text(&error, 240)),
});
}
},
@@ -58,7 +58,7 @@ pub(in crate::agent) fn agent_role_project_path_mutation_block(
tool: tool.to_string(),
status: "blocked".to_string(),
summary: "无法核对 autonomous owner 写入边界".to_string(),
detail: Some(sanitize_agent_runtime_text(&error, 240)),
detail: Some(truncate_agent_runtime_text(&error, 240)),
});
}
}
@@ -93,7 +93,7 @@ pub(in crate::agent) fn agent_role_project_path_mutation_block(
tool: tool.to_string(),
status: "blocked".to_string(),
summary: "无法核对 autonomous owner 写入边界".to_string(),
detail: Some(sanitize_agent_runtime_text(&error, 240)),
detail: Some(truncate_agent_runtime_text(&error, 240)),
}),
}
}
@@ -150,7 +150,7 @@ pub(in crate::agent) fn observe_agent_runtime_file(
format!(
"{} | {}",
start_line + index,
sanitize_agent_runtime_text(line, 1_000)
truncate_agent_runtime_text(line, 1_000)
)
})
.collect::<Vec<_>>();
@@ -180,7 +180,7 @@ pub(in crate::agent) fn observe_agent_runtime_file(
result.path, start_line, end_line, total_lines
),
detail: Some(truncate_agent_runtime_text(
sanitize_prompt_context(&detail.join("\n")).as_str(),
&detail.join("\n"),
AGENT_RUNTIME_FILE_CONTEXT_MAX_CHARS,
)),
}
@@ -188,7 +188,7 @@ pub(in crate::agent) fn observe_agent_runtime_file(
Err(error) => AgentRuntimeToolObservation {
tool: "file.read".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -252,7 +252,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_write(
return AgentRuntimeToolObservation {
tool: "file.write".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -269,7 +269,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_write(
return AgentRuntimeToolObservation {
tool: "file.write".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -303,10 +303,8 @@ pub(in crate::agent) fn observe_agent_runtime_file_write(
{
return agent_runtime_mutation_gate_failure_observation(root, "file.write", &error);
}
let observation_content = truncate_agent_runtime_text(
sanitize_prompt_context(content).as_str(),
AGENT_RUNTIME_TOOL_WRITE_MAX_CHARS,
);
let observation_content =
truncate_agent_runtime_text(content, AGENT_RUNTIME_TOOL_WRITE_MAX_CHARS);
let result = write_local_project_file_at(root, &path, content).and_then(|written| {
append_agent_db_record(
root,
@@ -328,7 +326,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_write(
Err(error) => AgentRuntimeToolObservation {
tool: "file.write".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -358,7 +356,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_delete(
return AgentRuntimeToolObservation {
tool: "file.delete".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -377,7 +375,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_delete(
return AgentRuntimeToolObservation {
tool: "file.delete".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -415,7 +413,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_delete(
return AgentRuntimeToolObservation {
tool: "file.delete".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -430,7 +428,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_delete(
}),
);
if let Err(error) = audit_result {
let audit_error = redact_agent_runtime_project_paths(root, &error, 240);
let audit_error = truncate_agent_runtime_text(&error, 240);
if deleted.deleted {
return AgentRuntimeToolObservation {
tool: "file.delete".to_string(),
@@ -537,7 +535,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_patch(
return AgentRuntimeToolObservation {
tool: "file.patch".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -555,7 +553,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_patch(
return AgentRuntimeToolObservation {
tool: "file.patch".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -595,7 +593,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_patch(
return AgentRuntimeToolObservation {
tool: "file.patch".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -667,7 +665,7 @@ pub(in crate::agent) fn observe_agent_runtime_file_patch(
Err(error) => AgentRuntimeToolObservation {
tool: "file.patch".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -115,7 +115,7 @@ pub(crate) fn observe_agent_runtime_goal_contract(
tool: "agent.goal_contract".to_string(),
status: "rejected".to_string(),
summary: "根 Goal Contract 未写入".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 800)),
detail: Some(truncate_agent_runtime_text(&error, 800)),
},
}
}
@@ -169,7 +169,7 @@ pub(crate) fn observe_agent_runtime_acceptance_update(
tool: "agent.acceptance_update".to_string(),
status: "rejected".to_string(),
summary: "Acceptance Graph 更新被拒绝".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 800)),
detail: Some(truncate_agent_runtime_text(&error, 800)),
},
}
}
@@ -69,12 +69,9 @@ pub(in crate::agent) fn agent_runtime_memory_write_entry(
let title = if title.trim().is_empty() {
"运行结论".to_string()
} else {
sanitize_agent_runtime_text(title, 80)
truncate_agent_runtime_text(title, 80)
};
let content = truncate_agent_runtime_text(
sanitize_prompt_context(content).as_str(),
AGENT_RUNTIME_TOOL_OBSERVATION_MAX_CHARS,
);
let content = truncate_agent_runtime_text(content, AGENT_RUNTIME_TOOL_OBSERVATION_MAX_CHARS);
format!("## Agent {agent_id} - {title}\n\n{content}\n")
}
@@ -126,11 +123,10 @@ pub(in crate::agent) fn observation_from_text_result_with_truncation(
) -> AgentRuntimeToolObservation {
match result {
Ok(content) => {
let sanitized = sanitize_prompt_context(&content);
let detail = if preserve_tail {
truncate_agent_runtime_text_preserving_tail(sanitized.as_str(), max_chars)
truncate_agent_runtime_text_preserving_tail(content.as_str(), max_chars)
} else {
truncate_agent_runtime_text(sanitized.as_str(), max_chars)
truncate_agent_runtime_text(content.as_str(), max_chars)
};
AgentRuntimeToolObservation {
tool: tool.to_string(),
@@ -150,7 +146,7 @@ pub(in crate::agent) fn observation_from_text_result_with_truncation(
Err(error) => AgentRuntimeToolObservation {
tool: tool.to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -99,12 +99,12 @@ impl AgentRuntimeUiPrototypeAssessment {
return Err("UI 原型视觉检查 issues 不能超过 8 项".to_string());
}
for issue in &mut self.issues {
*issue = sanitize_agent_runtime_text(issue, 160);
*issue = truncate_agent_runtime_text(issue, 160);
if issue.trim().is_empty() {
return Err("UI 原型视觉检查 issue 不能为空".to_string());
}
}
self.summary = sanitize_agent_runtime_text(&self.summary, 500);
self.summary = truncate_agent_runtime_text(&self.summary, 500);
if self.summary.trim().is_empty() {
return Err("UI 原型视觉检查 summary 不能为空".to_string());
}
@@ -226,7 +226,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("image.inspect 输入无效:{error}"),
240,
),
@@ -255,7 +255,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: "image.inspect 无法取得一致项目快照".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -276,7 +276,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -287,7 +287,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -300,7 +300,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -313,7 +313,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -324,7 +324,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
.map(|image| format!("- {}", image.relative_path))
.collect::<Vec<_>>()
.join("\n");
let question = sanitize_agent_runtime_text(&question, MAX_QUESTION_CHARS);
let question = truncate_agent_runtime_text(&question, MAX_QUESTION_CHARS);
let inspection_focus = if ui_prototype_inspection {
prompt_text!("media.ui_inspection_focus").to_string()
} else if question.trim().is_empty() {
@@ -371,7 +371,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -394,11 +394,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
let raw_conclusion = redact_agent_runtime_image_data_urls(
strip_llm_thinking_blocks(response.text.as_str()).as_str(),
);
let raw_conclusion = redact_absolute_path_tokens(&redact_agent_runtime_project_paths(
root,
&raw_conclusion,
MAX_CONCLUSION_CHARS,
));
let raw_conclusion = truncate_agent_runtime_text(&raw_conclusion, MAX_CONCLUSION_CHARS);
if raw_conclusion.trim().is_empty() {
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
@@ -414,7 +410,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -430,7 +426,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
let response_id = response
.response_id
.as_deref()
.map(|value| sanitize_agent_runtime_text(value, 160))
.map(|value| truncate_agent_runtime_text(value, 160))
.filter(|value| !value.trim().is_empty());
// 视觉检查审计按 sha256 记录并复核「检查过的就是当前这张图」,摘要缺失必须失败关闭。
let mut image_metadata = Vec::with_capacity(images.len());
@@ -441,7 +437,7 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -477,14 +473,20 @@ pub(in crate::agent) async fn observe_agent_runtime_image_inspect(
"validationProfile": validation_profile,
"passed": passed,
"checks": checks,
"issues": issues,
// 审计记录自己脱敏;给模型的 observation 用原文。
"issues": issues.map(|values| {
values
.iter()
.map(|value| sanitize_agent_runtime_text(value, 160))
.collect::<Vec<_>>()
}),
}),
) {
return AgentRuntimeToolObservation {
tool: "image.inspect".to_string(),
status: "failed".to_string(),
summary: "视觉检查已返回,但审计元数据落盘失败".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
let detail = serde_json::to_string(&serde_json::json!({
@@ -601,7 +603,7 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
return AgentRuntimeToolObservation {
tool: "canvas.asset_generate".to_string(),
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
}
}
@@ -668,7 +670,7 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
return AgentRuntimeToolObservation {
tool: "canvas.asset_generate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -789,8 +791,7 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
return AgentRuntimeToolObservation {
tool: "canvas.asset_generate".to_string(),
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: redact_agent_runtime_project_paths(
root,
summary: truncate_agent_runtime_text(
&format!("External Editor 生成账本无法通过恢复预检:{error}"),
240,
),
@@ -841,8 +842,7 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
"failed"
}
.to_string(),
summary: redact_agent_runtime_project_paths(
root,
summary: truncate_agent_runtime_text(
&format!("canvas.asset_generate 外部请求前置校验失败,未发起新请求:{error}"),
240,
),
@@ -865,7 +865,7 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
tool: "canvas.asset_generate".to_string(),
status: platform_art_generation_observation_status(root, agent_id, run_id, &error)
.to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -879,7 +879,7 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
return AgentRuntimeToolObservation {
tool: "canvas.asset_generate".to_string(),
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -892,15 +892,14 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: "External Editor 已产生 durable 结果,但当前根 Run 已变化,未提交本地素材"
.to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
if let Err(error) = options.recover_interrupted_strict_transaction_locked_at(root, &_lock) {
return AgentRuntimeToolObservation {
tool: "canvas.asset_generate".to_string(),
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: redact_agent_runtime_project_paths(
root,
summary: truncate_agent_runtime_text(
&format!("无法在项目写锁内恢复中断的平台图集事务:{error}"),
240,
),
@@ -934,7 +933,6 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
output_path,
) {
return canvas_durable_result_reconciliation_observation(
root,
"External Editor 已产生 durable 结果,但替换资格复检失败,未提交本地素材",
&error,
);
@@ -949,7 +947,6 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
Ok(revision) => revision,
Err(error) => {
return canvas_durable_result_reconciliation_observation(
root,
"External Editor 已产生 durable 结果,但项目 revision 准备失败,未提交本地素材",
&error,
);
@@ -995,7 +992,6 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
});
if let Err(error) = verification {
return canvas_durable_result_reconciliation_observation(
root,
"美术素材已生成,但无法提交当前 revision 的验证凭证",
&error,
);
@@ -1051,14 +1047,13 @@ pub(in crate::agent) async fn observe_agent_runtime_platform_art_asset_generatio
tool: "canvas.asset_generate".to_string(),
status: platform_art_generation_observation_status(root, agent_id, run_id, &error)
.to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
}
fn canvas_durable_result_reconciliation_observation(
root: &Path,
summary: &str,
error: &str,
) -> AgentRuntimeToolObservation {
@@ -1066,7 +1061,7 @@ fn canvas_durable_result_reconciliation_observation(
tool: "canvas.asset_generate".to_string(),
status: AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION.to_string(),
summary: summary.to_string(),
detail: Some(redact_agent_runtime_project_paths(root, error, 500)),
detail: Some(truncate_agent_runtime_text(error, 500)),
}
}
@@ -168,7 +168,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_start(
return AgentRuntimeToolObservation {
tool: "command.start".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("command.start 输入无效:{error}"),
240,
),
@@ -188,7 +188,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_start(
return AgentRuntimeToolObservation {
tool: "command.start".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -197,7 +197,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_start(
return AgentRuntimeToolObservation {
tool: "command.start".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -219,7 +219,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_start(
tool: "command.start".to_string(),
status: "failed".to_string(),
summary: "command.start 无法取得项目执行锁".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -264,7 +264,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_start(
return AgentRuntimeToolObservation {
tool: "command.start".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -275,11 +275,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_start(
tool: "command.start".to_string(),
status: "failed".to_string(),
summary: "command.start 沙箱预检失败,进程未启动".to_string(),
detail: Some(redact_agent_runtime_project_paths(
root,
error.message(),
500,
)),
detail: Some(truncate_agent_runtime_text(error.message(), 500)),
};
}
};
@@ -293,7 +289,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_start(
detail: Some(
serde_json::json!({
"revisionAdvanced": false,
"error": redact_agent_runtime_project_paths(root, &error, 500),
"error": truncate_agent_runtime_text(&error, 500),
})
.to_string(),
),
@@ -340,7 +336,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_start(
serde_json::json!({
"revisionAdvanced": revision_advanced,
"launchFailureKind": error.stage().as_str(),
"error": redact_agent_runtime_project_paths(root, error.message(), 500),
"error": truncate_agent_runtime_text(error.message(), 500),
})
.to_string(),
),
@@ -396,7 +392,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_poll(
return AgentRuntimeToolObservation {
tool: "command.poll".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("command.poll 输入无效:{error}"),
240,
),
@@ -425,7 +421,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_poll(
return AgentRuntimeToolObservation {
tool: "command.poll".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -443,7 +439,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_poll(
return AgentRuntimeToolObservation {
tool: "command.poll".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -489,7 +485,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_stdin(
return AgentRuntimeToolObservation {
tool: "command.stdin".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("command.stdin 输入无效:{error}"),
240,
),
@@ -518,7 +514,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_stdin(
return AgentRuntimeToolObservation {
tool: "command.stdin".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -541,7 +537,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_stdin(
detail: Some(
serde_json::json!({
"processId": input.process_id,
"error": redact_agent_runtime_project_paths(root, &error, 500),
"error": truncate_agent_runtime_text(&error, 500),
})
.to_string(),
),
@@ -618,7 +614,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_terminate(
return AgentRuntimeToolObservation {
tool: "command.terminate".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(
summary: truncate_agent_runtime_text(
&format!("command.terminate 输入无效:{error}"),
240,
),
@@ -647,7 +643,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_terminate(
return AgentRuntimeToolObservation {
tool: "command.terminate".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -668,7 +664,7 @@ pub(in crate::agent) fn observe_agent_runtime_command_terminate(
detail: Some(
serde_json::json!({
"processId": input.process_id,
"error": redact_agent_runtime_project_paths(root, &error, 500),
"error": truncate_agent_runtime_text(&error, 500),
})
.to_string(),
),
@@ -9,7 +9,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_checkpoint(
return AgentRuntimeToolObservation {
tool: "project.checkpoint".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -27,7 +27,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_checkpoint(
Err(error) => AgentRuntimeToolObservation {
tool: "project.checkpoint".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -55,7 +55,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_restore(
return AgentRuntimeToolObservation {
tool: "project.restore".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -78,7 +78,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_restore(
Err(error) => AgentRuntimeToolObservation {
tool: "project.restore".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -126,7 +126,7 @@ where
tool: tool.to_string(),
status: "failed".to_string(),
summary: "project.patchset 无法取得项目写锁".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 240)),
detail: Some(truncate_agent_runtime_text(&error, 240)),
};
}
};
@@ -184,7 +184,7 @@ where
tool: tool.to_string(),
status: "failed".to_string(),
summary: "project.patchset 预检失败,未修改项目".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -200,7 +200,7 @@ where
tool: tool.to_string(),
status: "failed".to_string(),
summary: "project.patchset 无法读取项目 revision,未修改项目".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -211,7 +211,7 @@ where
tool: tool.to_string(),
status: "failed".to_string(),
summary: "project.patchset 自动 checkpoint 失败,未修改项目".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -235,7 +235,7 @@ where
detail: Some(format!(
"checkpointId={} · {}",
checkpoint.checkpoint_id,
redact_agent_runtime_project_paths(root, &error, 400)
truncate_agent_runtime_text(&error, 400)
)),
};
}
@@ -274,12 +274,12 @@ where
""
},
checkpoint.checkpoint_id,
redact_agent_runtime_project_paths(root, &error, 500),
truncate_agent_runtime_text(&error, 500),
audit
.err()
.map(|audit_error| format!(
" · auditError={}",
redact_agent_runtime_project_paths(root, &audit_error, 300)
truncate_agent_runtime_text(&audit_error, 300)
))
.unwrap_or_default()
);
@@ -322,7 +322,7 @@ where
"revisionAdvanced=true · checkpointId={} · revision={} · {}",
checkpoint.checkpoint_id,
revision_after,
redact_agent_runtime_project_paths(root, &error, 500)
truncate_agent_runtime_text(&error, 500)
)),
};
}
@@ -380,12 +380,12 @@ where
revision_after,
error.side_effect_applied(),
error.rollback_complete(),
redact_agent_runtime_project_paths(root, error.message(), 500),
truncate_agent_runtime_text(error.message(), 500),
audit
.err()
.map(|audit_error| format!(
" · auditError={}",
redact_agent_runtime_project_paths(root, &audit_error, 300)
truncate_agent_runtime_text(&audit_error, 300)
))
.unwrap_or_default()
)),
@@ -490,8 +490,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_diff(
tool: "project.diff".to_string(),
status: "ok".to_string(),
summary: format!("已对比 checkpoint {} 的内容", diff.checkpoint_id),
detail: Some(redact_agent_runtime_project_paths(
root,
detail: Some(truncate_agent_runtime_text(
&detail,
max_chars.saturating_add(256),
)),
@@ -500,7 +499,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_diff(
Err(error) => AgentRuntimeToolObservation {
tool: "project.diff".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
};
@@ -513,7 +512,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_diff(
status: "ok".to_string(),
summary: format!("已对比 checkpoint {}", diff.checkpoint_id),
detail: Some(truncate_agent_runtime_text(
sanitize_prompt_context(&detail).as_str(),
&detail,
AGENT_RUNTIME_TOOL_OBSERVATION_MAX_CHARS,
)),
}
@@ -521,7 +520,7 @@ pub(in crate::agent) fn observe_agent_runtime_project_diff(
Err(error) => AgentRuntimeToolObservation {
tool: "project.diff".to_string(),
status: "failed".to_string(),
summary: sanitize_agent_runtime_text(&error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -623,8 +622,7 @@ pub(in crate::agent) fn observe_agent_runtime_git_inspect(
inspect.unstaged.len(),
inspect.untracked.len()
),
detail: Some(redact_agent_runtime_project_paths(
root,
detail: Some(truncate_agent_runtime_text(
&detail,
max_chars.saturating_add(512),
)),
@@ -633,7 +631,7 @@ pub(in crate::agent) fn observe_agent_runtime_git_inspect(
Err(error) => AgentRuntimeToolObservation {
tool: "git.inspect".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 320),
summary: truncate_agent_runtime_text(&error, 320),
detail: None,
},
}
@@ -754,7 +752,7 @@ where
tool: tool.to_string(),
status: "verification-failed".to_string(),
summary: "当前 Agent 修改尚未形成可提交的验证凭证".to_string(),
detail: Some(redact_agent_runtime_project_paths(root, &error, 500)),
detail: Some(truncate_agent_runtime_text(&error, 500)),
};
}
};
@@ -782,11 +780,7 @@ where
"project.git_commit 未创建提交"
}
.to_string(),
detail: Some(redact_agent_runtime_project_paths(
root,
error.message(),
500,
)),
detail: Some(truncate_agent_runtime_text(error.message(), 500)),
};
}
};
@@ -826,7 +820,7 @@ where
);
detail.insert(
"auditError".to_string(),
serde_json::Value::String(redact_agent_runtime_project_paths(root, &error, 320)),
serde_json::Value::String(truncate_agent_runtime_text(&error, 320)),
);
}
return AgentRuntimeToolObservation {
@@ -45,7 +45,7 @@ pub(in crate::agent) fn observe_claimed_static_delegate_contract_at(
Err(error) => AgentRuntimeToolObservation {
tool: "agent.run_status".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -119,7 +119,6 @@ pub(crate) fn observe_agent_runtime_run_status(
// still surface as an error instead of being silently downgraded.
let relaxed_autonomous = autonomous_relaxed_run_at(root, agent_id, run_id)?;
if relaxed_autonomous {
let detail = sanitize_prompt_context(&detail);
return Ok((detail, 0, 0, 0, 0, None));
}
let collaboration_policy_status = (agent_id == GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID)
@@ -267,9 +266,9 @@ pub(crate) fn observe_agent_runtime_run_status(
// Ready payloads are complete evidence. The ordinary status summary may be shortened,
// but evidence must fit its budget before the corresponding claim is committed.
let base_detail = truncate_agent_runtime_text(
sanitize_prompt_context(&detail).as_str(),
&detail,
AGENT_RUNTIME_RUN_STATUS_BASE_DETAIL_MAX_CHARS,
);
);
let mut detail = base_detail;
if ready_delegate_count > 0 {
let payload = serde_json::to_string(&serde_json::json!({
@@ -282,7 +281,6 @@ pub(crate) fn observe_agent_runtime_run_status(
if let Some(payload) = ready_join_payload {
detail = format!("readyIsolatedJoins: {payload}\n\n{detail}");
}
let detail = sanitize_prompt_context(&detail);
let detail_chars = detail.chars().count();
if detail_chars > AGENT_RUNTIME_RUN_STATUS_OBSERVATION_MAX_CHARS {
return Err(format!(
@@ -353,7 +351,7 @@ pub(crate) fn observe_agent_runtime_run_status(
status: "ok".to_string(),
summary,
detail: Some(truncate_agent_runtime_text(
sanitize_prompt_context(&detail).as_str(),
&detail,
AGENT_RUNTIME_RUN_STATUS_OBSERVATION_MAX_CHARS,
)),
}
@@ -361,7 +359,7 @@ pub(crate) fn observe_agent_runtime_run_status(
Err(error) => AgentRuntimeToolObservation {
tool: "agent.run_status".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -396,7 +394,7 @@ pub(in crate::agent) fn format_agent_runtime_status_observation(
.plan
.iter()
.take(3)
.map(|item| sanitize_agent_runtime_text(item, 100))
.map(|item| truncate_agent_runtime_text(item, 100))
.collect::<Vec<_>>()
.join(" / ")
};
@@ -415,7 +413,7 @@ pub(in crate::agent) fn format_agent_runtime_status_observation(
let error = state
.error
.as_deref()
.map(|value| sanitize_agent_runtime_text(value, 160))
.map(|value| truncate_agent_runtime_text(value, 160))
.filter(|value| !value.trim().is_empty())
.unwrap_or_else(|| "-".to_string());
format!(
@@ -442,7 +440,7 @@ pub(in crate::agent) fn format_agent_runtime_status_observation(
}
pub(in crate::agent) fn agent_runtime_status_text(value: &str, max_chars: usize) -> String {
let value = sanitize_agent_runtime_text(value, max_chars);
let value = truncate_agent_runtime_text(value, max_chars);
if value.trim().is_empty() {
"-".to_string()
} else {
@@ -467,7 +465,7 @@ pub(in crate::agent) fn format_agent_runtime_active_plan_step_observation(
"#{} [{}] {}",
step.index + 1,
step.status,
sanitize_agent_runtime_text(&step.title, 120)
truncate_agent_runtime_text(&step.title, 120)
)
})
.unwrap_or_else(|| "-".to_string())
@@ -498,7 +496,7 @@ pub(in crate::agent) fn format_agent_runtime_task_observation(
task.run_id,
task.status,
task.phase,
sanitize_agent_runtime_text(&task.current_action, 120)
truncate_agent_runtime_text(&task.current_action, 120)
);
if let (Some(parent_agent_id), Some(parent_run_id)) = (
task.parent_agent_id.as_deref(),
@@ -519,7 +517,7 @@ pub(in crate::agent) fn format_agent_runtime_tool_call_observation(
"{} / {} / {}",
call.tool,
call.status,
sanitize_agent_runtime_text(&call.summary, 120)
truncate_agent_runtime_text(&call.summary, 120)
);
if let Some(input_summary) = call
.input_summary
@@ -528,7 +526,7 @@ pub(in crate::agent) fn format_agent_runtime_tool_call_observation(
{
output.push_str(&format!(
" / target={}",
sanitize_agent_runtime_text(input_summary, 160)
truncate_agent_runtime_text(input_summary, 160)
));
}
output
@@ -201,7 +201,7 @@ pub(in crate::agent) fn observe_agent_runtime_task_create(
return AgentRuntimeToolObservation {
tool: "task.create".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -212,7 +212,7 @@ pub(in crate::agent) fn observe_agent_runtime_task_create(
return AgentRuntimeToolObservation {
tool: "task.create".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -265,7 +265,7 @@ pub(in crate::agent) fn observe_agent_runtime_task_create(
Err(error) => AgentRuntimeToolObservation {
tool: "task.create".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -305,7 +305,7 @@ pub(in crate::agent) fn observe_agent_runtime_task_update(
return AgentRuntimeToolObservation {
tool: "task.update".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -316,7 +316,7 @@ pub(in crate::agent) fn observe_agent_runtime_task_update(
return AgentRuntimeToolObservation {
tool: "task.update".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -324,7 +324,7 @@ pub(in crate::agent) fn observe_agent_runtime_task_update(
return AgentRuntimeToolObservation {
tool: "task.update".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
};
}
@@ -360,7 +360,7 @@ pub(in crate::agent) fn observe_agent_runtime_task_update(
Err(error) => AgentRuntimeToolObservation {
tool: "task.update".to_string(),
status: "failed".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 240),
summary: truncate_agent_runtime_text(&error, 240),
detail: None,
},
}
@@ -35,11 +35,11 @@ pub(in crate::agent) async fn observe_agent_runtime_ui_design_doc_from_images(
let tool = UI_DESIGN_DOC_FROM_IMAGES_TOOL;
let arguments = match serde_json::from_value::<FromImagesArguments>(input.clone()) {
Ok(arguments) => arguments,
Err(error) => return rejected(root, tool, format!("{tool} 输入无效:{error}")),
Err(error) => return rejected(tool, format!("{tool} 输入无效:{error}")),
};
let expected_project_id = match game_creator_agent_runtime_context_project_id(root) {
Ok(project_id) => project_id,
Err(error) => return rejected(root, tool, error),
Err(error) => return rejected(tool, error),
};
let revision_before = read_game_creator_agent_runtime_project_revision(root)
.ok()
@@ -58,9 +58,7 @@ pub(in crate::agent) async fn observe_agent_runtime_ui_design_doc_from_images(
.await
{
Ok(created) => created,
Err(_) => {
return error_observation(root, tool, "后台创建 UI 设计文档任务未完成".to_string())
}
Err(_) => return error_observation(tool, "后台创建 UI 设计文档任务未完成".to_string()),
};
match created {
Ok(created) => {
@@ -88,7 +86,6 @@ pub(in crate::agent) async fn observe_agent_runtime_ui_design_doc_from_images(
}
}
Err(error) => error_observation_with_revision_advance(
root,
tool,
error,
project_revision_advance_since(root, revision_before),
@@ -105,11 +102,11 @@ pub(in crate::agent) async fn observe_agent_runtime_ui_design_doc_run_workflow(
let tool = UI_DESIGN_DOC_RUN_WORKFLOW_TOOL;
let arguments = match serde_json::from_value::<DesignDocArguments>(input.clone()) {
Ok(arguments) => arguments,
Err(error) => return rejected(root, tool, format!("{tool} 输入无效:{error}")),
Err(error) => return rejected(tool, format!("{tool} 输入无效:{error}")),
};
let expected_project_id = match game_creator_agent_runtime_context_project_id(root) {
Ok(project_id) => project_id,
Err(error) => return rejected(root, tool, error),
Err(error) => return rejected(tool, error),
};
let revision_before = read_game_creator_agent_runtime_project_revision(root)
.ok()
@@ -157,7 +154,6 @@ pub(in crate::agent) async fn observe_agent_runtime_ui_design_doc_run_workflow(
}
}
Err(error) => error_observation_with_revision_advance(
root,
tool,
error,
project_revision_advance_since(root, revision_before),
@@ -172,11 +168,11 @@ pub(in crate::agent) async fn observe_agent_runtime_ui_design_doc_into_js(
let tool = UI_DESIGN_DOC_INTO_JS_TOOL;
let arguments = match serde_json::from_value::<DesignDocArguments>(input.clone()) {
Ok(arguments) => arguments,
Err(error) => return rejected(root, tool, format!("{tool} 输入无效:{error}")),
Err(error) => return rejected(tool, format!("{tool} 输入无效:{error}")),
};
let expected_project_id = match game_creator_agent_runtime_context_project_id(root) {
Ok(project_id) => project_id,
Err(error) => return rejected(root, tool, error),
Err(error) => return rejected(tool, error),
};
// 生成代码要读整份文档、算 SHA-256 再落盘,同样是阻塞 IO,放到 blocking 线程池。
let project_path = root.to_string_lossy().into_owned();
@@ -191,9 +187,7 @@ pub(in crate::agent) async fn observe_agent_runtime_ui_design_doc_into_js(
.await
{
Ok(generated) => generated,
Err(_) => {
return error_observation(root, tool, "后台生成 UI 设计代码任务未完成".to_string())
}
Err(_) => return error_observation(tool, "后台生成 UI 设计代码任务未完成".to_string()),
};
match generated {
Ok(result) => AgentRuntimeToolObservation {
@@ -205,25 +199,25 @@ pub(in crate::agent) async fn observe_agent_runtime_ui_design_doc_into_js(
),
detail: serde_json::to_string(&result).ok(),
},
Err(error) => error_observation(root, tool, error),
Err(error) => error_observation(tool, error),
}
}
/// 输入解析失败或项目上下文缺失:统一脱敏,避免摘要把宿主路径带给 provider。
fn rejected(root: &Path, tool: &str, summary: String) -> AgentRuntimeToolObservation {
/// 输入解析失败或项目上下文缺失:只做长度收口,原文给模型,脱敏留给写审计/日志的那一份。
fn rejected(tool: &str, summary: String) -> AgentRuntimeToolObservation {
AgentRuntimeToolObservation {
tool: tool.to_string(),
status: "rejected".to_string(),
summary: redact_agent_runtime_project_paths(root, &summary, 240),
summary: truncate_agent_runtime_text(&summary, 240),
detail: None,
}
}
fn error_observation(root: &Path, tool: &str, error: String) -> AgentRuntimeToolObservation {
fn error_observation(tool: &str, error: String) -> AgentRuntimeToolObservation {
AgentRuntimeToolObservation {
tool: tool.to_string(),
status: "error".to_string(),
summary: redact_agent_runtime_project_paths(root, &error, 500),
summary: truncate_agent_runtime_text(&error, 500),
detail: None,
}
}
@@ -240,12 +234,11 @@ fn project_revision_advance_since(root: &Path, revision_before: Option<u64>) ->
}
fn error_observation_with_revision_advance(
root: &Path,
tool: &str,
error: String,
revision_advance: u64,
) -> AgentRuntimeToolObservation {
let mut observation = error_observation(root, tool, error);
let mut observation = error_observation(tool, error);
if revision_advance > 0 {
observation.detail =
Some(serde_json::json!({ "revisionAdvanceCount": revision_advance }).to_string());