@team-agent/installer 0.2.11 → 0.3.1
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 +744 -0
- package/Cargo.toml +34 -0
- package/crates/team-agent/Cargo.toml +33 -0
- package/crates/team-agent/src/cli/adapters.rs +1343 -0
- package/crates/team-agent/src/cli/diagnose.rs +554 -0
- package/crates/team-agent/src/cli/emit.rs +1204 -0
- package/crates/team-agent/src/cli/helpers.rs +88 -0
- package/crates/team-agent/src/cli/leader.rs +216 -0
- package/crates/team-agent/src/cli/mod.rs +1207 -0
- package/crates/team-agent/src/cli/profile.rs +306 -0
- package/crates/team-agent/src/cli/send.rs +215 -0
- package/crates/team-agent/src/cli/status.rs +179 -0
- package/crates/team-agent/src/cli/status_port.rs +502 -0
- package/crates/team-agent/src/cli/tests/base.rs +616 -0
- package/crates/team-agent/src/cli/tests/compile.rs +96 -0
- package/crates/team-agent/src/cli/tests/divergence.rs +509 -0
- package/crates/team-agent/src/cli/tests/lane_c.rs +333 -0
- package/crates/team-agent/src/cli/tests/leader_watch.rs +395 -0
- package/crates/team-agent/src/cli/tests/main_preserved.rs +675 -0
- package/crates/team-agent/src/cli/tests/missing_subcommands.rs +390 -0
- package/crates/team-agent/src/cli/tests/mod.rs +97 -0
- package/crates/team-agent/src/cli/tests/peer_allow.rs +137 -0
- package/crates/team-agent/src/cli/tests/repair_state_byte_lock.rs +302 -0
- package/crates/team-agent/src/cli/tests/run_delegation.rs +305 -0
- package/crates/team-agent/src/cli/tests/status_send.rs +385 -0
- package/crates/team-agent/src/cli/tests/verb_profile.rs +182 -0
- package/crates/team-agent/src/cli/tests/verb_settle.rs +236 -0
- package/crates/team-agent/src/cli/tests/verb_validate.rs +184 -0
- package/crates/team-agent/src/cli/types.rs +605 -0
- package/crates/team-agent/src/compiler/tests.rs +701 -0
- package/crates/team-agent/src/compiler.rs +489 -0
- package/crates/team-agent/src/coordinator/backoff.rs +153 -0
- package/crates/team-agent/src/coordinator/health.rs +557 -0
- package/crates/team-agent/src/coordinator/mod.rs +80 -0
- package/crates/team-agent/src/coordinator/orphan.rs +179 -0
- package/crates/team-agent/src/coordinator/tests/abnormal.rs +255 -0
- package/crates/team-agent/src/coordinator/tests/basics.rs +262 -0
- package/crates/team-agent/src/coordinator/tests/daemon.rs +323 -0
- package/crates/team-agent/src/coordinator/tests/health_sync.rs +263 -0
- package/crates/team-agent/src/coordinator/tests/main_preserved.rs +136 -0
- package/crates/team-agent/src/coordinator/tests/mod.rs +310 -0
- package/crates/team-agent/src/coordinator/tests/spine.rs +261 -0
- package/crates/team-agent/src/coordinator/tests/takeover.rs +227 -0
- package/crates/team-agent/src/coordinator/tests/tick_core.rs +256 -0
- package/crates/team-agent/src/coordinator/tests/watch.rs +167 -0
- package/crates/team-agent/src/coordinator/tick.rs +2032 -0
- package/crates/team-agent/src/coordinator/types.rs +584 -0
- package/crates/team-agent/src/db/migration.rs +716 -0
- package/crates/team-agent/src/db/mod.rs +23 -0
- package/crates/team-agent/src/db/schema.rs +378 -0
- package/crates/team-agent/src/event_log.rs +375 -0
- package/crates/team-agent/src/fake_worker.rs +253 -0
- package/crates/team-agent/src/leader/helpers.rs +190 -0
- package/crates/team-agent/src/leader/inject.rs +33 -0
- package/crates/team-agent/src/leader/lease.rs +1084 -0
- package/crates/team-agent/src/leader/mod.rs +99 -0
- package/crates/team-agent/src/leader/owner_bind.rs +292 -0
- package/crates/team-agent/src/leader/rediscover/tests.rs +526 -0
- package/crates/team-agent/src/leader/rediscover.rs +1101 -0
- package/crates/team-agent/src/leader/start.rs +273 -0
- package/crates/team-agent/src/leader/takeover.rs +235 -0
- package/crates/team-agent/src/leader/tests/basics.rs +183 -0
- package/crates/team-agent/src/leader/tests/byte_findings.rs +237 -0
- package/crates/team-agent/src/leader/tests/identity.rs +206 -0
- package/crates/team-agent/src/leader/tests/idle.rs +272 -0
- package/crates/team-agent/src/leader/tests/lease_api.rs +225 -0
- package/crates/team-agent/src/leader/tests/lease_claim.rs +410 -0
- package/crates/team-agent/src/leader/tests/mod.rs +125 -0
- package/crates/team-agent/src/leader/tests/rediscover.rs +351 -0
- package/crates/team-agent/src/leader/tests/wake_start_owner.rs +204 -0
- package/crates/team-agent/src/leader/types.rs +489 -0
- package/crates/team-agent/src/lib.rs +85 -0
- package/crates/team-agent/src/lifecycle/display.rs +228 -0
- package/crates/team-agent/src/lifecycle/helpers.rs +112 -0
- package/crates/team-agent/src/lifecycle/launch/plan.rs +227 -0
- package/crates/team-agent/src/lifecycle/launch.rs +2109 -0
- package/crates/team-agent/src/lifecycle/mod.rs +62 -0
- package/crates/team-agent/src/lifecycle/restart/agent.rs +533 -0
- package/crates/team-agent/src/lifecycle/restart/common.rs +517 -0
- package/crates/team-agent/src/lifecycle/restart/orchestrator.rs +41 -0
- package/crates/team-agent/src/lifecycle/restart/rebuild.rs +268 -0
- package/crates/team-agent/src/lifecycle/restart/remove.rs +780 -0
- package/crates/team-agent/src/lifecycle/restart/selection.rs +208 -0
- package/crates/team-agent/src/lifecycle/restart/team_state.rs +242 -0
- package/crates/team-agent/src/lifecycle/restart.rs +76 -0
- package/crates/team-agent/src/lifecycle/tests/agent_ops.rs +455 -0
- package/crates/team-agent/src/lifecycle/tests/core.rs +989 -0
- package/crates/team-agent/src/lifecycle/tests/lane_ops.rs +583 -0
- package/crates/team-agent/src/lifecycle/tests/launch_spawn.rs +985 -0
- package/crates/team-agent/src/lifecycle/tests/main_preserved.rs +265 -0
- package/crates/team-agent/src/lifecycle/tests.rs +27 -0
- package/crates/team-agent/src/lifecycle/types.rs +710 -0
- package/crates/team-agent/src/main.rs +41 -0
- package/crates/team-agent/src/mcp_server/helpers.rs +228 -0
- package/crates/team-agent/src/mcp_server/mod.rs +183 -0
- package/crates/team-agent/src/mcp_server/normalize.rs +312 -0
- package/crates/team-agent/src/mcp_server/tests/golden.rs +283 -0
- package/crates/team-agent/src/mcp_server/tests/normalize.rs +244 -0
- package/crates/team-agent/src/mcp_server/tests/scoped.rs +189 -0
- package/crates/team-agent/src/mcp_server/tests/send.rs +222 -0
- package/crates/team-agent/src/mcp_server/tests/tools.rs +158 -0
- package/crates/team-agent/src/mcp_server/tests/wire.rs +187 -0
- package/crates/team-agent/src/mcp_server/tests.rs +38 -0
- package/crates/team-agent/src/mcp_server/tools.rs +603 -0
- package/crates/team-agent/src/mcp_server/types.rs +421 -0
- package/crates/team-agent/src/mcp_server/wire.rs +468 -0
- package/crates/team-agent/src/message_store.rs +767 -0
- package/crates/team-agent/src/messaging/activity.rs +433 -0
- package/crates/team-agent/src/messaging/delivery.rs +743 -0
- package/crates/team-agent/src/messaging/helpers.rs +209 -0
- package/crates/team-agent/src/messaging/leader_receiver.rs +329 -0
- package/crates/team-agent/src/messaging/mod.rs +147 -0
- package/crates/team-agent/src/messaging/peers.rs +32 -0
- package/crates/team-agent/src/messaging/results.rs +553 -0
- package/crates/team-agent/src/messaging/scheduler.rs +344 -0
- package/crates/team-agent/src/messaging/selftest.rs +100 -0
- package/crates/team-agent/src/messaging/send.rs +578 -0
- package/crates/team-agent/src/messaging/tests/basic.rs +357 -0
- package/crates/team-agent/src/messaging/tests/main_preserved.rs +122 -0
- package/crates/team-agent/src/messaging/tests/mod.rs +293 -0
- package/crates/team-agent/src/messaging/tests/runtime.rs +1422 -0
- package/crates/team-agent/src/messaging/tests/spine.rs +437 -0
- package/crates/team-agent/src/messaging/trust.rs +192 -0
- package/crates/team-agent/src/messaging/types.rs +355 -0
- package/crates/team-agent/src/messaging/watchers.rs +591 -0
- package/crates/team-agent/src/model/enums.rs +311 -0
- package/crates/team-agent/src/model/errors.rs +17 -0
- package/crates/team-agent/src/model/ids.rs +155 -0
- package/crates/team-agent/src/model/mod.rs +22 -0
- package/crates/team-agent/src/model/paths.rs +228 -0
- package/crates/team-agent/src/model/permissions.rs +567 -0
- package/crates/team-agent/src/model/routing.rs +340 -0
- package/crates/team-agent/src/model/spec.rs +680 -0
- package/crates/team-agent/src/model/task_graph.rs +380 -0
- package/crates/team-agent/src/model/testdata/fuzz.golden.yaml +43 -0
- package/crates/team-agent/src/model/testdata/fuzz.yaml +43 -0
- package/crates/team-agent/src/model/testdata/spec_invalid_a.yaml +207 -0
- package/crates/team-agent/src/model/testdata/team.spec.golden.yaml +206 -0
- package/crates/team-agent/src/model/testdata/team.spec.yaml +206 -0
- package/crates/team-agent/src/model/yaml/tests.rs +288 -0
- package/crates/team-agent/src/model/yaml.rs +800 -0
- package/crates/team-agent/src/packaging/install.rs +305 -0
- package/crates/team-agent/src/packaging/migrate.rs +30 -0
- package/crates/team-agent/src/packaging/mod.rs +82 -0
- package/crates/team-agent/src/packaging/repair.rs +24 -0
- package/crates/team-agent/src/packaging/tests.rs +829 -0
- package/crates/team-agent/src/packaging/types.rs +369 -0
- package/crates/team-agent/src/provider/adapter.rs +801 -0
- package/crates/team-agent/src/provider/approvals/mod.rs +2 -0
- package/crates/team-agent/src/provider/approvals/parsing.rs +452 -0
- package/crates/team-agent/src/provider/approvals/runtime_prompts.rs +163 -0
- package/crates/team-agent/src/provider/classify.rs +456 -0
- package/crates/team-agent/src/provider/faults.rs +136 -0
- package/crates/team-agent/src/provider/helpers.rs +41 -0
- package/crates/team-agent/src/provider/mod.rs +53 -0
- package/crates/team-agent/src/provider/startup_prompt.rs +423 -0
- package/crates/team-agent/src/provider/tests/adapter.rs +239 -0
- package/crates/team-agent/src/provider/tests/classify.rs +240 -0
- package/crates/team-agent/src/provider/tests/faults.rs +120 -0
- package/crates/team-agent/src/provider/tests/idle.rs +208 -0
- package/crates/team-agent/src/provider/tests/wire.rs +213 -0
- package/crates/team-agent/src/provider/tests.rs +31 -0
- package/crates/team-agent/src/provider/types.rs +424 -0
- package/crates/team-agent/src/state/identity.rs +659 -0
- package/crates/team-agent/src/state/mod.rs +58 -0
- package/crates/team-agent/src/state/owner_gate.rs +423 -0
- package/crates/team-agent/src/state/persist.rs +712 -0
- package/crates/team-agent/src/state/projection.rs +657 -0
- package/crates/team-agent/src/state/selector.rs +105 -0
- package/crates/team-agent/src/state/testdata/state-rich.canonical.json +133 -0
- package/crates/team-agent/src/tmux_backend/tests.rs +765 -0
- package/crates/team-agent/src/tmux_backend.rs +810 -0
- package/crates/team-agent/src/transport/test_support.rs +252 -0
- package/crates/team-agent/src/transport/tests/behavior.rs +327 -0
- package/crates/team-agent/src/transport/tests/mod.rs +199 -0
- package/crates/team-agent/src/transport/tests/wire.rs +527 -0
- package/crates/team-agent/src/transport.rs +774 -0
- package/npm/install.mjs +118 -112
- package/package.json +15 -13
- package/crates/team-agent-core/Cargo.toml +0 -12
- package/crates/team-agent-core/src/lib.rs +0 -332
- package/crates/team-agent-core/src/main.rs +0 -152
- package/pyproject.toml +0 -18
- package/scripts/install.py +0 -88
- package/scripts/run_regression_tests.py +0 -83
- package/src/team_agent/__init__.py +0 -3
- package/src/team_agent/__main__.py +0 -5
- package/src/team_agent/_legacy_pane_discovery.py +0 -186
- package/src/team_agent/abnormal_track.py +0 -253
- package/src/team_agent/approvals/__init__.py +0 -65
- package/src/team_agent/approvals/constants.py +0 -6
- package/src/team_agent/approvals/parsing.py +0 -176
- package/src/team_agent/approvals/runtime_prompts.py +0 -171
- package/src/team_agent/approvals/status.py +0 -176
- package/src/team_agent/cli/__init__.py +0 -137
- package/src/team_agent/cli/commands.py +0 -481
- package/src/team_agent/cli/e2e.py +0 -202
- package/src/team_agent/cli/helpers.py +0 -226
- package/src/team_agent/cli/parser.py +0 -540
- package/src/team_agent/compiler.py +0 -334
- package/src/team_agent/coordinator/__init__.py +0 -53
- package/src/team_agent/coordinator/__main__.py +0 -119
- package/src/team_agent/coordinator/lifecycle.py +0 -411
- package/src/team_agent/coordinator/metadata.py +0 -61
- package/src/team_agent/coordinator/paths.py +0 -17
- package/src/team_agent/diagnose/__init__.py +0 -48
- package/src/team_agent/diagnose/checks.py +0 -101
- package/src/team_agent/diagnose/comms.py +0 -213
- package/src/team_agent/diagnose/health.py +0 -241
- package/src/team_agent/diagnose/orphan_cleanup.py +0 -364
- package/src/team_agent/diagnose/preflight.py +0 -194
- package/src/team_agent/diagnose/quick_start.py +0 -324
- package/src/team_agent/display/__init__.py +0 -92
- package/src/team_agent/display/adaptive.py +0 -511
- package/src/team_agent/display/backend.py +0 -46
- package/src/team_agent/display/close.py +0 -154
- package/src/team_agent/display/ghostty.py +0 -77
- package/src/team_agent/display/rebuild.py +0 -102
- package/src/team_agent/display/tiling.py +0 -156
- package/src/team_agent/display/worker_window.py +0 -114
- package/src/team_agent/display/workspace.py +0 -382
- package/src/team_agent/errors.py +0 -10
- package/src/team_agent/events.py +0 -84
- package/src/team_agent/fake_worker.py +0 -80
- package/src/team_agent/idle_predicate.py +0 -218
- package/src/team_agent/idle_takeover.py +0 -59
- package/src/team_agent/idle_takeover_wiring.py +0 -114
- package/src/team_agent/launch/__init__.py +0 -41
- package/src/team_agent/launch/bootstrap.py +0 -85
- package/src/team_agent/launch/config.py +0 -106
- package/src/team_agent/launch/core.py +0 -301
- package/src/team_agent/launch/requirements.py +0 -57
- package/src/team_agent/leader/__init__.py +0 -926
- package/src/team_agent/leader_binding.py +0 -183
- package/src/team_agent/lifecycle/__init__.py +0 -5
- package/src/team_agent/lifecycle/agents.py +0 -278
- package/src/team_agent/lifecycle/operations.py +0 -411
- package/src/team_agent/lifecycle/paste_buffer_hygiene.py +0 -39
- package/src/team_agent/lifecycle/start.py +0 -363
- package/src/team_agent/mcp_server/__init__.py +0 -42
- package/src/team_agent/mcp_server/__main__.py +0 -7
- package/src/team_agent/mcp_server/contracts.py +0 -148
- package/src/team_agent/mcp_server/normalize.py +0 -257
- package/src/team_agent/mcp_server/server.py +0 -150
- package/src/team_agent/mcp_server/tools.py +0 -352
- package/src/team_agent/message_store/__init__.py +0 -23
- package/src/team_agent/message_store/agent_health.py +0 -113
- package/src/team_agent/message_store/core.py +0 -497
- package/src/team_agent/message_store/leader_notification_log.py +0 -198
- package/src/team_agent/message_store/result_watchers.py +0 -251
- package/src/team_agent/message_store/schema.py +0 -308
- package/src/team_agent/message_store/schema_migration.py +0 -448
- package/src/team_agent/messaging/__init__.py +0 -1
- package/src/team_agent/messaging/activity_detector.py +0 -262
- package/src/team_agent/messaging/delivery.py +0 -504
- package/src/team_agent/messaging/deps.py +0 -247
- package/src/team_agent/messaging/idle_alerts.py +0 -423
- package/src/team_agent/messaging/internal_delivery.py +0 -46
- package/src/team_agent/messaging/leader.py +0 -497
- package/src/team_agent/messaging/leader_api_errors.py +0 -216
- package/src/team_agent/messaging/leader_panes.py +0 -673
- package/src/team_agent/messaging/owner_bypass.py +0 -29
- package/src/team_agent/messaging/result_delivery.py +0 -539
- package/src/team_agent/messaging/results.py +0 -447
- package/src/team_agent/messaging/scheduler.py +0 -450
- package/src/team_agent/messaging/send.py +0 -532
- package/src/team_agent/messaging/session_drift.py +0 -94
- package/src/team_agent/messaging/tmux_io.py +0 -506
- package/src/team_agent/messaging/tmux_prompt.py +0 -338
- package/src/team_agent/messaging/trust_auto_answer.py +0 -52
- package/src/team_agent/orchestrator/__init__.py +0 -376
- package/src/team_agent/orchestrator/plan.py +0 -122
- package/src/team_agent/orchestrator/state.py +0 -128
- package/src/team_agent/paths.py +0 -45
- package/src/team_agent/permissions.py +0 -123
- package/src/team_agent/profiles/__init__.py +0 -82
- package/src/team_agent/profiles/constants.py +0 -19
- package/src/team_agent/profiles/core.py +0 -407
- package/src/team_agent/profiles/helpers.py +0 -69
- package/src/team_agent/profiles/provider_env.py +0 -188
- package/src/team_agent/profiles/smoke.py +0 -201
- package/src/team_agent/provider_cli/__init__.py +0 -43
- package/src/team_agent/provider_cli/adapter.py +0 -172
- package/src/team_agent/provider_cli/base.py +0 -48
- package/src/team_agent/provider_cli/claude.py +0 -503
- package/src/team_agent/provider_cli/codex.py +0 -336
- package/src/team_agent/provider_cli/copilot.py +0 -8
- package/src/team_agent/provider_cli/fake.py +0 -39
- package/src/team_agent/provider_cli/gemini.py +0 -95
- package/src/team_agent/provider_cli/opencode.py +0 -8
- package/src/team_agent/provider_cli/prompt.py +0 -62
- package/src/team_agent/provider_cli/registry.py +0 -18
- package/src/team_agent/provider_cli/unsupported.py +0 -32
- package/src/team_agent/provider_state/README.md +0 -78
- package/src/team_agent/provider_state/__init__.py +0 -91
- package/src/team_agent/provider_state/claude.py +0 -86
- package/src/team_agent/provider_state/codex.py +0 -84
- package/src/team_agent/provider_state/common.py +0 -207
- package/src/team_agent/provider_state/registry.py +0 -118
- package/src/team_agent/providers.py +0 -163
- package/src/team_agent/quality_gates.py +0 -104
- package/src/team_agent/restart/__init__.py +0 -34
- package/src/team_agent/restart/orchestration.py +0 -554
- package/src/team_agent/restart/selection.py +0 -89
- package/src/team_agent/restart/snapshot.py +0 -70
- package/src/team_agent/routing.py +0 -84
- package/src/team_agent/runtime.py +0 -1243
- package/src/team_agent/rust_core.py +0 -327
- package/src/team_agent/sessions/__init__.py +0 -25
- package/src/team_agent/sessions/capture.py +0 -144
- package/src/team_agent/sessions/inventory.py +0 -44
- package/src/team_agent/sessions/resume.py +0 -135
- package/src/team_agent/simple_yaml.py +0 -236
- package/src/team_agent/spec.py +0 -370
- package/src/team_agent/state.py +0 -693
- package/src/team_agent/status/__init__.py +0 -63
- package/src/team_agent/status/approvals.py +0 -52
- package/src/team_agent/status/compact.py +0 -158
- package/src/team_agent/status/constants.py +0 -18
- package/src/team_agent/status/inbox.py +0 -58
- package/src/team_agent/status/peek.py +0 -117
- package/src/team_agent/status/queries.py +0 -199
- package/src/team_agent/task_graph.py +0 -80
- package/src/team_agent/terminal.py +0 -57
- package/src/team_agent/wake.py +0 -58
- package/src/team_agent/watch/__init__.py +0 -145
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
import os
|
|
4
|
-
import uuid
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import Any, Protocol
|
|
7
|
-
|
|
8
|
-
from team_agent.state import load_runtime_state, select_runtime_state
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
COMMS_BOUNDARY_TEXT = (
|
|
12
|
-
"validates live pane binding consistency. Does NOT perform live runtime message round-trip. "
|
|
13
|
-
"comms contract suite deferred to 0.2.9 (test files not shipped). (zero token, zero pollution)"
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class CommsSelftestDriver(Protocol):
|
|
18
|
-
"""Injectable boundary for tests; production reads state only."""
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
def run_comms_selftest(
|
|
22
|
-
workspace: Path,
|
|
23
|
-
*,
|
|
24
|
-
team: str | None = None,
|
|
25
|
-
gate: str | None = None,
|
|
26
|
-
response_sla_sec: float = 20.0,
|
|
27
|
-
probe_content: str | None = None,
|
|
28
|
-
driver: CommsSelftestDriver | None = None,
|
|
29
|
-
) -> dict[str, Any]:
|
|
30
|
-
del gate, response_sla_sec, probe_content
|
|
31
|
-
workspace = workspace.resolve()
|
|
32
|
-
driver = driver or _DefaultCommsSelftestDriver()
|
|
33
|
-
run_id = _driver_call(driver, "run_id", default=None) or _driver_value(driver, "run_id", default=None) or uuid.uuid4().hex[:12]
|
|
34
|
-
checks = {
|
|
35
|
-
"receiver_binding": _receiver_binding_check(workspace, team, driver),
|
|
36
|
-
"contract_suite": _contract_suite_check(workspace, driver),
|
|
37
|
-
"provider_sdk_calls": _provider_sdk_calls_check(driver),
|
|
38
|
-
}
|
|
39
|
-
ok = all(_check_pass(check) for check in checks.values())
|
|
40
|
-
return {
|
|
41
|
-
"ok": ok,
|
|
42
|
-
"status": "pass" if ok else "fail",
|
|
43
|
-
"run_id": run_id,
|
|
44
|
-
"scope": "binding_consistency",
|
|
45
|
-
"boundary": COMMS_BOUNDARY_TEXT,
|
|
46
|
-
"checks": checks,
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def evaluate_idle_behavior(
|
|
51
|
-
workspace: Path,
|
|
52
|
-
*,
|
|
53
|
-
agent_id: str,
|
|
54
|
-
claimed_status: str,
|
|
55
|
-
response_sla_sec: float = 20.0,
|
|
56
|
-
token: str | None = None,
|
|
57
|
-
driver: CommsSelftestDriver | None = None,
|
|
58
|
-
) -> dict[str, Any]:
|
|
59
|
-
run_id = uuid.uuid4().hex[:12]
|
|
60
|
-
probe_token = token or f"idle-challenge-{run_id}"
|
|
61
|
-
driver = driver or _DefaultCommsSelftestDriver()
|
|
62
|
-
result = _driver_call(
|
|
63
|
-
driver,
|
|
64
|
-
"evaluate_idle_behavior",
|
|
65
|
-
workspace.resolve(),
|
|
66
|
-
agent_id=agent_id,
|
|
67
|
-
claimed_status=claimed_status,
|
|
68
|
-
response_sla_sec=response_sla_sec,
|
|
69
|
-
token=probe_token,
|
|
70
|
-
default=None,
|
|
71
|
-
)
|
|
72
|
-
if isinstance(result, dict):
|
|
73
|
-
return _normalize_idle_result(result, probe_token)
|
|
74
|
-
idle_execution = _driver_value(driver, "idle_execution", default=None)
|
|
75
|
-
if idle_execution is not None:
|
|
76
|
-
execution = str(idle_execution.get("status") if isinstance(idle_execution, dict) else idle_execution)
|
|
77
|
-
return {
|
|
78
|
-
"ok": execution not in {"timeout", "fail", "failed"},
|
|
79
|
-
"agent_id": agent_id,
|
|
80
|
-
"claimed_status": claimed_status,
|
|
81
|
-
"token": probe_token,
|
|
82
|
-
"status": "pass" if execution not in {"timeout", "fail", "failed"} else "fail",
|
|
83
|
-
"execution_ack": execution,
|
|
84
|
-
"classification_accuracy": "pass" if execution not in {"timeout", "fail", "failed"} else "fail",
|
|
85
|
-
}
|
|
86
|
-
status = str(claimed_status or "").upper()
|
|
87
|
-
return {
|
|
88
|
-
"ok": status in {"IDLE", "WORKING", "RUNNING"},
|
|
89
|
-
"agent_id": agent_id,
|
|
90
|
-
"claimed_status": claimed_status,
|
|
91
|
-
"token": probe_token,
|
|
92
|
-
"status": "not_challenged",
|
|
93
|
-
"execution_ack": "pass" if status in {"IDLE", "WORKING", "RUNNING"} else "timeout",
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def _receiver_binding_check(workspace: Path, team: str | None, driver: CommsSelftestDriver) -> dict[str, Any]:
|
|
98
|
-
override = _driver_call(driver, "receiver_binding", workspace, team=team, default=None)
|
|
99
|
-
if isinstance(override, dict):
|
|
100
|
-
out = dict(override)
|
|
101
|
-
out.setdefault("status", "pass" if out.get("ok", True) else "fail")
|
|
102
|
-
out.setdefault("verifies", "binding_consistency")
|
|
103
|
-
out.setdefault("proof", "state_read")
|
|
104
|
-
out.setdefault("state_read_observed", True)
|
|
105
|
-
return out
|
|
106
|
-
state = _selftest_state(workspace, team, driver)
|
|
107
|
-
receiver = state.get("leader_receiver") if isinstance(state.get("leader_receiver"), dict) else {}
|
|
108
|
-
owner = state.get("team_owner") if isinstance(state.get("team_owner"), dict) else {}
|
|
109
|
-
receiver_pane = str(receiver.get("pane_id") or "")
|
|
110
|
-
owner_pane = str(owner.get("pane_id") or "")
|
|
111
|
-
caller_pane = str(_driver_call(driver, "current_pane_id", default=None) or os.environ.get("TMUX_PANE") or "")
|
|
112
|
-
mismatches: list[str] = []
|
|
113
|
-
if owner_pane and receiver_pane and owner_pane != receiver_pane:
|
|
114
|
-
mismatches.append("owner_receiver_pane_mismatch")
|
|
115
|
-
if caller_pane and owner_pane and caller_pane != owner_pane:
|
|
116
|
-
mismatches.append("caller_owner_pane_mismatch")
|
|
117
|
-
if caller_pane and receiver_pane and caller_pane != receiver_pane:
|
|
118
|
-
mismatches.append("caller_receiver_pane_mismatch")
|
|
119
|
-
return {
|
|
120
|
-
"status": "fail" if mismatches else "pass",
|
|
121
|
-
"verifies": "binding_consistency",
|
|
122
|
-
"proof": "state_read",
|
|
123
|
-
"state_read_observed": True,
|
|
124
|
-
"pane_id": receiver_pane,
|
|
125
|
-
"owner_pane_id": owner_pane,
|
|
126
|
-
"caller_pane_id": caller_pane,
|
|
127
|
-
"mismatches": mismatches,
|
|
128
|
-
"configured": bool(receiver_pane),
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
def _contract_suite_check(workspace: Path, driver: CommsSelftestDriver) -> dict[str, Any]:
|
|
133
|
-
del workspace, driver
|
|
134
|
-
return {
|
|
135
|
-
"status": "deferred",
|
|
136
|
-
"deferred_to": "0.2.9",
|
|
137
|
-
"reason": "contract test files not shipped with package",
|
|
138
|
-
"message": "comms contract verification deferred to 0.2.9; contract test files not shipped with package",
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def _provider_sdk_calls_check(driver: CommsSelftestDriver) -> dict[str, Any]:
|
|
143
|
-
calls = _driver_value(driver, "provider_sdk_calls", default=None)
|
|
144
|
-
if not isinstance(calls, dict):
|
|
145
|
-
calls = {"anthropic": 0, "openai": 0, "httpx": 0}
|
|
146
|
-
calls = {name: int(calls.get(name, 0) or 0) for name in ("anthropic", "openai", "httpx")}
|
|
147
|
-
return {
|
|
148
|
-
"status": "fail" if any(calls.values()) else "pass",
|
|
149
|
-
"verifies": "no_provider_sdk_calls",
|
|
150
|
-
"calls": calls,
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
def _selftest_state(workspace: Path, team: str | None, driver: CommsSelftestDriver) -> dict[str, Any]:
|
|
155
|
-
override = _driver_call(driver, "select_runtime_state", workspace, team=team, default=None)
|
|
156
|
-
if isinstance(override, dict):
|
|
157
|
-
return dict(override)
|
|
158
|
-
override = _driver_call(driver, "load_runtime_state", workspace, default=None)
|
|
159
|
-
if isinstance(override, dict):
|
|
160
|
-
return dict(override)
|
|
161
|
-
override = _driver_value(driver, "state", default=None)
|
|
162
|
-
if isinstance(override, dict):
|
|
163
|
-
return dict(override)
|
|
164
|
-
override = _driver_value(driver, "state_before", default=None)
|
|
165
|
-
if isinstance(override, dict):
|
|
166
|
-
return dict(override)
|
|
167
|
-
return select_runtime_state(workspace, team)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def _check_pass(value: Any) -> bool:
|
|
171
|
-
if not isinstance(value, dict):
|
|
172
|
-
return False
|
|
173
|
-
if value.get("status") == "deferred":
|
|
174
|
-
return True
|
|
175
|
-
return value.get("status") in {"pass", "not_implemented"} and _has_required_evidence(value)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def _has_required_evidence(value: dict[str, Any]) -> bool:
|
|
179
|
-
verifies = value.get("verifies")
|
|
180
|
-
if verifies == "binding_consistency":
|
|
181
|
-
return value.get("proof") == "state_read" and value.get("state_read_observed") is True
|
|
182
|
-
if verifies == "no_provider_sdk_calls":
|
|
183
|
-
calls = value.get("calls") if isinstance(value.get("calls"), dict) else {}
|
|
184
|
-
return all(int(calls.get(name, 0) or 0) == 0 for name in ("anthropic", "openai", "httpx"))
|
|
185
|
-
return value.get("status") == "pass"
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
def _normalize_idle_result(result: dict[str, Any], token: str) -> dict[str, Any]:
|
|
189
|
-
out = dict(result)
|
|
190
|
-
out.setdefault("token", token)
|
|
191
|
-
if "execution_ack" not in out:
|
|
192
|
-
if out.get("ok") is False or out.get("status") in {"timeout", "busy", "fail"}:
|
|
193
|
-
out["execution_ack"] = "timeout"
|
|
194
|
-
else:
|
|
195
|
-
out["execution_ack"] = "pass"
|
|
196
|
-
return out
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
def _driver_call(driver: CommsSelftestDriver | None, name: str, *args: Any, default: Any = None, **kwargs: Any) -> Any:
|
|
200
|
-
fn = getattr(driver, name, None)
|
|
201
|
-
if not callable(fn):
|
|
202
|
-
return default
|
|
203
|
-
return fn(*args, **kwargs)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
def _driver_value(driver: CommsSelftestDriver | None, name: str, default: Any = None) -> Any:
|
|
207
|
-
if driver is None:
|
|
208
|
-
return default
|
|
209
|
-
return getattr(driver, name, default)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
class _DefaultCommsSelftestDriver:
|
|
213
|
-
pass
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from typing import Any
|
|
5
|
-
|
|
6
|
-
from team_agent.diagnose.checks import (
|
|
7
|
-
compact_model_checks,
|
|
8
|
-
model_checks_for_agents,
|
|
9
|
-
profile_checks_for_agents,
|
|
10
|
-
)
|
|
11
|
-
from team_agent.events import EventLog
|
|
12
|
-
from team_agent.message_store import MessageStore
|
|
13
|
-
from team_agent.paths import logs_dir, runtime_dir
|
|
14
|
-
from team_agent.profiles import compact_profile_check
|
|
15
|
-
from team_agent.spec import load_spec, workspace_from_spec
|
|
16
|
-
from team_agent.state import load_runtime_state
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def diagnose(workspace: Path) -> dict[str, Any]:
|
|
20
|
-
from team_agent.runtime import (
|
|
21
|
-
_capture_has_team_orchestrator_mcp_prompt,
|
|
22
|
-
_leader_receiver_is_direct,
|
|
23
|
-
_tmux_session_exists,
|
|
24
|
-
_tmux_window_exists,
|
|
25
|
-
_validate_leader_receiver,
|
|
26
|
-
get_adapter,
|
|
27
|
-
run_cmd,
|
|
28
|
-
status,
|
|
29
|
-
)
|
|
30
|
-
_ = EventLog # imported for symmetry / future use
|
|
31
|
-
state = load_runtime_state(workspace)
|
|
32
|
-
spec_path = Path(state.get("spec_path", workspace / "team.spec.yaml"))
|
|
33
|
-
spec = load_spec(spec_path) if spec_path.exists() else {}
|
|
34
|
-
store = MessageStore(workspace)
|
|
35
|
-
issues: list[dict[str, Any]] = []
|
|
36
|
-
suggested_repairs: list[dict[str, Any]] = [
|
|
37
|
-
{
|
|
38
|
-
"kind": "mcp_approval_prompt",
|
|
39
|
-
"action": "If a worker pane asks to allow team_orchestrator, select Allow for this session; then run team-agent collect.",
|
|
40
|
-
},
|
|
41
|
-
{
|
|
42
|
-
"kind": "codex_command_approval_prompt",
|
|
43
|
-
"action": "If a worker pane asks to run a shell command, approve only after checking the command; long servers should use pid/log/health-check protocol.",
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
"kind": "interrupted_worker",
|
|
47
|
-
"action": "Send: Continue from the current interrupted prompt. Do not redo completed work. Do the next bounded step, then report result_envelope_v1.",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"kind": "leader_receiver",
|
|
51
|
-
"action": "Worker-to-leader status requires a direct tmux leader receiver. Run team-agent attach-leader --workspace . --provider codex, or pass --pane <pane_id>.",
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"kind": "process_list_unavailable",
|
|
55
|
-
"action": "If pgrep/lsof fail, use pid files, logs, and health-check URLs; record the environment blocker instead of retrying process-list commands.",
|
|
56
|
-
},
|
|
57
|
-
]
|
|
58
|
-
session_name = state.get("session_name")
|
|
59
|
-
if session_name and not _tmux_session_exists(session_name):
|
|
60
|
-
issues.append(
|
|
61
|
-
{
|
|
62
|
-
"kind": "tmux_session_missing",
|
|
63
|
-
"session": session_name,
|
|
64
|
-
"reason": "tmux has no matching session",
|
|
65
|
-
"suggestion": "Run team-agent launch again or inspect .team/logs/events.jsonl for the shutdown/failure event.",
|
|
66
|
-
}
|
|
67
|
-
)
|
|
68
|
-
leader_receiver = state.get("leader_receiver", {})
|
|
69
|
-
if not _leader_receiver_is_direct(leader_receiver):
|
|
70
|
-
issues.append(
|
|
71
|
-
{
|
|
72
|
-
"kind": "leader_not_attached",
|
|
73
|
-
"mode": leader_receiver.get("mode", "fallback_inbox" if leader_receiver else "none"),
|
|
74
|
-
"suggestion": "Run team-agent attach-leader --workspace . --provider codex, or pass --pane <pane_id> for the existing Codex leader pane.",
|
|
75
|
-
}
|
|
76
|
-
)
|
|
77
|
-
else:
|
|
78
|
-
validation = _validate_leader_receiver(leader_receiver)
|
|
79
|
-
if not validation["ok"]:
|
|
80
|
-
issues.append(
|
|
81
|
-
{
|
|
82
|
-
"kind": validation["reason"],
|
|
83
|
-
"target": leader_receiver.get("pane_id"),
|
|
84
|
-
"provider": leader_receiver.get("provider"),
|
|
85
|
-
"error": validation.get("error"),
|
|
86
|
-
"suggestion": "Run team-agent attach-leader --workspace . --provider codex again with a live Codex pane.",
|
|
87
|
-
}
|
|
88
|
-
)
|
|
89
|
-
elif validation.get("warning"):
|
|
90
|
-
issues.append(
|
|
91
|
-
{
|
|
92
|
-
"kind": "leader_command_unexpected",
|
|
93
|
-
"target": leader_receiver.get("pane_id"),
|
|
94
|
-
"provider": leader_receiver.get("provider"),
|
|
95
|
-
"command": validation.get("pane", {}).get("pane_current_command"),
|
|
96
|
-
"warning": validation["warning"],
|
|
97
|
-
"suggestion": "If this is not the real Codex leader pane, rerun attach-leader with --pane <pane_id>.",
|
|
98
|
-
}
|
|
99
|
-
)
|
|
100
|
-
for agent in spec.get("agents", []):
|
|
101
|
-
adapter = get_adapter(agent["provider"])
|
|
102
|
-
if not adapter.is_installed():
|
|
103
|
-
issues.append(
|
|
104
|
-
{
|
|
105
|
-
"kind": "provider_missing",
|
|
106
|
-
"agent_id": agent["id"],
|
|
107
|
-
"provider": agent["provider"],
|
|
108
|
-
"command": adapter.command_name,
|
|
109
|
-
"suggestion": f"Install {adapter.command_name} and authenticate it before launch.",
|
|
110
|
-
}
|
|
111
|
-
)
|
|
112
|
-
mcp_path = runtime_dir(workspace) / "mcp" / f"{agent['id']}.json"
|
|
113
|
-
if not mcp_path.exists():
|
|
114
|
-
issues.append(
|
|
115
|
-
{
|
|
116
|
-
"kind": "mcp_not_installed",
|
|
117
|
-
"agent_id": agent["id"],
|
|
118
|
-
"provider": agent["provider"],
|
|
119
|
-
"path": str(mcp_path),
|
|
120
|
-
"suggestion": "Run team-agent launch to regenerate provider MCP config.",
|
|
121
|
-
}
|
|
122
|
-
)
|
|
123
|
-
agent_state = state.get("agents", {}).get(agent["id"], {})
|
|
124
|
-
if agent_state.get("status") == "interrupted":
|
|
125
|
-
issues.append(
|
|
126
|
-
{
|
|
127
|
-
"kind": "worker_interrupted",
|
|
128
|
-
"agent_id": agent["id"],
|
|
129
|
-
"suggestion": "Send the standard recovery prompt instead of redispatching the full task.",
|
|
130
|
-
}
|
|
131
|
-
)
|
|
132
|
-
window = agent_state.get("window", agent["id"])
|
|
133
|
-
if session_name and _tmux_window_exists(session_name, window):
|
|
134
|
-
proc = run_cmd(["tmux", "capture-pane", "-p", "-S", "-80", "-t", f"{session_name}:{window}"], timeout=5)
|
|
135
|
-
output = proc.stdout if proc.returncode == 0 else ""
|
|
136
|
-
if _capture_has_team_orchestrator_mcp_prompt(output):
|
|
137
|
-
issues.append(
|
|
138
|
-
{
|
|
139
|
-
"kind": "mcp_approval_prompt",
|
|
140
|
-
"agent_id": agent["id"],
|
|
141
|
-
"suggestion": "Team Agent will auto-approve allowlisted internal MCP prompts; if still blocked, inspect team-agent approvals.",
|
|
142
|
-
}
|
|
143
|
-
)
|
|
144
|
-
if "Would you like to run the following command" in output:
|
|
145
|
-
issues.append(
|
|
146
|
-
{
|
|
147
|
-
"kind": "codex_command_approval_prompt",
|
|
148
|
-
"agent_id": agent["id"],
|
|
149
|
-
"suggestion": "Review and approve or reject the command in the worker pane; do not keep waiting silently.",
|
|
150
|
-
}
|
|
151
|
-
)
|
|
152
|
-
if "Conversation interrupted" in output:
|
|
153
|
-
issues.append(
|
|
154
|
-
{
|
|
155
|
-
"kind": "worker_interrupted",
|
|
156
|
-
"agent_id": agent["id"],
|
|
157
|
-
"suggestion": "Send the standard recovery prompt instead of redispatching the full task.",
|
|
158
|
-
}
|
|
159
|
-
)
|
|
160
|
-
timeout_sec = int(spec.get("communication", {}).get("ack_timeout_sec", 60)) if spec else 60
|
|
161
|
-
failed_messages = store.fail_timeouts(timeout_sec)
|
|
162
|
-
for message_id in failed_messages:
|
|
163
|
-
issues.append(
|
|
164
|
-
{
|
|
165
|
-
"kind": "message_ack_timeout",
|
|
166
|
-
"message_id": message_id,
|
|
167
|
-
"suggestion": "Check target worker status and scrollback; message stayed unacknowledged past timeout.",
|
|
168
|
-
}
|
|
169
|
-
)
|
|
170
|
-
return {
|
|
171
|
-
"ok": not issues,
|
|
172
|
-
"issues": issues,
|
|
173
|
-
"suggested_repairs": suggested_repairs,
|
|
174
|
-
"runtime": status(workspace, as_json=True),
|
|
175
|
-
"event_log": str(logs_dir(workspace) / "events.jsonl"),
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
def doctor(spec_path: Path | None = None) -> dict[str, Any]:
|
|
180
|
-
from team_agent.runtime import _attach_team_profile_dirs, coordinator_health, get_adapter, shutil_which
|
|
181
|
-
providers = ["codex"]
|
|
182
|
-
spec = None
|
|
183
|
-
workspace = Path.cwd()
|
|
184
|
-
if spec_path:
|
|
185
|
-
spec = load_spec(spec_path)
|
|
186
|
-
workspace = workspace_from_spec(spec, spec_path)
|
|
187
|
-
_attach_team_profile_dirs(spec, spec_path, workspace)
|
|
188
|
-
providers = sorted({a["provider"] for a in spec.get("agents", []) if a["provider"] != "fake"})
|
|
189
|
-
checks: dict[str, Any] = {
|
|
190
|
-
"tmux": {
|
|
191
|
-
"installed": bool(shutil_which("tmux")),
|
|
192
|
-
"path": shutil_which("tmux"),
|
|
193
|
-
},
|
|
194
|
-
"workspace": str(workspace),
|
|
195
|
-
"workspace_is_git_repo": (workspace / ".git").exists(),
|
|
196
|
-
"providers": {},
|
|
197
|
-
"mcp": {
|
|
198
|
-
"server_command": shutil_which("team_orchestrator"),
|
|
199
|
-
"local_module": True,
|
|
200
|
-
},
|
|
201
|
-
"coordinator": coordinator_health(workspace),
|
|
202
|
-
}
|
|
203
|
-
for provider in providers:
|
|
204
|
-
adapter = get_adapter(provider)
|
|
205
|
-
checks["providers"][provider] = {
|
|
206
|
-
"command": adapter.command_name,
|
|
207
|
-
"installed": adapter.is_installed(),
|
|
208
|
-
"version": adapter.version(),
|
|
209
|
-
"auth": adapter.auth_hint(),
|
|
210
|
-
}
|
|
211
|
-
model_checks = model_checks_for_agents(spec.get("agents", []), workspace) if spec else []
|
|
212
|
-
if spec:
|
|
213
|
-
checks["models"] = compact_model_checks(model_checks)
|
|
214
|
-
profile_checks = profile_checks_for_agents(workspace, spec.get("agents", []))
|
|
215
|
-
checks["profiles"] = [compact_profile_check(item) for item in profile_checks]
|
|
216
|
-
missing_required = [
|
|
217
|
-
provider for provider, result in checks["providers"].items() if not result["installed"] and spec_path
|
|
218
|
-
]
|
|
219
|
-
missing_auth = [
|
|
220
|
-
provider
|
|
221
|
-
for provider, result in checks["providers"].items()
|
|
222
|
-
if spec_path and result.get("auth", {}).get("status") == "missing"
|
|
223
|
-
]
|
|
224
|
-
invalid_models = [item for item in model_checks if item.get("ok") is False]
|
|
225
|
-
invalid_profiles = [item for item in checks.get("profiles", []) if item.get("ok") is False]
|
|
226
|
-
checks["ok"] = (
|
|
227
|
-
checks["tmux"]["installed"]
|
|
228
|
-
and not missing_required
|
|
229
|
-
and not missing_auth
|
|
230
|
-
and not invalid_models
|
|
231
|
-
and not invalid_profiles
|
|
232
|
-
)
|
|
233
|
-
if missing_required:
|
|
234
|
-
checks["missing_required_providers"] = missing_required
|
|
235
|
-
if missing_auth:
|
|
236
|
-
checks["missing_provider_auth"] = missing_auth
|
|
237
|
-
if invalid_models:
|
|
238
|
-
checks["invalid_models"] = compact_model_checks(invalid_models)
|
|
239
|
-
if invalid_profiles:
|
|
240
|
-
checks["invalid_profiles"] = invalid_profiles
|
|
241
|
-
return checks
|