Files
Genarrative/apps/ai-game-creator-shell/src-tauri/src/agent/runtime_driver.rs
T
lhk229 1424c3ee5a
Project CI / AI game creator shell Rust crates (pull_request) Successful in 1m24s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m3s
Project CI / Backend tests (pull_request) Successful in 3m48s
Project CI / Frontend tests (pull_request) Successful in 1m49s
Project CI / Native shell tests (pull_request) Successful in 5m43s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 8m17s
Project CI / Repository checks (pull_request) Successful in 1m57s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m20s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 9m10s
清理测试编译中的未使用导入与辅助代码
限定 GUI 和平台测试导入的编译范围,删除多余导入与重导出
删除三个无调用的测试辅助函数,消除冗余赋值
补齐 DirectHome 命令工具禁用断言,明确测试路径校验参数用途
更新开发运维文档中的测试编译告警处理边界
2026-09-24 05:28:04 +00:00

492 lines
27 KiB
Rust

use super::*;
pub(super) static GAME_CREATOR_AGENT_RUNTIME_UPDATE_APP_HANDLE: OnceLock<tauri::AppHandle> =
OnceLock::new();
/// 同一 AppData 允许多个界面窗口同时挂载事件接收端,因此这里是按 token 去重的注册表。
pub(super) static GAME_CREATOR_MANIFEST_INVALIDATION_EVENT_SINKS: OnceLock<
std::sync::Mutex<Vec<GameCreatorManifestInvalidationEventSink>>,
> = OnceLock::new();
#[cfg(test)]
pub(super) static GAME_CREATOR_MANIFEST_INVALIDATION_EVENT_SINK_TEST_LOCK: std::sync::Mutex<()> =
std::sync::Mutex::new(());
pub(super) static STATIC_DELEGATE_PARENT_WAKE_SINGLEFLIGHT: OnceLock<
std::sync::Mutex<std::collections::BTreeMap<String, bool>>,
> = OnceLock::new();
pub(super) static AUTONOMOUS_MANIFEST_PARENT_WAKE_SINGLEFLIGHT: OnceLock<
std::sync::Mutex<std::collections::BTreeMap<String, bool>>,
> = OnceLock::new();
pub(super) static PROVIDER_RETRY_WAKE_SINGLEFLIGHT: OnceLock<
std::sync::Mutex<std::collections::BTreeSet<String>>,
> = OnceLock::new();
pub(super) static AGENT_RUNTIME_REAL_E2E_CHECKPOINT_TEMP_NONCE: AtomicU64 = AtomicU64::new(0);
pub(super) fn external_agent_runner_owns_background_execution() -> bool {
external_agent_runner_enabled() && !external_agent_runner_is_server_process()
}
pub(crate) const AGENT_RUNTIME_PENDING_ACTION_SCHEMA_VERSION: &str =
"game-creator-pending-action.v5";
pub(crate) const AGENT_RUNTIME_PENDING_ACTION_STATUS_PENDING: &str = "pending-confirmation";
pub(crate) const AGENT_RUNTIME_PENDING_ACTION_STATUS_WAITING_FOR_USER_INPUT: &str =
"waiting-for-user-input";
pub(crate) const AGENT_RUNTIME_PENDING_ACTION_STATUS_APPROVED: &str = "approved";
pub(crate) const AGENT_RUNTIME_PENDING_ACTION_STATUS_EXECUTING: &str = "executing";
pub(crate) const AGENT_RUNTIME_PENDING_ACTION_STATUS_OBSERVED_APPROVED: &str = "observed-approved";
pub(crate) const AGENT_RUNTIME_PENDING_ACTION_STATUS_OBSERVED_REJECTED: &str = "observed-rejected";
pub(crate) const AGENT_RUNTIME_TOOL_OBSERVATION_STATUS_NEEDS_RECONCILIATION: &str =
"needs-reconciliation";
pub(crate) const AGENT_RUNTIME_ACTION_EXECUTION_MODE_AUTO: &str = "auto";
pub(crate) const AGENT_RUNTIME_ACTION_EXECUTION_MODE_CONFIRMATION: &str = "confirmation";
pub(crate) const AGENT_RUNTIME_ACTION_FINGERPRINT_VERSION: &str = "sha256-serde-json-v2";
pub(crate) const AGENT_RUNTIME_CONTEXT_BUNDLE_SCHEMA_VERSION: &str =
"game-creator-runtime-context-bundle.v5";
pub(super) const AGENT_RUNTIME_CONTEXT_BUNDLE_PREVIOUS_SCHEMA_VERSION: &str =
"game-creator-runtime-context-bundle.v4";
pub(super) const AGENT_RUNTIME_CONTEXT_BUNDLE_LEGACY_SCHEMA_VERSION: &str =
"game-creator-runtime-context-bundle.v3";
pub(super) const AGENT_RUNTIME_CONTEXT_BUNDLE_OLDER_SCHEMA_VERSION: &str =
"game-creator-runtime-context-bundle.v2";
pub(crate) const AGENT_RUNTIME_PROJECT_REVISION_SCHEMA_VERSION: &str =
"game-creator-project-revision.v1";
pub(crate) const AGENT_RUNTIME_VERIFICATION_GATE_SCHEMA_VERSION: &str =
"game-creator-verification-gate.v1";
pub(super) const AGENT_RUNTIME_PROJECT_REVISION_RELATIVE_PATH: &str =
".agent/runtime/project-revision.json";
pub(super) const AGENT_RUNTIME_SIDECAR_MAX_BYTES: usize = 16 * 1024;
pub(super) const AGENT_RUNTIME_PENDING_ACTION_SIDECAR_MAX_BYTES: usize = 512 * 1024;
pub(super) const AGENT_RUNTIME_PARALLEL_READ_BATCH_SCHEMA_VERSION: &str =
"game-creator-parallel-read-batch.v1";
pub(super) const AGENT_RUNTIME_PARALLEL_READ_BATCH_STATUS_EXECUTING: &str = "executing";
pub(super) const AGENT_RUNTIME_PARALLEL_READ_BATCH_STATUS_OBSERVED: &str = "observed";
pub(super) const AGENT_RUNTIME_PARALLEL_READ_BATCH_SIDECAR_MAX_BYTES: usize = 4 * 1024 * 1024;
pub(crate) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_SCHEMA_VERSION: &str =
"game-creator-provider-action-batch.v3";
pub(super) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_PREVIOUS_SCHEMA_VERSION: &str =
"game-creator-provider-action-batch.v2";
pub(super) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_LEGACY_SCHEMA_VERSION: &str =
"game-creator-provider-action-batch.v1";
pub(super) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_STATUS_WAITING_CONFIRMATION: &str =
"waiting-confirmation";
pub(super) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_STATUS_READY: &str = "ready";
pub(super) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_STATUS_ABORTED: &str = "aborted";
pub(super) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_STATUS_SUPERSEDED: &str = "superseded";
pub(super) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_STATUS_COMPLETED: &str = "completed";
pub(super) const AGENT_RUNTIME_PROVIDER_ACTION_BATCH_SIDECAR_MAX_BYTES: usize = 4 * 1024 * 1024;
pub(super) const AGENT_RUNTIME_FINALIZATION_SIDECAR_MAX_BYTES: usize = 512 * 1024;
pub(super) const AGENT_RUNTIME_RESPONSE_STREAM_SCHEMA_VERSION: &str =
"game-creator-runtime-response-stream.v1";
pub(super) const AGENT_RUNTIME_RESPONSE_STREAM_SIDECAR_MAX_BYTES: usize = 256 * 1024;
pub(super) const AGENT_RUNTIME_RESPONSE_STREAM_MAX_CHARS: usize = 32_000;
pub(super) const AGENT_RUNTIME_RESPONSE_STREAM_PERSIST_INTERVAL: std::time::Duration =
std::time::Duration::from_millis(125);
pub(crate) const AGENT_RUNTIME_RESPONSE_STREAM_STATUS_STREAMING: &str = "streaming";
pub(crate) const AGENT_RUNTIME_RESPONSE_STREAM_STATUS_READY: &str = "ready";
pub(crate) const AGENT_RUNTIME_RESPONSE_STREAM_STATUS_COMMITTED: &str = "committed";
pub(crate) const AGENT_RUNTIME_RESPONSE_STREAM_STATUS_DISCARDED: &str = "discarded";
pub(crate) const AGENT_RUNTIME_RESPONSE_STREAM_STATUS_FAILED: &str = "failed";
pub(super) const AGENT_RUNTIME_STEER_SCHEMA_VERSION: &str = "game-creator-runtime-steer.v1";
pub(crate) const AGENT_RUNTIME_STEER_MAX_INSTRUCTION_BYTES: usize = 4 * 1024;
pub(super) const AGENT_RUNTIME_STEER_MAX_RUN_BYTES: usize = 16 * 1024;
pub(crate) const AGENT_RUNTIME_STEER_MAX_RUN_COUNT: usize = 16;
pub(super) const AGENT_RUNTIME_STEER_LEDGER_MAX_BYTES: usize = 256 * 1024;
pub(super) const AGENT_RUNTIME_VERIFICATION_STATUS_RUNNING: &str = "running";
pub(super) const AGENT_RUNTIME_VERIFICATION_STATUS_PASSED: &str = "passed";
pub(crate) const AGENT_RUNTIME_VERIFICATION_STATUS_FAILED: &str = "failed";
pub(crate) const AGENT_RUNTIME_CONTEXT_BUNDLE_OBSERVATION_LIMIT: usize = 2_048;
pub(crate) const AGENT_RUNTIME_CONTEXT_BUNDLE_MAX_BYTES: usize = 1024 * 1024;
pub(super) const AGENT_RUNTIME_CONTEXT_WINDOW_FINGERPRINT_LIMIT: usize =
AGENT_RUNTIME_BACKGROUND_LOOP_LIMIT * (AGENT_RUNTIME_BACKGROUND_TOOL_ACTION_LIMIT + 1);
pub(super) const AGENT_RUNTIME_CONTEXT_CONTENT_DIFF_DETAIL_MAX_CHARS: usize = 24_256;
pub(super) const AGENT_RUNTIME_GIT_INSPECT_DEFAULT_FILES: usize = 20;
pub(super) const AGENT_RUNTIME_GIT_INSPECT_MAX_FILES: usize = 50;
pub(super) const AGENT_RUNTIME_GIT_INSPECT_DEFAULT_CHARS: usize = 24_000;
pub(super) const AGENT_RUNTIME_GIT_INSPECT_MAX_CHARS: usize = 24_000;
pub(super) const AGENT_RUNTIME_DELEGATE_RECEIPT_SOURCE: &str = "agent-delegate-receipt";
pub(super) const AGENT_RUNTIME_DELEGATE_RECEIPT_TASK_MAX_CHARS: usize = 900;
pub(crate) const AGENT_RUNTIME_ISOLATED_CHILD_SOURCE: &str = "agent-isolated-child";
pub(crate) const AGENT_RUNTIME_ISOLATED_JOIN_SOURCE: &str = "agent-isolated-join";
pub(crate) const AGENT_RUNTIME_SUPERVISOR_GUI_SOURCE: &str = "project-supervisor-gui";
pub(crate) const AGENT_RUNTIME_SUPERVISOR_CLI_SOURCE: &str = "project-supervisor-cli";
pub(super) const AUTONOMOUS_GAME_BUILD_FIXED_TASK_GRAPH_STALLED_ERROR: &str =
"自主构建任务图无法继续推进";
pub(crate) fn agent_runtime_supervisor_source_is_trusted(source: &str) -> bool {
matches!(
source.trim(),
AGENT_RUNTIME_SUPERVISOR_GUI_SOURCE | AGENT_RUNTIME_SUPERVISOR_CLI_SOURCE
)
}
pub(crate) fn agent_runtime_supervisor_source_is_autonomous_game_build(source: &str) -> bool {
matches!(
source.trim(),
AGENT_RUNTIME_SUPERVISOR_GUI_SOURCE | AGENT_RUNTIME_SUPERVISOR_CLI_SOURCE
)
}
pub(super) const AGENT_RUNTIME_RUN_PROFILE_BINDING_SCHEMA_VERSION: &str =
"game-creator-run-profile-binding.v1";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_COMPLETION_CONTRACT_SCHEMA_VERSION: &str =
"game-creator-autonomous-completion-contract.v2";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_PLAYTEST_RECEIPT_SCHEMA_VERSION: &str =
"game-creator-autonomous-playtest-receipt.v2";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_GAME_INDEX_MAX_BYTES: u64 = 4 * 1024 * 1024;
pub(super) const AGENT_RUNTIME_AUTONOMOUS_BROWSER_EVIDENCE_MAX_BYTES: u64 = 16 * 1024 * 1024;
pub(super) const AGENT_RUNTIME_GAME_INDEX_PATH: &str = "game/index.html";
pub(super) const AGENT_RUNTIME_GAME_ENTRY_ROOT_PATH: &str = "index.html";
/// 判断一个项目相对路径是否当前游戏的入口(支持项目根 `index.html` 与
/// 旧布局 `game/index.html`)。
pub(super) fn is_agent_runtime_game_entry_relative_path(path: &str) -> bool {
path == AGENT_RUNTIME_GAME_ENTRY_ROOT_PATH || path == AGENT_RUNTIME_GAME_INDEX_PATH
}
/// 解析当前项目的实际游戏入口相对路径:项目根存在 `index.html` 时使用根入口,
/// 否则回退到旧布局 `game/index.html`。
pub(super) fn agent_runtime_game_entry_relative_path(root: &std::path::Path) -> &'static str {
if root.join(AGENT_RUNTIME_GAME_ENTRY_ROOT_PATH).is_file() {
AGENT_RUNTIME_GAME_ENTRY_ROOT_PATH
} else {
AGENT_RUNTIME_GAME_INDEX_PATH
}
}
pub(crate) const AGENT_RUNTIME_OWNER_ARTIFACT_VERIFICATION_TOOL: &str =
"runtime.owner_artifacts_validate";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_GAME_BUILD_AUTO_COMMAND_IDS: &[&str] = &[
"file.write",
"file.delete",
"project.patchset",
"project.verify",
"project.bootstrap",
"command.run_limited",
"preview.validate",
"canvas.asset_generate",
"canvas.asset_import",
"asset.register",
"agent.delegate",
"agent.spawn_isolated",
"agent.goal_contract",
"agent.acceptance_update",
"agent.run_status",
];
pub(crate) const AGENT_RUNTIME_TASK_MAX_CHARS: usize = 4_000;
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub(crate) struct AgentRuntimeTaskLink {
pub(crate) parent_agent_id: Option<String>,
pub(crate) parent_run_id: Option<String>,
pub(crate) delegation_id: Option<String>,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub(crate) struct AgentRuntimeRunProfileBinding {
pub(crate) schema_version: String,
pub(crate) project_id: String,
pub(crate) agent_id: String,
pub(crate) run_id: String,
pub(crate) root_agent_id: String,
pub(crate) root_run_id: String,
pub(crate) parent_agent_id: Option<String>,
pub(crate) parent_run_id: Option<String>,
pub(crate) source: String,
pub(crate) profile: String,
pub(crate) profile_fingerprint: String,
pub(crate) parent_binding_fingerprint: Option<String>,
pub(crate) binding_fingerprint: String,
pub(crate) bound_at: u64,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub(super) struct AgentRuntimeAutonomousCompletionContract {
pub(super) schema_version: String,
pub(super) project_id: String,
pub(super) agent_id: String,
pub(super) run_id: String,
pub(super) run_profile_binding_fingerprint: String,
pub(super) task_sha256: String,
pub(super) baseline_revision: u64,
pub(super) baseline_index_sha256: Option<String>,
pub(super) baseline_artifacts: Vec<AgentRuntimeAutonomousEvidenceDigest>,
pub(super) playtest_scenario: BrowserPlaytestScenario,
pub(super) contract_fingerprint: String,
pub(super) created_at: u64,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub(super) struct AgentRuntimeAutonomousEvidenceDigest {
pub(super) path: String,
pub(super) sha256: String,
pub(super) size_bytes: u64,
}
#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub(super) struct AgentRuntimeAutonomousPlaytestReceipt {
pub(super) schema_version: String,
pub(super) project_id: String,
pub(super) agent_id: String,
pub(super) run_id: String,
pub(super) run_profile_binding_fingerprint: String,
#[serde(default)]
pub(super) executor_agent_id: String,
#[serde(default)]
pub(super) executor_run_id: String,
#[serde(default)]
pub(super) executor_source: String,
#[serde(default)]
pub(super) executor_run_profile_binding_fingerprint: String,
pub(super) action_id: String,
pub(super) action_fingerprint: String,
pub(super) revision: u64,
pub(super) game_index: AgentRuntimeAutonomousEvidenceDigest,
pub(super) playtest_scenario: BrowserPlaytestScenario,
pub(super) scenario_fingerprint: String,
pub(super) report: AgentRuntimeAutonomousEvidenceDigest,
pub(super) screenshots: Vec<AgentRuntimeAutonomousEvidenceDigest>,
pub(super) receipt_fingerprint: String,
pub(super) created_at: u64,
}
#[path = "runtime_protocol/acceptance_graph.rs"]
mod acceptance_graph;
mod art_manifest_contract;
mod entrypoints;
mod finalization;
#[path = "runtime_protocol/goal_contract.rs"]
mod goal_contract;
mod interaction;
mod lifecycle_control;
mod main_loop;
mod pending_execution;
mod pending_recovery;
mod provider_recovery;
mod recovery_scan;
mod task_queue;
mod task_start;
pub(crate) use acceptance_graph::*;
pub(in crate::agent) use art_manifest_contract::*;
pub(in crate::agent) use entrypoints::*;
pub(in crate::agent) use finalization::*;
pub(crate) use goal_contract::*;
pub(in crate::agent) use interaction::*;
pub(in crate::agent) use lifecycle_control::*;
pub(in crate::agent) use main_loop::*;
pub(in crate::agent) use pending_execution::*;
pub(in crate::agent) use pending_recovery::*;
pub(in crate::agent) use provider_recovery::*;
pub(in crate::agent) use recovery_scan::*;
pub(crate) use task_queue::*;
pub(in crate::agent) use task_start::*;
#[cfg(test)]
pub(crate) use entrypoints::acquire_game_creator_manifest_invalidation_event_sink_test_guard;
#[allow(unused_imports)]
pub(crate) use entrypoints::{
chat_with_game_creator_agent_at, chat_with_game_creator_role_agent_at,
chat_with_game_creator_role_agent_for_session_at,
chat_with_game_creator_role_agent_runtime_for_session_at,
chat_with_game_creator_role_agent_stream_for_session_at, emit_direct_game_creator_progress,
emit_game_creator_agent_runtime_update, emit_game_creator_manifest_invalidated,
game_creator_agent_runtime_update_event, generate_local_game_draft_at,
read_game_creator_agent_runtime_at, read_game_creator_agent_runtime_for_session_at,
read_game_creator_agent_runtimes_at, register_game_creator_manifest_invalidation_event_sink,
set_game_creator_agent_runtime_update_app_handle,
start_game_creator_manifest_invalidation_event_sink,
validate_game_creator_manifest_invalidation_event_sink,
};
#[cfg(test)]
pub(crate) use finalization::resume_game_creator_agent_finalization_for_test_at;
pub(crate) use finalization::AgentRuntimePendingActionResume;
#[cfg(test)]
pub(crate) use interaction::agent_runtime_tool_requires_repository_context_fingerprint_gate;
pub(crate) use interaction::{
answer_game_creator_agent_runtime_user_input_at, confirm_game_creator_agent_runtime_task_at,
pending_repository_context_drift_observation, reject_game_creator_agent_runtime_task_at,
};
#[cfg(test)]
pub(crate) use lifecycle_control::resolve_game_creator_agent_runtime_retry_configuration_at;
pub(crate) use lifecycle_control::{
append_game_creator_agent_runtime_queued_cancellation,
cancel_game_creator_agent_runtime_task_at,
game_creator_agent_runtime_run_is_non_terminal_for_collaboration_migration_at,
pause_game_creator_agent_runtime_for_goal_at,
refresh_game_creator_agent_goal_runtime_projection_at,
resume_game_creator_agent_runtime_for_goal_at, retry_game_creator_agent_runtime_task_at,
};
pub(crate) use pending_execution::{
continue_game_creator_agent_pending_tool_action,
persist_agent_runtime_reconciliation_observation_before_cancellation,
};
pub(crate) use pending_recovery::resume_game_creator_agent_pending_tool_action_at;
#[cfg(test)]
pub(crate) use pending_recovery::resume_game_creator_agent_provider_action_batch_for_test_at;
#[cfg(test)]
pub(crate) use provider_recovery::{
autonomous_manifest_parent_wake_error_is_transient,
drive_waiting_autonomous_manifest_parent_wake_budget_for_test,
ensure_static_delegate_user_input_wait_at, ensure_waiting_provider_retry_records_for_test,
mark_autonomous_manifest_parent_wake_needs_reconciliation_for_test,
prepare_waiting_autonomous_manifest_parent_for_test,
probe_static_delegate_parent_wake_singleflight_coalescing,
repair_autonomous_manifest_parent_wake_reconciliation_projection_for_test,
};
pub(crate) use provider_recovery::{
schedule_waiting_autonomous_manifest_parent_wake_after_lane_release,
schedule_waiting_static_delegate_parent_wake_after_lane_release,
static_delegate_parent_wake_error_is_transient,
};
pub(crate) use recovery_scan::{
cleanup_game_creator_agent_runtime_completed_finalizations_at,
has_recoverable_game_creator_agent_background_tasks_at,
resume_game_creator_agent_background_tasks_at,
resume_game_creator_agent_pending_action_for_agent_at,
wake_pending_game_creator_agent_background_tasks_at,
};
#[cfg(test)]
pub(crate) use task_queue::agent_runtime_background_worker_threads_for_test;
#[cfg(test)]
pub(crate) use task_queue::drain_next_game_creator_agent_background_tasks_for_test;
pub(crate) use task_queue::{
run_game_creator_agent_background_task_with_context,
spawn_next_game_creator_agent_background_task_drain,
spawn_next_game_creator_agent_background_task_drain_with_lock,
spawn_started_game_creator_agent_background_task_drain_with_lock,
};
pub(crate) use task_start::{
autonomous_game_build_root_task_is_active, current_autonomous_game_build_root_task_at,
notify_external_agent_runner_after_background_task_enqueue,
project_autonomous_manifest_ready_task_terminal_at,
schedule_autonomous_game_build_ready_tasks_at, schedule_game_creator_agent_ready_tasks_at,
start_game_creator_agent_background_task_at,
start_game_creator_agent_goal_task_in_session_lane_at,
start_game_creator_supervisor_background_task_for_session_at,
};
#[cfg(test)]
pub(crate) use task_start::{
start_game_creator_agent_background_task_for_session_at,
start_game_creator_agent_background_task_with_session_lane_hook_at,
};
pub(crate) const AGENT_RUNTIME_BACKGROUND_LOOP_LIMIT: usize = 6;
pub(crate) const AGENT_RUNTIME_BACKGROUND_TOOL_ACTION_LIMIT: usize = 3;
pub(crate) const AGENT_RUNTIME_FINALIZATION_SCHEMA_VERSION: &str =
"game-creator-runtime-finalization.v4";
pub(super) const AGENT_RUNTIME_FINALIZATION_PREVIOUS_SCHEMA_VERSION: &str =
"game-creator-runtime-finalization.v3";
pub(super) const AGENT_RUNTIME_FINALIZATION_LEGACY_SCHEMA_VERSION: &str =
"game-creator-runtime-finalization.v2";
pub(super) const AGENT_RUNTIME_FINALIZATION_OLDER_SCHEMA_VERSION: &str =
"game-creator-runtime-finalization.v1";
pub(crate) const AGENT_RUNTIME_FINALIZATION_STATUS_PREPARED: &str = "prepared";
pub(super) const AGENT_RUNTIME_FINALIZATION_STATUS_ASSISTANT_PERSISTED: &str =
"assistant-persisted";
pub(super) const AGENT_RUNTIME_FINALIZATION_STATUS_RUNTIME_COMPLETED: &str = "runtime-completed";
pub(super) const AGENT_RUNTIME_PROVIDER_REQUEST_LIFECYCLE_SCHEMA_VERSION: &str =
"game-creator-provider-request-lifecycle.v2";
pub(super) const AGENT_RUNTIME_PROVIDER_REQUEST_LIFECYCLE_RECORD_TYPE: &str =
"agent.runtime.provider_request.lifecycle";
pub(super) const AGENT_RUNTIME_PROVIDER_REQUEST_RECONCILIATION_PREFIX: &str =
"provider-request-needs-reconciliation";
pub(super) const AGENT_RUNTIME_PROVIDER_TRANSIENT_ERROR_PREFIX: &str =
"agent-runtime-provider-transient-error:";
#[cfg(test)]
pub(super) const AGENT_RUNTIME_PROVIDER_HANDOFF_TEST_STOP: &str =
"agent-runtime-provider-handoff-test-stop";
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_SENTINEL_FILE_NAME: &str =
".agent-runtime-real-e2e-supervisor-swarm-tool-plan-handoff-runner-kill-appdata.json";
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_SENTINEL_SCHEMA_VERSION: &str =
"genarrative-agent-runtime-real-e2e-supervisor-swarm-tool-plan-handoff-runner-kill-appdata.v1";
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_CONTROL_FILE_NAME: &str =
".agent-runtime-real-e2e-tool-plan-handoff-checkpoint.json";
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_CONTROL_SCHEMA_VERSION: &str =
"game-creator-tool-plan-handoff-runner-kill-checkpoint.v1";
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_ACK_FILE_NAME: &str =
".agent-runtime-real-e2e-tool-plan-handoff-checkpoint-reached.json";
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_ACK_SCHEMA_VERSION: &str =
"game-creator-tool-plan-handoff-runner-kill-checkpoint-reached.v1";
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_MAX_BYTES: u64 = 16 * 1024;
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_POLL_MS: u64 = 50;
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_MAX_TTL_MS: u64 = 10 * 60 * 1_000;
pub(super) const AGENT_RUNTIME_REAL_E2E_TOOL_PLAN_CHECKPOINT_ERROR: &str =
"agent-runtime-real-e2e-tool-plan-handoff-checkpoint-needs-reconciliation";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_TOOL_PLAN_FORMAT_REPAIR_ATTEMPTS: usize = 4;
pub(super) const AGENT_RUNTIME_AUTONOMOUS_FORCED_ACTION_MAX_OUTPUT_TOKENS: u32 = 2_000;
pub(crate) const AGENT_RUNTIME_AUTONOMOUS_SCAFFOLD_MAX_OUTPUT_TOKENS: u32 = 2_600;
pub(crate) const AGENT_RUNTIME_AUTONOMOUS_TRUNCATED_SCAFFOLD_MAX_OUTPUT_TOKENS: u32 = 8_000;
pub(super) const AGENT_RUNTIME_AUTONOMOUS_SCAFFOLD_SOURCE_MAX_CHARS: usize = 6_000;
pub(crate) const AGENT_RUNTIME_AUTONOMOUS_PRE_MUTATION_LOOP_LIMIT: usize = 4;
pub(crate) const AGENT_RUNTIME_AUTONOMOUS_LIVENESS_OBSERVATION_LIMIT: usize = 3;
pub(super) const AGENT_RUNTIME_AUTONOMOUS_LIVENESS_ERROR_PREFIX: &str =
"自主构建专业 Agent 在首次项目修改前最多允许";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_PENDING_VERIFICATION_LIVENESS_ERROR_PREFIX: &str =
"自主构建专业 Agent 的最近一次项目修改仍未通过验证";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_REVERIFY_AFTER_MUTATION_LIVENESS_ERROR_PREFIX: &str =
"自主构建专业 Agent 的最近一次项目修改尚未重新验证";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_VERIFIED_DELIVERY_LIVENESS_ERROR_PREFIX: &str =
"自主构建专业 Agent 已取得当前 revision 的通过凭证";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_FAILED_PLAYTEST_LIVENESS_ERROR_PREFIX: &str =
"自主构建 Project Supervisor 的最近一次交互试玩仍未通过";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_DELEGATED_PLAYTEST_REPAIR_LIVENESS_ERROR_PREFIX: &str =
"自主构建 Project Supervisor 的最近一次交互试玩需要专业 Agent 修复";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_MANIFEST_DAG_WAIT_LIVENESS_ERROR_PREFIX: &str =
"自主构建 manifest DAG 仍在执行";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_RESPONSE_PLAN_LIVENESS_ERROR_PREFIX: &str =
"自主构建专业 Agent 已给出结论但结构化计划仍未完成";
pub(super) const AGENT_RUNTIME_AUTONOMOUS_TRUNCATED_SCAFFOLD_ERROR_PREFIX: &str =
"自主构建完整写入 game/index.html 时必须提交闭合且可运行的 HTML";
pub(super) const AGENT_RUNTIME_QUALITY_REVIEW_AGENT_ID: &str = "quality-review";
pub(super) const AGENT_RUNTIME_SUPERVISOR_INITIAL_COLLABORATION_LIVENESS_ERROR_PREFIX: &str =
"Project Supervisor 首批协作在首个 planning 窗口内未建立";
pub(crate) const AGENT_RUNTIME_AUTONOMOUS_TOOL_PLAN_PAYLOAD_GUIDANCE: &str =
prompt_text!("execution.planning.sourcePayloadGuidance");
pub(super) const AGENT_RUNTIME_PROVIDER_TRANSIENT_BACKOFF_MAX_MS: u64 = 30_000;
pub(super) const AGENT_RUNTIME_FINALIZATION_LIFECYCLE_RECORD_TYPE: &str =
"agent.runtime.finalization.lifecycle";
pub(super) const AGENT_RUNTIME_FINALIZATION_LIFECYCLE_SCHEMA_VERSION: &str =
"game-creator-finalization-lifecycle.v1";
pub(super) const AGENT_RUNTIME_FINALIZATION_RESPONSE_MAX_CHARS: usize = 32_000;
pub(crate) const AGENT_RUNTIME_TOOL_PLAN_FUNCTION_NAME: &str = "submit_agent_tool_plan";
pub(super) const AGENT_RUNTIME_RECENT_TOOL_CALL_LIMIT: usize = 20;
pub(crate) const AGENT_RUNTIME_ACTION_RECEIPT_RECORD_TYPE: &str = "agent.runtime.action_receipt";
pub(super) const AGENT_RUNTIME_ACTION_HISTORY_DEFAULT_LIMIT: usize = 5;
pub(super) const AGENT_RUNTIME_ACTION_HISTORY_MAX_LIMIT: usize = 10;
pub(super) const AGENT_RUNTIME_ACTION_HISTORY_MAX_DB_BYTES: u64 = 32 * 1024 * 1024;
pub(crate) const AGENT_RUNTIME_ACTION_HISTORY_MAX_OUTPUT_CHARS: usize = 7_200;
pub(super) const AGENT_RUNTIME_ACTION_RECEIPT_SAFE_DETAIL_MAX_CHARS: usize = 500;
pub(crate) const AGENT_RUNTIME_PLAN_STEP_LIMIT: usize = 8;
pub(super) const AGENT_RUNTIME_PLAN_STATUS_PENDING: &str = "pending";
pub(super) const AGENT_RUNTIME_PLAN_STATUS_IN_PROGRESS: &str = "in_progress";
pub(crate) const AGENT_RUNTIME_PLAN_STATUS_COMPLETED: &str = "completed";
pub(super) const AGENT_RUNTIME_PLAN_STATUS_FAILED: &str = "failed";
pub(super) const AGENT_RUNTIME_TOOL_OBSERVATION_MAX_CHARS: usize = 900;
pub(super) const AGENT_RUNTIME_RUN_STATUS_OBSERVATION_MAX_CHARS: usize = 16_000;
pub(super) const AGENT_RUNTIME_RUN_STATUS_BASE_DETAIL_MAX_CHARS: usize = 3_500;
pub(super) const AGENT_RUNTIME_READY_ISOLATED_JOIN_MIXED_PAYLOAD_MAX_CHARS: usize = 6_000;
pub(super) const AGENT_RUNTIME_READY_ISOLATED_JOIN_PAYLOAD_MAX_CHARS: usize = 10_000;
pub(super) const AGENT_RUNTIME_DELEGATE_CONTRACT_OBSERVATION_MAX_CHARS: usize = 20_000;
pub(super) const AGENT_RUNTIME_COMMAND_OUTPUT_CONTEXT_MAX_CHARS: usize = 64_000;
pub(super) const AGENT_RUNTIME_PROCESS_POLL_CONTEXT_MAX_CHARS: usize = 32_000;
pub(super) const AGENT_RUNTIME_TOOL_WRITE_MAX_CHARS: usize = 12_000;
pub(super) const AGENT_RUNTIME_TOOL_PLAN_MAX_OUTPUT_TOKENS: u32 = 4_000;
pub(super) const AGENT_RUNTIME_FINAL_REPLY_MAX_OUTPUT_TOKENS: u32 = 2_400;
pub(crate) const AGENT_RUNTIME_TOOL_PLAN_FORMAT_REPAIR_ATTEMPTS: usize = 2;
pub(super) const AGENT_RUNTIME_FILE_CONTEXT_MAX_CHARS: usize = 8_000;
pub(super) const AGENT_RUNTIME_FILE_READ_DEFAULT_LINES: usize = 120;
pub(super) const AGENT_RUNTIME_FILE_READ_MAX_LINES: usize = 240;
pub(super) const AGENT_RUNTIME_PROJECT_SEARCH_DEFAULT_RESULTS: usize = 20;
pub(super) const AGENT_RUNTIME_PROJECT_SEARCH_MAX_RESULTS: usize = 50;
pub(super) const AGENT_RUNTIME_PROJECT_SEARCH_MAX_FILES: usize = 500;
pub(super) const AGENT_RUNTIME_PROJECT_SEARCH_MAX_ENTRIES: usize = 5_000;
pub(super) const AGENT_RUNTIME_PROJECT_SEARCH_MAX_FILE_BYTES: u64 = 512 * 1024;
pub(super) const AGENT_RUNTIME_FILE_PATCH_MAX_FRAGMENT_BYTES: usize = 64 * 1024;
pub(super) const AGENT_RUNTIME_FILE_PATCH_MAX_FILE_BYTES: usize = 2 * 1024 * 1024;
pub(super) const AGENT_RUNTIME_PROJECT_DIFF_CONTENT_DEFAULT_FILES: usize = 20;
pub(super) const AGENT_RUNTIME_PROJECT_DIFF_CONTENT_MAX_FILES: usize = 50;
pub(super) const AGENT_RUNTIME_PROJECT_DIFF_CONTENT_DEFAULT_CHARS: usize = 24_000;
pub(super) const AGENT_RUNTIME_PROJECT_DIFF_CONTENT_MAX_CHARS: usize = 24_000;
pub(super) const AGENT_RUNTIME_PROJECT_VERIFY_DEFAULT_TIMEOUT_SECONDS: usize = 120;