@team-agent/installer 0.4.10 → 0.5.0
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 +1 -0
- package/crates/team-agent/src/cli/diagnose.rs +2 -15
- package/crates/team-agent/src/cli/emit.rs +62 -4
- package/crates/team-agent/src/compiler.rs +11 -20
- package/crates/team-agent/src/coordinator/orphan.rs +2 -2
- package/crates/team-agent/src/coordinator/runtime_detectors.rs +5 -4
- package/crates/team-agent/src/coordinator/steps/abnormal.rs +1776 -2
- package/crates/team-agent/src/coordinator/steps/mod.rs +19 -0
- package/crates/team-agent/src/coordinator/tests/a0_lostupdate.rs +78 -7
- package/crates/team-agent/src/coordinator/tests/abnormal.rs +195 -0
- package/crates/team-agent/src/coordinator/tick.rs +31 -932
- package/crates/team-agent/src/diagnose/orphans.rs +66 -8
- package/crates/team-agent/src/layout/worker_window_helpers.rs +5 -7
- package/crates/team-agent/src/leader/provider_attribution.rs +7 -5
- package/crates/team-agent/src/leader/rediscover.rs +1 -11
- package/crates/team-agent/src/leader/start.rs +169 -25
- package/crates/team-agent/src/lifecycle/launch/plan.rs +19 -8
- package/crates/team-agent/src/lifecycle/launch.rs +135 -58
- package/crates/team-agent/src/lifecycle/lock.rs +302 -0
- package/crates/team-agent/src/lifecycle/mod.rs +1 -0
- package/crates/team-agent/src/lifecycle/profile_smoke.rs +1 -11
- package/crates/team-agent/src/lifecycle/restart/agent.rs +436 -121
- package/crates/team-agent/src/lifecycle/restart/common.rs +108 -17
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +165 -32
- package/crates/team-agent/src/lifecycle/restart/remove.rs +16 -2
- package/crates/team-agent/src/lifecycle/restart/selection.rs +2 -1
- package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +193 -0
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +3 -3
- package/crates/team-agent/src/lifecycle/tests/lifecycle_lock.rs +321 -0
- package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +54 -15
- package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +802 -0
- package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +648 -0
- package/crates/team-agent/src/lifecycle/tests.rs +3 -0
- package/crates/team-agent/src/lifecycle/types.rs +8 -0
- package/crates/team-agent/src/lifecycle/worker_command_context.rs +24 -34
- package/crates/team-agent/src/mcp_server/lifecycle_tools/state_status.rs +24 -9
- package/crates/team-agent/src/mcp_server/tools.rs +157 -68
- package/crates/team-agent/src/messaging/activity.rs +43 -18
- package/crates/team-agent/src/messaging/delivery.rs +161 -97
- package/crates/team-agent/src/messaging/helpers.rs +1 -0
- package/crates/team-agent/src/messaging/leader_receiver.rs +22 -1
- package/crates/team-agent/src/messaging/results.rs +34 -9
- package/crates/team-agent/src/messaging/scheduler.rs +52 -9
- package/crates/team-agent/src/model/spec.rs +10 -6
- package/crates/team-agent/src/provider/adapter.rs +10 -1038
- package/crates/team-agent/src/provider/adapters/claude.rs +3 -8
- package/crates/team-agent/src/provider/adapters/copilot.rs +2 -5
- package/crates/team-agent/src/provider/classify.rs +23 -48
- package/crates/team-agent/src/provider/command.rs +16 -7
- package/crates/team-agent/src/provider/faults.rs +93 -53
- package/crates/team-agent/src/provider/session/capture.rs +4 -15
- package/crates/team-agent/src/provider/session_scan/claude.rs +309 -0
- package/crates/team-agent/src/provider/session_scan/codex.rs +40 -0
- package/crates/team-agent/src/provider/session_scan/common.rs +350 -0
- package/crates/team-agent/src/provider/session_scan/copilot.rs +202 -0
- package/crates/team-agent/src/provider/session_scan.rs +65 -27
- package/crates/team-agent/src/provider/tests/faults.rs +80 -0
- package/crates/team-agent/src/provider/types.rs +33 -1
- package/crates/team-agent/src/provider/wire.rs +171 -1
- package/crates/team-agent/src/state/identity.rs +242 -57
- package/crates/team-agent/src/state/identity_keys.rs +9 -12
- package/crates/team-agent/src/state/mod.rs +5 -1
- package/crates/team-agent/src/state/owner_gate.rs +59 -15
- package/crates/team-agent/src/state/ownership.rs +12 -11
- package/crates/team-agent/src/state/paths.rs +13 -6
- package/crates/team-agent/src/state/persist.rs +671 -128
- package/crates/team-agent/src/state/projection.rs +240 -49
- package/crates/team-agent/src/state/selector.rs +11 -5
- package/crates/team-agent/src/tmux_backend/tests.rs +51 -2
- package/crates/team-agent/src/tmux_backend.rs +42 -5
- package/crates/team-agent/src/transport/test_support.rs +55 -6
- package/package.json +4 -4
|
@@ -10,7 +10,9 @@ use crate::transport::{PaneId, Transport};
|
|
|
10
10
|
|
|
11
11
|
use super::delivery::{deliver_stored_message, handle_trust_retry_needed};
|
|
12
12
|
use super::helpers::{parse_scheduled_kind, status_wire};
|
|
13
|
-
use super::{
|
|
13
|
+
use super::{
|
|
14
|
+
AlertType, MessagingError, ScheduledKind, TrustRetryPayload, TRUST_RETRY_MAX_ATTEMPTS,
|
|
15
|
+
};
|
|
14
16
|
|
|
15
17
|
/// `_fire_due_scheduled_events` (`scheduler.py:41`):coordinator tick 的调度器心脏 —— 分派到期
|
|
16
18
|
/// `send`/`health_ping`/`trust_retry` ([`ScheduledKind`] 穷尽 match),send 失败有界重试。
|
|
@@ -50,9 +52,15 @@ pub fn fire_due_scheduled_events(
|
|
|
50
52
|
let outcome = deliver_stored_message(
|
|
51
53
|
workspace,
|
|
52
54
|
Some(&target),
|
|
53
|
-
payload
|
|
55
|
+
payload
|
|
56
|
+
.get("content")
|
|
57
|
+
.and_then(|v| v.as_str())
|
|
58
|
+
.unwrap_or(""),
|
|
54
59
|
None,
|
|
55
|
-
payload
|
|
60
|
+
payload
|
|
61
|
+
.get("sender")
|
|
62
|
+
.and_then(|v| v.as_str())
|
|
63
|
+
.unwrap_or("leader"),
|
|
56
64
|
payload
|
|
57
65
|
.get("requires_ack")
|
|
58
66
|
.and_then(|v| v.as_bool())
|
|
@@ -61,7 +69,10 @@ pub fn fire_due_scheduled_events(
|
|
|
61
69
|
.get("wait_visible")
|
|
62
70
|
.and_then(|v| v.as_bool())
|
|
63
71
|
.unwrap_or(false),
|
|
64
|
-
payload
|
|
72
|
+
payload
|
|
73
|
+
.get("timeout")
|
|
74
|
+
.and_then(|v| v.as_f64())
|
|
75
|
+
.unwrap_or(30.0),
|
|
65
76
|
None,
|
|
66
77
|
)?;
|
|
67
78
|
serde_json::json!({
|
|
@@ -114,7 +125,10 @@ pub fn fire_due_scheduled_events(
|
|
|
114
125
|
|
|
115
126
|
let (status, result_json) = match fire_one() {
|
|
116
127
|
Ok(result) => {
|
|
117
|
-
let ok = result
|
|
128
|
+
let ok = result
|
|
129
|
+
.get("ok")
|
|
130
|
+
.and_then(serde_json::Value::as_bool)
|
|
131
|
+
.unwrap_or(false);
|
|
118
132
|
(if ok { "done" } else { "failed" }, result.to_string())
|
|
119
133
|
}
|
|
120
134
|
Err(error) => {
|
|
@@ -242,7 +256,26 @@ pub fn stuck_cancel(
|
|
|
242
256
|
},
|
|
243
257
|
);
|
|
244
258
|
}
|
|
245
|
-
crate::state::persist::
|
|
259
|
+
crate::state::persist::save_runtime_state_reapplying_after_conflict(
|
|
260
|
+
workspace,
|
|
261
|
+
&state,
|
|
262
|
+
|latest| {
|
|
263
|
+
for kind in &alert_types {
|
|
264
|
+
upsert_suppression(
|
|
265
|
+
latest,
|
|
266
|
+
SuppressionRecord {
|
|
267
|
+
team: &team,
|
|
268
|
+
agent_id,
|
|
269
|
+
alert_type: kind,
|
|
270
|
+
suppressed_by,
|
|
271
|
+
suppressed_at: &now,
|
|
272
|
+
assigned_task_ids: assigned.clone(),
|
|
273
|
+
delivered_message_ids: delivered.clone(),
|
|
274
|
+
},
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
)?;
|
|
246
279
|
crate::event_log::EventLog::new(workspace).write(
|
|
247
280
|
"coordinator.idle_alert_suppressed",
|
|
248
281
|
serde_json::json!({
|
|
@@ -273,7 +306,11 @@ fn active_team_key(workspace: &Path, state: &serde_json::Value) -> String {
|
|
|
273
306
|
.and_then(serde_json::Value::as_str)
|
|
274
307
|
.filter(|team| !team.is_empty())
|
|
275
308
|
.map(ToString::to_string)
|
|
276
|
-
.or_else(||
|
|
309
|
+
.or_else(|| {
|
|
310
|
+
workspace
|
|
311
|
+
.file_name()
|
|
312
|
+
.map(|name| name.to_string_lossy().to_string())
|
|
313
|
+
})
|
|
277
314
|
.unwrap_or_else(|| "current".to_string())
|
|
278
315
|
}
|
|
279
316
|
|
|
@@ -284,8 +321,14 @@ fn assigned_task_ids(state: &serde_json::Value, agent_id: &str) -> Vec<String> {
|
|
|
284
321
|
.map(|tasks| {
|
|
285
322
|
tasks
|
|
286
323
|
.iter()
|
|
287
|
-
.filter(|task|
|
|
288
|
-
|
|
324
|
+
.filter(|task| {
|
|
325
|
+
task.get("assignee").and_then(serde_json::Value::as_str) == Some(agent_id)
|
|
326
|
+
})
|
|
327
|
+
.filter_map(|task| {
|
|
328
|
+
task.get("id")
|
|
329
|
+
.and_then(serde_json::Value::as_str)
|
|
330
|
+
.map(ToString::to_string)
|
|
331
|
+
})
|
|
289
332
|
.collect()
|
|
290
333
|
})
|
|
291
334
|
.unwrap_or_default();
|
|
@@ -18,6 +18,7 @@ use crate::model::ids::TaskId;
|
|
|
18
18
|
use crate::model::task_graph::{find_dependency_cycle, TaskNode};
|
|
19
19
|
use crate::model::yaml::Value as Yaml;
|
|
20
20
|
use crate::model::{permissions, yaml};
|
|
21
|
+
use crate::provider::wire::{is_claude_family, parse_canonical_provider};
|
|
21
22
|
|
|
22
23
|
/// result_envelope_v1 顶层 required(= allowed)。
|
|
23
24
|
const RESULT_REQUIRED: &[&str] = &[
|
|
@@ -175,9 +176,6 @@ fn result_schema_errors(envelope: &Value) -> Vec<String> {
|
|
|
175
176
|
const ROOT_KEYS: &[&str] = &[
|
|
176
177
|
"version", "team", "leader", "agents", "routing", "communication", "runtime", "context", "tasks",
|
|
177
178
|
];
|
|
178
|
-
// Copilot 一期加入白名单(design §B compiler.py:249-251 同位 + cr verdict 总裁,
|
|
179
|
-
// MUST-NOT-7 跨厂商等价 — 设计 / cr 已落地 26 约束)。
|
|
180
|
-
const SUPPORTED_PROVIDERS: &[&str] = &["claude", "claude_code", "codex", "copilot", "gemini_cli", "fake"];
|
|
181
179
|
const AUTH_MODES: &[&str] = &["subscription", "official_api", "compatible_api"];
|
|
182
180
|
const VALID_DISPLAY_BACKENDS: &[&str] = &[
|
|
183
181
|
"none", "tmux_attach", "iterm", "ghostty", "ghostty_window", "ghostty_workspace", "adaptive",
|
|
@@ -326,7 +324,7 @@ fn check_agent(agent: &Yaml, path: &str, errors: &mut Vec<String>) {
|
|
|
326
324
|
}
|
|
327
325
|
Some(effort) if effort.is_claude_only() => {
|
|
328
326
|
let provider = agent.get("provider").and_then(Yaml::as_str).unwrap_or("");
|
|
329
|
-
if !
|
|
327
|
+
if !parse_canonical_provider(provider).is_some_and(is_claude_family) {
|
|
330
328
|
errors.push(format!(
|
|
331
329
|
"{path}/effort: effort '{raw}' is only supported by claude/claude_code (provider: {provider})"
|
|
332
330
|
));
|
|
@@ -476,13 +474,19 @@ fn semantic_errors(spec: &Yaml, base_dir: &Path) -> Vec<String> {
|
|
|
476
474
|
}
|
|
477
475
|
|
|
478
476
|
let leader_provider = leader.and_then(|l| l.get("provider"));
|
|
479
|
-
if !leader_provider
|
|
477
|
+
if !leader_provider
|
|
478
|
+
.and_then(Yaml::as_str)
|
|
479
|
+
.is_some_and(|p| parse_canonical_provider(p).is_some())
|
|
480
|
+
{
|
|
480
481
|
e.push(format!("/leader/provider: unknown provider {}", py_repr(leader_provider)));
|
|
481
482
|
}
|
|
482
483
|
|
|
483
484
|
for (idx, agent) in agents.iter().enumerate() {
|
|
484
485
|
let provider = agent.get("provider");
|
|
485
|
-
if !provider
|
|
486
|
+
if !provider
|
|
487
|
+
.and_then(Yaml::as_str)
|
|
488
|
+
.is_some_and(|p| parse_canonical_provider(p).is_some())
|
|
489
|
+
{
|
|
486
490
|
e.push(format!("/agents/{idx}/provider: unknown provider {}", py_repr(provider)));
|
|
487
491
|
}
|
|
488
492
|
if let Some(auth) = agent.get("auth_mode") {
|