@team-agent/installer 0.5.85 → 0.5.86
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/mod.rs +0 -1
- package/crates/team-agent/src/compiler/tests.rs +13 -24
- package/crates/team-agent/src/compiler.rs +1 -50
- package/crates/team-agent/src/leader/start.rs +0 -2
- package/crates/team-agent/src/lifecycle/launch/add_agent.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/add_agent_state.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/agent_state.rs +0 -6
- package/crates/team-agent/src/lifecycle/launch/identity.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/layout.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/leader_context.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/mcp_config.rs +0 -58
- package/crates/team-agent/src/lifecycle/launch/ownership.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/pi_mcp.rs +0 -3
- package/crates/team-agent/src/lifecycle/launch/quick_start.rs +14 -24
- package/crates/team-agent/src/lifecycle/launch/quick_start_transport.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/readiness.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/spawn.rs +4 -8
- package/crates/team-agent/src/lifecycle/launch/spec_state.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/state_projection.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch/worker_env.rs +0 -1
- package/crates/team-agent/src/lifecycle/launch.rs +0 -9
- package/crates/team-agent/src/lifecycle/restart/common.rs +4 -8
- package/crates/team-agent/src/lifecycle/tests/claude_compatible_config_red.rs +1 -3
- package/crates/team-agent/src/lifecycle/tests/clone_agent_preserves_source_tools.rs +42 -46
- package/crates/team-agent/src/lifecycle/tests/copilot_provider_red.rs +30 -44
- package/crates/team-agent/src/lifecycle/tests/core_034_real_red.rs +32 -77
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +2 -13
- package/crates/team-agent/src/lifecycle/tests/pi_catalog_red.rs +0 -1
- package/crates/team-agent/src/lifecycle/tests/pi_command_red.rs +0 -2
- package/crates/team-agent/src/lifecycle/tests/pi_compiler_red.rs +14 -85
- package/crates/team-agent/src/lifecycle/tests/pi_dual_entry_red.rs +1 -1
- package/crates/team-agent/src/lifecycle/tests/pi_executable_mcp_red.rs +0 -5
- package/crates/team-agent/src/lifecycle/tests/pi_session_delivery_red.rs +0 -1
- package/crates/team-agent/src/lifecycle/tests/restart_rebind_hotfix_252_red.rs +4 -4
- package/crates/team-agent/src/lifecycle/tests.rs +0 -1
- package/crates/team-agent/src/lifecycle/types.rs +0 -10
- package/crates/team-agent/src/lifecycle/worker_command_context.rs +4 -248
- package/crates/team-agent/src/model/enums.rs +0 -35
- package/crates/team-agent/src/model/mod.rs +0 -1
- package/crates/team-agent/src/model/spec.rs +23 -84
- package/crates/team-agent/src/provider/adapter.rs +48 -50
- package/crates/team-agent/src/provider/adapters/claude.rs +5 -30
- package/crates/team-agent/src/provider/adapters/codex.rs +5 -25
- package/crates/team-agent/src/provider/adapters/copilot.rs +8 -41
- package/crates/team-agent/src/provider/adapters/cursor_agent.rs +4 -8
- package/crates/team-agent/src/provider/adapters/grok.rs +5 -58
- package/crates/team-agent/src/provider/adapters/mod.rs +5 -7
- package/crates/team-agent/src/provider/adapters/pi.rs +1 -56
- package/crates/team-agent/src/provider/bypass_flags.rs +1 -2
- package/crates/team-agent/src/provider/session/capture.rs +4 -4
- package/crates/team-agent/src/provider/tests/adapter.rs +7 -24
- package/crates/team-agent/src/provider/types.rs +1 -1
- package/package.json +4 -4
- package/schemas/team.schema.json +4 -9
- package/crates/team-agent/src/lifecycle/tests/g1_silent_faces.rs +0 -784
- package/crates/team-agent/src/model/permissions.rs +0 -721
package/Cargo.lock
CHANGED
package/Cargo.toml
CHANGED
|
@@ -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","
|
|
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","display_backend":"adaptive","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() {
|
|
@@ -261,7 +261,7 @@ dangerously_skip_permissions: false
|
|
|
261
261
|
Implement bounded tasks.
|
|
262
262
|
";
|
|
263
263
|
|
|
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,"
|
|
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","display_backend":"ghostty_window","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
265
|
|
|
266
266
|
#[test]
|
|
267
267
|
fn compile_runtime_front_matter_defaults_match_python() {
|
|
@@ -302,7 +302,7 @@ dangerously_skip_permissions: false
|
|
|
302
302
|
Edit and defend the argument.
|
|
303
303
|
";
|
|
304
304
|
|
|
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,"
|
|
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","display_backend":"none","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
306
|
|
|
307
307
|
#[test]
|
|
308
308
|
fn compile_provider_models_claude_code_falls_back_to_claude_alias() {
|
|
@@ -336,7 +336,7 @@ tools:
|
|
|
336
336
|
Implement bounded tasks.
|
|
337
337
|
";
|
|
338
338
|
|
|
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,"
|
|
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","display_backend":"none","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
340
|
|
|
341
341
|
#[test]
|
|
342
342
|
fn compile_subscription_without_model_uses_builtin_provider_default() {
|
|
@@ -378,7 +378,7 @@ tools:
|
|
|
378
378
|
Bravo body.
|
|
379
379
|
";
|
|
380
380
|
|
|
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","
|
|
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","display_backend":"adaptive","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
382
|
|
|
383
383
|
#[test]
|
|
384
384
|
fn compile_two_agents_sorted_by_filename_with_routing_and_startup_order() {
|
|
@@ -633,36 +633,25 @@ fn fix_a5_session_name_override_wins() {
|
|
|
633
633
|
// ── A6 tools ──
|
|
634
634
|
|
|
635
635
|
#[test]
|
|
636
|
-
fn
|
|
637
|
-
let role = "---\nname: w\nrole: R\nprovider: codex\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - shell\n -
|
|
636
|
+
fn fix_a6_tools_are_transparent_compatibility_metadata() {
|
|
637
|
+
let role = "---\nname: w\nrole: R\nprovider: codex\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools:\n - shell\n - provider_builtin\n---\nb\n";
|
|
638
638
|
let team = build_team(TM_CODEX, &[("w.md", role)], &[]);
|
|
639
|
-
let spec = compile_team(&team).expect("
|
|
640
|
-
|
|
641
|
-
agent0(&spec).get("tools"),
|
|
642
|
-
Some(&list_str(vec!["execute_bash", "mcp_team"]))
|
|
643
|
-
);
|
|
639
|
+
let spec = compile_team(&team).expect("tools metadata must not gate compilation");
|
|
640
|
+
assert!(agent0(&spec).get("tools").is_none());
|
|
644
641
|
}
|
|
645
642
|
|
|
646
643
|
#[test]
|
|
647
|
-
fn
|
|
644
|
+
fn fix_a6_missing_tools_is_allowed() {
|
|
648
645
|
let role = "---\nname: w\nrole: R\nprovider: codex\nauth_mode: subscription\ndangerously_skip_permissions: false\n---\nb\n";
|
|
649
646
|
let team = build_team(TM_CODEX, &[("w.md", role)], &[]);
|
|
650
|
-
|
|
651
|
-
assert!(
|
|
652
|
-
err.to_string().contains("missing front matter field tools"),
|
|
653
|
-
"got: {err}"
|
|
654
|
-
);
|
|
647
|
+
compile_team(&team).expect("omitted tools metadata must compile");
|
|
655
648
|
}
|
|
656
649
|
|
|
657
650
|
#[test]
|
|
658
|
-
fn
|
|
651
|
+
fn fix_a6_tools_non_list_is_transparent() {
|
|
659
652
|
let role = "---\nname: w\nrole: R\nprovider: codex\nauth_mode: subscription\ndangerously_skip_permissions: false\ntools: justastring\n---\nb\n";
|
|
660
653
|
let team = build_team(TM_CODEX, &[("w.md", role)], &[]);
|
|
661
|
-
|
|
662
|
-
assert!(
|
|
663
|
-
err.to_string().contains("tools must be a list"),
|
|
664
|
-
"got: {err}"
|
|
665
|
-
);
|
|
654
|
+
compile_team(&team).expect("any YAML tools metadata must compile");
|
|
666
655
|
}
|
|
667
656
|
|
|
668
657
|
// ── A7 system_prompt inline ──
|
|
@@ -30,8 +30,7 @@ use std::path::Path;
|
|
|
30
30
|
use crate::communication_mode::CommunicationMode;
|
|
31
31
|
use crate::model::enums::{Provider, ProviderEffort};
|
|
32
32
|
use crate::model::yaml::Value;
|
|
33
|
-
use crate::model::{paths,
|
|
34
|
-
use crate::provider::adapters::pi::first_unsupported_pi_tool_category;
|
|
33
|
+
use crate::model::{paths, spec, yaml, ModelError};
|
|
35
34
|
use crate::provider::wire::{
|
|
36
35
|
builtin_provider_model as wire_builtin_provider_model, is_claude_family,
|
|
37
36
|
parse_canonical_provider, provider_model_keys,
|
|
@@ -233,7 +232,6 @@ pub fn compile_team(team_dir: &Path) -> Result<Value, ModelError> {
|
|
|
233
232
|
("role", Value::Str(leader_role)),
|
|
234
233
|
("provider", Value::Str(leader_provider)),
|
|
235
234
|
("model", leader_model),
|
|
236
|
-
("tools", list_str(vec!["fs_read", "fs_list", "mcp_team"])),
|
|
237
235
|
(
|
|
238
236
|
"context_policy",
|
|
239
237
|
map(vec![
|
|
@@ -526,7 +524,6 @@ fn compile_role_agent_with_mode(
|
|
|
526
524
|
role_path.display(),
|
|
527
525
|
)));
|
|
528
526
|
}
|
|
529
|
-
let tools = required_tools(&meta, role_path)?;
|
|
530
527
|
let prompt_inline = non_empty_trimmed(&body).unwrap_or_else(|| role.clone());
|
|
531
528
|
let mut agent_items = vec![
|
|
532
529
|
("id", Value::Str(id.clone())),
|
|
@@ -542,7 +539,6 @@ fn compile_role_agent_with_mode(
|
|
|
542
539
|
("file", Value::Null),
|
|
543
540
|
]),
|
|
544
541
|
),
|
|
545
|
-
("tools", list_str(tools)),
|
|
546
542
|
// 0.5.66 bypass 单源:compiler 透传角色 md 的 `dangerously_skip_permissions`
|
|
547
543
|
// (必填 bool,spec 校验保证存在)。取代旧"恒发 permission_mode: restricted"。
|
|
548
544
|
(
|
|
@@ -758,25 +754,6 @@ fn validate_pi_role_fields(meta: &Value, path: &Path, provider: &str) -> Result<
|
|
|
758
754
|
)));
|
|
759
755
|
}
|
|
760
756
|
}
|
|
761
|
-
let tools = required_tools(meta, path)?;
|
|
762
|
-
if !tools.iter().any(|tool| tool == "mcp_team") {
|
|
763
|
-
return Err(ModelError::Validation(format!(
|
|
764
|
-
"{}: Pi roles require mcp_team",
|
|
765
|
-
path.display()
|
|
766
|
-
)));
|
|
767
|
-
}
|
|
768
|
-
let expanded = permissions::expand_tool_strings(tools.iter().map(String::as_str));
|
|
769
|
-
if let Some(category) = first_unsupported_pi_tool_category(
|
|
770
|
-
expanded
|
|
771
|
-
.iter()
|
|
772
|
-
.filter(|category| permissions::is_canonical_tool(category))
|
|
773
|
-
.map(String::as_str),
|
|
774
|
-
) {
|
|
775
|
-
return Err(ModelError::Validation(format!(
|
|
776
|
-
"{}: Pi does not support Team Agent tool category {category:?}; remove it from the role's tools",
|
|
777
|
-
path.display()
|
|
778
|
-
)));
|
|
779
|
-
}
|
|
780
757
|
Ok(())
|
|
781
758
|
}
|
|
782
759
|
|
|
@@ -876,32 +853,6 @@ fn py_int_value(value: &Value) -> Option<i64> {
|
|
|
876
853
|
}
|
|
877
854
|
}
|
|
878
855
|
|
|
879
|
-
fn required_tools(meta: &Value, path: &Path) -> Result<Vec<String>, ModelError> {
|
|
880
|
-
let Some(value) = meta.get("tools") else {
|
|
881
|
-
return Err(ModelError::Validation(format!(
|
|
882
|
-
"{}: missing front matter field tools",
|
|
883
|
-
path.display()
|
|
884
|
-
)));
|
|
885
|
-
};
|
|
886
|
-
let Some(items) = value.as_list() else {
|
|
887
|
-
return Err(ModelError::Validation(format!(
|
|
888
|
-
"{}: tools must be a list",
|
|
889
|
-
path.display()
|
|
890
|
-
)));
|
|
891
|
-
};
|
|
892
|
-
Ok(items
|
|
893
|
-
.iter()
|
|
894
|
-
.filter_map(Value::as_str)
|
|
895
|
-
.map(|tool| {
|
|
896
|
-
if tool == "shell" {
|
|
897
|
-
"execute_bash".to_string()
|
|
898
|
-
} else {
|
|
899
|
-
tool.to_string()
|
|
900
|
-
}
|
|
901
|
-
})
|
|
902
|
-
.collect())
|
|
903
|
-
}
|
|
904
|
-
|
|
905
856
|
fn resolve_model(role_meta: &Value, team_meta: &Value, provider: &str) -> Value {
|
|
906
857
|
if let Some(model) = string_field(role_meta, "model") {
|
|
907
858
|
return Value::Str(model);
|
|
@@ -304,7 +304,6 @@ fn leader_start_plan_with_ambient_authority(
|
|
|
304
304
|
identity.team_id.as_str(),
|
|
305
305
|
);
|
|
306
306
|
let prompt = crate::lifecycle::worker_command_context::compile_pi_leader_system_prompt();
|
|
307
|
-
let tools = ["mcp_team", "fs_read", "fs_list", "fs_write", "execute_bash"];
|
|
308
307
|
let team_mcp_tools = [
|
|
309
308
|
"assign_task",
|
|
310
309
|
"send_message",
|
|
@@ -327,7 +326,6 @@ fn leader_start_plan_with_ambient_authority(
|
|
|
327
326
|
model: parsed.model.as_deref(),
|
|
328
327
|
effort: parsed.effort,
|
|
329
328
|
system_prompt: &prompt,
|
|
330
|
-
tool_categories: &tools,
|
|
331
329
|
team_mcp_tools: &team_mcp_tools,
|
|
332
330
|
mcp_config: &mcp_config,
|
|
333
331
|
session_scope: crate::lifecycle::launch::pi_mcp::pi_leader_session_scope(
|
|
@@ -31,7 +31,6 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
31
31
|
use crate::lifecycle::*;
|
|
32
32
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
33
33
|
use crate::model::ids::AgentId;
|
|
34
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
35
34
|
use crate::model::yaml::{self, Value};
|
|
36
35
|
use crate::state::persist::load_runtime_state;
|
|
37
36
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -28,7 +28,6 @@ use std::process::Command;
|
|
|
28
28
|
use crate::lifecycle::*;
|
|
29
29
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
30
30
|
use crate::model::ids::AgentId;
|
|
31
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
32
31
|
use crate::model::yaml::{self, Value};
|
|
33
32
|
use crate::state::persist::load_runtime_state;
|
|
34
33
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -24,7 +24,6 @@ use std::process::Command;
|
|
|
24
24
|
use crate::lifecycle::*;
|
|
25
25
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
26
26
|
use crate::model::ids::AgentId;
|
|
27
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
28
27
|
use crate::model::yaml::{self, Value};
|
|
29
28
|
use crate::state::persist::load_runtime_state;
|
|
30
29
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -106,11 +105,6 @@ pub(super) fn running_agent_state(
|
|
|
106
105
|
"mcp_config".to_string(),
|
|
107
106
|
serde_json::json!(mcp_config_path.to_string_lossy().to_string()),
|
|
108
107
|
);
|
|
109
|
-
state.insert(
|
|
110
|
-
"permissions".to_string(),
|
|
111
|
-
permissions_json(agent, id, provider)
|
|
112
|
-
.map_err(|e| LifecycleError::Compile(e.to_string()))?,
|
|
113
|
-
);
|
|
114
108
|
// 0.5.66 bypass 单源:policy 从 agent 字段派生,不再用全队 `DangerousApproval`。
|
|
115
109
|
persist_effective_approval_policy_from_yaml_agent(&mut state, agent, provider);
|
|
116
110
|
// 0.5.66 bypass 单源 §2.6:fresh spawn 记录运行面 bypass 值(供 restart drift 挡板)。
|
|
@@ -33,7 +33,6 @@ use std::process::Command;
|
|
|
33
33
|
use crate::lifecycle::*;
|
|
34
34
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
35
35
|
use crate::model::ids::AgentId;
|
|
36
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
37
36
|
use crate::model::yaml::{self, Value};
|
|
38
37
|
use crate::state::persist::load_runtime_state;
|
|
39
38
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -25,7 +25,6 @@ use std::process::Command;
|
|
|
25
25
|
use crate::lifecycle::*;
|
|
26
26
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
27
27
|
use crate::model::ids::AgentId;
|
|
28
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
29
28
|
use crate::model::yaml::{self, Value};
|
|
30
29
|
use crate::state::persist::load_runtime_state;
|
|
31
30
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -31,7 +31,6 @@ use crate::lifecycle::profile_launch::parse_provider;
|
|
|
31
31
|
use crate::lifecycle::*;
|
|
32
32
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
33
33
|
use crate::model::ids::AgentId;
|
|
34
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
35
34
|
use crate::model::yaml::{self, Value};
|
|
36
35
|
use crate::state::persist::load_runtime_state;
|
|
37
36
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
//! what: 把 argv 里的 MCP 配置参数改指到已落盘的文件
|
|
17
17
|
//! depends:
|
|
18
18
|
//! - crate::provider::McpConfig
|
|
19
|
-
//! - crate::model::permissions
|
|
20
19
|
//! - crate::event_log::EventLog
|
|
21
20
|
//! - crate::lifecycle::profile_launch
|
|
22
21
|
//! - std::fs
|
|
@@ -33,8 +32,6 @@ use std::process::Command;
|
|
|
33
32
|
|
|
34
33
|
use crate::lifecycle::*;
|
|
35
34
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
36
|
-
use crate::model::ids::AgentId;
|
|
37
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
38
35
|
use crate::model::yaml::{self, Value};
|
|
39
36
|
use crate::state::persist::load_runtime_state;
|
|
40
37
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -644,58 +641,3 @@ pub(crate) fn point_native_mcp_config_at_file(
|
|
|
644
641
|
_ => {}
|
|
645
642
|
}
|
|
646
643
|
}
|
|
647
|
-
|
|
648
|
-
/// ---
|
|
649
|
-
/// purpose: 解析该席位的权限并序列化成 JSON
|
|
650
|
-
/// returns: 含 agent_id、provider、排序后的工具串、逐工具的执行强度与是否有仅提示项
|
|
651
|
-
/// errors: 权限解析失败时返回 ModelError
|
|
652
|
-
/// ---
|
|
653
|
-
pub(super) fn permissions_json(
|
|
654
|
-
agent: &Value,
|
|
655
|
-
id: &str,
|
|
656
|
-
provider: Provider,
|
|
657
|
-
) -> Result<serde_json::Value, crate::model::ModelError> {
|
|
658
|
-
let tools = agent.get("tools").and_then(Value::as_list).map(|items| {
|
|
659
|
-
items
|
|
660
|
-
.iter()
|
|
661
|
-
.filter_map(Value::as_str)
|
|
662
|
-
.map(str::to_string)
|
|
663
|
-
.collect::<Vec<_>>()
|
|
664
|
-
});
|
|
665
|
-
let resolved = permissions::resolve_permissions(&AgentPermissionInput {
|
|
666
|
-
id: Some(AgentId::new(id)),
|
|
667
|
-
provider,
|
|
668
|
-
role: agent
|
|
669
|
-
.get("role")
|
|
670
|
-
.and_then(Value::as_str)
|
|
671
|
-
.map(str::to_string),
|
|
672
|
-
tools,
|
|
673
|
-
})?;
|
|
674
|
-
let mut out = serde_json::Map::new();
|
|
675
|
-
out.insert("agent_id".to_string(), serde_json::json!(id));
|
|
676
|
-
out.insert("provider".to_string(), serde_json::json!(provider));
|
|
677
|
-
out.insert(
|
|
678
|
-
"tools".to_string(),
|
|
679
|
-
serde_json::json!(resolved.sorted_tool_strings()),
|
|
680
|
-
);
|
|
681
|
-
out.insert(
|
|
682
|
-
"resolved_tools".to_string(),
|
|
683
|
-
serde_json::Value::Array(
|
|
684
|
-
resolved
|
|
685
|
-
.resolved_tools
|
|
686
|
-
.iter()
|
|
687
|
-
.map(|tool| {
|
|
688
|
-
serde_json::json!({
|
|
689
|
-
"tool": tool.tool,
|
|
690
|
-
"enforcement": tool.enforcement,
|
|
691
|
-
})
|
|
692
|
-
})
|
|
693
|
-
.collect(),
|
|
694
|
-
),
|
|
695
|
-
);
|
|
696
|
-
out.insert(
|
|
697
|
-
"has_prompt_only".to_string(),
|
|
698
|
-
serde_json::json!(resolved.has_prompt_only),
|
|
699
|
-
);
|
|
700
|
-
Ok(serde_json::Value::Object(out))
|
|
701
|
-
}
|
|
@@ -25,7 +25,6 @@ use std::process::Command;
|
|
|
25
25
|
use crate::lifecycle::*;
|
|
26
26
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
27
27
|
use crate::model::ids::AgentId;
|
|
28
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
29
28
|
use crate::model::yaml::{self, Value};
|
|
30
29
|
use crate::state::persist::load_runtime_state;
|
|
31
30
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -995,7 +995,6 @@ pub(crate) struct PiMaterializeRequest<'a> {
|
|
|
995
995
|
pub model: Option<&'a str>,
|
|
996
996
|
pub effort: Option<ProviderEffort>,
|
|
997
997
|
pub system_prompt: &'a str,
|
|
998
|
-
pub tool_categories: &'a [&'a str],
|
|
999
998
|
pub team_mcp_tools: &'a [&'a str],
|
|
1000
999
|
pub mcp_config: &'a McpConfig,
|
|
1001
1000
|
pub session_scope: PiSessionScope,
|
|
@@ -1093,7 +1092,6 @@ fn materialize_pi_plan_with_session(
|
|
|
1093
1092
|
model: model.as_deref(),
|
|
1094
1093
|
effort: request.effort,
|
|
1095
1094
|
system_prompt: request.system_prompt,
|
|
1096
|
-
tool_categories: request.tool_categories,
|
|
1097
1095
|
session_dir,
|
|
1098
1096
|
session: PiSessionSelector::Resume { path: &exact_path },
|
|
1099
1097
|
agent_id: request.agent_id,
|
|
@@ -1106,7 +1104,6 @@ fn materialize_pi_plan_with_session(
|
|
|
1106
1104
|
model: model.as_deref(),
|
|
1107
1105
|
effort: request.effort,
|
|
1108
1106
|
system_prompt: request.system_prompt,
|
|
1109
|
-
tool_categories: request.tool_categories,
|
|
1110
1107
|
session_dir,
|
|
1111
1108
|
session: PiSessionSelector::Fresh {
|
|
1112
1109
|
session_id: session_id.as_str(),
|
|
@@ -31,7 +31,6 @@ use std::process::Command;
|
|
|
31
31
|
use crate::lifecycle::*;
|
|
32
32
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
33
33
|
use crate::model::ids::AgentId;
|
|
34
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
35
34
|
use crate::model::yaml::{self, Value};
|
|
36
35
|
use crate::state::persist::load_runtime_state;
|
|
37
36
|
use crate::transport::{PaneField, PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -4434,7 +4433,7 @@ mod fresh_quick_start_leader_binding_tests {
|
|
|
4434
4433
|
|
|
4435
4434
|
|
|
4436
4435
|
#[test]
|
|
4437
|
-
fn
|
|
4436
|
+
fn pi_tool_category_is_transparently_accepted_by_compiler() {
|
|
4438
4437
|
let root = std::env::temp_dir().join(format!(
|
|
4439
4438
|
"ta-quick-start-pi-tools-{}-{}",
|
|
4440
4439
|
std::process::id(),
|
|
@@ -4453,29 +4452,20 @@ mod fresh_quick_start_leader_binding_tests {
|
|
|
4453
4452
|
)
|
|
4454
4453
|
.unwrap();
|
|
4455
4454
|
|
|
4456
|
-
let
|
|
4457
|
-
|
|
4458
|
-
let
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
4462
|
-
|
|
4463
|
-
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
)
|
|
4468
|
-
.expect_err("invalid Pi category must fail before quick-start persistence");
|
|
4469
|
-
let error = error.to_string();
|
|
4470
|
-
assert!(error.contains("Pi does not support Team Agent tool category \"provider_builtin\""));
|
|
4471
|
-
assert!(error.contains("remove it from the role's tools"));
|
|
4472
|
-
assert!(
|
|
4473
|
-
!crate::state::persist::runtime_state_path(&root).exists(),
|
|
4474
|
-
"quick-start validation failure must not persist runtime state"
|
|
4475
|
-
);
|
|
4455
|
+
let spec = crate::compiler::compile_team(&team)
|
|
4456
|
+
.expect("tools metadata must be transparently accepted by the compiler");
|
|
4457
|
+
let worker = spec
|
|
4458
|
+
.get("agents")
|
|
4459
|
+
.and_then(Value::as_list)
|
|
4460
|
+
.and_then(|agents| {
|
|
4461
|
+
agents.iter().find(|agent| {
|
|
4462
|
+
agent.get("id").and_then(Value::as_str) == Some("worker")
|
|
4463
|
+
})
|
|
4464
|
+
})
|
|
4465
|
+
.expect("compiled spec must retain the worker role");
|
|
4476
4466
|
assert!(
|
|
4477
|
-
|
|
4478
|
-
"
|
|
4467
|
+
worker.get("tools").is_none(),
|
|
4468
|
+
"tools metadata must not acquire runtime semantics"
|
|
4479
4469
|
);
|
|
4480
4470
|
let _ = std::fs::remove_dir_all(root);
|
|
4481
4471
|
}
|
|
@@ -28,7 +28,6 @@ use std::process::Command;
|
|
|
28
28
|
use crate::lifecycle::*;
|
|
29
29
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
30
30
|
use crate::model::ids::AgentId;
|
|
31
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
32
31
|
use crate::model::yaml::{self, Value};
|
|
33
32
|
use crate::state::persist::load_runtime_state;
|
|
34
33
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -30,7 +30,6 @@ use std::process::Command;
|
|
|
30
30
|
use crate::lifecycle::*;
|
|
31
31
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
32
32
|
use crate::model::ids::AgentId;
|
|
33
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
34
33
|
use crate::model::yaml::{self, Value};
|
|
35
34
|
use crate::state::persist::load_runtime_state;
|
|
36
35
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -32,7 +32,6 @@ use crate::lifecycle::profile_launch::parse_provider;
|
|
|
32
32
|
use crate::lifecycle::*;
|
|
33
33
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
34
34
|
use crate::model::ids::AgentId;
|
|
35
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
36
35
|
use crate::model::yaml::{self, Value};
|
|
37
36
|
use crate::state::persist::load_runtime_state;
|
|
38
37
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -123,11 +122,6 @@ pub(super) fn spawn_agents(
|
|
|
123
122
|
)?;
|
|
124
123
|
let system_prompt =
|
|
125
124
|
crate::lifecycle::worker_command_context::compile_worker_system_prompt(&command_agent)?;
|
|
126
|
-
let tools = crate::lifecycle::worker_command_context::resolved_tool_strings_for_command(
|
|
127
|
-
&command_agent,
|
|
128
|
-
provider,
|
|
129
|
-
)?;
|
|
130
|
-
let resolved_tool_refs: Vec<&str> = tools.iter().map(String::as_str).collect();
|
|
131
125
|
// 0.5.66 bypass 单源:per-agent safety 只服务 env 注入与审计,不参与 argv 决策。
|
|
132
126
|
let safety = effective_runtime_config_for_worker_spawn(agent, provider)?;
|
|
133
127
|
let mcp_team_id = runtime_team_key_for_spec(spec_path, spec, session_name);
|
|
@@ -168,7 +162,10 @@ pub(super) fn spawn_agents(
|
|
|
168
162
|
mcp_config: Some(&mcp_config),
|
|
169
163
|
system_prompt: Some(system_prompt.as_str()),
|
|
170
164
|
model: command_model,
|
|
171
|
-
|
|
165
|
+
dangerously_skip_permissions: matches!(
|
|
166
|
+
agent.get("dangerously_skip_permissions"),
|
|
167
|
+
Some(Value::Bool(true))
|
|
168
|
+
),
|
|
172
169
|
profile_launch: Some(&profile_launch),
|
|
173
170
|
// Layer 1 self-healing (architect probe 2026-06-22): expose
|
|
174
171
|
// agent_id as a display-name hint so Claude / Copilot
|
|
@@ -186,7 +183,6 @@ pub(super) fn spawn_agents(
|
|
|
186
183
|
model: command_model,
|
|
187
184
|
effort: agent_effort,
|
|
188
185
|
system_prompt: &system_prompt,
|
|
189
|
-
tool_categories: &resolved_tool_refs,
|
|
190
186
|
team_mcp_tools: &["send_message", "report_result"],
|
|
191
187
|
mcp_config: &mcp_config,
|
|
192
188
|
session_scope: crate::lifecycle::launch::pi_mcp::PiSessionScope::Isolated,
|
|
@@ -62,7 +62,6 @@ use std::process::Command;
|
|
|
62
62
|
use crate::lifecycle::*;
|
|
63
63
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
64
64
|
use crate::model::ids::AgentId;
|
|
65
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
66
65
|
use crate::model::yaml::{self, Value};
|
|
67
66
|
use crate::state::persist::load_runtime_state;
|
|
68
67
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -37,7 +37,6 @@ use crate::lifecycle::profile_launch::parse_provider;
|
|
|
37
37
|
use crate::lifecycle::*;
|
|
38
38
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
39
39
|
use crate::model::ids::AgentId;
|
|
40
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
41
40
|
use crate::model::yaml::{self, Value};
|
|
42
41
|
use crate::state::persist::load_runtime_state;
|
|
43
42
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|
|
@@ -30,7 +30,6 @@ use std::process::Command;
|
|
|
30
30
|
use crate::lifecycle::*;
|
|
31
31
|
use crate::model::enums::{AuthMode, DisplayBackend, PaneLiveness, Provider, ProviderEffort};
|
|
32
32
|
use crate::model::ids::AgentId;
|
|
33
|
-
use crate::model::permissions::{self, AgentPermissionInput};
|
|
34
33
|
use crate::model::yaml::{self, Value};
|
|
35
34
|
use crate::state::persist::load_runtime_state;
|
|
36
35
|
use crate::transport::{PaneId, SessionName, Target, Transport, WindowName};
|