@team-agent/installer 0.5.101 → 0.5.103
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/emit.rs +2 -1
- package/crates/team-agent/src/cli/models.rs +92 -226
- package/crates/team-agent/src/cli/spec.rs +1 -1
- package/crates/team-agent/src/cli/tests/main_preserved.rs +0 -74
- package/crates/team-agent/src/compiler/tests.rs +20 -23
- package/crates/team-agent/src/compiler.rs +49 -65
- package/crates/team-agent/src/coordinator/tests/s3_bounded.rs +16 -48
- package/crates/team-agent/src/leader/start.rs +1 -14
- package/crates/team-agent/src/lifecycle/launch/pi_mcp.rs +37 -161
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +1 -1
- package/crates/team-agent/src/lifecycle/restart/common.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/host_cotenant_death_p0_contract.rs +0 -28
- package/crates/team-agent/src/lifecycle/tests/pi_compiler_red.rs +11 -9
- package/crates/team-agent/src/lifecycle/tests/pi_dual_entry_red.rs +8 -401
- package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/worker_command_context.rs +22 -8
- package/crates/team-agent/src/mcp_server/helpers.rs +0 -16
- package/crates/team-agent/src/mcp_server/lifecycle_tools/mod.rs +2 -7
- package/crates/team-agent/src/mcp_server/lifecycle_tools/state_status.rs +1 -127
- package/crates/team-agent/src/mcp_server/mod.rs +7 -12
- package/crates/team-agent/src/mcp_server/tests/scoped.rs +1 -132
- package/crates/team-agent/src/mcp_server/tests/send.rs +1 -93
- package/crates/team-agent/src/mcp_server/tests/tools.rs +0 -61
- package/crates/team-agent/src/mcp_server/tests/wire.rs +6 -51
- package/crates/team-agent/src/mcp_server/tests.rs +4 -200
- package/crates/team-agent/src/mcp_server/tools.rs +5 -396
- package/crates/team-agent/src/mcp_server/types.rs +3 -36
- package/crates/team-agent/src/mcp_server/wire.rs +2 -223
- package/crates/team-agent/src/messaging/leader_receiver.rs +1 -1
- package/crates/team-agent/src/messaging/mod.rs +2 -2
- package/crates/team-agent/src/messaging/results.rs +11 -42
- package/crates/team-agent/src/messaging/scheduler.rs +2 -205
- package/crates/team-agent/src/messaging/tests/basic.rs +0 -31
- package/crates/team-agent/src/messaging/tests/main_preserved.rs +0 -73
- package/crates/team-agent/src/messaging/tests/runtime.rs +0 -26
- package/crates/team-agent/src/messaging/types.rs +0 -20
- package/crates/team-agent/src/model/spec.rs +14 -18
- package/crates/team-agent/src/provider/mod.rs +1 -0
- package/crates/team-agent/src/provider/model_catalog.rs +650 -0
- package/crates/team-agent/src/state/repository/tests.rs +1 -16
- package/crates/team-agent/src/state/repository.rs +1 -33
- package/package.json +4 -4
- package/skills/team-agent/SKILL.md +5 -5
- package/skills/team-agent/command-coverage.json +7 -0
- package/skills/team-agent/references/team-agent-operator.md +24 -116
- package/skills/team-agent/references/team-in-team.md +4 -19
- package/crates/team-agent/src/mcp_server/lifecycle_tools/agent_ops.rs +0 -484
|
@@ -140,23 +140,6 @@ fn activity_status_serde_byte_locked() {
|
|
|
140
140
|
);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
#[test]
|
|
144
|
-
fn alert_type_serde_byte_locked() {
|
|
145
|
-
// scheduler.py:38 _ALERT_TYPES set members.
|
|
146
|
-
assert_eq!(
|
|
147
|
-
serde_json::to_string(&AlertType::Stuck).unwrap(),
|
|
148
|
-
"\"stuck\""
|
|
149
|
-
);
|
|
150
|
-
assert_eq!(
|
|
151
|
-
serde_json::to_string(&AlertType::IdleFallback).unwrap(),
|
|
152
|
-
"\"idle_fallback\""
|
|
153
|
-
);
|
|
154
|
-
assert_eq!(
|
|
155
|
-
serde_json::to_string(&AlertType::CrossWorkerDeadlock).unwrap(),
|
|
156
|
-
"\"cross_worker_deadlock\""
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
143
|
#[test]
|
|
161
144
|
fn check_status_serde_byte_locked() {
|
|
162
145
|
assert_eq!(
|
|
@@ -266,20 +249,6 @@ fn provider_sdk_calls_is_zero_only_when_all_three_zero() {
|
|
|
266
249
|
.is_zero());
|
|
267
250
|
}
|
|
268
251
|
|
|
269
|
-
#[test]
|
|
270
|
-
fn alert_type_all_is_sorted_full_set() {
|
|
271
|
-
// scheduler.py:269 sorted(_ALERT_TYPES) =
|
|
272
|
-
// ['cross_worker_deadlock','idle_fallback','stuck'].
|
|
273
|
-
assert_eq!(
|
|
274
|
-
AlertType::all(),
|
|
275
|
-
[
|
|
276
|
-
AlertType::CrossWorkerDeadlock,
|
|
277
|
-
AlertType::IdleFallback,
|
|
278
|
-
AlertType::Stuck
|
|
279
|
-
]
|
|
280
|
-
);
|
|
281
|
-
}
|
|
282
|
-
|
|
283
252
|
#[test]
|
|
284
253
|
fn activity_status_idle_takeover_gate_uncertain_never_idle() {
|
|
285
254
|
// THE IRON LAW (bug-071/077/085): only Idle passes; Uncertain/Working/Stuck
|
|
@@ -1,78 +1,5 @@
|
|
|
1
1
|
use super::*;
|
|
2
2
|
|
|
3
|
-
// ── F1 [P1 byte-shape] — stuck_cancel suppression snapshot.delivered_message_ids must use golden's
|
|
4
|
-
// _DELIVERED_MESSAGE_STATUSES = {visible, submitted, delivered, acknowledged} (scheduler.py:27,376-383),
|
|
5
|
-
// sorted. The Rust delivered_message_ids (scheduler.rs:243) used {injected, visible, submitted,
|
|
6
|
-
// submitted_unverified, delivered} — the WRONG set (reviewer's explicit warning: don't copy the
|
|
7
|
-
// activity.rs deadlock query set): it EXCLUDES 'acknowledged' and INCLUDES 'injected'/'submitted_unverified'.
|
|
8
|
-
// (The snapshot also must carry BOTH assigned_task_ids AND delivered_message_ids — that structural half
|
|
9
|
-
// is already present; this pins the STATUS SET.)
|
|
10
|
-
#[test]
|
|
11
|
-
fn stuck_cancel_snapshot_delivered_message_ids_uses_golden_status_set() {
|
|
12
|
-
let ws = tmp_ws("f1_delivered");
|
|
13
|
-
crate::state::persist::save_runtime_state(
|
|
14
|
-
&ws,
|
|
15
|
-
&serde_json::json!({
|
|
16
|
-
"active_team_key": "teamX",
|
|
17
|
-
"agents": {"w1": {"status": "running", "provider": "codex"}}
|
|
18
|
-
}),
|
|
19
|
-
)
|
|
20
|
-
.unwrap();
|
|
21
|
-
let store = crate::message_store::MessageStore::open(&ws).unwrap();
|
|
22
|
-
// golden-delivered (must be IN delivered_message_ids): acknowledged + visible.
|
|
23
|
-
let m_ack = store
|
|
24
|
-
.create_message(None, "leader", "w1", "ack-me", None, true, Some("teamX"))
|
|
25
|
-
.unwrap();
|
|
26
|
-
store.mark(&m_ack, "delivered", None).unwrap();
|
|
27
|
-
store.mark(&m_ack, "acknowledged", None).unwrap();
|
|
28
|
-
let m_vis = store
|
|
29
|
-
.create_message(None, "leader", "w1", "vis", None, true, Some("teamX"))
|
|
30
|
-
.unwrap();
|
|
31
|
-
store.mark(&m_vis, "visible", None).unwrap();
|
|
32
|
-
// NOT golden-delivered (must be EXCLUDED): injected.
|
|
33
|
-
let m_inj = store
|
|
34
|
-
.create_message(None, "leader", "w1", "inj", None, true, Some("teamX"))
|
|
35
|
-
.unwrap();
|
|
36
|
-
store.mark(&m_inj, "injected", None).unwrap();
|
|
37
|
-
drop(store);
|
|
38
|
-
let _ = stuck_cancel(&ws, "w1", None, "leader").unwrap();
|
|
39
|
-
let state = crate::state::persist::load_runtime_state(&ws).unwrap();
|
|
40
|
-
let snapshot =
|
|
41
|
-
&state["coordinator"]["suppressed_idle_alerts"]["teamX"]["w1"]["stuck"]["snapshot"];
|
|
42
|
-
assert!(
|
|
43
|
-
snapshot.get("assigned_task_ids").is_some(),
|
|
44
|
-
"F1: snapshot must carry assigned_task_ids; got {snapshot}"
|
|
45
|
-
);
|
|
46
|
-
let delivered = snapshot
|
|
47
|
-
.get("delivered_message_ids")
|
|
48
|
-
.and_then(serde_json::Value::as_array)
|
|
49
|
-
.map(|a| {
|
|
50
|
-
a.iter()
|
|
51
|
-
.filter_map(|v| v.as_str().map(str::to_string))
|
|
52
|
-
.collect::<Vec<_>>()
|
|
53
|
-
})
|
|
54
|
-
.unwrap_or_else(|| panic!("F1: snapshot must carry delivered_message_ids; got {snapshot}"));
|
|
55
|
-
assert!(
|
|
56
|
-
delivered.contains(&m_ack),
|
|
57
|
-
"F1: golden _DELIVERED_MESSAGE_STATUSES includes 'acknowledged' — the acknowledged message must be \
|
|
58
|
-
in delivered_message_ids; the Rust set omits it. got {delivered:?}"
|
|
59
|
-
);
|
|
60
|
-
assert!(
|
|
61
|
-
delivered.contains(&m_vis),
|
|
62
|
-
"F1: 'visible' is delivered (golden); got {delivered:?}"
|
|
63
|
-
);
|
|
64
|
-
assert!(
|
|
65
|
-
!delivered.contains(&m_inj),
|
|
66
|
-
"F1: 'injected' is NOT in golden _DELIVERED_MESSAGE_STATUSES — it must be EXCLUDED; the Rust set \
|
|
67
|
-
wrongly includes it. got {delivered:?}"
|
|
68
|
-
);
|
|
69
|
-
let mut sorted = delivered.clone();
|
|
70
|
-
sorted.sort();
|
|
71
|
-
assert_eq!(
|
|
72
|
-
delivered, sorted,
|
|
73
|
-
"F1: delivered_message_ids must be sorted (golden sorts); got {delivered:?}"
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
3
|
// ── collect --result-file INGEST SEMANTIC (golden results.py:58-73) ──────────────────────────────
|
|
77
4
|
// Golden `collect(result_file=…)` INDEPENDENTLY INGESTS a standalone result: a valid result_envelope_v1
|
|
78
5
|
// is `store.add_result(envelope)`'d (results.py:73) regardless of any in-flight delivery, then the
|
|
@@ -979,32 +979,6 @@ fn requeue_delivery_exhausted_watchers_reopens_only_exhausted() {
|
|
|
979
979
|
);
|
|
980
980
|
}
|
|
981
981
|
|
|
982
|
-
// ════════════════════════════════════════════════════════════════════════
|
|
983
|
-
// GROUP P — stuck_cancel owner-gate + invalid alert type refusal.
|
|
984
|
-
// scheduler.py:262-294.
|
|
985
|
-
// ════════════════════════════════════════════════════════════════════════
|
|
986
|
-
|
|
987
|
-
#[test]
|
|
988
|
-
fn stuck_cancel_none_alert_type_expands_to_all() {
|
|
989
|
-
// alert_type None == Python "all" → sorted(_ALERT_TYPES) expansion.
|
|
990
|
-
let ws = tmp_ws("stuckcancel");
|
|
991
|
-
let out = stuck_cancel(&ws, "w1", None, "leader").unwrap();
|
|
992
|
-
// The suppression result must enumerate all three alert types.
|
|
993
|
-
let types = out.get("alert_types").and_then(|v| v.as_array()).map(|a| {
|
|
994
|
-
a.iter()
|
|
995
|
-
.filter_map(|x| x.as_str().map(str::to_string))
|
|
996
|
-
.collect::<Vec<_>>()
|
|
997
|
-
});
|
|
998
|
-
assert_eq!(
|
|
999
|
-
types,
|
|
1000
|
-
Some(vec![
|
|
1001
|
-
"cross_worker_deadlock".to_string(),
|
|
1002
|
-
"idle_fallback".to_string(),
|
|
1003
|
-
"stuck".to_string()
|
|
1004
|
-
])
|
|
1005
|
-
);
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
982
|
// ════════════════════════════════════════════════════════════════════════
|
|
1009
983
|
// GROUP Q — collect intake (results.py:45-167): valid result advances task,
|
|
1010
984
|
// returns collected_results + delivered_messages + results counts shape.
|
|
@@ -219,26 +219,6 @@ impl WorkerRuntimeState {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
/// 告警类型 (card §49;`scheduler.py:38` `_ALERT_TYPES`)。`stuck_cancel` 还接 `all` (展开全集)。
|
|
223
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
224
|
-
#[serde(rename_all = "snake_case")]
|
|
225
|
-
pub enum AlertType {
|
|
226
|
-
Stuck,
|
|
227
|
-
IdleFallback,
|
|
228
|
-
CrossWorkerDeadlock,
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
impl AlertType {
|
|
232
|
-
/// `stuck_cancel(alert_type="all")` → `sorted(_ALERT_TYPES)` 全集 (`scheduler.py:269`)。
|
|
233
|
-
pub fn all() -> [AlertType; 3] {
|
|
234
|
-
[
|
|
235
|
-
AlertType::CrossWorkerDeadlock,
|
|
236
|
-
AlertType::IdleFallback,
|
|
237
|
-
AlertType::Stuck,
|
|
238
|
-
]
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
|
|
242
222
|
/// selftest check 状态 (card §47;`diagnose/comms.py`)。§19 必变 enum。
|
|
243
223
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
244
224
|
#[serde(rename_all = "snake_case")]
|
|
@@ -1135,19 +1135,10 @@ mod tests {
|
|
|
1135
1135
|
);
|
|
1136
1136
|
}
|
|
1137
1137
|
|
|
1138
|
-
// 0.5.66 bypass 单源 §4.1:7
|
|
1139
|
-
//
|
|
1140
|
-
// compile 级校验确实 fail-loud,即各触发面(经 compile_team)都被覆盖。
|
|
1138
|
+
// 0.5.66 bypass 单源 §4.1:7 个生命周期入口共享编译后的 spec。
|
|
1139
|
+
// 缺失 role frontmatter 值时由编译器注入 true;此处锁定公共编译入口的默认结果。
|
|
1141
1140
|
#[test]
|
|
1142
|
-
fn
|
|
1143
|
-
// compile_team 是 7 触发面的 spec 校验必经点:
|
|
1144
|
-
// quick-start(quick_start.rs:233 compile_team)
|
|
1145
|
-
// restart(rebuild.rs:3245 rebuild_runtime_spec_from_roles → compile_team)
|
|
1146
|
-
// add-agent(add_agent.rs:331 compile_role_agent)
|
|
1147
|
-
// clone-agent(clone_agent.rs:62 → add_agent)
|
|
1148
|
-
// fork-agent(fork_agent.rs:96 validate_spec)
|
|
1149
|
-
// start-agent / reset-agent(操作已编译 spec,团队创建时经 compile_team 校验)
|
|
1150
|
-
// 验证 compile_team 对缺字段的角色文档 fail-loud。
|
|
1141
|
+
fn test_all_7_triggers_use_compiled_default_bypass() {
|
|
1151
1142
|
let team = std::env::temp_dir().join(format!(
|
|
1152
1143
|
"ta-spec-7trigger-{}",
|
|
1153
1144
|
std::process::id()
|
|
@@ -1159,17 +1150,22 @@ mod tests {
|
|
|
1159
1150
|
"---\nname: t7\nobjective: 7 trigger.\nprovider: codex\n---\n\nteam.\n",
|
|
1160
1151
|
)
|
|
1161
1152
|
.unwrap();
|
|
1162
|
-
//
|
|
1153
|
+
// 角色文档故意省略该字段;纯文本默认必须写入 compiled spec。
|
|
1163
1154
|
std::fs::write(
|
|
1164
1155
|
team.join("agents").join("w.md"),
|
|
1165
1156
|
"---\nname: w\nrole: Worker\nprovider: codex\ntools:\n - mcp_team\n---\n\nw.\n",
|
|
1166
1157
|
)
|
|
1167
1158
|
.unwrap();
|
|
1168
|
-
let
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1159
|
+
let spec = crate::compiler::compile_team(&team)
|
|
1160
|
+
.expect("compile_team must materialize the default bypass value");
|
|
1161
|
+
let agent = spec
|
|
1162
|
+
.get("agents")
|
|
1163
|
+
.and_then(Yaml::as_list)
|
|
1164
|
+
.and_then(|agents| agents.first())
|
|
1165
|
+
.expect("compiled spec has a worker");
|
|
1166
|
+
assert_eq!(
|
|
1167
|
+
agent.get("dangerously_skip_permissions"),
|
|
1168
|
+
Some(&Yaml::Bool(true))
|
|
1173
1169
|
);
|
|
1174
1170
|
let _ = std::fs::remove_dir_all(&team);
|
|
1175
1171
|
}
|