@team-agent/installer 0.5.60 → 0.5.62
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +1 -1
- package/Cargo.toml +1 -1
- package/crates/team-agent/src/cli/adapters.rs +49 -3
- package/crates/team-agent/src/cli/attach_app_server_leader.rs +1 -0
- package/crates/team-agent/src/cli/diagnose.rs +184 -0
- package/crates/team-agent/src/cli/emit.rs +104 -21
- package/crates/team-agent/src/cli/helpers.rs +1 -0
- package/crates/team-agent/src/cli/leader.rs +14 -2
- package/crates/team-agent/src/cli/leaders.rs +2 -0
- package/crates/team-agent/src/cli/mod.rs +296 -8
- package/crates/team-agent/src/cli/named_address.rs +26 -2
- package/crates/team-agent/src/cli/profile.rs +2 -1
- package/crates/team-agent/src/cli/send/coordinator.rs +1 -0
- package/crates/team-agent/src/cli/send/mailbox.rs +3 -0
- package/crates/team-agent/src/cli/send/persist.rs +1 -0
- package/crates/team-agent/src/cli/send/presentation.rs +3 -0
- package/crates/team-agent/src/cli/send/resolve.rs +206 -1
- package/crates/team-agent/src/cli/send.rs +2 -1
- package/crates/team-agent/src/cli/spec.rs +5 -1
- package/crates/team-agent/src/cli/status.rs +2 -1
- package/crates/team-agent/src/cli/status_port/compact.rs +1 -0
- package/crates/team-agent/src/cli/status_port/format.rs +1 -0
- package/crates/team-agent/src/cli/status_port/inbox.rs +1 -0
- package/crates/team-agent/src/cli/status_port/store.rs +7 -3
- package/crates/team-agent/src/cli/tests/named_address.rs +65 -0
- package/crates/team-agent/src/cli/tests/verb_profile.rs +38 -0
- package/crates/team-agent/src/cli/types.rs +36 -2
- package/crates/team-agent/src/communication_mode/mod.rs +54 -0
- package/crates/team-agent/src/compiler/tests.rs +5 -5
- package/crates/team-agent/src/compiler.rs +54 -1
- package/crates/team-agent/src/conpty/backend.rs +1 -0
- package/crates/team-agent/src/conpty/mod.rs +1 -0
- package/crates/team-agent/src/coordinator/backoff.rs +5 -8
- package/crates/team-agent/src/coordinator/conpty_shim.rs +3 -2
- package/crates/team-agent/src/coordinator/health.rs +1 -0
- package/crates/team-agent/src/coordinator/mod.rs +2 -2
- package/crates/team-agent/src/coordinator/orphan.rs +4 -116
- package/crates/team-agent/src/coordinator/runtime_detectors.rs +1 -0
- package/crates/team-agent/src/coordinator/runtime_observation.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/abnormal.rs +6 -5
- package/crates/team-agent/src/coordinator/steps/delivery.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/health_sync.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/mod.rs +2 -0
- package/crates/team-agent/src/coordinator/steps/persist.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/runtime_prompts.rs +1 -0
- package/crates/team-agent/src/coordinator/steps/session_gate.rs +1 -0
- package/crates/team-agent/src/coordinator/tests/abnormal.rs +0 -174
- package/crates/team-agent/src/coordinator/tests/api_error_recovery.rs +0 -9
- package/crates/team-agent/src/coordinator/tests/basics.rs +0 -184
- package/crates/team-agent/src/coordinator/tests/mod.rs +2 -17
- package/crates/team-agent/src/coordinator/tests/tick_core.rs +0 -42
- package/crates/team-agent/src/coordinator/tick.rs +24 -28
- package/crates/team-agent/src/coordinator/types.rs +3 -176
- package/crates/team-agent/src/db/agent_health_capture.rs +1 -0
- package/crates/team-agent/src/db/message_store.rs +47 -2
- package/crates/team-agent/src/db/migration.rs +5 -4
- package/crates/team-agent/src/db/mod.rs +1 -0
- package/crates/team-agent/src/db/schema.rs +1 -0
- package/crates/team-agent/src/diagnose/comms.rs +2 -1
- package/crates/team-agent/src/diagnose/mod.rs +1 -0
- package/crates/team-agent/src/diagnose/orphans.rs +1 -0
- package/crates/team-agent/src/fake_worker.rs +21 -1
- package/crates/team-agent/src/layout/manager.rs +3 -7
- package/crates/team-agent/src/layout/mod.rs +2 -2
- package/crates/team-agent/src/layout/overlay.rs +6 -1
- package/crates/team-agent/src/layout/placement.rs +1 -0
- package/crates/team-agent/src/layout/recovery.rs +3 -0
- package/crates/team-agent/src/layout/runtime_sessions.rs +8 -3
- package/crates/team-agent/src/layout/sessions.rs +8 -1
- package/crates/team-agent/src/layout/tmux_endpoint.rs +3 -0
- package/crates/team-agent/src/layout/worker_env.rs +3 -0
- package/crates/team-agent/src/layout/worker_window_helpers.rs +2 -0
- package/crates/team-agent/src/leader/helpers.rs +1 -0
- package/crates/team-agent/src/leader/incident.rs +1 -0
- package/crates/team-agent/src/leader/lease.rs +27 -22
- package/crates/team-agent/src/leader/mod.rs +2 -3
- package/crates/team-agent/src/leader/owner_bind.rs +13 -3
- package/crates/team-agent/src/leader/provider_attribution.rs +1 -0
- package/crates/team-agent/src/leader/rediscover.rs +4 -17
- package/crates/team-agent/src/leader/registry.rs +3 -15
- package/crates/team-agent/src/leader/start.rs +1072 -186
- package/crates/team-agent/src/leader/takeover.rs +10 -232
- package/crates/team-agent/src/leader/tests/claim_leader_mailbox_flush_contract.rs +544 -0
- package/crates/team-agent/src/leader/tests/historical_inventory_upgrade_gate_red.rs +624 -0
- package/crates/team-agent/src/leader/tests/identity.rs +71 -59
- package/crates/team-agent/src/leader/tests/identity_session_names.rs +42 -0
- package/crates/team-agent/src/leader/tests/idle.rs +0 -193
- package/crates/team-agent/src/leader/tests/lease_api.rs +0 -45
- package/crates/team-agent/src/leader/tests/mod.rs +4 -41
- package/crates/team-agent/src/leader/tests/rehomed_env.rs +83 -0
- package/crates/team-agent/src/leader/tests/team_in_team_state_scope_red.rs +1273 -0
- package/crates/team-agent/src/leader/tests/terminal_and_replay_vs_rerender_invariants_red.rs +417 -0
- package/crates/team-agent/src/leader/tests/wake_start_owner.rs +22 -103
- package/crates/team-agent/src/leader/types.rs +1 -28
- package/crates/team-agent/src/lib.rs +7 -0
- package/crates/team-agent/src/lifecycle/display.rs +7 -1
- package/crates/team-agent/src/lifecycle/helpers.rs +3 -1
- package/crates/team-agent/src/lifecycle/launch/add_agent.rs +2 -2
- package/crates/team-agent/src/lifecycle/launch/fork_agent/completion.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch/fork_agent.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/fork_entry.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch/fork_finalize.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch/plan.rs +2 -2
- package/crates/team-agent/src/lifecycle/launch/quick_start.rs +4 -26
- package/crates/team-agent/src/lifecycle/launch/readiness.rs +0 -27
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +2 -28
- package/crates/team-agent/src/lifecycle/launch/spec_state.rs +4 -32
- package/crates/team-agent/src/lifecycle/launch/state_projection.rs +1 -0
- package/crates/team-agent/src/lifecycle/launch.rs +11 -12
- package/crates/team-agent/src/lifecycle/mod.rs +2 -1
- package/crates/team-agent/src/lifecycle/restart/agent.rs +4 -4
- package/crates/team-agent/src/lifecycle/restart/common.rs +1 -1
- package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +2 -2
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +13 -5
- package/crates/team-agent/src/lifecycle/restart/remove.rs +1 -1
- package/crates/team-agent/src/lifecycle/restart/selection.rs +3 -3
- package/crates/team-agent/src/lifecycle/restart.rs +13 -11
- package/crates/team-agent/src/lifecycle/tests/acceptance_b_batch_red.rs +1007 -0
- package/crates/team-agent/src/lifecycle/tests/b0_legacy_snapshot_nonauthority_contract.rs +265 -0
- package/crates/team-agent/src/lifecycle/tests/b0_reader_hideone_audit_contract.rs +459 -0
- package/crates/team-agent/src/lifecycle/tests/behavioral_diff_264_red.rs +849 -0
- package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +323 -0
- package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +423 -0
- package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +737 -0
- package/crates/team-agent/src/lifecycle/tests/codex_mcp_approval_inheritance_red.rs +1187 -0
- package/crates/team-agent/src/lifecycle/tests/codex_weak_window_attribution_red.rs +683 -0
- package/crates/team-agent/src/lifecycle/tests/communication_mode_runtime_contract_red.rs +394 -0
- package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +1856 -0
- package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +917 -0
- package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +481 -0
- package/crates/team-agent/src/lifecycle/tests/f032_startup_prompt_best_effort_red.rs +301 -0
- package/crates/team-agent/src/lifecycle/tests/harvest2_a_batch_red.rs +516 -0
- package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +986 -0
- package/crates/team-agent/src/lifecycle/tests/lifecycle_rollback_red.rs +651 -0
- package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +2 -0
- package/crates/team-agent/src/lifecycle/tests/quick_start_worker_readiness_red.rs +332 -0
- package/crates/team-agent/src/lifecycle/tests/realmachine_clusters_1_6_red.rs +846 -0
- package/crates/team-agent/src/lifecycle/tests/realmachine_residual_g1_g4_red.rs +648 -0
- package/crates/team-agent/src/lifecycle/tests/restart_build_before_destroy_0540_contract.rs +910 -0
- package/crates/team-agent/src/lifecycle/tests/restart_liveness_red.rs +630 -0
- package/crates/team-agent/src/lifecycle/tests/restart_rebind_hotfix_252_red.rs +1083 -0
- package/crates/team-agent/src/lifecycle/tests/restart_session_capture_red.rs +1677 -0
- package/crates/team-agent/src/lifecycle/tests/resume_recover_red.rs +410 -0
- package/crates/team-agent/src/lifecycle/tests/stale_team_saveconflict_contract.rs +428 -0
- package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +1032 -0
- package/crates/team-agent/src/lifecycle/tests/status_credential_redaction_contract.rs +869 -0
- package/crates/team-agent/src/lifecycle/tests/subprep_codex_trust_roundtrip_red.rs +1249 -0
- package/crates/team-agent/src/lifecycle/tests/swallow_batch4_semantics_red.rs +342 -0
- package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +542 -0
- package/crates/team-agent/src/lifecycle/tests/team_in_team_sibling_quick_start_red.rs +1103 -0
- package/crates/team-agent/src/lifecycle/tests/team_in_team_state_scope_red.rs +1276 -0
- package/crates/team-agent/src/lifecycle/tests/team_key_retirement_roster_red.rs +145 -0
- package/crates/team-agent/src/lifecycle/tests/team_key_retirement_txn_red.rs +603 -0
- package/crates/team-agent/src/lifecycle/tests/test_isolation_escape_contract.rs +837 -0
- package/crates/team-agent/src/lifecycle/tests/upgrade_compat_0211_red.rs +928 -0
- package/crates/team-agent/src/lifecycle/tests/verify_rs031_window_consistency_red.rs +951 -0
- package/crates/team-agent/src/lifecycle/tests/worker_dangerous_bypass_argv_red.rs +327 -0
- package/crates/team-agent/src/lifecycle/tests/worker_spawn_env_red.rs +760 -0
- package/crates/team-agent/src/lifecycle/tests.rs +59 -0
- package/crates/team-agent/src/lifecycle/types.rs +0 -9
- package/crates/team-agent/src/lifecycle/worker_command_context.rs +29 -11
- package/crates/team-agent/src/mcp_server/helpers.rs +1 -0
- package/crates/team-agent/src/mcp_server/lifecycle_tools/mod.rs +1 -0
- package/crates/team-agent/src/mcp_server/lifecycle_tools/state_status.rs +1 -0
- package/crates/team-agent/src/mcp_server/mod.rs +1 -0
- package/crates/team-agent/src/mcp_server/normalize.rs +5 -3
- package/crates/team-agent/src/mcp_server/tests/send.rs +26 -0
- package/crates/team-agent/src/mcp_server/tests/wire.rs +1 -1
- package/crates/team-agent/src/mcp_server/tools.rs +101 -66
- package/crates/team-agent/src/mcp_server/types.rs +6 -18
- package/crates/team-agent/src/mcp_server/wire.rs +32 -26
- package/crates/team-agent/src/messaging/activity.rs +1 -0
- package/crates/team-agent/src/messaging/address.rs +1 -0
- package/crates/team-agent/src/messaging/delivery.rs +109 -41
- package/crates/team-agent/src/messaging/helpers.rs +2 -1
- package/crates/team-agent/src/messaging/leader_channel.rs +34 -10
- package/crates/team-agent/src/messaging/leader_receiver.rs +42 -24
- package/crates/team-agent/src/messaging/mod.rs +10 -14
- package/crates/team-agent/src/messaging/peers.rs +2 -0
- package/crates/team-agent/src/messaging/persist.rs +3 -1
- package/crates/team-agent/src/messaging/presentation.rs +111 -1
- package/crates/team-agent/src/messaging/results.rs +166 -17
- package/crates/team-agent/src/messaging/scheduler.rs +1 -0
- package/crates/team-agent/src/messaging/selftest.rs +1 -1
- package/crates/team-agent/src/messaging/send.rs +135 -89
- package/crates/team-agent/src/messaging/tests/leader_channel.rs +6 -6
- package/crates/team-agent/src/messaging/tests/leader_inject_acceptance.rs +187 -0
- package/crates/team-agent/src/messaging/tests/mod.rs +5 -0
- package/crates/team-agent/src/messaging/tests/runtime.rs +13 -6
- package/crates/team-agent/src/messaging/types.rs +7 -2
- package/crates/team-agent/src/messaging/watchers.rs +24 -13
- package/crates/team-agent/src/model/enums.rs +1 -0
- package/crates/team-agent/src/model/errors.rs +1 -0
- package/crates/team-agent/src/model/ids.rs +1 -0
- package/crates/team-agent/src/model/mod.rs +2 -0
- package/crates/team-agent/src/model/name_similarity.rs +1 -0
- package/crates/team-agent/src/model/pane_authority_refusal.rs +359 -0
- package/crates/team-agent/src/model/paths.rs +1 -0
- package/crates/team-agent/src/model/permissions.rs +3 -2
- package/crates/team-agent/src/model/routing.rs +1 -0
- package/crates/team-agent/src/model/spec.rs +17 -0
- package/crates/team-agent/src/model/task_graph.rs +1 -0
- package/crates/team-agent/src/model/yaml/tests.rs +1 -0
- package/crates/team-agent/src/model/yaml.rs +1 -0
- package/crates/team-agent/src/packaging/install.rs +9 -147
- package/crates/team-agent/src/packaging/migrate.rs +2 -0
- package/crates/team-agent/src/packaging/mod.rs +1 -0
- package/crates/team-agent/src/packaging/repair.rs +2 -0
- package/crates/team-agent/src/packaging/tests.rs +29 -218
- package/crates/team-agent/src/packaging/types.rs +8 -15
- package/crates/team-agent/src/platform/argv.rs +4 -0
- package/crates/team-agent/src/platform/errors.rs +10 -1
- package/crates/team-agent/src/platform/file_lock.rs +4 -157
- package/crates/team-agent/src/platform/mod.rs +0 -61
- package/crates/team-agent/src/platform/process.rs +1 -0
- package/crates/team-agent/src/provider/adapter.rs +1 -0
- package/crates/team-agent/src/provider/adapters/claude.rs +1 -0
- package/crates/team-agent/src/provider/adapters/claude_fork.rs +1 -0
- package/crates/team-agent/src/provider/adapters/codex.rs +1 -0
- package/crates/team-agent/src/provider/adapters/copilot.rs +1 -0
- package/crates/team-agent/src/provider/adapters/copilot_fork.rs +1 -0
- package/crates/team-agent/src/provider/adapters/fake.rs +1 -0
- package/crates/team-agent/src/provider/adapters/mod.rs +1 -0
- package/crates/team-agent/src/provider/approvals/mod.rs +1 -0
- package/crates/team-agent/src/provider/approvals/parsing.rs +2 -5
- package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +6 -5
- package/crates/team-agent/src/provider/classify.rs +1 -0
- package/crates/team-agent/src/provider/faults.rs +1 -26
- package/crates/team-agent/src/provider/helpers.rs +1 -0
- package/crates/team-agent/src/provider/mod.rs +1 -1
- package/crates/team-agent/src/provider/session/capture.rs +41 -22
- package/crates/team-agent/src/provider/session/context_fork/claude.rs +1 -0
- package/crates/team-agent/src/provider/session/context_fork/codex.rs +1 -0
- package/crates/team-agent/src/provider/session/context_fork/outcome.rs +1 -0
- package/crates/team-agent/src/provider/session/context_fork.rs +1 -0
- package/crates/team-agent/src/provider/session/mod.rs +2 -4
- package/crates/team-agent/src/provider/session/resume.rs +2 -209
- package/crates/team-agent/src/provider/session_scan/claude.rs +93 -3
- package/crates/team-agent/src/provider/session_scan/codex.rs +1 -0
- package/crates/team-agent/src/provider/session_scan/common.rs +24 -7
- package/crates/team-agent/src/provider/session_scan/copilot.rs +1 -0
- package/crates/team-agent/src/provider/session_scan.rs +6 -42
- package/crates/team-agent/src/provider/startup_prompt.rs +1 -0
- package/crates/team-agent/src/provider/types.rs +1 -0
- package/crates/team-agent/src/provider/wire.rs +1 -0
- package/crates/team-agent/src/state/identity.rs +16 -5
- package/crates/team-agent/src/state/identity_keys.rs +1 -0
- package/crates/team-agent/src/state/mod.rs +2 -0
- package/crates/team-agent/src/state/owner_gate.rs +5 -0
- package/crates/team-agent/src/state/ownership.rs +10 -4
- package/crates/team-agent/src/state/paths.rs +12 -0
- package/crates/team-agent/src/state/persist.rs +9 -3
- package/crates/team-agent/src/state/projection.rs +15 -2
- package/crates/team-agent/src/state/repository/intent.rs +1 -0
- package/crates/team-agent/src/state/repository/tests.rs +1 -0
- package/crates/team-agent/src/state/repository.rs +7 -0
- package/crates/team-agent/src/state/selector.rs +1 -0
- package/crates/team-agent/src/tmux_backend/tests.rs +39 -0
- package/crates/team-agent/src/tmux_backend.rs +63 -0
- package/crates/team-agent/src/topology.rs +3 -0
- package/crates/team-agent/src/transport.rs +15 -0
- package/package.json +4 -4
- package/skills/team-agent/command-coverage.json +379 -0
- package/crates/team-agent/src/leader/inject.rs +0 -33
- package/crates/team-agent/src/provider/command.rs +0 -80
|
@@ -5,12 +5,13 @@ use std::path::Path;
|
|
|
5
5
|
use rusqlite::{params, OptionalExtension};
|
|
6
6
|
|
|
7
7
|
use crate::event_log::EventLog;
|
|
8
|
+
use crate::leader::LeaderIncident;
|
|
8
9
|
use crate::message_store::{MessageStore, NotificationClaimParams};
|
|
9
10
|
use crate::model::ids::{TaskId, TeamKey};
|
|
10
11
|
use crate::transport::PaneId;
|
|
11
12
|
|
|
12
13
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
13
|
-
pub struct RecoveryIncident {
|
|
14
|
+
pub(crate) struct RecoveryIncident {
|
|
14
15
|
pub incident_id: String,
|
|
15
16
|
pub occurred_at: String,
|
|
16
17
|
}
|
|
@@ -20,7 +21,7 @@ use super::{MessagingError, WatcherNotice, RESULT_DELIVERY_MAX_ATTEMPTS};
|
|
|
20
21
|
/// `notify_result_watchers` (`result_delivery.py:38`):匹配 + 去重 + (有界) 投递 result 给 leader
|
|
21
22
|
/// watcher。**恰好一次** (Gap 32/38):同 result_id 多 watcher → 1 次注入,余 `superseded`。
|
|
22
23
|
/// 去重唯一原语 = [`MessageStore::claim_leader_notification_delivery`]。`collect`/coordinator tick 调。
|
|
23
|
-
pub fn notify_result_watchers(
|
|
24
|
+
pub(crate) fn notify_result_watchers(
|
|
24
25
|
workspace: &Path,
|
|
25
26
|
result: &serde_json::Value,
|
|
26
27
|
event_log: &EventLog,
|
|
@@ -475,20 +476,25 @@ pub fn requeue_after_claim_leader(
|
|
|
475
476
|
|
|
476
477
|
pub fn recover_watchers_for_incident(
|
|
477
478
|
workspace: &Path,
|
|
478
|
-
store: &MessageStore,
|
|
479
479
|
event_log: &EventLog,
|
|
480
480
|
owner_team_id: &TeamKey,
|
|
481
481
|
claimed_pane_id: &PaneId,
|
|
482
|
-
incident:
|
|
482
|
+
incident: LeaderIncident,
|
|
483
483
|
) -> Result<Vec<WatcherNotice>, MessagingError> {
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
484
|
+
match incident {
|
|
485
|
+
LeaderIncident::LeaderAttached => Ok(Vec::new()),
|
|
486
|
+
LeaderIncident::LeaderClaimed => {
|
|
487
|
+
let store = MessageStore::open(workspace)?;
|
|
488
|
+
requeue_after_claim_leader(
|
|
489
|
+
workspace,
|
|
490
|
+
&store,
|
|
491
|
+
event_log,
|
|
492
|
+
owner_team_id,
|
|
493
|
+
claimed_pane_id,
|
|
494
|
+
None,
|
|
495
|
+
)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
492
498
|
}
|
|
493
499
|
|
|
494
500
|
/// 0.5.5 gate054 round-2: attach-leader (and claim-leader) requeue for leader messages
|
|
@@ -529,6 +535,11 @@ pub(crate) fn requeue_blocked_leader_messages(
|
|
|
529
535
|
"blocked_leader_unbound": counts.blocked_leader_unbound,
|
|
530
536
|
"queued_until_leader_attach": counts.queued_until_leader_attach,
|
|
531
537
|
},
|
|
538
|
+
"attach_window_failures": {
|
|
539
|
+
"reason": "leader_not_attached",
|
|
540
|
+
"count": counts.blocked_leader_unbound,
|
|
541
|
+
"status": "requeued_pending_physical_retry",
|
|
542
|
+
},
|
|
532
543
|
}),
|
|
533
544
|
)?;
|
|
534
545
|
}
|
|
@@ -596,7 +607,7 @@ pub fn requeue_delivery_exhausted_watchers(
|
|
|
596
607
|
|
|
597
608
|
/// `delivered_result_message` (`result_delivery.py:394`):内容级去重 —— 查某 result_id 是否已有
|
|
598
609
|
/// 投递的 leader 通知消息。
|
|
599
|
-
pub fn delivered_result_message(
|
|
610
|
+
pub(crate) fn delivered_result_message(
|
|
600
611
|
store: &MessageStore,
|
|
601
612
|
result_id: &str,
|
|
602
613
|
task_id: Option<&TaskId>,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! step 2 · model — typed bedrock (REWRITE_PROMPT.md §6 step 2).
|
|
2
3
|
//!
|
|
3
4
|
//! 纯数据 + 纯函数核心:Python 的散字符串 / `dict[str,Any]` 在此变 §3 id-newtype +
|
|
@@ -18,6 +19,7 @@ pub mod ids;
|
|
|
18
19
|
// cli/send.rs (positional adapter), mcp_server/tools.rs (owner-scoped
|
|
19
20
|
// peer suggestions). Never a routing authority — advisory only.
|
|
20
21
|
pub(crate) mod name_similarity;
|
|
22
|
+
pub mod pane_authority_refusal;
|
|
21
23
|
pub mod paths;
|
|
22
24
|
pub mod permissions;
|
|
23
25
|
pub mod routing;
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
//!
|
|
2
|
+
//! Shared typed catalog for ambient tmux pane authority refusals.
|
|
3
|
+
//!
|
|
4
|
+
//! This module owns identities and payload shape only. Launchers and CLI
|
|
5
|
+
//! presenters remain responsible for collecting facts and rendering them.
|
|
6
|
+
|
|
7
|
+
use std::path::PathBuf;
|
|
8
|
+
|
|
9
|
+
pub const REASON_FIELD: &str = "reason";
|
|
10
|
+
pub const AVAILABILITY_FIELD: &str = "availability";
|
|
11
|
+
pub const CAUSE_FIELD: &str = "cause";
|
|
12
|
+
pub const ACTION_REQUIRED_FIELD: &str = "action_required";
|
|
13
|
+
pub const HINT_ACTION_FIELD: &str = "hint_action";
|
|
14
|
+
pub const ACTION_FIELD: &str = "action";
|
|
15
|
+
|
|
16
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
17
|
+
pub enum PaneAuthorityRefusalField {
|
|
18
|
+
RequestedWorkspace,
|
|
19
|
+
ObservedPaneId,
|
|
20
|
+
ObservedPaneWorkspace,
|
|
21
|
+
Endpoint,
|
|
22
|
+
CallerControllingTty,
|
|
23
|
+
ObservedPaneTty,
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
impl PaneAuthorityRefusalField {
|
|
27
|
+
pub const fn as_str(self) -> &'static str {
|
|
28
|
+
match self {
|
|
29
|
+
Self::RequestedWorkspace => "requested_workspace",
|
|
30
|
+
Self::ObservedPaneId => "observed_pane_id",
|
|
31
|
+
Self::ObservedPaneWorkspace => "observed_pane_workspace",
|
|
32
|
+
Self::Endpoint => "endpoint",
|
|
33
|
+
Self::CallerControllingTty => "caller_controlling_tty",
|
|
34
|
+
Self::ObservedPaneTty => "observed_pane_tty",
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
40
|
+
pub enum PaneAuthorityRefusalReason {
|
|
41
|
+
AmbientTmuxEndpointUnavailable,
|
|
42
|
+
AmbientPaneIdUnavailable,
|
|
43
|
+
AmbientPaneWorkspaceUnavailable,
|
|
44
|
+
CallerControllingTtyUnavailable,
|
|
45
|
+
ObservedPaneTtyUnavailable,
|
|
46
|
+
PaneTtyMismatch,
|
|
47
|
+
PaneWorkspaceMismatch,
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
impl PaneAuthorityRefusalReason {
|
|
51
|
+
pub const ALL: [Self; 7] = [
|
|
52
|
+
Self::AmbientTmuxEndpointUnavailable,
|
|
53
|
+
Self::AmbientPaneIdUnavailable,
|
|
54
|
+
Self::AmbientPaneWorkspaceUnavailable,
|
|
55
|
+
Self::CallerControllingTtyUnavailable,
|
|
56
|
+
Self::ObservedPaneTtyUnavailable,
|
|
57
|
+
Self::PaneTtyMismatch,
|
|
58
|
+
Self::PaneWorkspaceMismatch,
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
pub const fn as_str(self) -> &'static str {
|
|
62
|
+
match self {
|
|
63
|
+
Self::AmbientTmuxEndpointUnavailable => "AmbientTmuxEndpointUnavailable",
|
|
64
|
+
Self::AmbientPaneIdUnavailable => "AmbientPaneIdUnavailable",
|
|
65
|
+
Self::AmbientPaneWorkspaceUnavailable => "AmbientPaneWorkspaceUnavailable",
|
|
66
|
+
Self::CallerControllingTtyUnavailable => "CallerControllingTtyUnavailable",
|
|
67
|
+
Self::ObservedPaneTtyUnavailable => "ObservedPaneTtyUnavailable",
|
|
68
|
+
Self::PaneTtyMismatch => "PaneTtyMismatch",
|
|
69
|
+
Self::PaneWorkspaceMismatch => "PaneWorkspaceMismatch",
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
pub const fn required_fact_fields(self) -> &'static [PaneAuthorityRefusalField] {
|
|
74
|
+
use PaneAuthorityRefusalField::{
|
|
75
|
+
CallerControllingTty, Endpoint, ObservedPaneId, ObservedPaneTty, ObservedPaneWorkspace,
|
|
76
|
+
RequestedWorkspace,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
match self {
|
|
80
|
+
Self::AmbientTmuxEndpointUnavailable => &[RequestedWorkspace, Endpoint],
|
|
81
|
+
Self::AmbientPaneIdUnavailable => &[RequestedWorkspace, ObservedPaneId, Endpoint],
|
|
82
|
+
Self::AmbientPaneWorkspaceUnavailable => &[
|
|
83
|
+
RequestedWorkspace,
|
|
84
|
+
ObservedPaneId,
|
|
85
|
+
ObservedPaneWorkspace,
|
|
86
|
+
Endpoint,
|
|
87
|
+
],
|
|
88
|
+
Self::CallerControllingTtyUnavailable => &[
|
|
89
|
+
RequestedWorkspace,
|
|
90
|
+
ObservedPaneId,
|
|
91
|
+
Endpoint,
|
|
92
|
+
CallerControllingTty,
|
|
93
|
+
],
|
|
94
|
+
Self::ObservedPaneTtyUnavailable => &[
|
|
95
|
+
RequestedWorkspace,
|
|
96
|
+
ObservedPaneId,
|
|
97
|
+
Endpoint,
|
|
98
|
+
ObservedPaneTty,
|
|
99
|
+
],
|
|
100
|
+
Self::PaneTtyMismatch => &[
|
|
101
|
+
RequestedWorkspace,
|
|
102
|
+
ObservedPaneId,
|
|
103
|
+
Endpoint,
|
|
104
|
+
CallerControllingTty,
|
|
105
|
+
ObservedPaneTty,
|
|
106
|
+
],
|
|
107
|
+
Self::PaneWorkspaceMismatch => &[
|
|
108
|
+
RequestedWorkspace,
|
|
109
|
+
ObservedPaneId,
|
|
110
|
+
ObservedPaneWorkspace,
|
|
111
|
+
Endpoint,
|
|
112
|
+
],
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
118
|
+
pub enum PaneAuthorityFactAvailability {
|
|
119
|
+
Unavailable,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
impl PaneAuthorityFactAvailability {
|
|
123
|
+
pub const fn as_str(self) -> &'static str {
|
|
124
|
+
match self {
|
|
125
|
+
Self::Unavailable => "unavailable",
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
131
|
+
pub struct UnavailablePaneAuthorityFact<C> {
|
|
132
|
+
pub cause: C,
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
impl<C> UnavailablePaneAuthorityFact<C> {
|
|
136
|
+
pub const fn new(cause: C) -> Self {
|
|
137
|
+
Self { cause }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
pub const fn availability(&self) -> PaneAuthorityFactAvailability {
|
|
141
|
+
PaneAuthorityFactAvailability::Unavailable
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
macro_rules! unavailable_causes {
|
|
146
|
+
($name:ident { $($variant:ident => $wire:literal),+ $(,)? }) => {
|
|
147
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
148
|
+
pub enum $name {
|
|
149
|
+
$($variant),+
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
impl $name {
|
|
153
|
+
pub const fn as_str(self) -> &'static str {
|
|
154
|
+
match self {
|
|
155
|
+
$(Self::$variant => $wire),+
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
unavailable_causes!(AmbientTmuxEndpointUnavailableCause {
|
|
163
|
+
TmuxValueNotUnicode => "tmux_value_not_unicode",
|
|
164
|
+
TmuxTupleFieldCountInvalid => "tmux_tuple_field_count_invalid",
|
|
165
|
+
EndpointMissing => "endpoint_missing",
|
|
166
|
+
EndpointNotAbsolute => "endpoint_not_absolute",
|
|
167
|
+
ServerPidInvalid => "server_pid_invalid",
|
|
168
|
+
SessionIndexInvalid => "session_index_invalid",
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
unavailable_causes!(AmbientPaneIdUnavailableCause {
|
|
172
|
+
EnvironmentValueMissing => "environment_value_missing",
|
|
173
|
+
EnvironmentValueEmpty => "environment_value_empty",
|
|
174
|
+
EnvironmentValueNotUnicode => "environment_value_not_unicode",
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
unavailable_causes!(AmbientPaneWorkspaceUnavailableCause {
|
|
178
|
+
PaneQueryFailed => "pane_query_failed",
|
|
179
|
+
PaneNotFound => "pane_not_found",
|
|
180
|
+
CurrentPathMissing => "current_path_missing",
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
unavailable_causes!(CallerControllingTtyUnavailableCause {
|
|
184
|
+
NoControllingTty => "no_controlling_tty",
|
|
185
|
+
DeviceIdentityUnresolvable => "device_identity_unresolvable",
|
|
186
|
+
PlatformUnsupported => "platform_unsupported",
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
unavailable_causes!(ObservedPaneTtyUnavailableCause {
|
|
190
|
+
PaneTtyMissing => "pane_tty_missing",
|
|
191
|
+
PaneTtyUnresolvable => "pane_tty_unresolvable",
|
|
192
|
+
PaneTtyNotCharacterDevice => "pane_tty_not_character_device",
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
196
|
+
pub struct AmbientTmuxEndpointUnavailableFacts {
|
|
197
|
+
pub requested_workspace: PathBuf,
|
|
198
|
+
pub endpoint: UnavailablePaneAuthorityFact<AmbientTmuxEndpointUnavailableCause>,
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
202
|
+
pub struct AmbientPaneIdUnavailableFacts {
|
|
203
|
+
pub requested_workspace: PathBuf,
|
|
204
|
+
pub observed_pane_id: UnavailablePaneAuthorityFact<AmbientPaneIdUnavailableCause>,
|
|
205
|
+
pub endpoint: String,
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
209
|
+
pub struct AmbientPaneWorkspaceUnavailableFacts {
|
|
210
|
+
pub requested_workspace: PathBuf,
|
|
211
|
+
pub observed_pane_id: String,
|
|
212
|
+
pub observed_pane_workspace: UnavailablePaneAuthorityFact<AmbientPaneWorkspaceUnavailableCause>,
|
|
213
|
+
pub endpoint: String,
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
217
|
+
pub struct CallerControllingTtyUnavailableFacts {
|
|
218
|
+
pub requested_workspace: PathBuf,
|
|
219
|
+
pub observed_pane_id: String,
|
|
220
|
+
pub endpoint: String,
|
|
221
|
+
pub caller_controlling_tty: UnavailablePaneAuthorityFact<CallerControllingTtyUnavailableCause>,
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
225
|
+
pub struct ObservedPaneTtyUnavailableFacts {
|
|
226
|
+
pub requested_workspace: PathBuf,
|
|
227
|
+
pub observed_pane_id: String,
|
|
228
|
+
pub endpoint: String,
|
|
229
|
+
pub observed_pane_tty: UnavailablePaneAuthorityFact<ObservedPaneTtyUnavailableCause>,
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
233
|
+
pub struct PaneTtyMismatchFacts {
|
|
234
|
+
pub requested_workspace: PathBuf,
|
|
235
|
+
pub observed_pane_id: String,
|
|
236
|
+
pub endpoint: String,
|
|
237
|
+
pub caller_controlling_tty: u64,
|
|
238
|
+
pub observed_pane_tty: u64,
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
242
|
+
pub struct PaneWorkspaceMismatchFacts {
|
|
243
|
+
pub requested_workspace: PathBuf,
|
|
244
|
+
pub observed_pane_id: String,
|
|
245
|
+
pub observed_pane_workspace: PathBuf,
|
|
246
|
+
pub endpoint: String,
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
250
|
+
pub enum PaneAuthorityRefusalFacts {
|
|
251
|
+
AmbientTmuxEndpointUnavailable(AmbientTmuxEndpointUnavailableFacts),
|
|
252
|
+
AmbientPaneIdUnavailable(AmbientPaneIdUnavailableFacts),
|
|
253
|
+
AmbientPaneWorkspaceUnavailable(AmbientPaneWorkspaceUnavailableFacts),
|
|
254
|
+
CallerControllingTtyUnavailable(CallerControllingTtyUnavailableFacts),
|
|
255
|
+
ObservedPaneTtyUnavailable(ObservedPaneTtyUnavailableFacts),
|
|
256
|
+
PaneTtyMismatch(PaneTtyMismatchFacts),
|
|
257
|
+
PaneWorkspaceMismatch(PaneWorkspaceMismatchFacts),
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
impl PaneAuthorityRefusalFacts {
|
|
261
|
+
pub const fn reason(&self) -> PaneAuthorityRefusalReason {
|
|
262
|
+
match self {
|
|
263
|
+
Self::AmbientTmuxEndpointUnavailable(_) => {
|
|
264
|
+
PaneAuthorityRefusalReason::AmbientTmuxEndpointUnavailable
|
|
265
|
+
}
|
|
266
|
+
Self::AmbientPaneIdUnavailable(_) => {
|
|
267
|
+
PaneAuthorityRefusalReason::AmbientPaneIdUnavailable
|
|
268
|
+
}
|
|
269
|
+
Self::AmbientPaneWorkspaceUnavailable(_) => {
|
|
270
|
+
PaneAuthorityRefusalReason::AmbientPaneWorkspaceUnavailable
|
|
271
|
+
}
|
|
272
|
+
Self::CallerControllingTtyUnavailable(_) => {
|
|
273
|
+
PaneAuthorityRefusalReason::CallerControllingTtyUnavailable
|
|
274
|
+
}
|
|
275
|
+
Self::ObservedPaneTtyUnavailable(_) => {
|
|
276
|
+
PaneAuthorityRefusalReason::ObservedPaneTtyUnavailable
|
|
277
|
+
}
|
|
278
|
+
Self::PaneTtyMismatch(_) => PaneAuthorityRefusalReason::PaneTtyMismatch,
|
|
279
|
+
Self::PaneWorkspaceMismatch(_) => PaneAuthorityRefusalReason::PaneWorkspaceMismatch,
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
285
|
+
pub enum PaneAuthorityRecoveryHint {
|
|
286
|
+
AttachLeader,
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
290
|
+
pub enum PaneAuthorityRecoveryAction {
|
|
291
|
+
OpenTerminalOutsideCurrentTmuxPaneOrAttachFromMatchingPane,
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
295
|
+
pub struct PaneAuthorityRecovery {
|
|
296
|
+
pub action_required: bool,
|
|
297
|
+
pub hint_action: PaneAuthorityRecoveryHint,
|
|
298
|
+
pub action: PaneAuthorityRecoveryAction,
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
impl PaneAuthorityRecovery {
|
|
302
|
+
pub const REQUIRED: Self = Self {
|
|
303
|
+
action_required: true,
|
|
304
|
+
hint_action: PaneAuthorityRecoveryHint::AttachLeader,
|
|
305
|
+
action:
|
|
306
|
+
PaneAuthorityRecoveryAction::OpenTerminalOutsideCurrentTmuxPaneOrAttachFromMatchingPane,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
311
|
+
pub struct PaneAuthorityRefusal {
|
|
312
|
+
pub facts: PaneAuthorityRefusalFacts,
|
|
313
|
+
pub recovery: PaneAuthorityRecovery,
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
impl PaneAuthorityRefusal {
|
|
317
|
+
pub const fn new(facts: PaneAuthorityRefusalFacts) -> Self {
|
|
318
|
+
Self {
|
|
319
|
+
facts,
|
|
320
|
+
recovery: PaneAuthorityRecovery::REQUIRED,
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
pub const fn reason(&self) -> PaneAuthorityRefusalReason {
|
|
325
|
+
self.facts.reason()
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
#[cfg(test)]
|
|
330
|
+
mod tests {
|
|
331
|
+
use super::{PaneAuthorityRefusalField as Field, PaneAuthorityRefusalReason as Reason};
|
|
332
|
+
|
|
333
|
+
#[test]
|
|
334
|
+
fn reason_catalog_is_closed_and_mismatch_requires_all_four_workspace_facts() {
|
|
335
|
+
assert_eq!(Reason::ALL.len(), 7);
|
|
336
|
+
assert_eq!(
|
|
337
|
+
Reason::PaneWorkspaceMismatch.required_fact_fields(),
|
|
338
|
+
&[
|
|
339
|
+
Field::RequestedWorkspace,
|
|
340
|
+
Field::ObservedPaneId,
|
|
341
|
+
Field::ObservedPaneWorkspace,
|
|
342
|
+
Field::Endpoint,
|
|
343
|
+
]
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
#[test]
|
|
348
|
+
fn unavailable_reasons_require_the_fact_they_could_not_observe() {
|
|
349
|
+
assert!(Reason::AmbientTmuxEndpointUnavailable
|
|
350
|
+
.required_fact_fields()
|
|
351
|
+
.contains(&Field::Endpoint));
|
|
352
|
+
assert!(Reason::AmbientPaneIdUnavailable
|
|
353
|
+
.required_fact_fields()
|
|
354
|
+
.contains(&Field::ObservedPaneId));
|
|
355
|
+
assert!(Reason::AmbientPaneWorkspaceUnavailable
|
|
356
|
+
.required_fact_fields()
|
|
357
|
+
.contains(&Field::ObservedPaneWorkspace));
|
|
358
|
+
}
|
|
359
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! §19/§3 移植 `permissions.py`:role/provider/alias → 规范化权限矩阵。
|
|
2
3
|
//!
|
|
3
4
|
//! Python 全程裸 `str` + `dict[str, Any]`(`expand_tools`/`resolve_permissions`/
|
|
@@ -56,7 +57,7 @@ impl Tool {
|
|
|
56
57
|
///
|
|
57
58
|
/// 注:返回**声明序集合**;Python 返回的是 role 字面顺序的 list,但下游 `resolve_*`
|
|
58
59
|
/// 立即过 `expand_tools`(去重+排序),顺序不参与对拍,故此处用 `BTreeSet` 即可。
|
|
59
|
-
|
|
60
|
+
fn default_tools_for_role(role: &str) -> BTreeSet<Tool> {
|
|
60
61
|
use Tool::*;
|
|
61
62
|
let tools: &[Tool] = match role {
|
|
62
63
|
"leader" | "supervisor" => &[FsRead, FsList, McpTeam, ProviderBuiltin],
|
|
@@ -175,7 +176,7 @@ pub fn is_canonical_tool(name: &str) -> bool {
|
|
|
175
176
|
///
|
|
176
177
|
/// 表里没有的 provider(如 `claude`)= Python 的 `.get(provider, {})` → 空表 →
|
|
177
178
|
/// 每个 tool 再 `.get(tool, "prompt_only")` → 全 `prompt_only`(对拍 `R-unknownprov`)。
|
|
178
|
-
|
|
179
|
+
fn provider_enforcement(provider: Provider, tool: Tool) -> Enforcement {
|
|
179
180
|
use Enforcement::{Hard, PromptOnly};
|
|
180
181
|
use Tool::*;
|
|
181
182
|
match provider {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
//!
|
|
1
2
|
//! spec / result-envelope 校验(`spec.py`)。
|
|
2
3
|
//!
|
|
3
4
|
//! 本 module **操作解析后的 Value**(非 typed struct)——与 Python 一样校验 dict,
|
|
@@ -400,6 +401,7 @@ fn check_agent(agent: &Yaml, path: &str, errors: &mut Vec<String>) {
|
|
|
400
401
|
"preferred_for",
|
|
401
402
|
"avoid_for",
|
|
402
403
|
"output_contract",
|
|
404
|
+
"communication_mode",
|
|
403
405
|
"paused",
|
|
404
406
|
"auth_mode",
|
|
405
407
|
"profile",
|
|
@@ -412,6 +414,21 @@ fn check_agent(agent: &Yaml, path: &str, errors: &mut Vec<String>) {
|
|
|
412
414
|
if !agent.is_map() {
|
|
413
415
|
return;
|
|
414
416
|
}
|
|
417
|
+
if let Some(value) = agent.get("communication_mode") {
|
|
418
|
+
match value.as_str() {
|
|
419
|
+
Some(raw) if crate::communication_mode::CommunicationMode::parse(raw).is_none() => {
|
|
420
|
+
errors.push(format!(
|
|
421
|
+
"{path}/communication_mode: unknown communication_mode '{raw}'"
|
|
422
|
+
));
|
|
423
|
+
}
|
|
424
|
+
None => {
|
|
425
|
+
errors.push(format!(
|
|
426
|
+
"{path}/communication_mode: unknown communication_mode"
|
|
427
|
+
));
|
|
428
|
+
}
|
|
429
|
+
Some(_) => {}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
415
432
|
// 0.4.x provider effort MVP step 3: effort syntactic + semantic validation.
|
|
416
433
|
if let Some(raw) = agent.get("effort").and_then(Yaml::as_str) {
|
|
417
434
|
match crate::model::enums::ProviderEffort::parse(raw) {
|