@spinabot/brigade 0.1.1 → 1.0.0
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/LICENSE +1 -1
- package/README.md +746 -93
- package/brigade.mjs +150 -73
- package/dist/agents/a2a-policy-canonicalize.d.ts +60 -0
- package/dist/agents/a2a-policy-canonicalize.d.ts.map +1 -0
- package/dist/agents/a2a-policy-canonicalize.js +103 -0
- package/dist/agents/a2a-policy-canonicalize.js.map +1 -0
- package/dist/agents/agent-event-bus.d.ts +221 -0
- package/dist/agents/agent-event-bus.d.ts.map +1 -0
- package/dist/agents/agent-event-bus.js +88 -0
- package/dist/agents/agent-event-bus.js.map +1 -0
- package/dist/agents/agent-events.d.ts +84 -0
- package/dist/agents/agent-events.d.ts.map +1 -0
- package/dist/agents/agent-events.js +309 -0
- package/dist/agents/agent-events.js.map +1 -0
- package/dist/agents/agent-events.types.d.ts +139 -0
- package/dist/agents/agent-events.types.d.ts.map +1 -0
- package/dist/agents/agent-events.types.js +27 -0
- package/dist/agents/agent-events.types.js.map +1 -0
- package/dist/agents/agent-loop.d.ts +145 -0
- package/dist/agents/agent-loop.d.ts.map +1 -0
- package/dist/agents/agent-loop.js +1938 -0
- package/dist/agents/agent-loop.js.map +1 -0
- package/dist/agents/agent-scope.d.ts +28 -0
- package/dist/agents/agent-scope.d.ts.map +1 -0
- package/dist/agents/agent-scope.js +39 -0
- package/dist/agents/agent-scope.js.map +1 -0
- package/dist/agents/approval-bridge.d.ts +139 -0
- package/dist/agents/approval-bridge.d.ts.map +1 -0
- package/dist/agents/approval-bridge.js +178 -0
- package/dist/agents/approval-bridge.js.map +1 -0
- package/dist/agents/carrow.d.ts +49 -0
- package/dist/agents/carrow.d.ts.map +1 -0
- package/dist/agents/carrow.js +57 -0
- package/dist/agents/carrow.js.map +1 -0
- package/dist/agents/channels/abort-triggers.d.ts +17 -0
- package/dist/agents/channels/abort-triggers.d.ts.map +1 -0
- package/dist/agents/channels/abort-triggers.js +52 -0
- package/dist/agents/channels/abort-triggers.js.map +1 -0
- package/dist/agents/channels/access-control/index.d.ts +5 -0
- package/dist/agents/channels/access-control/index.d.ts.map +1 -0
- package/dist/agents/channels/access-control/index.js +4 -0
- package/dist/agents/channels/access-control/index.js.map +1 -0
- package/dist/agents/channels/access-control/policy.d.ts +69 -0
- package/dist/agents/channels/access-control/policy.d.ts.map +1 -0
- package/dist/agents/channels/access-control/policy.js +123 -0
- package/dist/agents/channels/access-control/policy.js.map +1 -0
- package/dist/agents/channels/access-control/store.d.ts +86 -0
- package/dist/agents/channels/access-control/store.d.ts.map +1 -0
- package/dist/agents/channels/access-control/store.js +482 -0
- package/dist/agents/channels/access-control/store.js.map +1 -0
- package/dist/agents/channels/access-control/types.d.ts +52 -0
- package/dist/agents/channels/access-control/types.d.ts.map +1 -0
- package/dist/agents/channels/access-control/types.js +20 -0
- package/dist/agents/channels/access-control/types.js.map +1 -0
- package/dist/agents/channels/active-manager.d.ts +31 -0
- package/dist/agents/channels/active-manager.d.ts.map +1 -0
- package/dist/agents/channels/active-manager.js +41 -0
- package/dist/agents/channels/active-manager.js.map +1 -0
- package/dist/agents/channels/agent-switch-command.d.ts +53 -0
- package/dist/agents/channels/agent-switch-command.d.ts.map +1 -0
- package/dist/agents/channels/agent-switch-command.js +349 -0
- package/dist/agents/channels/agent-switch-command.js.map +1 -0
- package/dist/agents/channels/approval-router.d.ts +158 -0
- package/dist/agents/channels/approval-router.d.ts.map +1 -0
- package/dist/agents/channels/approval-router.js +446 -0
- package/dist/agents/channels/approval-router.js.map +1 -0
- package/dist/agents/channels/channel-entry-contract.d.ts +70 -0
- package/dist/agents/channels/channel-entry-contract.d.ts.map +1 -0
- package/dist/agents/channels/channel-entry-contract.js +48 -0
- package/dist/agents/channels/channel-entry-contract.js.map +1 -0
- package/dist/agents/channels/channel-plugin-manager.d.ts +86 -0
- package/dist/agents/channels/channel-plugin-manager.d.ts.map +1 -0
- package/dist/agents/channels/channel-plugin-manager.js +345 -0
- package/dist/agents/channels/channel-plugin-manager.js.map +1 -0
- package/dist/agents/channels/chat-type.d.ts +27 -0
- package/dist/agents/channels/chat-type.d.ts.map +1 -0
- package/dist/agents/channels/chat-type.js +33 -0
- package/dist/agents/channels/chat-type.js.map +1 -0
- package/dist/agents/channels/dedupe.d.ts +44 -0
- package/dist/agents/channels/dedupe.d.ts.map +1 -0
- package/dist/agents/channels/dedupe.js +80 -0
- package/dist/agents/channels/dedupe.js.map +1 -0
- package/dist/agents/channels/inbound-pipeline.d.ts +90 -0
- package/dist/agents/channels/inbound-pipeline.d.ts.map +1 -0
- package/dist/agents/channels/inbound-pipeline.js +721 -0
- package/dist/agents/channels/inbound-pipeline.js.map +1 -0
- package/dist/agents/channels/last-channel.d.ts +56 -0
- package/dist/agents/channels/last-channel.d.ts.map +1 -0
- package/dist/agents/channels/last-channel.js +65 -0
- package/dist/agents/channels/last-channel.js.map +1 -0
- package/dist/agents/channels/manager.d.ts +76 -0
- package/dist/agents/channels/manager.d.ts.map +1 -0
- package/dist/agents/channels/manager.js +132 -0
- package/dist/agents/channels/manager.js.map +1 -0
- package/dist/agents/channels/media-capture.d.ts +23 -0
- package/dist/agents/channels/media-capture.d.ts.map +1 -0
- package/dist/agents/channels/media-capture.js +40 -0
- package/dist/agents/channels/media-capture.js.map +1 -0
- package/dist/agents/channels/plugin-channel-manager-facade.d.ts +18 -0
- package/dist/agents/channels/plugin-channel-manager-facade.d.ts.map +1 -0
- package/dist/agents/channels/plugin-channel-manager-facade.js +52 -0
- package/dist/agents/channels/plugin-channel-manager-facade.js.map +1 -0
- package/dist/agents/channels/reply-sanitizer.d.ts +38 -0
- package/dist/agents/channels/reply-sanitizer.d.ts.map +1 -0
- package/dist/agents/channels/reply-sanitizer.js +94 -0
- package/dist/agents/channels/reply-sanitizer.js.map +1 -0
- package/dist/agents/channels/retryable-inbound.d.ts +31 -0
- package/dist/agents/channels/retryable-inbound.d.ts.map +1 -0
- package/dist/agents/channels/retryable-inbound.js +37 -0
- package/dist/agents/channels/retryable-inbound.js.map +1 -0
- package/dist/agents/channels/types.adapters.d.ts +399 -0
- package/dist/agents/channels/types.adapters.d.ts.map +1 -0
- package/dist/agents/channels/types.adapters.js +33 -0
- package/dist/agents/channels/types.adapters.js.map +1 -0
- package/dist/agents/channels/types.core.d.ts +134 -0
- package/dist/agents/channels/types.core.d.ts.map +1 -0
- package/dist/agents/channels/types.core.js +32 -0
- package/dist/agents/channels/types.core.js.map +1 -0
- package/dist/agents/channels/types.plugin.d.ts +78 -0
- package/dist/agents/channels/types.plugin.d.ts.map +1 -0
- package/dist/agents/channels/types.plugin.js +30 -0
- package/dist/agents/channels/types.plugin.js.map +1 -0
- package/dist/agents/channels/whatsapp/account-config.d.ts +50 -0
- package/dist/agents/channels/whatsapp/account-config.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/account-config.js +105 -0
- package/dist/agents/channels/whatsapp/account-config.js.map +1 -0
- package/dist/agents/channels/whatsapp/adapter.d.ts +22 -0
- package/dist/agents/channels/whatsapp/adapter.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/adapter.js +270 -0
- package/dist/agents/channels/whatsapp/adapter.js.map +1 -0
- package/dist/agents/channels/whatsapp/chunk.d.ts +26 -0
- package/dist/agents/channels/whatsapp/chunk.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/chunk.js +123 -0
- package/dist/agents/channels/whatsapp/chunk.js.map +1 -0
- package/dist/agents/channels/whatsapp/connection.d.ts +249 -0
- package/dist/agents/channels/whatsapp/connection.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/connection.js +1628 -0
- package/dist/agents/channels/whatsapp/connection.js.map +1 -0
- package/dist/agents/channels/whatsapp/convex-auth-state.d.ts +34 -0
- package/dist/agents/channels/whatsapp/convex-auth-state.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/convex-auth-state.js +168 -0
- package/dist/agents/channels/whatsapp/convex-auth-state.js.map +1 -0
- package/dist/agents/channels/whatsapp/format.d.ts +15 -0
- package/dist/agents/channels/whatsapp/format.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/format.js +66 -0
- package/dist/agents/channels/whatsapp/format.js.map +1 -0
- package/dist/agents/channels/whatsapp/inbound-extras.d.ts +30 -0
- package/dist/agents/channels/whatsapp/inbound-extras.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/inbound-extras.js +146 -0
- package/dist/agents/channels/whatsapp/inbound-extras.js.map +1 -0
- package/dist/agents/channels/whatsapp/index.d.ts +7 -0
- package/dist/agents/channels/whatsapp/index.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/index.js +7 -0
- package/dist/agents/channels/whatsapp/index.js.map +1 -0
- package/dist/agents/channels/whatsapp/media.d.ts +47 -0
- package/dist/agents/channels/whatsapp/media.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/media.js +192 -0
- package/dist/agents/channels/whatsapp/media.js.map +1 -0
- package/dist/agents/channels/whatsapp/module.d.ts +10 -0
- package/dist/agents/channels/whatsapp/module.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/module.js +17 -0
- package/dist/agents/channels/whatsapp/module.js.map +1 -0
- package/dist/agents/channels/whatsapp/plugin.d.ts +60 -0
- package/dist/agents/channels/whatsapp/plugin.d.ts.map +1 -0
- package/dist/agents/channels/whatsapp/plugin.js +238 -0
- package/dist/agents/channels/whatsapp/plugin.js.map +1 -0
- package/dist/agents/cmd-ism-guard.d.ts +47 -0
- package/dist/agents/cmd-ism-guard.d.ts.map +1 -0
- package/dist/agents/cmd-ism-guard.js +100 -0
- package/dist/agents/cmd-ism-guard.js.map +1 -0
- package/dist/agents/config-write-guard.d.ts +25 -0
- package/dist/agents/config-write-guard.d.ts.map +1 -0
- package/dist/agents/config-write-guard.js +95 -0
- package/dist/agents/config-write-guard.js.map +1 -0
- package/dist/agents/content-quality-retry.d.ts +66 -0
- package/dist/agents/content-quality-retry.d.ts.map +1 -0
- package/dist/agents/content-quality-retry.js +140 -0
- package/dist/agents/content-quality-retry.js.map +1 -0
- package/dist/agents/error-classifier.d.ts +89 -0
- package/dist/agents/error-classifier.d.ts.map +1 -0
- package/dist/agents/error-classifier.js +630 -0
- package/dist/agents/error-classifier.js.map +1 -0
- package/dist/agents/exec-gate.d.ts +113 -0
- package/dist/agents/exec-gate.d.ts.map +1 -0
- package/dist/agents/exec-gate.js +335 -0
- package/dist/agents/exec-gate.js.map +1 -0
- package/dist/agents/exec-session-allow.d.ts +30 -0
- package/dist/agents/exec-session-allow.d.ts.map +1 -0
- package/dist/agents/exec-session-allow.js +50 -0
- package/dist/agents/exec-session-allow.js.map +1 -0
- package/dist/agents/extensions/active-registry.d.ts +4 -0
- package/dist/agents/extensions/active-registry.d.ts.map +1 -0
- package/dist/agents/extensions/active-registry.js +18 -0
- package/dist/agents/extensions/active-registry.js.map +1 -0
- package/dist/agents/extensions/discovery.d.ts +84 -0
- package/dist/agents/extensions/discovery.d.ts.map +1 -0
- package/dist/agents/extensions/discovery.js +249 -0
- package/dist/agents/extensions/discovery.js.map +1 -0
- package/dist/agents/extensions/hook-runner.d.ts +67 -0
- package/dist/agents/extensions/hook-runner.d.ts.map +1 -0
- package/dist/agents/extensions/hook-runner.js +155 -0
- package/dist/agents/extensions/hook-runner.js.map +1 -0
- package/dist/agents/extensions/index.d.ts +15 -0
- package/dist/agents/extensions/index.d.ts.map +1 -0
- package/dist/agents/extensions/index.js +14 -0
- package/dist/agents/extensions/index.js.map +1 -0
- package/dist/agents/extensions/loader.d.ts +38 -0
- package/dist/agents/extensions/loader.d.ts.map +1 -0
- package/dist/agents/extensions/loader.js +142 -0
- package/dist/agents/extensions/loader.js.map +1 -0
- package/dist/agents/extensions/modules/arxiv.d.ts +28 -0
- package/dist/agents/extensions/modules/arxiv.d.ts.map +1 -0
- package/dist/agents/extensions/modules/arxiv.js +145 -0
- package/dist/agents/extensions/modules/arxiv.js.map +1 -0
- package/dist/agents/extensions/modules/brave.d.ts +28 -0
- package/dist/agents/extensions/modules/brave.d.ts.map +1 -0
- package/dist/agents/extensions/modules/brave.js +489 -0
- package/dist/agents/extensions/modules/brave.js.map +1 -0
- package/dist/agents/extensions/modules/duckduckgo.d.ts +27 -0
- package/dist/agents/extensions/modules/duckduckgo.d.ts.map +1 -0
- package/dist/agents/extensions/modules/duckduckgo.js +263 -0
- package/dist/agents/extensions/modules/duckduckgo.js.map +1 -0
- package/dist/agents/extensions/modules/exa.d.ts +19 -0
- package/dist/agents/extensions/modules/exa.d.ts.map +1 -0
- package/dist/agents/extensions/modules/exa.js +208 -0
- package/dist/agents/extensions/modules/exa.js.map +1 -0
- package/dist/agents/extensions/modules/firecrawl.d.ts +51 -0
- package/dist/agents/extensions/modules/firecrawl.d.ts.map +1 -0
- package/dist/agents/extensions/modules/firecrawl.js +280 -0
- package/dist/agents/extensions/modules/firecrawl.js.map +1 -0
- package/dist/agents/extensions/modules/github-search.d.ts +29 -0
- package/dist/agents/extensions/modules/github-search.d.ts.map +1 -0
- package/dist/agents/extensions/modules/github-search.js +197 -0
- package/dist/agents/extensions/modules/github-search.js.map +1 -0
- package/dist/agents/extensions/modules/hackernews.d.ts +17 -0
- package/dist/agents/extensions/modules/hackernews.d.ts.map +1 -0
- package/dist/agents/extensions/modules/hackernews.js +144 -0
- package/dist/agents/extensions/modules/hackernews.js.map +1 -0
- package/dist/agents/extensions/modules/index.d.ts +11 -0
- package/dist/agents/extensions/modules/index.d.ts.map +1 -0
- package/dist/agents/extensions/modules/index.js +64 -0
- package/dist/agents/extensions/modules/index.js.map +1 -0
- package/dist/agents/extensions/modules/npm-search.d.ts +15 -0
- package/dist/agents/extensions/modules/npm-search.d.ts.map +1 -0
- package/dist/agents/extensions/modules/npm-search.js +126 -0
- package/dist/agents/extensions/modules/npm-search.js.map +1 -0
- package/dist/agents/extensions/modules/ollama-search.d.ts +30 -0
- package/dist/agents/extensions/modules/ollama-search.d.ts.map +1 -0
- package/dist/agents/extensions/modules/ollama-search.js +171 -0
- package/dist/agents/extensions/modules/ollama-search.js.map +1 -0
- package/dist/agents/extensions/modules/perplexity.d.ts +19 -0
- package/dist/agents/extensions/modules/perplexity.d.ts.map +1 -0
- package/dist/agents/extensions/modules/perplexity.js +358 -0
- package/dist/agents/extensions/modules/perplexity.js.map +1 -0
- package/dist/agents/extensions/modules/searxng.d.ts +43 -0
- package/dist/agents/extensions/modules/searxng.d.ts.map +1 -0
- package/dist/agents/extensions/modules/searxng.js +191 -0
- package/dist/agents/extensions/modules/searxng.js.map +1 -0
- package/dist/agents/extensions/modules/tavily.d.ts +71 -0
- package/dist/agents/extensions/modules/tavily.d.ts.map +1 -0
- package/dist/agents/extensions/modules/tavily.js +330 -0
- package/dist/agents/extensions/modules/tavily.js.map +1 -0
- package/dist/agents/extensions/modules/web-provider-helpers.d.ts +89 -0
- package/dist/agents/extensions/modules/web-provider-helpers.d.ts.map +1 -0
- package/dist/agents/extensions/modules/web-provider-helpers.js +146 -0
- package/dist/agents/extensions/modules/web-provider-helpers.js.map +1 -0
- package/dist/agents/extensions/modules/web-search-filters.d.ts +62 -0
- package/dist/agents/extensions/modules/web-search-filters.d.ts.map +1 -0
- package/dist/agents/extensions/modules/web-search-filters.js +179 -0
- package/dist/agents/extensions/modules/web-search-filters.js.map +1 -0
- package/dist/agents/extensions/modules/wikipedia.d.ts +16 -0
- package/dist/agents/extensions/modules/wikipedia.d.ts.map +1 -0
- package/dist/agents/extensions/modules/wikipedia.js +138 -0
- package/dist/agents/extensions/modules/wikipedia.js.map +1 -0
- package/dist/agents/extensions/registry-cache.d.ts +74 -0
- package/dist/agents/extensions/registry-cache.d.ts.map +1 -0
- package/dist/agents/extensions/registry-cache.js +117 -0
- package/dist/agents/extensions/registry-cache.js.map +1 -0
- package/dist/agents/extensions/registry.d.ts +184 -0
- package/dist/agents/extensions/registry.d.ts.map +1 -0
- package/dist/agents/extensions/registry.js +512 -0
- package/dist/agents/extensions/registry.js.map +1 -0
- package/dist/agents/extensions/types.d.ts +1195 -0
- package/dist/agents/extensions/types.d.ts.map +1 -0
- package/dist/agents/extensions/types.js +28 -0
- package/dist/agents/extensions/types.js.map +1 -0
- package/dist/agents/gateway-call.d.ts +171 -0
- package/dist/agents/gateway-call.d.ts.map +1 -0
- package/dist/agents/gateway-call.js +74 -0
- package/dist/agents/gateway-call.js.map +1 -0
- package/dist/agents/heartbeat-runner.d.ts +100 -0
- package/dist/agents/heartbeat-runner.d.ts.map +1 -0
- package/dist/agents/heartbeat-runner.js +268 -0
- package/dist/agents/heartbeat-runner.js.map +1 -0
- package/dist/agents/heartbeat-scheduler.d.ts +56 -0
- package/dist/agents/heartbeat-scheduler.d.ts.map +1 -0
- package/dist/agents/heartbeat-scheduler.js +366 -0
- package/dist/agents/heartbeat-scheduler.js.map +1 -0
- package/dist/agents/heartbeat-wake.d.ts +99 -0
- package/dist/agents/heartbeat-wake.d.ts.map +1 -0
- package/dist/agents/heartbeat-wake.js +304 -0
- package/dist/agents/heartbeat-wake.js.map +1 -0
- package/dist/agents/identity-file.d.ts +26 -0
- package/dist/agents/identity-file.d.ts.map +1 -0
- package/dist/agents/identity-file.js +86 -0
- package/dist/agents/identity-file.js.map +1 -0
- package/dist/agents/identity-links.d.ts +44 -0
- package/dist/agents/identity-links.d.ts.map +1 -0
- package/dist/agents/identity-links.js +51 -0
- package/dist/agents/identity-links.js.map +1 -0
- package/dist/agents/loop/autonomous-agent.d.ts +55 -0
- package/dist/agents/loop/autonomous-agent.d.ts.map +1 -0
- package/dist/agents/loop/autonomous-agent.js +91 -0
- package/dist/agents/loop/autonomous-agent.js.map +1 -0
- package/dist/agents/loop/loop-guards.d.ts +95 -0
- package/dist/agents/loop/loop-guards.d.ts.map +1 -0
- package/dist/agents/loop/loop-guards.js +169 -0
- package/dist/agents/loop/loop-guards.js.map +1 -0
- package/dist/agents/loop/loop-runner.d.ts +72 -0
- package/dist/agents/loop/loop-runner.d.ts.map +1 -0
- package/dist/agents/loop/loop-runner.js +114 -0
- package/dist/agents/loop/loop-runner.js.map +1 -0
- package/dist/agents/memory/auto-recall.d.ts +69 -0
- package/dist/agents/memory/auto-recall.d.ts.map +1 -0
- package/dist/agents/memory/auto-recall.js +147 -0
- package/dist/agents/memory/auto-recall.js.map +1 -0
- package/dist/agents/memory/behavior-review.d.ts +68 -0
- package/dist/agents/memory/behavior-review.d.ts.map +1 -0
- package/dist/agents/memory/behavior-review.js +131 -0
- package/dist/agents/memory/behavior-review.js.map +1 -0
- package/dist/agents/memory/consolidate.d.ts +62 -0
- package/dist/agents/memory/consolidate.d.ts.map +1 -0
- package/dist/agents/memory/consolidate.js +275 -0
- package/dist/agents/memory/consolidate.js.map +1 -0
- package/dist/agents/memory/contradiction.d.ts +44 -0
- package/dist/agents/memory/contradiction.d.ts.map +1 -0
- package/dist/agents/memory/contradiction.js +86 -0
- package/dist/agents/memory/contradiction.js.map +1 -0
- package/dist/agents/memory/curator.d.ts +22 -0
- package/dist/agents/memory/curator.d.ts.map +1 -0
- package/dist/agents/memory/curator.js +52 -0
- package/dist/agents/memory/curator.js.map +1 -0
- package/dist/agents/memory/decay.d.ts +32 -0
- package/dist/agents/memory/decay.d.ts.map +1 -0
- package/dist/agents/memory/decay.js +86 -0
- package/dist/agents/memory/decay.js.map +1 -0
- package/dist/agents/memory/dream.d.ts +52 -0
- package/dist/agents/memory/dream.d.ts.map +1 -0
- package/dist/agents/memory/dream.js +192 -0
- package/dist/agents/memory/dream.js.map +1 -0
- package/dist/agents/memory/embedder-providers.d.ts +114 -0
- package/dist/agents/memory/embedder-providers.d.ts.map +1 -0
- package/dist/agents/memory/embedder-providers.js +213 -0
- package/dist/agents/memory/embedder-providers.js.map +1 -0
- package/dist/agents/memory/embedder.d.ts +84 -0
- package/dist/agents/memory/embedder.d.ts.map +1 -0
- package/dist/agents/memory/embedder.js +218 -0
- package/dist/agents/memory/embedder.js.map +1 -0
- package/dist/agents/memory/eval/asr-bench.d.ts +33 -0
- package/dist/agents/memory/eval/asr-bench.d.ts.map +1 -0
- package/dist/agents/memory/eval/asr-bench.js +129 -0
- package/dist/agents/memory/eval/asr-bench.js.map +1 -0
- package/dist/agents/memory/eval/capabilities.d.ts +97 -0
- package/dist/agents/memory/eval/capabilities.d.ts.map +1 -0
- package/dist/agents/memory/eval/capabilities.js +210 -0
- package/dist/agents/memory/eval/capabilities.js.map +1 -0
- package/dist/agents/memory/eval/gold-export.d.ts +44 -0
- package/dist/agents/memory/eval/gold-export.d.ts.map +1 -0
- package/dist/agents/memory/eval/gold-export.js +85 -0
- package/dist/agents/memory/eval/gold-export.js.map +1 -0
- package/dist/agents/memory/eval/gold-hard.d.ts +35 -0
- package/dist/agents/memory/eval/gold-hard.d.ts.map +1 -0
- package/dist/agents/memory/eval/gold-hard.js +113 -0
- package/dist/agents/memory/eval/gold-hard.js.map +1 -0
- package/dist/agents/memory/eval/gold-rich.d.ts +33 -0
- package/dist/agents/memory/eval/gold-rich.d.ts.map +1 -0
- package/dist/agents/memory/eval/gold-rich.js +82 -0
- package/dist/agents/memory/eval/gold-rich.js.map +1 -0
- package/dist/agents/memory/eval/gold-synthetic.d.ts +19 -0
- package/dist/agents/memory/eval/gold-synthetic.d.ts.map +1 -0
- package/dist/agents/memory/eval/gold-synthetic.js +65 -0
- package/dist/agents/memory/eval/gold-synthetic.js.map +1 -0
- package/dist/agents/memory/eval/gold.d.ts +73 -0
- package/dist/agents/memory/eval/gold.d.ts.map +1 -0
- package/dist/agents/memory/eval/gold.js +174 -0
- package/dist/agents/memory/eval/gold.js.map +1 -0
- package/dist/agents/memory/eval/harness.d.ts +110 -0
- package/dist/agents/memory/eval/harness.d.ts.map +1 -0
- package/dist/agents/memory/eval/harness.js +123 -0
- package/dist/agents/memory/eval/harness.js.map +1 -0
- package/dist/agents/memory/eval/metrics.d.ts +71 -0
- package/dist/agents/memory/eval/metrics.d.ts.map +1 -0
- package/dist/agents/memory/eval/metrics.js +169 -0
- package/dist/agents/memory/eval/metrics.js.map +1 -0
- package/dist/agents/memory/event-log.d.ts +52 -0
- package/dist/agents/memory/event-log.d.ts.map +1 -0
- package/dist/agents/memory/event-log.js +65 -0
- package/dist/agents/memory/event-log.js.map +1 -0
- package/dist/agents/memory/extract.d.ts +155 -0
- package/dist/agents/memory/extract.d.ts.map +1 -0
- package/dist/agents/memory/extract.js +571 -0
- package/dist/agents/memory/extract.js.map +1 -0
- package/dist/agents/memory/governance.d.ts +45 -0
- package/dist/agents/memory/governance.d.ts.map +1 -0
- package/dist/agents/memory/governance.js +113 -0
- package/dist/agents/memory/governance.js.map +1 -0
- package/dist/agents/memory/graph-export.d.ts +59 -0
- package/dist/agents/memory/graph-export.d.ts.map +1 -0
- package/dist/agents/memory/graph-export.js +181 -0
- package/dist/agents/memory/graph-export.js.map +1 -0
- package/dist/agents/memory/graph-recall.d.ts +42 -0
- package/dist/agents/memory/graph-recall.d.ts.map +1 -0
- package/dist/agents/memory/graph-recall.js +165 -0
- package/dist/agents/memory/graph-recall.js.map +1 -0
- package/dist/agents/memory/graph.d.ts +92 -0
- package/dist/agents/memory/graph.d.ts.map +1 -0
- package/dist/agents/memory/graph.js +266 -0
- package/dist/agents/memory/graph.js.map +1 -0
- package/dist/agents/memory/host-ports.d.ts +27 -0
- package/dist/agents/memory/host-ports.d.ts.map +1 -0
- package/dist/agents/memory/host-ports.js +31 -0
- package/dist/agents/memory/host-ports.js.map +1 -0
- package/dist/agents/memory/hybrid.d.ts +46 -0
- package/dist/agents/memory/hybrid.d.ts.map +1 -0
- package/dist/agents/memory/hybrid.js +184 -0
- package/dist/agents/memory/hybrid.js.map +1 -0
- package/dist/agents/memory/index.d.ts +13 -0
- package/dist/agents/memory/index.d.ts.map +1 -0
- package/dist/agents/memory/index.js +13 -0
- package/dist/agents/memory/index.js.map +1 -0
- package/dist/agents/memory/json-scan.d.ts +14 -0
- package/dist/agents/memory/json-scan.d.ts.map +1 -0
- package/dist/agents/memory/json-scan.js +47 -0
- package/dist/agents/memory/json-scan.js.map +1 -0
- package/dist/agents/memory/links.d.ts +92 -0
- package/dist/agents/memory/links.d.ts.map +1 -0
- package/dist/agents/memory/links.js +140 -0
- package/dist/agents/memory/links.js.map +1 -0
- package/dist/agents/memory/maintenance.d.ts +18 -0
- package/dist/agents/memory/maintenance.d.ts.map +1 -0
- package/dist/agents/memory/maintenance.js +66 -0
- package/dist/agents/memory/maintenance.js.map +1 -0
- package/dist/agents/memory/memory-mcp-server.d.ts +39 -0
- package/dist/agents/memory/memory-mcp-server.d.ts.map +1 -0
- package/dist/agents/memory/memory-mcp-server.js +122 -0
- package/dist/agents/memory/memory-mcp-server.js.map +1 -0
- package/dist/agents/memory/memory-mcp.d.ts +34 -0
- package/dist/agents/memory/memory-mcp.d.ts.map +1 -0
- package/dist/agents/memory/memory-mcp.js +130 -0
- package/dist/agents/memory/memory-mcp.js.map +1 -0
- package/dist/agents/memory/plugin-runtime.d.ts +133 -0
- package/dist/agents/memory/plugin-runtime.d.ts.map +1 -0
- package/dist/agents/memory/plugin-runtime.js +149 -0
- package/dist/agents/memory/plugin-runtime.js.map +1 -0
- package/dist/agents/memory/query.d.ts +50 -0
- package/dist/agents/memory/query.d.ts.map +1 -0
- package/dist/agents/memory/query.js +94 -0
- package/dist/agents/memory/query.js.map +1 -0
- package/dist/agents/memory/records.d.ts +617 -0
- package/dist/agents/memory/records.d.ts.map +1 -0
- package/dist/agents/memory/records.js +1327 -0
- package/dist/agents/memory/records.js.map +1 -0
- package/dist/agents/memory/reembed.d.ts +42 -0
- package/dist/agents/memory/reembed.d.ts.map +1 -0
- package/dist/agents/memory/reembed.js +60 -0
- package/dist/agents/memory/reembed.js.map +1 -0
- package/dist/agents/memory/relationship-extract.d.ts +259 -0
- package/dist/agents/memory/relationship-extract.d.ts.map +1 -0
- package/dist/agents/memory/relationship-extract.js +454 -0
- package/dist/agents/memory/relationship-extract.js.map +1 -0
- package/dist/agents/memory/rerank.d.ts +37 -0
- package/dist/agents/memory/rerank.d.ts.map +1 -0
- package/dist/agents/memory/rerank.js +43 -0
- package/dist/agents/memory/rerank.js.map +1 -0
- package/dist/agents/memory/scoring.d.ts +85 -0
- package/dist/agents/memory/scoring.d.ts.map +1 -0
- package/dist/agents/memory/scoring.js +139 -0
- package/dist/agents/memory/scoring.js.map +1 -0
- package/dist/agents/memory/self-improve.d.ts +56 -0
- package/dist/agents/memory/self-improve.d.ts.map +1 -0
- package/dist/agents/memory/self-improve.js +98 -0
- package/dist/agents/memory/self-improve.js.map +1 -0
- package/dist/agents/memory/self-review.d.ts +68 -0
- package/dist/agents/memory/self-review.d.ts.map +1 -0
- package/dist/agents/memory/self-review.js +109 -0
- package/dist/agents/memory/self-review.js.map +1 -0
- package/dist/agents/memory/storage.d.ts +156 -0
- package/dist/agents/memory/storage.d.ts.map +1 -0
- package/dist/agents/memory/storage.js +359 -0
- package/dist/agents/memory/storage.js.map +1 -0
- package/dist/agents/memory/tideline.d.ts +203 -0
- package/dist/agents/memory/tideline.d.ts.map +1 -0
- package/dist/agents/memory/tideline.js +189 -0
- package/dist/agents/memory/tideline.js.map +1 -0
- package/dist/agents/memory/vault.d.ts +142 -0
- package/dist/agents/memory/vault.d.ts.map +1 -0
- package/dist/agents/memory/vault.js +787 -0
- package/dist/agents/memory/vault.js.map +1 -0
- package/dist/agents/memory/write-gate.d.ts +76 -0
- package/dist/agents/memory/write-gate.d.ts.map +1 -0
- package/dist/agents/memory/write-gate.js +140 -0
- package/dist/agents/memory/write-gate.js.map +1 -0
- package/dist/agents/mid-turn-switch.d.ts +25 -0
- package/dist/agents/mid-turn-switch.d.ts.map +1 -0
- package/dist/agents/mid-turn-switch.js +103 -0
- package/dist/agents/mid-turn-switch.js.map +1 -0
- package/dist/agents/model-fallback.d.ts +50 -0
- package/dist/agents/model-fallback.d.ts.map +1 -0
- package/dist/agents/model-fallback.js +226 -0
- package/dist/agents/model-fallback.js.map +1 -0
- package/dist/agents/model-resolution.d.ts +38 -0
- package/dist/agents/model-resolution.d.ts.map +1 -0
- package/dist/agents/model-resolution.js +155 -0
- package/dist/agents/model-resolution.js.map +1 -0
- package/dist/agents/org/a2a-adapter.d.ts +49 -0
- package/dist/agents/org/a2a-adapter.d.ts.map +1 -0
- package/dist/agents/org/a2a-adapter.js +92 -0
- package/dist/agents/org/a2a-adapter.js.map +1 -0
- package/dist/agents/org/assets/mascots/README.md +34 -0
- package/dist/agents/org/assets/mascots/Untitled-1.png +0 -0
- package/dist/agents/org/assets/mascots/brigade_biceps.png +0 -0
- package/dist/agents/org/audit-log.d.ts +22 -0
- package/dist/agents/org/audit-log.d.ts.map +1 -0
- package/dist/agents/org/audit-log.js +37 -0
- package/dist/agents/org/audit-log.js.map +1 -0
- package/dist/agents/org/auto-derive.d.ts +22 -0
- package/dist/agents/org/auto-derive.d.ts.map +1 -0
- package/dist/agents/org/auto-derive.js +66 -0
- package/dist/agents/org/auto-derive.js.map +1 -0
- package/dist/agents/org/delivery-kind.d.ts +89 -0
- package/dist/agents/org/delivery-kind.d.ts.map +1 -0
- package/dist/agents/org/delivery-kind.js +149 -0
- package/dist/agents/org/delivery-kind.js.map +1 -0
- package/dist/agents/org/derive-graph.d.ts +34 -0
- package/dist/agents/org/derive-graph.d.ts.map +1 -0
- package/dist/agents/org/derive-graph.js +266 -0
- package/dist/agents/org/derive-graph.js.map +1 -0
- package/dist/agents/org/lints.d.ts +21 -0
- package/dist/agents/org/lints.d.ts.map +1 -0
- package/dist/agents/org/lints.js +133 -0
- package/dist/agents/org/lints.js.map +1 -0
- package/dist/agents/org/pride-html.d.ts +61 -0
- package/dist/agents/org/pride-html.d.ts.map +1 -0
- package/dist/agents/org/pride-html.js +565 -0
- package/dist/agents/org/pride-html.js.map +1 -0
- package/dist/agents/org/pride-image.d.ts +101 -0
- package/dist/agents/org/pride-image.d.ts.map +1 -0
- package/dist/agents/org/pride-image.js +210 -0
- package/dist/agents/org/pride-image.js.map +1 -0
- package/dist/agents/org/pride-taunts.d.ts +47 -0
- package/dist/agents/org/pride-taunts.d.ts.map +1 -0
- package/dist/agents/org/pride-taunts.js +411 -0
- package/dist/agents/org/pride-taunts.js.map +1 -0
- package/dist/agents/org/pride-template.d.ts +272 -0
- package/dist/agents/org/pride-template.d.ts.map +1 -0
- package/dist/agents/org/pride-template.js +892 -0
- package/dist/agents/org/pride-template.js.map +1 -0
- package/dist/agents/org/pride-themes.d.ts +80 -0
- package/dist/agents/org/pride-themes.d.ts.map +1 -0
- package/dist/agents/org/pride-themes.js +7596 -0
- package/dist/agents/org/pride-themes.js.map +1 -0
- package/dist/agents/org/structured-errors.d.ts +47 -0
- package/dist/agents/org/structured-errors.d.ts.map +1 -0
- package/dist/agents/org/structured-errors.js +97 -0
- package/dist/agents/org/structured-errors.js.map +1 -0
- package/dist/agents/org/types.d.ts +139 -0
- package/dist/agents/org/types.d.ts.map +1 -0
- package/dist/agents/org/types.js +43 -0
- package/dist/agents/org/types.js.map +1 -0
- package/dist/agents/org/validate.d.ts +36 -0
- package/dist/agents/org/validate.d.ts.map +1 -0
- package/dist/agents/org/validate.js +135 -0
- package/dist/agents/org/validate.js.map +1 -0
- package/dist/agents/path-write-guard.d.ts +82 -0
- package/dist/agents/path-write-guard.d.ts.map +1 -0
- package/dist/agents/path-write-guard.js +722 -0
- package/dist/agents/path-write-guard.js.map +1 -0
- package/dist/agents/payload-mutators.d.ts +175 -0
- package/dist/agents/payload-mutators.d.ts.map +1 -0
- package/dist/agents/payload-mutators.js +994 -0
- package/dist/agents/payload-mutators.js.map +1 -0
- package/dist/agents/pending-system-events.d.ts +76 -0
- package/dist/agents/pending-system-events.d.ts.map +1 -0
- package/dist/agents/pending-system-events.js +115 -0
- package/dist/agents/pending-system-events.js.map +1 -0
- package/dist/agents/provider-attribution.d.ts +19 -0
- package/dist/agents/provider-attribution.d.ts.map +1 -0
- package/dist/agents/provider-attribution.js +62 -0
- package/dist/agents/provider-attribution.js.map +1 -0
- package/dist/agents/quality/slop-detector.d.ts +40 -0
- package/dist/agents/quality/slop-detector.d.ts.map +1 -0
- package/dist/agents/quality/slop-detector.js +108 -0
- package/dist/agents/quality/slop-detector.js.map +1 -0
- package/dist/agents/quality/slop-index.d.ts +27 -0
- package/dist/agents/quality/slop-index.d.ts.map +1 -0
- package/dist/agents/quality/slop-index.js +124 -0
- package/dist/agents/quality/slop-index.js.map +1 -0
- package/dist/agents/retry-policy.d.ts +38 -0
- package/dist/agents/retry-policy.d.ts.map +1 -0
- package/dist/agents/retry-policy.js +276 -0
- package/dist/agents/retry-policy.js.map +1 -0
- package/dist/agents/routing/account-id.d.ts +43 -0
- package/dist/agents/routing/account-id.d.ts.map +1 -0
- package/dist/agents/routing/account-id.js +103 -0
- package/dist/agents/routing/account-id.js.map +1 -0
- package/dist/agents/routing/bindings.d.ts +20 -0
- package/dist/agents/routing/bindings.d.ts.map +1 -0
- package/dist/agents/routing/bindings.js +22 -0
- package/dist/agents/routing/bindings.js.map +1 -0
- package/dist/agents/routing/dm-scope-warning.d.ts +37 -0
- package/dist/agents/routing/dm-scope-warning.d.ts.map +1 -0
- package/dist/agents/routing/dm-scope-warning.js +110 -0
- package/dist/agents/routing/dm-scope-warning.js.map +1 -0
- package/dist/agents/routing/identity-links.d.ts +45 -0
- package/dist/agents/routing/identity-links.d.ts.map +1 -0
- package/dist/agents/routing/identity-links.js +85 -0
- package/dist/agents/routing/identity-links.js.map +1 -0
- package/dist/agents/routing/resolve-route.d.ts +91 -0
- package/dist/agents/routing/resolve-route.d.ts.map +1 -0
- package/dist/agents/routing/resolve-route.js +653 -0
- package/dist/agents/routing/resolve-route.js.map +1 -0
- package/dist/agents/routing/session-key.d.ts +168 -0
- package/dist/agents/routing/session-key.d.ts.map +1 -0
- package/dist/agents/routing/session-key.js +268 -0
- package/dist/agents/routing/session-key.js.map +1 -0
- package/dist/agents/sanitize-surrogates.d.ts +30 -0
- package/dist/agents/sanitize-surrogates.d.ts.map +1 -0
- package/dist/agents/sanitize-surrogates.js +56 -0
- package/dist/agents/sanitize-surrogates.js.map +1 -0
- package/dist/agents/session-context.d.ts +80 -0
- package/dist/agents/session-context.d.ts.map +1 -0
- package/dist/agents/session-context.js +76 -0
- package/dist/agents/session-context.js.map +1 -0
- package/dist/agents/session-event-prompt.d.ts +124 -0
- package/dist/agents/session-event-prompt.d.ts.map +1 -0
- package/dist/agents/session-event-prompt.js +179 -0
- package/dist/agents/session-event-prompt.js.map +1 -0
- package/dist/agents/session-inbox.d.ts +129 -0
- package/dist/agents/session-inbox.d.ts.map +1 -0
- package/dist/agents/session-inbox.js +492 -0
- package/dist/agents/session-inbox.js.map +1 -0
- package/dist/agents/session-registry.d.ts +148 -0
- package/dist/agents/session-registry.d.ts.map +1 -0
- package/dist/agents/session-registry.js +405 -0
- package/dist/agents/session-registry.js.map +1 -0
- package/dist/agents/session-wiring.d.ts +214 -0
- package/dist/agents/session-wiring.d.ts.map +1 -0
- package/dist/agents/session-wiring.js +278 -0
- package/dist/agents/session-wiring.js.map +1 -0
- package/dist/agents/session-write-lock.d.ts +15 -0
- package/dist/agents/session-write-lock.d.ts.map +1 -0
- package/dist/agents/session-write-lock.js +15 -0
- package/dist/agents/session-write-lock.js.map +1 -0
- package/dist/agents/skills/agent-filter.d.ts +43 -0
- package/dist/agents/skills/agent-filter.d.ts.map +1 -0
- package/dist/agents/skills/agent-filter.js +89 -0
- package/dist/agents/skills/agent-filter.js.map +1 -0
- package/dist/agents/skills/discovery.d.ts +97 -0
- package/dist/agents/skills/discovery.d.ts.map +1 -0
- package/dist/agents/skills/discovery.js +136 -0
- package/dist/agents/skills/discovery.js.map +1 -0
- package/dist/agents/skills/eligibility.d.ts +118 -0
- package/dist/agents/skills/eligibility.d.ts.map +1 -0
- package/dist/agents/skills/eligibility.js +280 -0
- package/dist/agents/skills/eligibility.js.map +1 -0
- package/dist/agents/skills/grant.d.ts +70 -0
- package/dist/agents/skills/grant.d.ts.map +1 -0
- package/dist/agents/skills/grant.js +106 -0
- package/dist/agents/skills/grant.js.map +1 -0
- package/dist/agents/skills/index.d.ts +35 -0
- package/dist/agents/skills/index.d.ts.map +1 -0
- package/dist/agents/skills/index.js +88 -0
- package/dist/agents/skills/index.js.map +1 -0
- package/dist/agents/skills/install-spec.d.ts +51 -0
- package/dist/agents/skills/install-spec.d.ts.map +1 -0
- package/dist/agents/skills/install-spec.js +21 -0
- package/dist/agents/skills/install-spec.js.map +1 -0
- package/dist/agents/skills/install.d.ts +68 -0
- package/dist/agents/skills/install.d.ts.map +1 -0
- package/dist/agents/skills/install.js +206 -0
- package/dist/agents/skills/install.js.map +1 -0
- package/dist/agents/skills/org-access.d.ts +27 -0
- package/dist/agents/skills/org-access.d.ts.map +1 -0
- package/dist/agents/skills/org-access.js +87 -0
- package/dist/agents/skills/org-access.js.map +1 -0
- package/dist/agents/skills/skill-consolidate.d.ts +76 -0
- package/dist/agents/skills/skill-consolidate.d.ts.map +1 -0
- package/dist/agents/skills/skill-consolidate.js +264 -0
- package/dist/agents/skills/skill-consolidate.js.map +1 -0
- package/dist/agents/skills/skill-curator.d.ts +91 -0
- package/dist/agents/skills/skill-curator.d.ts.map +1 -0
- package/dist/agents/skills/skill-curator.js +239 -0
- package/dist/agents/skills/skill-curator.js.map +1 -0
- package/dist/agents/skills/skill-manifest.d.ts +35 -0
- package/dist/agents/skills/skill-manifest.d.ts.map +1 -0
- package/dist/agents/skills/skill-manifest.js +82 -0
- package/dist/agents/skills/skill-manifest.js.map +1 -0
- package/dist/agents/skills/skill-review.d.ts +91 -0
- package/dist/agents/skills/skill-review.d.ts.map +1 -0
- package/dist/agents/skills/skill-review.js +271 -0
- package/dist/agents/skills/skill-review.js.map +1 -0
- package/dist/agents/skills/skill-usage.d.ts +81 -0
- package/dist/agents/skills/skill-usage.d.ts.map +1 -0
- package/dist/agents/skills/skill-usage.js +208 -0
- package/dist/agents/skills/skill-usage.js.map +1 -0
- package/dist/agents/skills/status.d.ts +68 -0
- package/dist/agents/skills/status.d.ts.map +1 -0
- package/dist/agents/skills/status.js +147 -0
- package/dist/agents/skills/status.js.map +1 -0
- package/dist/agents/skills/update-config.d.ts +32 -0
- package/dist/agents/skills/update-config.d.ts.map +1 -0
- package/dist/agents/skills/update-config.js +53 -0
- package/dist/agents/skills/update-config.js.map +1 -0
- package/dist/agents/slash-commands.d.ts +25 -0
- package/dist/agents/slash-commands.d.ts.map +1 -0
- package/dist/agents/slash-commands.js +151 -0
- package/dist/agents/slash-commands.js.map +1 -0
- package/dist/agents/smart-compaction.d.ts +105 -0
- package/dist/agents/smart-compaction.d.ts.map +1 -0
- package/dist/agents/smart-compaction.js +355 -0
- package/dist/agents/smart-compaction.js.map +1 -0
- package/dist/agents/stream-wrappers.d.ts +20 -0
- package/dist/agents/stream-wrappers.d.ts.map +1 -0
- package/dist/agents/stream-wrappers.js +307 -0
- package/dist/agents/stream-wrappers.js.map +1 -0
- package/dist/agents/subagent-abort-cascade.d.ts +31 -0
- package/dist/agents/subagent-abort-cascade.d.ts.map +1 -0
- package/dist/agents/subagent-abort-cascade.js +124 -0
- package/dist/agents/subagent-abort-cascade.js.map +1 -0
- package/dist/agents/subagent-announce-delivery.d.ts +83 -0
- package/dist/agents/subagent-announce-delivery.d.ts.map +1 -0
- package/dist/agents/subagent-announce-delivery.js +159 -0
- package/dist/agents/subagent-announce-delivery.js.map +1 -0
- package/dist/agents/subagent-budget.d.ts +36 -0
- package/dist/agents/subagent-budget.d.ts.map +1 -0
- package/dist/agents/subagent-budget.js +93 -0
- package/dist/agents/subagent-budget.js.map +1 -0
- package/dist/agents/subagent-completion-bridge.d.ts +42 -0
- package/dist/agents/subagent-completion-bridge.d.ts.map +1 -0
- package/dist/agents/subagent-completion-bridge.js +338 -0
- package/dist/agents/subagent-completion-bridge.js.map +1 -0
- package/dist/agents/subagent-lifecycle-events.d.ts +31 -0
- package/dist/agents/subagent-lifecycle-events.d.ts.map +1 -0
- package/dist/agents/subagent-lifecycle-events.js +21 -0
- package/dist/agents/subagent-lifecycle-events.js.map +1 -0
- package/dist/agents/subagent-policy.d.ts +206 -0
- package/dist/agents/subagent-policy.d.ts.map +1 -0
- package/dist/agents/subagent-policy.js +295 -0
- package/dist/agents/subagent-policy.js.map +1 -0
- package/dist/agents/subagent-registry-completion.d.ts +69 -0
- package/dist/agents/subagent-registry-completion.d.ts.map +1 -0
- package/dist/agents/subagent-registry-completion.js +128 -0
- package/dist/agents/subagent-registry-completion.js.map +1 -0
- package/dist/agents/subagent-registry.d.ts +85 -0
- package/dist/agents/subagent-registry.d.ts.map +1 -0
- package/dist/agents/subagent-registry.js +215 -0
- package/dist/agents/subagent-registry.js.map +1 -0
- package/dist/agents/subagent-registry.types.d.ts +94 -0
- package/dist/agents/subagent-registry.types.d.ts.map +1 -0
- package/dist/agents/subagent-registry.types.js +19 -0
- package/dist/agents/subagent-registry.types.js.map +1 -0
- package/dist/agents/subagent-runner.d.ts +75 -0
- package/dist/agents/subagent-runner.d.ts.map +1 -0
- package/dist/agents/subagent-runner.js +358 -0
- package/dist/agents/subagent-runner.js.map +1 -0
- package/dist/agents/subagent-spawn-abort-marker.d.ts +46 -0
- package/dist/agents/subagent-spawn-abort-marker.d.ts.map +1 -0
- package/dist/agents/subagent-spawn-abort-marker.js +81 -0
- package/dist/agents/subagent-spawn-abort-marker.js.map +1 -0
- package/dist/agents/subagent-spawn.d.ts +104 -0
- package/dist/agents/subagent-spawn.d.ts.map +1 -0
- package/dist/agents/subagent-spawn.js +358 -0
- package/dist/agents/subagent-spawn.js.map +1 -0
- package/dist/agents/thinking-fallback.d.ts +49 -0
- package/dist/agents/thinking-fallback.d.ts.map +1 -0
- package/dist/agents/thinking-fallback.js +97 -0
- package/dist/agents/thinking-fallback.js.map +1 -0
- package/dist/agents/tool-guard.d.ts +71 -0
- package/dist/agents/tool-guard.d.ts.map +1 -0
- package/dist/agents/tool-guard.js +154 -0
- package/dist/agents/tool-guard.js.map +1 -0
- package/dist/agents/tool-loop-detector.d.ts +115 -0
- package/dist/agents/tool-loop-detector.d.ts.map +1 -0
- package/dist/agents/tool-loop-detector.js +0 -0
- package/dist/agents/tool-loop-detector.js.map +1 -0
- package/dist/agents/tool-summaries.d.ts +3 -0
- package/dist/agents/tool-summaries.d.ts.map +1 -0
- package/dist/agents/tool-summaries.js +78 -0
- package/dist/agents/tool-summaries.js.map +1 -0
- package/dist/agents/tools/agents-list-tool.d.ts +51 -0
- package/dist/agents/tools/agents-list-tool.d.ts.map +1 -0
- package/dist/agents/tools/agents-list-tool.js +167 -0
- package/dist/agents/tools/agents-list-tool.js.map +1 -0
- package/dist/agents/tools/browser.d.ts +144 -0
- package/dist/agents/tools/browser.d.ts.map +1 -0
- package/dist/agents/tools/browser.js +1538 -0
- package/dist/agents/tools/browser.js.map +1 -0
- package/dist/agents/tools/common.d.ts +208 -0
- package/dist/agents/tools/common.d.ts.map +1 -0
- package/dist/agents/tools/common.js +405 -0
- package/dist/agents/tools/common.js.map +1 -0
- package/dist/agents/tools/composio-tool.d.ts +179 -0
- package/dist/agents/tools/composio-tool.d.ts.map +1 -0
- package/dist/agents/tools/composio-tool.js +474 -0
- package/dist/agents/tools/composio-tool.js.map +1 -0
- package/dist/agents/tools/cron-tool.d.ts +187 -0
- package/dist/agents/tools/cron-tool.d.ts.map +1 -0
- package/dist/agents/tools/cron-tool.js +985 -0
- package/dist/agents/tools/cron-tool.js.map +1 -0
- package/dist/agents/tools/find-tool.d.ts +55 -0
- package/dist/agents/tools/find-tool.d.ts.map +1 -0
- package/dist/agents/tools/find-tool.js +163 -0
- package/dist/agents/tools/find-tool.js.map +1 -0
- package/dist/agents/tools/generate-image-tool.d.ts +77 -0
- package/dist/agents/tools/generate-image-tool.d.ts.map +1 -0
- package/dist/agents/tools/generate-image-tool.js +421 -0
- package/dist/agents/tools/generate-image-tool.js.map +1 -0
- package/dist/agents/tools/index.d.ts +14 -0
- package/dist/agents/tools/index.d.ts.map +1 -0
- package/dist/agents/tools/index.js +12 -0
- package/dist/agents/tools/index.js.map +1 -0
- package/dist/agents/tools/manage-access-tool.d.ts +64 -0
- package/dist/agents/tools/manage-access-tool.d.ts.map +1 -0
- package/dist/agents/tools/manage-access-tool.js +188 -0
- package/dist/agents/tools/manage-access-tool.js.map +1 -0
- package/dist/agents/tools/manage-agent-tool.d.ts +50 -0
- package/dist/agents/tools/manage-agent-tool.d.ts.map +1 -0
- package/dist/agents/tools/manage-agent-tool.js +232 -0
- package/dist/agents/tools/manage-agent-tool.js.map +1 -0
- package/dist/agents/tools/manage-channel-access-tool.d.ts +44 -0
- package/dist/agents/tools/manage-channel-access-tool.d.ts.map +1 -0
- package/dist/agents/tools/manage-channel-access-tool.js +144 -0
- package/dist/agents/tools/manage-channel-access-tool.js.map +1 -0
- package/dist/agents/tools/manage-memory-tool.d.ts +30 -0
- package/dist/agents/tools/manage-memory-tool.d.ts.map +1 -0
- package/dist/agents/tools/manage-memory-tool.js +309 -0
- package/dist/agents/tools/manage-memory-tool.js.map +1 -0
- package/dist/agents/tools/manage-provider-tool.d.ts +65 -0
- package/dist/agents/tools/manage-provider-tool.d.ts.map +1 -0
- package/dist/agents/tools/manage-provider-tool.js +249 -0
- package/dist/agents/tools/manage-provider-tool.js.map +1 -0
- package/dist/agents/tools/manage-skill-tool.d.ts +121 -0
- package/dist/agents/tools/manage-skill-tool.d.ts.map +1 -0
- package/dist/agents/tools/manage-skill-tool.js +722 -0
- package/dist/agents/tools/manage-skill-tool.js.map +1 -0
- package/dist/agents/tools/memory-tools.d.ts +172 -0
- package/dist/agents/tools/memory-tools.d.ts.map +1 -0
- package/dist/agents/tools/memory-tools.js +561 -0
- package/dist/agents/tools/memory-tools.js.map +1 -0
- package/dist/agents/tools/oauth-authorize-tool.d.ts +94 -0
- package/dist/agents/tools/oauth-authorize-tool.d.ts.map +1 -0
- package/dist/agents/tools/oauth-authorize-tool.js +670 -0
- package/dist/agents/tools/oauth-authorize-tool.js.map +1 -0
- package/dist/agents/tools/org-tool.d.ts +208 -0
- package/dist/agents/tools/org-tool.d.ts.map +1 -0
- package/dist/agents/tools/org-tool.js +790 -0
- package/dist/agents/tools/org-tool.js.map +1 -0
- package/dist/agents/tools/registry.d.ts +146 -0
- package/dist/agents/tools/registry.d.ts.map +1 -0
- package/dist/agents/tools/registry.js +396 -0
- package/dist/agents/tools/registry.js.map +1 -0
- package/dist/agents/tools/send-media-tool.d.ts +92 -0
- package/dist/agents/tools/send-media-tool.d.ts.map +1 -0
- package/dist/agents/tools/send-media-tool.js +512 -0
- package/dist/agents/tools/send-media-tool.js.map +1 -0
- package/dist/agents/tools/send-message-tool.d.ts +84 -0
- package/dist/agents/tools/send-message-tool.d.ts.map +1 -0
- package/dist/agents/tools/send-message-tool.js +226 -0
- package/dist/agents/tools/send-message-tool.js.map +1 -0
- package/dist/agents/tools/sessions/history.d.ts +53 -0
- package/dist/agents/tools/sessions/history.d.ts.map +1 -0
- package/dist/agents/tools/sessions/history.js +138 -0
- package/dist/agents/tools/sessions/history.js.map +1 -0
- package/dist/agents/tools/sessions/index.d.ts +92 -0
- package/dist/agents/tools/sessions/index.d.ts.map +1 -0
- package/dist/agents/tools/sessions/index.js +125 -0
- package/dist/agents/tools/sessions/index.js.map +1 -0
- package/dist/agents/tools/sessions/list.d.ts +53 -0
- package/dist/agents/tools/sessions/list.d.ts.map +1 -0
- package/dist/agents/tools/sessions/list.js +134 -0
- package/dist/agents/tools/sessions/list.js.map +1 -0
- package/dist/agents/tools/sessions/resolve-access.d.ts +34 -0
- package/dist/agents/tools/sessions/resolve-access.d.ts.map +1 -0
- package/dist/agents/tools/sessions/resolve-access.js +67 -0
- package/dist/agents/tools/sessions/resolve-access.js.map +1 -0
- package/dist/agents/tools/sessions/send.d.ts +68 -0
- package/dist/agents/tools/sessions/send.d.ts.map +1 -0
- package/dist/agents/tools/sessions/send.js +556 -0
- package/dist/agents/tools/sessions/send.js.map +1 -0
- package/dist/agents/tools/sessions/shared.d.ts +145 -0
- package/dist/agents/tools/sessions/shared.d.ts.map +1 -0
- package/dist/agents/tools/sessions/shared.js +352 -0
- package/dist/agents/tools/sessions/shared.js.map +1 -0
- package/dist/agents/tools/sessions/spawn.d.ts +71 -0
- package/dist/agents/tools/sessions/spawn.d.ts.map +1 -0
- package/dist/agents/tools/sessions/spawn.js +132 -0
- package/dist/agents/tools/sessions/spawn.js.map +1 -0
- package/dist/agents/tools/spawn-agent-tool.d.ts +87 -0
- package/dist/agents/tools/spawn-agent-tool.d.ts.map +1 -0
- package/dist/agents/tools/spawn-agent-tool.js +189 -0
- package/dist/agents/tools/spawn-agent-tool.js.map +1 -0
- package/dist/agents/tools/spawn-agents-tool.d.ts +75 -0
- package/dist/agents/tools/spawn-agents-tool.d.ts.map +1 -0
- package/dist/agents/tools/spawn-agents-tool.js +267 -0
- package/dist/agents/tools/spawn-agents-tool.js.map +1 -0
- package/dist/agents/tools/types.d.ts +55 -0
- package/dist/agents/tools/types.d.ts.map +1 -0
- package/dist/agents/tools/types.js +28 -0
- package/dist/agents/tools/types.js.map +1 -0
- package/dist/agents/tools/web-fetch-utils.d.ts +114 -0
- package/dist/agents/tools/web-fetch-utils.d.ts.map +1 -0
- package/dist/agents/tools/web-fetch-utils.js +560 -0
- package/dist/agents/tools/web-fetch-utils.js.map +1 -0
- package/dist/agents/tools/web-fetch.d.ts +97 -0
- package/dist/agents/tools/web-fetch.d.ts.map +1 -0
- package/dist/agents/tools/web-fetch.js +369 -0
- package/dist/agents/tools/web-fetch.js.map +1 -0
- package/dist/agents/tools/web-retry.d.ts +55 -0
- package/dist/agents/tools/web-retry.d.ts.map +1 -0
- package/dist/agents/tools/web-retry.js +172 -0
- package/dist/agents/tools/web-retry.js.map +1 -0
- package/dist/agents/tools/web-search.d.ts +96 -0
- package/dist/agents/tools/web-search.d.ts.map +1 -0
- package/dist/agents/tools/web-search.js +459 -0
- package/dist/agents/tools/web-search.js.map +1 -0
- package/dist/agents/tools/web-shared.d.ts +123 -0
- package/dist/agents/tools/web-shared.d.ts.map +1 -0
- package/dist/agents/tools/web-shared.js +207 -0
- package/dist/agents/tools/web-shared.js.map +1 -0
- package/dist/assets/brigade-favicon.png +0 -0
- package/dist/auth/profile-cooldown.d.ts +105 -0
- package/dist/auth/profile-cooldown.d.ts.map +1 -0
- package/dist/auth/profile-cooldown.js +466 -0
- package/dist/auth/profile-cooldown.js.map +1 -0
- package/dist/auth/profiles.d.ts +93 -0
- package/dist/auth/profiles.d.ts.map +1 -0
- package/dist/auth/profiles.js +321 -0
- package/dist/auth/profiles.js.map +1 -0
- package/dist/buildstamp.json +1 -0
- package/dist/cli/argv.d.ts +20 -0
- package/dist/cli/argv.d.ts.map +1 -0
- package/dist/cli/argv.js +47 -0
- package/dist/cli/argv.js.map +1 -0
- package/dist/cli/commands/agent.d.ts +19 -0
- package/dist/cli/commands/agent.d.ts.map +1 -0
- package/dist/cli/commands/agent.js +297 -0
- package/dist/cli/commands/agent.js.map +1 -0
- package/dist/cli/commands/agents-bindings.d.ts +80 -0
- package/dist/cli/commands/agents-bindings.d.ts.map +1 -0
- package/dist/cli/commands/agents-bindings.js +252 -0
- package/dist/cli/commands/agents-bindings.js.map +1 -0
- package/dist/cli/commands/agents-cmd.d.ts +160 -0
- package/dist/cli/commands/agents-cmd.d.ts.map +1 -0
- package/dist/cli/commands/agents-cmd.js +1199 -0
- package/dist/cli/commands/agents-cmd.js.map +1 -0
- package/dist/cli/commands/agents-config.d.ts +102 -0
- package/dist/cli/commands/agents-config.d.ts.map +1 -0
- package/dist/cli/commands/agents-config.js +294 -0
- package/dist/cli/commands/agents-config.js.map +1 -0
- package/dist/cli/commands/agents-shared.d.ts +57 -0
- package/dist/cli/commands/agents-shared.d.ts.map +1 -0
- package/dist/cli/commands/agents-shared.js +83 -0
- package/dist/cli/commands/agents-shared.js.map +1 -0
- package/dist/cli/commands/backup.d.ts +36 -0
- package/dist/cli/commands/backup.d.ts.map +1 -0
- package/dist/cli/commands/backup.js +244 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/channels.d.ts +106 -0
- package/dist/cli/commands/channels.d.ts.map +1 -0
- package/dist/cli/commands/channels.js +830 -0
- package/dist/cli/commands/channels.js.map +1 -0
- package/dist/cli/commands/chat.d.ts +43 -0
- package/dist/cli/commands/chat.d.ts.map +1 -0
- package/dist/cli/commands/chat.js +84 -0
- package/dist/cli/commands/chat.js.map +1 -0
- package/dist/cli/commands/config-cmd.d.ts +62 -0
- package/dist/cli/commands/config-cmd.d.ts.map +1 -0
- package/dist/cli/commands/config-cmd.js +404 -0
- package/dist/cli/commands/config-cmd.js.map +1 -0
- package/dist/cli/commands/connect.d.ts +73 -0
- package/dist/cli/commands/connect.d.ts.map +1 -0
- package/dist/cli/commands/connect.js +1952 -0
- package/dist/cli/commands/connect.js.map +1 -0
- package/dist/cli/commands/cron.d.ts +58 -0
- package/dist/cli/commands/cron.d.ts.map +1 -0
- package/dist/cli/commands/cron.js +250 -0
- package/dist/cli/commands/cron.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +25 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +618 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/encrypt-cmd.d.ts +12 -0
- package/dist/cli/commands/encrypt-cmd.d.ts.map +1 -0
- package/dist/cli/commands/encrypt-cmd.js +119 -0
- package/dist/cli/commands/encrypt-cmd.js.map +1 -0
- package/dist/cli/commands/exec-cmd.d.ts +55 -0
- package/dist/cli/commands/exec-cmd.d.ts.map +1 -0
- package/dist/cli/commands/exec-cmd.js +253 -0
- package/dist/cli/commands/exec-cmd.js.map +1 -0
- package/dist/cli/commands/gateway-install.d.ts +21 -0
- package/dist/cli/commands/gateway-install.d.ts.map +1 -0
- package/dist/cli/commands/gateway-install.js +71 -0
- package/dist/cli/commands/gateway-install.js.map +1 -0
- package/dist/cli/commands/gateway-supervise.d.ts +102 -0
- package/dist/cli/commands/gateway-supervise.d.ts.map +1 -0
- package/dist/cli/commands/gateway-supervise.js +194 -0
- package/dist/cli/commands/gateway-supervise.js.map +1 -0
- package/dist/cli/commands/gateway.d.ts +58 -0
- package/dist/cli/commands/gateway.d.ts.map +1 -0
- package/dist/cli/commands/gateway.js +497 -0
- package/dist/cli/commands/gateway.js.map +1 -0
- package/dist/cli/commands/logs.d.ts +14 -0
- package/dist/cli/commands/logs.d.ts.map +1 -0
- package/dist/cli/commands/logs.js +93 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/mcp-cmd.d.ts +4 -0
- package/dist/cli/commands/mcp-cmd.d.ts.map +1 -0
- package/dist/cli/commands/mcp-cmd.js +30 -0
- package/dist/cli/commands/mcp-cmd.js.map +1 -0
- package/dist/cli/commands/onboard-config.d.ts +23 -0
- package/dist/cli/commands/onboard-config.d.ts.map +1 -0
- package/dist/cli/commands/onboard-config.js +33 -0
- package/dist/cli/commands/onboard-config.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +48 -0
- package/dist/cli/commands/onboard.d.ts.map +1 -0
- package/dist/cli/commands/onboard.js +397 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/org-cmd.d.ts +87 -0
- package/dist/cli/commands/org-cmd.d.ts.map +1 -0
- package/dist/cli/commands/org-cmd.js +394 -0
- package/dist/cli/commands/org-cmd.js.map +1 -0
- package/dist/cli/commands/org-cmd.templates.d.ts +66 -0
- package/dist/cli/commands/org-cmd.templates.d.ts.map +1 -0
- package/dist/cli/commands/org-cmd.templates.js +145 -0
- package/dist/cli/commands/org-cmd.templates.js.map +1 -0
- package/dist/cli/commands/org-slash.d.ts +107 -0
- package/dist/cli/commands/org-slash.d.ts.map +1 -0
- package/dist/cli/commands/org-slash.js +263 -0
- package/dist/cli/commands/org-slash.js.map +1 -0
- package/dist/cli/commands/pairing.d.ts +33 -0
- package/dist/cli/commands/pairing.d.ts.map +1 -0
- package/dist/cli/commands/pairing.js +155 -0
- package/dist/cli/commands/pairing.js.map +1 -0
- package/dist/cli/commands/secrets-audit.d.ts +17 -0
- package/dist/cli/commands/secrets-audit.d.ts.map +1 -0
- package/dist/cli/commands/secrets-audit.js +109 -0
- package/dist/cli/commands/secrets-audit.js.map +1 -0
- package/dist/cli/commands/sessions.d.ts +22 -0
- package/dist/cli/commands/sessions.d.ts.map +1 -0
- package/dist/cli/commands/sessions.js +99 -0
- package/dist/cli/commands/sessions.js.map +1 -0
- package/dist/cli/commands/skills.d.ts +17 -0
- package/dist/cli/commands/skills.d.ts.map +1 -0
- package/dist/cli/commands/skills.js +100 -0
- package/dist/cli/commands/skills.js.map +1 -0
- package/dist/cli/commands/status.d.ts +26 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +252 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/store-cmd.d.ts +36 -0
- package/dist/cli/commands/store-cmd.d.ts.map +1 -0
- package/dist/cli/commands/store-cmd.js +405 -0
- package/dist/cli/commands/store-cmd.js.map +1 -0
- package/dist/cli/flows/web-setup.d.ts +47 -0
- package/dist/cli/flows/web-setup.d.ts.map +1 -0
- package/dist/cli/flows/web-setup.js +324 -0
- package/dist/cli/flows/web-setup.js.map +1 -0
- package/dist/cli/program/build-program.d.ts +3 -0
- package/dist/cli/program/build-program.d.ts.map +1 -0
- package/dist/cli/program/build-program.js +1326 -0
- package/dist/cli/program/build-program.js.map +1 -0
- package/dist/cli/run-main.d.ts +2 -0
- package/dist/cli/run-main.d.ts.map +1 -0
- package/dist/cli/run-main.js +63 -0
- package/dist/cli/run-main.js.map +1 -0
- package/dist/config/agent-limits.d.ts +22 -0
- package/dist/config/agent-limits.d.ts.map +1 -0
- package/dist/config/agent-limits.js +34 -0
- package/dist/config/agent-limits.js.map +1 -0
- package/dist/config/io.d.ts +378 -0
- package/dist/config/io.d.ts.map +1 -0
- package/dist/config/io.js +602 -0
- package/dist/config/io.js.map +1 -0
- package/dist/config/paths.d.ts +80 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +342 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/types.d.ts +12 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +12 -0
- package/dist/config/types.js.map +1 -0
- package/dist/core/agent-dispatcher.d.ts +91 -0
- package/dist/core/agent-dispatcher.d.ts.map +1 -0
- package/dist/core/agent-dispatcher.js +251 -0
- package/dist/core/agent-dispatcher.js.map +1 -0
- package/dist/core/agent-events-stream.d.ts +76 -0
- package/dist/core/agent-events-stream.d.ts.map +1 -0
- package/dist/core/agent-events-stream.js +185 -0
- package/dist/core/agent-events-stream.js.map +1 -0
- package/dist/core/agent-runtime-persist.d.ts +53 -0
- package/dist/core/agent-runtime-persist.d.ts.map +1 -0
- package/dist/core/agent-runtime-persist.js +114 -0
- package/dist/core/agent-runtime-persist.js.map +1 -0
- package/dist/core/auth-bridge.d.ts +8 -0
- package/dist/core/auth-bridge.d.ts.map +1 -0
- package/dist/core/auth-bridge.js +102 -0
- package/dist/core/auth-bridge.js.map +1 -0
- package/dist/core/auth-error.d.ts +49 -0
- package/dist/core/auth-error.d.ts.map +1 -0
- package/dist/core/auth-error.js.map +1 -0
- package/dist/core/brigade-config.d.ts +205 -0
- package/dist/core/brigade-config.d.ts.map +1 -0
- package/dist/core/brigade-config.js +58 -6
- package/dist/core/brigade-config.js.map +1 -0
- package/dist/core/config.d.ts +17 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +92 -246
- package/dist/core/config.js.map +1 -0
- package/dist/core/console-stream.d.ts +52 -0
- package/dist/core/console-stream.d.ts.map +1 -0
- package/dist/core/console-stream.js +49 -3
- package/dist/core/console-stream.js.map +1 -0
- package/dist/core/daemon/launchd.d.ts +19 -0
- package/dist/core/daemon/launchd.d.ts.map +1 -0
- package/dist/core/daemon/launchd.js +117 -0
- package/dist/core/daemon/launchd.js.map +1 -0
- package/dist/core/daemon/schtasks.d.ts +23 -0
- package/dist/core/daemon/schtasks.d.ts.map +1 -0
- package/dist/core/daemon/schtasks.js +139 -0
- package/dist/core/daemon/schtasks.js.map +1 -0
- package/dist/core/daemon/service.d.ts +56 -0
- package/dist/core/daemon/service.d.ts.map +1 -0
- package/dist/core/daemon/service.js +54 -0
- package/dist/core/daemon/service.js.map +1 -0
- package/dist/core/daemon/systemd.d.ts +19 -0
- package/dist/core/daemon/systemd.d.ts.map +1 -0
- package/dist/core/daemon/systemd.js +117 -0
- package/dist/core/daemon/systemd.js.map +1 -0
- package/dist/core/event-logger.d.ts +74 -0
- package/dist/core/event-logger.d.ts.map +1 -0
- package/dist/core/event-logger.js +299 -6
- package/dist/core/event-logger.js.map +1 -0
- package/dist/core/exec-approvals.d.ts +178 -0
- package/dist/core/exec-approvals.d.ts.map +1 -0
- package/dist/core/exec-approvals.js +591 -266
- package/dist/core/exec-approvals.js.map +1 -0
- package/dist/core/extension-lifecycle.d.ts +27 -0
- package/dist/core/extension-lifecycle.d.ts.map +1 -0
- package/dist/core/extension-lifecycle.js +45 -0
- package/dist/core/extension-lifecycle.js.map +1 -0
- package/dist/core/gateway-caller-impl.d.ts +42 -0
- package/dist/core/gateway-caller-impl.d.ts.map +1 -0
- package/dist/core/gateway-caller-impl.js +95 -0
- package/dist/core/gateway-caller-impl.js.map +1 -0
- package/dist/core/gateway-lock.d.ts +88 -0
- package/dist/core/gateway-lock.d.ts.map +1 -0
- package/dist/core/gateway-lock.js +204 -0
- package/dist/core/gateway-lock.js.map +1 -0
- package/dist/core/gateway-probe.d.ts +148 -0
- package/dist/core/gateway-probe.d.ts.map +1 -0
- package/dist/core/gateway-probe.js +319 -0
- package/dist/core/gateway-probe.js.map +1 -0
- package/dist/core/gateway-spawn.d.ts +40 -0
- package/dist/core/gateway-spawn.d.ts.map +1 -0
- package/dist/core/gateway-spawn.js +156 -0
- package/dist/core/gateway-spawn.js.map +1 -0
- package/dist/core/model-caps.d.ts +85 -0
- package/dist/core/model-caps.d.ts.map +1 -0
- package/dist/core/model-caps.js +88 -2
- package/dist/core/model-caps.js.map +1 -0
- package/dist/core/port-inspect.d.ts +37 -0
- package/dist/core/port-inspect.d.ts.map +1 -0
- package/dist/core/port-inspect.js +165 -0
- package/dist/core/port-inspect.js.map +1 -0
- package/dist/core/server-lanes.d.ts +25 -0
- package/dist/core/server-lanes.d.ts.map +1 -0
- package/dist/core/server-lanes.js +31 -0
- package/dist/core/server-lanes.js.map +1 -0
- package/dist/core/server-methods/cron.d.ts +104 -0
- package/dist/core/server-methods/cron.d.ts.map +1 -0
- package/dist/core/server-methods/cron.js +183 -0
- package/dist/core/server-methods/cron.js.map +1 -0
- package/dist/core/server-methods/health.d.ts +36 -0
- package/dist/core/server-methods/health.d.ts.map +1 -0
- package/dist/core/server-methods/health.js +51 -0
- package/dist/core/server-methods/health.js.map +1 -0
- package/dist/core/server-methods/org.d.ts +93 -0
- package/dist/core/server-methods/org.d.ts.map +1 -0
- package/dist/core/server-methods/org.js +95 -0
- package/dist/core/server-methods/org.js.map +1 -0
- package/dist/core/server-methods/sessions.d.ts +133 -0
- package/dist/core/server-methods/sessions.d.ts.map +1 -0
- package/dist/core/server-methods/sessions.js +209 -0
- package/dist/core/server-methods/sessions.js.map +1 -0
- package/dist/core/server.d.ts +46 -0
- package/dist/core/server.d.ts.map +1 -0
- package/dist/core/server.js +4716 -249
- package/dist/core/server.js.map +1 -0
- package/dist/core/system-prompt.d.ts +92 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +180 -1584
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/version.d.ts +4 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +8 -13
- package/dist/core/version.js.map +1 -0
- package/dist/core/webhook-guards.d.ts +131 -0
- package/dist/core/webhook-guards.d.ts.map +1 -0
- package/dist/core/webhook-guards.js +283 -0
- package/dist/core/webhook-guards.js.map +1 -0
- package/dist/core/ws-subscription-filter.d.ts +9 -0
- package/dist/core/ws-subscription-filter.d.ts.map +1 -0
- package/dist/core/ws-subscription-filter.js +39 -0
- package/dist/core/ws-subscription-filter.js.map +1 -0
- package/dist/cron/active-service.d.ts +30 -0
- package/dist/cron/active-service.d.ts.map +1 -0
- package/dist/cron/active-service.js +48 -0
- package/dist/cron/active-service.js.map +1 -0
- package/dist/cron/isolated-agent/run-executor.d.ts +49 -0
- package/dist/cron/isolated-agent/run-executor.d.ts.map +1 -0
- package/dist/cron/isolated-agent/run-executor.js +343 -0
- package/dist/cron/isolated-agent/run-executor.js.map +1 -0
- package/dist/cron/isolated-agent/run.d.ts +27 -0
- package/dist/cron/isolated-agent/run.d.ts.map +1 -0
- package/dist/cron/isolated-agent/run.js +29 -0
- package/dist/cron/isolated-agent/run.js.map +1 -0
- package/dist/cron/normalize.d.ts +103 -0
- package/dist/cron/normalize.d.ts.map +1 -0
- package/dist/cron/normalize.js +376 -0
- package/dist/cron/normalize.js.map +1 -0
- package/dist/cron/parse.d.ts +27 -0
- package/dist/cron/parse.d.ts.map +1 -0
- package/dist/cron/parse.js +55 -0
- package/dist/cron/parse.js.map +1 -0
- package/dist/cron/reminder-context.d.ts +78 -0
- package/dist/cron/reminder-context.d.ts.map +1 -0
- package/dist/cron/reminder-context.js +167 -0
- package/dist/cron/reminder-context.js.map +1 -0
- package/dist/cron/run-log.d.ts +48 -0
- package/dist/cron/run-log.d.ts.map +1 -0
- package/dist/cron/run-log.js +225 -0
- package/dist/cron/run-log.js.map +1 -0
- package/dist/cron/schedule.d.ts +46 -0
- package/dist/cron/schedule.d.ts.map +1 -0
- package/dist/cron/schedule.js +144 -0
- package/dist/cron/schedule.js.map +1 -0
- package/dist/cron/service/jobs.d.ts +138 -0
- package/dist/cron/service/jobs.d.ts.map +1 -0
- package/dist/cron/service/jobs.js +370 -0
- package/dist/cron/service/jobs.js.map +1 -0
- package/dist/cron/service/locked.d.ts +46 -0
- package/dist/cron/service/locked.d.ts.map +1 -0
- package/dist/cron/service/locked.js +54 -0
- package/dist/cron/service/locked.js.map +1 -0
- package/dist/cron/service/ops.d.ts +124 -0
- package/dist/cron/service/ops.d.ts.map +1 -0
- package/dist/cron/service/ops.js +415 -0
- package/dist/cron/service/ops.js.map +1 -0
- package/dist/cron/service/state.d.ts +254 -0
- package/dist/cron/service/state.d.ts.map +1 -0
- package/dist/cron/service/state.js +50 -0
- package/dist/cron/service/state.js.map +1 -0
- package/dist/cron/service/store.d.ts +65 -0
- package/dist/cron/service/store.d.ts.map +1 -0
- package/dist/cron/service/store.js +350 -0
- package/dist/cron/service/store.js.map +1 -0
- package/dist/cron/service/timer.d.ts +113 -0
- package/dist/cron/service/timer.d.ts.map +1 -0
- package/dist/cron/service/timer.js +1081 -0
- package/dist/cron/service/timer.js.map +1 -0
- package/dist/cron/session-reaper.d.ts +62 -0
- package/dist/cron/session-reaper.d.ts.map +1 -0
- package/dist/cron/session-reaper.js +152 -0
- package/dist/cron/session-reaper.js.map +1 -0
- package/dist/cron/session-target.d.ts +56 -0
- package/dist/cron/session-target.d.ts.map +1 -0
- package/dist/cron/session-target.js +96 -0
- package/dist/cron/session-target.js.map +1 -0
- package/dist/cron/stagger.d.ts +34 -0
- package/dist/cron/stagger.d.ts.map +1 -0
- package/dist/cron/stagger.js +69 -0
- package/dist/cron/stagger.js.map +1 -0
- package/dist/cron/types.d.ts +287 -0
- package/dist/cron/types.d.ts.map +1 -0
- package/dist/cron/types.js +22 -0
- package/dist/cron/types.js.map +1 -0
- package/dist/cron/validate-timestamp.d.ts +33 -0
- package/dist/cron/validate-timestamp.d.ts.map +1 -0
- package/dist/cron/validate-timestamp.js +54 -0
- package/dist/cron/validate-timestamp.js.map +1 -0
- package/dist/entry.d.ts +2 -0
- package/dist/entry.d.ts.map +1 -0
- package/dist/entry.js +57 -0
- package/dist/entry.js.map +1 -0
- package/dist/extension-sdk.d.ts +28 -0
- package/dist/extension-sdk.d.ts.map +1 -0
- package/dist/extension-sdk.js +26 -0
- package/dist/extension-sdk.js.map +1 -0
- package/dist/identity/device.d.ts +19 -0
- package/dist/identity/device.d.ts.map +1 -0
- package/dist/identity/device.js +88 -0
- package/dist/identity/device.js.map +1 -0
- package/dist/infra/backoff.d.ts +24 -0
- package/dist/infra/backoff.d.ts.map +1 -0
- package/dist/infra/backoff.js +48 -0
- package/dist/infra/backoff.js.map +1 -0
- package/dist/infra/errors.d.ts +35 -0
- package/dist/infra/errors.d.ts.map +1 -0
- package/dist/infra/errors.js +54 -0
- package/dist/infra/errors.js.map +1 -0
- package/dist/infra/fs/atomic-rename.d.ts +31 -0
- package/dist/infra/fs/atomic-rename.d.ts.map +1 -0
- package/dist/infra/fs/atomic-rename.js +75 -0
- package/dist/infra/fs/atomic-rename.js.map +1 -0
- package/dist/infra/json-file.d.ts +25 -0
- package/dist/infra/json-file.d.ts.map +1 -0
- package/dist/infra/json-file.js +49 -0
- package/dist/infra/json-file.js.map +1 -0
- package/dist/infra/json-utf8-bytes.d.ts +14 -0
- package/dist/infra/json-utf8-bytes.d.ts.map +1 -0
- package/dist/infra/json-utf8-bytes.js +20 -0
- package/dist/infra/json-utf8-bytes.js.map +1 -0
- package/dist/infra/net/dns-pinning.d.ts +66 -0
- package/dist/infra/net/dns-pinning.d.ts.map +1 -0
- package/dist/infra/net/dns-pinning.js +128 -0
- package/dist/infra/net/dns-pinning.js.map +1 -0
- package/dist/infra/net/fetch-guard.d.ts +85 -0
- package/dist/infra/net/fetch-guard.d.ts.map +1 -0
- package/dist/infra/net/fetch-guard.js +439 -0
- package/dist/infra/net/fetch-guard.js.map +1 -0
- package/dist/infra/prototype-keys.d.ts +19 -0
- package/dist/infra/prototype-keys.d.ts.map +1 -0
- package/dist/infra/prototype-keys.js +22 -0
- package/dist/infra/prototype-keys.js.map +1 -0
- package/dist/integrations/ollama.d.ts +67 -0
- package/dist/integrations/ollama.d.ts.map +1 -0
- package/dist/integrations/ollama.js +53 -0
- package/dist/integrations/ollama.js.map +1 -0
- package/dist/integrations/provider-discovery.d.ts +66 -0
- package/dist/integrations/provider-discovery.d.ts.map +1 -0
- package/dist/integrations/provider-discovery.js +166 -0
- package/dist/integrations/provider-discovery.js.map +1 -0
- package/dist/logging/redact.d.ts +28 -0
- package/dist/logging/redact.d.ts.map +1 -0
- package/dist/logging/redact.js +51 -0
- package/dist/logging/redact.js.map +1 -0
- package/dist/logging/subsystem-logger.d.ts +77 -0
- package/dist/logging/subsystem-logger.d.ts.map +1 -0
- package/dist/logging/subsystem-logger.js +577 -0
- package/dist/logging/subsystem-logger.js.map +1 -0
- package/dist/logging/subsystem.d.ts +13 -0
- package/dist/logging/subsystem.d.ts.map +1 -0
- package/dist/logging/subsystem.js +12 -0
- package/dist/logging/subsystem.js.map +1 -0
- package/dist/process/command-queue.d.ts +152 -0
- package/dist/process/command-queue.d.ts.map +1 -0
- package/dist/process/command-queue.js +420 -0
- package/dist/process/command-queue.js.map +1 -0
- package/dist/process/lanes.d.ts +102 -0
- package/dist/process/lanes.d.ts.map +1 -0
- package/dist/process/lanes.js +117 -0
- package/dist/process/lanes.js.map +1 -0
- package/dist/process/session-lane.d.ts +31 -0
- package/dist/process/session-lane.d.ts.map +1 -0
- package/dist/process/session-lane.js +45 -0
- package/dist/process/session-lane.js.map +1 -0
- package/dist/protocol/errors.d.ts +35 -0
- package/dist/protocol/errors.d.ts.map +1 -0
- package/dist/protocol/errors.js +36 -0
- package/dist/protocol/errors.js.map +1 -0
- package/dist/protocol/handshake.d.ts +101 -0
- package/dist/protocol/handshake.d.ts.map +1 -0
- package/dist/protocol/handshake.js +49 -0
- package/dist/protocol/handshake.js.map +1 -0
- package/dist/protocol/messages.d.ts +68 -0
- package/dist/protocol/messages.d.ts.map +1 -0
- package/dist/protocol/messages.js +20 -0
- package/dist/protocol/messages.js.map +1 -0
- package/dist/protocol/methods.d.ts +312 -0
- package/dist/protocol/methods.d.ts.map +1 -0
- package/dist/protocol/methods.js +16 -0
- package/dist/protocol/methods.js.map +1 -0
- package/dist/protocol.d.ts +598 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +12 -0
- package/dist/protocol.js.map +1 -0
- package/dist/providers/auth-methods.d.ts +82 -0
- package/dist/providers/auth-methods.d.ts.map +1 -0
- package/dist/providers/auth-methods.js +180 -0
- package/dist/providers/auth-methods.js.map +1 -0
- package/dist/providers/catalog.d.ts +85 -0
- package/dist/providers/catalog.d.ts.map +1 -0
- package/dist/providers/catalog.js +41 -0
- package/dist/providers/catalog.js.map +1 -0
- package/dist/providers/validate-key.d.ts +42 -0
- package/dist/providers/validate-key.d.ts.map +1 -0
- package/dist/providers/validate-key.js.map +1 -0
- package/dist/security/external-content.d.ts +67 -0
- package/dist/security/external-content.d.ts.map +1 -0
- package/dist/security/external-content.js +80 -0
- package/dist/security/external-content.js.map +1 -0
- package/dist/security/injection-patterns.d.ts +33 -0
- package/dist/security/injection-patterns.d.ts.map +1 -0
- package/dist/security/injection-patterns.js +97 -0
- package/dist/security/injection-patterns.js.map +1 -0
- package/dist/security/media-path-guard.d.ts +25 -0
- package/dist/security/media-path-guard.d.ts.map +1 -0
- package/dist/security/media-path-guard.js +98 -0
- package/dist/security/media-path-guard.js.map +1 -0
- package/dist/security/terminal-input-sanitizer.d.ts +30 -0
- package/dist/security/terminal-input-sanitizer.d.ts.map +1 -0
- package/dist/security/terminal-input-sanitizer.js +70 -0
- package/dist/security/terminal-input-sanitizer.js.map +1 -0
- package/dist/sessions/bootstrap-marker.d.ts +5 -0
- package/dist/sessions/bootstrap-marker.d.ts.map +1 -0
- package/dist/sessions/bootstrap-marker.js +120 -0
- package/dist/sessions/bootstrap-marker.js.map +1 -0
- package/dist/sessions/session-file-repair.d.ts +12 -0
- package/dist/sessions/session-file-repair.d.ts.map +1 -0
- package/dist/sessions/session-file-repair.js +155 -0
- package/dist/sessions/session-file-repair.js.map +1 -0
- package/dist/sessions/session-key-utils.d.ts +54 -0
- package/dist/sessions/session-key-utils.d.ts.map +1 -0
- package/dist/sessions/session-key-utils.js +133 -0
- package/dist/sessions/session-key-utils.js.map +1 -0
- package/dist/sessions/session-manager-factory.d.ts +21 -0
- package/dist/sessions/session-manager-factory.d.ts.map +1 -0
- package/dist/sessions/session-manager-factory.js +142 -0
- package/dist/sessions/session-manager-factory.js.map +1 -0
- package/dist/sessions/session-store.d.ts +154 -0
- package/dist/sessions/session-store.d.ts.map +1 -0
- package/dist/sessions/session-store.js +498 -0
- package/dist/sessions/session-store.js.map +1 -0
- package/dist/sessions/session-write-lock.d.ts +10 -0
- package/dist/sessions/session-write-lock.d.ts.map +1 -0
- package/dist/sessions/session-write-lock.js +167 -0
- package/dist/sessions/session-write-lock.js.map +1 -0
- package/dist/sessions/transcript-reader.d.ts +37 -0
- package/dist/sessions/transcript-reader.d.ts.map +1 -0
- package/dist/sessions/transcript-reader.js +136 -0
- package/dist/sessions/transcript-reader.js.map +1 -0
- package/dist/sessions/transcript-repair.d.ts +16 -0
- package/dist/sessions/transcript-repair.d.ts.map +1 -0
- package/dist/sessions/transcript-repair.js +214 -0
- package/dist/sessions/transcript-repair.js.map +1 -0
- package/dist/shared/global-singleton.d.ts +27 -0
- package/dist/shared/global-singleton.d.ts.map +1 -0
- package/dist/shared/global-singleton.js +35 -0
- package/dist/shared/global-singleton.js.map +1 -0
- package/dist/shared/string-coerce.d.ts +12 -0
- package/dist/shared/string-coerce.d.ts.map +1 -0
- package/dist/shared/string-coerce.js +12 -0
- package/dist/shared/string-coerce.js.map +1 -0
- package/dist/storage/boot.d.ts +28 -0
- package/dist/storage/boot.d.ts.map +1 -0
- package/dist/storage/boot.js +588 -0
- package/dist/storage/boot.js.map +1 -0
- package/dist/storage/config-cache.d.ts +23 -0
- package/dist/storage/config-cache.d.ts.map +1 -0
- package/dist/storage/config-cache.js +58 -0
- package/dist/storage/config-cache.js.map +1 -0
- package/dist/storage/convex/auth-store.d.ts +52 -0
- package/dist/storage/convex/auth-store.d.ts.map +1 -0
- package/dist/storage/convex/auth-store.js +282 -0
- package/dist/storage/convex/auth-store.js.map +1 -0
- package/dist/storage/convex/blob-store.d.ts +20 -0
- package/dist/storage/convex/blob-store.d.ts.map +1 -0
- package/dist/storage/convex/blob-store.js +74 -0
- package/dist/storage/convex/blob-store.js.map +1 -0
- package/dist/storage/convex/channel-store.d.ts +112 -0
- package/dist/storage/convex/channel-store.d.ts.map +1 -0
- package/dist/storage/convex/channel-store.js +267 -0
- package/dist/storage/convex/channel-store.js.map +1 -0
- package/dist/storage/convex/client.d.ts +53 -0
- package/dist/storage/convex/client.d.ts.map +1 -0
- package/dist/storage/convex/client.js +121 -0
- package/dist/storage/convex/client.js.map +1 -0
- package/dist/storage/convex/config-store.d.ts +29 -0
- package/dist/storage/convex/config-store.d.ts.map +1 -0
- package/dist/storage/convex/config-store.js +205 -0
- package/dist/storage/convex/config-store.js.map +1 -0
- package/dist/storage/convex/cron-store.d.ts +86 -0
- package/dist/storage/convex/cron-store.d.ts.map +1 -0
- package/dist/storage/convex/cron-store.js +428 -0
- package/dist/storage/convex/cron-store.js.map +1 -0
- package/dist/storage/convex/exec-approval-store.d.ts +38 -0
- package/dist/storage/convex/exec-approval-store.d.ts.map +1 -0
- package/dist/storage/convex/exec-approval-store.js +147 -0
- package/dist/storage/convex/exec-approval-store.js.map +1 -0
- package/dist/storage/convex/extension-store.d.ts +28 -0
- package/dist/storage/convex/extension-store.d.ts.map +1 -0
- package/dist/storage/convex/extension-store.js +39 -0
- package/dist/storage/convex/extension-store.js.map +1 -0
- package/dist/storage/convex/index.d.ts +35 -0
- package/dist/storage/convex/index.d.ts.map +1 -0
- package/dist/storage/convex/index.js +141 -0
- package/dist/storage/convex/index.js.map +1 -0
- package/dist/storage/convex/instance-store.d.ts +37 -0
- package/dist/storage/convex/instance-store.d.ts.map +1 -0
- package/dist/storage/convex/instance-store.js +88 -0
- package/dist/storage/convex/instance-store.js.map +1 -0
- package/dist/storage/convex/log-store.d.ts +36 -0
- package/dist/storage/convex/log-store.d.ts.map +1 -0
- package/dist/storage/convex/log-store.js +213 -0
- package/dist/storage/convex/log-store.js.map +1 -0
- package/dist/storage/convex/memory-store.d.ts +50 -0
- package/dist/storage/convex/memory-store.d.ts.map +1 -0
- package/dist/storage/convex/memory-store.js +537 -0
- package/dist/storage/convex/memory-store.js.map +1 -0
- package/dist/storage/convex/message-store.d.ts +32 -0
- package/dist/storage/convex/message-store.d.ts.map +1 -0
- package/dist/storage/convex/message-store.js +272 -0
- package/dist/storage/convex/message-store.js.map +1 -0
- package/dist/storage/convex/org-store.d.ts +46 -0
- package/dist/storage/convex/org-store.d.ts.map +1 -0
- package/dist/storage/convex/org-store.js +101 -0
- package/dist/storage/convex/org-store.js.map +1 -0
- package/dist/storage/convex/session-store.d.ts +44 -0
- package/dist/storage/convex/session-store.d.ts.map +1 -0
- package/dist/storage/convex/session-store.js +257 -0
- package/dist/storage/convex/session-store.js.map +1 -0
- package/dist/storage/convex/skill-store.d.ts +49 -0
- package/dist/storage/convex/skill-store.d.ts.map +1 -0
- package/dist/storage/convex/skill-store.js +84 -0
- package/dist/storage/convex/skill-store.js.map +1 -0
- package/dist/storage/convex/subagent-store.d.ts +28 -0
- package/dist/storage/convex/subagent-store.d.ts.map +1 -0
- package/dist/storage/convex/subagent-store.js +83 -0
- package/dist/storage/convex/subagent-store.js.map +1 -0
- package/dist/storage/convex/workspace-store.d.ts +25 -0
- package/dist/storage/convex/workspace-store.d.ts.map +1 -0
- package/dist/storage/convex/workspace-store.js +127 -0
- package/dist/storage/convex/workspace-store.js.map +1 -0
- package/dist/storage/cron-cache.d.ts +17 -0
- package/dist/storage/cron-cache.d.ts.map +1 -0
- package/dist/storage/cron-cache.js +67 -0
- package/dist/storage/cron-cache.js.map +1 -0
- package/dist/storage/encryption.d.ts +69 -0
- package/dist/storage/encryption.d.ts.map +1 -0
- package/dist/storage/encryption.js +389 -0
- package/dist/storage/encryption.js.map +1 -0
- package/dist/storage/factory-reset.d.ts +7 -0
- package/dist/storage/factory-reset.d.ts.map +1 -0
- package/dist/storage/factory-reset.js +34 -0
- package/dist/storage/factory-reset.js.map +1 -0
- package/dist/storage/facts-cache.d.ts +24 -0
- package/dist/storage/facts-cache.d.ts.map +1 -0
- package/dist/storage/facts-cache.js +110 -0
- package/dist/storage/facts-cache.js.map +1 -0
- package/dist/storage/flush.d.ts +4 -0
- package/dist/storage/flush.d.ts.map +1 -0
- package/dist/storage/flush.js +128 -0
- package/dist/storage/flush.js.map +1 -0
- package/dist/storage/instance-admin.d.ts +52 -0
- package/dist/storage/instance-admin.d.ts.map +1 -0
- package/dist/storage/instance-admin.js +90 -0
- package/dist/storage/instance-admin.js.map +1 -0
- package/dist/storage/local/auth-store.d.ts +44 -0
- package/dist/storage/local/auth-store.d.ts.map +1 -0
- package/dist/storage/local/auth-store.js +252 -0
- package/dist/storage/local/auth-store.js.map +1 -0
- package/dist/storage/local/blob-store.d.ts +14 -0
- package/dist/storage/local/blob-store.d.ts.map +1 -0
- package/dist/storage/local/blob-store.js +87 -0
- package/dist/storage/local/blob-store.js.map +1 -0
- package/dist/storage/local/channel-store.d.ts +107 -0
- package/dist/storage/local/channel-store.d.ts.map +1 -0
- package/dist/storage/local/channel-store.js +147 -0
- package/dist/storage/local/channel-store.js.map +1 -0
- package/dist/storage/local/config-store.d.ts +23 -0
- package/dist/storage/local/config-store.d.ts.map +1 -0
- package/dist/storage/local/config-store.js +98 -0
- package/dist/storage/local/config-store.js.map +1 -0
- package/dist/storage/local/cron-store.d.ts +30 -0
- package/dist/storage/local/cron-store.d.ts.map +1 -0
- package/dist/storage/local/cron-store.js +186 -0
- package/dist/storage/local/cron-store.js.map +1 -0
- package/dist/storage/local/exec-approval-store.d.ts +41 -0
- package/dist/storage/local/exec-approval-store.d.ts.map +1 -0
- package/dist/storage/local/exec-approval-store.js +78 -0
- package/dist/storage/local/exec-approval-store.js.map +1 -0
- package/dist/storage/local/extension-store.d.ts +13 -0
- package/dist/storage/local/extension-store.d.ts.map +1 -0
- package/dist/storage/local/extension-store.js +36 -0
- package/dist/storage/local/extension-store.js.map +1 -0
- package/dist/storage/local/file-watcher.d.ts +24 -0
- package/dist/storage/local/file-watcher.d.ts.map +1 -0
- package/dist/storage/local/file-watcher.js +141 -0
- package/dist/storage/local/file-watcher.js.map +1 -0
- package/dist/storage/local/index.d.ts +33 -0
- package/dist/storage/local/index.d.ts.map +1 -0
- package/dist/storage/local/index.js +143 -0
- package/dist/storage/local/index.js.map +1 -0
- package/dist/storage/local/instance-store.d.ts +30 -0
- package/dist/storage/local/instance-store.d.ts.map +1 -0
- package/dist/storage/local/instance-store.js +83 -0
- package/dist/storage/local/instance-store.js.map +1 -0
- package/dist/storage/local/log-store.d.ts +27 -0
- package/dist/storage/local/log-store.d.ts.map +1 -0
- package/dist/storage/local/log-store.js +185 -0
- package/dist/storage/local/log-store.js.map +1 -0
- package/dist/storage/local/memory-store.d.ts +39 -0
- package/dist/storage/local/memory-store.d.ts.map +1 -0
- package/dist/storage/local/memory-store.js +258 -0
- package/dist/storage/local/memory-store.js.map +1 -0
- package/dist/storage/local/message-store.d.ts +27 -0
- package/dist/storage/local/message-store.d.ts.map +1 -0
- package/dist/storage/local/message-store.js +253 -0
- package/dist/storage/local/message-store.js.map +1 -0
- package/dist/storage/local/org-store.d.ts +39 -0
- package/dist/storage/local/org-store.d.ts.map +1 -0
- package/dist/storage/local/org-store.js +155 -0
- package/dist/storage/local/org-store.js.map +1 -0
- package/dist/storage/local/session-store.d.ts +30 -0
- package/dist/storage/local/session-store.d.ts.map +1 -0
- package/dist/storage/local/session-store.js +82 -0
- package/dist/storage/local/session-store.js.map +1 -0
- package/dist/storage/local/skill-store.d.ts +40 -0
- package/dist/storage/local/skill-store.d.ts.map +1 -0
- package/dist/storage/local/skill-store.js +121 -0
- package/dist/storage/local/skill-store.js.map +1 -0
- package/dist/storage/local/subagent-store.d.ts +20 -0
- package/dist/storage/local/subagent-store.d.ts.map +1 -0
- package/dist/storage/local/subagent-store.js +71 -0
- package/dist/storage/local/subagent-store.js.map +1 -0
- package/dist/storage/local/workspace-store.d.ts +22 -0
- package/dist/storage/local/workspace-store.d.ts.map +1 -0
- package/dist/storage/local/workspace-store.js +190 -0
- package/dist/storage/local/workspace-store.js.map +1 -0
- package/dist/storage/migrate.d.ts +64 -0
- package/dist/storage/migrate.d.ts.map +1 -0
- package/dist/storage/migrate.js +581 -0
- package/dist/storage/migrate.js.map +1 -0
- package/dist/storage/runtime-context.d.ts +35 -0
- package/dist/storage/runtime-context.d.ts.map +1 -0
- package/dist/storage/runtime-context.js +145 -0
- package/dist/storage/runtime-context.js.map +1 -0
- package/dist/storage/sentinel.d.ts +28 -0
- package/dist/storage/sentinel.d.ts.map +1 -0
- package/dist/storage/sentinel.js +98 -0
- package/dist/storage/sentinel.js.map +1 -0
- package/dist/storage/session-cache.d.ts +15 -0
- package/dist/storage/session-cache.d.ts.map +1 -0
- package/dist/storage/session-cache.js +81 -0
- package/dist/storage/session-cache.js.map +1 -0
- package/dist/storage/store.d.ts +745 -0
- package/dist/storage/store.d.ts.map +1 -0
- package/dist/storage/store.js +36 -0
- package/dist/storage/store.js.map +1 -0
- package/dist/storage/strict-guard.d.ts +17 -0
- package/dist/storage/strict-guard.d.ts.map +1 -0
- package/dist/storage/strict-guard.js +200 -0
- package/dist/storage/strict-guard.js.map +1 -0
- package/dist/storage/workspace-live-mirror.d.ts +33 -0
- package/dist/storage/workspace-live-mirror.d.ts.map +1 -0
- package/dist/storage/workspace-live-mirror.js +207 -0
- package/dist/storage/workspace-live-mirror.js.map +1 -0
- package/dist/system-prompt/assembler.d.ts +113 -0
- package/dist/system-prompt/assembler.d.ts.map +1 -0
- package/dist/system-prompt/assembler.js +649 -0
- package/dist/system-prompt/assembler.js.map +1 -0
- package/dist/system-prompt/bootstrap-budget.d.ts +22 -0
- package/dist/system-prompt/bootstrap-budget.d.ts.map +1 -0
- package/dist/system-prompt/bootstrap-budget.js +83 -0
- package/dist/system-prompt/bootstrap-budget.js.map +1 -0
- package/dist/system-prompt/cache-boundary.d.ts +13 -0
- package/dist/system-prompt/cache-boundary.d.ts.map +1 -0
- package/dist/system-prompt/cache-boundary.js +56 -0
- package/dist/system-prompt/cache-boundary.js.map +1 -0
- package/dist/system-prompt/cache-stability.d.ts +3 -0
- package/dist/system-prompt/cache-stability.d.ts.map +1 -0
- package/dist/system-prompt/cache-stability.js +18 -0
- package/dist/system-prompt/cache-stability.js.map +1 -0
- package/dist/system-prompt/guidance.d.ts +147 -0
- package/dist/system-prompt/guidance.d.ts.map +1 -0
- package/dist/system-prompt/guidance.js +352 -0
- package/dist/system-prompt/guidance.js.map +1 -0
- package/dist/system-prompt/identity-defaults.d.ts +50 -0
- package/dist/system-prompt/identity-defaults.d.ts.map +1 -0
- package/dist/system-prompt/identity-defaults.js +119 -0
- package/dist/system-prompt/identity-defaults.js.map +1 -0
- package/dist/system-prompt/org/escalation-inbox.d.ts +53 -0
- package/dist/system-prompt/org/escalation-inbox.d.ts.map +1 -0
- package/dist/system-prompt/org/escalation-inbox.js +71 -0
- package/dist/system-prompt/org/escalation-inbox.js.map +1 -0
- package/dist/system-prompt/org/receiver-hint.d.ts +72 -0
- package/dist/system-prompt/org/receiver-hint.d.ts.map +1 -0
- package/dist/system-prompt/org/receiver-hint.js +116 -0
- package/dist/system-prompt/org/receiver-hint.js.map +1 -0
- package/dist/system-prompt/org/render-org-block.d.ts +42 -0
- package/dist/system-prompt/org/render-org-block.d.ts.map +1 -0
- package/dist/system-prompt/org/render-org-block.js +57 -0
- package/dist/system-prompt/org/render-org-block.js.map +1 -0
- package/dist/system-prompt/org/sub-agent-anchor.d.ts +30 -0
- package/dist/system-prompt/org/sub-agent-anchor.d.ts.map +1 -0
- package/dist/system-prompt/org/sub-agent-anchor.js +36 -0
- package/dist/system-prompt/org/sub-agent-anchor.js.map +1 -0
- package/dist/system-prompt/override.d.ts +7 -0
- package/dist/system-prompt/override.d.ts.map +1 -0
- package/dist/system-prompt/override.js +13 -0
- package/dist/system-prompt/override.js.map +1 -0
- package/dist/system-prompt/pi-injection.d.ts +5 -0
- package/dist/system-prompt/pi-injection.d.ts.map +1 -0
- package/dist/system-prompt/pi-injection.js +33 -0
- package/dist/system-prompt/pi-injection.js.map +1 -0
- package/dist/system-prompt/runtime-params.d.ts +34 -0
- package/dist/system-prompt/runtime-params.d.ts.map +1 -0
- package/dist/system-prompt/runtime-params.js +108 -0
- package/dist/system-prompt/runtime-params.js.map +1 -0
- package/dist/system-prompt/sanitize.d.ts +7 -0
- package/dist/system-prompt/sanitize.d.ts.map +1 -0
- package/dist/system-prompt/sanitize.js +31 -0
- package/dist/system-prompt/sanitize.js.map +1 -0
- package/dist/system-prompt/types.d.ts +7 -0
- package/dist/system-prompt/types.d.ts.map +1 -0
- package/dist/system-prompt/types.js +3 -0
- package/dist/system-prompt/types.js.map +1 -0
- package/dist/system-prompt/workspace-loader.d.ts +12 -0
- package/dist/system-prompt/workspace-loader.d.ts.map +1 -0
- package/dist/system-prompt/workspace-loader.js +115 -0
- package/dist/system-prompt/workspace-loader.js.map +1 -0
- package/dist/tideline/advanced.d.ts +25 -0
- package/dist/tideline/advanced.d.ts.map +1 -0
- package/dist/tideline/advanced.js +34 -0
- package/dist/tideline/advanced.js.map +1 -0
- package/dist/tideline/eval.d.ts +19 -0
- package/dist/tideline/eval.d.ts.map +1 -0
- package/dist/tideline/eval.js +24 -0
- package/dist/tideline/eval.js.map +1 -0
- package/dist/tideline/host-ports.standalone.d.ts +49 -0
- package/dist/tideline/host-ports.standalone.d.ts.map +1 -0
- package/dist/tideline/host-ports.standalone.js +61 -0
- package/dist/tideline/host-ports.standalone.js.map +1 -0
- package/dist/tideline/index.d.ts +34 -0
- package/dist/tideline/index.d.ts.map +1 -0
- package/dist/tideline/index.js +42 -0
- package/dist/tideline/index.js.map +1 -0
- package/dist/tui/approval-prompt.d.ts +73 -0
- package/dist/tui/approval-prompt.d.ts.map +1 -0
- package/dist/tui/approval-prompt.js +272 -0
- package/dist/tui/approval-prompt.js.map +1 -0
- package/dist/tui/client.d.ts +89 -0
- package/dist/tui/client.d.ts.map +1 -0
- package/dist/tui/client.js.map +1 -0
- package/dist/ui/brand-frames-cli.d.ts +19 -0
- package/dist/ui/brand-frames-cli.d.ts.map +1 -0
- package/dist/ui/brand-frames-cli.js +8 -13
- package/dist/ui/brand-frames-cli.js.map +1 -0
- package/dist/ui/brand.d.ts +41 -0
- package/dist/ui/brand.d.ts.map +1 -0
- package/dist/ui/brand.js +28 -6
- package/dist/ui/brand.js.map +1 -0
- package/dist/ui/editor.d.ts +30 -0
- package/dist/ui/editor.d.ts.map +1 -0
- package/dist/ui/editor.js +73 -0
- package/dist/ui/editor.js.map +1 -0
- package/dist/ui/format-session.d.ts +68 -0
- package/dist/ui/format-session.d.ts.map +1 -0
- package/dist/ui/format-session.js +181 -0
- package/dist/ui/format-session.js.map +1 -0
- package/dist/ui/markdown.d.ts +48 -0
- package/dist/ui/markdown.d.ts.map +1 -0
- package/dist/ui/markdown.js +60 -0
- package/dist/ui/markdown.js.map +1 -0
- package/dist/ui/onboard-storage-mode.d.ts +17 -0
- package/dist/ui/onboard-storage-mode.d.ts.map +1 -0
- package/dist/ui/onboard-storage-mode.js +638 -0
- package/dist/ui/onboard-storage-mode.js.map +1 -0
- package/dist/ui/onboarding.d.ts +97 -0
- package/dist/ui/onboarding.d.ts.map +1 -0
- package/dist/ui/onboarding.js +259 -111
- package/dist/ui/onboarding.js.map +1 -0
- package/dist/ui/searchable-select.d.ts +48 -0
- package/dist/ui/searchable-select.d.ts.map +1 -0
- package/dist/ui/searchable-select.js +108 -0
- package/dist/ui/searchable-select.js.map +1 -0
- package/dist/ui/syntax-theme.d.ts +30 -0
- package/dist/ui/syntax-theme.d.ts.map +1 -0
- package/dist/ui/syntax-theme.js +72 -0
- package/dist/ui/syntax-theme.js.map +1 -0
- package/dist/ui/terminal-cleanup.d.ts +46 -0
- package/dist/ui/terminal-cleanup.d.ts.map +1 -0
- package/dist/ui/terminal-cleanup.js +17 -5
- package/dist/ui/terminal-cleanup.js.map +1 -0
- package/dist/ui/theme.d.ts +21 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +66 -2
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/tool-result.d.ts +47 -0
- package/dist/ui/tool-result.d.ts.map +1 -0
- package/dist/ui/tool-result.js +100 -0
- package/dist/ui/tool-result.js.map +1 -0
- package/dist/utils/delivery-context.d.ts +50 -0
- package/dist/utils/delivery-context.d.ts.map +1 -0
- package/dist/utils/delivery-context.js +82 -0
- package/dist/utils/delivery-context.js.map +1 -0
- package/dist/utils/message-channel.d.ts +60 -0
- package/dist/utils/message-channel.d.ts.map +1 -0
- package/dist/utils/message-channel.js +103 -0
- package/dist/utils/message-channel.js.map +1 -0
- package/dist/utils/string-coerce.d.ts +50 -0
- package/dist/utils/string-coerce.d.ts.map +1 -0
- package/dist/utils/string-coerce.js +101 -0
- package/dist/utils/string-coerce.js.map +1 -0
- package/dist/version.d.ts +20 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +54 -0
- package/dist/version.js.map +1 -0
- package/dist/workspace/bootstrap.d.ts +12 -0
- package/dist/workspace/bootstrap.d.ts.map +1 -0
- package/dist/workspace/bootstrap.js +123 -0
- package/dist/workspace/bootstrap.js.map +1 -0
- package/dist/workspace/fs-utils.d.ts +2 -0
- package/dist/workspace/fs-utils.d.ts.map +1 -0
- package/dist/workspace/fs-utils.js +14 -0
- package/dist/workspace/fs-utils.js.map +1 -0
- package/dist/workspace/git-init.d.ts +5 -0
- package/dist/workspace/git-init.d.ts.map +1 -0
- package/dist/workspace/git-init.js +71 -0
- package/dist/workspace/git-init.js.map +1 -0
- package/dist/workspace/state.d.ts +13 -0
- package/dist/workspace/state.d.ts.map +1 -0
- package/dist/workspace/state.js +128 -0
- package/dist/workspace/state.js.map +1 -0
- package/dist/workspace/template-loader.d.ts +15 -0
- package/dist/workspace/template-loader.d.ts.map +1 -0
- package/dist/workspace/template-loader.js +214 -0
- package/dist/workspace/template-loader.js.map +1 -0
- package/package.json +173 -68
- package/scripts/build-done.mjs +125 -0
- package/scripts/run-brigade.mjs +208 -0
- package/skills/1password/SKILL.md +70 -0
- package/skills/1password/references/cli-examples.md +29 -0
- package/skills/1password/references/get-started.md +17 -0
- package/skills/apple-notes/SKILL.md +77 -0
- package/skills/apple-reminders/SKILL.md +118 -0
- package/skills/bear-notes/SKILL.md +107 -0
- package/skills/blogwatcher/SKILL.md +69 -0
- package/skills/blucli/SKILL.md +47 -0
- package/skills/bluebubbles/SKILL.md +136 -0
- package/skills/camsnap/SKILL.md +45 -0
- package/skills/canvas/SKILL.md +204 -0
- package/skills/coding-agent/SKILL.md +316 -0
- package/skills/discord/SKILL.md +197 -0
- package/skills/eightctl/SKILL.md +50 -0
- package/skills/gemini/SKILL.md +43 -0
- package/skills/gh-issues/SKILL.md +885 -0
- package/skills/gifgrep/SKILL.md +79 -0
- package/skills/git-commit/SKILL.md +40 -0
- package/skills/github/SKILL.md +163 -0
- package/skills/gog/SKILL.md +116 -0
- package/skills/goplaces/SKILL.md +52 -0
- package/skills/healthcheck/SKILL.md +245 -0
- package/skills/himalaya/SKILL.md +257 -0
- package/skills/himalaya/references/configuration.md +184 -0
- package/skills/himalaya/references/message-composition.md +199 -0
- package/skills/imsg/SKILL.md +122 -0
- package/skills/lead-scout/SKILL.md +46 -0
- package/skills/mcporter/SKILL.md +61 -0
- package/skills/model-usage/SKILL.md +69 -0
- package/skills/nano-pdf/SKILL.md +38 -0
- package/skills/node-connect/SKILL.md +142 -0
- package/skills/notion/SKILL.md +174 -0
- package/skills/oauth-setup/SKILL.md +55 -0
- package/skills/obsidian/SKILL.md +81 -0
- package/skills/openai-whisper/SKILL.md +38 -0
- package/skills/openai-whisper-api/SKILL.md +62 -0
- package/skills/openai-whisper-api/scripts/transcribe.sh +88 -0
- package/skills/openhue/SKILL.md +112 -0
- package/skills/oracle/SKILL.md +125 -0
- package/skills/ordercli/SKILL.md +78 -0
- package/skills/peekaboo/SKILL.md +190 -0
- package/skills/sag/SKILL.md +87 -0
- package/skills/session-logs/SKILL.md +151 -0
- package/skills/share-skills/SKILL.md +72 -0
- package/skills/sherpa-onnx-tts/SKILL.md +109 -0
- package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
- package/skills/skill-creator/SKILL.md +372 -0
- package/skills/skill-creator/license.txt +202 -0
- package/skills/skill-creator/scripts/init_skill.py +378 -0
- package/skills/skill-creator/scripts/package_skill.py +139 -0
- package/skills/skill-creator/scripts/quick_validate.py +159 -0
- package/skills/skill-creator/scripts/test_package_skill.py +160 -0
- package/skills/skill-creator/scripts/test_quick_validate.py +72 -0
- package/skills/slack/SKILL.md +144 -0
- package/skills/songsee/SKILL.md +49 -0
- package/skills/sonoscli/SKILL.md +65 -0
- package/skills/spotify-player/SKILL.md +64 -0
- package/skills/summarize/SKILL.md +87 -0
- package/skills/taskflow/SKILL.md +149 -0
- package/skills/taskflow-inbox-triage/SKILL.md +119 -0
- package/skills/things-mac/SKILL.md +86 -0
- package/skills/tmux/SKILL.md +170 -0
- package/skills/tmux/scripts/find-sessions.sh +112 -0
- package/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/skills/trello/SKILL.md +108 -0
- package/skills/video-frames/SKILL.md +46 -0
- package/skills/video-frames/scripts/frame.sh +81 -0
- package/skills/voice-call/SKILL.md +45 -0
- package/skills/wacli/SKILL.md +72 -0
- package/skills/weather/SKILL.md +129 -0
- package/skills/xurl/SKILL.md +461 -0
- package/templates/workspace/AGENTS.md +223 -0
- package/templates/workspace/BOOTSTRAP.md +64 -0
- package/templates/workspace/HEARTBEAT.md +15 -0
- package/templates/workspace/IDENTITY.md +31 -0
- package/templates/workspace/SOUL.md +47 -0
- package/templates/workspace/TOOLS.md +48 -0
- package/templates/workspace/USER.md +25 -0
- package/CHANGELOG.md +0 -41
- package/SECURITY.md +0 -208
- package/assets/brigade-wordmark.png +0 -0
- package/dist/cli/chat-cmd.js +0 -191
- package/dist/cli/config-cmd.js +0 -171
- package/dist/cli/connect-cmd.js +0 -487
- package/dist/cli/doctor-cmd.js +0 -387
- package/dist/cli/gateway-cmd.js +0 -155
- package/dist/cli.js +0 -328
- package/dist/core/agent.js +0 -1123
- package/dist/core/auth-label.js +0 -147
- package/dist/core/cli-error.js +0 -94
- package/dist/core/error-classifier.js +0 -354
- package/dist/core/provider-payload-mutators.js +0 -517
- package/dist/core/provider-quirks.js +0 -285
- package/dist/core/smart-compaction.js +0 -209
- package/dist/core/system-prompt-defaults.js +0 -264
- package/dist/core/system-prompt-guidance.js +0 -271
- package/dist/index.js +0 -32
- package/dist/ui/brand-frames.js +0 -36
- package/dist/ui/chat.js +0 -1008
|
@@ -0,0 +1,1938 @@
|
|
|
1
|
+
// Brigade's wrapper around the Pi SDK agent loop. Single-turn driver:
|
|
2
|
+
// 1. Resolve session (key → id → JSONL transcript path).
|
|
3
|
+
// 2. Build a Pi AuthStorage from the on-disk auth-profiles store (api_key
|
|
4
|
+
// profiles only; oauth/token shapes are queued for the next layer).
|
|
5
|
+
// 3. Construct a ModelRegistry over auth + models.json. Pi merges in its
|
|
6
|
+
// built-in catalog so an empty models.json still resolves known
|
|
7
|
+
// Anthropic / OpenAI / Google / Ollama models.
|
|
8
|
+
// 4. Open a SessionManager at <agentDir>/sessions/<sessionId>.jsonl —
|
|
9
|
+
// Pi creates the file lazily on first append.
|
|
10
|
+
// 5. createAgentSession with the resolved model + persona-aware
|
|
11
|
+
// DefaultResourceLoader.
|
|
12
|
+
// 6. Assemble the persona prompt and pin it via the three-write hack
|
|
13
|
+
// (state.systemPrompt + _baseSystemPrompt + _rebuildSystemPrompt) so
|
|
14
|
+
// Pi's tool-list rebuild can't clobber the persona on turn 2+.
|
|
15
|
+
// 7. session.prompt(userMessage). Defensive settle wait with a 30s
|
|
16
|
+
// budget guards against runaway compactions.
|
|
17
|
+
// 8. Return the last assistant message text + raw message array.
|
|
18
|
+
//
|
|
19
|
+
// Pi 0.50+ removed the `discover*` convenience helpers, so brigade builds
|
|
20
|
+
// AuthStorage directly via the class's `inMemory` factory and ModelRegistry
|
|
21
|
+
// via its `create` static (with a `new` fallback for older minors).
|
|
22
|
+
import { AuthStorage, DefaultResourceLoader, ModelRegistry, createAgentSession, } from "@mariozechner/pi-coding-agent";
|
|
23
|
+
import fs from "node:fs";
|
|
24
|
+
import { resolveAgentDir, resolveAgentWorkspaceDir, resolveAuthProfilesPath, resolveModelsPath, } from "../config/paths.js";
|
|
25
|
+
import { defaultSessionKey, resolveOrCreateSession, } from "../sessions/session-store.js";
|
|
26
|
+
import { awaitTranscriptFlush, openSessionManagerForAgent, } from "../sessions/session-manager-factory.js";
|
|
27
|
+
import { readConfigOrInit } from "../config/io.js";
|
|
28
|
+
import { discoverEligibleSkills } from "./skills/index.js";
|
|
29
|
+
import { BUNDLED_MODULES } from "./extensions/index.js";
|
|
30
|
+
import { getActiveChannelManager } from "./channels/active-manager.js";
|
|
31
|
+
import { getOrLoadExtensionRegistry } from "./extensions/registry-cache.js";
|
|
32
|
+
import { assembleSystemPrompt } from "../system-prompt/assembler.js";
|
|
33
|
+
import { loadHeartbeatFile, loadWorkspaceContextFiles, } from "../system-prompt/workspace-loader.js";
|
|
34
|
+
import { resolveSystemPromptOverride } from "../system-prompt/override.js";
|
|
35
|
+
import { resolveRuntimeParams } from "../system-prompt/runtime-params.js";
|
|
36
|
+
import { applyPersonaOverrideToSession } from "../system-prompt/pi-injection.js";
|
|
37
|
+
import { deriveOrgDisplayGraph } from "./org/derive-graph.js";
|
|
38
|
+
import { renderSubAgentAnchor } from "../system-prompt/org/sub-agent-anchor.js";
|
|
39
|
+
import { bootstrapWorkspace } from "../workspace/bootstrap.js";
|
|
40
|
+
import { evaluateBootstrapPhase, markSetupCompleted, } from "../workspace/state.js";
|
|
41
|
+
import { hasDeliveredBootstrapToSession, markBootstrapDeliveredToSession, } from "../sessions/bootstrap-marker.js";
|
|
42
|
+
import { createSubsystemLogger } from "../logging/subsystem-logger.js";
|
|
43
|
+
import { runWithRetry } from "./retry-policy.js";
|
|
44
|
+
import { scrubAnthropicRefusalSentinel } from "./error-classifier.js";
|
|
45
|
+
import { cleanProviderError } from "../core/model-caps.js";
|
|
46
|
+
import { resolveModelNeverMiss } from "./model-resolution.js";
|
|
47
|
+
import { buildAutoRecallBlock, resolveAutoRecallOrigin } from "./memory/auto-recall.js";
|
|
48
|
+
import { runPreCompactionExtraction } from "./memory/extract.js";
|
|
49
|
+
import { resolveActiveMemoryCapability } from "./memory/plugin-runtime.js";
|
|
50
|
+
import { buildBrigadeTransformContext } from "./payload-mutators.js";
|
|
51
|
+
import { drainPendingSystemEvents, formatPendingEventsPrefix, } from "./pending-system-events.js";
|
|
52
|
+
import { drainFormattedSessionEvents, inspectPendingSessionEvents, } from "./session-event-prompt.js";
|
|
53
|
+
// Per-turn session-tool access policy resolution. The flatten + org-graph-
|
|
54
|
+
// vs-flat-allow logic lives in `resolve-access.ts` so `sessions_send` can
|
|
55
|
+
// re-resolve it live (honouring a mid-run manage_access change) with the
|
|
56
|
+
// exact same derivation this build uses.
|
|
57
|
+
import { resolveSessionAccessPolicy } from "./tools/sessions/resolve-access.js";
|
|
58
|
+
import { wrapStreamFnWithPayloadMutations } from "./payload-mutators.js";
|
|
59
|
+
import { repairSessionFileIfNeeded } from "../sessions/session-file-repair.js";
|
|
60
|
+
import { acquireSessionWriteLock } from "../sessions/session-write-lock.js";
|
|
61
|
+
import { runWithContentQualityRetry } from "./content-quality-retry.js";
|
|
62
|
+
import { runWithThinkingFallback } from "./thinking-fallback.js";
|
|
63
|
+
import { assembleBrigadeToolset, composeBrigadeBeforeToolCall, } from "./session-wiring.js";
|
|
64
|
+
import { buildSessionContext } from "./session-context.js";
|
|
65
|
+
import { getSubagentDepthFromSessionKey } from "./subagent-policy.js";
|
|
66
|
+
import { getSpawnedKeysForSession } from "./subagent-registry.js";
|
|
67
|
+
import { emitAgentEvent } from "./agent-event-bus.js";
|
|
68
|
+
import { randomUUID } from "node:crypto";
|
|
69
|
+
import { evaluateCompactionDecision } from "./smart-compaction.js";
|
|
70
|
+
import { resolveToolSummary } from "./tool-summaries.js";
|
|
71
|
+
import { runWithModelFallback, } from "./model-fallback.js";
|
|
72
|
+
import { loadProfileStateLocked, recordProfileFailureLocked, recordProfileSuccessLocked, } from "../auth/profile-cooldown.js";
|
|
73
|
+
import { PROVIDERS } from "../providers/catalog.js";
|
|
74
|
+
import { orderProfilesForSelection } from "../auth/profile-cooldown.js";
|
|
75
|
+
import { readProfiles } from "../auth/profiles.js";
|
|
76
|
+
import { tryGetRuntimeContext } from "../storage/runtime-context.js";
|
|
77
|
+
import { wrapStreamFnWithIdleTimeout, wrapStreamFnWithStopReasonRecovery, wrapStreamFnWithToolCallRepair, } from "./stream-wrappers.js";
|
|
78
|
+
const log = createSubsystemLogger("loop/turn");
|
|
79
|
+
// Default idle-timeout for a streaming provider response. Bypassed by setting
|
|
80
|
+
// `BRIGADE_LLM_IDLE_TIMEOUT_SECONDS=0`. Tuned to 90s — comfortably above the
|
|
81
|
+
// slowest Anthropic Opus reasoning warmup, well below the limit at which a
|
|
82
|
+
// hung connection wastes a session's worth of tokens of headroom.
|
|
83
|
+
const DEFAULT_LLM_IDLE_TIMEOUT_MS = 90_000;
|
|
84
|
+
function resolveIdleTimeoutMs() {
|
|
85
|
+
const raw = process.env.BRIGADE_LLM_IDLE_TIMEOUT_SECONDS?.trim();
|
|
86
|
+
if (!raw)
|
|
87
|
+
return DEFAULT_LLM_IDLE_TIMEOUT_MS;
|
|
88
|
+
const n = Number(raw);
|
|
89
|
+
if (!Number.isFinite(n) || n < 0)
|
|
90
|
+
return DEFAULT_LLM_IDLE_TIMEOUT_MS;
|
|
91
|
+
return Math.floor(n * 1000);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Compute the effective bootstrap phase for one agent turn, given:
|
|
95
|
+
* - the workspace-level phase (whether `setupCompletedAt` is stamped),
|
|
96
|
+
* - whether THIS session has already received the bootstrap context,
|
|
97
|
+
* - whether the sender is the operator (owner).
|
|
98
|
+
*
|
|
99
|
+
* Truth table (the only one that matters for the user-visible behaviour):
|
|
100
|
+
*
|
|
101
|
+
* workspacePhase sessionHasBootstrap senderIsOwner → effective
|
|
102
|
+
* ---------------- ------------------- ------------- ----------
|
|
103
|
+
* "first-turn" false true → "first-turn" (operator's first conversation; do the BOOTSTRAP intro)
|
|
104
|
+
* "first-turn" true true → "in-progress" (operator continuing; no re-nudge)
|
|
105
|
+
* "first-turn" any false → "in-progress" (NON-OWNER never sees BOOTSTRAP — fixes the "friend gets identity onboarding" bug)
|
|
106
|
+
* "in-progress" any any → "in-progress"
|
|
107
|
+
* "complete" any any → "complete"
|
|
108
|
+
*
|
|
109
|
+
* Pure — no I/O — so the gate is unit-testable. Lifted out of the runSingleTurn
|
|
110
|
+
* body specifically so the regression "approved peer triggers the operator's
|
|
111
|
+
* onboarding ritual" can be locked at the helper level.
|
|
112
|
+
*/
|
|
113
|
+
export function resolveEffectiveBootstrapPhase(args) {
|
|
114
|
+
// BOOTSTRAP is an operator-onboarding flow (see templates/workspace/BOOTSTRAP.md
|
|
115
|
+
// — "You just woke up. Who am I? Who are you?"). Approved peers must NEVER
|
|
116
|
+
// see the FIRST-TURN nudge — collapse to in-progress for non-owners only
|
|
117
|
+
// when the workspace is still in first-turn. `in-progress` and `complete`
|
|
118
|
+
// are already peer-safe so they pass through unchanged.
|
|
119
|
+
if (!args.senderIsOwner && args.workspacePhase === "first-turn") {
|
|
120
|
+
return "in-progress";
|
|
121
|
+
}
|
|
122
|
+
// Operator path (or peer on a non-first-turn workspace) — apply the existing
|
|
123
|
+
// session-marker gate so the synthetic nudge fires only on the operator's
|
|
124
|
+
// first session-turn, not on every continuing-session turn just because
|
|
125
|
+
// BOOTSTRAP.md is still on disk.
|
|
126
|
+
if (args.workspacePhase === "first-turn" && args.sessionAlreadyHasBootstrap) {
|
|
127
|
+
return "in-progress";
|
|
128
|
+
}
|
|
129
|
+
return args.workspacePhase;
|
|
130
|
+
}
|
|
131
|
+
export async function runSingleTurn(args) {
|
|
132
|
+
const agentId = args.agentId;
|
|
133
|
+
const sessionKey = args.sessionKey ?? defaultSessionKey(agentId);
|
|
134
|
+
const agentDir = resolveAgentDir(agentId);
|
|
135
|
+
const workspaceDir = resolveAgentWorkspaceDir(agentId, args.workspaceDir);
|
|
136
|
+
// Default Pi's cwd to the agent's workspace dir. Relative tool paths
|
|
137
|
+
// now resolve into the persona directory naturally — `write({path:
|
|
138
|
+
// "USER.md"})` lands at `<workspace>/USER.md` without any path-jail
|
|
139
|
+
// guard. Absolute paths are passed through unchanged so the agent can
|
|
140
|
+
// still reach project files when the operator gives it one.
|
|
141
|
+
const cwd = args.cwd ?? workspaceDir;
|
|
142
|
+
const modelsFile = resolveModelsPath(agentId);
|
|
143
|
+
const authProfilesPath = resolveAuthProfilesPath(agentId);
|
|
144
|
+
const resolved = resolveOrCreateSession({
|
|
145
|
+
agentId,
|
|
146
|
+
sessionKey,
|
|
147
|
+
overrides: {
|
|
148
|
+
provider: args.provider,
|
|
149
|
+
modelId: args.modelId,
|
|
150
|
+
// Primitive #6 — persist sub-agent metadata on the entry so post-crash
|
|
151
|
+
// forensics can identify children + walk the ancestry chain. Only set
|
|
152
|
+
// when this turn IS a sub-agent run (top-level turns leave it unset
|
|
153
|
+
// and the open index signature on SessionEntry tolerates `undefined`).
|
|
154
|
+
...(args.subagentMetadata !== undefined ? { subagent: args.subagentMetadata } : {}),
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
// Profile cooldown gate. The on-disk profile-state.json tracks per-profile
|
|
158
|
+
// failure history, cooldown windows, and disabled-until timestamps. We
|
|
159
|
+
// sweep expired windows up-front so a profile that was rate-limited an
|
|
160
|
+
// hour ago is eligible again now, then pass the eligibility filter to
|
|
161
|
+
// the credential-map builder so cooled profiles don't get handed to Pi.
|
|
162
|
+
//
|
|
163
|
+
// Locked variant: serialises the load+sweep against concurrent
|
|
164
|
+
// markProfileFailure/Success writes for the SAME agent. Two `brigade
|
|
165
|
+
// agent` runs hitting the same agentId from the same process can no
|
|
166
|
+
// longer interleave their snapshots — each waits for the previous
|
|
167
|
+
// mark to land on disk before reading.
|
|
168
|
+
let cooldownState = await loadProfileStateLocked(agentId);
|
|
169
|
+
const authBuild = buildAuthStorage(authProfilesPath, {
|
|
170
|
+
cooldownState,
|
|
171
|
+
provider: args.provider,
|
|
172
|
+
modelId: args.modelId,
|
|
173
|
+
}, agentId);
|
|
174
|
+
const authStorage = authBuild.storage;
|
|
175
|
+
const selectedProfileId = authBuild.selectedProfileId;
|
|
176
|
+
const modelRegistry = buildModelRegistry(authStorage, modelsFile);
|
|
177
|
+
// ModelRegistry.find returns undefined when the provider+modelId pair isn't
|
|
178
|
+
// registered. Surface a clear error so the user knows to seed models.json
|
|
179
|
+
// (or wire `brigade auth login` once that command lands).
|
|
180
|
+
//
|
|
181
|
+
// Pi version drift guard: if a future Pi minor renames or removes `find`,
|
|
182
|
+
// throw a curated error rather than letting a raw `TypeError: undefined
|
|
183
|
+
// is not a function` surface from inside Pi.
|
|
184
|
+
const registryAsFinder = modelRegistry;
|
|
185
|
+
if (typeof registryAsFinder.find !== "function") {
|
|
186
|
+
throw new Error("Pi ModelRegistry.find is not a function — likely a Pi SDK version drift. " +
|
|
187
|
+
"Brigade was built against the 0.70.x ModelRegistry surface. " +
|
|
188
|
+
"Pin `@mariozechner/pi-coding-agent` to a known-compatible version, or " +
|
|
189
|
+
"update brigade's agent-loop to match the new Pi API.");
|
|
190
|
+
}
|
|
191
|
+
let model = registryAsFinder.find(args.provider, args.modelId);
|
|
192
|
+
// Never-miss resolution. On a static miss, discover or synthesize a
|
|
193
|
+
// usable Model: Ollama re-queries /api/tags; cloud providers hit their
|
|
194
|
+
// /models endpoint for accurate metadata and synthesize from a
|
|
195
|
+
// catalogued template (inheriting api/baseUrl/auth). See
|
|
196
|
+
// model-resolution.ts.
|
|
197
|
+
if (!model) {
|
|
198
|
+
model = await resolveModelNeverMiss({
|
|
199
|
+
modelRegistry,
|
|
200
|
+
provider: args.provider,
|
|
201
|
+
modelId: args.modelId,
|
|
202
|
+
modelsFile,
|
|
203
|
+
authStorage,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
if (!model) {
|
|
207
|
+
throw new Error(`Model not registered: provider=${args.provider} model=${args.modelId}.\n` +
|
|
208
|
+
` • Pi's built-in catalog covers known Anthropic/OpenAI/Google/Ollama models;\n` +
|
|
209
|
+
` if yours isn't listed, append an entry to ${modelsFile}\n` +
|
|
210
|
+
` (one object under .providers.<provider>.models[]).\n` +
|
|
211
|
+
` • For local Ollama: run \`ollama pull <model>\` first.\n` +
|
|
212
|
+
` • Verify your auth profile is configured: ` +
|
|
213
|
+
`\`cat ${resolveAuthProfilesPath(args.agentId)}\``);
|
|
214
|
+
}
|
|
215
|
+
// Cross-process lock to prevent two `brigade agent` runs from interleaving
|
|
216
|
+
// appends to the same JSONL. The lock is PID-tagged with a 10-min stale
|
|
217
|
+
// window, so a crashed peer doesn't block us forever; the timeout below
|
|
218
|
+
// surfaces an honest error if a real peer is genuinely active.
|
|
219
|
+
const sessionLock = await acquireSessionWriteLock({
|
|
220
|
+
sessionFile: resolved.transcriptPath,
|
|
221
|
+
signal: args.signal,
|
|
222
|
+
timeoutMs: 30_000,
|
|
223
|
+
});
|
|
224
|
+
let result;
|
|
225
|
+
try {
|
|
226
|
+
// Repair any malformed JSONL lines in the transcript before Pi opens it.
|
|
227
|
+
// A power-loss / SIGKILL during a previous append can leave a partial
|
|
228
|
+
// last line that throws on JSON.parse — without this pass the next run
|
|
229
|
+
// would crash on session open with no obvious cause. The repair is
|
|
230
|
+
// idempotent + atomic (writes a `.bak-<pid>-<ts>` snapshot first), so a
|
|
231
|
+
// failed repair leaves the original file intact.
|
|
232
|
+
const repairReport = await repairSessionFileIfNeeded({
|
|
233
|
+
sessionFile: resolved.transcriptPath,
|
|
234
|
+
});
|
|
235
|
+
if (repairReport.repaired) {
|
|
236
|
+
log.warn("session file repaired before open", {
|
|
237
|
+
sessionId: resolved.sessionId,
|
|
238
|
+
droppedLines: repairReport.droppedLines,
|
|
239
|
+
backupPath: repairReport.backupPath,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
result = await runSingleTurnLocked({
|
|
243
|
+
args,
|
|
244
|
+
agentId,
|
|
245
|
+
agentDir,
|
|
246
|
+
cwd,
|
|
247
|
+
workspaceDir,
|
|
248
|
+
modelsFile,
|
|
249
|
+
authProfilesPath,
|
|
250
|
+
resolved,
|
|
251
|
+
cooldownState,
|
|
252
|
+
authStorage,
|
|
253
|
+
modelRegistry,
|
|
254
|
+
selectedProfileId,
|
|
255
|
+
model,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
// Convex mode: drain the transcript write-behind queue before the lock
|
|
260
|
+
// releases — the next turn's readTranscript must see this turn's rows.
|
|
261
|
+
// Filesystem mode resolves immediately (Pi appended inline). Bounded so
|
|
262
|
+
// a wedged backend can't hold the session lock hostage.
|
|
263
|
+
try {
|
|
264
|
+
await Promise.race([
|
|
265
|
+
awaitTranscriptFlush(),
|
|
266
|
+
new Promise((resolve) => setTimeout(resolve, 5_000).unref?.()),
|
|
267
|
+
]);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
/* flush failures already logged by the factory */
|
|
271
|
+
}
|
|
272
|
+
await sessionLock.release();
|
|
273
|
+
}
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
async function runSingleTurnLocked(p) {
|
|
277
|
+
const { args, agentId, agentDir, cwd, workspaceDir, resolved, model, authStorage, modelRegistry } = p;
|
|
278
|
+
let cooldownState = p.cooldownState;
|
|
279
|
+
const selectedProfileId = p.selectedProfileId;
|
|
280
|
+
// Filesystem mode: SessionManager.open creates the JSONL on first write;
|
|
281
|
+
// passing the canonical transcript path keeps Pi and brigade aligned on
|
|
282
|
+
// filenames. Convex mode: an inMemory() manager pre-seeded from the
|
|
283
|
+
// sessionTranscriptRecords table whose appends flush to Convex — the
|
|
284
|
+
// factory owns that dispatch (src/sessions/session-manager-factory.ts).
|
|
285
|
+
const sessionManager = await openSessionManagerForAgent({
|
|
286
|
+
agentId,
|
|
287
|
+
sessionId: resolved.sessionId,
|
|
288
|
+
transcriptPath: resolved.transcriptPath,
|
|
289
|
+
});
|
|
290
|
+
// Anthropic models are the only family today that enforce a hard
|
|
291
|
+
// cache_control breakpoint cap (Anthropic accepts ≤4). Run the sweep
|
|
292
|
+
// unconditionally — it's a safe no-op for non-Anthropic providers because
|
|
293
|
+
// their messages don't carry cache_control blocks. The scrubber pass
|
|
294
|
+
// (refusal sentinel) always runs.
|
|
295
|
+
const transformContext = buildBrigadeTransformContext({
|
|
296
|
+
applyAnthropicSweep: args.provider === "anthropic" || args.provider.startsWith("anthropic"),
|
|
297
|
+
// H5 — pass the active model so the message-level provider quirks
|
|
298
|
+
// (Mistral tool-id, OpenAI-Responses reasoning-pair, Anthropic
|
|
299
|
+
// thinking-strip) gate on the active provider. `model` is the resolved
|
|
300
|
+
// model object from `resolveModelNeverMiss` — falsy here means the
|
|
301
|
+
// quirks run in strip-everything defensive mode (safe for the wrap
|
|
302
|
+
// chain but more aggressive).
|
|
303
|
+
...(model ? { activeModel: model } : {}),
|
|
304
|
+
}, {
|
|
305
|
+
onTranscriptRepaired: (info) => {
|
|
306
|
+
log.warn("transcript paired-repair fired", {
|
|
307
|
+
sessionId: resolved.sessionId,
|
|
308
|
+
syntheticAdded: info.syntheticToolResultsAdded,
|
|
309
|
+
orphansDropped: info.orphanedToolResultsDropped,
|
|
310
|
+
});
|
|
311
|
+
},
|
|
312
|
+
});
|
|
313
|
+
// Primitive #5 (Skills): discover the skills eligible for this turn — a
|
|
314
|
+
// cheap synchronous scan of the bundled + workspace roots, OS/binary/env
|
|
315
|
+
// filtered. The rendered <available_skills> block (if any) is injected into
|
|
316
|
+
// the assembled persona prompt below; the model loads a skill's body on
|
|
317
|
+
// demand via the existing `read` tool. `capabilities.skills` gates the
|
|
318
|
+
// `## Skills` guidance section so it only appears when a skill is available.
|
|
319
|
+
// Read the config ONCE per turn and thread it to both skill discovery and
|
|
320
|
+
// the persona assembler — avoids a duplicate brigade.json read and any
|
|
321
|
+
// chance the two reads disagree if the file is rewritten mid-turn.
|
|
322
|
+
const turnConfig = readConfigOrInit();
|
|
323
|
+
const skillDiscovery = discoverEligibleSkills({ workspaceDir, config: turnConfig, agentId });
|
|
324
|
+
// Extension layer: load Brigade modules (bundled now; user `~/.brigade/extensions`
|
|
325
|
+
// later) into a registry. Agent-level registrations (tools/hooks/commands) are
|
|
326
|
+
// replayed into THIS Pi session via an ExtensionFactory; product-level ones
|
|
327
|
+
// (channels/voice/…) are consumed by the gateway. We pass our own resource
|
|
328
|
+
// loader, so createAgentSession won't reload it — we MUST reload() ourselves or
|
|
329
|
+
// getExtensions() stays empty. The loader runs ONLY our factory: every other
|
|
330
|
+
// resource type is opted out because Brigade owns skills/prompts/themes/context
|
|
331
|
+
// itself and the persona pin owns the system prompt.
|
|
332
|
+
//
|
|
333
|
+
// Loaded BEFORE the toolset assembly because the memory capability resolver
|
|
334
|
+
// (`extensions.slots.memory` slot pin) consults the registry — a plugin-
|
|
335
|
+
// registered backend has to be in `registry.memoryCapabilities` before we
|
|
336
|
+
// build the memory tools so `recall_memory` / `write_memory` route through
|
|
337
|
+
// it on this very turn.
|
|
338
|
+
const extensionRegistry = await getOrLoadExtensionRegistry({
|
|
339
|
+
modules: BUNDLED_MODULES,
|
|
340
|
+
meta: { agentId, workspaceDir, cwd, config: turnConfig },
|
|
341
|
+
});
|
|
342
|
+
// Resolve the active memory backend — plugin if `extensions.slots.memory`
|
|
343
|
+
// pins one, otherwise the built-in file-based default. Threaded into the
|
|
344
|
+
// tool registry AND the auto-recall helper so memory routes through one
|
|
345
|
+
// capability per turn (no per-call-site branching).
|
|
346
|
+
const memoryCapability = resolveActiveMemoryCapability({
|
|
347
|
+
config: turnConfig,
|
|
348
|
+
registry: extensionRegistry,
|
|
349
|
+
workspaceDir,
|
|
350
|
+
agentId,
|
|
351
|
+
});
|
|
352
|
+
// Assemble Brigade's full tool surface via the SHARED helper — the SAME
|
|
353
|
+
// one `buildAgent` (TUI + gateway) uses, so every surface exposes an
|
|
354
|
+
// identical set (7 built-ins + memory tools). Pi's `tools` field is an
|
|
355
|
+
// allowlist of NAMES; `customTools` is the slot for the Brigade-native
|
|
356
|
+
// Tool objects. The unknown-tool guard's allowlist must include the
|
|
357
|
+
// custom names too (else `recall_memory` is refused as unknown), which
|
|
358
|
+
// `enabledToolNames` already covers.
|
|
359
|
+
// Primitive #6: derive sub-agent depth from the session key. Top-level turns
|
|
360
|
+
// (e.g. `agent:main:main`) yield depth 0 — spawn_agent registers. Sub-agent
|
|
361
|
+
// turns (e.g. `agent:main:subagent:<uuid>`) yield depth 1 — spawn_agent is
|
|
362
|
+
// automatically filtered out at the leaf so recursion is impossible.
|
|
363
|
+
const callerSubagentDepth = getSubagentDepthFromSessionKey(resolved.sessionKey);
|
|
364
|
+
// H2 + H3 — derive the EFFECTIVE owner flag for this turn's toolset.
|
|
365
|
+
// The caller's `args.senderIsOwner` (defaults to true for TUI/CLI) is the
|
|
366
|
+
// base; any UNTRUSTED pending event flips it to false so a model running
|
|
367
|
+
// with a poisoned third-party context cannot reach ownerOnly tools.
|
|
368
|
+
const senderIsOwnerArg = args.senderIsOwner !== false;
|
|
369
|
+
const pendingEventsInspection = inspectPendingSessionEvents(resolved.sessionKey);
|
|
370
|
+
const effectiveSenderIsOwner = senderIsOwnerArg && !pendingEventsInspection.hasUntrusted;
|
|
371
|
+
// O0 — resolve the per-turn session-tool access policy from config so the
|
|
372
|
+
// four sessions tools fail-closed when the caller is not allowed to read /
|
|
373
|
+
// send to the target session. Defaults stay backward-compatible:
|
|
374
|
+
// visibility="self" (tool only sees the caller's own session) + A2A disabled.
|
|
375
|
+
// Resolve the per-turn session-tool access policy. Extracted to
|
|
376
|
+
// `resolveSessionAccessPolicy` (2026-06-11) so the SAME derivation backs
|
|
377
|
+
// both this build AND the `sessions_send` live re-check that honours a
|
|
378
|
+
// mid-run `manage_access` change — identical flatten + org-graph-vs-flat
|
|
379
|
+
// logic in one place. Behaviour is bit-for-bit the legacy block.
|
|
380
|
+
const { visibility, a2aPolicy } = resolveSessionAccessPolicy(turnConfig);
|
|
381
|
+
// Wave O0.5 (fix #3): populate spawnedKeys so visibility="tree" actually
|
|
382
|
+
// permits the caller to reach its own sub-agents. The registry walk
|
|
383
|
+
// returns the transitive set of children for `resolved.sessionKey`; an
|
|
384
|
+
// empty set is the right answer when no children exist (the same-key
|
|
385
|
+
// fast path handles the parent's own session).
|
|
386
|
+
const spawnedKeys = getSpawnedKeysForSession(resolved.sessionKey);
|
|
387
|
+
const toolset = assembleBrigadeToolset({
|
|
388
|
+
workspaceDir,
|
|
389
|
+
agentId,
|
|
390
|
+
cwd,
|
|
391
|
+
memoryCapability,
|
|
392
|
+
senderIsOwner: effectiveSenderIsOwner,
|
|
393
|
+
sessionToolAccess: {
|
|
394
|
+
visibility,
|
|
395
|
+
a2aPolicy,
|
|
396
|
+
spawnedKeys,
|
|
397
|
+
},
|
|
398
|
+
subagentContext: {
|
|
399
|
+
parentSessionKey: resolved.sessionKey,
|
|
400
|
+
callerDepth: callerSubagentDepth,
|
|
401
|
+
...(args.signal ? { parentSignal: args.signal } : {}),
|
|
402
|
+
// Inherit the parent's RESOLVED provider+modelId so the child uses
|
|
403
|
+
// whatever the operator is actually running (Anthropic, Ollama, ...)
|
|
404
|
+
// instead of the runner's hardcoded fallback. The `spawn_agent` tool's
|
|
405
|
+
// `model` param can still override per-call.
|
|
406
|
+
parentProvider: args.provider,
|
|
407
|
+
parentModelId: args.modelId,
|
|
408
|
+
},
|
|
409
|
+
// Cron primitive: per-job toolsAllow filter — stacks AFTER ownerOnly.
|
|
410
|
+
// Undefined for non-cron turns, an array for cron-fired turns whose
|
|
411
|
+
// payload sets a tool allowlist.
|
|
412
|
+
...(args.toolsAllow !== undefined ? { toolsAllow: args.toolsAllow } : {}),
|
|
413
|
+
// Channel context — set when the inbound came from a channel adapter.
|
|
414
|
+
// The cron tool reads it to auto-fill `delivery.channel/to/threadId` so
|
|
415
|
+
// a `cron add` mid-chat replies back to the same chat by default. The
|
|
416
|
+
// model can still override by passing explicit delivery params.
|
|
417
|
+
...(args.channelApprovalRoute !== undefined
|
|
418
|
+
? { channelContext: args.channelApprovalRoute }
|
|
419
|
+
: {}),
|
|
420
|
+
// Per-turn session context — bind the cron tool (and sessions tools)
|
|
421
|
+
// to THIS session's key so `sessionTarget: "current"` resolves to
|
|
422
|
+
// `session:<resolved.sessionKey>` instead of falling back to
|
|
423
|
+
// `"isolated"`. Built from the RESOLVED key (not args.sessionKey)
|
|
424
|
+
// because the agent loop may have minted a default key when the
|
|
425
|
+
// caller omitted one — the cron must bind to the live session, not
|
|
426
|
+
// the missing-input alias.
|
|
427
|
+
...(() => {
|
|
428
|
+
const ctx = buildSessionContext({
|
|
429
|
+
sessionKey: resolved.sessionKey,
|
|
430
|
+
agentId,
|
|
431
|
+
});
|
|
432
|
+
return ctx ? { sessionContext: ctx } : {};
|
|
433
|
+
})(),
|
|
434
|
+
});
|
|
435
|
+
const brigadeCustomTools = toolset.customTools;
|
|
436
|
+
const enabledToolNames = toolset.enabledToolNames;
|
|
437
|
+
const promptCapabilities = {
|
|
438
|
+
...toolset.capabilities,
|
|
439
|
+
// Gate on the RENDERED block, not the eligible count: a skill set that's
|
|
440
|
+
// entirely model-invocation-disabled yields an empty block, and emitting
|
|
441
|
+
// the "scan the skills listed below" guidance with no list beneath it is
|
|
442
|
+
// misleading. promptBlock is undefined exactly when there's nothing to show.
|
|
443
|
+
skills: skillDiscovery.promptBlock !== undefined,
|
|
444
|
+
// Wired below — flipped to `true` once the web-tool resolver decides at
|
|
445
|
+
// least one of `fetch_url` / `web_search` lands in `customTools`. The
|
|
446
|
+
// ## Web section in the prompt is gated on this flag.
|
|
447
|
+
web: false,
|
|
448
|
+
// Primitive #6 — flip the assembler into sub-agent mode when this turn's
|
|
449
|
+
// session key indicates we ARE a sub-agent (depth > 0). The assembler
|
|
450
|
+
// swaps the identity opener for the SUB-AGENT banner and gates off
|
|
451
|
+
// operator-only sections; the workspace loader drops BOOTSTRAP.md +
|
|
452
|
+
// MEMORY.md from the persona set; the heartbeat file is skipped.
|
|
453
|
+
subagentMode: callerSubagentDepth > 0,
|
|
454
|
+
// Cron primitive — when the cron service fires a scheduled run, the
|
|
455
|
+
// executor passes `cronMode: true`. Assembler swaps the opener for the
|
|
456
|
+
// cron banner + gates operator-only sections (same shape as
|
|
457
|
+
// subagentMode). `lightContext` (passed downstream into the workspace
|
|
458
|
+
// loader) decides whether to also drop the persona files for the
|
|
459
|
+
// cheapest possible system prompt.
|
|
460
|
+
cronMode: args.cronMode === true,
|
|
461
|
+
};
|
|
462
|
+
// `agents.defaults.toolset` (when set in `brigade.json`) narrows the active
|
|
463
|
+
// tool profile — e.g. `"minimal" | "coding" | "messaging"`. The registry
|
|
464
|
+
// filters extension-registered tools whose own `toolset` doesn't match (and
|
|
465
|
+
// isn't `"*"` / unset). Unset / `"full"` means "no filter" (full surface).
|
|
466
|
+
// The same value must reach BOTH the Pi factory (so excluded tools aren't
|
|
467
|
+
// registered) AND `toolNames()` (so the unknown-tool guard's allowlist
|
|
468
|
+
// agrees with what Pi sees).
|
|
469
|
+
const toolsetProfile = turnConfig.agents?.defaults?.toolset;
|
|
470
|
+
const brigadeResourceLoader = new DefaultResourceLoader({
|
|
471
|
+
cwd,
|
|
472
|
+
agentDir,
|
|
473
|
+
noSkills: true, // Brigade discovers + renders skills itself (see skills/)
|
|
474
|
+
noExtensions: true, // skip FILE extension discovery (cwd/.pi/extensions); our factory still runs
|
|
475
|
+
noPromptTemplates: true,
|
|
476
|
+
noThemes: true,
|
|
477
|
+
noContextFiles: true,
|
|
478
|
+
extensionFactories: [
|
|
479
|
+
extensionRegistry.toPiExtensionFactory({
|
|
480
|
+
toolset: toolsetProfile,
|
|
481
|
+
// Wave K — surface per-turn agent + session ctx so `b.tool({ create })`
|
|
482
|
+
// factories can scope state to THIS turn instead of closing over boot
|
|
483
|
+
// metadata.
|
|
484
|
+
agentId,
|
|
485
|
+
sessionKey: resolved.sessionKey,
|
|
486
|
+
}),
|
|
487
|
+
],
|
|
488
|
+
});
|
|
489
|
+
await brigadeResourceLoader.reload();
|
|
490
|
+
// ── Web tools (fetch_url + web_search) ────────────────────────────────────
|
|
491
|
+
// Build the canonical `fetch_url` tool with the configured WebFetchProvider
|
|
492
|
+
// as fallback (Firecrawl when keyed; built-in raw stays primary always).
|
|
493
|
+
// Build `web_search` only when an active WebSearchProvider resolved
|
|
494
|
+
// (DuckDuckGo is keyless and ships bundled, so it's always available
|
|
495
|
+
// unless explicitly opted out). Both join the customTools slot + the
|
|
496
|
+
// unknown-tool allowlist below.
|
|
497
|
+
const webProviderCtx = {
|
|
498
|
+
config: turnConfig,
|
|
499
|
+
env: process.env,
|
|
500
|
+
workspaceDir,
|
|
501
|
+
};
|
|
502
|
+
const activeFetchProvider = extensionRegistry.resolveActiveWebFetchProvider(turnConfig, process.env);
|
|
503
|
+
// Operator-configurable cache TTLs. `tools.web.{fetch,search}.cacheTtlMinutes`
|
|
504
|
+
// — unset/garbage → defaults (15min). Number conversion is permissive
|
|
505
|
+
// because TypeBox-validated config may flow through unknown shapes.
|
|
506
|
+
const webConfigShape = turnConfig.tools?.web;
|
|
507
|
+
const fetchCacheTtlMinutes = typeof webConfigShape?.fetch?.cacheTtlMinutes === "number"
|
|
508
|
+
? webConfigShape.fetch.cacheTtlMinutes
|
|
509
|
+
: undefined;
|
|
510
|
+
const searchCacheTtlMinutes = typeof webConfigShape?.search?.cacheTtlMinutes === "number"
|
|
511
|
+
? webConfigShape.search.cacheTtlMinutes
|
|
512
|
+
: undefined;
|
|
513
|
+
const fetchUrlTool = (await import("./tools/web-fetch.js")).makeFetchUrlTool({
|
|
514
|
+
provider: activeFetchProvider ?? null,
|
|
515
|
+
providerCtx: activeFetchProvider ? webProviderCtx : undefined,
|
|
516
|
+
cacheTtlMinutes: fetchCacheTtlMinutes,
|
|
517
|
+
});
|
|
518
|
+
const activeSearchProvider = extensionRegistry.resolveActiveWebSearchProvider(turnConfig, process.env);
|
|
519
|
+
const webSearchTool = activeSearchProvider
|
|
520
|
+
? (await import("./tools/web-search.js")).makeWebSearchTool({
|
|
521
|
+
provider: activeSearchProvider,
|
|
522
|
+
providerCtx: webProviderCtx,
|
|
523
|
+
cacheTtlMinutes: searchCacheTtlMinutes,
|
|
524
|
+
// Per-call provider override: the agent can pass `provider: "<id>"`
|
|
525
|
+
// in a single web_search call to route through a different backend
|
|
526
|
+
// without changing operator config. The lookup respects the same
|
|
527
|
+
// allow/deny config the default resolver does.
|
|
528
|
+
lookupProviderById: (id) => extensionRegistry.lookupWebSearchProviderById(id, turnConfig),
|
|
529
|
+
// Error-time fallback: when the active provider THROWS (429 /
|
|
530
|
+
// anti-bot / network), the tool walks this chain instead of losing
|
|
531
|
+
// search outright. Empty when the operator pinned a provider.
|
|
532
|
+
fallbackProviders: () => extensionRegistry.listWebSearchFallbackChain(turnConfig, process.env),
|
|
533
|
+
})
|
|
534
|
+
: null;
|
|
535
|
+
// Diagnostic toggle — when BRIGADE_DEBUG_WEB=1 the gateway log gets one
|
|
536
|
+
// line per turn telling you WHICH web-search provider got resolved, whether
|
|
537
|
+
// it supports filters, and whether the tool was actually built. Hard to
|
|
538
|
+
// debug a "3ms ✗ web_search" failure without this — the model could be
|
|
539
|
+
// hitting any of 5 distinct early-refusal branches (unknown tool, schema
|
|
540
|
+
// rejection, unsupported filter, provider key gate, DDG anti-bot). Off by
|
|
541
|
+
// default so it doesn't bloat the log for everyone.
|
|
542
|
+
if (process.env.BRIGADE_DEBUG_WEB === "1") {
|
|
543
|
+
const dbg = {
|
|
544
|
+
activeSearchProviderId: activeSearchProvider?.id ?? null,
|
|
545
|
+
supportsFilters: activeSearchProvider?.supportsFilters ?? null,
|
|
546
|
+
webSearchToolBuilt: webSearchTool !== null,
|
|
547
|
+
};
|
|
548
|
+
// eslint-disable-next-line no-console
|
|
549
|
+
console.error("[brigade.web]", JSON.stringify(dbg));
|
|
550
|
+
}
|
|
551
|
+
// Browser tool — ALWAYS registered (matches the upstream reference's
|
|
552
|
+
// behaviour). `playwright-core` is a hard dependency that ships the
|
|
553
|
+
// runtime engine WITHOUT a bundled Chromium binary (~30 MB). When the
|
|
554
|
+
// model actually calls the tool, the execute path probes for a system
|
|
555
|
+
// Chrome/Chromium/Edge/Brave and surfaces a clear "install Chrome or
|
|
556
|
+
// configure browser.executablePath" error if none is found.
|
|
557
|
+
//
|
|
558
|
+
// Opt-out: set `BRIGADE_DISABLE_BROWSER_TOOL=1` in the gateway env.
|
|
559
|
+
const browserTool = await (async () => {
|
|
560
|
+
if (process.env.BRIGADE_DISABLE_BROWSER_TOOL === "1")
|
|
561
|
+
return null;
|
|
562
|
+
try {
|
|
563
|
+
const { makeBrowserTool } = await import("./tools/browser.js");
|
|
564
|
+
return makeBrowserTool({});
|
|
565
|
+
}
|
|
566
|
+
catch {
|
|
567
|
+
// Fatal import error (browser.ts itself broken) — silently drop the
|
|
568
|
+
// tool rather than crash the whole agent loop. Should never happen
|
|
569
|
+
// in a healthy build.
|
|
570
|
+
return null;
|
|
571
|
+
}
|
|
572
|
+
})();
|
|
573
|
+
const webTools = [
|
|
574
|
+
fetchUrlTool,
|
|
575
|
+
...(webSearchTool ? [webSearchTool] : []),
|
|
576
|
+
...(browserTool ? [browserTool] : []),
|
|
577
|
+
];
|
|
578
|
+
const webToolNames = webTools.map((t) => t.name);
|
|
579
|
+
brigadeCustomTools.push(...webTools);
|
|
580
|
+
// Gate the system-prompt ## Web section on whether ANY web tool actually
|
|
581
|
+
// landed in customTools. `fetch_url` is always available (built-in raw
|
|
582
|
+
// fetch needs no provider), so this is effectively always true today;
|
|
583
|
+
// becomes meaningful if a future flag disables web tools entirely.
|
|
584
|
+
if (webTools.length > 0)
|
|
585
|
+
promptCapabilities.web = true;
|
|
586
|
+
// Extension tool names join the allowlist so the unknown-tool guard + Pi's
|
|
587
|
+
// `tools` activation gate accept them alongside the built-ins + memory tools.
|
|
588
|
+
const allEnabledToolNames = [
|
|
589
|
+
...new Set([
|
|
590
|
+
...enabledToolNames,
|
|
591
|
+
...extensionRegistry.toolNames({ toolset: toolsetProfile }),
|
|
592
|
+
...webToolNames,
|
|
593
|
+
]),
|
|
594
|
+
];
|
|
595
|
+
// ── Lane J: agent-harness slot warning ────────────────────────────────────
|
|
596
|
+
// Pi-coding-agent is the ONLY harness Brigade drives today. If an operator
|
|
597
|
+
// pinned `extensions.slots.agentHarness` to a registered plugin, log a
|
|
598
|
+
// warning that the slot won't activate yet — we don't swap the harness here
|
|
599
|
+
// (Pi's session is sacred; replacing it would lose auth wrapping and break
|
|
600
|
+
// every call silently). The slot becomes load-bearing the day a harness
|
|
601
|
+
// plugin actually ships; until then this warning is the safety net so the
|
|
602
|
+
// operator isn't silently ignored.
|
|
603
|
+
const pinnedHarness = extensionRegistry.resolveSlot("agentHarness", turnConfig, extensionRegistry.agentHarnesses);
|
|
604
|
+
if (pinnedHarness) {
|
|
605
|
+
log.warn("agentHarness slot pinned but Brigade uses Pi-coding-agent as the sole harness today — slot will activate when a harness plugin ships", { slot: pinnedHarness.id });
|
|
606
|
+
}
|
|
607
|
+
// ── Lane J: context-engine systemPromptAddition merge ─────────────────────
|
|
608
|
+
// When an operator pins `extensions.slots.contextEngine` to a registered
|
|
609
|
+
// engine, call its `assemble()` and capture any `systemPromptAddition`
|
|
610
|
+
// string. That string is merged into the assembled persona's ephemeral
|
|
611
|
+
// (below-cache-boundary) slot so a future engine can layer extra context
|
|
612
|
+
// without busting the prompt cache. Today no engine ships, so this is a
|
|
613
|
+
// no-op; on plugin error we swallow rather than failing the turn (the
|
|
614
|
+
// built-in path takes over).
|
|
615
|
+
let contextEngineAddition;
|
|
616
|
+
const pinnedContextEngine = extensionRegistry.resolveSlot("contextEngine", turnConfig, extensionRegistry.contextEngines);
|
|
617
|
+
if (pinnedContextEngine?.assemble) {
|
|
618
|
+
try {
|
|
619
|
+
// Pi session isn't built yet — pass an empty array. The contract lets
|
|
620
|
+
// an engine assemble before-turn; richer "live session messages" wiring
|
|
621
|
+
// can land once a real engine ships and we know what it needs.
|
|
622
|
+
const result = await pinnedContextEngine.assemble({ sessionMessages: [] });
|
|
623
|
+
contextEngineAddition = result.systemPromptAddition;
|
|
624
|
+
}
|
|
625
|
+
catch (err) {
|
|
626
|
+
log.warn("context-engine assemble() threw — falling back to built-in", {
|
|
627
|
+
slot: pinnedContextEngine.id,
|
|
628
|
+
error: err instanceof Error ? err.message : String(err),
|
|
629
|
+
});
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
const { session } = await createAgentSession({
|
|
633
|
+
cwd,
|
|
634
|
+
agentDir,
|
|
635
|
+
authStorage,
|
|
636
|
+
modelRegistry,
|
|
637
|
+
model: model,
|
|
638
|
+
thinkingLevel: args.thinkingLevel ?? "off",
|
|
639
|
+
tools: allEnabledToolNames,
|
|
640
|
+
customTools: brigadeCustomTools,
|
|
641
|
+
sessionManager,
|
|
642
|
+
resourceLoader: brigadeResourceLoader,
|
|
643
|
+
transformContext,
|
|
644
|
+
});
|
|
645
|
+
if (!session) {
|
|
646
|
+
throw new Error("Pi createAgentSession returned no session.");
|
|
647
|
+
}
|
|
648
|
+
// H4 — install the payload-level streamFn wrap so every outbound LLM
|
|
649
|
+
// payload runs the four provider-payload mutators (Anthropic cache hints,
|
|
650
|
+
// universal CACHE_BOUNDARY_MARKER strip, Gemini thinking-config reformat,
|
|
651
|
+
// SiliconFlow `thinking: "off"` swap, Minimax disable). Wraps OVER Pi's
|
|
652
|
+
// existing auth-aware streamFn so credentials still flow; never replaces
|
|
653
|
+
// it. Safe to call once per session — guards on the original being a fn.
|
|
654
|
+
wrapStreamFnWithPayloadMutations(session);
|
|
655
|
+
// Install the composed beforeToolCall guard. Three layers run in order:
|
|
656
|
+
//
|
|
657
|
+
// 1. UNKNOWN-TOOL GUARD (`makeUnknownToolGuard`) — name validation:
|
|
658
|
+
// tool not in `enabledToolNames`, malformed args. Allowlist
|
|
659
|
+
// uses normalised names so `Read`/`READ`/` read ` all match.
|
|
660
|
+
// If this blocks, we stop here.
|
|
661
|
+
//
|
|
662
|
+
// 2. TOOL-LOOP DETECTOR (`makeToolLoopDetector`) — catches a model
|
|
663
|
+
// that's stuck repeating the same call. Warns at 10 identical
|
|
664
|
+
// consecutive calls (bus event), blocks at 20 with a synthetic
|
|
665
|
+
// refusal that teaches the model to try something different.
|
|
666
|
+
// Per-session ring buffer keyed by sessionKey via the shared
|
|
667
|
+
// gateCtxRef so loops persist across turn boundaries within a
|
|
668
|
+
// single session.
|
|
669
|
+
//
|
|
670
|
+
// 3. EXEC GATE (`makeExecGate`) — bash/exec/shell/sh routing
|
|
671
|
+
// through `decideApproval` (Primitive #3): allow / deny / prompt.
|
|
672
|
+
// Also refuses workdir/cwd/env overrides on shell tools and
|
|
673
|
+
// surfaces a typed message when the on-disk allowlist file
|
|
674
|
+
// has an unsupported schema version.
|
|
675
|
+
//
|
|
676
|
+
// Pi turns any guard's `block: true` return into a synthetic
|
|
677
|
+
// tool_result the model sees inline, so the next turn can self-correct.
|
|
678
|
+
//
|
|
679
|
+
// Path-mutating tools (`write`, `edit`) are intentionally NOT gated
|
|
680
|
+
// here — Pi resolves their relative paths against the session cwd
|
|
681
|
+
// (the agent's workspace dir), and absolute paths pass through. This
|
|
682
|
+
// matches the established `tools.fs.workspaceOnly = false` default.
|
|
683
|
+
const sessionWithBeforeHook = session;
|
|
684
|
+
// Mutable closure-bag the shared guard chain reads for `tool-blocked`
|
|
685
|
+
// bus-event correlation. The agent-loop sets
|
|
686
|
+
// `gateCtxRef.value = {runId, agentId, sessionKey}` once it has those
|
|
687
|
+
// (just before the prompt() call) and clears it in the finally block.
|
|
688
|
+
const gateCtxRef = { value: {} };
|
|
689
|
+
if (sessionWithBeforeHook.agent) {
|
|
690
|
+
// SHARED guard chain — identical to the one buildAgent installs:
|
|
691
|
+
// unknown-tool guard → loop detector → exec-gate.
|
|
692
|
+
sessionWithBeforeHook.agent.beforeToolCall = composeBrigadeBeforeToolCall({
|
|
693
|
+
enabledToolNames: allEnabledToolNames,
|
|
694
|
+
gateCtxRef,
|
|
695
|
+
displayCwd: cwd,
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
// Compose stream-fn wrappers around Pi's auth-aware streamFn. Order
|
|
699
|
+
// matters and is from-the-outside-in: the outermost wrapper sees events
|
|
700
|
+
// last (closest to Pi's consumer), the innermost sees them first
|
|
701
|
+
// (closest to the provider). We chain idle-timeout outermost so a hung
|
|
702
|
+
// provider trips the timer regardless of inner repair work; tool-call
|
|
703
|
+
// repair is innermost so even a malformed delta from the wire gets
|
|
704
|
+
// cleaned before the stop-reason wrapper sees it.
|
|
705
|
+
//
|
|
706
|
+
// Crucially — never REPLACE Pi's streamFn (a brigade memory note locks
|
|
707
|
+
// this in: replacement loses the auth wrapping and every call goes
|
|
708
|
+
// silently keyless). Wrapping preserves Pi's wrapper at the bottom of
|
|
709
|
+
// the call stack.
|
|
710
|
+
const sessionAgent = session.agent;
|
|
711
|
+
if (sessionAgent && typeof sessionAgent.streamFn === "function") {
|
|
712
|
+
const baseStreamFn = sessionAgent.streamFn;
|
|
713
|
+
const idleTimeoutMs = resolveIdleTimeoutMs();
|
|
714
|
+
sessionAgent.streamFn = wrapStreamFnWithIdleTimeout(wrapStreamFnWithStopReasonRecovery(wrapStreamFnWithToolCallRepair(baseStreamFn)), { timeoutMs: idleTimeoutMs });
|
|
715
|
+
log.debug("stream wrappers installed", {
|
|
716
|
+
idleTimeoutMs,
|
|
717
|
+
provider: args.provider,
|
|
718
|
+
model: args.modelId,
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
// Seed the workspace before we read its state. Idempotent: only writes
|
|
722
|
+
// files that don't exist yet, so an established workspace is a no-op.
|
|
723
|
+
// Without this, a fresh `~/.brigade/` (e.g. after `rm -rf ~/.brigade`)
|
|
724
|
+
// would have no BOOTSTRAP.md / IDENTITY.md / AGENTS.md / etc., the
|
|
725
|
+
// assembler would have nothing to inject, and the model would default
|
|
726
|
+
// to its baseline ("I'm your coding assistant") instead of the
|
|
727
|
+
// BOOTSTRAP-driven greeting. Runtime A's `buildAgent` already does
|
|
728
|
+
// this at boot — runSingleTurn was missing the equivalent step.
|
|
729
|
+
await bootstrapWorkspace(workspaceDir);
|
|
730
|
+
// Detect lifecycle phase BEFORE the turn. Two layers stack here:
|
|
731
|
+
// 1. Workspace-level phase from workspace-state.json. Scopes to
|
|
732
|
+
// "has this workspace been onboarded? has BOOTSTRAP.md been
|
|
733
|
+
// consumed?" Persists across sessions.
|
|
734
|
+
// 2. Per-session bootstrap-delivery marker in the JSONL transcript.
|
|
735
|
+
// Scopes to "has the full bootstrap context already been
|
|
736
|
+
// delivered to *this* session, and not invalidated by a
|
|
737
|
+
// compaction since?" Lets sub-agent forks and post-compaction
|
|
738
|
+
// recovery emit the first-turn nudge again when needed, while
|
|
739
|
+
// the workspace has long since completed setup.
|
|
740
|
+
const phaseBefore = await evaluateBootstrapPhase(workspaceDir);
|
|
741
|
+
// Per-session bootstrap-delivery marker. Convex mode has no JSONL on disk,
|
|
742
|
+
// so the file-scan returns false every turn (→ wasteful re-delivery); read
|
|
743
|
+
// the marker from the convex transcript records instead. The marker is
|
|
744
|
+
// WRITTEN via markBootstrapDeliveredToSession (appendCustomEntry → the
|
|
745
|
+
// convex-backed SessionManager persists it), so both sides agree on the
|
|
746
|
+
// canonical customType.
|
|
747
|
+
const rctxForBootstrap = tryGetRuntimeContext();
|
|
748
|
+
const sessionAlreadyHasBootstrap = rctxForBootstrap?.mode === "convex"
|
|
749
|
+
? await rctxForBootstrap.store.messages
|
|
750
|
+
.hasBootstrapDelivered(agentId, resolved.sessionId)
|
|
751
|
+
.catch(() => false)
|
|
752
|
+
: await hasDeliveredBootstrapToSession(resolved.transcriptPath);
|
|
753
|
+
// `senderIsOwner` defaults to true — TUI, bash, and direct-RPC callers are
|
|
754
|
+
// always the operator. Channel adapters set this to `false` when the
|
|
755
|
+
// approved peer is NOT the operator's own linked-channel id, so a friend's
|
|
756
|
+
// first DM doesn't trigger the operator's identity-onboarding ritual.
|
|
757
|
+
const senderIsOwner = args.senderIsOwner !== false;
|
|
758
|
+
const effectivePhase = resolveEffectiveBootstrapPhase({
|
|
759
|
+
workspacePhase: phaseBefore,
|
|
760
|
+
sessionAlreadyHasBootstrap,
|
|
761
|
+
senderIsOwner,
|
|
762
|
+
});
|
|
763
|
+
// Query the actual tool names Pi wired to this session, then map each to
|
|
764
|
+
// a one-line summary. We pass the resolved descriptions through to the
|
|
765
|
+
// assembler so the system prompt enumerates the live tool surface (model
|
|
766
|
+
// calls them by exact name + knows what each does). Pi 0.70.x exposes
|
|
767
|
+
// `getActiveToolNames()`; older minors may not — fall back to our
|
|
768
|
+
// configured allowlist so the prompt still has a useful list.
|
|
769
|
+
const sessionWithTools = session;
|
|
770
|
+
const activeToolNames = (typeof sessionWithTools.getActiveToolNames === "function"
|
|
771
|
+
? sessionWithTools.getActiveToolNames()
|
|
772
|
+
: allEnabledToolNames).slice();
|
|
773
|
+
const toolDescriptions = activeToolNames.map((name) => ({
|
|
774
|
+
name,
|
|
775
|
+
summary: resolveToolSummary(name) ?? "",
|
|
776
|
+
}));
|
|
777
|
+
// Resolve the SAFE auto-recall origin for this turn ONCE — fail-closed
|
|
778
|
+
// `undefined` means SKIP auto-recall (no safe scope). Threads
|
|
779
|
+
// `effectiveSenderIsOwner` (the injection-downgraded owner flag, not the raw
|
|
780
|
+
// `senderIsOwner`) so a poisoned-inbox turn does not auto-recall owner memory.
|
|
781
|
+
const recallOrigin = resolveAutoRecallOrigin({
|
|
782
|
+
senderIsOwner: effectiveSenderIsOwner,
|
|
783
|
+
sessionKey: resolved.sessionKey,
|
|
784
|
+
...(args.channelApprovalRoute ? { channelApprovalRoute: args.channelApprovalRoute } : {}),
|
|
785
|
+
});
|
|
786
|
+
// Pin the assembled persona before the first turn. Done after
|
|
787
|
+
// createAgentSession (which has already set up Pi's stock prompt) but
|
|
788
|
+
// before prompt() so the model sees the brigade-flavoured persona on
|
|
789
|
+
// turn 1 and on every subsequent turn (the pi-injection helper patches
|
|
790
|
+
// the rebuild hook so tool-list changes don't clobber it).
|
|
791
|
+
const personaPrompt = await buildPersonaPrompt({
|
|
792
|
+
agentId,
|
|
793
|
+
workspaceDir,
|
|
794
|
+
cwd,
|
|
795
|
+
modelLabel: `${args.provider}/${args.modelId}`,
|
|
796
|
+
// Raw model id (no provider prefix) so the assembler's
|
|
797
|
+
// `pickModelFamilyGuidance` can match `gpt-*` / `o[13]-*` / `gemini-*`
|
|
798
|
+
// / `claude-*` / `codex-*` and inject the per-family identity-override
|
|
799
|
+
// block (e.g. "your baseline says 'I'm ChatGPT' — OVERRIDDEN by the
|
|
800
|
+
// persona configuration above"). Without this, smaller / cheaper models
|
|
801
|
+
// happily reply with their training-data identity ("I'm your coding
|
|
802
|
+
// assistant") instead of following IDENTITY.md.
|
|
803
|
+
modelId: args.modelId,
|
|
804
|
+
thinkingLevel: args.thinkingLevel ?? "off",
|
|
805
|
+
bootstrapPhase: effectivePhase,
|
|
806
|
+
toolDescriptions,
|
|
807
|
+
capabilities: promptCapabilities,
|
|
808
|
+
// Pre-rendered <available_skills> XML for the eligible skills (Primitive
|
|
809
|
+
// #5). Lands in the cached prefix under `## Skills`; the model reads a
|
|
810
|
+
// skill's body on demand via the read tool.
|
|
811
|
+
skillsPromptBlock: skillDiscovery.promptBlock,
|
|
812
|
+
// Channel surface for the `## Messaging` section. Reads from the
|
|
813
|
+
// process-wide channel-manager singleton — when the gateway has
|
|
814
|
+
// started adapters, the model sees the directory + (when this turn
|
|
815
|
+
// came from a channel inbound) the in-place-reply hint. Skipped in
|
|
816
|
+
// standalone CLI runs where no manager is mounted.
|
|
817
|
+
channels: (() => {
|
|
818
|
+
const manager = getActiveChannelManager();
|
|
819
|
+
if (!manager || manager.started.length === 0)
|
|
820
|
+
return undefined;
|
|
821
|
+
const route = args.channelApprovalRoute;
|
|
822
|
+
// Probe each started adapter's health (sync, cheap — reads a cached
|
|
823
|
+
// bool) so the assembler can surface a `⚠️ degraded` block when any
|
|
824
|
+
// adapter is logged-out / disconnected / starting. Without this the
|
|
825
|
+
// model recommends a channel that will refuse the send.
|
|
826
|
+
const degraded = [];
|
|
827
|
+
// Linked self-account per adapter (sync, cheap — reads the cached
|
|
828
|
+
// connection id). The assembler surfaces it in `## Messaging` so the
|
|
829
|
+
// model knows the operator's own number instead of asking for it.
|
|
830
|
+
const linked = [];
|
|
831
|
+
for (const id of manager.started) {
|
|
832
|
+
const adapter = manager.adapter(id);
|
|
833
|
+
if (!adapter)
|
|
834
|
+
continue;
|
|
835
|
+
const selfId = typeof adapter.selfId === "function" ? adapter.selfId() : undefined;
|
|
836
|
+
if (selfId)
|
|
837
|
+
linked.push({ channelId: id, selfId });
|
|
838
|
+
if (typeof adapter.health !== "function")
|
|
839
|
+
continue;
|
|
840
|
+
const status = adapter.health();
|
|
841
|
+
if (!status.ok) {
|
|
842
|
+
degraded.push({
|
|
843
|
+
channelId: id,
|
|
844
|
+
reason: status.reason,
|
|
845
|
+
...(status.remediation !== undefined ? { remediation: status.remediation } : {}),
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
return {
|
|
850
|
+
started: manager.started,
|
|
851
|
+
...(linked.length > 0 ? { linked } : {}),
|
|
852
|
+
...(degraded.length > 0 ? { degraded } : {}),
|
|
853
|
+
...(route
|
|
854
|
+
? {
|
|
855
|
+
currentChannel: {
|
|
856
|
+
channelId: route.channelId,
|
|
857
|
+
...(route.conversationId !== undefined
|
|
858
|
+
? { conversationId: route.conversationId }
|
|
859
|
+
: {}),
|
|
860
|
+
...(route.threadId !== undefined ? { threadId: route.threadId } : {}),
|
|
861
|
+
},
|
|
862
|
+
}
|
|
863
|
+
: {}),
|
|
864
|
+
};
|
|
865
|
+
})(),
|
|
866
|
+
config: turnConfig,
|
|
867
|
+
// Auto-recall: lexically surface the top relevant structured facts for THIS
|
|
868
|
+
// user message as an ephemeral (per-turn, below-cache-boundary) suffix, so
|
|
869
|
+
// the model has them without calling recall_memory. Sync + free. This is a
|
|
870
|
+
// PASSIVE injection — it does NOT bump accessCount (only the explicit
|
|
871
|
+
// recall_memory tool reinforces decay). Only present when memory is enabled.
|
|
872
|
+
//
|
|
873
|
+
// Lane J: when a `contextEngine` slot plugin returned a
|
|
874
|
+
// `systemPromptAddition`, append it AFTER the auto-recall block so it
|
|
875
|
+
// also lands below the cache boundary. Both are per-turn dynamic so they
|
|
876
|
+
// share the ephemeral slot; the assembler's sanitiser handles either as
|
|
877
|
+
// plain text.
|
|
878
|
+
// Auto-recall is for the OPERATOR-facing turn: surface what the parent
|
|
879
|
+
// remembers about THIS user message so the model can use it without an
|
|
880
|
+
// explicit recall_memory call. Sub-agents (Primitive #6) get a focused,
|
|
881
|
+
// parent-injected task — auto-recalling parent-scoped memory facts there
|
|
882
|
+
// would pollute the bounded context with content the task didn't ask for.
|
|
883
|
+
// Gate on `!subagentMode` so the suffix stays clean for delegated runs.
|
|
884
|
+
//
|
|
885
|
+
// Origin filter: owner turns recall only owner-origin facts; channel-
|
|
886
|
+
// routed peers recall only their own session's facts. Without this
|
|
887
|
+
// filter, an approved peer's auto-recall would surface the operator's
|
|
888
|
+
// private memory (and vice versa). A non-owner turn missing a
|
|
889
|
+
// channelContext or sessionKey falls back to `undefined` — auto-recall
|
|
890
|
+
// sees no records (consistent with the recall_memory tool's behaviour).
|
|
891
|
+
ephemeralSuffix: mergeEphemeralSuffix(promptCapabilities?.memory &&
|
|
892
|
+
!promptCapabilities.subagentMode &&
|
|
893
|
+
!promptCapabilities.cronMode &&
|
|
894
|
+
// Fail CLOSED: only auto-recall when there is a SAFE origin (owner turn, or
|
|
895
|
+
// a channel-routed peer). A non-owner turn with no channel route is skipped
|
|
896
|
+
// entirely — never the operator's facts. (Defends the isolation invariant
|
|
897
|
+
// at THIS sink, not via a caller-enforced precondition.)
|
|
898
|
+
//
|
|
899
|
+
// Use `effectiveSenderIsOwner` (NOT the raw `senderIsOwner`): an untrusted
|
|
900
|
+
// pending event downgrades this turn to non-owner, so a poisoned-inbox turn
|
|
901
|
+
// must NOT auto-recall owner-scope memory. Resolve the origin ONCE and reuse
|
|
902
|
+
// it for the block — a single source of truth for the recall scope.
|
|
903
|
+
recallOrigin
|
|
904
|
+
? await buildAutoRecallBlock(memoryCapability, args.message, { origin: recallOrigin })
|
|
905
|
+
: undefined, contextEngineAddition),
|
|
906
|
+
// Cron primitive: thread the `lightContext` flag down to the persona
|
|
907
|
+
// builder. When set, the entire workspace bootstrap surface is dropped
|
|
908
|
+
// for a minimal prompt (cron's task message carries the context).
|
|
909
|
+
...(args.lightContext === true ? { lightContext: true } : {}),
|
|
910
|
+
});
|
|
911
|
+
if (personaPrompt) {
|
|
912
|
+
applyPersonaOverrideToSession(session, personaPrompt);
|
|
913
|
+
}
|
|
914
|
+
// Hand the fully-wired session to the per-turn driver (gateway / TUI) so it
|
|
915
|
+
// can steer / abort / switch-model mid-stream for the duration of THIS turn.
|
|
916
|
+
// The driver drops the reference when the turn settles — no session lives
|
|
917
|
+
// between turns (the per-turn mirror). Guarded so a throwing callback can't
|
|
918
|
+
// abort the turn.
|
|
919
|
+
if (args.onSessionReady) {
|
|
920
|
+
try {
|
|
921
|
+
args.onSessionReady(session);
|
|
922
|
+
}
|
|
923
|
+
catch (err) {
|
|
924
|
+
log.warn("onSessionReady callback threw", {
|
|
925
|
+
sessionId: resolved.sessionId,
|
|
926
|
+
error: err instanceof Error ? err.message : String(err),
|
|
927
|
+
});
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
// prompt() runs a full user turn — Pi enqueues the message, drives the
|
|
931
|
+
// agent loop, and resolves once the turn is complete (assistant reply
|
|
932
|
+
// committed to messages, isStreaming/isCompacting cleared).
|
|
933
|
+
//
|
|
934
|
+
// Do NOT use steer() here: steer is for *mid-turn* injection. With no
|
|
935
|
+
// active run it just enqueues into the steering buffer and returns
|
|
936
|
+
// immediately — the assistant never speaks and brigade prints nothing.
|
|
937
|
+
//
|
|
938
|
+
// Wrapped in runWithRetry so a transient provider failure (rate limit,
|
|
939
|
+
// overload, timeout) is automatically retried with backoff + jitter
|
|
940
|
+
// instead of surfacing as a hard turn error to the caller. Same-model
|
|
941
|
+
// retries only — multi-model fallback is one layer up (see
|
|
942
|
+
// model-fallback.ts), which is wired in by the resilient agent runner.
|
|
943
|
+
//
|
|
944
|
+
// The user message is scrubbed of the Anthropic refusal-trigger magic
|
|
945
|
+
// string before Pi sees it; otherwise a paste-through of that literal
|
|
946
|
+
// would coerce Claude into refusing the next turn.
|
|
947
|
+
// Drain any pending system events queued for THIS session. Cron's
|
|
948
|
+
// fire-time announces now land in the SESSION INBOX (drained below as
|
|
949
|
+
// `inboxBlock`) so the heartbeat runner can consume them for synthetic
|
|
950
|
+
// turns; this legacy pending queue still carries cron DELIVERY-FAILURE
|
|
951
|
+
// notices ("couldn't deliver via whatsapp — …", see the announce
|
|
952
|
+
// dispatcher in `src/core/server.ts`). Each pending event becomes a
|
|
953
|
+
// `<system_event>` block prepended to the user's text so the model sees
|
|
954
|
+
// the failure BEFORE it answers the new message instead of bullshitting
|
|
955
|
+
// "should be landing any moment now".
|
|
956
|
+
const pendingEvents = drainPendingSystemEvents(resolved.sessionKey);
|
|
957
|
+
const pendingPrefix = formatPendingEventsPrefix(pendingEvents);
|
|
958
|
+
// SessionInbox drain (Step 12). A2A messages (`sessions_send`), sub-agent
|
|
959
|
+
// completion announces, heartbeat-fired wakes, exec-event surfaces all
|
|
960
|
+
// land in the broader SessionInbox queue (`session-inbox.ts`). Drain +
|
|
961
|
+
// format them here so they prefix the user message alongside the cron-
|
|
962
|
+
// specific Track-2 events drained above. Returns `undefined` when no
|
|
963
|
+
// surface-able events are pending; the prompt body stays unchanged.
|
|
964
|
+
// Stage D additive-gate: PEEK the inbox BEFORE draining so the org
|
|
965
|
+
// layer can render receiver-side hints (per-event framing) and the
|
|
966
|
+
// top-of-org escalation inbox summary. Both helpers return `undefined`
|
|
967
|
+
// unless cfg.org is present AND an event in the batch carries
|
|
968
|
+
// `brigade-org-kind:` metadata on its contextKey — when cfg.org is
|
|
969
|
+
// absent, this block emits ZERO new bytes and the legacy combinedPrefix
|
|
970
|
+
// assembly is preserved bit-for-bit.
|
|
971
|
+
let orgEphemeralBlock;
|
|
972
|
+
try {
|
|
973
|
+
const orgConfig = turnConfig;
|
|
974
|
+
if (orgConfig.org) {
|
|
975
|
+
const inspected = inspectPendingSessionEvents(resolved.sessionKey);
|
|
976
|
+
if (inspected.events.length > 0) {
|
|
977
|
+
const orgBlocks = [];
|
|
978
|
+
// Per-event hint render (delegation / escalation / review framing).
|
|
979
|
+
const { renderReceiverHints } = await import("../system-prompt/org/receiver-hint.js");
|
|
980
|
+
const hints = renderReceiverHints(inspected.events);
|
|
981
|
+
if (hints)
|
|
982
|
+
orgBlocks.push(hints);
|
|
983
|
+
// Top-of-org escalation inbox summary (only when caller is topOrder).
|
|
984
|
+
const orgGraph = deriveOrgDisplayGraph(turnConfig);
|
|
985
|
+
if (orgGraph) {
|
|
986
|
+
const { renderEscalationInbox } = await import("../system-prompt/org/escalation-inbox.js");
|
|
987
|
+
const inboxSummary = renderEscalationInbox({
|
|
988
|
+
callerAgentId: agentId,
|
|
989
|
+
graph: orgGraph,
|
|
990
|
+
events: inspected.events,
|
|
991
|
+
});
|
|
992
|
+
if (inboxSummary)
|
|
993
|
+
orgBlocks.push(inboxSummary);
|
|
994
|
+
}
|
|
995
|
+
if (orgBlocks.length > 0)
|
|
996
|
+
orgEphemeralBlock = orgBlocks.join("\n\n");
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
catch (err) {
|
|
1001
|
+
// Org peek failures are non-fatal: skip the block and keep the
|
|
1002
|
+
// legacy combinedPrefix shape rather than crashing turn assembly.
|
|
1003
|
+
log.warn("Stage D receiver-hint peek failed", {
|
|
1004
|
+
sessionId: resolved.sessionId,
|
|
1005
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
const inboxBlock = drainFormattedSessionEvents({ sessionKey: resolved.sessionKey });
|
|
1009
|
+
const combinedPrefix = [orgEphemeralBlock, inboxBlock, pendingPrefix]
|
|
1010
|
+
.filter(Boolean)
|
|
1011
|
+
.join("\n\n");
|
|
1012
|
+
const scrubbedMessage = scrubAnthropicRefusalSentinel(combinedPrefix ? `${combinedPrefix}\n${args.message}` : args.message);
|
|
1013
|
+
// Process-level event bus wiring. A short-lived run id correlates
|
|
1014
|
+
// every event from this turn so multi-consumer subscribers (TUI,
|
|
1015
|
+
// gateway WebSocket broadcast, debug logs) can group them. The
|
|
1016
|
+
// forwarder pipes Pi's per-event stream into the global bus and
|
|
1017
|
+
// is detached at the end of the function so listeners don't pile
|
|
1018
|
+
// up across the gateway's long-running process. This is the standard
|
|
1019
|
+
// global agent-events registry pattern.
|
|
1020
|
+
const runId = randomUUID();
|
|
1021
|
+
// Wave L P2#10 — per-turn bound logger. Every log emitted via
|
|
1022
|
+
// `turnLog` automatically carries `agentId / sessionId / runId`
|
|
1023
|
+
// so observability tooling can correlate without each call-site
|
|
1024
|
+
// threading the trio by hand. Existing `log.*` callsites still
|
|
1025
|
+
// work unchanged.
|
|
1026
|
+
const turnLog = log.bind({
|
|
1027
|
+
agentId,
|
|
1028
|
+
sessionId: resolved.sessionId,
|
|
1029
|
+
runId,
|
|
1030
|
+
});
|
|
1031
|
+
void turnLog;
|
|
1032
|
+
// Publish runId+agentId+sessionKey to the closure-bag so any
|
|
1033
|
+
// `tool-blocked` events emitted during this turn carry accurate
|
|
1034
|
+
// correlation ids AND the loop detector keys its ring buffer to
|
|
1035
|
+
// this session's transcript (so loops persist across turn
|
|
1036
|
+
// boundaries but stay scoped per-session). Cleared in finally
|
|
1037
|
+
// so a subsequent turn (which reuses the same session) doesn't
|
|
1038
|
+
// leak stale ids.
|
|
1039
|
+
gateCtxRef.value = {
|
|
1040
|
+
runId,
|
|
1041
|
+
agentId,
|
|
1042
|
+
sessionKey: resolved.sessionKey,
|
|
1043
|
+
// Primitive #6: when this turn IS a sub-agent run, propagate depth + label
|
|
1044
|
+
// + parent runId to every guard event (exec-gate routes them into the
|
|
1045
|
+
// approval prompt so the operator sees "Sub-agent 'audit auth flow' wants
|
|
1046
|
+
// to run …" instead of the default "Brigade wants to run …" attribution).
|
|
1047
|
+
// Top-level turns leave all three unset.
|
|
1048
|
+
...(callerSubagentDepth > 0 ? { subagentDepth: callerSubagentDepth } : {}),
|
|
1049
|
+
...(args.subagentLabel !== undefined ? { subagentLabel: args.subagentLabel } : {}),
|
|
1050
|
+
...(args.parentRunId !== undefined ? { parentRunId: args.parentRunId } : {}),
|
|
1051
|
+
// Channel routing — exec-gate uses this to send approval prompts into
|
|
1052
|
+
// the originating chat instead of (only) the gateway WS. Channel-routed
|
|
1053
|
+
// inbounds populate it via runGatewayTurn; TUI / sub-agent / cron turns
|
|
1054
|
+
// leave it unset and fall back to the legacy WS-only broadcast.
|
|
1055
|
+
...(args.channelApprovalRoute !== undefined
|
|
1056
|
+
? { channelRoute: args.channelApprovalRoute }
|
|
1057
|
+
: {}),
|
|
1058
|
+
};
|
|
1059
|
+
// Duck-typed Pi session subscription. We assert the SHAPE we want
|
|
1060
|
+
// rather than coupling to a specific Pi version's exported type. If
|
|
1061
|
+
// a future Pi changes `subscribe` to return `Promise<() => void>` or
|
|
1062
|
+
// an object with `.unsubscribe()`, calling `rawDetach()` may throw —
|
|
1063
|
+
// that throw is caught by `detachPiForwarder`'s internal try/catch
|
|
1064
|
+
// (see below), so the bus listener still gets cleared and the worst
|
|
1065
|
+
// case is a stale per-event log line, not a leak.
|
|
1066
|
+
const subscribableSession = session;
|
|
1067
|
+
const rawDetach = typeof subscribableSession.subscribe === "function"
|
|
1068
|
+
? subscribableSession.subscribe((piEvent) => emitAgentEvent({
|
|
1069
|
+
type: "pi",
|
|
1070
|
+
runId,
|
|
1071
|
+
agentId,
|
|
1072
|
+
sessionId: resolved.sessionId,
|
|
1073
|
+
piEvent,
|
|
1074
|
+
// Primitive #6: tag sub-agent depth so the gateway can indent
|
|
1075
|
+
// child events in the connect-mode TUI without re-deriving from
|
|
1076
|
+
// the session key on every event.
|
|
1077
|
+
...(callerSubagentDepth > 0 ? { subagentDepth: callerSubagentDepth } : {}),
|
|
1078
|
+
}))
|
|
1079
|
+
: () => { };
|
|
1080
|
+
// Idempotent detach. Called in two places: the success path emits
|
|
1081
|
+
// turn-settled then detaches; the error path's finally block detaches
|
|
1082
|
+
// unconditionally. Both routes converge here without double-detaching.
|
|
1083
|
+
let piForwarderDetached = false;
|
|
1084
|
+
const detachPiForwarder = () => {
|
|
1085
|
+
if (piForwarderDetached)
|
|
1086
|
+
return;
|
|
1087
|
+
piForwarderDetached = true;
|
|
1088
|
+
try {
|
|
1089
|
+
rawDetach();
|
|
1090
|
+
}
|
|
1091
|
+
catch {
|
|
1092
|
+
// session may already be torn down; nothing useful to do
|
|
1093
|
+
}
|
|
1094
|
+
};
|
|
1095
|
+
try {
|
|
1096
|
+
log.info("turn starting", {
|
|
1097
|
+
agentId,
|
|
1098
|
+
sessionId: resolved.sessionId,
|
|
1099
|
+
isNewSession: resolved.isNew,
|
|
1100
|
+
provider: args.provider,
|
|
1101
|
+
model: args.modelId,
|
|
1102
|
+
bootstrapPhase: effectivePhase,
|
|
1103
|
+
});
|
|
1104
|
+
emitAgentEvent({
|
|
1105
|
+
type: "turn-start",
|
|
1106
|
+
runId,
|
|
1107
|
+
agentId,
|
|
1108
|
+
sessionId: resolved.sessionId,
|
|
1109
|
+
isNewSession: resolved.isNew,
|
|
1110
|
+
provider: args.provider,
|
|
1111
|
+
modelId: args.modelId,
|
|
1112
|
+
bootstrapPhase: String(effectivePhase),
|
|
1113
|
+
});
|
|
1114
|
+
// Pre-emptive compaction. When estimated context usage crosses the
|
|
1115
|
+
// 85% threshold, ask Pi to compact NOW rather than rolling into the
|
|
1116
|
+
// turn and discovering mid-flight that we've blown the window. The
|
|
1117
|
+
// estimator is rough (chars/4) but conservative — better to compact
|
|
1118
|
+
// a turn early than fail mid-stream.
|
|
1119
|
+
//
|
|
1120
|
+
// The estimate must reflect the FULL request, not just the transcript:
|
|
1121
|
+
// the pinned persona prompt (state.systemPrompt — a SEPARATE field Pi
|
|
1122
|
+
// reads at request time, NOT in session.messages) and the about-to-be-
|
|
1123
|
+
// sent user message both consume window on every request. Omitting them
|
|
1124
|
+
// biases the estimate low by the fixed persona cost present on each
|
|
1125
|
+
// request, so the 85% trigger fires LATE and the turn is likelier to
|
|
1126
|
+
// fall through to Pi's mid-stream auto-compaction. Thread both in so the
|
|
1127
|
+
// decision sees the true pre-prompt fill.
|
|
1128
|
+
await maybeTriggerCompaction({
|
|
1129
|
+
session: session,
|
|
1130
|
+
model: model,
|
|
1131
|
+
agentId,
|
|
1132
|
+
sessionId: resolved.sessionId,
|
|
1133
|
+
// The pinned persona prompt — empty string when the workspace is empty
|
|
1134
|
+
// (the assembler returns "" and applyPersonaOverrideToSession is skipped),
|
|
1135
|
+
// which contributes 0 to the estimate.
|
|
1136
|
+
systemPrompt: personaPrompt,
|
|
1137
|
+
// The incoming user message (with any drained prefixes) that prompt()
|
|
1138
|
+
// will send below; maybeTriggerCompaction runs BEFORE that send.
|
|
1139
|
+
incomingMessage: scrubbedMessage,
|
|
1140
|
+
...(recallOrigin ? { origin: recallOrigin } : {}),
|
|
1141
|
+
});
|
|
1142
|
+
// Snapshot the transcript length immediately before the FIRST prompt of
|
|
1143
|
+
// this turn. Used by the max_tokens continuation path below: every settled
|
|
1144
|
+
// run (initial + each continuation) pushes a NEW assistant message into
|
|
1145
|
+
// session.messages, so a capped answer split across N continuations lands
|
|
1146
|
+
// as N distinct segments — NOT restatements. extractLastAssistantText
|
|
1147
|
+
// returns only the most-recent segment, which would silently drop the
|
|
1148
|
+
// truncated head + every middle segment. We instead concatenate every
|
|
1149
|
+
// assistant message produced from this index forward (see `reply` below).
|
|
1150
|
+
// Captured once here — before runWithRetry, which may re-invoke the
|
|
1151
|
+
// attempt closure on transient failures — so retries don't move it.
|
|
1152
|
+
const messageCountBeforeTurn = session.messages.length;
|
|
1153
|
+
await runWithRetry({
|
|
1154
|
+
ctx: { provider: args.provider, model: args.modelId },
|
|
1155
|
+
signal: args.signal,
|
|
1156
|
+
onAttemptFailed: async (info) => {
|
|
1157
|
+
const fields = {
|
|
1158
|
+
agentId,
|
|
1159
|
+
sessionId: resolved.sessionId,
|
|
1160
|
+
provider: args.provider,
|
|
1161
|
+
model: args.modelId,
|
|
1162
|
+
attempt: info.attemptIndex,
|
|
1163
|
+
reason: info.reason,
|
|
1164
|
+
willRetry: info.willRetry,
|
|
1165
|
+
backoffMs: info.backoffMs,
|
|
1166
|
+
error: info.errorSummary,
|
|
1167
|
+
profileId: selectedProfileId,
|
|
1168
|
+
};
|
|
1169
|
+
if (info.willRetry)
|
|
1170
|
+
log.warn("turn attempt failed, retrying", fields);
|
|
1171
|
+
else
|
|
1172
|
+
log.error("turn attempt failed, surfacing", fields);
|
|
1173
|
+
// Narrate the retry on the bus so connect-mode clients see "retrying…"
|
|
1174
|
+
// (the gateway translates this into a `log` frame). Only on actual
|
|
1175
|
+
// retries — a terminal failure surfaces as the turn's error, not a retry.
|
|
1176
|
+
if (info.willRetry) {
|
|
1177
|
+
emitAgentEvent({
|
|
1178
|
+
type: "turn-retry-attempt",
|
|
1179
|
+
runId,
|
|
1180
|
+
agentId,
|
|
1181
|
+
sessionKey: resolved.sessionKey,
|
|
1182
|
+
errorClass: String(info.class ?? "unknown"),
|
|
1183
|
+
reason: String(info.reason ?? info.errorSummary ?? "transient error"),
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
// Update the on-disk cooldown state so this profile rotates out on
|
|
1187
|
+
// the next run if its failure category warrants a cooldown. Skipped
|
|
1188
|
+
// when no profile id was tracked (single-profile fallback path).
|
|
1189
|
+
//
|
|
1190
|
+
// Locked variant: re-loads fresh state under the per-agent cooldown
|
|
1191
|
+
// lock, merges THIS failure against THAT snapshot, then saves. The
|
|
1192
|
+
// surrounding retry orchestrator awaits the returned Promise so the
|
|
1193
|
+
// next attempt's `loadProfileStateLocked` sees this write.
|
|
1194
|
+
if (selectedProfileId) {
|
|
1195
|
+
cooldownState = await recordProfileFailureLocked({
|
|
1196
|
+
agentId,
|
|
1197
|
+
state: cooldownState,
|
|
1198
|
+
profileId: selectedProfileId,
|
|
1199
|
+
reason: info.reason,
|
|
1200
|
+
modelId: args.modelId,
|
|
1201
|
+
});
|
|
1202
|
+
}
|
|
1203
|
+
},
|
|
1204
|
+
attempt: async (_attemptIndex, _signal) => {
|
|
1205
|
+
// Compose order (outer → inner):
|
|
1206
|
+
// thinkingFallback → contentQualityRetry → prompt(scrubbedMessage)
|
|
1207
|
+
//
|
|
1208
|
+
// thinkingFallback OUTER: if the very first prompt fails with
|
|
1209
|
+
// "thinking not supported", downgrade thinkingLevel and retry the
|
|
1210
|
+
// SAME user message before contentQualityRetry ever sees it. The
|
|
1211
|
+
// retry body inside thinkingFallback re-runs everything — including
|
|
1212
|
+
// contentQualityRetry — so the second attempt still gets the
|
|
1213
|
+
// "did the model actually act?" check.
|
|
1214
|
+
//
|
|
1215
|
+
// contentQualityRetry INNER: only fires after a successful prompt
|
|
1216
|
+
// settles. If the model returned "I'll do X" without doing X, OR
|
|
1217
|
+
// reasoning-only, OR empty, queue one steering re-prompt.
|
|
1218
|
+
//
|
|
1219
|
+
// Both wrappers are hard-capped at one retry. Combined ceiling is
|
|
1220
|
+
// 4 prompts in the worst case (initial → thinking-downgrade →
|
|
1221
|
+
// initial-of-retry → content-quality-steer-of-retry) — bounded.
|
|
1222
|
+
await runWithThinkingFallback(session, async () => {
|
|
1223
|
+
await runWithContentQualityRetry(session, async () => {
|
|
1224
|
+
await session.prompt(scrubbedMessage);
|
|
1225
|
+
// Defensive settle wait. prompt() should already have settled
|
|
1226
|
+
// the run, but if Pi adds queued steers or background
|
|
1227
|
+
// compactions in a future minor, this catches the late activity.
|
|
1228
|
+
await waitForStreamSettled(session);
|
|
1229
|
+
// Surface a provider-error stop BEFORE content-quality inspects
|
|
1230
|
+
// the (empty) content — otherwise it's mistaken for an "empty"
|
|
1231
|
+
// reply and we re-prompt a model that's hard-erroring.
|
|
1232
|
+
assertNoProviderErrorStop(session);
|
|
1233
|
+
}, {
|
|
1234
|
+
onRetry: (reason) => {
|
|
1235
|
+
log.warn("content-quality retry triggered", {
|
|
1236
|
+
agentId,
|
|
1237
|
+
sessionId: resolved.sessionId,
|
|
1238
|
+
reason,
|
|
1239
|
+
provider: args.provider,
|
|
1240
|
+
model: args.modelId,
|
|
1241
|
+
});
|
|
1242
|
+
// Connect-mode narration: "<reason> — re-prompting for a
|
|
1243
|
+
// usable answer". The gateway maps this to a `log` frame.
|
|
1244
|
+
emitAgentEvent({
|
|
1245
|
+
type: "turn-content-retry",
|
|
1246
|
+
runId,
|
|
1247
|
+
agentId,
|
|
1248
|
+
sessionKey: resolved.sessionKey,
|
|
1249
|
+
reason,
|
|
1250
|
+
});
|
|
1251
|
+
},
|
|
1252
|
+
});
|
|
1253
|
+
}, {
|
|
1254
|
+
onDowngrade: (originalLevel, errorMessage) => {
|
|
1255
|
+
log.warn("thinking level downgraded due to capability error", {
|
|
1256
|
+
agentId,
|
|
1257
|
+
sessionId: resolved.sessionId,
|
|
1258
|
+
originalLevel,
|
|
1259
|
+
errorMessage,
|
|
1260
|
+
provider: args.provider,
|
|
1261
|
+
model: args.modelId,
|
|
1262
|
+
});
|
|
1263
|
+
// Connect-mode narration: "model doesn't support thinking —
|
|
1264
|
+
// switching from <level> to off and retrying".
|
|
1265
|
+
emitAgentEvent({
|
|
1266
|
+
type: "turn-thinking-downgrade",
|
|
1267
|
+
runId,
|
|
1268
|
+
agentId,
|
|
1269
|
+
sessionKey: resolved.sessionKey,
|
|
1270
|
+
from: String(originalLevel),
|
|
1271
|
+
});
|
|
1272
|
+
},
|
|
1273
|
+
});
|
|
1274
|
+
},
|
|
1275
|
+
});
|
|
1276
|
+
// max_tokens auto-continuation. If the model hit its output cap rather
|
|
1277
|
+
// than ending naturally, drive a follow-up turn that asks it to continue
|
|
1278
|
+
// the previous response. Bounded to 3 continuations per user message so
|
|
1279
|
+
// a runaway response can't spin forever; each continuation runs through
|
|
1280
|
+
// the same retry loop so transient failures during continuation are
|
|
1281
|
+
// handled identically.
|
|
1282
|
+
let continuations = 0;
|
|
1283
|
+
const MAX_CONTINUATIONS = 3;
|
|
1284
|
+
while (continuations < MAX_CONTINUATIONS &&
|
|
1285
|
+
detectMaxTokensStop(session)) {
|
|
1286
|
+
continuations++;
|
|
1287
|
+
log.info("max_tokens stop detected — auto-continuing", {
|
|
1288
|
+
agentId,
|
|
1289
|
+
sessionId: resolved.sessionId,
|
|
1290
|
+
continuationIndex: continuations,
|
|
1291
|
+
});
|
|
1292
|
+
await runWithRetry({
|
|
1293
|
+
ctx: { provider: args.provider, model: args.modelId },
|
|
1294
|
+
signal: args.signal,
|
|
1295
|
+
attempt: async () => {
|
|
1296
|
+
await session.prompt("Please continue your previous response from where you left off. Don't repeat what you've already said.");
|
|
1297
|
+
await waitForStreamSettled(session);
|
|
1298
|
+
assertNoProviderErrorStop(session);
|
|
1299
|
+
},
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1302
|
+
if (continuations >= MAX_CONTINUATIONS && detectMaxTokensStop(session)) {
|
|
1303
|
+
log.warn("max_tokens continuation limit reached", {
|
|
1304
|
+
agentId,
|
|
1305
|
+
sessionId: resolved.sessionId,
|
|
1306
|
+
attempted: continuations,
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
// Successful turn — clear any prior failure state on the profile so the
|
|
1310
|
+
// next run prefers it again under the round-robin order. Locked variant:
|
|
1311
|
+
// re-loads fresh state under the per-agent cooldown lock, applies the
|
|
1312
|
+
// mark against THAT snapshot, then saves — so a sibling turn's recent
|
|
1313
|
+
// failure-write isn't silently clobbered by our pre-failure snapshot.
|
|
1314
|
+
if (selectedProfileId) {
|
|
1315
|
+
cooldownState = await recordProfileSuccessLocked({
|
|
1316
|
+
agentId,
|
|
1317
|
+
state: cooldownState,
|
|
1318
|
+
profileId: selectedProfileId,
|
|
1319
|
+
provider: args.provider,
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
log.info("turn settled", {
|
|
1323
|
+
agentId,
|
|
1324
|
+
sessionId: resolved.sessionId,
|
|
1325
|
+
provider: args.provider,
|
|
1326
|
+
model: args.modelId,
|
|
1327
|
+
});
|
|
1328
|
+
emitAgentEvent({
|
|
1329
|
+
type: "turn-settled",
|
|
1330
|
+
runId,
|
|
1331
|
+
agentId,
|
|
1332
|
+
sessionId: resolved.sessionId,
|
|
1333
|
+
provider: args.provider,
|
|
1334
|
+
modelId: args.modelId,
|
|
1335
|
+
});
|
|
1336
|
+
// Release the Pi listener now rather than waiting for GC. On error
|
|
1337
|
+
// paths the function exits without reaching here, but the session
|
|
1338
|
+
// goes out of scope so the listener is collected eventually — no
|
|
1339
|
+
// long-lived leak in the gateway's process.
|
|
1340
|
+
detachPiForwarder();
|
|
1341
|
+
// Build the user-facing reply. Zero-continuation fast path: the whole
|
|
1342
|
+
// answer is the single last assistant message. When the model hit its
|
|
1343
|
+
// output cap and we drove one or more continuations, the answer is split
|
|
1344
|
+
// across the assistant messages produced THIS turn (the truncated head +
|
|
1345
|
+
// each continuation segment) — concatenate them so callers (channels,
|
|
1346
|
+
// dispatcher, server) receive the COMPLETE response, not just the last
|
|
1347
|
+
// segment. messageCountBeforeTurn is the transcript length captured before
|
|
1348
|
+
// the first prompt, so the join starts at this turn's first new message.
|
|
1349
|
+
const reply = continuations > 0
|
|
1350
|
+
? joinAssistantTextFrom(session, messageCountBeforeTurn)
|
|
1351
|
+
: extractLastAssistantText(session);
|
|
1352
|
+
// After-turn lifecycle:
|
|
1353
|
+
//
|
|
1354
|
+
// 1. If we just delivered the full bootstrap context to this session
|
|
1355
|
+
// (workspace was first-turn AND session hadn't received it before),
|
|
1356
|
+
// emit the per-session marker into the JSONL transcript. Subsequent
|
|
1357
|
+
// turns short-circuit the nudge because the model already has the
|
|
1358
|
+
// context cached.
|
|
1359
|
+
if (phaseBefore === "first-turn" && !sessionAlreadyHasBootstrap) {
|
|
1360
|
+
markBootstrapDeliveredToSession(sessionManager);
|
|
1361
|
+
}
|
|
1362
|
+
// 2. Stamp setupCompletedAt the first time we observe BOOTSTRAP.md is
|
|
1363
|
+
// gone after seeding. The check fires on EVERY turn (not just on a
|
|
1364
|
+
// within-turn first-turn → complete transition) because BOOTSTRAP.md
|
|
1365
|
+
// can be deleted out of band — by the user from another shell, or
|
|
1366
|
+
// by the previous turn's reply. markSetupCompleted is idempotent.
|
|
1367
|
+
const phaseAfter = await evaluateBootstrapPhase(workspaceDir);
|
|
1368
|
+
if (phaseAfter === "complete") {
|
|
1369
|
+
await markSetupCompleted(workspaceDir);
|
|
1370
|
+
}
|
|
1371
|
+
return {
|
|
1372
|
+
sessionId: resolved.sessionId,
|
|
1373
|
+
sessionKey: resolved.sessionKey,
|
|
1374
|
+
isNewSession: resolved.isNew,
|
|
1375
|
+
reply,
|
|
1376
|
+
messages: session.messages.slice(),
|
|
1377
|
+
};
|
|
1378
|
+
}
|
|
1379
|
+
finally {
|
|
1380
|
+
// Safety net: if anything between subscribe-time and the success-
|
|
1381
|
+
// path detach throws (runWithRetry rejects, AbortError mid-stream,
|
|
1382
|
+
// an exception in the cooldown bookkeeping), the listener still
|
|
1383
|
+
// gets cleaned up here. Idempotent — the success path's explicit
|
|
1384
|
+
// detach above is a no-op once this fires.
|
|
1385
|
+
detachPiForwarder();
|
|
1386
|
+
// Clear the gate context bag so the NEXT turn (which reuses the
|
|
1387
|
+
// session) doesn't see this turn's runId on a refusal that fired
|
|
1388
|
+
// outside a prompt() call (e.g. a steer-triggered tool retry that
|
|
1389
|
+
// races the turn boundary).
|
|
1390
|
+
gateCtxRef.value = {};
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
// Merge two optional ephemeral-suffix strings into one. Auto-recall (Memory
|
|
1394
|
+
// Primitive #4) and the context-engine slot's `systemPromptAddition` (Lane J)
|
|
1395
|
+
// both target the same below-cache-boundary slot; when both are present, we
|
|
1396
|
+
// concatenate with a blank line between so each block reads as its own
|
|
1397
|
+
// section. Either-undefined / both-empty collapses to `undefined` so the
|
|
1398
|
+
// assembler skips the `# Per-turn Notes` block entirely.
|
|
1399
|
+
function mergeEphemeralSuffix(...parts) {
|
|
1400
|
+
const kept = parts
|
|
1401
|
+
.map((p) => p?.trim())
|
|
1402
|
+
.filter((p) => typeof p === "string" && p.length > 0);
|
|
1403
|
+
if (kept.length === 0)
|
|
1404
|
+
return undefined;
|
|
1405
|
+
return kept.join("\n\n");
|
|
1406
|
+
}
|
|
1407
|
+
// Build the per-turn system prompt. Three steps:
|
|
1408
|
+
// 1. Honour an explicit override in brigade.json (escape hatch — replaces
|
|
1409
|
+
// the assembled prompt entirely).
|
|
1410
|
+
// 2. Otherwise load workspace persona files + heartbeat + runtime, run
|
|
1411
|
+
// them through the assembler.
|
|
1412
|
+
// 3. Empty workspace → return empty so Pi keeps its stock prompt rather
|
|
1413
|
+
// than getting an empty system message it might balk at.
|
|
1414
|
+
async function buildPersonaPrompt(args) {
|
|
1415
|
+
const config = args.config ?? readConfigOrInit();
|
|
1416
|
+
const override = resolveSystemPromptOverride({ config, agentId: args.agentId });
|
|
1417
|
+
if (override)
|
|
1418
|
+
return override;
|
|
1419
|
+
// Primitive #6 — sub-agent mode flips three things in the assembled prompt:
|
|
1420
|
+
// 1. The persona loader drops BOOTSTRAP.md + MEMORY.md (operator-only).
|
|
1421
|
+
// 2. The heartbeat file is skipped entirely (parent's cycle state).
|
|
1422
|
+
// 3. The assembler swaps the identity opener for the SUB-AGENT banner and
|
|
1423
|
+
// gates off operator-only sections (CLI quick ref, execution bias,
|
|
1424
|
+
// output formatting, per-family identity override, memory wrapper).
|
|
1425
|
+
const subagentMode = args.capabilities?.subagentMode === true;
|
|
1426
|
+
const cronMode = args.capabilities?.cronMode === true;
|
|
1427
|
+
const lightContext = args.lightContext === true;
|
|
1428
|
+
// Cron-mode + lightContext drops the entire persona set; cron-mode alone
|
|
1429
|
+
// still loads persona files (operator wants the agent to behave with its
|
|
1430
|
+
// configured voice, just without the operator-onboarding ritual).
|
|
1431
|
+
const personaFiles = lightContext
|
|
1432
|
+
? []
|
|
1433
|
+
: await loadWorkspaceContextFiles(args.workspaceDir, { subagentMode: subagentMode || cronMode });
|
|
1434
|
+
const heartbeatFile = (subagentMode || cronMode || lightContext)
|
|
1435
|
+
? undefined
|
|
1436
|
+
: await loadHeartbeatFile(args.workspaceDir);
|
|
1437
|
+
if (personaFiles.length === 0 && !heartbeatFile)
|
|
1438
|
+
return "";
|
|
1439
|
+
const runtime = resolveRuntimeParams({
|
|
1440
|
+
agentId: args.agentId,
|
|
1441
|
+
workspaceDir: args.workspaceDir,
|
|
1442
|
+
cwd: args.cwd,
|
|
1443
|
+
modelLabel: args.modelLabel,
|
|
1444
|
+
thinkingLevel: args.thinkingLevel,
|
|
1445
|
+
});
|
|
1446
|
+
// Stage-B virtual-office layer. ADDITIVE-CONDITIONAL: when
|
|
1447
|
+
// `config.org` is absent (the default for every existing install),
|
|
1448
|
+
// `deriveOrgGraph` returns `undefined` and the assembler's `## Org`
|
|
1449
|
+
// block emits ZERO bytes. Sub-agent runs get a one-line anchor merged
|
|
1450
|
+
// into `ephemeralSuffix` instead of the full block. Existing callers
|
|
1451
|
+
// see no behavioural change when `cfg.org` is absent.
|
|
1452
|
+
const orgGraph = config.org ? deriveOrgDisplayGraph(config) : undefined;
|
|
1453
|
+
// Sub-agent anchor: when this turn IS a sub-agent run AND we have an
|
|
1454
|
+
// org graph, append a one-line "Spawned by <id>, inheriting <dept>"
|
|
1455
|
+
// anchor to the ephemeral suffix (below the cache boundary, so the
|
|
1456
|
+
// sub-agent's cached prefix stays identical to the legacy shape).
|
|
1457
|
+
let effectiveEphemeralSuffix = args.ephemeralSuffix;
|
|
1458
|
+
if (subagentMode && orgGraph) {
|
|
1459
|
+
const anchor = renderSubAgentAnchor(orgGraph, args.agentId);
|
|
1460
|
+
if (anchor) {
|
|
1461
|
+
effectiveEphemeralSuffix =
|
|
1462
|
+
effectiveEphemeralSuffix && effectiveEphemeralSuffix.trim().length > 0
|
|
1463
|
+
? `${anchor}\n\n${effectiveEphemeralSuffix}`
|
|
1464
|
+
: anchor;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
// OC mirror: the system prompt does NOT enumerate peers. The model
|
|
1468
|
+
// learns the agent catalog exclusively by calling `agents_list`
|
|
1469
|
+
// (allowlist-scoped) + the Runtime line's `agent=<id>` field. This is
|
|
1470
|
+
// the deliberate anti-hallucination contract — no inline catalog means
|
|
1471
|
+
// no stale-roster drift.
|
|
1472
|
+
const assembled = assembleSystemPrompt({
|
|
1473
|
+
runtime,
|
|
1474
|
+
personaFiles,
|
|
1475
|
+
heartbeatFile,
|
|
1476
|
+
toolDescriptions: args.toolDescriptions ?? [],
|
|
1477
|
+
bootstrapPhase: args.bootstrapPhase,
|
|
1478
|
+
// Pass the raw model id + thinking level so the assembler's
|
|
1479
|
+
// `pickModelFamilyGuidance` (OpenAI / Google identity-override blocks)
|
|
1480
|
+
// and conditional-capability gates fire on the right matches.
|
|
1481
|
+
modelId: args.modelId,
|
|
1482
|
+
thinkingLevel: args.thinkingLevel,
|
|
1483
|
+
capabilities: args.capabilities,
|
|
1484
|
+
skillsPromptBlock: args.skillsPromptBlock,
|
|
1485
|
+
ephemeralSuffix: effectiveEphemeralSuffix,
|
|
1486
|
+
...(args.channels !== undefined ? { channels: args.channels } : {}),
|
|
1487
|
+
// Stage-B: when `cfg.org` is present, hand the derived graph to the
|
|
1488
|
+
// assembler so its conditional `## Org` block can render. Undefined
|
|
1489
|
+
// in legacy mode → assembler skips the block (zero-cost no-op).
|
|
1490
|
+
...(orgGraph !== undefined ? { orgGraph } : {}),
|
|
1491
|
+
});
|
|
1492
|
+
return assembled.text;
|
|
1493
|
+
}
|
|
1494
|
+
function buildAuthStorage(authProfilesPath, cooldownFilter, agentId) {
|
|
1495
|
+
const { credentials, selectedProfileId } = readAuthProfilesAsCredentialMap(authProfilesPath, cooldownFilter, agentId);
|
|
1496
|
+
const Storage = AuthStorage;
|
|
1497
|
+
let storage;
|
|
1498
|
+
if (typeof Storage.inMemory === "function") {
|
|
1499
|
+
storage = Storage.inMemory(credentials);
|
|
1500
|
+
}
|
|
1501
|
+
else if (typeof Storage.fromStorage === "function") {
|
|
1502
|
+
// Fallback path for Pi minors that removed inMemory.
|
|
1503
|
+
storage = Storage.fromStorage({
|
|
1504
|
+
withLock(update) {
|
|
1505
|
+
const { result } = update(JSON.stringify(credentials, null, 2));
|
|
1506
|
+
return result;
|
|
1507
|
+
},
|
|
1508
|
+
});
|
|
1509
|
+
}
|
|
1510
|
+
else {
|
|
1511
|
+
throw new Error("Pi AuthStorage exposes neither inMemory nor fromStorage; pin to 0.70.x or update brigade.");
|
|
1512
|
+
}
|
|
1513
|
+
return { storage, selectedProfileId };
|
|
1514
|
+
}
|
|
1515
|
+
export function readAuthProfilesAsCredentialMap(authProfilesPath, cooldownFilter, agentId) {
|
|
1516
|
+
const out = {};
|
|
1517
|
+
let selectedProfileId;
|
|
1518
|
+
let parsed = {};
|
|
1519
|
+
// Convex mode — no auth-profiles.json on disk; the secrets live as sealed
|
|
1520
|
+
// columns mirrored into the in-process cache at boot. Route through the
|
|
1521
|
+
// mode-aware `readProfiles` choke point so the credential map is populated
|
|
1522
|
+
// identically to filesystem mode. Requires the agentId (the path can't be
|
|
1523
|
+
// reverse-mapped reliably); falls back to the fs read when it's absent.
|
|
1524
|
+
if (agentId && tryGetRuntimeContext()?.mode === "convex") {
|
|
1525
|
+
try {
|
|
1526
|
+
parsed = readProfiles(agentId);
|
|
1527
|
+
}
|
|
1528
|
+
catch {
|
|
1529
|
+
parsed = {};
|
|
1530
|
+
}
|
|
1531
|
+
}
|
|
1532
|
+
else if (fs.existsSync(authProfilesPath)) {
|
|
1533
|
+
try {
|
|
1534
|
+
parsed = JSON.parse(fs.readFileSync(authProfilesPath, "utf8"));
|
|
1535
|
+
}
|
|
1536
|
+
catch {
|
|
1537
|
+
// Treat a corrupt profile file the same as a missing one — env fallback
|
|
1538
|
+
// below still gets a chance to surface a working key.
|
|
1539
|
+
parsed = {};
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
// Bucket profiles by provider so we can apply the cooldown ordering before
|
|
1543
|
+
// collapsing to "first wins" per provider.
|
|
1544
|
+
const byProvider = new Map();
|
|
1545
|
+
for (const [profileId, profile] of Object.entries(parsed.profiles ?? {})) {
|
|
1546
|
+
if (!profile?.provider || profile.type !== "api_key")
|
|
1547
|
+
continue;
|
|
1548
|
+
const resolvedKey = resolveCredentialSecret(profile.key, profile.keyRef, profile.provider);
|
|
1549
|
+
if (!resolvedKey)
|
|
1550
|
+
continue;
|
|
1551
|
+
const list = byProvider.get(profile.provider) ?? [];
|
|
1552
|
+
list.push({ profileId, provider: profile.provider, resolvedKey });
|
|
1553
|
+
byProvider.set(profile.provider, list);
|
|
1554
|
+
}
|
|
1555
|
+
for (const [provider, list] of byProvider) {
|
|
1556
|
+
if (cooldownFilter && provider === cooldownFilter.provider) {
|
|
1557
|
+
const ordered = orderProfilesForSelection({
|
|
1558
|
+
state: cooldownFilter.cooldownState,
|
|
1559
|
+
provider,
|
|
1560
|
+
profileIds: list.map((p) => p.profileId),
|
|
1561
|
+
forModel: cooldownFilter.modelId,
|
|
1562
|
+
});
|
|
1563
|
+
// Pick the first eligible profile (orderProfilesForSelection puts
|
|
1564
|
+
// eligibles first, then cooled by soonest-expiry as probes).
|
|
1565
|
+
let selected = list.find((p) => p.profileId === ordered[0]);
|
|
1566
|
+
// If the cooldown filter excluded everyone, fall back to the first
|
|
1567
|
+
// available so the run gets at least one attempt.
|
|
1568
|
+
if (!selected)
|
|
1569
|
+
selected = list[0];
|
|
1570
|
+
if (selected) {
|
|
1571
|
+
out[provider] = { type: "api_key", key: selected.resolvedKey };
|
|
1572
|
+
selectedProfileId = selected.profileId;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
else {
|
|
1576
|
+
const first = list[0];
|
|
1577
|
+
if (first)
|
|
1578
|
+
out[provider] = { type: "api_key", key: first.resolvedKey };
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
// C5: env-fallback. If no profile-stored key surfaced for a known provider
|
|
1582
|
+
// but the user has e.g. `ANTHROPIC_API_KEY` exported in their shell, return
|
|
1583
|
+
// that key so a fresh agent with no auth-profiles.json entry still boots
|
|
1584
|
+
// instead of failing with a 401. Mirrors core/auth-bridge.ts:91-97.
|
|
1585
|
+
for (const provider of PROVIDERS) {
|
|
1586
|
+
if (!provider.envVar || provider.noAuth)
|
|
1587
|
+
continue;
|
|
1588
|
+
if (out[provider.id] !== undefined)
|
|
1589
|
+
continue;
|
|
1590
|
+
const apiKey = process.env[provider.envVar];
|
|
1591
|
+
if (!apiKey)
|
|
1592
|
+
continue;
|
|
1593
|
+
out[provider.id] = { type: "api_key", key: apiKey };
|
|
1594
|
+
}
|
|
1595
|
+
return { credentials: out, selectedProfileId };
|
|
1596
|
+
}
|
|
1597
|
+
// Resolve a profile's api-key secret across both persisted shapes:
|
|
1598
|
+
// • literal `key` → returned verbatim
|
|
1599
|
+
// • string `keyRef` (legacy `${VAR}`) → env-expanded
|
|
1600
|
+
// • object `keyRef` (BrigadeSecretRef) → env-source resolved by `id`
|
|
1601
|
+
// File/exec backends need an async resolver and are out of scope for this
|
|
1602
|
+
// synchronous credential-map build (they surface "no key" → env fallback).
|
|
1603
|
+
function resolveCredentialSecret(key, keyRef, provider) {
|
|
1604
|
+
if (key && key.length > 0)
|
|
1605
|
+
return key;
|
|
1606
|
+
if (!keyRef)
|
|
1607
|
+
return "";
|
|
1608
|
+
if (typeof keyRef === "string")
|
|
1609
|
+
return expandEnvRef(keyRef, provider);
|
|
1610
|
+
if (keyRef.source === "env" && keyRef.id)
|
|
1611
|
+
return process.env[keyRef.id] ?? "";
|
|
1612
|
+
return "";
|
|
1613
|
+
}
|
|
1614
|
+
const ENV_REF_PATTERN = /^\$\{([A-Z_][A-Z0-9_]*)\}$/;
|
|
1615
|
+
// Resolve a literal-or-${VAR} secret. If the value is a `${VAR}` reference
|
|
1616
|
+
// and the env var isn't set, log a warning to stderr so the user gets a
|
|
1617
|
+
// breadcrumb pointing at the missing env var instead of a downstream
|
|
1618
|
+
// "no API key found" from Pi with no context about *why*.
|
|
1619
|
+
function expandEnvRef(value, provider) {
|
|
1620
|
+
const m = ENV_REF_PATTERN.exec(value);
|
|
1621
|
+
if (!m || !m[1])
|
|
1622
|
+
return value;
|
|
1623
|
+
const resolved = process.env[m[1]] ?? "";
|
|
1624
|
+
if (!resolved) {
|
|
1625
|
+
console.error(`brigade: auth profile for ${provider} references ${value} ` +
|
|
1626
|
+
`but the env var isn't set; the profile will be skipped.`);
|
|
1627
|
+
}
|
|
1628
|
+
return resolved;
|
|
1629
|
+
}
|
|
1630
|
+
function buildModelRegistry(authStorage, modelsFile) {
|
|
1631
|
+
const Registry = ModelRegistry;
|
|
1632
|
+
if (typeof Registry.create === "function") {
|
|
1633
|
+
return Registry.create(authStorage, modelsFile);
|
|
1634
|
+
}
|
|
1635
|
+
return new Registry(authStorage, modelsFile);
|
|
1636
|
+
}
|
|
1637
|
+
// Both flags must clear for the turn to be considered done. prompt() is
|
|
1638
|
+
// supposed to resolve only after settle, so this loop almost always exits
|
|
1639
|
+
// on the first iteration. The 30s budget guards against the pathological
|
|
1640
|
+
// case where Pi enters an unbounded compaction or a streaming hang we'd
|
|
1641
|
+
// otherwise wait on forever.
|
|
1642
|
+
const STREAM_SETTLE_BUDGET_MS = 30_000;
|
|
1643
|
+
const STREAM_SETTLE_POLL_MS = 50;
|
|
1644
|
+
async function waitForStreamSettled(session) {
|
|
1645
|
+
const deadline = Date.now() + STREAM_SETTLE_BUDGET_MS;
|
|
1646
|
+
while (Date.now() < deadline) {
|
|
1647
|
+
if (!session.isStreaming && !session.isCompacting)
|
|
1648
|
+
return;
|
|
1649
|
+
await sleep(STREAM_SETTLE_POLL_MS);
|
|
1650
|
+
}
|
|
1651
|
+
throw new Error(`Turn did not settle within ${STREAM_SETTLE_BUDGET_MS / 1000}s ` +
|
|
1652
|
+
`(isStreaming=${session.isStreaming} isCompacting=${session.isCompacting}). ` +
|
|
1653
|
+
`Likely a hung provider connection — abort the run and retry.`);
|
|
1654
|
+
}
|
|
1655
|
+
// Surface a provider/transport failure that Pi reports as DATA rather than a
|
|
1656
|
+
// thrown exception.
|
|
1657
|
+
//
|
|
1658
|
+
// Pi emits provider/transport failures as a SETTLED assistant message
|
|
1659
|
+
// with `stopReason: "error"` and an `errorMessage` — not an exception,
|
|
1660
|
+
// and not an intentionally-empty reply. A failover layer can inspect
|
|
1661
|
+
// `stopReason`/`errorMessage` to decide retry → rotate → fallback-model
|
|
1662
|
+
// → surface.
|
|
1663
|
+
//
|
|
1664
|
+
// Brigade reaches the same outcome through its existing throw-based machinery:
|
|
1665
|
+
// we convert that error-as-data into a thrown error carrying the cleaned
|
|
1666
|
+
// provider message, so it flows into `error-classifier` → `runWithRetry`
|
|
1667
|
+
// (transient like rate_limit/overloaded/timeout → retried) and, in the
|
|
1668
|
+
// resilient path, `runWithModelFallback` (→ failover to the next model);
|
|
1669
|
+
// a permanent failure (model_not_found / auth) is surfaced to the caller
|
|
1670
|
+
// instead of being mistaken for a content-quality "empty" and returning blank.
|
|
1671
|
+
// `"aborted"` is user-initiated (Ctrl-C / disconnect) and is left alone.
|
|
1672
|
+
function assertNoProviderErrorStop(session) {
|
|
1673
|
+
const messages = session.messages;
|
|
1674
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1675
|
+
const m = messages[i];
|
|
1676
|
+
if (!m || m.role !== "assistant")
|
|
1677
|
+
continue;
|
|
1678
|
+
if (m.stopReason === "error") {
|
|
1679
|
+
const raw = m.errorMessage?.trim();
|
|
1680
|
+
// cleanProviderError peels the provider's JSON error blob down to
|
|
1681
|
+
// its human-readable message so the classifier matches on real
|
|
1682
|
+
// text and the user sees a readable line, not a raw payload.
|
|
1683
|
+
throw new Error(raw
|
|
1684
|
+
? cleanProviderError(raw)
|
|
1685
|
+
: "the model returned an error with no detail (the provider request failed before producing any output)");
|
|
1686
|
+
}
|
|
1687
|
+
// Most recent assistant message settled normally — nothing to surface.
|
|
1688
|
+
return;
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
function extractLastAssistantText(session) {
|
|
1692
|
+
const messages = session.messages;
|
|
1693
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1694
|
+
const m = messages[i];
|
|
1695
|
+
if (m?.role !== "assistant")
|
|
1696
|
+
continue;
|
|
1697
|
+
return flattenAssistantContent(m.content);
|
|
1698
|
+
}
|
|
1699
|
+
return "";
|
|
1700
|
+
}
|
|
1701
|
+
// Concatenate the text of every assistant message from `fromIndex` forward.
|
|
1702
|
+
// Used by the max_tokens continuation path: a capped reply driven across N
|
|
1703
|
+
// continuations lands as N separate assistant messages (each prompt() runs a
|
|
1704
|
+
// fresh agent loop that pushes a new message), so the complete answer is the
|
|
1705
|
+
// JOIN of those segments — not the last one. flattenAssistantContent already
|
|
1706
|
+
// keeps only text blocks, so interleaved tool_use blocks don't pollute the
|
|
1707
|
+
// concatenation. Segments are joined with a blank line so a hard wrap between
|
|
1708
|
+
// two segments doesn't fuse the last word of one onto the first of the next.
|
|
1709
|
+
function joinAssistantTextFrom(session, fromIndex) {
|
|
1710
|
+
const messages = session.messages;
|
|
1711
|
+
const start = Math.max(0, fromIndex);
|
|
1712
|
+
const parts = [];
|
|
1713
|
+
for (let i = start; i < messages.length; i++) {
|
|
1714
|
+
const m = messages[i];
|
|
1715
|
+
if (m?.role !== "assistant")
|
|
1716
|
+
continue;
|
|
1717
|
+
const text = flattenAssistantContent(m.content);
|
|
1718
|
+
if (text.length > 0)
|
|
1719
|
+
parts.push(text);
|
|
1720
|
+
}
|
|
1721
|
+
return parts.join("\n\n");
|
|
1722
|
+
}
|
|
1723
|
+
function flattenAssistantContent(content) {
|
|
1724
|
+
if (typeof content === "string")
|
|
1725
|
+
return content;
|
|
1726
|
+
if (!Array.isArray(content))
|
|
1727
|
+
return "";
|
|
1728
|
+
const parts = [];
|
|
1729
|
+
for (const block of content) {
|
|
1730
|
+
if (typeof block === "string") {
|
|
1731
|
+
parts.push(block);
|
|
1732
|
+
continue;
|
|
1733
|
+
}
|
|
1734
|
+
if (block && typeof block === "object") {
|
|
1735
|
+
const b = block;
|
|
1736
|
+
if (b.type === "text" && typeof b.text === "string")
|
|
1737
|
+
parts.push(b.text);
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
return parts.join("");
|
|
1741
|
+
}
|
|
1742
|
+
function sleep(ms) {
|
|
1743
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1744
|
+
}
|
|
1745
|
+
export async function runResilientTurn(args) {
|
|
1746
|
+
const fallbacks = args.fallbacks ?? [];
|
|
1747
|
+
if (fallbacks.length === 0) {
|
|
1748
|
+
return runSingleTurn(args);
|
|
1749
|
+
}
|
|
1750
|
+
// Lift the run inside runWithModelFallback's `attempt` callback. Each
|
|
1751
|
+
// candidate gets its own runSingleTurn invocation — fresh session, fresh
|
|
1752
|
+
// credential map, fresh stream wrappers. The cost is one extra session
|
|
1753
|
+
// open per failed candidate, which is fine since fallbacks are rare.
|
|
1754
|
+
const fallbackResult = await runWithModelFallback({
|
|
1755
|
+
primary: { provider: args.provider, model: args.modelId, isPrimary: true },
|
|
1756
|
+
fallbacks: fallbacks.map((f) => ({
|
|
1757
|
+
provider: f.provider,
|
|
1758
|
+
model: f.modelId,
|
|
1759
|
+
isPrimary: false,
|
|
1760
|
+
})),
|
|
1761
|
+
signal: args.signal,
|
|
1762
|
+
attempt: async (candidate, signal) => {
|
|
1763
|
+
const r = await runSingleTurn({
|
|
1764
|
+
...args,
|
|
1765
|
+
provider: candidate.provider,
|
|
1766
|
+
modelId: candidate.model,
|
|
1767
|
+
signal,
|
|
1768
|
+
});
|
|
1769
|
+
return r;
|
|
1770
|
+
},
|
|
1771
|
+
});
|
|
1772
|
+
return {
|
|
1773
|
+
...fallbackResult.result,
|
|
1774
|
+
servedBy: {
|
|
1775
|
+
provider: fallbackResult.candidate.provider,
|
|
1776
|
+
modelId: fallbackResult.candidate.model,
|
|
1777
|
+
},
|
|
1778
|
+
fallbackAttempts: fallbackResult.attempts.map((a) => ({
|
|
1779
|
+
provider: a.provider,
|
|
1780
|
+
modelId: a.model,
|
|
1781
|
+
reason: a.reason,
|
|
1782
|
+
error: a.errorSummary,
|
|
1783
|
+
})),
|
|
1784
|
+
};
|
|
1785
|
+
}
|
|
1786
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1787
|
+
// Compaction trigger.
|
|
1788
|
+
//
|
|
1789
|
+
// Estimate whether context usage has crossed the 85% trigger threshold and,
|
|
1790
|
+
// if so, ask Pi to compact NOW rather than discovering mid-turn that we've
|
|
1791
|
+
// blown the window. The estimator walks the session messages and divides
|
|
1792
|
+
// total stringified char-count by 4 (rough chars-per-token across modern
|
|
1793
|
+
// tokenizers). Imprecise but conservative — over-compacting is cheaper
|
|
1794
|
+
// than running out of context.
|
|
1795
|
+
//
|
|
1796
|
+
// Pi's auto-compaction handles the actual fallback if the request exceeds
|
|
1797
|
+
// the window despite this pre-emptive check; this module's value is in
|
|
1798
|
+
// avoiding the "we're streaming and it failed" failure mode by compacting
|
|
1799
|
+
// at a calm boundary instead.
|
|
1800
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
1801
|
+
const APPROX_CHARS_PER_TOKEN = 4;
|
|
1802
|
+
async function maybeTriggerCompaction(args) {
|
|
1803
|
+
const contextWindow = args.model?.contextWindow;
|
|
1804
|
+
if (!contextWindow || !Number.isFinite(contextWindow) || contextWindow <= 0) {
|
|
1805
|
+
// No context window metadata — skip; Pi's auto-compaction is the
|
|
1806
|
+
// fallback if usage actually overflows.
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
// Estimate the FULL request: the transcript PLUS the pinned system prompt
|
|
1810
|
+
// PLUS the about-to-be-sent user message. The latter two are absent from
|
|
1811
|
+
// session.messages but present on every request, so folding them in keeps
|
|
1812
|
+
// the 0.85 trigger from firing systematically late (and falling through to
|
|
1813
|
+
// Pi's mid-stream auto-compaction). Same chars/APPROX_CHARS_PER_TOKEN
|
|
1814
|
+
// heuristic estimateUsageTokens uses, so the units line up.
|
|
1815
|
+
const prePromptChars = (args.systemPrompt?.length ?? 0) + (args.incomingMessage?.length ?? 0);
|
|
1816
|
+
const estimatedTokens = estimateUsageTokens(args.session.messages) +
|
|
1817
|
+
Math.ceil(prePromptChars / APPROX_CHARS_PER_TOKEN);
|
|
1818
|
+
const decision = evaluateCompactionDecision({
|
|
1819
|
+
contextWindowTokens: contextWindow,
|
|
1820
|
+
estimatedUsageTokens: estimatedTokens,
|
|
1821
|
+
});
|
|
1822
|
+
if (!decision.shouldRecommendCompaction) {
|
|
1823
|
+
log.debug("compaction not needed", {
|
|
1824
|
+
agentId: args.agentId,
|
|
1825
|
+
sessionId: args.sessionId,
|
|
1826
|
+
estimatedTokens,
|
|
1827
|
+
contextWindow,
|
|
1828
|
+
reason: decision.reason,
|
|
1829
|
+
});
|
|
1830
|
+
return;
|
|
1831
|
+
}
|
|
1832
|
+
log.info("triggering pre-emptive compaction", {
|
|
1833
|
+
agentId: args.agentId,
|
|
1834
|
+
sessionId: args.sessionId,
|
|
1835
|
+
estimatedTokens,
|
|
1836
|
+
contextWindow,
|
|
1837
|
+
promptBudgetTokens: decision.promptBudgetTokens,
|
|
1838
|
+
reason: decision.reason,
|
|
1839
|
+
});
|
|
1840
|
+
try {
|
|
1841
|
+
const compactor = args.session.compact;
|
|
1842
|
+
if (typeof compactor !== "function") {
|
|
1843
|
+
log.warn("session has no compact() method — skipping", {
|
|
1844
|
+
sessionId: args.sessionId,
|
|
1845
|
+
});
|
|
1846
|
+
return;
|
|
1847
|
+
}
|
|
1848
|
+
// PRE-COMPACTION extraction — distil the about-to-be-replaced history NOW so a
|
|
1849
|
+
// fact living ONLY in these turns isn't lost when compact() swaps them for a
|
|
1850
|
+
// summary. Fire-and-forget over a SNAPSHOT (no turn latency, no race with the
|
|
1851
|
+
// replace). Skipped when origin is undefined (unidentified peer → fail closed).
|
|
1852
|
+
if (args.origin) {
|
|
1853
|
+
runPreCompactionExtraction({
|
|
1854
|
+
agentId: args.agentId,
|
|
1855
|
+
sessionId: args.sessionId,
|
|
1856
|
+
messages: [...args.session.messages],
|
|
1857
|
+
origin: args.origin,
|
|
1858
|
+
});
|
|
1859
|
+
}
|
|
1860
|
+
await compactor.call(args.session);
|
|
1861
|
+
log.info("pre-emptive compaction completed", {
|
|
1862
|
+
agentId: args.agentId,
|
|
1863
|
+
sessionId: args.sessionId,
|
|
1864
|
+
});
|
|
1865
|
+
}
|
|
1866
|
+
catch (err) {
|
|
1867
|
+
// Compaction failure isn't fatal — Pi's auto-compaction gets a chance
|
|
1868
|
+
// to run during the prompt, and worst case the request fails with a
|
|
1869
|
+
// context-window error that the retry policy classifies as transient.
|
|
1870
|
+
log.warn("pre-emptive compaction failed; proceeding anyway", {
|
|
1871
|
+
agentId: args.agentId,
|
|
1872
|
+
sessionId: args.sessionId,
|
|
1873
|
+
error: err.message,
|
|
1874
|
+
});
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
function estimateUsageTokens(messages) {
|
|
1878
|
+
if (!Array.isArray(messages))
|
|
1879
|
+
return 0;
|
|
1880
|
+
let chars = 0;
|
|
1881
|
+
for (const m of messages) {
|
|
1882
|
+
if (!m)
|
|
1883
|
+
continue;
|
|
1884
|
+
chars += approxMessageChars(m);
|
|
1885
|
+
}
|
|
1886
|
+
return Math.ceil(chars / APPROX_CHARS_PER_TOKEN);
|
|
1887
|
+
}
|
|
1888
|
+
// Detect whether the most-recent assistant message ended on a max_tokens
|
|
1889
|
+
// stop reason. We check both the assistant message's `stopReason` field
|
|
1890
|
+
// (Pi's normalised key) and the raw `stop_reason` (provider passthrough)
|
|
1891
|
+
// because not all Pi minors normalise consistently.
|
|
1892
|
+
function detectMaxTokensStop(session) {
|
|
1893
|
+
const messages = session.messages;
|
|
1894
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
1895
|
+
const m = messages[i];
|
|
1896
|
+
if (!m || m.role !== "assistant")
|
|
1897
|
+
continue;
|
|
1898
|
+
const reason = (m.stopReason ?? m.stop_reason ?? "").toLowerCase();
|
|
1899
|
+
return reason === "max_tokens";
|
|
1900
|
+
}
|
|
1901
|
+
return false;
|
|
1902
|
+
}
|
|
1903
|
+
function approxMessageChars(message) {
|
|
1904
|
+
if (typeof message === "string")
|
|
1905
|
+
return message.length;
|
|
1906
|
+
if (!message || typeof message !== "object")
|
|
1907
|
+
return 0;
|
|
1908
|
+
const m = message;
|
|
1909
|
+
const content = m.content;
|
|
1910
|
+
if (typeof content === "string")
|
|
1911
|
+
return content.length;
|
|
1912
|
+
if (!Array.isArray(content))
|
|
1913
|
+
return 0;
|
|
1914
|
+
let total = 0;
|
|
1915
|
+
for (const block of content) {
|
|
1916
|
+
if (typeof block === "string") {
|
|
1917
|
+
total += block.length;
|
|
1918
|
+
continue;
|
|
1919
|
+
}
|
|
1920
|
+
if (!block || typeof block !== "object")
|
|
1921
|
+
continue;
|
|
1922
|
+
const b = block;
|
|
1923
|
+
if (typeof b.text === "string")
|
|
1924
|
+
total += b.text.length;
|
|
1925
|
+
if (typeof b.content === "string")
|
|
1926
|
+
total += b.content.length;
|
|
1927
|
+
if (b.input !== undefined) {
|
|
1928
|
+
try {
|
|
1929
|
+
total += JSON.stringify(b.input).length;
|
|
1930
|
+
}
|
|
1931
|
+
catch {
|
|
1932
|
+
// ignore unserialisable
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
return total;
|
|
1937
|
+
}
|
|
1938
|
+
//# sourceMappingURL=agent-loop.js.map
|