Files
Genarrative/apps/ai-game-creator-shell/src-tauri/src/tool_plan_handoff.rs
T
lhk229 ec3a187dd7
Project CI / AI game creator shell Rust crates (push) Successful in 1m11s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m34s
Project CI / Backend tests (push) Successful in 4m46s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 8m31s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 9m41s
Project CI / Frontend tests (push) Successful in 2m19s
Project CI / Native shell tests (push) Successful in 7m5s
Project CI / AI game creator shell web tests (push) Successful in 1m54s
Project CI / Repository checks (push) Successful in 2m36s
处理编译大量warning问题 (#503)
Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/503
Co-authored-by: Linghong <ink29535@proton.me>
Co-committed-by: Linghong <ink29535@proton.me>
2026-09-24 13:01:31 +08:00

163 lines
5.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
mod content_validation;
mod discovery;
mod identity_order_validation;
mod ledger;
mod model;
mod storage_common;
#[cfg(unix)]
mod storage_unix;
#[cfg(windows)]
mod storage_windows;
#[cfg(test)]
mod tests;
mod thinking;
const TOOL_PLAN_HANDOFF_SAFE_DIAGNOSTIC_MARKER: &str = ";safeDiagnostic=";
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, Eq, PartialEq)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub(crate) struct AgentRuntimeToolPlanHandoffSafeDiagnostic {
pub(crate) function_class: String,
pub(crate) json_pointer: String,
pub(crate) path_shape: String,
pub(crate) relation_to_root: String,
pub(crate) duplicate_safe_json: bool,
pub(crate) hit_count: usize,
}
#[cfg(any(unix, windows))]
pub(crate) use discovery::list_at;
pub(crate) use ledger::{
ensure_capacity_for_request_at, is_later_repair_identity, lookup_at, read_for_run_at,
remove_at, write_at,
};
pub(crate) use model::{AgentRuntimeToolPlanHandoffEntry, AgentRuntimeToolPlanHandoffLookup};
#[cfg(test)]
pub(crate) use model::{AgentRuntimeToolPlanHandoffLedger, TOOL_PLAN_HANDOFF_SCHEMA_VERSION};
pub(crate) fn absolute_path_validation_error(
label: &str,
diagnostic: &AgentRuntimeToolPlanHandoffSafeDiagnostic,
) -> String {
let diagnostic = serde_json::to_string(diagnostic)
.unwrap_or_else(|_| "{\"diagnostic\":\"unavailable\"}".to_string());
format!(
"tool-plan 成功响应交接 {label} 的结构化输入包含绝对路径{TOOL_PLAN_HANDOFF_SAFE_DIAGNOSTIC_MARKER}{diagnostic}"
)
}
pub(crate) fn safe_failure_diagnostic(
error: &str,
) -> Option<AgentRuntimeToolPlanHandoffSafeDiagnostic> {
let (_, diagnostic) = error.split_once(TOOL_PLAN_HANDOFF_SAFE_DIAGNOSTIC_MARKER)?;
serde_json::from_str(diagnostic)
.ok()
.filter(valid_safe_failure_diagnostic)
}
fn valid_safe_failure_diagnostic(diagnostic: &AgentRuntimeToolPlanHandoffSafeDiagnostic) -> bool {
let function_class_valid = matches!(
diagnostic.function_class.as_str(),
"legacy-tool-plan"
| "other"
| "native:project.search"
| "native:file.list"
| "native:file.read"
| "native:file.write"
| "native:file.patch"
| "native:file.delete"
| "native:project.patchset"
| "native:project.git_commit"
| "native:command.exec"
| "native:command.start"
| "native:image.inspect"
| "native:canvas.asset_generate"
);
function_class_valid
&& valid_safe_json_pointer(&diagnostic.json_pointer)
&& matches!(
diagnostic.path_shape.as_str(),
"exact-absolute" | "exact-platform-absolute" | "file-uri" | "embedded-absolute"
)
&& matches!(
diagnostic.relation_to_root.as_str(),
"project-root" | "project-internal" | "external-or-unresolved" | "not-applicable"
)
&& (1..=4096).contains(&diagnostic.hit_count)
}
fn valid_safe_json_pointer(pointer: &str) -> bool {
if pointer == "#" {
return true;
}
if pointer.len() > 192 || !pointer.starts_with("#/") || !pointer.is_ascii() {
return false;
}
pointer[2..].split('/').all(|segment| {
[
"input",
"program",
"args",
"cwd",
"path",
"paths",
"changes",
"outputPath",
"output_path",
"expectedArtifacts",
"expected_artifacts",
"writeScopes",
"write_scopes",
"artifacts",
"children",
"scope",
"field",
"truncated",
]
.contains(&segment)
|| (segment.len() <= 4
&& !segment.is_empty()
&& segment.bytes().all(|byte| byte.is_ascii_digit()))
})
}
pub(crate) fn failure_kind(error: &str) -> &'static str {
if error.contains("敏感规则") || error.contains("敏感 JSON") {
"tool-plan-sensitive-content"
} else if error.contains("绝对路径") {
"tool-plan-absolute-path"
} else if error.contains("thinking") {
"tool-plan-thinking-normalization"
} else if error.contains("超过")
|| error.contains("不能为空")
|| error.contains("无效")
|| error.contains("不支持")
{
"tool-plan-response-shape"
} else if error.contains("slot")
|| error.contains("loop")
|| error.contains("repair")
|| error.contains("identity")
|| error.contains("顺序")
{
"tool-plan-identity-order"
} else if error.contains("写入")
|| error.contains("读取")
|| error.contains("创建")
|| error.contains("安装")
|| error.contains("目录")
|| error.contains("文件")
|| error.contains("权限")
{
"tool-plan-storage"
} else if error.contains("冲突")
|| error.contains("不匹配")
|| error.contains("不存在")
|| error.contains("损坏")
{
"tool-plan-integrity"
} else {
"tool-plan-unknown"
}
}