@cohortapp/agent-sdk 2.17.0 → 2.18.4
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/.claude/settings.json +18 -0
- package/.env.example +18 -5
- package/README.md +1 -0
- package/bin/maestro.mjs +62 -0
- package/docs/guides/billing-console-keys.md +60 -0
- package/docs/guides/front-door-session.md +54 -9
- package/docs/guides/mac-mini.md +20 -25
- package/docs/guides/setup-wizard.md +1 -1
- package/docs/runbooks/fleet-rollout.md +156 -0
- package/docs/runbooks/mac-mini-bootstrap.md +12 -14
- package/lib/action-executor.js +19 -3
- package/lib/budget-guard.mjs +279 -3
- package/lib/channels/base-adapter.mjs +3 -1
- package/lib/channels/contract.mjs +2 -1
- package/lib/channels/inbox-item.mjs +8 -0
- package/lib/claude-bin.mjs +5 -6
- package/lib/cli/doctor-checks.mjs +141 -10
- package/lib/cli/global-setup-extras.mjs +5 -1
- package/lib/cli/inbox.mjs +100 -15
- package/lib/cli/seat-auth.mjs +463 -0
- package/lib/cli/session.mjs +80 -12
- package/lib/collective/capture.mjs +8 -6
- package/lib/collective/global-config.mjs +63 -1
- package/lib/collective/presence.mjs +142 -5
- package/lib/comms/send-gate.mjs +559 -1
- package/lib/diagnostics/alerts.mjs +49 -0
- package/lib/diagnostics/cadence-output-freshness.mjs +288 -0
- package/lib/engine/agents/definitions.mjs +343 -0
- package/lib/engine/agents/persist.mjs +275 -0
- package/lib/engine/agents/runtime.mjs +748 -0
- package/lib/engine/agents/usage.mjs +95 -0
- package/lib/engine/auth-status.mjs +139 -0
- package/lib/engine/budget.mjs +194 -0
- package/lib/engine/cli.mjs +1204 -0
- package/lib/engine/commands/index.mjs +269 -0
- package/lib/engine/context/budget.mjs +219 -0
- package/lib/engine/context/cache.mjs +125 -0
- package/lib/engine/context/child-env.mjs +215 -0
- package/lib/engine/context/compaction.mjs +342 -0
- package/lib/engine/context/images.mjs +90 -0
- package/lib/engine/context/instructions.mjs +327 -0
- package/lib/engine/context/lazy-instructions.mjs +169 -0
- package/lib/engine/context/manager.mjs +182 -0
- package/lib/engine/context/real-path.mjs +91 -0
- package/lib/engine/context/secret-values.mjs +163 -0
- package/lib/engine/context/settings.mjs +274 -0
- package/lib/engine/context/stream-input.mjs +159 -0
- package/lib/engine/guard.mjs +152 -0
- package/lib/engine/hooks.mjs +713 -0
- package/lib/engine/loop.mjs +560 -0
- package/lib/engine/mcp/client.mjs +254 -0
- package/lib/engine/mcp/config.mjs +301 -0
- package/lib/engine/mcp/http.mjs +201 -0
- package/lib/engine/mcp/index.mjs +146 -0
- package/lib/engine/mcp/jsonrpc.mjs +147 -0
- package/lib/engine/mcp/naming.mjs +66 -0
- package/lib/engine/mcp/resources.mjs +89 -0
- package/lib/engine/mcp/results.mjs +133 -0
- package/lib/engine/mcp/stdio.mjs +137 -0
- package/lib/engine/mcp/supervisor.mjs +116 -0
- package/lib/engine/messages.mjs +104 -0
- package/lib/engine/output/json.mjs +164 -0
- package/lib/engine/output/stream-json.mjs +266 -0
- package/lib/engine/permissions.mjs +845 -0
- package/lib/engine/process-identity.mjs +164 -0
- package/lib/engine/process-tree.mjs +551 -0
- package/lib/engine/prompt.mjs +60 -0
- package/lib/engine/session/store.mjs +299 -0
- package/lib/engine/session-runtime/args.mjs +97 -0
- package/lib/engine/session-runtime/host.mjs +143 -0
- package/lib/engine/session-runtime/inbox.mjs +122 -0
- package/lib/engine/session-runtime/notifications.mjs +129 -0
- package/lib/engine/session-runtime/registry.mjs +328 -0
- package/lib/engine/session-runtime/runner.mjs +344 -0
- package/lib/engine/session-runtime/socket.mjs +212 -0
- package/lib/engine/session-runtime/wakeup.mjs +115 -0
- package/lib/engine/skills/index.mjs +321 -0
- package/lib/engine/tools/bash-background.mjs +533 -0
- package/lib/engine/tools/bash.mjs +216 -0
- package/lib/engine/tools/edit.mjs +97 -0
- package/lib/engine/tools/glob.mjs +81 -0
- package/lib/engine/tools/grep.mjs +224 -0
- package/lib/engine/tools/index.mjs +84 -0
- package/lib/engine/tools/list-agents.mjs +32 -0
- package/lib/engine/tools/ls.mjs +127 -0
- package/lib/engine/tools/monitor.mjs +82 -0
- package/lib/engine/tools/notebook-edit.mjs +218 -0
- package/lib/engine/tools/read.mjs +103 -0
- package/lib/engine/tools/schedule-wakeup.mjs +45 -0
- package/lib/engine/tools/schema.mjs +144 -0
- package/lib/engine/tools/send-message.mjs +77 -0
- package/lib/engine/tools/session.mjs +70 -0
- package/lib/engine/tools/todo.mjs +144 -0
- package/lib/engine/tools/toolsearch.mjs +217 -0
- package/lib/engine/tools/walk.mjs +193 -0
- package/lib/engine/tools/web-switch.mjs +31 -0
- package/lib/engine/tools/webfetch-html.mjs +387 -0
- package/lib/engine/tools/webfetch-net.mjs +340 -0
- package/lib/engine/tools/webfetch.mjs +198 -0
- package/lib/engine/tools/websearch.mjs +91 -0
- package/lib/engine/tools/workflow.mjs +95 -0
- package/lib/engine/tools/write.mjs +76 -0
- package/lib/engine/tui/line-editor.mjs +137 -0
- package/lib/engine/tui/render.mjs +86 -0
- package/lib/engine/tui/tui.mjs +274 -0
- package/lib/engine/wire/anthropic-messages.mjs +263 -0
- package/lib/engine/wire/effort.mjs +36 -0
- package/lib/engine/wire/errors.mjs +496 -0
- package/lib/engine/wire/http.mjs +441 -0
- package/lib/engine/wire/index.mjs +76 -0
- package/lib/engine/wire/openai-chat.mjs +332 -0
- package/lib/engine/wire/prompt-cache.mjs +79 -0
- package/lib/engine/wire/search.mjs +140 -0
- package/lib/engine/wire/sse.mjs +114 -0
- package/lib/engine/wire/stall.mjs +349 -0
- package/lib/engine/wire/token-provider.mjs +175 -0
- package/lib/engine/wire/usage.mjs +192 -0
- package/lib/engine/workflow/host.mjs +524 -0
- package/lib/engine/workflow/journal.mjs +188 -0
- package/lib/engine/workflow/json-schema.mjs +171 -0
- package/lib/engine/workflow/meta.mjs +329 -0
- package/lib/engine/workflow/notifications.mjs +52 -0
- package/lib/engine/workflow/runtime.mjs +447 -0
- package/lib/engine/workflow/sandbox.mjs +534 -0
- package/lib/engine/workflow/worker.mjs +141 -0
- package/lib/engine/workflow/worktree.mjs +74 -0
- package/lib/execution/disposition.mjs +1 -1
- package/lib/execution/intake.mjs +10 -0
- package/lib/execution/surface-policy.mjs +15 -0
- package/lib/learning/curator.mjs +8 -6
- package/lib/learning/reflect.mjs +8 -6
- package/lib/model-router/catalog/cohort.yaml +137 -0
- package/lib/model-router/catalog.mjs +118 -1
- package/lib/model-router/failover.mjs +67 -16
- package/lib/model-router/llm-task.mjs +39 -3
- package/lib/model-router/resolve.mjs +89 -3
- package/lib/model-router/spawn.mjs +46 -47
- package/lib/model-router/taxonomy.mjs +126 -4
- package/lib/org/cost-sync.mjs +141 -11
- package/lib/org/inbound/broadcast.mjs +289 -0
- package/lib/org/inbound/collective.mjs +375 -0
- package/lib/org/inbound/directedness.mjs +96 -8
- package/lib/org/inbound/facts.mjs +78 -2
- package/lib/org/inbound/project.mjs +22 -0
- package/lib/org/inbound/surfaces.mjs +14 -0
- package/lib/org/llm-token.mjs +879 -0
- package/lib/org/mesh.mjs +61 -0
- package/lib/org/messaging.mjs +3 -1
- package/lib/org/protocol.checksum +1 -1
- package/lib/org/protocol.mjs +15 -0
- package/lib/org/quota.mjs +520 -0
- package/lib/org/tool-surface.mjs +104 -16
- package/lib/org/ui-parity.mjs +16 -1
- package/lib/org/work-ledger.mjs +37 -6
- package/lib/rate-guard.mjs +114 -1
- package/lib/resource-governor.mjs +41 -6
- package/lib/runtime/adapter.mjs +823 -0
- package/lib/runtime/child-env.mjs +191 -0
- package/lib/runtime/legacy-shell-guard.mjs +97 -0
- package/lib/runtime/seat-engine.mjs +162 -0
- package/lib/session/ask-ledger.mjs +271 -0
- package/lib/session/current-work.mjs +676 -0
- package/lib/session/feed-core.mjs +40 -3
- package/lib/session/launch-args.mjs +56 -4
- package/lib/session/status-summary.mjs +26 -9
- package/lib/session/upgrade-notice.mjs +42 -0
- package/lib/setup/claude-probe.mjs +117 -13
- package/lib/setup/enrich.mjs +13 -10
- package/lib/setup/sections/model.mjs +39 -13
- package/lib/telemetry/collect.mjs +208 -9
- package/lib/upgrade/ignored-drift.mjs +105 -0
- package/lib/voice/post-call-brief.mjs +30 -17
- package/package.json +13 -3
- package/plugins/maestro-skills/skills/board-work.md +5 -0
- package/plugins/maestro-skills/skills/inbound-triage.md +56 -15
- package/plugins/maestro-skills/skills/main-session.md +18 -7
- package/scripts/ci/check-tarball-fidelity.mjs +126 -2
- package/scripts/ci/run-tests.mjs +47 -19
- package/scripts/cohort-llm/api-key-helper.mjs +92 -0
- package/scripts/collective/hook-runner.mjs +29 -2
- package/scripts/continuous-monitor.sh +13 -0
- package/scripts/cost/track-claude-usage.mjs +15 -0
- package/scripts/daemon/agent-daemon.mjs +408 -20
- package/scripts/daemon/assurance.mjs +48 -12
- package/scripts/daemon/cadence-consumer.mjs +218 -68
- package/scripts/daemon/cadence-handlers.mjs +73 -4
- package/scripts/daemon/classifier.mjs +75 -26
- package/scripts/daemon/context-compiler.mjs +51 -37
- package/scripts/daemon/deliver.mjs +30 -1
- package/scripts/daemon/dispatcher.mjs +595 -149
- package/scripts/daemon/health.mjs +14 -1
- package/scripts/daemon/maestro-daemon.mjs +11 -0
- package/scripts/daemon/prompt-builder.mjs +24 -0
- package/scripts/daemon/responder.mjs +246 -79
- package/scripts/daemon/sdk-version.mjs +98 -16
- package/scripts/eval/probe-gateway.mjs +635 -0
- package/scripts/eval/replay/extract.mjs +270 -0
- package/scripts/eval/replay/grade.mjs +260 -0
- package/scripts/eval/replay/lib/config.mjs +50 -0
- package/scripts/eval/replay/lib/effects.mjs +65 -0
- package/scripts/eval/replay/lib/fixture.mjs +188 -0
- package/scripts/eval/replay/lib/judge.mjs +72 -0
- package/scripts/eval/replay/lib/redact.mjs +136 -0
- package/scripts/eval/replay/lib/sandbox.mjs +170 -0
- package/scripts/eval/replay/lib/schema-check.mjs +63 -0
- package/scripts/eval/replay/lib/transcript.mjs +76 -0
- package/scripts/eval/replay/mcp-replay-stub.mjs +101 -0
- package/scripts/eval/replay/report.mjs +185 -0
- package/scripts/eval/replay/run.mjs +404 -0
- package/scripts/fleet/rollout.mjs +1094 -0
- package/scripts/hooks/pre-send-audit.sh +36 -245
- package/scripts/hooks/pre-write-yaml-validate.mjs +275 -0
- package/scripts/hooks/validate-state-yaml.sh +190 -0
- package/scripts/huddle/huddle-llm.mjs +361 -0
- package/scripts/huddle/huddle-server.mjs +46 -121
- package/scripts/local-triggers/autoupdate.sh +448 -78
- package/scripts/local-triggers/run-trigger.sh +13 -0
- package/scripts/maintenance/pin-integrity.mjs +364 -0
- package/scripts/poll-slack-events.sh +41 -9
- package/scripts/poller/slack-socket-mode.mjs +28 -3
- package/scripts/session/supervisor.mjs +80 -13
- package/scripts/spawn-session.sh +13 -0
- package/bin/maestro.test.mjs +0 -1574
- package/lib/action-executor.test.mjs +0 -871
- package/lib/archetype.test.mjs +0 -132
- package/lib/assurance/plan-note.test.mjs +0 -234
- package/lib/assurance/room-budget.test.mjs +0 -486
- package/lib/assurance/tier.test.mjs +0 -174
- package/lib/autonomy.test.mjs +0 -66
- package/lib/backlog.test.mjs +0 -302
- package/lib/backup/policy.test.mjs +0 -305
- package/lib/budget-escalate.test.mjs +0 -232
- package/lib/budget-guard.envelope.test.mjs +0 -476
- package/lib/budget-guard.test.mjs +0 -427
- package/lib/cadence-bus-requeue.test.mjs +0 -83
- package/lib/cadence-bus-schedule.test.mjs +0 -194
- package/lib/cadence-bus.test.mjs +0 -720
- package/lib/cadences.test.mjs +0 -230
- package/lib/capability/inventory.test.mjs +0 -232
- package/lib/capability.test.mjs +0 -78
- package/lib/channels/base-adapter.test.mjs +0 -590
- package/lib/channels/channels.test.mjs +0 -371
- package/lib/channels/contract.test.mjs +0 -162
- package/lib/channels/inbox-item.test.mjs +0 -368
- package/lib/channels/orgmail/adapter.test.mjs +0 -448
- package/lib/channels/pairing.test.mjs +0 -270
- package/lib/channels/repeat-suppressor.test.mjs +0 -134
- package/lib/channels/slack-adapter.test.mjs +0 -212
- package/lib/channels/telegram-adapter.test.mjs +0 -306
- package/lib/channels/voice/adapter.test.mjs +0 -278
- package/lib/channels/whatsapp/adapter-baileys.test.mjs +0 -359
- package/lib/channels/whatsapp/baileys-typing.test.mjs +0 -154
- package/lib/charter.test.mjs +0 -89
- package/lib/claude-bin.test.mjs +0 -131
- package/lib/cli/board.test.mjs +0 -227
- package/lib/cli/design.test.mjs +0 -270
- package/lib/cli/doctor-checks.test.mjs +0 -336
- package/lib/cli/global-setup-extras.test.mjs +0 -462
- package/lib/cli/inbox.test.mjs +0 -230
- package/lib/cli/session-ack.test.mjs +0 -63
- package/lib/cli/session.test.mjs +0 -613
- package/lib/collective/capture.test.mjs +0 -121
- package/lib/collective/cards.test.mjs +0 -114
- package/lib/collective/config.test.mjs +0 -123
- package/lib/collective/global-config.test.mjs +0 -220
- package/lib/collective/global-skills.test.mjs +0 -126
- package/lib/collective/presence.test.mjs +0 -95
- package/lib/collective/recall.test.mjs +0 -116
- package/lib/collective/vendor-skills.test.mjs +0 -306
- package/lib/comms/send-gate.test.mjs +0 -770
- package/lib/comms.test.mjs +0 -41
- package/lib/context/budget.test.mjs +0 -252
- package/lib/context/history-scope.test.mjs +0 -79
- package/lib/cost/ledger-row.test.mjs +0 -183
- package/lib/design/design-md.test.mjs +0 -318
- package/lib/design/fixtures/DESIGN.golden.md +0 -238
- package/lib/design/fixtures/PRODUCT.golden.md +0 -67
- package/lib/design/fixtures/foundation.json +0 -133
- package/lib/design/refresh-gate.test.mjs +0 -144
- package/lib/design/write.test.mjs +0 -241
- package/lib/diagnostics/alerts.test.mjs +0 -318
- package/lib/diagnostics/backup-freshness.test.mjs +0 -185
- package/lib/diagnostics/counters.test.mjs +0 -206
- package/lib/diagnostics/events.test.mjs +0 -290
- package/lib/diagnostics/otel.test.mjs +0 -196
- package/lib/diagnostics/trace.test.mjs +0 -251
- package/lib/env-compat.test.mjs +0 -104
- package/lib/execution/disposition.test.mjs +0 -553
- package/lib/execution/drive.test.mjs +0 -270
- package/lib/execution/effects.test.mjs +0 -344
- package/lib/execution/intake.test.mjs +0 -389
- package/lib/execution/journal.test.mjs +0 -261
- package/lib/execution/match.test.mjs +0 -235
- package/lib/execution/pipeline.test.mjs +0 -392
- package/lib/execution/route.test.mjs +0 -186
- package/lib/execution/surface-policy.test.mjs +0 -162
- package/lib/fs-atomic.test.mjs +0 -72
- package/lib/fs-ownership.test.mjs +0 -158
- package/lib/goals/admission.test.mjs +0 -164
- package/lib/goals/classify.test.mjs +0 -167
- package/lib/goals/collaborate.test.mjs +0 -336
- package/lib/goals/gaps.test.mjs +0 -284
- package/lib/goals/loop.test.mjs +0 -845
- package/lib/hooks/bus.test.mjs +0 -387
- package/lib/identity/persona.test.mjs +0 -142
- package/lib/kpi-sensors.test.mjs +0 -278
- package/lib/kpi.test.mjs +0 -244
- package/lib/learning/config.test.mjs +0 -75
- package/lib/learning/counters.test.mjs +0 -69
- package/lib/learning/curator-consolidate.test.mjs +0 -238
- package/lib/learning/curator.test.mjs +0 -106
- package/lib/learning/reflect.test.mjs +0 -0
- package/lib/learning/session-index.test.mjs +0 -125
- package/lib/learning/skill-writer.test.mjs +0 -210
- package/lib/mandate/audit.test.mjs +0 -195
- package/lib/mandate/contract.test.mjs +0 -185
- package/lib/mandate/derive.test.mjs +0 -274
- package/lib/mandate/model.test.mjs +0 -164
- package/lib/mandate/refresh.test.mjs +0 -389
- package/lib/mcp/server.test.mjs +0 -426
- package/lib/model-router/auth-profiles.test.mjs +0 -580
- package/lib/model-router/catalog.test.mjs +0 -385
- package/lib/model-router/economics.test.mjs +0 -438
- package/lib/model-router/failover.test.mjs +0 -439
- package/lib/model-router/health.test.mjs +0 -338
- package/lib/model-router/integration-coverage.test.mjs +0 -831
- package/lib/model-router/integration.test.mjs +0 -564
- package/lib/model-router/ledger.test.mjs +0 -415
- package/lib/model-router/llm-task.test.mjs +0 -392
- package/lib/model-router/org-credentials.test.mjs +0 -265
- package/lib/model-router/pricing-refresh.test.mjs +0 -286
- package/lib/model-router/reconcile.test.mjs +0 -316
- package/lib/model-router/repair.test.mjs +0 -180
- package/lib/model-router/spawn.test.mjs +0 -446
- package/lib/model-router/taxonomy.test.mjs +0 -410
- package/lib/model-router.test.mjs +0 -1207
- package/lib/org/activity.test.mjs +0 -134
- package/lib/org/approvals.test.mjs +0 -216
- package/lib/org/awareness.test.mjs +0 -159
- package/lib/org/board-mine-cache.test.mjs +0 -53
- package/lib/org/board.test.mjs +0 -187
- package/lib/org/bootstrap-context.test.mjs +0 -153
- package/lib/org/client.test.mjs +0 -1206
- package/lib/org/cohort-client.test.mjs +0 -126
- package/lib/org/cost-sync.test.mjs +0 -153
- package/lib/org/doctor.test.mjs +0 -346
- package/lib/org/engagement-ledger.test.mjs +0 -112
- package/lib/org/engagement.test.mjs +0 -739
- package/lib/org/handoff.test.mjs +0 -269
- package/lib/org/inbound/directedness.test.mjs +0 -668
- package/lib/org/inbound/facts.test.mjs +0 -471
- package/lib/org/inbound/hydrate.test.mjs +0 -908
- package/lib/org/inbound/index.test.mjs +0 -429
- package/lib/org/inbound/project.test.mjs +0 -287
- package/lib/org/integration-tools.test.mjs +0 -160
- package/lib/org/keys.test.mjs +0 -92
- package/lib/org/knowledge.test.mjs +0 -326
- package/lib/org/leases.test.mjs +0 -235
- package/lib/org/mesh-directives.test.mjs +0 -110
- package/lib/org/mesh-integration.test.mjs +0 -127
- package/lib/org/mesh.test.mjs +0 -400
- package/lib/org/messaging.test.mjs +0 -471
- package/lib/org/param-contract.test.mjs +0 -477
- package/lib/org/policy.test.mjs +0 -237
- package/lib/org/protocol.checksum.test.mjs +0 -90
- package/lib/org/protocol.test.mjs +0 -323
- package/lib/org/push.test.mjs +0 -792
- package/lib/org/registry.test.mjs +0 -100
- package/lib/org/resource-tools.test.mjs +0 -361
- package/lib/org/tool-access.test.mjs +0 -144
- package/lib/org/tool-surface-integration.test.mjs +0 -120
- package/lib/org/tool-surface.test.mjs +0 -1268
- package/lib/org/typing.test.mjs +0 -291
- package/lib/org/ui-parity.test.mjs +0 -560
- package/lib/org/verify.test.mjs +0 -194
- package/lib/org/work-ledger.test.mjs +0 -273
- package/lib/plan/adoption-e2e.test.mjs +0 -366
- package/lib/plan/budget-enforcement.test.mjs +0 -400
- package/lib/plan/compile.test.mjs +0 -382
- package/lib/plan/emit.test.mjs +0 -269
- package/lib/plan/explain.test.mjs +0 -188
- package/lib/prompts/parallelism.test.mjs +0 -177
- package/lib/rag/rag.test.mjs +0 -505
- package/lib/rate-guard.test.mjs +0 -272
- package/lib/reactive-gate.test.mjs +0 -57
- package/lib/render.test.mjs +0 -68
- package/lib/resource-governor.test.mjs +0 -488
- package/lib/scheduling/dynamic-jobs.test.mjs +0 -344
- package/lib/scheduling/jitter.test.mjs +0 -140
- package/lib/secrets/broker.test.mjs +0 -280
- package/lib/secrets/providers.test.mjs +0 -274
- package/lib/security/audit-engine.test.mjs +0 -424
- package/lib/security/coerce-args.test.mjs +0 -281
- package/lib/security/dangerous-tools.test.mjs +0 -68
- package/lib/security/external-content.test.mjs +0 -84
- package/lib/security/redact.test.mjs +0 -441
- package/lib/security/secret-equal.test.mjs +0 -55
- package/lib/session/config.test.mjs +0 -92
- package/lib/session/feed-core.test.mjs +0 -198
- package/lib/session/first-run.test.mjs +0 -121
- package/lib/session/frontdoor.test.mjs +0 -205
- package/lib/session/handoffs.test.mjs +0 -183
- package/lib/session/identity.test.mjs +0 -180
- package/lib/session/inbox-claims.test.mjs +0 -286
- package/lib/session/launch-args.test.mjs +0 -157
- package/lib/session/liveness.test.mjs +0 -100
- package/lib/session/status-summary.test.mjs +0 -118
- package/lib/session-permissions.test.mjs +0 -120
- package/lib/setup/claude-probe.test.mjs +0 -187
- package/lib/setup/completeness.test.mjs +0 -110
- package/lib/setup/context-pack.test.mjs +0 -89
- package/lib/setup/enrich.test.mjs +0 -115
- package/lib/setup/enroll-from-cohort.test.mjs +0 -300
- package/lib/setup/integration.test.mjs +0 -162
- package/lib/setup/io.test.mjs +0 -77
- package/lib/setup/runner.test.mjs +0 -132
- package/lib/setup/sections/identity.test.mjs +0 -234
- package/lib/setup/sections/inventory.test.mjs +0 -198
- package/lib/setup/sections/learning.test.mjs +0 -81
- package/lib/setup/sections/mandate.test.mjs +0 -388
- package/lib/setup/sections/messaging.test.mjs +0 -127
- package/lib/setup/sections/model.test.mjs +0 -240
- package/lib/setup/sections/org.test.mjs +0 -346
- package/lib/setup/sections/orgmail.test.mjs +0 -118
- package/lib/setup/sections/recovery.test.mjs +0 -98
- package/lib/setup/sections/subagents.test.mjs +0 -429
- package/lib/setup/sections/verify.test.mjs +0 -175
- package/lib/setup/sot.test.mjs +0 -81
- package/lib/setup/state.test.mjs +0 -115
- package/lib/singleton.test.mjs +0 -151
- package/lib/subagents/cli.test.mjs +0 -389
- package/lib/subagents/client.test.mjs +0 -309
- package/lib/subagents/gap.test.mjs +0 -234
- package/lib/subagents/lock.test.mjs +0 -248
- package/lib/subagents/manifest.test.mjs +0 -175
- package/lib/subagents/refs.test.mjs +0 -204
- package/lib/subagents/resolve.test.mjs +0 -422
- package/lib/subagents/schema.test.mjs +0 -328
- package/lib/telemetry/alerts.test.mjs +0 -109
- package/lib/telemetry/collect.test.mjs +0 -1274
- package/lib/tool-definitions-integration.test.mjs +0 -83
- package/lib/tool-definitions.test.mjs +0 -437
- package/lib/upgrade/global-refresh.test.mjs +0 -65
- package/lib/upgrade/launchd-reconcile.test.mjs +0 -272
- package/lib/upgrade/post-steps.test.mjs +0 -200
- package/lib/upgrade/verify.test.mjs +0 -164
- package/lib/util/fetch-timeout.test.mjs +0 -202
- package/lib/util/reconnect.test.mjs +0 -369
- package/lib/util/unhandled.test.mjs +0 -216
- package/lib/voice/outbound.test.mjs +0 -69
- package/lib/voice/session-rotation.test.mjs +0 -114
- package/lib/voice/stt.test.mjs +0 -226
- package/lib/voice/voice.test.mjs +0 -990
- package/scripts/cadence/enqueue-cadence-tick.test.mjs +0 -187
- package/scripts/ci/check-docs-accuracy.test.mjs +0 -409
- package/scripts/ci/check-durable-write-seam.test.mjs +0 -90
- package/scripts/ci/check-no-build-artifacts.test.mjs +0 -71
- package/scripts/ci/check-no-residual-identity.test.mjs +0 -202
- package/scripts/ci/check-skill-packs.test.mjs +0 -495
- package/scripts/ci/check-subagent-frontmatter.test.mjs +0 -124
- package/scripts/ci/check.test.mjs +0 -194
- package/scripts/ci/conformance-org-api.test.mjs +0 -425
- package/scripts/cloud-relay/voice/relay-identity.test.mjs +0 -96
- package/scripts/collective/hook-runner.test.mjs +0 -173
- package/scripts/cost/fleet-digest.test.mjs +0 -207
- package/scripts/cost/track-claude-usage-pricing.test.mjs +0 -183
- package/scripts/cost/track-claude-usage.test.mjs +0 -148
- package/scripts/daemon/agent-daemon-board-mine.test.mjs +0 -96
- package/scripts/daemon/agent-daemon-design.test.mjs +0 -238
- package/scripts/daemon/agent-daemon-frontdoor.test.mjs +0 -60
- package/scripts/daemon/agent-daemon.test.mjs +0 -995
- package/scripts/daemon/assurance-e2e.test.mjs +0 -613
- package/scripts/daemon/assurance.test.mjs +0 -1791
- package/scripts/daemon/board-mirror.test.mjs +0 -165
- package/scripts/daemon/cadence-consumer-frontdoor.test.mjs +0 -393
- package/scripts/daemon/cadence-consumer-governance.test.mjs +0 -276
- package/scripts/daemon/cadence-consumer.test.mjs +0 -776
- package/scripts/daemon/cadence-handlers.test.mjs +0 -837
- package/scripts/daemon/classifier-identity.test.mjs +0 -137
- package/scripts/daemon/classifier.test.mjs +0 -266
- package/scripts/daemon/classify-kind.test.mjs +0 -40
- package/scripts/daemon/context-compiler.test.mjs +0 -406
- package/scripts/daemon/deliver.test.mjs +0 -564
- package/scripts/daemon/dispatcher-cooldown.test.mjs +0 -122
- package/scripts/daemon/dispatcher-governance.test.mjs +0 -1013
- package/scripts/daemon/dispatcher-resume.test.mjs +0 -166
- package/scripts/daemon/dispatcher-session-continuity.test.mjs +0 -365
- package/scripts/daemon/execution-ladder.test.mjs +0 -470
- package/scripts/daemon/goal-steward-cadence.test.mjs +0 -312
- package/scripts/daemon/inbox-deferral-session.test.mjs +0 -49
- package/scripts/daemon/inbox-deferral.test.mjs +0 -336
- package/scripts/daemon/inbox-wake.test.mjs +0 -199
- package/scripts/daemon/integration.test.mjs +0 -149
- package/scripts/daemon/lib/self-echo.test.mjs +0 -153
- package/scripts/daemon/lib/session-router.test.mjs +0 -554
- package/scripts/daemon/prompt-builder-preamble.test.mjs +0 -210
- package/scripts/daemon/prompt-builder.test.mjs +0 -556
- package/scripts/daemon/responder-cost.test.mjs +0 -68
- package/scripts/daemon/responder-history.test.mjs +0 -221
- package/scripts/daemon/sdk-version.test.mjs +0 -31
- package/scripts/daemon/session-lock.test.mjs +0 -252
- package/scripts/daemon/session-outcomes.test.mjs +0 -533
- package/scripts/daemon/typing-registry.test.mjs +0 -102
- package/scripts/hooks/pre-send-audit.test.mjs +0 -354
- package/scripts/huddle/huddle-prompt.test.mjs +0 -176
- package/scripts/local-triggers/autoupdate.test.mjs +0 -518
- package/scripts/local-triggers/generate-plists.test.mjs +0 -456
- package/scripts/media-generation/brand-clause.test.mjs +0 -135
- package/scripts/org/send-orgmail.first-contact.test.mjs +0 -102
- package/scripts/poller/inbox-privilege-injection.test.mjs +0 -167
- package/scripts/poller/inbox-scan-poller.test.mjs +0 -295
- package/scripts/poller/lib/cloud-relay-dedup.test.mjs +0 -133
- package/scripts/poller/slack-socket-mode.test.mjs +0 -805
- package/scripts/poller-launchd/install.test.mjs +0 -243
- package/scripts/restore-from-backup.test.mjs +0 -181
- package/scripts/session/feed.test.mjs +0 -196
- package/scripts/session/supervisor-sh.test.mjs +0 -218
- package/scripts/session/supervisor.test.mjs +0 -482
- package/scripts/setup/configure-macos.test.mjs +0 -306
- package/scripts/setup/gen-subagent-manifest.test.mjs +0 -124
- package/scripts/setup/generate-agent-package-json.test.mjs +0 -143
- package/scripts/setup/generate-capability.test.mjs +0 -134
- package/scripts/setup/init-agent.test.mjs +0 -370
- package/scripts/setup/init-skill-marketplace.test.mjs +0 -193
- package/scripts/vendor/sync-skill-packs.test.mjs +0 -103
- package/scripts/watchdog/memory-watchdog.test.mjs +0 -64
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/engine/workflow/worktree.mjs — a git worktree for one agent() call with
|
|
3
|
+
* `isolation: "worktree"`.
|
|
4
|
+
*
|
|
5
|
+
* The worktree is created on a new branch from the repository's HEAD, under the
|
|
6
|
+
* run's directory (outside the project, so it never shows up as untracked
|
|
7
|
+
* files in it). The child works there. When it ends, a worktree whose HEAD has
|
|
8
|
+
* not moved and whose status is clean is removed with its branch; anything
|
|
9
|
+
* else is kept, and the agent's result names its path and branch.
|
|
10
|
+
*
|
|
11
|
+
* Only for a working directory inside a git repository with at least one
|
|
12
|
+
* commit; otherwise the call gets an error (`usage: true`, which agent()
|
|
13
|
+
* rejects with) instead of running unisolated. A kept worktree is listed in the
|
|
14
|
+
* run's `end` record. Before creating one, `git worktree prune` forgets
|
|
15
|
+
* worktrees whose directories no longer exist.
|
|
16
|
+
*
|
|
17
|
+
* @module lib/engine/workflow/worktree
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { execFile } from "node:child_process";
|
|
21
|
+
import { mkdirSync } from "node:fs";
|
|
22
|
+
import path from "node:path";
|
|
23
|
+
|
|
24
|
+
const GIT_TIMEOUT_MS = 30_000;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @param {string[]} args @param {string} cwd
|
|
28
|
+
* @returns {Promise<{ok:boolean, stdout:string, stderr:string}>}
|
|
29
|
+
*/
|
|
30
|
+
function git(args, cwd) {
|
|
31
|
+
// GIT_DIR and friends in the engine's environment (a hook's, say) would point git elsewhere.
|
|
32
|
+
const env = { PATH: process.env.PATH ?? "/usr/bin:/bin", HOME: process.env.HOME ?? "", LANG: "C", GIT_TERMINAL_PROMPT: "0" };
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
execFile("git", args, { cwd, env, timeout: GIT_TIMEOUT_MS, maxBuffer: 4 * 1024 * 1024 }, (err, stdout, stderr) => {
|
|
35
|
+
resolve({ ok: !err, stdout: String(stdout ?? "").trim(), stderr: String(stderr ?? "").trim() || (err ? err.message : "") });
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {{cwd:string, dir:string, branch:string}} o
|
|
42
|
+
* @returns {Promise<{ok:true, path:string, branch:string, base:string, repo:string, root:string}|{ok:false, error:string, usage?:boolean}>}
|
|
43
|
+
*/
|
|
44
|
+
export async function createWorktree({ cwd, dir, branch }) {
|
|
45
|
+
const top = await git(["rev-parse", "--show-toplevel"], cwd);
|
|
46
|
+
if (!top.ok || top.stdout === "") return { ok: false, usage: true, error: `isolation "worktree" needs a git repository, and ${cwd} is not in one` };
|
|
47
|
+
const base = await git(["rev-parse", "HEAD"], top.stdout);
|
|
48
|
+
if (!base.ok) return { ok: false, usage: true, error: `isolation "worktree" needs a commit to start from; the repository at ${top.stdout} has none` };
|
|
49
|
+
// Forget worktrees whose directories are gone (a run directory deleted, a process
|
|
50
|
+
// that exited before removing one), so they do not stay registered in .git/worktrees.
|
|
51
|
+
await git(["worktree", "prune"], top.stdout);
|
|
52
|
+
mkdirSync(path.dirname(dir), { recursive: true });
|
|
53
|
+
const add = await git(["worktree", "add", "-b", branch, dir, base.stdout], top.stdout);
|
|
54
|
+
if (!add.ok) return { ok: false, error: `could not create a worktree: ${add.stderr}` };
|
|
55
|
+
// The child works in the same place inside the worktree as cwd is inside the repository.
|
|
56
|
+
const rel = path.relative(top.stdout, cwd);
|
|
57
|
+
return { ok: true, path: rel && !rel.startsWith("..") ? path.join(dir, rel) : dir, branch, base: base.stdout, repo: top.stdout, root: dir };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Remove the worktree when nothing changed; keep it otherwise.
|
|
62
|
+
* @param {{root:string, branch:string, base:string, repo:string}} w
|
|
63
|
+
* @returns {Promise<{removed:boolean, reason:string}>}
|
|
64
|
+
*/
|
|
65
|
+
export async function finishWorktree(w) {
|
|
66
|
+
const status = await git(["status", "--porcelain"], w.root);
|
|
67
|
+
const head = await git(["rev-parse", "HEAD"], w.root);
|
|
68
|
+
if (!status.ok || !head.ok) return { removed: false, reason: "its state could not be read" };
|
|
69
|
+
if (status.stdout !== "" || head.stdout !== w.base) return { removed: false, reason: status.stdout !== "" ? "it has uncommitted changes" : "it has new commits" };
|
|
70
|
+
const rm = await git(["worktree", "remove", "--force", w.root], w.repo);
|
|
71
|
+
if (!rm.ok) return { removed: false, reason: `removing it failed: ${rm.stderr}` };
|
|
72
|
+
await git(["branch", "-D", w.branch], w.repo);
|
|
73
|
+
return { removed: true, reason: "unchanged" };
|
|
74
|
+
}
|
|
@@ -47,7 +47,7 @@ import { dedupeKey, threadKey } from "./journal.mjs";
|
|
|
47
47
|
* directedness ladder. A human pointed at this agent; the agent owes an answer.
|
|
48
48
|
*/
|
|
49
49
|
export const T0_REASONS = Object.freeze([
|
|
50
|
-
"direct", "dm", "mention", "named", "assignee", "reviewer", "owner",
|
|
50
|
+
"direct", "dm", "mention", "collective", "named", "assignee", "reviewer", "owner",
|
|
51
51
|
"approver", "requester", "proposer", "participant", "invited", "attendee",
|
|
52
52
|
"waiting_on",
|
|
53
53
|
]);
|
package/lib/execution/intake.mjs
CHANGED
|
@@ -64,6 +64,7 @@ export const INTAKE_ORIGINS = Object.freeze([
|
|
|
64
64
|
export const SURFACE_FAMILY = Object.freeze({
|
|
65
65
|
dm: "messaging",
|
|
66
66
|
mention: "messaging",
|
|
67
|
+
broadcast: "messaging",
|
|
67
68
|
thread_reply: "messaging",
|
|
68
69
|
call: "calling",
|
|
69
70
|
task_assigned: "board",
|
|
@@ -99,6 +100,7 @@ export const SURFACE_TOPIC = Object.freeze({
|
|
|
99
100
|
export const KIND_SURFACE = Object.freeze({
|
|
100
101
|
message: "dm",
|
|
101
102
|
mention: "mention",
|
|
103
|
+
broadcast: "broadcast",
|
|
102
104
|
thread_reply: "thread_reply",
|
|
103
105
|
call: "call",
|
|
104
106
|
voice_note: "dm",
|
|
@@ -129,6 +131,7 @@ export const KIND_SURFACE = Object.freeze({
|
|
|
129
131
|
export const RECONSTRUCTED_REASON = Object.freeze({
|
|
130
132
|
dm: "dm",
|
|
131
133
|
mention: "mention",
|
|
134
|
+
broadcast: "collective",
|
|
132
135
|
thread_reply: "thread",
|
|
133
136
|
call: "invited",
|
|
134
137
|
task_assigned: "assignee",
|
|
@@ -424,6 +427,13 @@ export function fromChannelEvent(item, o = {}) {
|
|
|
424
427
|
surface = "mention";
|
|
425
428
|
reason = "mention";
|
|
426
429
|
why.push(`${service} channel item names me`);
|
|
430
|
+
} else if (kind === "broadcast") {
|
|
431
|
+
// The org projection already proved the four broadcast conditions (human
|
|
432
|
+
// author, my room, not threaded, collective address) before stamping the
|
|
433
|
+
// kind; a channel adapter that stamps it is making the same claim.
|
|
434
|
+
surface = "broadcast";
|
|
435
|
+
reason = "collective";
|
|
436
|
+
why.push(`${service} channel item is a human's roll-call to the whole room`);
|
|
427
437
|
} else if (kind === "thread_reply" || (item.is_reply === true && s(item.thread_id))) {
|
|
428
438
|
// A reply in a thread. Whether the agent is IN that thread is a fact only
|
|
429
439
|
// the adapter has; without it this is a lane-tier claim at best.
|
|
@@ -140,6 +140,21 @@ export const ORG_SURFACE_POLICY = Object.freeze({
|
|
|
140
140
|
maxChainDepth: 2,
|
|
141
141
|
ambientDrop: false,
|
|
142
142
|
}),
|
|
143
|
+
/**
|
|
144
|
+
* A human's roll-call to the whole room. Respondable, now, in public — and
|
|
145
|
+
* the chain depth is ONE: the answer is a single post about myself, and a
|
|
146
|
+
* roll-call must never become a conversation between thirteen agents.
|
|
147
|
+
*/
|
|
148
|
+
broadcast: Object.freeze({
|
|
149
|
+
respondable: true,
|
|
150
|
+
replyMethod: "messaging.send",
|
|
151
|
+
latency: "now",
|
|
152
|
+
actionClasses: Object.freeze([]),
|
|
153
|
+
offlineSafe: true,
|
|
154
|
+
selfApprove: true,
|
|
155
|
+
maxChainDepth: 1,
|
|
156
|
+
ambientDrop: true,
|
|
157
|
+
}),
|
|
143
158
|
/** A reply in a thread I am part of. Same room, same tightness as a mention. */
|
|
144
159
|
thread_reply: Object.freeze({
|
|
145
160
|
respondable: true,
|
package/lib/learning/curator.mjs
CHANGED
|
@@ -339,14 +339,16 @@ export function parseConsolidationEnvelope(text, validIds) {
|
|
|
339
339
|
export async function defaultConsolidateSpawn(prompt, opts = {}) {
|
|
340
340
|
try {
|
|
341
341
|
const { spawnSync } = await import("node:child_process");
|
|
342
|
-
const {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
const
|
|
346
|
-
|
|
342
|
+
const { buildSpawn } = await import("../runtime/adapter.mjs");
|
|
343
|
+
// argv + env from the runtime adapter (lane "curator"): --print --model <m>
|
|
344
|
+
// <daemon MCP args>, prompt on stdin, PATH augmented.
|
|
345
|
+
const spec = buildSpawn({ lane: "curator", model: opts.model || "sonnet", prompt, mcp: {}, env: process.env });
|
|
346
|
+
if (!spec.ok) return "";
|
|
347
|
+
const res = spawnSync(spec.bin, spec.argv, {
|
|
348
|
+
input: spec.stdin,
|
|
347
349
|
encoding: "utf8",
|
|
348
350
|
timeout: opts.timeoutMs || CONSOLIDATE_TIMEOUT_MS,
|
|
349
|
-
env:
|
|
351
|
+
env: spec.env,
|
|
350
352
|
maxBuffer: 8 * 1024 * 1024,
|
|
351
353
|
});
|
|
352
354
|
if (res.status === 0 && res.stdout) return res.stdout;
|
package/lib/learning/reflect.mjs
CHANGED
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"use strict";
|
|
29
29
|
|
|
30
30
|
import { spawnSync } from "node:child_process";
|
|
31
|
-
import {
|
|
31
|
+
import { buildSpawn } from "../runtime/adapter.mjs";
|
|
32
32
|
import { captureSession, countUserTurns } from "../collective/capture.mjs";
|
|
33
33
|
import { readRecentCards } from "../collective/cards.mjs";
|
|
34
34
|
import { jaccard, tokenSet } from "../collective/recall.mjs";
|
|
@@ -146,13 +146,15 @@ export function buildReviewPrompt(transcriptText, extras = {}) {
|
|
|
146
146
|
/** Default reviewer spawn: one `claude --print --model <sonnet>`. Fail-open → "". */
|
|
147
147
|
export function defaultReviewSpawn(prompt, opts = {}) {
|
|
148
148
|
try {
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
const
|
|
152
|
-
|
|
149
|
+
// argv + env from the runtime adapter (lane "reflect"): --print --model <m>
|
|
150
|
+
// <daemon MCP args>, prompt on stdin, PATH augmented.
|
|
151
|
+
const spec = buildSpawn({ lane: "reflect", model: opts.model || "sonnet", prompt, mcp: {}, env: process.env });
|
|
152
|
+
if (!spec.ok) return "";
|
|
153
|
+
const res = spawnSync(spec.bin, spec.argv, {
|
|
154
|
+
input: spec.stdin,
|
|
153
155
|
encoding: "utf8",
|
|
154
156
|
timeout: opts.timeoutMs || REFLECT_TIMEOUT_MS,
|
|
155
|
-
env:
|
|
157
|
+
env: spec.env,
|
|
156
158
|
maxBuffer: 8 * 1024 * 1024,
|
|
157
159
|
});
|
|
158
160
|
if (res.status === 0 && res.stdout) return res.stdout;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# lib/model-router/catalog/cohort.yaml
|
|
2
|
+
# Bundled cohort-llm catalog rows (ships with @cohortapp/agent-sdk).
|
|
3
|
+
#
|
|
4
|
+
# cohort-llm is Cohort's OWN model gateway (hq docs/cohort-llm/design.md §4).
|
|
5
|
+
# The rows are Cohort model TIERS, never upstream model ids: the gateway routes
|
|
6
|
+
# each tier to its legs (design §4.7) and failover never changes the tier a seat
|
|
7
|
+
# is billed for (§5.1 TierRate).
|
|
8
|
+
#
|
|
9
|
+
# first_party: true — this provider is Cohort's own infrastructure, so:
|
|
10
|
+
# - tool_reliability A is an explicit first-party declaration (the gateway owns
|
|
11
|
+
# tier→leg selection and the parity eval, design §8.4), not a probe grade;
|
|
12
|
+
# - data_classes allows public/internal/sensitive without a config backends
|
|
13
|
+
# entry (it is not a third-party supplier; the gateway's own data-class
|
|
14
|
+
# supplier gates, design §4.7, sit behind it).
|
|
15
|
+
#
|
|
16
|
+
# auth: seat_token — there is no static env key. The seat exchanges its
|
|
17
|
+
# OrgApiKey for a short-lived cst_… token at POST /cohort/v1/tokens
|
|
18
|
+
# (lib/org/llm-token.mjs). There is deliberately no auth_env key.
|
|
19
|
+
#
|
|
20
|
+
# endpoints are the DEFAULT gateway; the loader rewrites both to
|
|
21
|
+
# org.cohort.llmBaseUrl or COHORT_LLM_BASE_URL when either is set.
|
|
22
|
+
#
|
|
23
|
+
# cost: null on every row. cohort-llm prices usage from its versioned price book
|
|
24
|
+
# and returns the cost (x-cohort-cost-micros / the cohort SSE frame); a local
|
|
25
|
+
# $/MTok here would be the kind of guess design C7 removes. Budget-guard reads
|
|
26
|
+
# /cohort/v1/quota for cohort-metered seats instead of pricing tokens.
|
|
27
|
+
#
|
|
28
|
+
# context_window follows the tier's smallest leg in the design §4.7 starting slot
|
|
29
|
+
# map (R3 research, fetched 2026-09-14):
|
|
30
|
+
# cohort-agentic GLM-5.3 (1M) → DeepSeek-V4-Pro-0813 (1M) → 1M
|
|
31
|
+
# cohort-reason Kimi-K3 (1M) → GLM-5.3 (1M) → 1M
|
|
32
|
+
# cohort-fast gpt-oss-120b (131K) → GLM-5.3-Flash (1M) → 131K
|
|
33
|
+
# cohort-extract DeepSeek-V4-Flash-0731 (1M) → GLM-5.3-Flash (1M) → 1M
|
|
34
|
+
# max_tokens is the gateway's default per-request ceiling (32K, design §4.1).
|
|
35
|
+
# The slot map is PROVISIONAL until the parity eval (design §8.4, W4-C).
|
|
36
|
+
#
|
|
37
|
+
# tier_map: the Anthropic-slot aliases a claude-shaped caller passes
|
|
38
|
+
# (`--model opus`, ANTHROPIC_DEFAULT_*_MODEL) → Cohort tiers, used when a seat's
|
|
39
|
+
# routing selects this provider. fable is the premium slot (Kimi-K3 class, R3).
|
|
40
|
+
|
|
41
|
+
provider: cohort
|
|
42
|
+
first_party: true
|
|
43
|
+
auth: seat_token
|
|
44
|
+
endpoints:
|
|
45
|
+
anthropic: https://llm.cohortapp.com
|
|
46
|
+
openai: https://llm.cohortapp.com/v1
|
|
47
|
+
data_residency: us
|
|
48
|
+
data_classes: [public, internal, sensitive]
|
|
49
|
+
tier_map:
|
|
50
|
+
fable: cohort-reason
|
|
51
|
+
opus: cohort-agentic
|
|
52
|
+
sonnet: cohort-agentic
|
|
53
|
+
haiku: cohort-fast
|
|
54
|
+
models:
|
|
55
|
+
- id: cohort-agentic
|
|
56
|
+
status: available
|
|
57
|
+
replaced_by: null
|
|
58
|
+
context_window: 1000000
|
|
59
|
+
context_tokens: 950000
|
|
60
|
+
max_tokens: 32000
|
|
61
|
+
cost: { input: null, output: null, cache_read: null, cache_write: null, tiered: [] }
|
|
62
|
+
cost_provenance: { source: gateway, fetched: "2026-09-14", volatile: true }
|
|
63
|
+
compat:
|
|
64
|
+
cache_control: anthropic
|
|
65
|
+
max_tokens_field: max_tokens
|
|
66
|
+
thinking_format: anthropic
|
|
67
|
+
requires_reasoning_echo: false
|
|
68
|
+
rejects_duplicate_tool_names: false
|
|
69
|
+
omit_temperature: false
|
|
70
|
+
supports_prompt_cache_key: true
|
|
71
|
+
tool_reliability: A
|
|
72
|
+
harness: { session: true, direct: true, batch: false }
|
|
73
|
+
quality: {}
|
|
74
|
+
notes: "2026-09-14: first-party tier; main agent loop. Legs GLM-5.3 → DeepSeek-V4-Pro-0813 (design §4.7, provisional)."
|
|
75
|
+
|
|
76
|
+
- id: cohort-reason
|
|
77
|
+
status: available
|
|
78
|
+
replaced_by: null
|
|
79
|
+
context_window: 1000000
|
|
80
|
+
context_tokens: 950000
|
|
81
|
+
max_tokens: 32000
|
|
82
|
+
cost: { input: null, output: null, cache_read: null, cache_write: null, tiered: [] }
|
|
83
|
+
cost_provenance: { source: gateway, fetched: "2026-09-14", volatile: true }
|
|
84
|
+
compat:
|
|
85
|
+
cache_control: anthropic
|
|
86
|
+
max_tokens_field: max_tokens
|
|
87
|
+
thinking_format: anthropic
|
|
88
|
+
requires_reasoning_echo: false
|
|
89
|
+
rejects_duplicate_tool_names: false
|
|
90
|
+
omit_temperature: false
|
|
91
|
+
supports_prompt_cache_key: true
|
|
92
|
+
tool_reliability: A
|
|
93
|
+
harness: { session: true, direct: true, batch: false }
|
|
94
|
+
quality: {}
|
|
95
|
+
notes: "2026-09-14: first-party tier; hardest background work (TTFT). Legs Kimi-K3 → GLM-5.3 (design §4.7, provisional)."
|
|
96
|
+
|
|
97
|
+
- id: cohort-fast
|
|
98
|
+
status: available
|
|
99
|
+
replaced_by: null
|
|
100
|
+
context_window: 131072
|
|
101
|
+
context_tokens: 124000
|
|
102
|
+
max_tokens: 32000
|
|
103
|
+
cost: { input: null, output: null, cache_read: null, cache_write: null, tiered: [] }
|
|
104
|
+
cost_provenance: { source: gateway, fetched: "2026-09-14", volatile: true }
|
|
105
|
+
compat:
|
|
106
|
+
cache_control: anthropic
|
|
107
|
+
max_tokens_field: max_tokens
|
|
108
|
+
thinking_format: anthropic
|
|
109
|
+
requires_reasoning_echo: false
|
|
110
|
+
rejects_duplicate_tool_names: false
|
|
111
|
+
omit_temperature: false
|
|
112
|
+
supports_prompt_cache_key: true
|
|
113
|
+
tool_reliability: A
|
|
114
|
+
harness: { session: true, direct: true, batch: false }
|
|
115
|
+
quality: {}
|
|
116
|
+
notes: "2026-09-14: first-party tier; classifier/haiku lanes. Legs gpt-oss-120b (131K) → GLM-5.3-Flash (design §4.7, provisional)."
|
|
117
|
+
|
|
118
|
+
- id: cohort-extract
|
|
119
|
+
status: available
|
|
120
|
+
replaced_by: null
|
|
121
|
+
context_window: 1000000
|
|
122
|
+
context_tokens: 950000
|
|
123
|
+
max_tokens: 32000
|
|
124
|
+
cost: { input: null, output: null, cache_read: null, cache_write: null, tiered: [] }
|
|
125
|
+
cost_provenance: { source: gateway, fetched: "2026-09-14", volatile: true }
|
|
126
|
+
compat:
|
|
127
|
+
cache_control: anthropic
|
|
128
|
+
max_tokens_field: max_tokens
|
|
129
|
+
thinking_format: anthropic
|
|
130
|
+
requires_reasoning_echo: false
|
|
131
|
+
rejects_duplicate_tool_names: false
|
|
132
|
+
omit_temperature: false
|
|
133
|
+
supports_prompt_cache_key: true
|
|
134
|
+
tool_reliability: A
|
|
135
|
+
harness: { session: true, direct: true, batch: false }
|
|
136
|
+
quality: {}
|
|
137
|
+
notes: "2026-09-14: first-party tier; structured extraction. Legs DeepSeek-V4-Flash-0731 → GLM-5.3-Flash (design §4.7, provisional)."
|
|
@@ -43,6 +43,9 @@ import {
|
|
|
43
43
|
import { join, resolve, dirname, basename } from "node:path";
|
|
44
44
|
import { fileURLToPath } from "node:url";
|
|
45
45
|
|
|
46
|
+
import { resolveLlmBaseUrl, cohortEndpoints } from "../org/llm-token.mjs";
|
|
47
|
+
import { loadOrgConfig } from "../org/client.mjs";
|
|
48
|
+
|
|
46
49
|
// js-yaml is a hard dependency of @cohortapp/agent-sdk (package.json), but we still
|
|
47
50
|
// import it defensively so the read path can degrade rather than crash if the
|
|
48
51
|
// dep tree is ever broken on a machine.
|
|
@@ -87,12 +90,17 @@ const VALID_COST_KEYS = new Set([
|
|
|
87
90
|
|
|
88
91
|
const COST_FIELDS = ["input", "output", "cache_read", "cache_write"];
|
|
89
92
|
|
|
93
|
+
/** How a provider authenticates: a static env key, or a Cohort seat token. */
|
|
94
|
+
const VALID_AUTH = new Set(["env", "seat_token"]);
|
|
95
|
+
const DATA_CLASS_NAMES = new Set(["public", "internal", "sensitive"]);
|
|
96
|
+
|
|
90
97
|
// Bundled providers we recognise. The authority-merge rule "never add providers"
|
|
91
98
|
// is enforced for the overlay (tighten-only); agent config MAY introduce a new
|
|
92
99
|
// provider via catalog_overrides (it is the highest authority and the agent owns
|
|
93
100
|
// its own machine), but we surface a warning so a typo'd provider name is loud.
|
|
94
101
|
const BUNDLED_PROVIDERS = new Set([
|
|
95
102
|
"anthropic",
|
|
103
|
+
"cohort",
|
|
96
104
|
"deepseek",
|
|
97
105
|
"moonshot",
|
|
98
106
|
"qwen",
|
|
@@ -294,6 +302,7 @@ function normaliseRow(provider, rawRow, errors) {
|
|
|
294
302
|
tool_reliability: VALID_GRADES.has(tool_reliability) ? tool_reliability : null,
|
|
295
303
|
harness: normaliseHarness(rawRow.harness, errors, label),
|
|
296
304
|
quality: rawRow.quality && typeof rawRow.quality === "object" ? { ...rawRow.quality } : {},
|
|
305
|
+
notes: typeof rawRow.notes === "string" ? rawRow.notes : null,
|
|
297
306
|
};
|
|
298
307
|
return { ok: true, row };
|
|
299
308
|
}
|
|
@@ -323,6 +332,7 @@ function parseProviderDoc(doc, label, errors) {
|
|
|
323
332
|
errors.push({ source: label, error: "catalog document missing string `provider`" });
|
|
324
333
|
return null;
|
|
325
334
|
}
|
|
335
|
+
const meta = providerMeta(doc, label, errors);
|
|
326
336
|
const rows = new Map();
|
|
327
337
|
const models = Array.isArray(doc.models) ? doc.models : [];
|
|
328
338
|
if (!Array.isArray(doc.models)) {
|
|
@@ -337,6 +347,7 @@ function parseProviderDoc(doc, label, errors) {
|
|
|
337
347
|
row.endpoints = doc.endpoints && typeof doc.endpoints === "object" ? { ...doc.endpoints } : {};
|
|
338
348
|
row.data_residency =
|
|
339
349
|
typeof doc.data_residency === "string" ? doc.data_residency : null;
|
|
350
|
+
Object.assign(row, cloneMeta(meta));
|
|
340
351
|
rows.set(row.id, row);
|
|
341
352
|
}
|
|
342
353
|
return {
|
|
@@ -344,10 +355,59 @@ function parseProviderDoc(doc, label, errors) {
|
|
|
344
355
|
auth_env: typeof doc.auth_env === "string" ? doc.auth_env : null,
|
|
345
356
|
endpoints: doc.endpoints && typeof doc.endpoints === "object" ? { ...doc.endpoints } : {},
|
|
346
357
|
data_residency: typeof doc.data_residency === "string" ? doc.data_residency : null,
|
|
358
|
+
...cloneMeta(meta),
|
|
347
359
|
rows,
|
|
348
360
|
};
|
|
349
361
|
}
|
|
350
362
|
|
|
363
|
+
/**
|
|
364
|
+
* Provider-level identity the router gates on (hoisted onto every row):
|
|
365
|
+
* first_party Cohort's own infrastructure (the cohort-llm gateway). A
|
|
366
|
+
* first-party provider declares its own grade and data-class
|
|
367
|
+
* allowance instead of earning them from a probe/config entry.
|
|
368
|
+
* auth "env" (auth_env names a static key, the default) or
|
|
369
|
+
* "seat_token" (a short-lived Cohort seat token, lib/org/llm-token.mjs).
|
|
370
|
+
* data_classes classes a FIRST-PARTY provider allows without a config entry.
|
|
371
|
+
* tier_map Anthropic-slot alias (fable/opus/sonnet/haiku) → this provider's row id.
|
|
372
|
+
*/
|
|
373
|
+
function providerMeta(doc, label, errors) {
|
|
374
|
+
const auth = doc.auth == null ? "env" : doc.auth;
|
|
375
|
+
if (!VALID_AUTH.has(auth)) errors.push({ source: label, error: `auth "${auth}" not in {env,seat_token}` });
|
|
376
|
+
const firstParty = doc.first_party === true;
|
|
377
|
+
let dataClasses = null;
|
|
378
|
+
if (doc.data_classes != null) {
|
|
379
|
+
if (!Array.isArray(doc.data_classes)) {
|
|
380
|
+
errors.push({ source: label, error: "data_classes must be an array" });
|
|
381
|
+
} else {
|
|
382
|
+
const bad = doc.data_classes.filter((c) => !DATA_CLASS_NAMES.has(c));
|
|
383
|
+
if (bad.length) errors.push({ source: label, error: `unknown data_classes ${JSON.stringify(bad)}` });
|
|
384
|
+
dataClasses = doc.data_classes.filter((c) => DATA_CLASS_NAMES.has(c));
|
|
385
|
+
if (!firstParty) errors.push({ source: label, error: "data_classes is only honoured on a first_party provider (third parties are allowed per config backends)" });
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const tierMap = {};
|
|
389
|
+
if (doc.tier_map != null) {
|
|
390
|
+
if (typeof doc.tier_map !== "object" || Array.isArray(doc.tier_map)) {
|
|
391
|
+
errors.push({ source: label, error: "tier_map must be an object" });
|
|
392
|
+
} else {
|
|
393
|
+
for (const [k, v] of Object.entries(doc.tier_map)) {
|
|
394
|
+
if (typeof v === "string" && v) tierMap[String(k).toLowerCase()] = v;
|
|
395
|
+
else errors.push({ source: label, error: `tier_map.${k} must be a row id string` });
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return { first_party: firstParty, auth: VALID_AUTH.has(auth) ? auth : "env", data_classes: dataClasses, tier_map: tierMap };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function cloneMeta(meta) {
|
|
403
|
+
return {
|
|
404
|
+
first_party: meta.first_party,
|
|
405
|
+
auth: meta.auth,
|
|
406
|
+
data_classes: meta.data_classes ? [...meta.data_classes] : null,
|
|
407
|
+
tier_map: { ...meta.tier_map },
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
351
411
|
// ---------------------------------------------------------------------------
|
|
352
412
|
// Source gathering (each returns provider docs + records its file mtime)
|
|
353
413
|
// ---------------------------------------------------------------------------
|
|
@@ -596,6 +656,8 @@ function mergePartialRow(byRef, ref, entry, layer, errors, warnings) {
|
|
|
596
656
|
row.auth_env = entry.auth_env ?? null;
|
|
597
657
|
row.endpoints = entry.endpoints ?? {};
|
|
598
658
|
row.data_residency = entry.data_residency ?? null;
|
|
659
|
+
// A config-created row is never first-party: that is a bundled declaration.
|
|
660
|
+
Object.assign(row, { first_party: false, auth: "env", data_classes: null, tier_map: {} });
|
|
599
661
|
byRef.set(ref, row);
|
|
600
662
|
}
|
|
601
663
|
return;
|
|
@@ -689,6 +751,11 @@ export function loadCatalog(agentRoot, opts = {}) {
|
|
|
689
751
|
for (const row of parsed.rows.values()) byRef.set(row.ref, row);
|
|
690
752
|
}
|
|
691
753
|
|
|
754
|
+
// The cohort gateway's base URL is seat configuration, not catalog data:
|
|
755
|
+
// org.cohort.llmBaseUrl, then COHORT_LLM_BASE_URL, then the default. Applied
|
|
756
|
+
// on the bundled floor so an explicit agent catalog_override still wins.
|
|
757
|
+
applyCohortBaseUrl(byRef, providersByName, cohortBaseUrlFor(root, opts));
|
|
758
|
+
|
|
692
759
|
// Layer 3: pricing cache (COST ONLY).
|
|
693
760
|
const pricing = gatherPricingCache(root, opts, errors, mtimes);
|
|
694
761
|
if (pricing) {
|
|
@@ -745,6 +812,10 @@ export function loadCatalog(agentRoot, opts = {}) {
|
|
|
745
812
|
auth_env: doc.auth_env,
|
|
746
813
|
endpoints: doc.endpoints,
|
|
747
814
|
data_residency: doc.data_residency,
|
|
815
|
+
first_party: doc.first_party === true,
|
|
816
|
+
auth: doc.auth || "env",
|
|
817
|
+
data_classes: doc.data_classes || null,
|
|
818
|
+
tier_map: doc.tier_map || {},
|
|
748
819
|
});
|
|
749
820
|
}
|
|
750
821
|
|
|
@@ -761,6 +832,49 @@ export function loadCatalog(agentRoot, opts = {}) {
|
|
|
761
832
|
};
|
|
762
833
|
}
|
|
763
834
|
|
|
835
|
+
/** The cohort gateway base URL for this load (injectable, else config/env). */
|
|
836
|
+
function cohortBaseUrlFor(root, opts) {
|
|
837
|
+
if (opts && typeof opts.cohortLlmBaseUrl === "string" && opts.cohortLlmBaseUrl) {
|
|
838
|
+
return opts.cohortLlmBaseUrl.replace(/\/+$/, "");
|
|
839
|
+
}
|
|
840
|
+
let cfg = opts && opts.orgConfig !== undefined ? opts.orgConfig : null;
|
|
841
|
+
if (cfg === null) {
|
|
842
|
+
try { cfg = existsSync(join(root, "config", "org.yaml")) ? loadOrgConfig(root) : {}; } catch { cfg = {}; }
|
|
843
|
+
}
|
|
844
|
+
return resolveLlmBaseUrl({ cfg, env: (opts && opts.env) || process.env });
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
/** Point the cohort provider (and its rows) at a gateway base URL. */
|
|
848
|
+
function applyCohortBaseUrl(byRef, providersByName, baseUrl) {
|
|
849
|
+
const doc = providersByName.get("cohort");
|
|
850
|
+
if (!doc) return;
|
|
851
|
+
const endpoints = cohortEndpoints(baseUrl);
|
|
852
|
+
doc.endpoints = { ...doc.endpoints, ...endpoints };
|
|
853
|
+
for (const row of byRef.values()) {
|
|
854
|
+
if (row.provider === "cohort") row.endpoints = { ...row.endpoints, ...endpoints };
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* The Cohort tier for a claude-shaped model flag. A `cohort-*` id passes
|
|
860
|
+
* through; an Anthropic-slot alias or id (fable/opus/sonnet/haiku, e.g.
|
|
861
|
+
* "claude-sonnet-4-6") maps through the provider's tier_map; anything else is
|
|
862
|
+
* null (the caller decides — never a silent guess).
|
|
863
|
+
* @param {string} modelFlag
|
|
864
|
+
* @param {Record<string,string>} tierMap
|
|
865
|
+
* @returns {string|null}
|
|
866
|
+
*/
|
|
867
|
+
export function cohortTierFor(modelFlag, tierMap) {
|
|
868
|
+
const m = typeof modelFlag === "string" ? modelFlag.trim().toLowerCase() : "";
|
|
869
|
+
if (!m) return null;
|
|
870
|
+
if (m.startsWith("cohort-")) return m;
|
|
871
|
+
const map = tierMap && typeof tierMap === "object" ? tierMap : {};
|
|
872
|
+
for (const slot of ["fable", "opus", "sonnet", "haiku"]) {
|
|
873
|
+
if ((m === slot || m.includes(slot)) && map[slot]) return map[slot];
|
|
874
|
+
}
|
|
875
|
+
return null;
|
|
876
|
+
}
|
|
877
|
+
|
|
764
878
|
function maxMtime(mtimes) {
|
|
765
879
|
let m = 0;
|
|
766
880
|
for (const t of mtimes) if (t > m) m = t;
|
|
@@ -863,6 +977,7 @@ function mtimeSignature(root, opts) {
|
|
|
863
977
|
}
|
|
864
978
|
}
|
|
865
979
|
for (const [tag, fn, injected] of [
|
|
980
|
+
["org", (r) => join(r, "config", "org.yaml"), opts.orgConfig !== undefined || typeof opts.cohortLlmBaseUrl === "string"],
|
|
866
981
|
["price", pricingCachePath, opts.pricingCache !== undefined],
|
|
867
982
|
["local", localConfigPath, opts.localConfig !== undefined],
|
|
868
983
|
["agent", agentConfigPath, opts.agentConfig !== undefined],
|
|
@@ -870,6 +985,8 @@ function mtimeSignature(root, opts) {
|
|
|
870
985
|
if (injected) parts.push(`${tag}:injected`);
|
|
871
986
|
else parts.push(`${tag}:${mtimeSafe(fn(root))}`);
|
|
872
987
|
}
|
|
988
|
+
// The gateway URL may come from the environment.
|
|
989
|
+
parts.push(`llm:${typeof opts.cohortLlmBaseUrl === "string" ? opts.cohortLlmBaseUrl : ((opts.env || process.env).COHORT_LLM_BASE_URL || "")}`);
|
|
873
990
|
// Overlay is passed by value (already verified); fold its version in.
|
|
874
991
|
if (opts.overlay) parts.push(`ovl:${opts.overlay.version || "?"}`);
|
|
875
992
|
return parts.join("|");
|
|
@@ -922,4 +1039,4 @@ export const _internals = {
|
|
|
922
1039
|
mtimeSignature,
|
|
923
1040
|
};
|
|
924
1041
|
|
|
925
|
-
export default { loadCatalog, loadCatalogCached, invalidateCatalogCache, lookupModel, listModels };
|
|
1042
|
+
export default { loadCatalog, loadCatalogCached, invalidateCatalogCache, lookupModel, listModels, cohortTierFor };
|