agent-tempo 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +213 -0
- package/LICENSE +21 -0
- package/README.md +289 -0
- package/assets/icon-32.png +0 -0
- package/assets/icon-512.png +0 -0
- package/assets/icon-64.png +0 -0
- package/assets/icon-dark-32.png +0 -0
- package/assets/icon-dark-64.png +0 -0
- package/assets/icon-dark.svg +9 -0
- package/assets/icon.svg +9 -0
- package/assets/logo-dark.svg +11 -0
- package/assets/logo-light.svg +11 -0
- package/dashboard/README.md +91 -0
- package/dashboard/dist/assets/index-CB78ToNE.css +2 -0
- package/dashboard/dist/assets/index-_5jV0Znu.js +62 -0
- package/dashboard/dist/assets/index-_5jV0Znu.js.map +1 -0
- package/dashboard/dist/index.html +21 -0
- package/dashboard/package.json +47 -0
- package/dist/activities/hard-terminate.d.ts +32 -0
- package/dist/activities/hard-terminate.js +460 -0
- package/dist/activities/maestro.d.ts +72 -0
- package/dist/activities/maestro.js +254 -0
- package/dist/activities/outbox.d.ts +188 -0
- package/dist/activities/outbox.js +849 -0
- package/dist/activities/resolve.d.ts +64 -0
- package/dist/activities/resolve.js +129 -0
- package/dist/activities/schedule-fire.d.ts +36 -0
- package/dist/activities/schedule-fire.js +147 -0
- package/dist/adapters/base.d.ts +426 -0
- package/dist/adapters/base.js +1270 -0
- package/dist/adapters/claude-api/adapter.d.ts +168 -0
- package/dist/adapters/claude-api/adapter.js +797 -0
- package/dist/adapters/claude-api/api-error.d.ts +96 -0
- package/dist/adapters/claude-api/api-error.js +191 -0
- package/dist/adapters/claude-api/index.d.ts +16 -0
- package/dist/adapters/claude-api/index.js +21 -0
- package/dist/adapters/claude-api/mcp-bridge.d.ts +50 -0
- package/dist/adapters/claude-api/mcp-bridge.js +157 -0
- package/dist/adapters/claude-code/adapter.d.ts +133 -0
- package/dist/adapters/claude-code/adapter.js +274 -0
- package/dist/adapters/claude-code/index.d.ts +15 -0
- package/dist/adapters/claude-code/index.js +20 -0
- package/dist/adapters/claude-code-headless/adapter.d.ts +131 -0
- package/dist/adapters/claude-code-headless/adapter.js +710 -0
- package/dist/adapters/claude-code-headless/error-mapper.d.ts +107 -0
- package/dist/adapters/claude-code-headless/error-mapper.js +281 -0
- package/dist/adapters/claude-code-headless/index.d.ts +17 -0
- package/dist/adapters/claude-code-headless/index.js +26 -0
- package/dist/adapters/claude-code-headless/pre-flight.d.ts +51 -0
- package/dist/adapters/claude-code-headless/pre-flight.js +207 -0
- package/dist/adapters/claude-code-headless/prompt.d.ts +93 -0
- package/dist/adapters/claude-code-headless/prompt.js +79 -0
- package/dist/adapters/claude-code-headless/stream-json.d.ts +242 -0
- package/dist/adapters/claude-code-headless/stream-json.js +208 -0
- package/dist/adapters/claude-code-headless/types.d.ts +28 -0
- package/dist/adapters/claude-code-headless/types.js +36 -0
- package/dist/adapters/copilot/adapter.d.ts +100 -0
- package/dist/adapters/copilot/adapter.js +730 -0
- package/dist/adapters/copilot/index.d.ts +15 -0
- package/dist/adapters/copilot/index.js +20 -0
- package/dist/adapters/index.d.ts +42 -0
- package/dist/adapters/index.js +115 -0
- package/dist/adapters/opencode/adapter.d.ts +82 -0
- package/dist/adapters/opencode/adapter.js +710 -0
- package/dist/adapters/opencode/config.d.ts +90 -0
- package/dist/adapters/opencode/config.js +137 -0
- package/dist/adapters/opencode/helpers.d.ts +40 -0
- package/dist/adapters/opencode/helpers.js +144 -0
- package/dist/adapters/opencode/index.d.ts +12 -0
- package/dist/adapters/opencode/index.js +17 -0
- package/dist/adapters/opencode/server-bridge.d.ts +124 -0
- package/dist/adapters/opencode/server-bridge.js +216 -0
- package/dist/adapters/sdk/base.d.ts +95 -0
- package/dist/adapters/sdk/base.js +134 -0
- package/dist/adapters/sdk/system-prompt.d.ts +64 -0
- package/dist/adapters/sdk/system-prompt.js +78 -0
- package/dist/adapters/terminal-error.d.ts +27 -0
- package/dist/adapters/terminal-error.js +39 -0
- package/dist/channel.d.ts +3 -0
- package/dist/channel.js +48 -0
- package/dist/cli/commands.d.ts +245 -0
- package/dist/cli/commands.js +2438 -0
- package/dist/cli/config-command.d.ts +8 -0
- package/dist/cli/config-command.js +254 -0
- package/dist/cli/daemon-command.d.ts +57 -0
- package/dist/cli/daemon-command.js +493 -0
- package/dist/cli/daemon.d.ts +217 -0
- package/dist/cli/daemon.js +632 -0
- package/dist/cli/dashboard-command.d.ts +20 -0
- package/dist/cli/dashboard-command.js +241 -0
- package/dist/cli/dev-banner.d.ts +107 -0
- package/dist/cli/dev-banner.js +190 -0
- package/dist/cli/dev-mode-bootstrap.d.ts +29 -0
- package/dist/cli/dev-mode-bootstrap.js +36 -0
- package/dist/cli/dev-verbs.d.ts +43 -0
- package/dist/cli/dev-verbs.js +254 -0
- package/dist/cli/help-text.d.ts +1 -0
- package/dist/cli/help-text.js +158 -0
- package/dist/cli/legacy-migration.d.ts +35 -0
- package/dist/cli/legacy-migration.js +335 -0
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +63 -0
- package/dist/cli/output.d.ts +12 -0
- package/dist/cli/output.js +37 -0
- package/dist/cli/preflight.d.ts +9 -0
- package/dist/cli/preflight.js +96 -0
- package/dist/cli/removed-verbs.d.ts +9 -0
- package/dist/cli/removed-verbs.js +78 -0
- package/dist/cli/sa-preflight.d.ts +99 -0
- package/dist/cli/sa-preflight.js +183 -0
- package/dist/cli/scenarios-command.d.ts +6 -0
- package/dist/cli/scenarios-command.js +167 -0
- package/dist/cli/startup.d.ts +112 -0
- package/dist/cli/startup.js +641 -0
- package/dist/cli/upgrade-command.d.ts +5 -0
- package/dist/cli/upgrade-command.js +240 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +680 -0
- package/dist/client/core.d.ts +33 -0
- package/dist/client/core.js +1260 -0
- package/dist/client/ensure-conductor-spawned.d.ts +35 -0
- package/dist/client/ensure-conductor-spawned.js +48 -0
- package/dist/client/index.d.ts +32 -0
- package/dist/client/index.js +22 -0
- package/dist/client/interface.d.ts +461 -0
- package/dist/client/interface.js +2 -0
- package/dist/client/subscribe.d.ts +108 -0
- package/dist/client/subscribe.js +598 -0
- package/dist/client/with-spawn.d.ts +27 -0
- package/dist/client/with-spawn.js +87 -0
- package/dist/config.d.ts +323 -0
- package/dist/config.js +593 -0
- package/dist/connection.d.ts +7 -0
- package/dist/connection.js +46 -0
- package/dist/constants.d.ts +50 -0
- package/dist/constants.js +74 -0
- package/dist/copilot-bridge.d.ts +22 -0
- package/dist/copilot-bridge.js +565 -0
- package/dist/daemon-adapter-versions.d.ts +52 -0
- package/dist/daemon-adapter-versions.js +170 -0
- package/dist/daemon.d.ts +275 -0
- package/dist/daemon.js +989 -0
- package/dist/ensemble/agent-types.d.ts +23 -0
- package/dist/ensemble/agent-types.js +132 -0
- package/dist/ensemble/loader.d.ts +14 -0
- package/dist/ensemble/loader.js +140 -0
- package/dist/ensemble/saver.d.ts +49 -0
- package/dist/ensemble/saver.js +201 -0
- package/dist/ensemble/schema.d.ts +71 -0
- package/dist/ensemble/schema.js +3 -0
- package/dist/git-info.d.ts +4 -0
- package/dist/git-info.js +29 -0
- package/dist/http/aggregate.d.ts +319 -0
- package/dist/http/aggregate.js +684 -0
- package/dist/http/auth.d.ts +67 -0
- package/dist/http/auth.js +177 -0
- package/dist/http/body.d.ts +71 -0
- package/dist/http/body.js +121 -0
- package/dist/http/catalog.d.ts +67 -0
- package/dist/http/catalog.js +209 -0
- package/dist/http/cors.d.ts +42 -0
- package/dist/http/cors.js +111 -0
- package/dist/http/dashboard-pair.d.ts +94 -0
- package/dist/http/dashboard-pair.js +148 -0
- package/dist/http/dashboard.d.ts +20 -0
- package/dist/http/dashboard.js +160 -0
- package/dist/http/event-bus.d.ts +217 -0
- package/dist/http/event-bus.js +365 -0
- package/dist/http/event-id.d.ts +77 -0
- package/dist/http/event-id.js +117 -0
- package/dist/http/event-types.d.ts +348 -0
- package/dist/http/event-types.js +36 -0
- package/dist/http/fixtures/chat-stress.d.ts +8 -0
- package/dist/http/fixtures/chat-stress.js +63 -0
- package/dist/http/fixtures/conductor-leaving.d.ts +8 -0
- package/dist/http/fixtures/conductor-leaving.js +80 -0
- package/dist/http/fixtures/constants.d.ts +10 -0
- package/dist/http/fixtures/constants.js +13 -0
- package/dist/http/fixtures/eight-player-broadcast.d.ts +10 -0
- package/dist/http/fixtures/eight-player-broadcast.js +81 -0
- package/dist/http/fixtures/empty-ensemble.d.ts +6 -0
- package/dist/http/fixtures/empty-ensemble.js +26 -0
- package/dist/http/fixtures/index.d.ts +55 -0
- package/dist/http/fixtures/index.js +110 -0
- package/dist/http/fixtures/single-conductor.d.ts +7 -0
- package/dist/http/fixtures/single-conductor.js +46 -0
- package/dist/http/fixtures/sse-reconnect.d.ts +8 -0
- package/dist/http/fixtures/sse-reconnect.js +77 -0
- package/dist/http/index.d.ts +21 -0
- package/dist/http/index.js +61 -0
- package/dist/http/port-file.d.ts +22 -0
- package/dist/http/port-file.js +132 -0
- package/dist/http/responses.d.ts +27 -0
- package/dist/http/responses.js +40 -0
- package/dist/http/ring-buffer.d.ts +41 -0
- package/dist/http/ring-buffer.js +80 -0
- package/dist/http/server.d.ts +122 -0
- package/dist/http/server.js +459 -0
- package/dist/http/snapshot.d.ts +85 -0
- package/dist/http/snapshot.js +180 -0
- package/dist/http/sse-handler.d.ts +87 -0
- package/dist/http/sse-handler.js +294 -0
- package/dist/http/writes.d.ts +55 -0
- package/dist/http/writes.js +240 -0
- package/dist/palette/index.d.ts +138 -0
- package/dist/palette/index.js +221 -0
- package/dist/reconcile/orphans.d.ts +255 -0
- package/dist/reconcile/orphans.js +340 -0
- package/dist/scripts/258-spotcheck.js +303 -0
- package/dist/scripts/check-components-css-sync.js +199 -0
- package/dist/scripts/run-shard.js +121 -0
- package/dist/scripts/verify-daemon-isolation-guard.js +128 -0
- package/dist/server-tools.d.ts +87 -0
- package/dist/server-tools.js +146 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +366 -0
- package/dist/spawn.d.ts +296 -0
- package/dist/spawn.js +747 -0
- package/dist/tools/agent-types.d.ts +2 -0
- package/dist/tools/agent-types.js +21 -0
- package/dist/tools/attachment-info.d.ts +4 -0
- package/dist/tools/attachment-info.js +48 -0
- package/dist/tools/broadcast.d.ts +4 -0
- package/dist/tools/broadcast.js +76 -0
- package/dist/tools/cancel-stage.d.ts +3 -0
- package/dist/tools/cancel-stage.js +20 -0
- package/dist/tools/clear-state.d.ts +3 -0
- package/dist/tools/clear-state.js +37 -0
- package/dist/tools/coat-check-evict.d.ts +4 -0
- package/dist/tools/coat-check-evict.js +43 -0
- package/dist/tools/coat-check-get.d.ts +4 -0
- package/dist/tools/coat-check-get.js +56 -0
- package/dist/tools/coat-check-list.d.ts +4 -0
- package/dist/tools/coat-check-list.js +60 -0
- package/dist/tools/coat-check-put.d.ts +4 -0
- package/dist/tools/coat-check-put.js +53 -0
- package/dist/tools/cue.d.ts +44 -0
- package/dist/tools/cue.js +201 -0
- package/dist/tools/destroy.d.ts +4 -0
- package/dist/tools/destroy.js +188 -0
- package/dist/tools/detach.d.ts +4 -0
- package/dist/tools/detach.js +45 -0
- package/dist/tools/encore.d.ts +4 -0
- package/dist/tools/encore.js +31 -0
- package/dist/tools/ensemble.d.ts +32 -0
- package/dist/tools/ensemble.js +198 -0
- package/dist/tools/evaluate-gate.d.ts +3 -0
- package/dist/tools/evaluate-gate.js +32 -0
- package/dist/tools/fetch-state.d.ts +13 -0
- package/dist/tools/fetch-state.js +78 -0
- package/dist/tools/gates.d.ts +3 -0
- package/dist/tools/gates.js +41 -0
- package/dist/tools/helpers.d.ts +21 -0
- package/dist/tools/helpers.js +25 -0
- package/dist/tools/hosts.d.ts +4 -0
- package/dist/tools/hosts.js +40 -0
- package/dist/tools/listen.d.ts +3 -0
- package/dist/tools/listen.js +22 -0
- package/dist/tools/load-lineup.d.ts +5 -0
- package/dist/tools/load-lineup.js +381 -0
- package/dist/tools/migrate.d.ts +4 -0
- package/dist/tools/migrate.js +60 -0
- package/dist/tools/pause-ensemble.d.ts +4 -0
- package/dist/tools/pause-ensemble.js +58 -0
- package/dist/tools/pause.d.ts +4 -0
- package/dist/tools/pause.js +36 -0
- package/dist/tools/play.d.ts +4 -0
- package/dist/tools/play.js +57 -0
- package/dist/tools/quality-gate.d.ts +3 -0
- package/dist/tools/quality-gate.js +26 -0
- package/dist/tools/recall.d.ts +3 -0
- package/dist/tools/recall.js +32 -0
- package/dist/tools/recruit.d.ts +38 -0
- package/dist/tools/recruit.js +447 -0
- package/dist/tools/release.d.ts +4 -0
- package/dist/tools/release.js +98 -0
- package/dist/tools/report.d.ts +3 -0
- package/dist/tools/report.js +29 -0
- package/dist/tools/resolve.d.ts +1 -0
- package/dist/tools/resolve.js +7 -0
- package/dist/tools/restart.d.ts +35 -0
- package/dist/tools/restart.js +131 -0
- package/dist/tools/restore.d.ts +4 -0
- package/dist/tools/restore.js +107 -0
- package/dist/tools/resume-ensemble.d.ts +4 -0
- package/dist/tools/resume-ensemble.js +79 -0
- package/dist/tools/save-lineup.d.ts +4 -0
- package/dist/tools/save-lineup.js +36 -0
- package/dist/tools/save-state.d.ts +3 -0
- package/dist/tools/save-state.js +57 -0
- package/dist/tools/schedule.d.ts +4 -0
- package/dist/tools/schedule.js +152 -0
- package/dist/tools/schedules.d.ts +4 -0
- package/dist/tools/schedules.js +54 -0
- package/dist/tools/set-ensemble-description.d.ts +4 -0
- package/dist/tools/set-ensemble-description.js +37 -0
- package/dist/tools/set-name.d.ts +4 -0
- package/dist/tools/set-name.js +45 -0
- package/dist/tools/set-part.d.ts +3 -0
- package/dist/tools/set-part.js +20 -0
- package/dist/tools/shutdown.d.ts +4 -0
- package/dist/tools/shutdown.js +54 -0
- package/dist/tools/stage.d.ts +3 -0
- package/dist/tools/stage.js +28 -0
- package/dist/tools/stages.d.ts +3 -0
- package/dist/tools/stages.js +35 -0
- package/dist/tools/stop.d.ts +4 -0
- package/dist/tools/stop.js +29 -0
- package/dist/tools/unschedule.d.ts +4 -0
- package/dist/tools/unschedule.js +35 -0
- package/dist/tools/who-am-i.d.ts +3 -0
- package/dist/tools/who-am-i.js +34 -0
- package/dist/tools/worktree.d.ts +4 -0
- package/dist/tools/worktree.js +181 -0
- package/dist/tui/App.d.ts +85 -0
- package/dist/tui/App.js +1791 -0
- package/dist/tui/bootstrap-types.d.ts +46 -0
- package/dist/tui/bootstrap-types.js +7 -0
- package/dist/tui/client.d.ts +6 -0
- package/dist/tui/client.js +9 -0
- package/dist/tui/commands.d.ts +71 -0
- package/dist/tui/commands.js +1375 -0
- package/dist/tui/components/ActivityLog.d.ts +16 -0
- package/dist/tui/components/ActivityLog.js +36 -0
- package/dist/tui/components/ChatView.d.ts +35 -0
- package/dist/tui/components/ChatView.js +54 -0
- package/dist/tui/components/CommandOverlay.d.ts +15 -0
- package/dist/tui/components/CommandOverlay.js +34 -0
- package/dist/tui/components/CommandPalette.d.ts +21 -0
- package/dist/tui/components/CommandPalette.js +67 -0
- package/dist/tui/components/ConductorChat.d.ts +16 -0
- package/dist/tui/components/ConductorChat.js +32 -0
- package/dist/tui/components/ConversationStream.d.ts +114 -0
- package/dist/tui/components/ConversationStream.js +307 -0
- package/dist/tui/components/CreateEnsembleWizard.d.ts +19 -0
- package/dist/tui/components/CreateEnsembleWizard.js +223 -0
- package/dist/tui/components/DestroyConfirmModal.d.ts +17 -0
- package/dist/tui/components/DestroyConfirmModal.js +62 -0
- package/dist/tui/components/EnsembleListView.d.ts +14 -0
- package/dist/tui/components/EnsembleListView.js +32 -0
- package/dist/tui/components/EnsemblePanel.d.ts +12 -0
- package/dist/tui/components/EnsemblePanel.js +40 -0
- package/dist/tui/components/ErrorView.d.ts +31 -0
- package/dist/tui/components/ErrorView.js +129 -0
- package/dist/tui/components/HomeView.d.ts +54 -0
- package/dist/tui/components/HomeView.js +306 -0
- package/dist/tui/components/InputBar.d.ts +13 -0
- package/dist/tui/components/InputBar.js +58 -0
- package/dist/tui/components/LoadLineupModal.d.ts +18 -0
- package/dist/tui/components/LoadLineupModal.js +79 -0
- package/dist/tui/components/MainView.d.ts +21 -0
- package/dist/tui/components/MainView.js +107 -0
- package/dist/tui/components/NewEnsembleModal.d.ts +9 -0
- package/dist/tui/components/NewEnsembleModal.js +73 -0
- package/dist/tui/components/Picker.d.ts +23 -0
- package/dist/tui/components/Picker.js +70 -0
- package/dist/tui/components/PlayerDetailView.d.ts +26 -0
- package/dist/tui/components/PlayerDetailView.js +118 -0
- package/dist/tui/components/PromptArea.d.ts +50 -0
- package/dist/tui/components/PromptArea.js +303 -0
- package/dist/tui/components/RecruitWizard.d.ts +17 -0
- package/dist/tui/components/RecruitWizard.js +221 -0
- package/dist/tui/components/RestoreConfirmModal.d.ts +18 -0
- package/dist/tui/components/RestoreConfirmModal.js +71 -0
- package/dist/tui/components/ScheduleOverlay.d.ts +13 -0
- package/dist/tui/components/ScheduleOverlay.js +113 -0
- package/dist/tui/components/ScheduleWizard.d.ts +19 -0
- package/dist/tui/components/ScheduleWizard.js +259 -0
- package/dist/tui/components/Splash.d.ts +23 -0
- package/dist/tui/components/Splash.js +221 -0
- package/dist/tui/components/StatusBar.d.ts +48 -0
- package/dist/tui/components/StatusBar.js +128 -0
- package/dist/tui/components/StatusOverlay.d.ts +15 -0
- package/dist/tui/components/StatusOverlay.js +76 -0
- package/dist/tui/components/TitleBar.d.ts +10 -0
- package/dist/tui/components/TitleBar.js +21 -0
- package/dist/tui/components/TopBar.d.ts +12 -0
- package/dist/tui/components/TopBar.js +15 -0
- package/dist/tui/core-api.d.ts +26 -0
- package/dist/tui/core-api.js +67 -0
- package/dist/tui/hooks/useEnsembleDiscovery.d.ts +3 -0
- package/dist/tui/hooks/useEnsembleDiscovery.js +30 -0
- package/dist/tui/hooks/useMaestroPoller.d.ts +3 -0
- package/dist/tui/hooks/useMaestroPoller.js +36 -0
- package/dist/tui/hooks/useSendCommand.d.ts +7 -0
- package/dist/tui/hooks/useSendCommand.js +29 -0
- package/dist/tui/index.d.ts +15 -0
- package/dist/tui/index.js +156 -0
- package/dist/tui/ink-context.d.ts +18 -0
- package/dist/tui/ink-context.js +59 -0
- package/dist/tui/ink-loader.d.ts +26 -0
- package/dist/tui/ink-loader.js +42 -0
- package/dist/tui/removed-commands.d.ts +9 -0
- package/dist/tui/removed-commands.js +22 -0
- package/dist/tui/sse-handler.d.ts +52 -0
- package/dist/tui/sse-handler.js +157 -0
- package/dist/tui/store.d.ts +598 -0
- package/dist/tui/store.js +753 -0
- package/dist/tui/utils/format.d.ts +56 -0
- package/dist/tui/utils/format.js +155 -0
- package/dist/tui/utils/fullscreen.d.ts +23 -0
- package/dist/tui/utils/fullscreen.js +71 -0
- package/dist/tui/utils/history.d.ts +10 -0
- package/dist/tui/utils/history.js +85 -0
- package/dist/tui/utils/platform.d.ts +45 -0
- package/dist/tui/utils/platform.js +258 -0
- package/dist/tui/utils/theme.d.ts +21 -0
- package/dist/tui/utils/theme.js +24 -0
- package/dist/types.d.ts +1020 -0
- package/dist/types.js +39 -0
- package/dist/utils/attachment-format.d.ts +22 -0
- package/dist/utils/attachment-format.js +32 -0
- package/dist/utils/default-part.d.ts +43 -0
- package/dist/utils/default-part.js +104 -0
- package/dist/utils/duration.d.ts +30 -0
- package/dist/utils/duration.js +69 -0
- package/dist/utils/ensemble-ops.d.ts +61 -0
- package/dist/utils/ensemble-ops.js +77 -0
- package/dist/utils/format-hosts.d.ts +21 -0
- package/dist/utils/format-hosts.js +73 -0
- package/dist/utils/hosts.d.ts +113 -0
- package/dist/utils/hosts.js +265 -0
- package/dist/utils/parent-death-watchdog.d.ts +1 -0
- package/dist/utils/parent-death-watchdog.js +47 -0
- package/dist/utils/query-timeout.d.ts +103 -0
- package/dist/utils/query-timeout.js +113 -0
- package/dist/utils/recall-format.d.ts +78 -0
- package/dist/utils/recall-format.js +105 -0
- package/dist/utils/restore-format.d.ts +49 -0
- package/dist/utils/restore-format.js +91 -0
- package/dist/utils/safe-path.d.ts +10 -0
- package/dist/utils/safe-path.js +43 -0
- package/dist/utils/sdk-probe.d.ts +9 -0
- package/dist/utils/sdk-probe.js +45 -0
- package/dist/utils/search-attributes.d.ts +76 -0
- package/dist/utils/search-attributes.js +86 -0
- package/dist/utils/validation.d.ts +113 -0
- package/dist/utils/validation.js +163 -0
- package/dist/utils/visibility-deadline.d.ts +186 -0
- package/dist/utils/visibility-deadline.js +158 -0
- package/dist/utils/worktree.d.ts +103 -0
- package/dist/utils/worktree.js +327 -0
- package/dist/worker.d.ts +14 -0
- package/dist/worker.js +146 -0
- package/dist/workflows/attachment-math.d.ts +56 -0
- package/dist/workflows/attachment-math.js +47 -0
- package/dist/workflows/index.d.ts +3 -0
- package/dist/workflows/index.js +11 -0
- package/dist/workflows/maestro-signals.d.ts +217 -0
- package/dist/workflows/maestro-signals.js +155 -0
- package/dist/workflows/maestro.d.ts +3 -0
- package/dist/workflows/maestro.js +812 -0
- package/dist/workflows/scheduler-signals.d.ts +10 -0
- package/dist/workflows/scheduler-signals.js +14 -0
- package/dist/workflows/scheduler.d.ts +17 -0
- package/dist/workflows/scheduler.js +143 -0
- package/dist/workflows/session.d.ts +2 -0
- package/dist/workflows/session.js +1638 -0
- package/dist/workflows/signals.d.ts +297 -0
- package/dist/workflows/signals.js +239 -0
- package/examples/agents/tempo-composer.md +56 -0
- package/examples/agents/tempo-conductor.md +117 -0
- package/examples/agents/tempo-critic.md +73 -0
- package/examples/agents/tempo-improv.md +74 -0
- package/examples/agents/tempo-liner.md +75 -0
- package/examples/agents/tempo-roadie.md +61 -0
- package/examples/agents/tempo-soloist.md +71 -0
- package/examples/agents/tempo-tuner.md +94 -0
- package/examples/ensembles/tempo-big-band.yaml +146 -0
- package/examples/ensembles/tempo-dev-team.yaml +58 -0
- package/examples/ensembles/tempo-headless-jam.yaml +77 -0
- package/examples/ensembles/tempo-jam-session.yaml +41 -0
- package/examples/ensembles/tempo-mock-jam.yaml +79 -0
- package/examples/ensembles/tempo-review-squad.yaml +32 -0
- package/package.json +172 -0
- package/packaging/launchd/com.agent.tempo.plist +46 -0
- package/packaging/systemd/agent-tempo.service +32 -0
- package/packaging/windows/install-task.ps1 +71 -0
- package/scenarios/conductor-recruit-mock.yaml +33 -0
- package/scenarios/echo-roundtrip.yaml +15 -0
- package/scenarios/multi-player-handoff.yaml +38 -0
- package/scenarios/recruit-cascade.yaml +38 -0
- package/scenarios/two-player-conversation.yaml +33 -0
- package/workflow-bundle.js +14146 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic-API error classifier for the claude-api adapter (#521).
|
|
3
|
+
*
|
|
4
|
+
* Parallels `src/adapters/terminal-error.ts` (#249) for Temporal-side
|
|
5
|
+
* errors. Categorizes failures from `messages.create` (streaming or not)
|
|
6
|
+
* into:
|
|
7
|
+
*
|
|
8
|
+
* - **`fatal`** — non-retriable. The adapter should detach + exit,
|
|
9
|
+
* surfacing a clear reason in stderr so the operator can fix the
|
|
10
|
+
* underlying problem. Examples: 400 `invalid_request_error` (bad
|
|
11
|
+
* model id, low credits, tokens-too-large), 401 unauthorized,
|
|
12
|
+
* 403 permission denied, 404 model not found, 422 unprocessable.
|
|
13
|
+
*
|
|
14
|
+
* - **`retriable`** — transient. The adapter should sleep
|
|
15
|
+
* (`retryAfterMs` if the server provided one, else exponential
|
|
16
|
+
* backoff with jitter) and retry, up to `DEFAULT_RETRY_BUDGET`
|
|
17
|
+
* consecutive failures. After that the verdict escalates to
|
|
18
|
+
* fatal so we don't hot-loop on a sustained outage. Examples: 408
|
|
19
|
+
* request timeout, 429 rate limit, 5xx server errors, 529
|
|
20
|
+
* overloaded, network / connection drops.
|
|
21
|
+
*
|
|
22
|
+
* **Why duck-typing instead of `instanceof`.** The `@anthropic-ai/sdk`
|
|
23
|
+
* is an optional dependency (#131) — importing its error classes here
|
|
24
|
+
* would couple every adapter consumer to the SDK. Status / name
|
|
25
|
+
* sniffing also tolerates minor-version drift in the SDK's class
|
|
26
|
+
* hierarchy without a rebuild. Same tradeoff `terminal-error.ts`
|
|
27
|
+
* makes for `@temporalio/client`.
|
|
28
|
+
*
|
|
29
|
+
* Acceptance criteria mapping (issue #521):
|
|
30
|
+
* 1. Classifier: `classifyApiError(err): ApiErrorVerdict`
|
|
31
|
+
* 2. Adapter consumes verdict in `adapter.ts` catch block at the
|
|
32
|
+
* former `deliver error` line.
|
|
33
|
+
* 3. Exponential backoff: `computeBackoffMs(attempt)` — pure function,
|
|
34
|
+
* injectable randomness for deterministic tests.
|
|
35
|
+
* 4. Retry budget: `DEFAULT_RETRY_BUDGET` (= 10 consecutive failures).
|
|
36
|
+
* 5. Detach reason surfaces: logged on stderr (operator-visible) and
|
|
37
|
+
* the adapter detaches with `DetachReason: 'agent-exited'` so
|
|
38
|
+
* `attachment_info` shows a non-recoverable detach.
|
|
39
|
+
*/
|
|
40
|
+
export type ApiErrorClassification = 'fatal' | 'retriable';
|
|
41
|
+
export interface ApiErrorVerdict {
|
|
42
|
+
/** Coarse-grained verdict driving the adapter's retry decision. */
|
|
43
|
+
classification: ApiErrorClassification;
|
|
44
|
+
/** Short reason string suitable for log + operator-facing surface. */
|
|
45
|
+
reason: string;
|
|
46
|
+
/** HTTP status code if the error carried one. */
|
|
47
|
+
status?: number;
|
|
48
|
+
/**
|
|
49
|
+
* If the server requested a specific wait (`retry-after` header), this
|
|
50
|
+
* is that wait in milliseconds. Caller honors this verbatim instead of
|
|
51
|
+
* applying exponential backoff. Absent means "use computeBackoffMs".
|
|
52
|
+
*/
|
|
53
|
+
retryAfterMs?: number;
|
|
54
|
+
}
|
|
55
|
+
/** Minimal Headers shape we read off Anthropic SDK errors. */
|
|
56
|
+
interface HeadersLike {
|
|
57
|
+
get(name: string): string | null;
|
|
58
|
+
}
|
|
59
|
+
/** Retry budget — give up after this many consecutive retriable failures. */
|
|
60
|
+
export declare const DEFAULT_RETRY_BUDGET = 10;
|
|
61
|
+
/**
|
|
62
|
+
* Classify an error thrown out of `messages.create` (or surrounding
|
|
63
|
+
* helper calls inside the adapter's deliver path).
|
|
64
|
+
*/
|
|
65
|
+
export declare function classifyApiError(err: unknown): ApiErrorVerdict;
|
|
66
|
+
/**
|
|
67
|
+
* Parse the standard HTTP `retry-after` header (seconds value, or
|
|
68
|
+
* HTTP-date). Returns ms, or `undefined` if absent / unparseable.
|
|
69
|
+
*
|
|
70
|
+
* Anthropic's API uses the integer-seconds form on 429 responses
|
|
71
|
+
* (per their docs), but we tolerate the HTTP-date form too for
|
|
72
|
+
* forward-compat with proxies that rewrite it.
|
|
73
|
+
*
|
|
74
|
+
* Exported for unit testing.
|
|
75
|
+
*/
|
|
76
|
+
export declare function parseRetryAfter(headers: HeadersLike | undefined): number | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Compute exponential-backoff delay (ms) for the Nth retriable failure.
|
|
79
|
+
*
|
|
80
|
+
* Doubling cadence with a 30s cap + ±25% jitter so synchronized retries
|
|
81
|
+
* (e.g. a multi-player ensemble all hitting the same 5xx blip) spread
|
|
82
|
+
* across a window. Attempt is 1-indexed (1 = first retry).
|
|
83
|
+
*
|
|
84
|
+
* attempt 1 → 750-1250 ms (base 1000)
|
|
85
|
+
* attempt 2 → 1500-2500 ms (base 2000)
|
|
86
|
+
* attempt 3 → 3000-5000 ms (base 4000)
|
|
87
|
+
* attempt 4 → 6000-10000 ms (base 8000)
|
|
88
|
+
* attempt 5 → 12000-20000 ms (base 16000)
|
|
89
|
+
* attempt 6+→ 22500-37500 ms (cap 30000)
|
|
90
|
+
*
|
|
91
|
+
* Pure function with injectable randomness so tests can pin the result.
|
|
92
|
+
*
|
|
93
|
+
* Exported for unit testing.
|
|
94
|
+
*/
|
|
95
|
+
export declare function computeBackoffMs(attempt: number, random?: () => number): number;
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Anthropic-API error classifier for the claude-api adapter (#521).
|
|
4
|
+
*
|
|
5
|
+
* Parallels `src/adapters/terminal-error.ts` (#249) for Temporal-side
|
|
6
|
+
* errors. Categorizes failures from `messages.create` (streaming or not)
|
|
7
|
+
* into:
|
|
8
|
+
*
|
|
9
|
+
* - **`fatal`** — non-retriable. The adapter should detach + exit,
|
|
10
|
+
* surfacing a clear reason in stderr so the operator can fix the
|
|
11
|
+
* underlying problem. Examples: 400 `invalid_request_error` (bad
|
|
12
|
+
* model id, low credits, tokens-too-large), 401 unauthorized,
|
|
13
|
+
* 403 permission denied, 404 model not found, 422 unprocessable.
|
|
14
|
+
*
|
|
15
|
+
* - **`retriable`** — transient. The adapter should sleep
|
|
16
|
+
* (`retryAfterMs` if the server provided one, else exponential
|
|
17
|
+
* backoff with jitter) and retry, up to `DEFAULT_RETRY_BUDGET`
|
|
18
|
+
* consecutive failures. After that the verdict escalates to
|
|
19
|
+
* fatal so we don't hot-loop on a sustained outage. Examples: 408
|
|
20
|
+
* request timeout, 429 rate limit, 5xx server errors, 529
|
|
21
|
+
* overloaded, network / connection drops.
|
|
22
|
+
*
|
|
23
|
+
* **Why duck-typing instead of `instanceof`.** The `@anthropic-ai/sdk`
|
|
24
|
+
* is an optional dependency (#131) — importing its error classes here
|
|
25
|
+
* would couple every adapter consumer to the SDK. Status / name
|
|
26
|
+
* sniffing also tolerates minor-version drift in the SDK's class
|
|
27
|
+
* hierarchy without a rebuild. Same tradeoff `terminal-error.ts`
|
|
28
|
+
* makes for `@temporalio/client`.
|
|
29
|
+
*
|
|
30
|
+
* Acceptance criteria mapping (issue #521):
|
|
31
|
+
* 1. Classifier: `classifyApiError(err): ApiErrorVerdict`
|
|
32
|
+
* 2. Adapter consumes verdict in `adapter.ts` catch block at the
|
|
33
|
+
* former `deliver error` line.
|
|
34
|
+
* 3. Exponential backoff: `computeBackoffMs(attempt)` — pure function,
|
|
35
|
+
* injectable randomness for deterministic tests.
|
|
36
|
+
* 4. Retry budget: `DEFAULT_RETRY_BUDGET` (= 10 consecutive failures).
|
|
37
|
+
* 5. Detach reason surfaces: logged on stderr (operator-visible) and
|
|
38
|
+
* the adapter detaches with `DetachReason: 'agent-exited'` so
|
|
39
|
+
* `attachment_info` shows a non-recoverable detach.
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.DEFAULT_RETRY_BUDGET = void 0;
|
|
43
|
+
exports.classifyApiError = classifyApiError;
|
|
44
|
+
exports.parseRetryAfter = parseRetryAfter;
|
|
45
|
+
exports.computeBackoffMs = computeBackoffMs;
|
|
46
|
+
/** Retry budget — give up after this many consecutive retriable failures. */
|
|
47
|
+
exports.DEFAULT_RETRY_BUDGET = 10;
|
|
48
|
+
/**
|
|
49
|
+
* Classify an error thrown out of `messages.create` (or surrounding
|
|
50
|
+
* helper calls inside the adapter's deliver path).
|
|
51
|
+
*/
|
|
52
|
+
function classifyApiError(err) {
|
|
53
|
+
const e = (err ?? {});
|
|
54
|
+
const name = e.name ?? '';
|
|
55
|
+
const status = typeof e.status === 'number' ? e.status : undefined;
|
|
56
|
+
const apiType = e.type ?? e.error?.type ?? '';
|
|
57
|
+
const apiMessage = e.error?.message ?? e.message ?? '';
|
|
58
|
+
// User / lease-revoke abort path. `APIUserAbortError` (status undefined)
|
|
59
|
+
// is fired by the SDK when we call `AbortController.abort()` in
|
|
60
|
+
// `onSuperseded`. Don't retry — the next loop iteration's
|
|
61
|
+
// `shouldStop()` check will exit cleanly. We classify as `fatal` so
|
|
62
|
+
// the caller short-circuits, but the caller's `shouldStop()` guard
|
|
63
|
+
// means we won't double-fire the detach signal.
|
|
64
|
+
if (name === 'APIUserAbortError' || name === 'AbortError') {
|
|
65
|
+
return {
|
|
66
|
+
classification: 'fatal',
|
|
67
|
+
reason: 'request aborted',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// No status — either an SDK connection error (network drop, DNS
|
|
71
|
+
// failure, fetch threw) or a plain Error from non-SDK code (e.g.
|
|
72
|
+
// JSON.parse threw, tool dispatch threw before the SDK call). Treat
|
|
73
|
+
// as retriable so we don't wedge on a brief network blip. The retry
|
|
74
|
+
// budget will catch sustained outages.
|
|
75
|
+
if (status === undefined) {
|
|
76
|
+
return {
|
|
77
|
+
classification: 'retriable',
|
|
78
|
+
reason: `connection error: ${truncate(apiMessage || e.message || name || 'unknown')}`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
// 5xx → retriable. Covers 500, 502, 503, 504, 529 (overloaded).
|
|
82
|
+
if (status >= 500) {
|
|
83
|
+
return {
|
|
84
|
+
classification: 'retriable',
|
|
85
|
+
reason: `server error ${status}${apiType ? ` (${apiType})` : ''}`,
|
|
86
|
+
status,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
// 429 rate limit → retriable, honoring `retry-after` if present.
|
|
90
|
+
if (status === 429) {
|
|
91
|
+
return {
|
|
92
|
+
classification: 'retriable',
|
|
93
|
+
reason: 'rate limited (429)',
|
|
94
|
+
status,
|
|
95
|
+
retryAfterMs: parseRetryAfter(e.headers),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// 408 request timeout → retriable.
|
|
99
|
+
if (status === 408) {
|
|
100
|
+
return {
|
|
101
|
+
classification: 'retriable',
|
|
102
|
+
reason: 'request timeout (408)',
|
|
103
|
+
status,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// Any other 4xx → fatal. Covers 400 invalid_request_error (bad
|
|
107
|
+
// model id, low credits, tokens-too-large), 401 unauthorized, 403
|
|
108
|
+
// permission denied, 404 model not found, 409 conflict, 422
|
|
109
|
+
// unprocessable. Retrying these is futile — the request itself is
|
|
110
|
+
// rejected, not the network — so we surface the failure
|
|
111
|
+
// immediately instead of burning quota.
|
|
112
|
+
if (status >= 400) {
|
|
113
|
+
const detail = apiType || truncate(apiMessage) || name || 'bad request';
|
|
114
|
+
return {
|
|
115
|
+
classification: 'fatal',
|
|
116
|
+
reason: `${status} ${detail}`,
|
|
117
|
+
status,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// Unrecognized 1xx/2xx/3xx with status (shouldn't happen — the SDK
|
|
121
|
+
// only throws on >=400). Be permissive: bias toward retriable so we
|
|
122
|
+
// don't wedge on an unexpected shape. The budget will still cap
|
|
123
|
+
// hot-loop failures.
|
|
124
|
+
return {
|
|
125
|
+
classification: 'retriable',
|
|
126
|
+
reason: `unrecognized error status=${status}`,
|
|
127
|
+
status,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Parse the standard HTTP `retry-after` header (seconds value, or
|
|
132
|
+
* HTTP-date). Returns ms, or `undefined` if absent / unparseable.
|
|
133
|
+
*
|
|
134
|
+
* Anthropic's API uses the integer-seconds form on 429 responses
|
|
135
|
+
* (per their docs), but we tolerate the HTTP-date form too for
|
|
136
|
+
* forward-compat with proxies that rewrite it.
|
|
137
|
+
*
|
|
138
|
+
* Exported for unit testing.
|
|
139
|
+
*/
|
|
140
|
+
function parseRetryAfter(headers) {
|
|
141
|
+
const raw = headers?.get?.('retry-after');
|
|
142
|
+
if (!raw)
|
|
143
|
+
return undefined;
|
|
144
|
+
// Numeric (seconds) — common case for Anthropic.
|
|
145
|
+
const secs = Number(raw);
|
|
146
|
+
if (Number.isFinite(secs)) {
|
|
147
|
+
if (secs <= 0)
|
|
148
|
+
return 0;
|
|
149
|
+
return Math.floor(secs * 1000);
|
|
150
|
+
}
|
|
151
|
+
// HTTP-date fallback.
|
|
152
|
+
const dateMs = Date.parse(raw);
|
|
153
|
+
if (Number.isFinite(dateMs)) {
|
|
154
|
+
const delta = dateMs - Date.now();
|
|
155
|
+
return delta <= 0 ? 0 : delta;
|
|
156
|
+
}
|
|
157
|
+
// Unparseable — let the caller fall back to exponential backoff.
|
|
158
|
+
return undefined;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Compute exponential-backoff delay (ms) for the Nth retriable failure.
|
|
162
|
+
*
|
|
163
|
+
* Doubling cadence with a 30s cap + ±25% jitter so synchronized retries
|
|
164
|
+
* (e.g. a multi-player ensemble all hitting the same 5xx blip) spread
|
|
165
|
+
* across a window. Attempt is 1-indexed (1 = first retry).
|
|
166
|
+
*
|
|
167
|
+
* attempt 1 → 750-1250 ms (base 1000)
|
|
168
|
+
* attempt 2 → 1500-2500 ms (base 2000)
|
|
169
|
+
* attempt 3 → 3000-5000 ms (base 4000)
|
|
170
|
+
* attempt 4 → 6000-10000 ms (base 8000)
|
|
171
|
+
* attempt 5 → 12000-20000 ms (base 16000)
|
|
172
|
+
* attempt 6+→ 22500-37500 ms (cap 30000)
|
|
173
|
+
*
|
|
174
|
+
* Pure function with injectable randomness so tests can pin the result.
|
|
175
|
+
*
|
|
176
|
+
* Exported for unit testing.
|
|
177
|
+
*/
|
|
178
|
+
function computeBackoffMs(attempt, random = Math.random) {
|
|
179
|
+
if (attempt <= 0)
|
|
180
|
+
return 0;
|
|
181
|
+
const BASE_MS = 1000;
|
|
182
|
+
const CAP_MS = 30_000;
|
|
183
|
+
const exp = Math.min(CAP_MS, BASE_MS * 2 ** (attempt - 1));
|
|
184
|
+
// ±25% jitter — `random()` returns [0, 1), so (random*0.5 - 0.25) gives
|
|
185
|
+
// [-0.25, +0.25).
|
|
186
|
+
const jitter = (random() * 0.5 - 0.25) * exp;
|
|
187
|
+
return Math.max(0, Math.round(exp + jitter));
|
|
188
|
+
}
|
|
189
|
+
function truncate(s, max = 80) {
|
|
190
|
+
return s.length > max ? s.slice(0, max) + '…' : s;
|
|
191
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* claude-api adapter — barrel export.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the descriptor and class from `./adapter`. `src/adapters/index.ts`
|
|
5
|
+
* imports the descriptor here at module load and registers it with the
|
|
6
|
+
* singleton {@link AdapterRegistry}. Direct consumers should fetch from the
|
|
7
|
+
* registry, not import the descriptor directly.
|
|
8
|
+
*
|
|
9
|
+
* The descriptor constant itself lives colocated with the class in `./adapter`
|
|
10
|
+
* so this file has no inward-pointing imports — same cycle-avoidance pattern
|
|
11
|
+
* the copilot adapter uses.
|
|
12
|
+
*
|
|
13
|
+
* Design reference: docs/design/131-claude-api-adapter.md §2 (adapter class
|
|
14
|
+
* placement) + §3.5 (optional dep gating).
|
|
15
|
+
*/
|
|
16
|
+
export { DirectApiAttachment, claudeApiDescriptor } from './adapter';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.claudeApiDescriptor = exports.DirectApiAttachment = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* claude-api adapter — barrel export.
|
|
6
|
+
*
|
|
7
|
+
* Re-exports the descriptor and class from `./adapter`. `src/adapters/index.ts`
|
|
8
|
+
* imports the descriptor here at module load and registers it with the
|
|
9
|
+
* singleton {@link AdapterRegistry}. Direct consumers should fetch from the
|
|
10
|
+
* registry, not import the descriptor directly.
|
|
11
|
+
*
|
|
12
|
+
* The descriptor constant itself lives colocated with the class in `./adapter`
|
|
13
|
+
* so this file has no inward-pointing imports — same cycle-avoidance pattern
|
|
14
|
+
* the copilot adapter uses.
|
|
15
|
+
*
|
|
16
|
+
* Design reference: docs/design/131-claude-api-adapter.md §2 (adapter class
|
|
17
|
+
* placement) + §3.5 (optional dep gating).
|
|
18
|
+
*/
|
|
19
|
+
var adapter_1 = require("./adapter");
|
|
20
|
+
Object.defineProperty(exports, "DirectApiAttachment", { enumerable: true, get: function () { return adapter_1.DirectApiAttachment; } });
|
|
21
|
+
Object.defineProperty(exports, "claudeApiDescriptor", { enumerable: true, get: function () { return adapter_1.claudeApiDescriptor; } });
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Client as McpClient } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
|
+
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { type RegisterAllTempoToolsOpts } from '../../server-tools';
|
|
4
|
+
/**
|
|
5
|
+
* Anthropic Messages API tool shape — the JSON contract `messages.create`
|
|
6
|
+
* accepts in its `tools` array. Mirrors the MCP tool shape exactly except
|
|
7
|
+
* for the field name (`inputSchema` → `input_schema`). Declared here
|
|
8
|
+
* (rather than imported from `@anthropic-ai/sdk`) so this module can ship
|
|
9
|
+
* without the optional Anthropic dep — only the adapter's spawn-time entry
|
|
10
|
+
* point requires the SDK to be installed.
|
|
11
|
+
*/
|
|
12
|
+
export interface AnthropicTool {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
input_schema: object;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Live in-process MCP bridge — server + client + cached tool list. Returned
|
|
19
|
+
* from {@link bootMcpBridge} and held by `DirectApiAttachment` for the
|
|
20
|
+
* duration of the session.
|
|
21
|
+
*/
|
|
22
|
+
export interface McpBridge {
|
|
23
|
+
/** MCP client — call `bridge.client.callTool({ name, arguments })` from the tool-use loop. */
|
|
24
|
+
client: McpClient;
|
|
25
|
+
/**
|
|
26
|
+
* Cached Anthropic-shaped tool list (translated from MCP `listTools()` once
|
|
27
|
+
* at session start). Tools don't change mid-session in v1, so the cache is
|
|
28
|
+
* safe; if a Phase 2 adds dynamic tool registration, refresh on a signal.
|
|
29
|
+
*/
|
|
30
|
+
tools: AnthropicTool[];
|
|
31
|
+
/**
|
|
32
|
+
* Dispatch a tool call from the adapter's streaming loop. Returns the MCP
|
|
33
|
+
* `CallToolResult` content + isError shape, ready to slot into a
|
|
34
|
+
* Messages API `tool_result` block (`content`, `is_error`).
|
|
35
|
+
*/
|
|
36
|
+
callTool: (name: string, args: Record<string, unknown>) => Promise<CallToolResult>;
|
|
37
|
+
/** Tear down both halves of the in-memory transport on shutdown. */
|
|
38
|
+
close: () => Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Boot the in-process MCP bridge for the claude-api adapter. Registers the
|
|
42
|
+
* full tempo tool surface against an `McpServer`, pairs an `McpClient` via
|
|
43
|
+
* `InMemoryTransport.createLinkedPair()`, calls `client.listTools()` once
|
|
44
|
+
* to populate the cached Anthropic-shaped tool array.
|
|
45
|
+
*
|
|
46
|
+
* @param opts Same option struct `registerAllTempoTools` consumes —
|
|
47
|
+
* identity + workflow handle + conductor flag. The adapter
|
|
48
|
+
* builds it from its env-var contract.
|
|
49
|
+
*/
|
|
50
|
+
export declare function bootMcpBridge(opts: RegisterAllTempoToolsOpts): Promise<McpBridge>;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.bootMcpBridge = bootMcpBridge;
|
|
37
|
+
/**
|
|
38
|
+
* In-process MCP bridge for the claude-api adapter.
|
|
39
|
+
*
|
|
40
|
+
* Boots an MCP `Server` (the same `McpServer` class `src/server.ts` uses),
|
|
41
|
+
* registers every tempo tool onto it via the shared `registerAllTempoTools`
|
|
42
|
+
* helper, and pairs an MCP `Client` to it via
|
|
43
|
+
* `InMemoryTransport.createLinkedPair()` — no subprocess, no stdio buffering,
|
|
44
|
+
* direct in-process JS calls under the hood.
|
|
45
|
+
*
|
|
46
|
+
* Why in-process (vs stdio sidecar):
|
|
47
|
+
* - No second process to manage / lifecycle / clean up
|
|
48
|
+
* - Zero stdio buffering edge cases
|
|
49
|
+
* - ~50 LoC of glue vs 200+ for a sidecar
|
|
50
|
+
* - MCP boundary preserved — adding a new tempo tool lights up
|
|
51
|
+
* automatically with no adapter change
|
|
52
|
+
*
|
|
53
|
+
* The bridge owns the schema translation (MCP `inputSchema` → Anthropic
|
|
54
|
+
* Messages API `input_schema`) so the adapter's tool-use loop can hand
|
|
55
|
+
* the converted list straight to `messages.create({ tools })`.
|
|
56
|
+
*
|
|
57
|
+
* Design reference: `docs/design/131-claude-api-adapter.md` §4 (in-process
|
|
58
|
+
* MCP).
|
|
59
|
+
*/
|
|
60
|
+
const fs = __importStar(require("fs"));
|
|
61
|
+
const path_1 = require("path");
|
|
62
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
63
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
64
|
+
const inMemory_js_1 = require("@modelcontextprotocol/sdk/inMemory.js");
|
|
65
|
+
const server_tools_1 = require("../../server-tools");
|
|
66
|
+
/**
|
|
67
|
+
* Resolve agent-tempo's `version` from its own `package.json`. Walks up
|
|
68
|
+
* from `__dirname` searching for a `package.json` whose `name` matches —
|
|
69
|
+
* robust across all build contexts:
|
|
70
|
+
* - `src/adapters/claude-api/mcp-bridge.ts` (ts-node dev)
|
|
71
|
+
* - `dist/adapters/claude-api/mcp-bridge.js` (production)
|
|
72
|
+
* - `dist-test/src/adapters/claude-api/mcp-bridge.js` (mocha integration build)
|
|
73
|
+
*
|
|
74
|
+
* The naive `require('../../../package.json')` worked for the first two
|
|
75
|
+
* but hit ENOENT in the third because `dist-test/` adds an extra `src/`
|
|
76
|
+
* layer that shifts the relative anchor (caught by CI on PR #455).
|
|
77
|
+
*
|
|
78
|
+
* Cached after first resolve so repeated `bootMcpBridge` calls don't re-walk.
|
|
79
|
+
* Falls back to `'0.0.0-unknown'` if the walk fails — only used as a
|
|
80
|
+
* diagnostic-grade `version` field on the MCP server/client identity, not
|
|
81
|
+
* for any version-gating behaviour.
|
|
82
|
+
*/
|
|
83
|
+
let cachedPackageVersion = null;
|
|
84
|
+
function packageVersion() {
|
|
85
|
+
if (cachedPackageVersion !== null)
|
|
86
|
+
return cachedPackageVersion;
|
|
87
|
+
let resolved = '0.0.0-unknown';
|
|
88
|
+
let dir = __dirname;
|
|
89
|
+
for (let i = 0; i < 8; i++) {
|
|
90
|
+
try {
|
|
91
|
+
const pkg = JSON.parse(fs.readFileSync((0, path_1.join)(dir, 'package.json'), 'utf8'));
|
|
92
|
+
if (pkg && pkg.name === 'agent-tempo' && typeof pkg.version === 'string') {
|
|
93
|
+
resolved = pkg.version;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch { /* not here, walk up */ }
|
|
98
|
+
const parent = (0, path_1.dirname)(dir);
|
|
99
|
+
if (parent === dir)
|
|
100
|
+
break;
|
|
101
|
+
dir = parent;
|
|
102
|
+
}
|
|
103
|
+
cachedPackageVersion = resolved;
|
|
104
|
+
return resolved;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Boot the in-process MCP bridge for the claude-api adapter. Registers the
|
|
108
|
+
* full tempo tool surface against an `McpServer`, pairs an `McpClient` via
|
|
109
|
+
* `InMemoryTransport.createLinkedPair()`, calls `client.listTools()` once
|
|
110
|
+
* to populate the cached Anthropic-shaped tool array.
|
|
111
|
+
*
|
|
112
|
+
* @param opts Same option struct `registerAllTempoTools` consumes —
|
|
113
|
+
* identity + workflow handle + conductor flag. The adapter
|
|
114
|
+
* builds it from its env-var contract.
|
|
115
|
+
*/
|
|
116
|
+
async function bootMcpBridge(opts) {
|
|
117
|
+
const server = new mcp_js_1.McpServer({
|
|
118
|
+
name: 'agent-tempo',
|
|
119
|
+
version: packageVersion(),
|
|
120
|
+
});
|
|
121
|
+
(0, server_tools_1.registerAllTempoTools)(server, opts);
|
|
122
|
+
const [clientTransport, serverTransport] = inMemory_js_1.InMemoryTransport.createLinkedPair();
|
|
123
|
+
await server.connect(serverTransport);
|
|
124
|
+
const client = new index_js_1.Client({
|
|
125
|
+
name: 'claude-api-adapter',
|
|
126
|
+
version: packageVersion(),
|
|
127
|
+
});
|
|
128
|
+
await client.connect(clientTransport);
|
|
129
|
+
const { tools: mcpTools } = await client.listTools();
|
|
130
|
+
const tools = mcpTools.map((t) => ({
|
|
131
|
+
name: t.name,
|
|
132
|
+
description: t.description ?? '',
|
|
133
|
+
input_schema: t.inputSchema,
|
|
134
|
+
}));
|
|
135
|
+
return {
|
|
136
|
+
client,
|
|
137
|
+
tools,
|
|
138
|
+
callTool: async (name, args) => {
|
|
139
|
+
const result = await client.callTool({ name, arguments: args });
|
|
140
|
+
return result;
|
|
141
|
+
},
|
|
142
|
+
close: async () => {
|
|
143
|
+
// Closing the client transport drains both halves of the linked pair.
|
|
144
|
+
// McpServer/McpClient close methods are best-effort; swallow per-half
|
|
145
|
+
// errors so a partial teardown doesn't mask the original shutdown
|
|
146
|
+
// cause from upstream callers.
|
|
147
|
+
try {
|
|
148
|
+
await client.close();
|
|
149
|
+
}
|
|
150
|
+
catch { /* ignore */ }
|
|
151
|
+
try {
|
|
152
|
+
await server.close();
|
|
153
|
+
}
|
|
154
|
+
catch { /* ignore */ }
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* claude-code adapter — interactive class.
|
|
3
|
+
*
|
|
4
|
+
* Owns the V2 attachment lifecycle for Claude Code CLI sessions: claims the
|
|
5
|
+
* attachment, drives the base-class heartbeat + phase-watcher loops, and runs
|
|
6
|
+
* the delivery poll against a runId-pinned handle. PR-H (#132) removed the
|
|
7
|
+
* `AGENT_TEMPO_LIFECYCLE_V2=0` escape hatch that previously gated V1 vs V2.
|
|
8
|
+
*
|
|
9
|
+
* Delivery itself (per design §5.3): push via MCP notification, ack via
|
|
10
|
+
* `markDelivered`. No `processingStart`/`End` pairs — those are for SDK
|
|
11
|
+
* adapters (`CopilotSdkAttachment`).
|
|
12
|
+
*
|
|
13
|
+
* **This file runs in the Node.js adapter process, NOT the Temporal workflow
|
|
14
|
+
* sandbox.** `setTimeout` / `setInterval` are appropriate here; the pre-bundled
|
|
15
|
+
* workflow code lives in `src/workflows/`.
|
|
16
|
+
*
|
|
17
|
+
* Design reference: docs/design/session-lifecycle-rebuild-v2.md §5 (interactive),
|
|
18
|
+
* §§3.2, 4.3 (base lifecycle), §9.4 (WorkflowNotFound).
|
|
19
|
+
*/
|
|
20
|
+
import type { WorkflowHandle } from '@temporalio/client';
|
|
21
|
+
import { BaseAttachment, type BaseAttachmentOptions } from '../base';
|
|
22
|
+
import type { AdapterDescriptor, DetachReason } from '../../types';
|
|
23
|
+
import { Message } from '../../types';
|
|
24
|
+
/**
|
|
25
|
+
* Descriptor for the claude-code adapter. Kept colocated with the class so
|
|
26
|
+
* `adapter.ts` has no import dependency on `index.ts` (breaks the circular
|
|
27
|
+
* module-graph cycle flagged in QA review of PR-B). `index.ts` re-exports
|
|
28
|
+
* this constant alongside the class.
|
|
29
|
+
*
|
|
30
|
+
* Design reference: docs/design/session-lifecycle-rebuild-v2.md §4.2–4.3.
|
|
31
|
+
*/
|
|
32
|
+
export declare const claudeCodeDescriptor: AdapterDescriptor;
|
|
33
|
+
/**
|
|
34
|
+
* Interactive adapter for the Claude Code CLI.
|
|
35
|
+
*
|
|
36
|
+
* Delivery model is push-based: messages are fetched via the `pendingMessages`
|
|
37
|
+
* query, notified to the MCP server via `notifications/claude/channel`, then
|
|
38
|
+
* `markDelivered` is signaled to the workflow. Delivery does not block on an
|
|
39
|
+
* LLM turn (`blocksOnLLMTurn: false`).
|
|
40
|
+
*
|
|
41
|
+
* V2 attachment lifecycle: the adapter calls `claimAttachment` via
|
|
42
|
+
* `startV2Lifecycle()`, pins the runId, and runs the delivery poll on the
|
|
43
|
+
* pinned handle. Base class drives heartbeat + phase watcher in parallel.
|
|
44
|
+
*
|
|
45
|
+
* Reconnect (#201): the adapter opts into the base class's reconnect loop
|
|
46
|
+
* via {@link shouldReconnect}. On a recoverable terminal (lease reaped
|
|
47
|
+
* workflow-side without a competitor, or superseded-then-released), the
|
|
48
|
+
* base class runs a budget-bounded backoff + fresh-claim flow, then calls
|
|
49
|
+
* {@link onReconnected} with a freshly pinned handle so the delivery poll
|
|
50
|
+
* can resume. Truly terminal events (`destroy`, `reconnect-exhausted`)
|
|
51
|
+
* still tear the adapter down permanently.
|
|
52
|
+
*
|
|
53
|
+
* CAN rebind (#226): when the session workflow continues-as-new, the pinned
|
|
54
|
+
* runId starts returning `WorkflowExecutionAlreadyCompleted`. The base class
|
|
55
|
+
* reads the closed run's history, extracts the successor runId from the
|
|
56
|
+
* `WorkflowExecutionContinuedAsNewEvent`, rebinds `pinnedHandle` in place (no
|
|
57
|
+
* re-claim — the workflow's §2.3 CAN-boundary lease extension keeps the lease
|
|
58
|
+
* alive across the transition), and calls {@link onReconnected} so we restart
|
|
59
|
+
* the poller on the live run. Transparent to upstream.
|
|
60
|
+
*
|
|
61
|
+
* PR-H (#132): the legacy unpinned-poll fallback (gated on
|
|
62
|
+
* `AGENT_TEMPO_LIFECYCLE_V2=0`) has been removed. V2 is the only path.
|
|
63
|
+
*/
|
|
64
|
+
export declare class InteractiveAttachment extends BaseAttachment {
|
|
65
|
+
readonly descriptor: AdapterDescriptor;
|
|
66
|
+
/** Current delivery poller stopper; null when no poll is running (pre-claim, mid-reconnect, post-terminal). */
|
|
67
|
+
private stopPoller;
|
|
68
|
+
/** Retained across `onReconnected` calls so the poller can be restarted on a new pinned handle. */
|
|
69
|
+
private onMessages;
|
|
70
|
+
/** True once user-initiated `stop()` has fired or the adapter reached a true terminal. */
|
|
71
|
+
private localStopped;
|
|
72
|
+
constructor(options?: BaseAttachmentOptions);
|
|
73
|
+
/**
|
|
74
|
+
* Start polling for pending messages and delivering each batch via `onMessages`.
|
|
75
|
+
* Returns a `stop()` function the caller invokes on shutdown.
|
|
76
|
+
*
|
|
77
|
+
* The `handle` argument is forwarded for its `workflowId` only — V2 mode
|
|
78
|
+
* claims its own runId-pinned handle via the base class for all subsequent
|
|
79
|
+
* queries/signals.
|
|
80
|
+
*/
|
|
81
|
+
start(handle: WorkflowHandle, onMessages: (messages: Message[]) => Promise<void> | void): () => void;
|
|
82
|
+
/**
|
|
83
|
+
* V2 path: claim the attachment, pin the handle, then run the poll/deliver/
|
|
84
|
+
* markDelivered loop against the pinned handle. The base class simultaneously
|
|
85
|
+
* drives heartbeats and the `attachmentInfo` watcher, and (via {@link shouldReconnect})
|
|
86
|
+
* may reclaim on recoverable lease loss without this method firing terminal.
|
|
87
|
+
*
|
|
88
|
+
* Returns a stop function that tears down the delivery poll AND the base
|
|
89
|
+
* class lifecycle. Safe to call multiple times.
|
|
90
|
+
*
|
|
91
|
+
* **Error handling:** a `claimAttachment` rejection at startup
|
|
92
|
+
* (`AttachmentConflict`, `WorkflowGone`) propagates up — the caller in
|
|
93
|
+
* `server.ts` treats it like any other startup failure. Runtime lease loss
|
|
94
|
+
* on the pinned handle is first routed through `shouldReconnect`; only truly
|
|
95
|
+
* terminal reasons (`destroy`, `reconnect-exhausted`) reach `onTerminal`
|
|
96
|
+
* and tear down the poller permanently.
|
|
97
|
+
*/
|
|
98
|
+
private startV2;
|
|
99
|
+
/**
|
|
100
|
+
* #201 / #226: reconnect opt-in. The interactive adapter is stateless wrt
|
|
101
|
+
* in-flight messages (no processing-signal pairing; `markDelivered` is
|
|
102
|
+
* idempotent), so every recoverable reason is safe to replay on a fresh or
|
|
103
|
+
* re-bound lease:
|
|
104
|
+
*
|
|
105
|
+
* - `heartbeat-timeout` (#201): the workflow reaped our lease (e.g. laptop
|
|
106
|
+
* slept). Re-claim and resume — full budget-bounded reconnect loop.
|
|
107
|
+
* - `superseded` (#201): another adapter currently holds our slot. The
|
|
108
|
+
* reconnect loop's pre-check will re-query and bail cleanly if that's
|
|
109
|
+
* still true; we enter the loop in case the competitor releases during
|
|
110
|
+
* our backoff.
|
|
111
|
+
* - `continued-as-new` (#226): the session workflow's CAN transition closed
|
|
112
|
+
* our pinned runId while the workflow id kept running on a successor. The
|
|
113
|
+
* base class transparently rebinds to the successor runId (no re-claim —
|
|
114
|
+
* the lease is carried across CAN per §2.3) and our poller resumes.
|
|
115
|
+
*
|
|
116
|
+
* Unrecoverable reasons (`destroy`, `gone`, anything else) fall through to
|
|
117
|
+
* the default `false`, firing terminal directly.
|
|
118
|
+
*/
|
|
119
|
+
protected shouldReconnect(reason: DetachReason): boolean;
|
|
120
|
+
/**
|
|
121
|
+
* Tear down the current poller immediately when entering the reconnect loop.
|
|
122
|
+
* The old pinned handle may still respond to `pendingMessages` queries but
|
|
123
|
+
* the workflow side will ignore our `markDelivered` signals (our `attachmentId`
|
|
124
|
+
* is no longer current), so continuing to poll wastes I/O and logs noise.
|
|
125
|
+
*/
|
|
126
|
+
protected onReconnectStart(_reason: DetachReason): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Fresh pinned handle is live — restart the delivery poller. The workflow's
|
|
129
|
+
* `pendingMessages` queue carries everything that landed while we were
|
|
130
|
+
* detached; the first poll will drain it in one batch.
|
|
131
|
+
*/
|
|
132
|
+
protected onReconnected(handle: WorkflowHandle): Promise<void>;
|
|
133
|
+
}
|