@team-agent/installer 0.5.98 → 0.5.100
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 -163
- package/crates/team-agent/src/cli/diagnose.rs +3 -19
- package/crates/team-agent/src/cli/emit.rs +20 -204
- package/crates/team-agent/src/cli/mod.rs +138 -205
- package/crates/team-agent/src/cli/send/coordinator.rs +2 -2
- package/crates/team-agent/src/cli/spec.rs +41 -67
- package/crates/team-agent/src/cli/tests/main_preserved.rs +2 -186
- package/crates/team-agent/src/cli/tests/missing_subcommands.rs +9 -10
- package/crates/team-agent/src/cli/tests/run_delegation.rs +0 -3
- package/crates/team-agent/src/cli/tests/verb_validate.rs +0 -1
- package/crates/team-agent/src/cli/triage.rs +1 -1
- package/crates/team-agent/src/cli/types.rs +0 -55
- package/crates/team-agent/src/compiler/tests.rs +5 -8
- package/crates/team-agent/src/compiler.rs +6 -14
- package/crates/team-agent/src/leader/lease.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/add_agent.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/agent_state.rs +5 -25
- package/crates/team-agent/src/lifecycle/launch/identity.rs +2 -18
- package/crates/team-agent/src/lifecycle/launch/layout.rs +7 -29
- package/crates/team-agent/src/lifecycle/launch/leader_context.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/mcp_config.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/ownership.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/pi_mcp.rs +7 -7
- package/crates/team-agent/src/lifecycle/launch/quick_start.rs +12 -49
- package/crates/team-agent/src/lifecycle/launch/quick_start_transport.rs +3 -9
- package/crates/team-agent/src/lifecycle/launch/readiness.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +2 -61
- package/crates/team-agent/src/lifecycle/launch/spec_state.rs +2 -15
- package/crates/team-agent/src/lifecycle/launch/state_projection.rs +3 -7
- package/crates/team-agent/src/lifecycle/launch/worker_env.rs +1 -1
- package/crates/team-agent/src/lifecycle/launch.rs +3 -4
- package/crates/team-agent/src/lifecycle/mod.rs +0 -8
- package/crates/team-agent/src/lifecycle/restart/agent.rs +62 -8
- package/crates/team-agent/src/lifecycle/restart/common.rs +0 -32
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +6 -15
- package/crates/team-agent/src/lifecycle/tests/b0_reader_hideone_audit_contract.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/claude_profile_launch_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/clone_agent_preserves_source_tools.rs +1 -2
- package/crates/team-agent/src/lifecycle/tests/clone_fork_copilot_perms_red.rs +0 -1
- package/crates/team-agent/src/lifecycle/tests/core.rs +0 -213
- package/crates/team-agent/src/lifecycle/tests/issue238_codex_effort_contract.rs +96 -0
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +1 -0
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +31 -77
- package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests/phase_b_contracts.rs +4 -8
- package/crates/team-agent/src/lifecycle/tests/phase_golden.rs +16 -9
- package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/realmachine_clusters_1_6_red.rs +0 -60
- package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +3 -4
- package/crates/team-agent/src/lifecycle/tests/team_in_team_identity_scope_red.rs +2 -2
- package/crates/team-agent/src/lifecycle/tests.rs +1 -2
- package/crates/team-agent/src/lifecycle/types.rs +3 -133
- package/crates/team-agent/src/messaging/send.rs +2 -2
- package/crates/team-agent/src/model/enums.rs +21 -71
- package/crates/team-agent/src/model/spec.rs +5 -20
- package/crates/team-agent/src/provider/adapters/codex.rs +2 -2
- package/crates/team-agent/src/provider/types.rs +7 -6
- package/crates/team-agent/src/state/repository.rs +0 -5
- package/examples/team.spec.yaml +0 -1
- package/package.json +4 -4
- package/schemas/team.schema.json +2 -2
- package/skills/team-agent/SKILL.md +1 -1
- package/skills/team-agent/references/recovery-runbook.md +2 -2
- package/skills/team-agent/references/team-agent-operator.md +3 -10
- package/skills/team-agent/references/team-in-team.md +0 -6
- package/crates/team-agent/src/lifecycle/display.rs +0 -550
- package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +0 -884
- package/crates/team-agent/src/lifecycle/tests/display_adaptive_red.rs +0 -481
|
@@ -58,11 +58,9 @@ mod codex_weak_window_attribution_red;
|
|
|
58
58
|
mod communication_mode_runtime_contract_red;
|
|
59
59
|
mod copilot_provider_red;
|
|
60
60
|
mod core;
|
|
61
|
-
mod core_034_real_red;
|
|
62
61
|
mod cursor_mcp_overlay;
|
|
63
62
|
mod cursor_require_explicit_model_red;
|
|
64
63
|
mod cursor_restart_resume_red;
|
|
65
|
-
mod display_adaptive_red;
|
|
66
64
|
mod f032_startup_prompt_best_effort_red;
|
|
67
65
|
mod grok_effort_argv_red;
|
|
68
66
|
mod grok_mcp_overlay_red;
|
|
@@ -70,6 +68,7 @@ mod grok_require_explicit_model_red;
|
|
|
70
68
|
mod grok_restart_resume_red;
|
|
71
69
|
mod harvest2_a_batch_red;
|
|
72
70
|
mod host_cotenant_death_p0_contract;
|
|
71
|
+
mod issue238_codex_effort_contract;
|
|
73
72
|
mod lane_ops;
|
|
74
73
|
mod launch_spawn;
|
|
75
74
|
mod lifecycle_lock;
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
//! ---
|
|
25
25
|
//! lifecycle 数据类型:newtype / enum / data struct / error / outcome-report 集中定义。
|
|
26
26
|
|
|
27
|
-
use std::collections::BTreeMap;
|
|
28
27
|
use std::path::PathBuf;
|
|
29
28
|
|
|
30
29
|
use serde::{Deserialize, Serialize};
|
|
@@ -32,9 +31,7 @@ use thiserror::Error;
|
|
|
32
31
|
|
|
33
32
|
use crate::model::ids::AgentId;
|
|
34
33
|
use crate::provider::{RolloutPath, SessionId};
|
|
35
|
-
use crate::transport::
|
|
36
|
-
|
|
37
|
-
use super::DisplayBackend;
|
|
34
|
+
use crate::transport::SessionName;
|
|
38
35
|
|
|
39
36
|
// ===========================================================================
|
|
40
37
|
// CROSS-LANE PLACEHOLDERS(13/14/15 兄弟 lane 尚未交付;leader 集成时 reconcile)
|
|
@@ -184,22 +181,6 @@ impl std::fmt::Display for PlanId {
|
|
|
184
181
|
}
|
|
185
182
|
}
|
|
186
183
|
|
|
187
|
-
/// ghostty 派生的唯一 linked-session 名(`ghostty_display_session_name`,sha1 派生,
|
|
188
|
-
/// `display/ghostty.py`)。与 worker 的 `SessionName` 类型上区分,防混传(card §57)。
|
|
189
|
-
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
190
|
-
#[serde(transparent)]
|
|
191
|
-
pub struct DisplaySessionName(pub String);
|
|
192
|
-
|
|
193
|
-
impl DisplaySessionName {
|
|
194
|
-
/// ---
|
|
195
|
-
/// purpose: 取 ghostty 派生 display session 名的原始字符串
|
|
196
|
-
/// returns: 内部保存的名字
|
|
197
|
-
/// ---
|
|
198
|
-
pub fn as_str(&self) -> &str {
|
|
199
|
-
&self.0
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
184
|
// ===========================================================================
|
|
204
185
|
// ENUM(card §3/§11:散字符串 → 穷尽 enum)
|
|
205
186
|
// ===========================================================================
|
|
@@ -240,30 +221,6 @@ pub enum FirstSendAtState {
|
|
|
240
221
|
Corrupt,
|
|
241
222
|
}
|
|
242
223
|
|
|
243
|
-
/// adaptive 阻塞 reason(`ADAPTIVE_BLOCK_REASONS`,6 个封闭值,`display/adaptive.py:21`)。
|
|
244
|
-
/// **必须 enum**(契约 C16 封闭集);`adaptive_blocked` 对越界 reason 兜底成
|
|
245
|
-
/// `AggregatorRebuildFailed`。
|
|
246
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
247
|
-
#[serde(rename_all = "snake_case")]
|
|
248
|
-
pub enum AdaptiveBlockReason {
|
|
249
|
-
LeaderNotInTmux,
|
|
250
|
-
SplitFailed,
|
|
251
|
-
WindowCreateFailed,
|
|
252
|
-
WorkerSessionMissing,
|
|
253
|
-
NotImplementedThisPlatform,
|
|
254
|
-
AggregatorRebuildFailed,
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/// display `status`(`agent_state["display"]["status"]`,`start.py:123`)。
|
|
258
|
-
/// **应 enum**:决定 `start_agent` 是否重开显示。
|
|
259
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
260
|
-
#[serde(rename_all = "snake_case")]
|
|
261
|
-
pub enum DisplayStatus {
|
|
262
|
-
Opened,
|
|
263
|
-
Blocked,
|
|
264
|
-
Stopped,
|
|
265
|
-
}
|
|
266
|
-
|
|
267
224
|
/// plan `status`(`orchestrator/__init__.py`)。**应 enum**:`start_plan` 对已
|
|
268
225
|
/// running/halted/completed 幂等返回。
|
|
269
226
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
@@ -285,64 +242,9 @@ pub enum DangerousApprovalSource {
|
|
|
285
242
|
}
|
|
286
243
|
|
|
287
244
|
// ===========================================================================
|
|
288
|
-
// DATA STRUCT(
|
|
245
|
+
// DATA STRUCT(restart 候选 / plan state / 危险审批)
|
|
289
246
|
// ===========================================================================
|
|
290
247
|
|
|
291
|
-
/// adaptive 能力探测结果(`probe_display_capabilities`,`display/adaptive.py:31`)。
|
|
292
|
-
/// **C13 一等公民**:分支只看 probe,不看 `cfg!(target_os)`;Windows/WSL →
|
|
293
|
-
/// `NotImplementedThisPlatform`。
|
|
294
|
-
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
295
|
-
pub struct DisplayProbe {
|
|
296
|
-
pub in_tmux: bool,
|
|
297
|
-
pub platform: String,
|
|
298
|
-
pub leader_session: Option<SessionName>,
|
|
299
|
-
pub leader_pane: Option<PaneId>,
|
|
300
|
-
pub caps: CapsFlags,
|
|
301
|
-
/// 探测后的 adaptive 状态(可开 / 已封闭+reason)。
|
|
302
|
-
pub adaptive_status: DisplayStatus,
|
|
303
|
-
/// 封闭时填 reason(C16 封闭集)。
|
|
304
|
-
pub reason: Option<AdaptiveBlockReason>,
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
/// 平台能力位(`caps{tmux_append_windows, adaptive_display}`)。
|
|
308
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
309
|
-
pub struct CapsFlags {
|
|
310
|
-
pub tmux_append_windows: bool,
|
|
311
|
-
pub adaptive_display: bool,
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/// 每 worker display state(写进 `state.agents.<id>.display`)。adaptive vs ghostty_window
|
|
315
|
-
/// vs ghostty_workspace 字段不同 → enum 区分(card §50)。
|
|
316
|
-
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
317
|
-
#[serde(tag = "backend", rename_all = "snake_case")]
|
|
318
|
-
pub enum WorkerDisplay {
|
|
319
|
-
Adaptive {
|
|
320
|
-
status: DisplayStatus,
|
|
321
|
-
window: Option<WindowName>,
|
|
322
|
-
workspace_window: Option<WindowName>,
|
|
323
|
-
pane_id: Option<PaneId>,
|
|
324
|
-
pane_title: Option<String>,
|
|
325
|
-
target: Option<String>,
|
|
326
|
-
target_worker_session: Option<String>,
|
|
327
|
-
linked_session: Option<String>,
|
|
328
|
-
leader_session: Option<SessionName>,
|
|
329
|
-
display_session: Option<SessionName>,
|
|
330
|
-
fallback: Option<String>,
|
|
331
|
-
},
|
|
332
|
-
GhosttyWindow {
|
|
333
|
-
status: DisplayStatus,
|
|
334
|
-
linked_session: DisplaySessionName,
|
|
335
|
-
display_session: DisplaySessionName,
|
|
336
|
-
},
|
|
337
|
-
GhosttyWorkspace {
|
|
338
|
-
status: DisplayStatus,
|
|
339
|
-
display_session: DisplaySessionName,
|
|
340
|
-
},
|
|
341
|
-
Blocked {
|
|
342
|
-
reason: AdaptiveBlockReason,
|
|
343
|
-
},
|
|
344
|
-
}
|
|
345
|
-
|
|
346
248
|
/// `RestartCandidate`(`restart/selection.py:27`)。`select_restart_state` 多 team 选择;
|
|
347
249
|
/// `has_context` 是 resume 可行性粗判。
|
|
348
250
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
@@ -464,8 +366,7 @@ impl PlanCondition {
|
|
|
464
366
|
// ERROR(card §10:fallible 边界;daemon/CLI 入口返 rich Result<Report, Error>)
|
|
465
367
|
// ===========================================================================
|
|
466
368
|
|
|
467
|
-
/// lifecycle
|
|
468
|
-
/// outcome(`DisplayStatus::Blocked` / `AdaptiveBlockReason`)。这里只装真失败:
|
|
369
|
+
/// lifecycle 子系统错误。这里只装真失败:
|
|
469
370
|
/// owner-gate 拒绝、session 冲突、state 写崩(bug-084)、provider/transport I/O、回滚失败。
|
|
470
371
|
#[derive(Debug, Error)]
|
|
471
372
|
pub enum LifecycleError {
|
|
@@ -560,10 +461,6 @@ pub struct StartedAgent {
|
|
|
560
461
|
pub claude_config_dir: Option<PathBuf>,
|
|
561
462
|
pub provider_projects_root: Option<PathBuf>,
|
|
562
463
|
pub managed_mcp_config: bool,
|
|
563
|
-
pub layout_window: Option<WindowName>,
|
|
564
|
-
pub layout_index: Option<usize>,
|
|
565
|
-
pub pane_index: Option<usize>,
|
|
566
|
-
pub display: WorkerDisplay,
|
|
567
464
|
}
|
|
568
465
|
|
|
569
466
|
/// 路由决策(`routing.decision` 事件 / launch `routes[]`)。
|
|
@@ -603,7 +500,6 @@ pub enum QuickStartReport {
|
|
|
603
500
|
launch: Box<LaunchReport>,
|
|
604
501
|
next_actions: Vec<String>,
|
|
605
502
|
attach_commands: Vec<String>,
|
|
606
|
-
display_backend: String,
|
|
607
503
|
/// BUG-7: real readiness verdict. `Ready` ⇒ the wrapper completed AND the
|
|
608
504
|
/// caller already verified tool-set availability; the framework itself
|
|
609
505
|
/// never emits this without an external observable confirming worker
|
|
@@ -940,32 +836,6 @@ pub struct RestartPlan {
|
|
|
940
836
|
pub unresumable: Vec<UnresumableWorker>,
|
|
941
837
|
}
|
|
942
838
|
|
|
943
|
-
/// display 解析结果(`resolve_display_backend`,`display/backend.py`)。非默认时非静默
|
|
944
|
-
/// 发 `display.backend_resolved`。
|
|
945
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
946
|
-
pub struct ResolvedBackend {
|
|
947
|
-
pub backend: DisplayBackend,
|
|
948
|
-
/// 是否非默认(默认 adaptive;非默认非静默发事件)。
|
|
949
|
-
pub non_default: bool,
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
/// `open_worker_displays` 结果(`display/worker_window.py`)。每 worker 一个
|
|
953
|
-
/// `WorkerDisplay`,失败不阻塞 team readiness(C14)。
|
|
954
|
-
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
955
|
-
pub struct OpenDisplaysReport {
|
|
956
|
-
pub backend: DisplayBackend,
|
|
957
|
-
pub displays: BTreeMap<String, WorkerDisplay>,
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
/// `close_team_display_backends` 结果(`display/close.py`,C9 close-by-recorded-backend)。
|
|
961
|
-
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
962
|
-
pub struct CloseDisplaysReport {
|
|
963
|
-
/// 按 state 记录的后端关掉的窗口/会话标识。
|
|
964
|
-
pub closed: Vec<String>,
|
|
965
|
-
/// orphan 清理(adaptive 只删带 team tag 的窗口,C2 leader pane 安全)。
|
|
966
|
-
pub orphans_cleaned: Vec<String>,
|
|
967
|
-
}
|
|
968
|
-
|
|
969
839
|
/// plan 状态机推进结果(`orchestrator/__init__.py` start_plan / handle_report_result /
|
|
970
840
|
/// halt_plan 的 typed 版)。
|
|
971
841
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
@@ -551,11 +551,11 @@ fn coordinator_unavailable_outcome(
|
|
|
551
551
|
);
|
|
552
552
|
let warning = if persist {
|
|
553
553
|
format!(
|
|
554
|
-
"coordinator is not running; message was queued for {recipient} and will retry. Run `team-agent
|
|
554
|
+
"coordinator is not running; message was queued for {recipient} and will retry. Run `team-agent doctor` or restart the team."
|
|
555
555
|
)
|
|
556
556
|
} else {
|
|
557
557
|
format!(
|
|
558
|
-
"coordinator protocol or schema is incompatible; message was not queued for {recipient}. Run `team-agent
|
|
558
|
+
"coordinator protocol or schema is incompatible; message was not queued for {recipient}. Run `team-agent doctor` or upgrade the runtime."
|
|
559
559
|
)
|
|
560
560
|
};
|
|
561
561
|
event_log.write(
|
|
@@ -34,15 +34,18 @@ pub enum Provider {
|
|
|
34
34
|
|
|
35
35
|
/// 0.4.x Provider effort MVP: reasoning effort level passed to the provider.
|
|
36
36
|
/// Configuration sources (resolution order):
|
|
37
|
-
/// 1. role doc front matter `effort: low|medium|high|xhigh|max`
|
|
38
|
-
/// 2. TEAM.md front matter `provider_effort: low|medium|high|xhigh|max`
|
|
37
|
+
/// 1. role doc front matter `effort: low|medium|high|xhigh|max|ultra`
|
|
38
|
+
/// 2. TEAM.md front matter `provider_effort: low|medium|high|xhigh|max|ultra` (except Pi)
|
|
39
39
|
/// 3. provider default (framework passes no flag)
|
|
40
40
|
///
|
|
41
41
|
/// Provider support:
|
|
42
42
|
/// - claude / claude_code: low|medium|high|xhigh|max → `--effort <level>`
|
|
43
|
-
/// - codex: low|medium|high|xhigh
|
|
44
|
-
///
|
|
45
|
-
/// -
|
|
43
|
+
/// - codex: low|medium|high|xhigh|max|ultra → `-c model_reasoning_effort=<level>`
|
|
44
|
+
/// Ultra adds Codex client delegation to max reasoning; it is not an API effort.
|
|
45
|
+
/// - pi: low|medium|high|xhigh|max → `--thinking <level>`
|
|
46
|
+
/// - grok: low|medium|high|xhigh → `--effort <level>`; max/ultra rejected
|
|
47
|
+
/// - copilot / gemini_cli / fake: low..xhigh ignored with warning; max/ultra rejected
|
|
48
|
+
/// - cursor_agent: all effort rejected
|
|
46
49
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
47
50
|
pub enum ProviderEffort {
|
|
48
51
|
#[serde(rename = "low")]
|
|
@@ -55,6 +58,8 @@ pub enum ProviderEffort {
|
|
|
55
58
|
XHigh,
|
|
56
59
|
#[serde(rename = "max")]
|
|
57
60
|
Max,
|
|
61
|
+
#[serde(rename = "ultra")]
|
|
62
|
+
Ultra,
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
impl ProviderEffort {
|
|
@@ -66,6 +71,7 @@ impl ProviderEffort {
|
|
|
66
71
|
"high" => Some(Self::High),
|
|
67
72
|
"xhigh" => Some(Self::XHigh),
|
|
68
73
|
"max" => Some(Self::Max),
|
|
74
|
+
"ultra" => Some(Self::Ultra),
|
|
69
75
|
_ => None,
|
|
70
76
|
}
|
|
71
77
|
}
|
|
@@ -78,20 +84,17 @@ impl ProviderEffort {
|
|
|
78
84
|
Self::High => "high",
|
|
79
85
|
Self::XHigh => "xhigh",
|
|
80
86
|
Self::Max => "max",
|
|
87
|
+
Self::Ultra => "ultra",
|
|
81
88
|
}
|
|
82
89
|
}
|
|
83
90
|
|
|
84
|
-
///
|
|
85
|
-
|
|
86
|
-
matches!(self, Self::Max)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/// Native command support. Claude/Pi accept max; Codex/Grok accept
|
|
90
|
-
/// the other levels. Use resolve_for_provider for admission/ignore policy.
|
|
91
|
+
/// Native command support: Codex through ultra, Claude/Pi through max,
|
|
92
|
+
/// Grok through xhigh. Use resolve_for_provider for admission/ignore policy.
|
|
91
93
|
pub fn is_supported_by(self, provider: Provider) -> bool {
|
|
92
94
|
match provider {
|
|
93
|
-
Provider::
|
|
94
|
-
Provider::
|
|
95
|
+
Provider::Codex => true,
|
|
96
|
+
Provider::Claude | Provider::ClaudeCode | Provider::Pi => self != Self::Ultra,
|
|
97
|
+
Provider::Grok => !matches!(self, Self::Max | Self::Ultra),
|
|
95
98
|
Provider::Copilot | Provider::GeminiCli | Provider::CursorAgent | Provider::Fake => {
|
|
96
99
|
false
|
|
97
100
|
}
|
|
@@ -106,8 +109,10 @@ impl ProviderEffort {
|
|
|
106
109
|
}
|
|
107
110
|
if self.is_supported_by(provider) {
|
|
108
111
|
Ok(Some(self))
|
|
109
|
-
} else if self
|
|
110
|
-
Err("effort '
|
|
112
|
+
} else if self == Self::Ultra {
|
|
113
|
+
Err("effort 'ultra' is only supported by codex")
|
|
114
|
+
} else if self == Self::Max {
|
|
115
|
+
Err("effort 'max' is only supported by claude/claude_code/codex/pi")
|
|
111
116
|
} else {
|
|
112
117
|
Ok(None)
|
|
113
118
|
}
|
|
@@ -208,30 +213,6 @@ pub enum Backend {
|
|
|
208
213
|
Pty,
|
|
209
214
|
}
|
|
210
215
|
|
|
211
|
-
/// display backend(`VALID_DISPLAY_BACKENDS` `display/backend.py:7-9`)。
|
|
212
|
-
/// **`adaptive` 在代码集里但不在 JSON schema enum** —— 以代码为准(陷阱 #5)。
|
|
213
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
214
|
-
#[serde(rename_all = "snake_case")]
|
|
215
|
-
pub enum DisplayBackend {
|
|
216
|
-
None,
|
|
217
|
-
TmuxAttach,
|
|
218
|
-
Iterm,
|
|
219
|
-
Ghostty,
|
|
220
|
-
GhosttyWindow,
|
|
221
|
-
GhosttyWorkspace,
|
|
222
|
-
Adaptive,
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
impl DisplayBackend {
|
|
226
|
-
/// `DISPLAY_BACKENDS_WITH_WORKER_VIEWS = GHOSTTY_* | {adaptive}`(`display/backend.py:8`)。
|
|
227
|
-
pub fn has_worker_views(self) -> bool {
|
|
228
|
-
matches!(
|
|
229
|
-
self,
|
|
230
|
-
Self::Ghostty | Self::GhosttyWindow | Self::GhosttyWorkspace | Self::Adaptive
|
|
231
|
-
)
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
216
|
/// agent permission mode(schema `agent.permission_mode`;compiler 恒发 `restricted`)。
|
|
236
217
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
237
218
|
#[serde(rename_all = "snake_case")]
|
|
@@ -324,18 +305,6 @@ mod tests {
|
|
|
324
305
|
serde_json::to_string(&CommProtocol::McpInbox).unwrap(),
|
|
325
306
|
"\"mcp_inbox\"",
|
|
326
307
|
),
|
|
327
|
-
(
|
|
328
|
-
serde_json::to_string(&DisplayBackend::TmuxAttach).unwrap(),
|
|
329
|
-
"\"tmux_attach\"",
|
|
330
|
-
),
|
|
331
|
-
(
|
|
332
|
-
serde_json::to_string(&DisplayBackend::GhosttyWorkspace).unwrap(),
|
|
333
|
-
"\"ghostty_workspace\"",
|
|
334
|
-
),
|
|
335
|
-
(
|
|
336
|
-
serde_json::to_string(&DisplayBackend::Adaptive).unwrap(),
|
|
337
|
-
"\"adaptive\"",
|
|
338
|
-
),
|
|
339
308
|
(
|
|
340
309
|
serde_json::to_string(&PaneLiveness::Unknown).unwrap(),
|
|
341
310
|
"\"unknown\"",
|
|
@@ -380,25 +349,6 @@ mod tests {
|
|
|
380
349
|
}
|
|
381
350
|
}
|
|
382
351
|
|
|
383
|
-
#[test]
|
|
384
|
-
fn display_backend_worker_views() {
|
|
385
|
-
for b in [
|
|
386
|
-
DisplayBackend::Ghostty,
|
|
387
|
-
DisplayBackend::GhosttyWindow,
|
|
388
|
-
DisplayBackend::GhosttyWorkspace,
|
|
389
|
-
DisplayBackend::Adaptive,
|
|
390
|
-
] {
|
|
391
|
-
assert!(b.has_worker_views());
|
|
392
|
-
}
|
|
393
|
-
for b in [
|
|
394
|
-
DisplayBackend::None,
|
|
395
|
-
DisplayBackend::TmuxAttach,
|
|
396
|
-
DisplayBackend::Iterm,
|
|
397
|
-
] {
|
|
398
|
-
assert!(!b.has_worker_views());
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
|
|
402
352
|
#[test]
|
|
403
353
|
fn receive_worker_outputs_passthrough_preserves_drift_value() {
|
|
404
354
|
// compiler 发的 drift 值必须原样保留(byte 不丢),不被拒。
|
|
@@ -20,6 +20,8 @@ use crate::model::yaml::Value as Yaml;
|
|
|
20
20
|
use crate::model::yaml;
|
|
21
21
|
use crate::provider::wire::parse_canonical_provider;
|
|
22
22
|
|
|
23
|
+
const LEGACY_DISPLAY_KEY: &str = concat!("display", "_backend");
|
|
24
|
+
|
|
23
25
|
/// result_envelope_v1 顶层 required(= allowed)。
|
|
24
26
|
const RESULT_REQUIRED: &[&str] = &[
|
|
25
27
|
"schema_version",
|
|
@@ -211,15 +213,6 @@ const ROOT_KEYS: &[&str] = &[
|
|
|
211
213
|
"tasks",
|
|
212
214
|
];
|
|
213
215
|
const AUTH_MODES: &[&str] = &["subscription", "official_api", "compatible_api"];
|
|
214
|
-
const VALID_DISPLAY_BACKENDS: &[&str] = &[
|
|
215
|
-
"none",
|
|
216
|
-
"tmux_attach",
|
|
217
|
-
"iterm",
|
|
218
|
-
"ghostty",
|
|
219
|
-
"ghostty_window",
|
|
220
|
-
"ghostty_workspace",
|
|
221
|
-
"adaptive",
|
|
222
|
-
];
|
|
223
216
|
const TASK_STATUS_STRS: &[&str] = &[
|
|
224
217
|
"pending",
|
|
225
218
|
"ready",
|
|
@@ -319,7 +312,7 @@ fn basic_schema_errors(spec: &Yaml) -> Vec<String> {
|
|
|
319
312
|
if let Some(raw) = team.get("provider_effort").and_then(Yaml::as_str) {
|
|
320
313
|
if crate::model::enums::ProviderEffort::parse(raw).is_none() {
|
|
321
314
|
e.push(format!(
|
|
322
|
-
"/team/provider_effort: unknown effort '{raw}' (allowed: low|medium|high|xhigh|max)"
|
|
315
|
+
"/team/provider_effort: unknown effort '{raw}' (allowed: low|medium|high|xhigh|max|ultra)"
|
|
323
316
|
));
|
|
324
317
|
}
|
|
325
318
|
}
|
|
@@ -460,7 +453,7 @@ fn check_agent(agent: &Yaml, path: &str, errors: &mut Vec<String>) {
|
|
|
460
453
|
match crate::model::enums::ProviderEffort::parse(raw) {
|
|
461
454
|
None => {
|
|
462
455
|
errors.push(format!(
|
|
463
|
-
"{path}/effort: unknown effort '{raw}' (allowed: low|medium|high|xhigh|max)"
|
|
456
|
+
"{path}/effort: unknown effort '{raw}' (allowed: low|medium|high|xhigh|max|ultra)"
|
|
464
457
|
));
|
|
465
458
|
}
|
|
466
459
|
Some(effort) => {
|
|
@@ -598,7 +591,7 @@ fn check_runtime(runtime: Option<&Yaml>, errors: &mut Vec<String>) {
|
|
|
598
591
|
"require_user_approval_before_launch",
|
|
599
592
|
"max_active_agents",
|
|
600
593
|
"startup_order",
|
|
601
|
-
|
|
594
|
+
LEGACY_DISPLAY_KEY,
|
|
602
595
|
"auto_attach_leader",
|
|
603
596
|
"fast",
|
|
604
597
|
"tick_interval_sec",
|
|
@@ -614,14 +607,6 @@ fn check_runtime(runtime: Option<&Yaml>, errors: &mut Vec<String>) {
|
|
|
614
607
|
if !matches!(get("backend").and_then(Yaml::as_str), Some("tmux" | "pty")) {
|
|
615
608
|
errors.push("/runtime/backend: invalid backend".to_string());
|
|
616
609
|
}
|
|
617
|
-
if let Some(db) = get("display_backend") {
|
|
618
|
-
if !db
|
|
619
|
-
.as_str()
|
|
620
|
-
.is_some_and(|s| VALID_DISPLAY_BACKENDS.contains(&s))
|
|
621
|
-
{
|
|
622
|
-
errors.push("/runtime/display_backend: invalid display backend".to_string());
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
610
|
if get("auto_trust_own_workspace").is_some_and(|v| !matches!(v, Yaml::Bool(_))) {
|
|
626
611
|
errors.push("/runtime/auto_trust_own_workspace: must be a boolean".to_string());
|
|
627
612
|
}
|
|
@@ -21,8 +21,8 @@ pub(crate) fn codex_base_command(
|
|
|
21
21
|
// 0.4.x provider effort MVP step 6: when Some, inject
|
|
22
22
|
// `-c model_reasoning_effort=<level>` AFTER existing profile
|
|
23
23
|
// codex_config overrides — explicit launch effort wins over profile.
|
|
24
|
-
//
|
|
25
|
-
//
|
|
24
|
+
// Preserve max/ultra verbatim: ultra enables Codex client delegation
|
|
25
|
+
// on top of max reasoning, rather than a separate model API effort.
|
|
26
26
|
effort: Option<crate::model::enums::ProviderEffort>,
|
|
27
27
|
) -> Vec<String> {
|
|
28
28
|
let mut argv = vec!["codex".to_string()];
|
|
@@ -172,7 +172,7 @@ pub enum AuthHintStatus {
|
|
|
172
172
|
pub enum NoPingReason {
|
|
173
173
|
/// worker 从未 open 过 turn(`idle_predicate.py:61`)。
|
|
174
174
|
NotArmedNoWorkerTurn,
|
|
175
|
-
///
|
|
175
|
+
/// Suppress flag from a legacy idle acknowledgement (`idle_predicate.py:63`).
|
|
176
176
|
Acknowledged,
|
|
177
177
|
/// armed 但 elapsed < debounce(`idle_predicate.py:65`)。
|
|
178
178
|
DebounceActive,
|
|
@@ -352,11 +352,12 @@ pub struct ProviderCommandContext<'a> {
|
|
|
352
352
|
/// from role doc / TEAM.md / provider default. `None` means the
|
|
353
353
|
/// framework passes no effort flag (provider default).
|
|
354
354
|
/// - Claude / ClaudeCode: low|medium|high|xhigh|max → `--effort <level>`
|
|
355
|
-
/// - Codex: low|medium|high|xhigh → `-c model_reasoning_effort=<level>`
|
|
356
|
-
///
|
|
357
|
-
/// -
|
|
358
|
-
///
|
|
359
|
-
///
|
|
355
|
+
/// - Codex: low|medium|high|xhigh|max|ultra → `-c model_reasoning_effort=<level>`
|
|
356
|
+
/// Ultra enables Codex client delegation on top of max reasoning.
|
|
357
|
+
/// - Pi: low|medium|high|xhigh|max → `--thinking <level>`; ultra rejected
|
|
358
|
+
/// - Grok: low|medium|high|xhigh → `--effort <level>`; max/ultra rejected
|
|
359
|
+
/// - Copilot / Gemini / Fake: low..xhigh ignored with a caller warning;
|
|
360
|
+
/// max/ultra rejected. CursorAgent rejects all effort.
|
|
360
361
|
pub effort: Option<crate::model::enums::ProviderEffort>,
|
|
361
362
|
}
|
|
362
363
|
|
|
@@ -419,9 +419,6 @@ pub enum StateWriteIntent<'a> {
|
|
|
419
419
|
SchedulerSuppression {
|
|
420
420
|
owner_team_id: Option<&'a str>,
|
|
421
421
|
},
|
|
422
|
-
IdleAck {
|
|
423
|
-
team_key: Option<&'a str>,
|
|
424
|
-
},
|
|
425
422
|
TaskRepair {
|
|
426
423
|
team_key: Option<&'a str>,
|
|
427
424
|
},
|
|
@@ -650,8 +647,6 @@ fn route_direct(
|
|
|
650
647
|
},
|
|
651
648
|
// SchedulerSuppression -> root save (messaging/scheduler.rs:259).
|
|
652
649
|
StateWriteIntent::SchedulerSuppression { .. } => helper_write_root(workspace, state),
|
|
653
|
-
// IdleAck -> root save (cli/mod.rs:2544).
|
|
654
|
-
StateWriteIntent::IdleAck { .. } => helper_write_root(workspace, state),
|
|
655
650
|
// TaskRepair -> `save_team_scoped_state` (cli/adapters.rs:675).
|
|
656
651
|
StateWriteIntent::TaskRepair { .. } => helper_write_team_scoped(workspace, state),
|
|
657
652
|
// FakeE2eSeed / SelfMigration are diagnostic seams. The current
|
package/examples/team.spec.yaml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@team-agent/installer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.100",
|
|
4
4
|
"description": "npx installer for Team Agent",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codex",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"team-agent-installer": "npm/install.mjs"
|
|
21
21
|
},
|
|
22
22
|
"optionalDependencies": {
|
|
23
|
-
"@team-agent/cli-darwin-arm64": "0.5.
|
|
24
|
-
"@team-agent/cli-darwin-x64": "0.5.
|
|
25
|
-
"@team-agent/cli-linux-x64": "0.5.
|
|
23
|
+
"@team-agent/cli-darwin-arm64": "0.5.100",
|
|
24
|
+
"@team-agent/cli-darwin-x64": "0.5.100",
|
|
25
|
+
"@team-agent/cli-linux-x64": "0.5.100"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"postinstall": "node npm/bincheck.mjs",
|
package/schemas/team.schema.json
CHANGED
|
@@ -59,11 +59,11 @@
|
|
|
59
59
|
},
|
|
60
60
|
"runtime": {
|
|
61
61
|
"type": "object",
|
|
62
|
-
"required": ["backend", "
|
|
62
|
+
"required": ["backend", "session_name", "auto_launch", "require_user_approval_before_launch", "max_active_agents", "startup_order"],
|
|
63
63
|
"additionalProperties": false,
|
|
64
64
|
"properties": {
|
|
65
65
|
"backend": { "enum": ["tmux", "pty"] },
|
|
66
|
-
"display_backend": {
|
|
66
|
+
"display_backend": {},
|
|
67
67
|
"session_name": { "type": "string", "minLength": 1 },
|
|
68
68
|
"auto_launch": { "type": "boolean" },
|
|
69
69
|
"require_user_approval_before_launch": { "type": "boolean" },
|
|
@@ -17,7 +17,7 @@ team-agent --help
|
|
|
17
17
|
team-agent doctor --help
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
**Launch** from a tmux-addressable pane: `team-agent claude` or `team-agent codex`, then `team-agent quick-start .team/current`. Do not start a real team from a naked terminal.
|
|
20
|
+
**Launch** from a tmux-addressable pane: `team-agent claude` or `team-agent codex`, then `team-agent quick-start .team/current`. Do not start a real team from a naked terminal. Workers always run in independent background windows on the workspace-scoped tmux server.
|
|
21
21
|
|
|
22
22
|
**Operate**
|
|
23
23
|
|
|
@@ -157,10 +157,10 @@ Resume/repair:
|
|
|
157
157
|
team-agent restart "$WORKSPACE" --team "$TEAM" --json
|
|
158
158
|
```
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
A single-worker clean-context reset is not a resume operation. Only after the user explicitly approves discarding that worker's session, use:
|
|
161
161
|
|
|
162
162
|
```bash
|
|
163
|
-
team-agent
|
|
163
|
+
team-agent reset-agent "$AGENT_ID" --workspace "$WORKSPACE" --team "$TEAM" --discard-session --json
|
|
164
164
|
```
|
|
165
165
|
|
|
166
166
|
Validate:
|
|
@@ -43,7 +43,7 @@ team-agent codex
|
|
|
43
43
|
team-agent claude
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Pass provider flags after the provider name, for example `team-agent codex --dangerously-bypass-approvals-and-sandbox`.
|
|
46
|
+
Pass provider flags after the provider name, for example `team-agent codex --dangerously-bypass-approvals-and-sandbox`. Run `team-agent quick-start` from the leader's current tmux pane. Do not start a real team from a naked terminal that Team Agent cannot address through tmux.
|
|
47
47
|
|
|
48
48
|
**0.5.66:** leader `--dangerously-*` flags no longer inherit bypass to workers. Per-worker bypass is the role field `dangerously_skip_permissions` (see Permissions).
|
|
49
49
|
|
|
@@ -98,14 +98,7 @@ team-agent quick-start .team/current
|
|
|
98
98
|
|
|
99
99
|
YAML lists must be block style. Use `tools:\n - fs_read`; do not use `tools: [fs_read, mcp_team]`.
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
- `none` (default): headless / no GUI window manager. The team runs entirely in the per-workspace tmux server; this is what the demo above uses.
|
|
104
|
-
- `adaptive`: framework picks an available GUI layout for the local platform.
|
|
105
|
-
- `ghostty_workspace`: one Ghostty window. Workers are shown in tmux tabs/windows, up to 3 side-by-side panes per tab. Four workers become `3 + 1`; eight become `3 + 3 + 2`.
|
|
106
|
-
- `ghostty_window`: one Ghostty window per worker.
|
|
107
|
-
|
|
108
|
-
**Omitting `display_backend` defaults to `none`** (changed in 0.3.4). Set `display_backend: adaptive` (or one of the explicit ghostty variants) in `TEAM.md` only when the user wants GUI windows.
|
|
101
|
+
Workers always run headlessly in independent windows on the per-workspace tmux server. No GUI display backend is configured in `TEAM.md`.
|
|
109
102
|
|
|
110
103
|
## Private Tmux Socket
|
|
111
104
|
|
|
@@ -267,7 +260,7 @@ Observed (all exit 0):
|
|
|
267
260
|
|
|
268
261
|
```text
|
|
269
262
|
usage: team-agent restart [WORKSPACE] [--team TEAM] [--allow-fresh] [--session-converge-deadline SECONDS] [--json]
|
|
270
|
-
usage: team-agent add-agent AGENT --role-file FILE [--force] [--workspace WORKSPACE] [--team TEAM] [--
|
|
263
|
+
usage: team-agent add-agent AGENT --role-file FILE [--force] [--workspace WORKSPACE] [--team TEAM] [--json]
|
|
271
264
|
usage: team-agent shutdown [--workspace WORKSPACE] [--team TEAM] [--keep-logs] [--json]
|
|
272
265
|
```
|
|
273
266
|
|
|
@@ -112,12 +112,6 @@ For an existing worker that should restart with a blank provider context, the le
|
|
|
112
112
|
team-agent reset-agent "$AGENT_ID" --workspace "$WORKSPACE" --team "$TEAM" --discard-session --json
|
|
113
113
|
```
|
|
114
114
|
|
|
115
|
-
or the equivalent restart form:
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
team-agent restart-agent "$AGENT_ID" --workspace "$WORKSPACE" --team "$TEAM" --discard-session --json
|
|
119
|
-
```
|
|
120
|
-
|
|
121
115
|
Use this only when the user intentionally wants a clean context. For incident recovery, follow `recovery-runbook.md`, where context-preserving repair comes first.
|
|
122
116
|
|
|
123
117
|
## Framework Gaps To Track
|