@team-agent/installer 0.5.98 → 0.5.99
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 +0 -7
- package/crates/team-agent/src/cli/diagnose.rs +0 -16
- package/crates/team-agent/src/cli/emit.rs +15 -20
- package/crates/team-agent/src/cli/mod.rs +130 -31
- package/crates/team-agent/src/cli/spec.rs +7 -7
- package/crates/team-agent/src/cli/tests/main_preserved.rs +0 -1
- package/crates/team-agent/src/cli/tests/missing_subcommands.rs +0 -1
- 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/types.rs +0 -6
- package/crates/team-agent/src/compiler/tests.rs +5 -8
- package/crates/team-agent/src/compiler.rs +6 -14
- 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 +0 -9
- 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 +7 -7
- package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/startup_latency_contract.rs +3 -4
- 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/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 +6 -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/team-agent-operator.md +3 -10
- 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
|
@@ -295,7 +295,6 @@ pub struct QuickStartArgs {
|
|
|
295
295
|
pub name: Option<String>,
|
|
296
296
|
pub team_id: Option<String>,
|
|
297
297
|
pub yes: bool,
|
|
298
|
-
pub no_display: bool,
|
|
299
298
|
pub json: bool,
|
|
300
299
|
/// Include internal receiver/topology diagnostics in the response.
|
|
301
300
|
pub detail: bool,
|
|
@@ -489,7 +488,6 @@ pub struct StartAgentArgs {
|
|
|
489
488
|
pub team: Option<String>,
|
|
490
489
|
pub force: bool,
|
|
491
490
|
pub allow_fresh: bool,
|
|
492
|
-
pub no_display: bool,
|
|
493
491
|
pub json: bool,
|
|
494
492
|
}
|
|
495
493
|
|
|
@@ -509,7 +507,6 @@ pub struct ResetAgentArgs {
|
|
|
509
507
|
pub workspace: PathBuf,
|
|
510
508
|
pub team: Option<String>,
|
|
511
509
|
pub discard_session: bool,
|
|
512
|
-
pub no_display: bool,
|
|
513
510
|
pub json: bool,
|
|
514
511
|
}
|
|
515
512
|
|
|
@@ -521,7 +518,6 @@ pub struct AddAgentArgs {
|
|
|
521
518
|
pub team: Option<String>,
|
|
522
519
|
pub role_file: String,
|
|
523
520
|
pub force: bool,
|
|
524
|
-
pub no_display: bool,
|
|
525
521
|
pub json: bool,
|
|
526
522
|
}
|
|
527
523
|
|
|
@@ -533,7 +529,6 @@ pub struct ForkAgentArgs {
|
|
|
533
529
|
pub team: Option<String>,
|
|
534
530
|
pub as_agent: String,
|
|
535
531
|
pub label: Option<String>,
|
|
536
|
-
pub no_display: bool,
|
|
537
532
|
pub json: bool,
|
|
538
533
|
}
|
|
539
534
|
|
|
@@ -544,7 +539,6 @@ pub struct CloneAgentArgs {
|
|
|
544
539
|
pub team: Option<String>,
|
|
545
540
|
pub as_agent: String,
|
|
546
541
|
pub label: Option<String>,
|
|
547
|
-
pub no_display: bool,
|
|
548
542
|
pub json: bool,
|
|
549
543
|
}
|
|
550
544
|
|
|
@@ -190,7 +190,7 @@ fn front_matter_non_object_errors() {
|
|
|
190
190
|
// separators=(",",":"))` with the workspace path templated to __WS__.
|
|
191
191
|
// (team-agent-public v0.2.11, /tmp/probe_compiler.py.)
|
|
192
192
|
|
|
193
|
-
const BASE_NOPROFILE_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":"gpt-5.5","context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks and report result_envelope_v1.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","
|
|
193
|
+
const BASE_NOPROFILE_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":"gpt-5.5","context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks and report result_envelope_v1.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
|
|
194
194
|
|
|
195
195
|
#[test]
|
|
196
196
|
fn compile_base_noprofile_matches_python_dict_order_and_values() {
|
|
@@ -237,7 +237,6 @@ default_model: gpt-5.4
|
|
|
237
237
|
default_auth_mode: subscription
|
|
238
238
|
dangerous_auto_approve: true
|
|
239
239
|
fast: true
|
|
240
|
-
display_backend: ghostty_window
|
|
241
240
|
tick_interval_sec: 1
|
|
242
241
|
push_min_interval_sec: 3
|
|
243
242
|
stuck_timeout_sec: 5
|
|
@@ -261,7 +260,7 @@ dangerously_skip_permissions: false
|
|
|
261
260
|
Implement bounded tasks.
|
|
262
261
|
";
|
|
263
262
|
|
|
264
|
-
const RUNTIME_DEFAULTS_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.4","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","
|
|
263
|
+
const RUNTIME_DEFAULTS_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.4","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":true,"tick_interval_sec":1,"push_min_interval_sec":3,"stuck_timeout_sec":5},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
|
|
265
264
|
|
|
266
265
|
#[test]
|
|
267
266
|
fn compile_runtime_front_matter_defaults_match_python() {
|
|
@@ -283,7 +282,6 @@ objective: Compile thin role docs.
|
|
|
283
282
|
provider_models:
|
|
284
283
|
claude: claude-sonnet-4-6
|
|
285
284
|
default_auth_mode: subscription
|
|
286
|
-
display_backend: none
|
|
287
285
|
---
|
|
288
286
|
|
|
289
287
|
Team config.
|
|
@@ -302,7 +300,7 @@ dangerously_skip_permissions: false
|
|
|
302
300
|
Edit and defend the argument.
|
|
303
301
|
";
|
|
304
302
|
|
|
305
|
-
const ALIAS_JSON: &str = r#"{"version":1,"team":{"name":"debate-team","mode":"supervisor_worker","objective":"Compile thin role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"editor","role":"Editor and Defender","provider":"claude_code","model":"claude-sonnet-4-6","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Edit and defend the argument.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["editor","Editor and Defender"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"editor","rules":[{"id":"route-editor","match":{"assignee":["editor"]},"assign_to":"editor","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","
|
|
303
|
+
const ALIAS_JSON: &str = r#"{"version":1,"team":{"name":"debate-team","mode":"supervisor_worker","objective":"Compile thin role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"editor","role":"Editor and Defender","provider":"claude_code","model":"claude-sonnet-4-6","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Edit and defend the argument.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["editor","Editor and Defender"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"editor","rules":[{"id":"route-editor","match":{"assignee":["editor"]},"assign_to":"editor","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-debate-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["editor"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"editor","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
|
|
306
304
|
|
|
307
305
|
#[test]
|
|
308
306
|
fn compile_provider_models_claude_code_falls_back_to_claude_alias() {
|
|
@@ -316,7 +314,6 @@ const BUILTIN_TEAM: &str = "\
|
|
|
316
314
|
---
|
|
317
315
|
name: default-model-team
|
|
318
316
|
objective: Compile role docs without model fields.
|
|
319
|
-
display_backend: none
|
|
320
317
|
---
|
|
321
318
|
|
|
322
319
|
Team config.
|
|
@@ -336,7 +333,7 @@ tools:
|
|
|
336
333
|
Implement bounded tasks.
|
|
337
334
|
";
|
|
338
335
|
|
|
339
|
-
const BUILTIN_JSON: &str = r#"{"version":1,"team":{"name":"default-model-team","mode":"supervisor_worker","objective":"Compile role docs without model fields.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","
|
|
336
|
+
const BUILTIN_JSON: &str = r#"{"version":1,"team":{"name":"default-model-team","mode":"supervisor_worker","objective":"Compile role docs without model fields.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":null,"context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"implementer","role":"Implementation Engineer","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Implement bounded tasks.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["implementer","Implementation Engineer"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"implementer","rules":[{"id":"route-implementer","match":{"assignee":["implementer"]},"assign_to":"implementer","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-default-model-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":1,"startup_order":["implementer"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"implementer","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
|
|
340
337
|
|
|
341
338
|
#[test]
|
|
342
339
|
fn compile_subscription_without_model_uses_builtin_provider_default() {
|
|
@@ -378,7 +375,7 @@ tools:
|
|
|
378
375
|
Bravo body.
|
|
379
376
|
";
|
|
380
377
|
|
|
381
|
-
const TWO_AGENTS_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":"gpt-5.5","context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"alpha","role":"Alpha Worker","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Alpha body.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["alpha","Alpha Worker"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}},{"id":"bravo","role":"Bravo Worker","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Bravo body.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["bravo","Bravo Worker"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"alpha","rules":[{"id":"route-alpha","match":{"assignee":["alpha"]},"assign_to":"alpha","priority":10},{"id":"route-bravo","match":{"assignee":["bravo"]},"assign_to":"bravo","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","
|
|
378
|
+
const TWO_AGENTS_JSON: &str = r#"{"version":1,"team":{"name":"doc-team","mode":"supervisor_worker","objective":"Compile role docs.","workspace":"__WS__"},"leader":{"id":"leader","role":"leader","provider":"codex","model":"gpt-5.5","context_policy":{"keep_user_thread":true,"receive_worker_outputs":"business_messages_and_short_summaries","max_worker_result_tokens":2000}},"agents":[{"id":"alpha","role":"Alpha Worker","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Alpha body.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["alpha","Alpha Worker"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}},{"id":"bravo","role":"Bravo Worker","provider":"codex","model":"gpt-5.5","auth_mode":"subscription","working_directory":"__WS__","system_prompt":{"inline":"Bravo body.","file":null},"dangerously_skip_permissions":false,"communication_mode":"leader_centric","preferred_for":["bravo","Bravo Worker"],"avoid_for":[],"output_contract":{"format":"result_envelope_v1","required_fields":["task_id","status","summary","artifacts"]}}],"routing":{"default_assignee":"alpha","rules":[{"id":"route-alpha","match":{"assignee":["alpha"]},"assign_to":"alpha","priority":10},{"id":"route-bravo","match":{"assignee":["bravo"]},"assign_to":"bravo","priority":10}]},"communication":{"protocol":"mcp_inbox","topology":"leader_centered","worker_to_worker":true,"ack_timeout_sec":60,"result_format":"result_envelope_v1","message_store":{"sqlite":".team/runtime/team.db","mirror_files":".team/messages"}},"runtime":{"backend":"tmux","session_name":"team-doc-team","auto_launch":true,"require_user_approval_before_launch":true,"max_active_agents":2,"startup_order":["alpha","bravo"],"fast":false,"tick_interval_sec":2,"push_min_interval_sec":60,"stuck_timeout_sec":300},"context":{"state_file":"team_state.md","artifact_dir":".team/artifacts","log_dir":".team/logs","summarization":{"worker_full_logs":"retain_outside_leader_context","state_update":"after_each_result"}},"tasks":[{"id":"task_initial","title":"Initial document-driven team task","type":"implementation","assignee":"alpha","deps":[],"acceptance":["Worker reports valid result_envelope_v1"],"status":"pending","requires_tools":["mcp_team"],"files":[],"risk":"low"}]}"#;
|
|
382
379
|
|
|
383
380
|
#[test]
|
|
384
381
|
fn compile_two_agents_sorted_by_filename_with_routing_and_startup_order() {
|
|
@@ -203,7 +203,7 @@ pub fn compile_team(team_dir: &Path) -> Result<Value, ModelError> {
|
|
|
203
203
|
let value = raw.trim();
|
|
204
204
|
let parsed = ProviderEffort::parse(value).ok_or_else(|| {
|
|
205
205
|
ModelError::Validation(format!(
|
|
206
|
-
"{}: unknown provider_effort '{value}' (allowed: low|medium|high|xhigh|max)",
|
|
206
|
+
"{}: unknown provider_effort '{value}' (allowed: low|medium|high|xhigh|max|ultra)",
|
|
207
207
|
team_md.display()
|
|
208
208
|
))
|
|
209
209
|
})?;
|
|
@@ -280,13 +280,6 @@ pub fn compile_team(team_dir: &Path) -> Result<Value, ModelError> {
|
|
|
280
280
|
"runtime",
|
|
281
281
|
map(vec![
|
|
282
282
|
("backend", Value::Str("tmux".to_string())),
|
|
283
|
-
(
|
|
284
|
-
"display_backend",
|
|
285
|
-
Value::Str(
|
|
286
|
-
string_field(&team_meta, "display_backend")
|
|
287
|
-
.unwrap_or_else(|| "adaptive".to_string()),
|
|
288
|
-
),
|
|
289
|
-
),
|
|
290
283
|
(
|
|
291
284
|
"session_name",
|
|
292
285
|
Value::Str(session_name(&team_meta, &team_name)),
|
|
@@ -565,16 +558,15 @@ fn compile_role_agent_with_mode(
|
|
|
565
558
|
if let Some(profile) = string_field(&meta, "profile") {
|
|
566
559
|
agent_items.push(("profile", Value::Str(profile)));
|
|
567
560
|
}
|
|
568
|
-
// 0.4.x provider effort MVP step 3: resolve effort with role > team > none
|
|
569
|
-
//
|
|
570
|
-
//
|
|
571
|
-
// unsupported combinations fail at compile, not at runtime).
|
|
561
|
+
// 0.4.x provider effort MVP step 3: resolve effort with role > team > none
|
|
562
|
+
// (Pi uses only explicit role effort). Validate syntax and provider support
|
|
563
|
+
// here so unsupported combinations fail at compile, not at runtime.
|
|
572
564
|
let role_effort = match string_field(&meta, "effort") {
|
|
573
565
|
Some(raw) if !raw.trim().is_empty() => {
|
|
574
566
|
let value = raw.trim();
|
|
575
567
|
let parsed = ProviderEffort::parse(value).ok_or_else(|| {
|
|
576
568
|
ModelError::Validation(format!(
|
|
577
|
-
"{}: unknown effort '{value}' (allowed: low|medium|high|xhigh|max)",
|
|
569
|
+
"{}: unknown effort '{value}' (allowed: low|medium|high|xhigh|max|ultra)",
|
|
578
570
|
role_path.display()
|
|
579
571
|
))
|
|
580
572
|
})?;
|
|
@@ -592,7 +584,7 @@ fn compile_role_agent_with_mode(
|
|
|
592
584
|
role_effort.or(team_effort)
|
|
593
585
|
};
|
|
594
586
|
if let Some(effort) = resolved_effort {
|
|
595
|
-
//
|
|
587
|
+
// Apply the shared provider admission policy at compile time.
|
|
596
588
|
let provider_str = agent_items
|
|
597
589
|
.iter()
|
|
598
590
|
.find(|(k, _)| *k == "provider")
|
|
@@ -29,7 +29,7 @@ use std::process::Command;
|
|
|
29
29
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
30
30
|
|
|
31
31
|
use crate::lifecycle::*;
|
|
32
|
-
use crate::model::enums::{AuthMode,
|
|
32
|
+
use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
|
|
33
33
|
use crate::model::ids::AgentId;
|
|
34
34
|
use crate::model::yaml::{self, Value};
|
|
35
35
|
use crate::state::persist::load_runtime_state;
|
|
@@ -26,7 +26,7 @@ use std::path::{Path, PathBuf};
|
|
|
26
26
|
use std::process::Command;
|
|
27
27
|
|
|
28
28
|
use crate::lifecycle::*;
|
|
29
|
-
use crate::model::enums::{AuthMode,
|
|
29
|
+
use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
|
|
30
30
|
use crate::model::ids::AgentId;
|
|
31
31
|
use crate::model::yaml::{self, Value};
|
|
32
32
|
use crate::state::persist::load_runtime_state;
|
|
@@ -22,11 +22,11 @@ use std::path::{Path, PathBuf};
|
|
|
22
22
|
use std::process::Command;
|
|
23
23
|
|
|
24
24
|
use crate::lifecycle::*;
|
|
25
|
-
use crate::model::enums::{AuthMode,
|
|
25
|
+
use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
|
|
26
26
|
use crate::model::ids::AgentId;
|
|
27
27
|
use crate::model::yaml::{self, Value};
|
|
28
28
|
use crate::state::persist::load_runtime_state;
|
|
29
|
-
use crate::transport::{PaneId, SessionName, Target, Transport
|
|
29
|
+
use crate::transport::{PaneId, SessionName, Target, Transport};
|
|
30
30
|
|
|
31
31
|
use crate::lifecycle::lock::{acquire_agent_lifecycle_lock, LifecycleLockRequest};
|
|
32
32
|
|
|
@@ -64,10 +64,9 @@ pub(super) fn running_agent_state(
|
|
|
64
64
|
.get("profile")
|
|
65
65
|
.map(yaml_value_to_json)
|
|
66
66
|
.unwrap_or(serde_json::Value::Null);
|
|
67
|
-
let window =
|
|
68
|
-
.
|
|
69
|
-
.
|
|
70
|
-
.or_else(|| agent.get("window").and_then(Value::as_str))
|
|
67
|
+
let window = agent
|
|
68
|
+
.get("window")
|
|
69
|
+
.and_then(Value::as_str)
|
|
71
70
|
.unwrap_or(id);
|
|
72
71
|
let mcp_config = crate::provider::get_adapter(provider)
|
|
73
72
|
.mcp_config(auth_mode)
|
|
@@ -129,25 +128,6 @@ pub(super) fn running_agent_state(
|
|
|
129
128
|
);
|
|
130
129
|
if let Some(started_agent) = started_agent {
|
|
131
130
|
persist_started_agent_plan_state(&mut state, started_agent);
|
|
132
|
-
if let Some(layout_window) = started_agent.layout_window.as_ref() {
|
|
133
|
-
state.insert(
|
|
134
|
-
"layout_window".to_string(),
|
|
135
|
-
serde_json::json!(layout_window.as_str()),
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
if let Some(layout_index) = started_agent.layout_index {
|
|
139
|
-
state.insert("layout_index".to_string(), serde_json::json!(layout_index));
|
|
140
|
-
}
|
|
141
|
-
if let Some(pane_index) = started_agent.pane_index {
|
|
142
|
-
state.insert("pane_index".to_string(), serde_json::json!(pane_index));
|
|
143
|
-
}
|
|
144
|
-
if !matches!(started_agent.display, WorkerDisplay::Blocked { .. }) {
|
|
145
|
-
state.insert(
|
|
146
|
-
"display".to_string(),
|
|
147
|
-
serde_json::to_value(&started_agent.display)
|
|
148
|
-
.map_err(|e| LifecycleError::StatePersist(e.to_string()))?,
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
131
|
}
|
|
152
132
|
state.insert(
|
|
153
133
|
"spawn_cwd".to_string(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//! ---
|
|
2
|
-
//! purpose: team 与席位的身份取值,团队键、
|
|
2
|
+
//! purpose: team 与席位的身份取值,团队键、auth_mode、effort 与 quick-start 层级判定
|
|
3
3
|
//! contract:
|
|
4
4
|
//! provides:
|
|
5
5
|
//! - name: spec_team_id
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
//! - crate::state::projection
|
|
19
19
|
//! - crate::state::persist
|
|
20
20
|
//! - crate::state::repository
|
|
21
|
-
//! - crate::lifecycle::display
|
|
22
21
|
//! - crate::provider::wire
|
|
23
22
|
//! boundary:
|
|
24
23
|
//! - 只做身份判定与取值,不 spawn、不开显示
|
|
@@ -31,7 +30,7 @@ use std::path::{Path, PathBuf};
|
|
|
31
30
|
use std::process::Command;
|
|
32
31
|
|
|
33
32
|
use crate::lifecycle::*;
|
|
34
|
-
use crate::model::enums::{AuthMode,
|
|
33
|
+
use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
|
|
35
34
|
use crate::model::ids::AgentId;
|
|
36
35
|
use crate::model::yaml::{self, Value};
|
|
37
36
|
use crate::state::persist::load_runtime_state;
|
|
@@ -99,21 +98,6 @@ pub(super) fn transport_has_session(transport: &dyn Transport, session_name: &Se
|
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
/// ---
|
|
103
|
-
/// purpose: 取 spec 请求的显示后端并交给 display 解析
|
|
104
|
-
/// returns: 解析后的后端,spec 未写或写了未知值时为默认 adaptive
|
|
105
|
-
/// ---
|
|
106
|
-
pub(super) fn spec_display_backend(spec: &Value) -> DisplayBackend {
|
|
107
|
-
let requested = spec
|
|
108
|
-
.get("runtime")
|
|
109
|
-
.and_then(|runtime| runtime.get("display_backend"))
|
|
110
|
-
.and_then(Value::as_str)
|
|
111
|
-
.and_then(|backend| {
|
|
112
|
-
serde_json::from_value::<DisplayBackend>(serde_json::json!(backend)).ok()
|
|
113
|
-
});
|
|
114
|
-
crate::lifecycle::display::resolve_display_backend(requested, None).backend
|
|
115
|
-
}
|
|
116
|
-
|
|
117
101
|
use crate::provider::wire::parse_provider;
|
|
118
102
|
|
|
119
103
|
/// ---
|
|
@@ -23,7 +23,7 @@ use std::path::{Path, PathBuf};
|
|
|
23
23
|
use std::process::Command;
|
|
24
24
|
|
|
25
25
|
use crate::lifecycle::*;
|
|
26
|
-
use crate::model::enums::{AuthMode,
|
|
26
|
+
use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
|
|
27
27
|
use crate::model::ids::AgentId;
|
|
28
28
|
use crate::model::yaml::{self, Value};
|
|
29
29
|
use crate::state::persist::load_runtime_state;
|
|
@@ -72,31 +72,10 @@ pub(crate) fn adaptive_layout_plan(
|
|
|
72
72
|
|
|
73
73
|
pub(crate) const ADAPTIVE_LAYOUT_MAX_PER_WINDOW: usize = 3;
|
|
74
74
|
|
|
75
|
-
///
|
|
76
|
-
///
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
pub(crate) fn state_uses_adaptive_layout(state: &serde_json::Value) -> bool {
|
|
80
|
-
state
|
|
81
|
-
.get("display_backend")
|
|
82
|
-
.and_then(serde_json::Value::as_str)
|
|
83
|
-
.is_some_and(|backend| backend == "adaptive")
|
|
84
|
-
|| state
|
|
85
|
-
.get("runtime")
|
|
86
|
-
.and_then(|runtime| runtime.get("display_backend"))
|
|
87
|
-
.and_then(serde_json::Value::as_str)
|
|
88
|
-
.is_some_and(|backend| backend == "adaptive")
|
|
89
|
-
|| state
|
|
90
|
-
.get("agents")
|
|
91
|
-
.and_then(serde_json::Value::as_object)
|
|
92
|
-
.is_some_and(|agents| {
|
|
93
|
-
agents.values().any(|agent| {
|
|
94
|
-
agent
|
|
95
|
-
.get("layout_window")
|
|
96
|
-
.and_then(serde_json::Value::as_str)
|
|
97
|
-
.is_some_and(|window| !window.is_empty())
|
|
98
|
-
})
|
|
99
|
-
})
|
|
75
|
+
/// Adaptive display layout was removed; existing state is always resumed in
|
|
76
|
+
/// the per-agent window topology.
|
|
77
|
+
pub(crate) fn state_uses_adaptive_layout(_state: &serde_json::Value) -> bool {
|
|
78
|
+
false
|
|
100
79
|
}
|
|
101
80
|
|
|
102
81
|
/// ---
|
|
@@ -204,9 +183,8 @@ pub(crate) fn adaptive_placement_for_agent(
|
|
|
204
183
|
});
|
|
205
184
|
}
|
|
206
185
|
}
|
|
207
|
-
//
|
|
208
|
-
//
|
|
209
|
-
// display_backend=adaptive), DO NOT synthesise a fresh `team-w<N>`
|
|
186
|
+
// When the live session has no real layout window, do not synthesise
|
|
187
|
+
// a fresh `team-w<N>`
|
|
210
188
|
// window — that would force the new agent into an adaptive-layout pane
|
|
211
189
|
// shape the rest of the session does not actually use. Return None so
|
|
212
190
|
// the caller (`start_agent_at_paths` → `spawn_agent_window`) falls back
|
|
@@ -29,7 +29,7 @@ use std::process::Command;
|
|
|
29
29
|
|
|
30
30
|
use crate::lifecycle::profile_launch::parse_provider;
|
|
31
31
|
use crate::lifecycle::*;
|
|
32
|
-
use crate::model::enums::{AuthMode,
|
|
32
|
+
use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
|
|
33
33
|
use crate::model::ids::AgentId;
|
|
34
34
|
use crate::model::yaml::{self, Value};
|
|
35
35
|
use crate::state::persist::load_runtime_state;
|
|
@@ -31,7 +31,7 @@ use std::path::{Path, PathBuf};
|
|
|
31
31
|
use std::process::Command;
|
|
32
32
|
|
|
33
33
|
use crate::lifecycle::*;
|
|
34
|
-
use crate::model::enums::{AuthMode,
|
|
34
|
+
use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
|
|
35
35
|
use crate::model::yaml::{self, Value};
|
|
36
36
|
use crate::state::persist::load_runtime_state;
|
|
37
37
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -23,7 +23,7 @@ use std::path::{Path, PathBuf};
|
|
|
23
23
|
use std::process::Command;
|
|
24
24
|
|
|
25
25
|
use crate::lifecycle::*;
|
|
26
|
-
use crate::model::enums::{AuthMode,
|
|
26
|
+
use crate::model::enums::{AuthMode, PaneLiveness, Provider, ProviderEffort};
|
|
27
27
|
use crate::model::ids::AgentId;
|
|
28
28
|
use crate::model::yaml::{self, Value};
|
|
29
29
|
use crate::state::persist::load_runtime_state;
|
|
@@ -26,7 +26,7 @@ use std::time::{Duration, Instant};
|
|
|
26
26
|
|
|
27
27
|
use sha2::{Digest, Sha256};
|
|
28
28
|
|
|
29
|
-
use crate::model::enums::ProviderEffort;
|
|
29
|
+
use crate::model::enums::{Provider, ProviderEffort};
|
|
30
30
|
use crate::provider::adapters::pi::{build_pi_command_argv, PiCommandRequest, PiSessionSelector};
|
|
31
31
|
use crate::provider::{CommandPlan, McpConfig, ProviderError, SessionId};
|
|
32
32
|
|
|
@@ -559,12 +559,12 @@ pub(crate) fn parse_pi_leader_args(args: &[String]) -> Result<PiLeaderArgs, Prov
|
|
|
559
559
|
match flag {
|
|
560
560
|
"--model" if model.is_none() => model = Some(value.clone()),
|
|
561
561
|
"--thinking" if effort.is_none() => {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
)
|
|
567
|
-
|
|
562
|
+
let parsed = ProviderEffort::parse(value).ok_or_else(|| {
|
|
563
|
+
ProviderError::Command(format!("unknown Pi thinking effort {value:?}"))
|
|
564
|
+
})?;
|
|
565
|
+
effort = parsed
|
|
566
|
+
.resolve_for_provider(Provider::Pi)
|
|
567
|
+
.map_err(|reason| ProviderError::Command(reason.to_string()))?;
|
|
568
568
|
}
|
|
569
569
|
_ => {
|
|
570
570
|
return Err(ProviderError::Command(format!(
|