botmancers 0.4.2 → 0.6.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/CHANGELOG.md +83 -0
- package/README.md +26 -17
- package/app/.next/BUILD_ID +1 -1
- package/app/.next/app-path-routes-manifest.json +16 -0
- package/app/.next/build-manifest.json +3 -3
- package/app/.next/node_modules/@slack/socket-mode-77e8cba3b9ba4738/index.js +1 -0
- package/app/.next/node_modules/@slack/socket-mode-77e8cba3b9ba4738/package.json +1 -0
- package/app/.next/node_modules/@slack/web-api-d6dbe405b6902642/index.js +1 -0
- package/app/.next/node_modules/@slack/web-api-d6dbe405b6902642/package.json +1 -0
- package/app/.next/prerender-manifest.json +5 -5
- package/app/.next/required-server-files.json +8 -3
- package/app/.next/routes-manifest.json +122 -0
- package/app/.next/server/app/_global-error/page.js +1 -1
- package/app/.next/server/app/_global-error/page.js.nft.json +1 -1
- package/app/.next/server/app/_global-error.html +1 -1
- package/app/.next/server/app/_global-error.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/app/.next/server/app/_not-found/page.js +1 -1
- package/app/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/_not-found.html +1 -1
- package/app/.next/server/app/_not-found.rsc +2 -2
- package/app/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/app/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/app/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/api/agent-deck/decks/route.js +3 -3
- package/app/.next/server/app/api/agent-deck/decks/route.js.nft.json +1 -1
- package/app/.next/server/app/api/agent-deck/settings/route.js +3 -3
- package/app/.next/server/app/api/agent-deck/settings/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/[id]/config/route.js +3 -3
- package/app/.next/server/app/api/bots/[id]/config/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/pins/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/pins/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/pins/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/pins/route.js +11 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/pins/route.js.nft.json +1 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/pins/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/route.js +3 -3
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/shares/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/shares/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/shares/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/shares/route.js +11 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/shares/route.js.nft.json +1 -0
- package/app/.next/server/app/api/bots/[id]/sessions/[ref]/shares/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/bots/[id]/sessions/route.js +6 -4
- package/app/.next/server/app/api/bots/[id]/sessions/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/[id]/share-policy/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/bots/[id]/share-policy/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/bots/[id]/share-policy/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/bots/[id]/share-policy/route.js +11 -0
- package/app/.next/server/app/api/bots/[id]/share-policy/route.js.nft.json +1 -0
- package/app/.next/server/app/api/bots/[id]/share-policy/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/bots/[id]/skill/route.js +3 -3
- package/app/.next/server/app/api/bots/[id]/skill/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/availability/route.js +2 -2
- package/app/.next/server/app/api/bots/availability/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/delete-preview/route.js +3 -3
- package/app/.next/server/app/api/bots/delete-preview/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/import/route.js +3 -3
- package/app/.next/server/app/api/bots/import/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/manage/route.js +3 -3
- package/app/.next/server/app/api/bots/manage/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/name-migrations/route.js +3 -3
- package/app/.next/server/app/api/bots/name-migrations/route.js.nft.json +1 -1
- package/app/.next/server/app/api/bots/route.js +6 -6
- package/app/.next/server/app/api/bots/route.js.nft.json +1 -1
- package/app/.next/server/app/api/conversations/[id]/approve/route.js +3 -3
- package/app/.next/server/app/api/conversations/[id]/approve/route.js.nft.json +1 -1
- package/app/.next/server/app/api/conversations/[id]/deny/route.js +3 -3
- package/app/.next/server/app/api/conversations/[id]/deny/route.js.nft.json +1 -1
- package/app/.next/server/app/api/conversations/[id]/draft/route.js +3 -3
- package/app/.next/server/app/api/conversations/[id]/draft/route.js.nft.json +1 -1
- package/app/.next/server/app/api/conversations/[id]/messages/[messageId]/stop/route.js +3 -3
- package/app/.next/server/app/api/conversations/[id]/messages/[messageId]/stop/route.js.nft.json +1 -1
- package/app/.next/server/app/api/conversations/[id]/messages/route.js +6 -6
- package/app/.next/server/app/api/conversations/[id]/messages/route.js.nft.json +1 -1
- package/app/.next/server/app/api/conversations/[id]/route.js +3 -3
- package/app/.next/server/app/api/conversations/[id]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/conversations/[id]/stop/route.js +6 -6
- package/app/.next/server/app/api/conversations/[id]/stop/route.js.nft.json +1 -1
- package/app/.next/server/app/api/conversations/route.js +3 -3
- package/app/.next/server/app/api/conversations/route.js.nft.json +1 -1
- package/app/.next/server/app/api/exchanges/[id]/cancel/route.js +5 -5
- package/app/.next/server/app/api/exchanges/[id]/cancel/route.js.nft.json +1 -1
- package/app/.next/server/app/api/exchanges/[id]/route.js +5 -5
- package/app/.next/server/app/api/exchanges/[id]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/exchanges/route.js +5 -5
- package/app/.next/server/app/api/exchanges/route.js.nft.json +1 -1
- package/app/.next/server/app/api/files/[name]/route.js +3 -2
- package/app/.next/server/app/api/files/[name]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/groups/route.js +3 -3
- package/app/.next/server/app/api/groups/route.js.nft.json +1 -1
- package/app/.next/server/app/api/health/route.js +6 -2
- package/app/.next/server/app/api/health/route.js.nft.json +1 -1
- package/app/.next/server/app/api/import-capabilities/route.js +1 -1
- package/app/.next/server/app/api/import-capabilities/route.js.nft.json +1 -1
- package/app/.next/server/app/api/marketplace-handoff/route.js +1 -1
- package/app/.next/server/app/api/marketplace-handoff/route.js.nft.json +1 -1
- package/app/.next/server/app/api/marketplace-handoff/status/route.js +1 -1
- package/app/.next/server/app/api/marketplace-handoff/status/route.js.nft.json +1 -1
- package/app/.next/server/app/api/mcp/route.js +3 -3
- package/app/.next/server/app/api/mcp/route.js.nft.json +1 -1
- package/app/.next/server/app/api/messages/[id]/between/route.js +3 -3
- package/app/.next/server/app/api/messages/[id]/between/route.js.nft.json +1 -1
- package/app/.next/server/app/api/runtime-connections/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/runtime-connections/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/runtime-connections/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/runtime-connections/route.js +9 -0
- package/app/.next/server/app/api/runtime-connections/route.js.nft.json +1 -0
- package/app/.next/server/app/api/runtime-connections/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/service-grants/route.js +3 -3
- package/app/.next/server/app/api/service-grants/route.js.nft.json +1 -1
- package/app/.next/server/app/api/shares/[shareRef]/revoke/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/shares/[shareRef]/revoke/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/shares/[shareRef]/revoke/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/shares/[shareRef]/revoke/route.js +11 -0
- package/app/.next/server/app/api/shares/[shareRef]/revoke/route.js.nft.json +1 -0
- package/app/.next/server/app/api/shares/[shareRef]/revoke/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/shares/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/shares/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/shares/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/shares/route.js +11 -0
- package/app/.next/server/app/api/shares/route.js.nft.json +1 -0
- package/app/.next/server/app/api/shares/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/agents/[agentId]/conversations/[conversationId]/route.js +6 -6
- package/app/.next/server/app/api/v0/agents/[agentId]/conversations/[conversationId]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/agents/[agentId]/conversations/route.js +6 -6
- package/app/.next/server/app/api/v0/agents/[agentId]/conversations/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/agents/[agentId]/messages/route.js +5 -5
- package/app/.next/server/app/api/v0/agents/[agentId]/messages/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/agents/[agentId]/pins/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/agents/[agentId]/pins/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/agents/[agentId]/pins/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/agents/[agentId]/pins/route.js +11 -0
- package/app/.next/server/app/api/v0/agents/[agentId]/pins/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/agents/[agentId]/pins/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/agents/[agentId]/route.js +6 -6
- package/app/.next/server/app/api/v0/agents/[agentId]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/agents/[agentId]/sessions/[ref]/route.js +6 -6
- package/app/.next/server/app/api/v0/agents/[agentId]/sessions/[ref]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/agents/[agentId]/sessions/route.js +6 -6
- package/app/.next/server/app/api/v0/agents/[agentId]/sessions/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/agents/route.js +6 -6
- package/app/.next/server/app/api/v0/agents/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/capabilities/route.js +6 -6
- package/app/.next/server/app/api/v0/capabilities/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/conversations/[id]/route.js +5 -5
- package/app/.next/server/app/api/v0/conversations/[id]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/exchanges/[id]/cancel/route.js +6 -6
- package/app/.next/server/app/api/v0/exchanges/[id]/cancel/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/exchanges/[id]/route.js +6 -6
- package/app/.next/server/app/api/v0/exchanges/[id]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/exchanges/route.js +6 -6
- package/app/.next/server/app/api/v0/exchanges/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/mcp/route.js +6 -6
- package/app/.next/server/app/api/v0/mcp/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/pins/[pinRef]/detach/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/detach/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/detach/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/detach/route.js +11 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/detach/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/detach/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/messages/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/messages/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/messages/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/messages/route.js +11 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/messages/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/messages/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/route.js +11 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/pins/[pinRef]/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/requests/[id]/route.js +5 -5
- package/app/.next/server/app/api/v0/requests/[id]/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/sessions/[ref]/messages/route.js +6 -6
- package/app/.next/server/app/api/v0/sessions/[ref]/messages/route.js.nft.json +1 -1
- package/app/.next/server/app/api/v0/sessions/[ref]/pins/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/pins/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/pins/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/pins/route.js +11 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/pins/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/pins/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/shares/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/shares/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/shares/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/shares/route.js +11 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/shares/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/sessions/[ref]/shares/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/revoke/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/revoke/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/revoke/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/revoke/route.js +11 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/revoke/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/revoke/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/route.js +11 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/shares/[shareRef]/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/shares/current/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/shares/current/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/shares/current/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/shares/current/route.js +11 -0
- package/app/.next/server/app/api/v0/shares/current/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/shares/current/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/v0/shares/route/app-paths-manifest.json +3 -0
- package/app/.next/server/app/api/v0/shares/route/build-manifest.json +12 -0
- package/app/.next/server/app/api/v0/shares/route/server-reference-manifest.json +4 -0
- package/app/.next/server/app/api/v0/shares/route.js +11 -0
- package/app/.next/server/app/api/v0/shares/route.js.nft.json +1 -0
- package/app/.next/server/app/api/v0/shares/route_client-reference-manifest.js +3 -0
- package/app/.next/server/app/api/wake-grants/[id]/revoke/route.js +5 -5
- package/app/.next/server/app/api/wake-grants/[id]/revoke/route.js.nft.json +1 -1
- package/app/.next/server/app/api/wakes/[id]/decision/route.js +5 -5
- package/app/.next/server/app/api/wakes/[id]/decision/route.js.nft.json +1 -1
- package/app/.next/server/app/api/wakes/[id]/retry/route.js +5 -5
- package/app/.next/server/app/api/wakes/[id]/retry/route.js.nft.json +1 -1
- package/app/.next/server/app/bots/[id]/config/page.js +1 -1
- package/app/.next/server/app/bots/[id]/config/page.js.nft.json +1 -1
- package/app/.next/server/app/bots/[id]/config/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/exchanges/page.js +1 -1
- package/app/.next/server/app/exchanges/page.js.nft.json +1 -1
- package/app/.next/server/app/exchanges/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/exchanges.html +1 -1
- package/app/.next/server/app/exchanges.rsc +3 -3
- package/app/.next/server/app/exchanges.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/exchanges.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/exchanges.segments/exchanges/__PAGE__.segment.rsc +3 -3
- package/app/.next/server/app/index.html +1 -1
- package/app/.next/server/app/index.rsc +3 -3
- package/app/.next/server/app/index.segments/__PAGE__.segment.rsc +3 -3
- package/app/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/page.js +1 -1
- package/app/.next/server/app/page.js.nft.json +1 -1
- package/app/.next/server/app/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/settings/page.js +1 -1
- package/app/.next/server/app/settings/page.js.nft.json +1 -1
- package/app/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app/settings.html +1 -1
- package/app/.next/server/app/settings.rsc +3 -3
- package/app/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- package/app/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/app/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +3 -3
- package/app/.next/server/app/threads/[id]/page.js +1 -1
- package/app/.next/server/app/threads/[id]/page.js.nft.json +1 -1
- package/app/.next/server/app/threads/[id]/page_client-reference-manifest.js +1 -1
- package/app/.next/server/app-paths-manifest.json +16 -0
- package/app/.next/server/chunks/1oeh_server_app_api_bots_[id]_sessions_[ref]_pins_route_actions_0e1st6o.js +3 -0
- package/app/.next/server/chunks/1oeh_server_app_api_bots_[id]_sessions_[ref]_shares_route_actions_1jr6f0v.js +3 -0
- package/app/.next/server/chunks/[externals]_@slack_0owayck._.js +3 -0
- package/app/.next/server/chunks/[externals]__17bolvp._.js +3 -0
- package/app/.next/server/chunks/{[externals]__06lqs5i._.js → [externals]__1eaoma8._.js} +1 -1
- package/app/.next/server/chunks/[root-of-the-server]__0-vcyi-._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0-w_t2y._.js +3 -0
- package/app/.next/server/chunks/{[root-of-the-server]__17oz13o._.js → [root-of-the-server]__029-_9t._.js} +3 -3
- package/app/.next/server/chunks/[root-of-the-server]__02kssr-._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__02vrtib._.js +4 -0
- package/app/.next/server/chunks/[root-of-the-server]__04b3ml2._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__06w5xhe._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__07q5mnr._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0888o0_._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0aincj4._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0e_agq4._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0ey3_2x._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0fku-bw._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0iqh5ta._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0ivjcgs._.js +4 -0
- package/app/.next/server/chunks/[root-of-the-server]__0j4pjyg._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0kgnysc._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0lwsto-._.js +5 -0
- package/app/.next/server/chunks/[root-of-the-server]__0mo_kn3._.js +48 -0
- package/app/.next/server/chunks/[root-of-the-server]__0mp8bap._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0o9ijih._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0qaiqut._.js +44 -0
- package/app/.next/server/chunks/[root-of-the-server]__0s1enbp._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0wg992i._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__0zrx1iz._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__10b5-i-._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__17mum5-._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__17xl_55._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__1bhzfu_._.js +7 -0
- package/app/.next/server/chunks/[root-of-the-server]__1dxr858._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__1eps2a4._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__1g_n99l._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__1ggmit0._.js +4 -0
- package/app/.next/server/chunks/[root-of-the-server]__1hwy3jx._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__1i388e2._.js +3 -0
- package/app/.next/server/chunks/[root-of-the-server]__1i8glt4._.js +4 -0
- package/app/.next/server/chunks/{[root-of-the-server]__0j0i8xz._.js → [root-of-the-server]__1igzl05._.js} +1 -1
- package/app/.next/server/chunks/[root-of-the-server]__1kczttr._.js +3 -0
- package/app/.next/server/chunks/{[root-of-the-server]__1c3e2ds._.js → [root-of-the-server]__1kik2zt._.js} +1 -1
- package/app/.next/server/chunks/[root-of-the-server]__1t4ybp2._.js +48 -0
- package/app/.next/server/chunks/[root-of-the-server]__1v3ikuo._.js +3 -0
- package/app/.next/server/chunks/{[root-of-the-server]__0-45blq._.js → [root-of-the-server]__1z5l5cg._.js} +2 -2
- package/app/.next/server/chunks/[root-of-the-server]__200ep0k._.js +3 -0
- package/app/.next/server/chunks/_0061c2q._.js +50 -0
- package/app/.next/server/chunks/_04e2bgj._.js +3 -0
- package/app/.next/server/chunks/_05po7b4._.js +3 -0
- package/app/.next/server/chunks/_06sxx0e._.js +3 -0
- package/app/.next/server/chunks/_0a2do3x._.js +1 -1
- package/app/.next/server/chunks/_0ar2ooe._.js +3 -0
- package/app/.next/server/chunks/_0fmotaz._.js +3 -0
- package/app/.next/server/chunks/_0i8_xso._.js +3 -0
- package/app/.next/server/chunks/_0kpfto_._.js +3 -0
- package/app/.next/server/chunks/_0lm6uis._.js +3 -0
- package/app/.next/server/chunks/_0mpu5tl._.js +3 -0
- package/app/.next/server/chunks/_0qv-4by._.js +3 -0
- package/app/.next/server/chunks/_0u9cfq9._.js +3 -0
- package/app/.next/server/chunks/_0ul8k7g._.js +3 -0
- package/app/.next/server/chunks/_1-5mthb._.js +1 -1
- package/app/.next/server/chunks/_1-60d3o._.js +3 -0
- package/app/.next/server/chunks/_11-q8k1._.js +3 -0
- package/app/.next/server/chunks/_133y3b0._.js +3 -0
- package/app/.next/server/chunks/_167960a._.js +3 -0
- package/app/.next/server/chunks/_17vgjlt._.js +3 -0
- package/app/.next/server/chunks/_1amx9_4._.js +3 -0
- package/app/.next/server/chunks/_1b01v-_._.js +3 -0
- package/app/.next/server/chunks/_1c-g4gq._.js +3 -0
- package/app/.next/server/chunks/_1ess5if._.js +3 -0
- package/app/.next/server/chunks/_1ey6l4p._.js +3 -0
- package/app/.next/server/chunks/_1i0zod4._.js +3 -0
- package/app/.next/server/chunks/_1nlg4x_._.js +3 -0
- package/app/.next/server/chunks/_1x4dqzv._.js +3 -0
- package/app/.next/server/chunks/_1z0qbzc._.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_bots_[id]_share-policy_route_actions_0x-p250.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_runtime-connections_route_actions_06rulng.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_shares_[shareRef]_revoke_route_actions_1cu5kah.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_shares_route_actions_0wk7x1r.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_agents_[agentId]_pins_route_actions_08uftk9.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_pins_[pinRef]_detach_route_actions_0nk3268.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_pins_[pinRef]_messages_route_actions_1wenu96.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_pins_[pinRef]_route_actions_0z7fu_c.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_sessions_[ref]_pins_route_actions_0y3ere3.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_sessions_[ref]_shares_route_actions_11fh--7.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_shares_[shareRef]_revoke_route_actions_00rzyj9.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_shares_[shareRef]_route_actions_0i1t5qb.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_shares_current_route_actions_1w_bpas.js +3 -0
- package/app/.next/server/chunks/_next-internal_server_app_api_v0_shares_route_actions_1b38was.js +3 -0
- package/app/.next/server/chunks/lib_0kik6bx._.js +1 -1
- package/app/.next/server/chunks/lib_0pe3tiv._.js +1 -1
- package/app/.next/server/chunks/lib_0v4d9w0._.js +339 -0
- package/app/.next/server/chunks/lib_0zzo6zb._.js +339 -0
- package/app/.next/server/chunks/lib_15adnlz._.js +2189 -0
- package/app/.next/server/chunks/lib_1_u7n-u._.js +339 -0
- package/app/.next/server/chunks/lib_1muhwn7._.js +339 -0
- package/app/.next/server/chunks/lib_1xnxg-q._.js +339 -0
- package/app/.next/server/chunks/lib_1zc7-gl._.js +2189 -0
- package/app/.next/server/chunks/lib_agent-api_ts_0iv52-o._.js +3 -0
- package/app/.next/server/chunks/lib_db_ts_1ttuckb._.js +1951 -0
- package/app/.next/server/chunks/lib_service-api-http_ts_0xzqhny._.js +5 -5
- package/app/.next/server/chunks/lib_slack-runtime_ts_0fgsejy._.js +63 -0
- package/app/.next/server/chunks/ssr/{[root-of-the-server]__03186rx._.js → [root-of-the-server]__1smmfpx._.js} +1 -1
- package/app/.next/server/chunks/ssr/_0_fa0na._.js +3 -0
- package/app/.next/server/chunks/ssr/_0epgorw._.js +3 -0
- package/app/.next/server/chunks/ssr/_1cvuhjt._.js +3 -0
- package/app/.next/server/chunks/ssr/_1i02yyi._.js +3 -0
- package/app/.next/server/chunks/ssr/_1n5mvo5._.js +3 -0
- package/app/.next/server/chunks/ssr/_1o94bnv._.js +1 -1
- package/app/.next/server/chunks/ssr/app_bots_[id]_config_page_tsx_1e0uue9._.js +1 -1
- package/app/.next/server/chunks/ssr/app_components_AgentDeckRuntime_tsx_024janf._.js +1 -1
- package/app/.next/server/chunks/ssr/app_exchanges_page_tsx_0j-n2a1._.js +3 -0
- package/app/.next/server/chunks/ssr/node_modules_@swc_helpers_cjs__interop_require_default_cjs_1ztp13a._.js +3 -0
- package/app/.next/server/instrumentation.js +4 -0
- package/app/.next/server/middleware-build-manifest.js +3 -3
- package/app/.next/server/middleware.js +1 -1
- package/app/.next/server/pages/404.html +1 -1
- package/app/.next/server/pages/500.html +1 -1
- package/app/.next/server/server-reference-manifest.js +1 -1
- package/app/.next/server/server-reference-manifest.json +1 -1
- package/app/.next/static/chunks/0jon21u-9j2aw.css +3 -0
- package/app/.next/static/chunks/14k6cvywgknx2.js +3 -0
- package/app/.next/static/chunks/1ku9himlsx-hn.js +1 -0
- package/app/.next/static/chunks/1r5tqd-7h1xjn.js +1 -0
- package/app/.next/static/chunks/21aqekm5z0j47.js +1 -0
- package/app/.next/static/chunks/22xbkclbkct3s.js +1 -0
- package/app/.next/static/chunks/2c953okoei6ip.js +1 -0
- package/app/.next/static/chunks/2t_2gf3xoxz_m.js +1 -0
- package/app/.next/static/chunks/34vnvo1qssbaj.js +1 -0
- package/app/BUILD_INFO.json +2 -2
- package/app/node_modules/@slack/logger/dist/index.js +94 -0
- package/app/node_modules/@slack/logger/package.json +43 -0
- package/app/node_modules/@slack/socket-mode/dist/package.json +67 -0
- package/app/node_modules/@slack/socket-mode/dist/src/SlackWebSocket.js +242 -0
- package/app/node_modules/@slack/socket-mode/dist/src/SocketModeClient.js +363 -0
- package/app/node_modules/@slack/socket-mode/dist/src/UnrecoverableSocketModeStartError.js +14 -0
- package/app/node_modules/@slack/socket-mode/dist/src/errors.js +68 -0
- package/app/node_modules/@slack/socket-mode/dist/src/index.js +13 -0
- package/app/node_modules/@slack/socket-mode/dist/src/logger.js +26 -0
- package/app/node_modules/@slack/socket-mode/package.json +67 -0
- package/app/node_modules/@slack/types/dist/block-kit/block-elements.js +4 -0
- package/app/node_modules/@slack/types/dist/block-kit/blocks.js +3 -0
- package/app/node_modules/@slack/types/dist/block-kit/composition-objects.js +4 -0
- package/app/node_modules/@slack/types/dist/block-kit/extensions.js +3 -0
- package/app/node_modules/@slack/types/dist/calls.js +6 -0
- package/app/node_modules/@slack/types/dist/chunk.js +3 -0
- package/app/node_modules/@slack/types/dist/dialog.js +3 -0
- package/app/node_modules/@slack/types/dist/events/app.js +3 -0
- package/app/node_modules/@slack/types/dist/events/assistant.js +3 -0
- package/app/node_modules/@slack/types/dist/events/call.js +3 -0
- package/app/node_modules/@slack/types/dist/events/channel.js +3 -0
- package/app/node_modules/@slack/types/dist/events/dnd.js +3 -0
- package/app/node_modules/@slack/types/dist/events/email.js +3 -0
- package/app/node_modules/@slack/types/dist/events/emoji.js +3 -0
- package/app/node_modules/@slack/types/dist/events/file.js +4 -0
- package/app/node_modules/@slack/types/dist/events/function.js +3 -0
- package/app/node_modules/@slack/types/dist/events/grid-migration.js +3 -0
- package/app/node_modules/@slack/types/dist/events/group.js +3 -0
- package/app/node_modules/@slack/types/dist/events/im.js +3 -0
- package/app/node_modules/@slack/types/dist/events/index.js +43 -0
- package/app/node_modules/@slack/types/dist/events/invite.js +3 -0
- package/app/node_modules/@slack/types/dist/events/link-shared.js +3 -0
- package/app/node_modules/@slack/types/dist/events/member.js +3 -0
- package/app/node_modules/@slack/types/dist/events/message-metadata.js +3 -0
- package/app/node_modules/@slack/types/dist/events/message.js +3 -0
- package/app/node_modules/@slack/types/dist/events/pin.js +3 -0
- package/app/node_modules/@slack/types/dist/events/reaction.js +3 -0
- package/app/node_modules/@slack/types/dist/events/shared-channel.js +3 -0
- package/app/node_modules/@slack/types/dist/events/star.js +3 -0
- package/app/node_modules/@slack/types/dist/events/steps-from-apps.js +3 -0
- package/app/node_modules/@slack/types/dist/events/subteam.js +3 -0
- package/app/node_modules/@slack/types/dist/events/team.js +3 -0
- package/app/node_modules/@slack/types/dist/events/token.js +3 -0
- package/app/node_modules/@slack/types/dist/events/user.js +3 -0
- package/app/node_modules/@slack/types/dist/index.js +28 -0
- package/app/node_modules/@slack/types/dist/message-attachments.js +3 -0
- package/app/node_modules/@slack/types/dist/message-metadata.js +27 -0
- package/app/node_modules/@slack/types/dist/views.js +3 -0
- package/app/node_modules/@slack/types/package.json +47 -0
- package/app/node_modules/@slack/web-api/dist/WebClient.js +818 -0
- package/app/node_modules/@slack/web-api/dist/chat-stream.js +178 -0
- package/app/node_modules/@slack/web-api/dist/errors.js +80 -0
- package/app/node_modules/@slack/web-api/dist/file-upload.js +360 -0
- package/app/node_modules/@slack/web-api/dist/helpers.js +14 -0
- package/app/node_modules/@slack/web-api/dist/index.js +39 -0
- package/app/node_modules/@slack/web-api/dist/instrument.js +87 -0
- package/app/node_modules/@slack/web-api/dist/logger.js +29 -0
- package/app/node_modules/@slack/web-api/dist/methods.js +1647 -0
- package/app/node_modules/@slack/web-api/dist/retry-policies.js +34 -0
- package/app/node_modules/@slack/web-api/dist/types/helpers.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/analytics.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/apps.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/auth.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/barriers.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/conversations.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/emoji.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/functions.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/inviteRequests.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/roles.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/teams.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/usergroups.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/users.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/admin/workflows.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/api.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/apps.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/assistant.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/auth.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/bookmarks.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/bots.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/calls.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/canvas.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/chat.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/common.js +4 -0
- package/app/node_modules/@slack/web-api/dist/types/request/conversations.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/dialog.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/dnd.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/emoji.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/entity.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/files.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/functions.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/index.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/manifest.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/migration.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/oauth.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/openid.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/pins.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/reactions.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/reminders.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/rtm.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/search.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/slackLists.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/stars.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/team.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/tooling.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/usergroups.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/users.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/views.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/request/workflows.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAnalyticsGetFileResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsActivitiesListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsApproveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsApprovedListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsClearResolutionResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsConfigLookupResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsConfigSetResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsRequestsCancelResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsRequestsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsRestrictResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsRestrictedListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAppsUninstallResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAuthPolicyAssignEntitiesResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAuthPolicyGetEntitiesResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminAuthPolicyRemoveEntitiesResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminBarriersCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminBarriersDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminBarriersListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminBarriersUpdateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsArchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsBulkArchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsBulkDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsBulkMoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsConvertToPrivateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsConvertToPublicResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsDisconnectSharedResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsEkmListOriginalConnectedChannelInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsGetConversationPrefsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsGetCustomRetentionResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsGetTeamsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsInviteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsLookupResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsRemoveCustomRetentionResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsRenameResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsRestrictAccessAddGroupResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsRestrictAccessListGroupsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsRestrictAccessRemoveGroupResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsSearchResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsSetConversationPrefsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsSetCustomRetentionResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsSetTeamsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsUnarchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsWhitelistAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsWhitelistListGroupsLinkedToChannelResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminConversationsWhitelistRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminEmojiAddAliasResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminEmojiAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminEmojiListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminEmojiRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminEmojiRenameResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminFunctionsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminFunctionsPermissionsLookupResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminFunctionsPermissionsSetResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminInviteRequestsApproveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminInviteRequestsApprovedListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminInviteRequestsDeniedListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminInviteRequestsDenyResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminInviteRequestsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminRolesAddAssignmentsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminRolesListAssignmentsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminRolesRemoveAssignmentsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsAdminsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsOwnersListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsSettingsInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsSettingsSetDefaultChannelsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsSettingsSetDescriptionResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsSettingsSetDiscoverabilityResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsSettingsSetIconResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminTeamsSettingsSetNameResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsergroupsAddChannelsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsergroupsAddTeamsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsergroupsListChannelsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsergroupsRemoveChannelsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersAssignResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersInviteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSessionClearSettingsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSessionGetSettingsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSessionInvalidateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSessionListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSessionResetBulkResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSessionResetResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSessionSetSettingsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSetAdminResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSetExpirationResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSetOwnerResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersSetRegularResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminUsersUnsupportedVersionsExportResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminWorkflowsCollaboratorsAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminWorkflowsCollaboratorsRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminWorkflowsPermissionsLookupResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminWorkflowsSearchResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AdminWorkflowsUnpublishResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ApiTestResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsConnectionsOpenResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsEventAuthorizationsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsManifestCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsManifestDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsManifestExportResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsManifestUpdateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsManifestValidateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsPermissionsInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsPermissionsRequestResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsPermissionsResourcesListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsPermissionsScopesListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsPermissionsUsersListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsPermissionsUsersRequestResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsUninstallResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AppsUserConnectionUpdateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AssistantThreadsSetStatusResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AssistantThreadsSetSuggestedPromptsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AssistantThreadsSetTitleResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AuthRevokeResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AuthTeamsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/AuthTestResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/BookmarksAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/BookmarksEditResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/BookmarksListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/BookmarksRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/BotsInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CallsAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CallsEndResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CallsInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CallsParticipantsAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CallsParticipantsRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CallsUpdateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CanvasesAccessDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CanvasesAccessSetResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CanvasesCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CanvasesDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CanvasesEditResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/CanvasesSectionsLookupResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsArchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsHistoryResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsInviteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsJoinResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsKickResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsLeaveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsMarkResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsRenameResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsRepliesResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsSetPurposeResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsSetTopicResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChannelsUnarchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatAppendStreamResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatDeleteScheduledMessageResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatGetPermalinkResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatMeMessageResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatPostEphemeralResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatPostMessageResponse.js +67 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatScheduleMessageResponse.js +48 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatScheduledMessagesListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatStartStreamResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatStopStreamResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatUnfurlResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ChatUpdateResponse.js +48 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsAcceptSharedInviteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsApproveSharedInviteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsArchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsCanvasesCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsCloseResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsDeclineSharedInviteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsExternalInvitePermissionsSetResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsHistoryResponse.js +67 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsInviteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsInviteSharedResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsJoinResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsKickResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsLeaveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsListConnectInvitesResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsMarkResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsMembersResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsOpenResponse.js +48 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsRenameResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsRepliesResponse.js +67 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsRequestSharedInviteApproveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsRequestSharedInviteDenyResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsRequestSharedInviteListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsSetPurposeResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsSetTopicResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ConversationsUnarchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/DialogOpenResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/DndEndDndResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/DndEndSnoozeResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/DndInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/DndSetSnoozeResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/DndTeamInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/EmojiListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/EntityPresentDetailsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesCommentsAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesCommentsDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesCommentsEditResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesCompleteUploadExternalResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesGetUploadURLExternalResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesInfoResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesListResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesRemoteAddResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesRemoteInfoResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesRemoteListResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesRemoteRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesRemoteShareResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesRemoteUpdateResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesRevokePublicURLResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesSharedPublicURLResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FilesUploadResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FunctionsCompleteErrorResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/FunctionsCompleteSuccessResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsArchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsCloseResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsCreateChildResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsHistoryResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsInviteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsKickResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsLeaveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsMarkResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsOpenResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsRenameResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsRepliesResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsSetPurposeResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsSetTopicResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/GroupsUnarchiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ImCloseResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ImHistoryResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ImListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ImMarkResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ImOpenResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ImRepliesResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/MigrationExchangeResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/MpimCloseResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/MpimHistoryResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/MpimListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/MpimMarkResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/MpimOpenResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/MpimRepliesResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/OauthAccessResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/OauthTokenResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/OauthV2AccessResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/OauthV2ExchangeResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/OpenIDConnectTokenResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/OpenIDConnectUserInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/PinsAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/PinsListResponse.js +37 -0
- package/app/node_modules/@slack/web-api/dist/types/response/PinsRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ReactionsAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ReactionsGetResponse.js +48 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ReactionsListResponse.js +67 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ReactionsRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/RemindersAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/RemindersCompleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/RemindersDeleteResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/RemindersInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/RemindersListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/RtmConnectResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/RtmStartResponse.js +77 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SearchAllResponse.js +82 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SearchFilesResponse.js +63 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SearchMessagesResponse.js +67 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsAccessDeleteResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsAccessSetResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsCreateResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsDownloadGetResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsDownloadStartResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsItemsCreateResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsItemsDeleteMultipleResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsItemsDeleteResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsItemsInfoResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsItemsListResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsItemsUpdateResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/SlackListsUpdateResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/StarsAddResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/StarsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/StarsRemoveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamAccessLogsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamBillableInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamBillingInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamExternalTeamsDisconnectResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamExternalTeamsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamIntegrationLogsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamPreferencesListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/TeamProfileGetResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ToolingTokensRotateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsergroupsCreateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsergroupsDisableResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsergroupsEnableResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsergroupsListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsergroupsUpdateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsergroupsUsersListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsergroupsUsersUpdateResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersConversationsResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersDeletePhotoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersDiscoverableContactsLookupResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersGetPresenceResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersIdentityResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersInfoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersListResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersLookupByEmailResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersProfileGetResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersProfileSetResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersSetActiveResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersSetPhotoResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/UsersSetPresenceResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ViewsOpenResponse.js +31 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ViewsPublishResponse.js +31 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ViewsPushResponse.js +31 -0
- package/app/node_modules/@slack/web-api/dist/types/response/ViewsUpdateResponse.js +31 -0
- package/app/node_modules/@slack/web-api/dist/types/response/WorkflowsFeaturedAddResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/WorkflowsFeaturedListResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/WorkflowsFeaturedRemoveResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/WorkflowsFeaturedSetResponse.js +3 -0
- package/app/node_modules/@slack/web-api/dist/types/response/WorkflowsStepCompletedResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/WorkflowsStepFailedResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/WorkflowsUpdateStepResponse.js +11 -0
- package/app/node_modules/@slack/web-api/dist/types/response/index.js +3 -0
- package/app/node_modules/@slack/web-api/package.json +75 -0
- package/app/node_modules/agent-base/dist/src/index.js +203 -0
- package/app/node_modules/agent-base/dist/src/promisify.js +18 -0
- package/app/node_modules/agent-base/package.json +64 -0
- package/app/node_modules/asynckit/index.js +6 -0
- package/app/node_modules/asynckit/lib/abort.js +29 -0
- package/app/node_modules/asynckit/lib/async.js +34 -0
- package/app/node_modules/asynckit/lib/defer.js +26 -0
- package/app/node_modules/asynckit/lib/iterate.js +75 -0
- package/app/node_modules/asynckit/lib/state.js +37 -0
- package/app/node_modules/asynckit/lib/terminator.js +29 -0
- package/app/node_modules/asynckit/package.json +63 -0
- package/app/node_modules/asynckit/parallel.js +43 -0
- package/app/node_modules/asynckit/serial.js +17 -0
- package/app/node_modules/asynckit/serialOrdered.js +75 -0
- package/app/node_modules/axios/dist/node/axios.cjs +6808 -0
- package/app/node_modules/axios/package.json +203 -0
- package/app/node_modules/call-bind-apply-helpers/actualApply.js +10 -0
- package/app/node_modules/call-bind-apply-helpers/functionApply.js +4 -0
- package/app/node_modules/call-bind-apply-helpers/functionCall.js +4 -0
- package/app/node_modules/call-bind-apply-helpers/index.js +15 -0
- package/app/node_modules/call-bind-apply-helpers/package.json +85 -0
- package/app/node_modules/call-bind-apply-helpers/reflectApply.js +4 -0
- package/app/node_modules/combined-stream/lib/combined_stream.js +208 -0
- package/app/node_modules/combined-stream/package.json +25 -0
- package/app/node_modules/debug/package.json +64 -0
- package/app/node_modules/debug/src/browser.js +272 -0
- package/app/node_modules/debug/src/common.js +292 -0
- package/app/node_modules/debug/src/index.js +10 -0
- package/app/node_modules/debug/src/node.js +263 -0
- package/app/node_modules/delayed-stream/lib/delayed_stream.js +107 -0
- package/app/node_modules/delayed-stream/package.json +27 -0
- package/app/node_modules/dunder-proto/get.js +30 -0
- package/app/node_modules/dunder-proto/package.json +76 -0
- package/app/node_modules/es-define-property/index.js +14 -0
- package/app/node_modules/es-define-property/package.json +81 -0
- package/app/node_modules/es-errors/eval.js +4 -0
- package/app/node_modules/es-errors/index.js +4 -0
- package/app/node_modules/es-errors/package.json +80 -0
- package/app/node_modules/es-errors/range.js +4 -0
- package/app/node_modules/es-errors/ref.js +4 -0
- package/app/node_modules/es-errors/syntax.js +4 -0
- package/app/node_modules/es-errors/type.js +4 -0
- package/app/node_modules/es-errors/uri.js +4 -0
- package/app/node_modules/es-object-atoms/index.js +4 -0
- package/app/node_modules/es-object-atoms/package.json +79 -0
- package/app/node_modules/es-set-tostringtag/index.js +35 -0
- package/app/node_modules/es-set-tostringtag/package.json +78 -0
- package/app/node_modules/eventemitter3/index.js +336 -0
- package/app/node_modules/eventemitter3/package.json +62 -0
- package/app/node_modules/follow-redirects/debug.js +15 -0
- package/app/node_modules/follow-redirects/index.js +709 -0
- package/app/node_modules/follow-redirects/package.json +58 -0
- package/app/node_modules/form-data/lib/browser.js +4 -0
- package/app/node_modules/form-data/lib/form_data.js +506 -0
- package/app/node_modules/form-data/lib/populate.js +10 -0
- package/app/node_modules/form-data/package.json +82 -0
- package/app/node_modules/function-bind/implementation.js +84 -0
- package/app/node_modules/function-bind/index.js +5 -0
- package/app/node_modules/function-bind/package.json +87 -0
- package/app/node_modules/get-intrinsic/index.js +378 -0
- package/app/node_modules/get-intrinsic/package.json +97 -0
- package/app/node_modules/get-proto/Object.getPrototypeOf.js +6 -0
- package/app/node_modules/get-proto/Reflect.getPrototypeOf.js +4 -0
- package/app/node_modules/get-proto/index.js +27 -0
- package/app/node_modules/get-proto/package.json +81 -0
- package/app/node_modules/gopd/gOPD.js +4 -0
- package/app/node_modules/gopd/index.js +15 -0
- package/app/node_modules/gopd/package.json +77 -0
- package/app/node_modules/has-flag/index.js +8 -0
- package/app/node_modules/has-flag/package.json +46 -0
- package/app/node_modules/has-symbols/index.js +14 -0
- package/app/node_modules/has-symbols/package.json +111 -0
- package/app/node_modules/has-symbols/shams.js +45 -0
- package/app/node_modules/has-tostringtag/package.json +108 -0
- package/app/node_modules/has-tostringtag/shams.js +8 -0
- package/app/node_modules/hasown/index.js +8 -0
- package/app/node_modules/hasown/package.json +91 -0
- package/app/node_modules/https-proxy-agent/dist/agent.js +177 -0
- package/app/node_modules/https-proxy-agent/dist/index.js +14 -0
- package/app/node_modules/https-proxy-agent/dist/parse-proxy-response.js +66 -0
- package/app/node_modules/https-proxy-agent/package.json +56 -0
- package/app/node_modules/is-electron/index.js +21 -0
- package/app/node_modules/is-electron/package.json +34 -0
- package/app/node_modules/is-stream/index.js +28 -0
- package/app/node_modules/is-stream/package.json +42 -0
- package/app/node_modules/math-intrinsics/abs.js +4 -0
- package/app/node_modules/math-intrinsics/floor.js +4 -0
- package/app/node_modules/math-intrinsics/isNaN.js +6 -0
- package/app/node_modules/math-intrinsics/max.js +4 -0
- package/app/node_modules/math-intrinsics/min.js +4 -0
- package/app/node_modules/math-intrinsics/package.json +86 -0
- package/app/node_modules/math-intrinsics/pow.js +4 -0
- package/app/node_modules/math-intrinsics/round.js +4 -0
- package/app/node_modules/math-intrinsics/sign.js +11 -0
- package/app/node_modules/mime-db/db.json +8519 -0
- package/app/node_modules/mime-db/index.js +12 -0
- package/app/node_modules/mime-db/package.json +60 -0
- package/app/node_modules/mime-types/index.js +188 -0
- package/app/node_modules/mime-types/package.json +44 -0
- package/app/node_modules/ms/index.js +162 -0
- package/app/node_modules/ms/package.json +38 -0
- package/app/node_modules/p-finally/index.js +15 -0
- package/app/node_modules/p-finally/package.json +42 -0
- package/app/node_modules/p-queue/dist/index.js +279 -0
- package/app/node_modules/p-queue/dist/lower-bound.js +21 -0
- package/app/node_modules/p-queue/dist/priority-queue.js +32 -0
- package/app/node_modules/p-queue/node_modules/eventemitter3/index.js +336 -0
- package/app/node_modules/p-queue/node_modules/eventemitter3/package.json +56 -0
- package/app/node_modules/p-queue/package.json +92 -0
- package/app/node_modules/p-retry/index.js +85 -0
- package/app/node_modules/p-retry/package.json +51 -0
- package/app/node_modules/p-timeout/index.js +57 -0
- package/app/node_modules/p-timeout/package.json +45 -0
- package/app/node_modules/retry/index.js +1 -0
- package/app/node_modules/retry/lib/retry.js +100 -0
- package/app/node_modules/retry/lib/retry_operation.js +162 -0
- package/app/node_modules/retry/package.json +36 -0
- package/app/node_modules/supports-color/index.js +135 -0
- package/app/node_modules/supports-color/package.json +53 -0
- package/app/node_modules/ws/index.js +22 -0
- package/app/node_modules/ws/lib/buffer-util.js +131 -0
- package/app/node_modules/ws/lib/constants.js +19 -0
- package/app/node_modules/ws/lib/event-target.js +292 -0
- package/app/node_modules/ws/lib/extension.js +203 -0
- package/app/node_modules/ws/lib/limiter.js +55 -0
- package/app/node_modules/ws/lib/permessage-deflate.js +530 -0
- package/app/node_modules/ws/lib/receiver.js +743 -0
- package/app/node_modules/ws/lib/sender.js +607 -0
- package/app/node_modules/ws/lib/stream.js +161 -0
- package/app/node_modules/ws/lib/subprotocol.js +62 -0
- package/app/node_modules/ws/lib/validation.js +152 -0
- package/app/node_modules/ws/lib/websocket-server.js +562 -0
- package/app/node_modules/ws/lib/websocket.js +1421 -0
- package/app/node_modules/ws/package.json +74 -0
- package/app/package.json +1 -1
- package/app/server.js +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +7 -4
- package/dist/clients.js +7 -3
- package/dist/config.d.ts +2 -1
- package/dist/config.js +5 -4
- package/dist/contract.d.ts +1 -0
- package/dist/contract.js +5 -0
- package/dist/home.d.ts +1 -1
- package/dist/home.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/product.d.ts +8 -0
- package/dist/product.js +70 -4
- package/dist/upstream.js +2 -2
- package/package.json +2 -2
- package/schemas/botmancers.mcp.v2.tools.json +2353 -4
- package/skills/botmancers-collaboration/SKILL.md +25 -6
- package/skills/botmancers-collaboration/references/workflows.md +93 -0
- package/app/.next/server/chunks/[root-of-the-server]__0ab4e_k._.js +0 -3
- package/app/.next/server/chunks/[root-of-the-server]__0izjfmr._.js +0 -1656
- package/app/.next/server/chunks/[root-of-the-server]__0qozubc._.js +0 -3
- package/app/.next/server/chunks/[root-of-the-server]__0wtzcge._.js +0 -3
- package/app/.next/server/chunks/[root-of-the-server]__10m3szc._.js +0 -3
- package/app/.next/server/chunks/[root-of-the-server]__15hknun._.js +0 -3
- package/app/.next/server/chunks/[root-of-the-server]__16ikszu._.js +0 -3
- package/app/.next/server/chunks/[root-of-the-server]__1afl75n._.js +0 -3
- package/app/.next/server/chunks/[root-of-the-server]__1kvvdpx._.js +0 -7
- package/app/.next/server/chunks/[root-of-the-server]__1qoa704._.js +0 -7
- package/app/.next/server/chunks/[root-of-the-server]__1slu7d7._.js +0 -7
- package/app/.next/server/chunks/_06rti77._.js +0 -30
- package/app/.next/server/chunks/_09k38l1._.js +0 -3
- package/app/.next/server/chunks/_0dlg5kj._.js +0 -30
- package/app/.next/server/chunks/_0dyculb._.js +0 -30
- package/app/.next/server/chunks/_0eig2jc._.js +0 -30
- package/app/.next/server/chunks/_0ggf7vy._.js +0 -3
- package/app/.next/server/chunks/_0gtqbub._.js +0 -3
- package/app/.next/server/chunks/_0i7ga8c._.js +0 -3
- package/app/.next/server/chunks/_0kghtb6._.js +0 -3
- package/app/.next/server/chunks/_0orubev._.js +0 -3
- package/app/.next/server/chunks/_0sfpe9z._.js +0 -3
- package/app/.next/server/chunks/_0th2j4w._.js +0 -3
- package/app/.next/server/chunks/_0uz7r06._.js +0 -30
- package/app/.next/server/chunks/_0x05ts4._.js +0 -3
- package/app/.next/server/chunks/_0y3geoj._.js +0 -30
- package/app/.next/server/chunks/_12tq5uv._.js +0 -30
- package/app/.next/server/chunks/_147-4gl._.js +0 -3
- package/app/.next/server/chunks/_14ky6a2._.js +0 -30
- package/app/.next/server/chunks/_16kbxdt._.js +0 -30
- package/app/.next/server/chunks/_1963m2f._.js +0 -30
- package/app/.next/server/chunks/_1_34_h3._.js +0 -30
- package/app/.next/server/chunks/_1cc-2mx._.js +0 -3
- package/app/.next/server/chunks/_1ee4ej2._.js +0 -3
- package/app/.next/server/chunks/_1esxu1s._.js +0 -3
- package/app/.next/server/chunks/_1gn7eh7._.js +0 -3
- package/app/.next/server/chunks/_1gw7qwf._.js +0 -3
- package/app/.next/server/chunks/_1inyx08._.js +0 -3
- package/app/.next/server/chunks/_1kjsnlr._.js +0 -3
- package/app/.next/server/chunks/_1nurj3f._.js +0 -30
- package/app/.next/server/chunks/_1p2rf_n._.js +0 -30
- package/app/.next/server/chunks/_1p8rola._.js +0 -3
- package/app/.next/server/chunks/_1u6tw78._.js +0 -30
- package/app/.next/server/chunks/app_api_import-capabilities_route_ts_013w1kt._.js +0 -3
- package/app/.next/server/chunks/lib_0t3s3rj._.js +0 -30
- package/app/.next/server/chunks/lib_0zxi6rx._.js +0 -148
- package/app/.next/server/chunks/lib_12udr7g._.js +0 -148
- package/app/.next/server/chunks/lib_draft_ts_1atoius._.js +0 -3
- package/app/.next/server/chunks/lib_session-catalog_ts_1i7f38f._.js +0 -30
- package/app/.next/server/chunks/ssr/_00ysoah._.js +0 -3
- package/app/.next/server/chunks/ssr/_157wnb_._.js +0 -3
- package/app/.next/server/chunks/ssr/app_1-nwnha._.js +0 -3
- package/app/.next/server/chunks/ssr/app_components_0bhuhd-._.js +0 -3
- package/app/.next/server/chunks/ssr/app_components_0w2_b3t._.js +0 -3
- package/app/.next/server/chunks/ssr/node_modules_next_dist_client_components_server-async-storage_0t1dato.js +0 -3
- package/app/.next/static/chunks/0774d7ob6aze_.js +0 -1
- package/app/.next/static/chunks/0d3ein53nlgja.js +0 -1
- package/app/.next/static/chunks/1i5xroz391zkb.js +0 -1
- package/app/.next/static/chunks/1vz50l951sr9e.css +0 -3
- package/app/.next/static/chunks/24ggj819yt3y6.js +0 -1
- package/app/.next/static/chunks/2_8lcalraul5s.js +0 -3
- package/app/.next/static/chunks/30i0-l04mmdvk.js +0 -1
- package/app/.next/static/chunks/3wdlh25l1vww9.js +0 -1
- /package/app/.next/static/{ewp56HqU5-d9bpFog3bli → _yrIZIFsIbXA0Gaxkytjd}/_buildManifest.js +0 -0
- /package/app/.next/static/{ewp56HqU5-d9bpFog3bli → _yrIZIFsIbXA0Gaxkytjd}/_clientMiddlewareManifest.js +0 -0
- /package/app/.next/static/{ewp56HqU5-d9bpFog3bli → _yrIZIFsIbXA0Gaxkytjd}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,2189 @@
|
|
|
1
|
+
module.exports=[99904,89965,98307,76422,34923,98596,46632,94057,99684,74455,71711,23325,78636,48758,e=>{"use strict";let t;var n=e.i(85148),r=e.i(22734),i=e.i(14747),s=e.i(54799);let a=["hermes","cursor","claude","codex","muse"],o={hermes:"Hermes",cursor:"Cursor",claude:"Claude",codex:"Codex",muse:"Muse Code"},d="hermes",u={hermes:"hermes-gateway",cursor:"agent-deck-run",claude:"agent-deck-run",codex:"agent-deck-run",muse:"agent-deck-run"};function l(e){return u[e]}class _ extends Error{code="invalid-agent";constructor(e){super(`Invalid agent: ${JSON.stringify(String(e))}. Expected one of ${a.join("|")}.`)}}function c(e){if(null==e)return null;let t=String(e).trim();if(!t)return null;if(a.includes(t))return t;throw new _(e)}function E(e){return null==e?null:String(e).trim()||null}function p(e){if(!0===e||1===e)return!0;if("string"==typeof e){let t=e.trim().toLowerCase();return"1"===t||"true"===t}return!1}function m(e){let t,n=d,r=!0;try{n=c(e.agent)??d}catch{r=!1}let i=E(e.deck_id),s=E(e.deck_name),a=E(e.working_directory);if("launch_profile"in e){let n=e.launch_profile;t="direct"===n||"agent_deck"===n?n:null}else t=i?"agent_deck":null;let o="direct"!==t&&(null===i||p(e.needs_deck_selection)),u=null;return r?t?!function(e){if(!("session_scope_kind"in e))return!0;let t=e.session_scope_kind,n=[];try{n=e.session_scope_items?JSON.parse(e.session_scope_items):[]}catch{return!1}if(!Array.isArray(n))return!1;let r=n.filter(e=>"string"==typeof e&&e.trim()).length;return"all_provider_sessions"===t?0===r:("workspaces"===t||"sessions"===t)&&r>0}(e)?u="session_scope":"agent_deck"===t&&o?u="deck":"direct"===t&&"hermes-gateway"!==l(n)&&(u="direct_runtime"):u="launch_profile":u="agent",{agent:n,deck_id:"direct"===t?null:i,deck_name:s,working_directory:"direct"===t?null:a,needs_deck_selection:o,launch_profile:t,needs_launch_profile:null===t,launchable:null===u,launch_blocker:u}}a.join("|");let f=["codex","claude","cursor","muse"];function T(e){let t=E(e);return t&&f.includes(t)?t:null}function g(e){let t=E(e.deck_id),n=E(e.deck_name),r=E(e.working_directory);try{let s=c(e.agent);if(s){var i;return{agent:s,deck_id:t,deck_name:n,working_directory:r,needs_deck_selection:null===t||(i=e.needs_deck_selection,p(i)),migrated:!1}}}catch{}let s=E(e.runtime),a=d,o=p(e.needs_deck_reselection);if("agent-deck"===s){let t=T(e.agent_client);t?a=t:o=!0}else if("hermes"!==s){let t=T(e.coding_runtime);t&&n&&r&&(a=t,o=!0)}return{agent:a,deck_id:t,deck_name:n,working_directory:r,needs_deck_selection:null===t||o,migrated:!0}}function h(e,t){let n=m(e),r=t.agent??n.agent,i=void 0!==t.working_directory?t.working_directory:n.working_directory;return void 0!==t.deck_id?{agent:r,deck_id:t.deck_id,deck_name:null,working_directory:i,needs_deck_selection:!1}:{agent:r,deck_id:n.deck_id,deck_name:n.deck_name,working_directory:i,needs_deck_selection:n.needs_deck_selection}}e.s(["AGENTS",0,a,"AGENT_LABELS",0,o,"DEFAULT_AGENT",0,d,"agentTransport",0,l,"applyAgentUpdate",0,h,"migrateLegacyAgentFields",0,g,"normalizeAgent",0,c,"resolveAgent",0,m],89965);let N=["read_only","workspace_write"],R=["workspaces","sessions","all_provider_sessions"],v="This computer";function k(e){return null==e?null:String(e).trim()||null}function y(e){return`rc-local-${e}`}function w(e){return`${o[e]} on ${v.toLowerCase()}`}function L(e){return e.length>1?e.replace(/\/+$/,""):e}function O(e,t){let n=L(e),r=L(t);return n===r||r.startsWith("/"===n?"/":`${n}/`)}function I(e){return!0===e||1===e||"1"===e}function A(e){var t;return{runtime_connection_id:e.runtime_connection_id,launch_profile:e.launch_profile,deck_id:"agent_deck"===e.launch_profile?e.deck_id:null,working_directory:"agent_deck"===e.launch_profile?e.working_directory:null,session_scope_kind:e.session_scope.kind,session_scope_items:JSON.stringify("workspaces"===(t=e.session_scope).kind?t.workspaces:"sessions"===t.kind?t.sessions:[]),default_workspace:e.default_workspace,policy_mode:e.policy.mode,allow_new_sessions:+!!e.policy.allow_new_sessions,allow_resume_with_edits:+!!e.policy.allow_resume_with_edits,home_session_id:e.home_session_id,needs_deck_selection:0}}function S(e){let t="hermes";try{t=c(e.agent)??"hermes"}catch{t="hermes"}let n=k(e.deck_id),r=I(e.needs_deck_selection),i=k(e.working_directory)??`~/.botmancers/${e.id}`;return{runtime_connection_id:y(t),provider:t,launch_profile:n&&!r?"agent_deck":null,session_scope_kind:"workspaces",session_scope_items:JSON.stringify([i]),policy_mode:"read_only",allow_new_sessions:1,allow_resume_with_edits:0}}function b(e){return"chief-of-staff"===String(e??"").trim().toLowerCase()}a.join("|"),e.s(["LOCAL_HOST",0,v,"localConnectionId",0,y,"localConnectionLabel",0,w,"migrateRegistration",0,S,"readStoredPolicy",0,function(e){var t;return"string"==typeof(t=e.policy_mode)&&N.includes(t)?{mode:e.policy_mode,allow_new_sessions:I(e.allow_new_sessions),allow_resume_with_edits:I(e.allow_resume_with_edits)}:null},"readStoredScope",0,function(e){let t=e.session_scope_kind;if(!("string"==typeof t&&R.includes(t)))return null;let n=[];if(e.session_scope_items)try{let t=function(e){if(null==e)return[];if(!Array.isArray(e))return null;let t=[];for(let n of e){if("string"!=typeof n)return null;let e=n.trim();e&&!t.includes(e)&&t.push(e)}return t}(JSON.parse(e.session_scope_items));if(null===t)return null;n=t}catch{return null}return"all_provider_sessions"===t?0===n.length?{kind:t,workspaces:[],sessions:[]}:null:0===n.length?null:"workspaces"===t?{kind:t,workspaces:n,sessions:[]}:{kind:t,workspaces:[],sessions:n}},"registrationColumns",0,A,"workspaceContains",0,O],98307);let q=Object.freeze(["conversation","implementation","review","revision"]),C=Object.freeze(["readonly","edit"]);Object.freeze(["ui","api","wake","continuation","exchange"]);let x=Object.freeze({conversation:"readonly",implementation:"edit",review:"readonly",revision:"edit"});function D(e){return"string"==typeof e&&q.includes(e)}function U(e,t){return{ok:!1,code:e,reason:t}}function F(e){var t,n,r,i;if(!D(e.executionKind))return U("unknown_execution_kind",`Unknown execution kind ${JSON.stringify(String(e.executionKind))}.`);let s=e.executionKind,a=(t=e.entryPoint,n=s,r=e.wakeSyntax,i=!0===e.resumesWorkRequest,"ui"===t||"api"===t?"conversation"!==n?{code:"unsupported_authority",reason:`A direct message runs as a read-only conversation turn, not ${n}.`}:"direct_message_conversation":"continuation"===t?"conversation"!==n?{code:"unsupported_authority",reason:`A coordinator continuation runs as a read-only conversation turn, not ${n}.`}:"coordinator_continuation":"exchange"===t?"conversation"!==n?{code:"unsupported_authority",reason:`A session exchange runs as a read-only conversation turn, not ${n}.`}:"session_exchange_conversation":"wake"!==t?{code:"unsupported_authority",reason:"Unknown policy entry point."}:"legacy"===r?"conversation"!==n?{code:"unsupported_authority",reason:`A legacy WAKE directive runs as a conversation turn, not ${n}.`}:"legacy_wake_conversation":"structured"!==r?{code:"unsupported_authority",reason:"Unknown Wake syntax."}:"revision"===n!==i?{code:"unsupported_authority",reason:"revision"===n?"A revision names the Work Request it resumes.":"Only a revision resumes a Work Request."}:"structured_wake");return"string"!=typeof a?U(a.code,a.reason):{ok:!0,policy:Object.freeze({policy_version:1,execution_kind:s,tool_profile:x[s],entry_point:e.entryPoint,rule:a})}}let W=new Set(["policy_version","execution_kind","tool_profile","entry_point","rule"]);function M(e){if(!e||"object"!=typeof e||Array.isArray(e))return U("malformed_policy","The execution policy snapshot is missing.");let t=Object.keys(e);if(t.length!==W.size||t.some(e=>!W.has(e)))return U("malformed_policy","The execution policy snapshot has unexpected fields.");if(1!==e.policy_version)return U("malformed_policy","Unsupported execution policy version.");if(!D(e.execution_kind))return U("unknown_execution_kind",`Unknown execution kind ${JSON.stringify(String(e.execution_kind))}.`);if(!C.includes(e.tool_profile))return U("unsupported_authority",`Unsupported tool profile ${JSON.stringify(String(e.tool_profile))}.`);if(x[e.execution_kind]!==e.tool_profile)return U("unsupported_authority",`Execution kind ${e.execution_kind} requires the ${x[e.execution_kind]} tool profile.`);let n={direct_message_conversation:{entry:["ui","api"],kinds:["conversation"]},legacy_wake_conversation:{entry:["wake"],kinds:["conversation"]},coordinator_continuation:{entry:["continuation"],kinds:["conversation"]},session_exchange_conversation:{entry:["exchange"],kinds:["conversation"]},structured_wake:{entry:["wake"],kinds:[...q]}},r="string"==typeof e.rule?n[e.rule]:void 0;return r&&r.entry.includes(e.entry_point)?r.kinds.includes(e.execution_kind)?{ok:!0,policy:Object.freeze({...e})}:U("unsupported_authority",`Rule ${e.rule} does not grant ${e.execution_kind}.`):U("malformed_policy","The execution policy rule does not match its entry point.")}e.s(["TOOL_PROFILE_FOR_KIND",0,x,"authorizeWorkRequest",0,function(e){let t;if(!D(e.execution_kind))return U("unknown_execution_kind",`Unknown execution kind ${JSON.stringify(String(e.execution_kind))}.`);try{t="string"==typeof e.policy_snapshot?JSON.parse(e.policy_snapshot):null}catch{return U("malformed_policy","The policy snapshot is not valid JSON.")}let n=M(t&&"object"==typeof t&&!Array.isArray(t)?t.execution_policy:void 0);return n.ok?n.policy.execution_kind!==e.execution_kind||n.policy.tool_profile!==e.tool_profile?U("unsupported_authority","The Work Request authority does not match its policy snapshot."):t.tool_profile!==e.tool_profile?U("malformed_policy","The policy snapshot tool profile does not match the Work Request."):n:n},"isExecutionKind",0,D,"selectExecutionPolicy",0,F,"validateExecutionPolicy",0,M],76422);let H=Object.freeze({max_attempts:1,base_delay_ms:1e3,max_delay_ms:6e4,attempt_timeout_ms:null});function X(e){if(void 0===e||!/^\d+$/.test(e.trim()))return null;let t=Number(e.trim());return Number.isSafeInteger(t)&&t>0?t:null}function G(e=process.env){let t=X(e.BOTMANCERS_RETRY_MAX_ATTEMPTS),n=X(e.BOTMANCERS_RETRY_BASE_DELAY_MS)??H.base_delay_ms,r=X(e.BOTMANCERS_RETRY_MAX_DELAY_MS)??H.max_delay_ms,i=$({max_attempts:null===t?H.max_attempts:Math.min(t,10),base_delay_ms:n,max_delay_ms:Math.max(r,n),attempt_timeout_ms:X(e.BOTMANCERS_ATTEMPT_TIMEOUT_MS)});return{deadlineMs:X(e.BOTMANCERS_REQUEST_DEADLINE_MS),retryPolicy:i.ok?i.policy:{...H}}}function $(e){if(!e||"object"!=typeof e||Array.isArray(e))return{ok:!1,reason:"A retry policy is an object."};let t=e=>"number"==typeof e&&Number.isSafeInteger(e);if(!t(e.max_attempts)||e.max_attempts<1||e.max_attempts>10)return{ok:!1,reason:"max_attempts must be an integer from 1 to 10."};if(!t(e.base_delay_ms)||e.base_delay_ms<0)return{ok:!1,reason:"base_delay_ms must be a non-negative integer."};if(!t(e.max_delay_ms)||e.max_delay_ms<e.base_delay_ms)return{ok:!1,reason:"max_delay_ms must be an integer no smaller than base_delay_ms."};let n=e.attempt_timeout_ms??null;return null!==n&&(!t(n)||n<1)?{ok:!1,reason:"attempt_timeout_ms must be a positive integer or null."}:{ok:!0,policy:{max_attempts:e.max_attempts,base_delay_ms:e.base_delay_ms,max_delay_ms:e.max_delay_ms,attempt_timeout_ms:n}}}let B=["agent_deck_token_missing","agent_deck_unauthorized","agent_deck_forbidden"],K={unavailable:"retryable",runtime_failed:"retryable",timed_out:"retryable",launch_failed:"terminal",unsupported_authority:"terminal",result_contract:"terminal",cancelled:"terminal",session_mismatch:"manual_attention"};e.s(["DEFAULT_RETRY_POLICY",0,H,"attemptDeadline",0,function(e,t,n){let r=null===e.attempt_timeout_ms?null:n+e.attempt_timeout_ms;return null===r?t:null===t?r:Math.min(r,t)},"classifyFailure",0,function(e,t=null){return t&&B.includes(t)?"manual_attention":K[e??"runtime_failed"]??"terminal"},"decideRetry",0,function(e){var t;let n;if("terminal"===e.disposition)return{action:"fail",disposition:"terminal"};let r=e.attemptCount<e.policy.max_attempts;if("manual_attention"===e.disposition)return r?{action:"attention"}:{action:"fail",disposition:"terminal"};if(!r)return{action:"exhausted"};let i=e.attemptCount,s=(t=e.policy,n=Math.max(0,i-1),Math.min(t.max_delay_ms,t.base_delay_ms*2**Math.min(n,30))),a=e.now+s;return null!==e.deadlineAt&&a>=e.deadlineAt?{action:"deadline"}:{action:"retry",nextEligibleAt:a,delayMs:s,retry:i}},"requestControlDefaultsFromEnv",0,G,"storedRetryPolicy",0,function(e){if(!e)return{...H};try{let t=$(JSON.parse(e));return t.ok?t.policy:{...H}}catch{return{...H}}},"validateRetryPolicy",0,$],34923);let P={cached_input_tokens:"cached_input_tokens",cachedInputTokens:"cached_input_tokens",cache_read_input_tokens:"cache_read_input_tokens",cacheReadInputTokens:"cache_read_input_tokens",cacheReadTokens:"cache_read_input_tokens",cache_creation_input_tokens:"cache_creation_input_tokens",cacheCreationInputTokens:"cache_creation_input_tokens",cacheWriteTokens:"cache_creation_input_tokens",reasoning_output_tokens:"reasoning_output_tokens",reasoningOutputTokens:"reasoning_output_tokens",reasoningTokens:"reasoning_output_tokens"};function j(e){return null===e||"object"!=typeof e||Array.isArray(e)?null:e}function Y(e){return"number"==typeof e&&Number.isInteger(e)&&e>=0&&e<=Number.MAX_SAFE_INTEGER?e:null}function z(e){return"number"==typeof e&&Number.isFinite(e)&&e>=0&&e<1e9?e:null}function J(e,t,n){for(let r of t)if(r in e){let t=n(e[r]);if(null!==t)return t}return null}function V(e,t,n){let r=e?J(e,["input_tokens","inputTokens"],Y):null,i=e?J(e,["output_tokens","outputTokens"],Y):null;return null===r&&null===i&&null===t?null:{input_tokens:r,output_tokens:i,cost_usd:t,source:n,breakdown:e?function(e){let t={};for(let[n,r]of Object.entries(P)){let i=Y(e[n]);null!==i&&void 0===t[r]&&(t[r]=i)}return Object.keys(t).length>0?t:null}(e):null}}function Q(e){let t=j(e);if(!t)return null;let n="string"==typeof t.type?t.type:null,r=j(t.usage);if("turn.completed"===n)return V(r,null,"codex.turn_completed");if("result"===n)return V(r,J(t,["total_cost_usd","totalCostUsd","cost_usd","costUsd"],z),"result");if(null===n||"usage"===n){let e=r??t,n=J(e,["cost_usd","costUsd","total_cost_usd","totalCostUsd"],z)??(r?J(t,["cost_usd","costUsd","total_cost_usd","totalCostUsd"],z):null);return V(e,n,"normalized")}return null}function Z(e,t){return null===e?t:null===t?e:e+t}function ee(e){let t=j(e);if(!t)return null;let n="codex.turn_completed"===t.source||"result"===t.source||"normalized"===t.source?t.source:"normalized",r=Y(t.input_tokens),i=Y(t.output_tokens),s=z(t.cost_usd);if(null===r&&null===i&&null===s)return null;let a=j(t.breakdown),o={};if(a)for(let e of new Set(Object.values(P))){let t=Y(a[e]);null!==t&&(o[e]=t)}return{input_tokens:r,output_tokens:i,cost_usd:s,source:n,breakdown:Object.keys(o).length>0?o:null}}function et(e,t,n,r){if(!e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'usage_samples'").get())return;let i=ee(r.usage),a=r.now??Date.now();e.prepare(`
|
|
2
|
+
INSERT INTO usage_samples (
|
|
3
|
+
id, sample_key, agent_id, attempt_id, session_ref, turn_id, provider, source,
|
|
4
|
+
input_tokens, output_tokens, cost_usd, breakdown, observed_at, created_at, updated_at
|
|
5
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
6
|
+
ON CONFLICT(sample_key) DO UPDATE SET
|
|
7
|
+
input_tokens = COALESCE(usage_samples.input_tokens, excluded.input_tokens),
|
|
8
|
+
output_tokens = COALESCE(usage_samples.output_tokens, excluded.output_tokens),
|
|
9
|
+
cost_usd = COALESCE(usage_samples.cost_usd, excluded.cost_usd),
|
|
10
|
+
breakdown = COALESCE(usage_samples.breakdown, excluded.breakdown),
|
|
11
|
+
source = CASE WHEN usage_samples.source = 'none' THEN excluded.source ELSE usage_samples.source END,
|
|
12
|
+
updated_at = CASE
|
|
13
|
+
WHEN (usage_samples.input_tokens IS NULL AND excluded.input_tokens IS NOT NULL)
|
|
14
|
+
OR (usage_samples.output_tokens IS NULL AND excluded.output_tokens IS NOT NULL)
|
|
15
|
+
OR (usage_samples.cost_usd IS NULL AND excluded.cost_usd IS NOT NULL)
|
|
16
|
+
THEN excluded.updated_at ELSE usage_samples.updated_at END
|
|
17
|
+
`).run((0,s.randomUUID)(),t,r.agentId,n.attemptId,n.sessionRef,n.turnId,String(r.provider).slice(0,100),i?.source??"none",i?.input_tokens??null,i?.output_tokens??null,i?.cost_usd??null,i?.breakdown?JSON.stringify(i.breakdown):null,r.observedAt,a,a)}function en(e,t,n){et(e,`attempt:${t}`,{attemptId:t,sessionRef:null,turnId:null},n)}e.s(["normalizeUsage",0,ee,"usageFromEvent",0,Q,"usageFromEvents",0,function(e){if(!e)return null;let t=null,n=null,r=null,i=new Set;for(let s of e){let e=j(s),a=e&&("number"==typeof e.seq||"string"==typeof e.id)?`${e.type}:${e.seq??e.id}`:null;if(a){if(i.has(a))continue;i.add(a)}let o=Q(s);o&&("result"===o.source?t=o:"codex.turn_completed"===o.source?n=null===n?o:{input_tokens:Z(n.input_tokens,o.input_tokens),output_tokens:Z(n.output_tokens,o.output_tokens),cost_usd:null,source:"codex.turn_completed",breakdown:function(e,t){if(!e)return t;if(!t)return e;let n={...e};for(let[e,r]of Object.entries(t))n[e]=(n[e]??0)+r;return n}(n.breakdown,o.breakdown)}:r=o)}return t??n??r}],98596),e.s(["recordAttemptUsageSample",0,en,"recordTurnUsageSample",0,function(e,t,n,r){et(e,`turn:${t}`,{attemptId:null,sessionRef:n,turnId:t},r)}],46632);let er=["queued","extracting","delivering","completed","failed","cancelled"],ei=["completed","failed","cancelled"],es={queued:["extracting","failed","cancelled"],extracting:["delivering","completed","failed","cancelled"],delivering:["completed","failed","cancelled"],completed:[],failed:[],cancelled:[]},ea=Object.freeze({instructionChars:4e3,packetChars:16e3,packetObjectiveChars:2e3,packetListItems:20,packetItemChars:500,answerChars:16e3,replyChars:16e3,extractionOutputChars:32e3,promptChars:24e3}),eo=["queued","blocked","running","waiting","completed","failed","cancelled"],ed=["completed","failed","cancelled"],eu={queued:["running","blocked","cancelled","failed"],blocked:["queued","cancelled","failed"],running:["waiting","queued","completed","failed","cancelled"],waiting:["running","queued","cancelled","failed"],completed:[],failed:[],cancelled:[]},el=["dispatcher","ui_message","ui_continuation"];class e_ extends Error{code;constructor(e,t){super(t),this.code=e}}let ec=ed.map(e=>`'${e}'`).join(", "),eE=eo.map(e=>`'${e}'`).join(", "),ep=[{version:1,name:"core_engine_tables",up:e=>{e.exec(`
|
|
18
|
+
CREATE TABLE work_request_transitions (
|
|
19
|
+
from_state TEXT NOT NULL,
|
|
20
|
+
to_state TEXT NOT NULL,
|
|
21
|
+
PRIMARY KEY (from_state, to_state)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
CREATE TABLE work_requests (
|
|
25
|
+
id TEXT PRIMARY KEY,
|
|
26
|
+
source_conversation_id TEXT NOT NULL,
|
|
27
|
+
source_event_id TEXT NOT NULL,
|
|
28
|
+
requester_kind TEXT NOT NULL CHECK (requester_kind IN ('person', 'bot', 'service')),
|
|
29
|
+
requester_id TEXT NOT NULL,
|
|
30
|
+
target_agent_id TEXT NOT NULL,
|
|
31
|
+
intent TEXT NOT NULL,
|
|
32
|
+
execution_kind TEXT NOT NULL CHECK (execution_kind IN ('conversation', 'implementation', 'review', 'revision')),
|
|
33
|
+
tool_profile TEXT NOT NULL CHECK (tool_profile IN ('readonly', 'edit')),
|
|
34
|
+
parent_request_id TEXT,
|
|
35
|
+
root_request_id TEXT NOT NULL,
|
|
36
|
+
wake_event_id TEXT,
|
|
37
|
+
depth INTEGER NOT NULL DEFAULT 0 CHECK (depth >= 0),
|
|
38
|
+
idempotency_key TEXT NOT NULL CHECK (length(idempotency_key) > 0),
|
|
39
|
+
request_hash TEXT NOT NULL,
|
|
40
|
+
policy_snapshot TEXT NOT NULL,
|
|
41
|
+
state TEXT NOT NULL CHECK (state IN (${eE})),
|
|
42
|
+
state_reason TEXT,
|
|
43
|
+
result TEXT,
|
|
44
|
+
error_code TEXT,
|
|
45
|
+
error_message TEXT,
|
|
46
|
+
version INTEGER NOT NULL DEFAULT 0,
|
|
47
|
+
legacy_agent_request_id TEXT UNIQUE,
|
|
48
|
+
created_at INTEGER NOT NULL,
|
|
49
|
+
updated_at INTEGER NOT NULL,
|
|
50
|
+
terminal_at INTEGER,
|
|
51
|
+
CHECK ((state IN (${ec})) = (terminal_at IS NOT NULL)),
|
|
52
|
+
FOREIGN KEY (source_conversation_id) REFERENCES conversations(id),
|
|
53
|
+
FOREIGN KEY (target_agent_id) REFERENCES bots(id),
|
|
54
|
+
FOREIGN KEY (parent_request_id) REFERENCES work_requests(id),
|
|
55
|
+
FOREIGN KEY (root_request_id) REFERENCES work_requests(id)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
CREATE UNIQUE INDEX idx_work_requests_idempotency
|
|
59
|
+
ON work_requests(requester_kind, requester_id, idempotency_key);
|
|
60
|
+
CREATE INDEX idx_work_requests_conversation
|
|
61
|
+
ON work_requests(source_conversation_id, created_at);
|
|
62
|
+
CREATE INDEX idx_work_requests_state
|
|
63
|
+
ON work_requests(state, created_at);
|
|
64
|
+
CREATE INDEX idx_work_requests_parent
|
|
65
|
+
ON work_requests(parent_request_id) WHERE parent_request_id IS NOT NULL;
|
|
66
|
+
|
|
67
|
+
CREATE TABLE session_bindings (
|
|
68
|
+
id TEXT PRIMARY KEY,
|
|
69
|
+
agent_id TEXT NOT NULL,
|
|
70
|
+
adapter TEXT NOT NULL,
|
|
71
|
+
conversation_id TEXT,
|
|
72
|
+
request_id TEXT,
|
|
73
|
+
external_session_id TEXT NOT NULL,
|
|
74
|
+
source_attempt_id TEXT,
|
|
75
|
+
created_at INTEGER NOT NULL,
|
|
76
|
+
released_at INTEGER,
|
|
77
|
+
CHECK (conversation_id IS NOT NULL OR request_id IS NOT NULL),
|
|
78
|
+
FOREIGN KEY (agent_id) REFERENCES bots(id),
|
|
79
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
80
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id),
|
|
81
|
+
FOREIGN KEY (source_attempt_id) REFERENCES work_attempts(id)
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
CREATE UNIQUE INDEX idx_session_bindings_active
|
|
85
|
+
ON session_bindings(agent_id, adapter, IFNULL(conversation_id, ''), IFNULL(request_id, ''))
|
|
86
|
+
WHERE released_at IS NULL;
|
|
87
|
+
|
|
88
|
+
CREATE TABLE work_attempts (
|
|
89
|
+
id TEXT PRIMARY KEY,
|
|
90
|
+
request_id TEXT NOT NULL,
|
|
91
|
+
attempt_number INTEGER NOT NULL CHECK (attempt_number >= 1),
|
|
92
|
+
kind TEXT NOT NULL CHECK (kind IN ('launch', 'resume')),
|
|
93
|
+
adapter TEXT NOT NULL CHECK (length(adapter) > 0),
|
|
94
|
+
tool_profile TEXT NOT NULL CHECK (tool_profile IN ('readonly', 'edit')),
|
|
95
|
+
launch_snapshot TEXT NOT NULL,
|
|
96
|
+
launch_snapshot_hash TEXT NOT NULL,
|
|
97
|
+
resumed_session_binding_id TEXT,
|
|
98
|
+
external_run_id TEXT,
|
|
99
|
+
external_session_id TEXT,
|
|
100
|
+
outcome TEXT CHECK (outcome IN ('succeeded', 'failed', 'cancelled', 'interrupted', 'timed_out')),
|
|
101
|
+
error_category TEXT,
|
|
102
|
+
error_message TEXT,
|
|
103
|
+
artifacts TEXT NOT NULL DEFAULT '[]',
|
|
104
|
+
started_at INTEGER NOT NULL,
|
|
105
|
+
finished_at INTEGER,
|
|
106
|
+
CHECK ((outcome IS NULL) = (finished_at IS NULL)),
|
|
107
|
+
CHECK ((kind = 'resume') = (resumed_session_binding_id IS NOT NULL)),
|
|
108
|
+
UNIQUE (request_id, attempt_number),
|
|
109
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id),
|
|
110
|
+
FOREIGN KEY (resumed_session_binding_id) REFERENCES session_bindings(id)
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
CREATE UNIQUE INDEX idx_work_attempts_open
|
|
114
|
+
ON work_attempts(request_id) WHERE finished_at IS NULL;
|
|
115
|
+
|
|
116
|
+
CREATE TABLE engine_events (
|
|
117
|
+
id TEXT PRIMARY KEY,
|
|
118
|
+
request_id TEXT NOT NULL,
|
|
119
|
+
sequence INTEGER NOT NULL CHECK (sequence >= 1),
|
|
120
|
+
attempt_id TEXT,
|
|
121
|
+
type TEXT NOT NULL CHECK (length(type) > 0),
|
|
122
|
+
data TEXT,
|
|
123
|
+
created_at INTEGER NOT NULL,
|
|
124
|
+
UNIQUE (request_id, sequence),
|
|
125
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id),
|
|
126
|
+
FOREIGN KEY (attempt_id) REFERENCES work_attempts(id)
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
-- Foreign keys (insert/update side).
|
|
130
|
+
CREATE TRIGGER trg_work_requests_fk_insert BEFORE INSERT ON work_requests
|
|
131
|
+
BEGIN
|
|
132
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.source_conversation_id')
|
|
133
|
+
WHERE NOT EXISTS (SELECT 1 FROM conversations WHERE id = NEW.source_conversation_id);
|
|
134
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.target_agent_id')
|
|
135
|
+
WHERE NOT EXISTS (SELECT 1 FROM bots WHERE id = NEW.target_agent_id);
|
|
136
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.parent_request_id')
|
|
137
|
+
WHERE NEW.parent_request_id IS NOT NULL
|
|
138
|
+
AND NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.parent_request_id);
|
|
139
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.root_request_id')
|
|
140
|
+
WHERE NEW.root_request_id <> NEW.id
|
|
141
|
+
AND NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.root_request_id);
|
|
142
|
+
END;
|
|
143
|
+
|
|
144
|
+
-- Identity, lineage, and policy are fixed at intake.
|
|
145
|
+
CREATE TRIGGER trg_work_requests_immutable BEFORE UPDATE OF
|
|
146
|
+
id, source_conversation_id, source_event_id, requester_kind, requester_id,
|
|
147
|
+
target_agent_id, intent, execution_kind, tool_profile, parent_request_id,
|
|
148
|
+
root_request_id, wake_event_id, depth, idempotency_key, request_hash,
|
|
149
|
+
policy_snapshot, legacy_agent_request_id, created_at
|
|
150
|
+
ON work_requests
|
|
151
|
+
BEGIN
|
|
152
|
+
SELECT RAISE(ABORT, 'work_requests identity, lineage, and policy are immutable');
|
|
153
|
+
END;
|
|
154
|
+
|
|
155
|
+
CREATE TRIGGER trg_work_requests_transition BEFORE UPDATE OF state ON work_requests
|
|
156
|
+
WHEN NEW.state <> OLD.state
|
|
157
|
+
BEGIN
|
|
158
|
+
SELECT RAISE(ABORT, 'invalid work_requests state transition')
|
|
159
|
+
WHERE NOT EXISTS (
|
|
160
|
+
SELECT 1 FROM work_request_transitions WHERE from_state = OLD.state AND to_state = NEW.state
|
|
161
|
+
);
|
|
162
|
+
END;
|
|
163
|
+
|
|
164
|
+
CREATE TRIGGER trg_work_requests_terminal BEFORE UPDATE ON work_requests
|
|
165
|
+
WHEN OLD.state IN (${ec})
|
|
166
|
+
BEGIN
|
|
167
|
+
SELECT RAISE(ABORT, 'terminal work_requests are immutable');
|
|
168
|
+
END;
|
|
169
|
+
|
|
170
|
+
CREATE TRIGGER trg_session_bindings_fk BEFORE INSERT ON session_bindings
|
|
171
|
+
BEGIN
|
|
172
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.conversation_id')
|
|
173
|
+
WHERE NEW.conversation_id IS NOT NULL
|
|
174
|
+
AND NOT EXISTS (SELECT 1 FROM conversations WHERE id = NEW.conversation_id);
|
|
175
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.request_id')
|
|
176
|
+
WHERE NEW.request_id IS NOT NULL
|
|
177
|
+
AND NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.request_id);
|
|
178
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.source_attempt_id')
|
|
179
|
+
WHERE NEW.source_attempt_id IS NOT NULL
|
|
180
|
+
AND NOT EXISTS (SELECT 1 FROM work_attempts WHERE id = NEW.source_attempt_id);
|
|
181
|
+
END;
|
|
182
|
+
|
|
183
|
+
-- A binding's session value is opaque and never rewritten; only
|
|
184
|
+
-- release (supersession) may change.
|
|
185
|
+
CREATE TRIGGER trg_session_bindings_immutable BEFORE UPDATE OF
|
|
186
|
+
id, agent_id, adapter, conversation_id, request_id, external_session_id, source_attempt_id, created_at
|
|
187
|
+
ON session_bindings
|
|
188
|
+
BEGIN
|
|
189
|
+
SELECT RAISE(ABORT, 'session_bindings are immutable');
|
|
190
|
+
END;
|
|
191
|
+
|
|
192
|
+
CREATE TRIGGER trg_work_attempts_fk BEFORE INSERT ON work_attempts
|
|
193
|
+
BEGIN
|
|
194
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_attempts.request_id')
|
|
195
|
+
WHERE NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.request_id);
|
|
196
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_attempts.resumed_session_binding_id')
|
|
197
|
+
WHERE NEW.resumed_session_binding_id IS NOT NULL
|
|
198
|
+
AND NOT EXISTS (SELECT 1 FROM session_bindings WHERE id = NEW.resumed_session_binding_id);
|
|
199
|
+
END;
|
|
200
|
+
|
|
201
|
+
-- Launch snapshot and authority never change after insert.
|
|
202
|
+
CREATE TRIGGER trg_work_attempts_immutable BEFORE UPDATE OF
|
|
203
|
+
id, request_id, attempt_number, kind, adapter, tool_profile,
|
|
204
|
+
launch_snapshot, launch_snapshot_hash, resumed_session_binding_id, started_at
|
|
205
|
+
ON work_attempts
|
|
206
|
+
BEGIN
|
|
207
|
+
SELECT RAISE(ABORT, 'work_attempts launch fields are immutable');
|
|
208
|
+
END;
|
|
209
|
+
|
|
210
|
+
-- External identifiers are recorded once, never rewritten.
|
|
211
|
+
CREATE TRIGGER trg_work_attempts_external_ids BEFORE UPDATE OF external_run_id, external_session_id ON work_attempts
|
|
212
|
+
WHEN (OLD.external_run_id IS NOT NULL AND NEW.external_run_id IS NOT OLD.external_run_id)
|
|
213
|
+
OR (OLD.external_session_id IS NOT NULL AND NEW.external_session_id IS NOT OLD.external_session_id)
|
|
214
|
+
BEGIN
|
|
215
|
+
SELECT RAISE(ABORT, 'work_attempts external identifiers are set once');
|
|
216
|
+
END;
|
|
217
|
+
|
|
218
|
+
CREATE TRIGGER trg_work_attempts_finished BEFORE UPDATE ON work_attempts
|
|
219
|
+
WHEN OLD.finished_at IS NOT NULL
|
|
220
|
+
BEGIN
|
|
221
|
+
SELECT RAISE(ABORT, 'finished work_attempts are immutable');
|
|
222
|
+
END;
|
|
223
|
+
|
|
224
|
+
CREATE TRIGGER trg_engine_events_fk BEFORE INSERT ON engine_events
|
|
225
|
+
BEGIN
|
|
226
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: engine_events.request_id')
|
|
227
|
+
WHERE NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.request_id);
|
|
228
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: engine_events.attempt_id')
|
|
229
|
+
WHERE NEW.attempt_id IS NOT NULL
|
|
230
|
+
AND NOT EXISTS (SELECT 1 FROM work_attempts WHERE id = NEW.attempt_id AND request_id = NEW.request_id);
|
|
231
|
+
END;
|
|
232
|
+
|
|
233
|
+
CREATE TRIGGER trg_engine_events_append_only BEFORE UPDATE ON engine_events
|
|
234
|
+
BEGIN
|
|
235
|
+
SELECT RAISE(ABORT, 'engine_events are append-only');
|
|
236
|
+
END;
|
|
237
|
+
`);let t=e.prepare("INSERT INTO work_request_transitions (from_state, to_state) VALUES (?, ?)");for(let e of eo)for(let n of eu[e])t.run(e,n)}},{version:2,name:"core_engine_referential_integrity",up:e=>{e.exec(`
|
|
238
|
+
-- Foreign keys (delete side): RESTRICT. A referenced row cannot be
|
|
239
|
+
-- deleted while anything still points at it; deleteEngineRecords
|
|
240
|
+
-- removes dependants first, in one transaction.
|
|
241
|
+
CREATE TRIGGER trg_conversations_engine_restrict BEFORE DELETE ON conversations
|
|
242
|
+
BEGIN
|
|
243
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.source_conversation_id')
|
|
244
|
+
WHERE EXISTS (SELECT 1 FROM work_requests WHERE source_conversation_id = OLD.id);
|
|
245
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.conversation_id')
|
|
246
|
+
WHERE EXISTS (SELECT 1 FROM session_bindings WHERE conversation_id = OLD.id);
|
|
247
|
+
END;
|
|
248
|
+
|
|
249
|
+
CREATE TRIGGER trg_bots_engine_restrict BEFORE DELETE ON bots
|
|
250
|
+
BEGIN
|
|
251
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.target_agent_id')
|
|
252
|
+
WHERE EXISTS (SELECT 1 FROM work_requests WHERE target_agent_id = OLD.id);
|
|
253
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.agent_id')
|
|
254
|
+
WHERE EXISTS (SELECT 1 FROM session_bindings WHERE agent_id = OLD.id);
|
|
255
|
+
END;
|
|
256
|
+
|
|
257
|
+
CREATE TRIGGER trg_work_requests_restrict BEFORE DELETE ON work_requests
|
|
258
|
+
BEGIN
|
|
259
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.parent_request_id')
|
|
260
|
+
WHERE EXISTS (
|
|
261
|
+
SELECT 1 FROM work_requests
|
|
262
|
+
WHERE id <> OLD.id AND (parent_request_id = OLD.id OR root_request_id = OLD.id)
|
|
263
|
+
);
|
|
264
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_attempts.request_id')
|
|
265
|
+
WHERE EXISTS (SELECT 1 FROM work_attempts WHERE request_id = OLD.id);
|
|
266
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: engine_events.request_id')
|
|
267
|
+
WHERE EXISTS (SELECT 1 FROM engine_events WHERE request_id = OLD.id);
|
|
268
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.request_id')
|
|
269
|
+
WHERE EXISTS (SELECT 1 FROM session_bindings WHERE request_id = OLD.id);
|
|
270
|
+
END;
|
|
271
|
+
|
|
272
|
+
CREATE TRIGGER trg_work_attempts_restrict BEFORE DELETE ON work_attempts
|
|
273
|
+
BEGIN
|
|
274
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: engine_events.attempt_id')
|
|
275
|
+
WHERE EXISTS (SELECT 1 FROM engine_events WHERE attempt_id = OLD.id);
|
|
276
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.source_attempt_id')
|
|
277
|
+
WHERE EXISTS (SELECT 1 FROM session_bindings WHERE source_attempt_id = OLD.id);
|
|
278
|
+
END;
|
|
279
|
+
|
|
280
|
+
CREATE TRIGGER trg_session_bindings_restrict BEFORE DELETE ON session_bindings
|
|
281
|
+
BEGIN
|
|
282
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_attempts.resumed_session_binding_id')
|
|
283
|
+
WHERE EXISTS (SELECT 1 FROM work_attempts WHERE resumed_session_binding_id = OLD.id);
|
|
284
|
+
END;
|
|
285
|
+
|
|
286
|
+
-- Session continuity: a binding belongs to one Agent and adapter in
|
|
287
|
+
-- one scope, and its source attempt must come from that scope.
|
|
288
|
+
CREATE TRIGGER trg_session_bindings_scope BEFORE INSERT ON session_bindings
|
|
289
|
+
BEGIN
|
|
290
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.agent_id')
|
|
291
|
+
WHERE NOT EXISTS (SELECT 1 FROM bots WHERE id = NEW.agent_id);
|
|
292
|
+
SELECT RAISE(ABORT, 'session binding does not match its work request')
|
|
293
|
+
WHERE NEW.request_id IS NOT NULL AND NOT EXISTS (
|
|
294
|
+
SELECT 1 FROM work_requests r
|
|
295
|
+
WHERE r.id = NEW.request_id AND r.target_agent_id = NEW.agent_id
|
|
296
|
+
AND (NEW.conversation_id IS NULL OR r.source_conversation_id = NEW.conversation_id)
|
|
297
|
+
);
|
|
298
|
+
SELECT RAISE(ABORT, 'session binding does not match its source attempt')
|
|
299
|
+
WHERE NEW.source_attempt_id IS NOT NULL AND NOT EXISTS (
|
|
300
|
+
SELECT 1 FROM work_attempts a JOIN work_requests r ON r.id = a.request_id
|
|
301
|
+
WHERE a.id = NEW.source_attempt_id AND a.adapter = NEW.adapter AND r.target_agent_id = NEW.agent_id
|
|
302
|
+
AND (NEW.request_id IS NULL OR a.request_id = NEW.request_id)
|
|
303
|
+
AND (NEW.conversation_id IS NULL OR r.source_conversation_id = NEW.conversation_id)
|
|
304
|
+
);
|
|
305
|
+
END;
|
|
306
|
+
|
|
307
|
+
-- A resume continues an active binding of the same Agent and
|
|
308
|
+
-- adapter, from the same conversation and request lineage.
|
|
309
|
+
CREATE TRIGGER trg_work_attempts_resume_scope BEFORE INSERT ON work_attempts
|
|
310
|
+
WHEN NEW.resumed_session_binding_id IS NOT NULL
|
|
311
|
+
BEGIN
|
|
312
|
+
SELECT RAISE(ABORT, 'resumed session binding does not match the work request')
|
|
313
|
+
WHERE NOT EXISTS (
|
|
314
|
+
SELECT 1 FROM session_bindings b
|
|
315
|
+
JOIN work_requests r ON r.id = NEW.request_id
|
|
316
|
+
LEFT JOIN work_requests br ON br.id = b.request_id
|
|
317
|
+
WHERE b.id = NEW.resumed_session_binding_id AND b.released_at IS NULL
|
|
318
|
+
AND b.agent_id = r.target_agent_id AND b.adapter = NEW.adapter
|
|
319
|
+
AND (b.conversation_id IS NULL OR b.conversation_id = r.source_conversation_id)
|
|
320
|
+
AND (b.request_id IS NULL OR br.root_request_id = r.root_request_id)
|
|
321
|
+
);
|
|
322
|
+
END;
|
|
323
|
+
`)}},{version:3,name:"core_engine_hardening",up:e=>{let t=eo.flatMap(e=>eu[e].map(t=>`'${e}>${t}'`)).join(", ");e.exec(`
|
|
324
|
+
-- The lifecycle allowlist lives in the trigger itself, so no data
|
|
325
|
+
-- write can widen or break it. work_request_transitions stays as a
|
|
326
|
+
-- readable copy and is locked against writes.
|
|
327
|
+
DROP TRIGGER trg_work_requests_transition;
|
|
328
|
+
CREATE TRIGGER trg_work_requests_transition BEFORE UPDATE OF state ON work_requests
|
|
329
|
+
WHEN NEW.state <> OLD.state
|
|
330
|
+
BEGIN
|
|
331
|
+
SELECT RAISE(ABORT, 'invalid work_requests state transition')
|
|
332
|
+
WHERE (OLD.state || '>' || NEW.state) NOT IN (${t});
|
|
333
|
+
END;
|
|
334
|
+
|
|
335
|
+
CREATE TRIGGER trg_work_request_transitions_insert BEFORE INSERT ON work_request_transitions
|
|
336
|
+
BEGIN
|
|
337
|
+
SELECT RAISE(ABORT, 'work_request_transitions is read-only');
|
|
338
|
+
END;
|
|
339
|
+
CREATE TRIGGER trg_work_request_transitions_update BEFORE UPDATE ON work_request_transitions
|
|
340
|
+
BEGIN
|
|
341
|
+
SELECT RAISE(ABORT, 'work_request_transitions is read-only');
|
|
342
|
+
END;
|
|
343
|
+
CREATE TRIGGER trg_work_request_transitions_delete BEFORE DELETE ON work_request_transitions
|
|
344
|
+
BEGIN
|
|
345
|
+
SELECT RAISE(ABORT, 'work_request_transitions is read-only');
|
|
346
|
+
END;
|
|
347
|
+
|
|
348
|
+
-- Engine events are never deleted one by one. Aggregate cleanup
|
|
349
|
+
-- (deleteEngineRecords) first marks the requests it removes in
|
|
350
|
+
-- engine_event_purges; only events of a marked request may go.
|
|
351
|
+
CREATE TABLE engine_event_purges (
|
|
352
|
+
request_id TEXT PRIMARY KEY
|
|
353
|
+
);
|
|
354
|
+
CREATE TRIGGER trg_engine_events_no_delete BEFORE DELETE ON engine_events
|
|
355
|
+
BEGIN
|
|
356
|
+
SELECT RAISE(ABORT, 'engine_events are append-only')
|
|
357
|
+
WHERE NOT EXISTS (SELECT 1 FROM engine_event_purges WHERE request_id = OLD.request_id);
|
|
358
|
+
END;
|
|
359
|
+
|
|
360
|
+
-- Foreign keys (parent-key update side): RESTRICT.
|
|
361
|
+
CREATE TRIGGER trg_conversations_engine_restrict_update BEFORE UPDATE OF id ON conversations
|
|
362
|
+
WHEN NEW.id IS NOT OLD.id
|
|
363
|
+
BEGIN
|
|
364
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.source_conversation_id')
|
|
365
|
+
WHERE EXISTS (SELECT 1 FROM work_requests WHERE source_conversation_id = OLD.id);
|
|
366
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.conversation_id')
|
|
367
|
+
WHERE EXISTS (SELECT 1 FROM session_bindings WHERE conversation_id = OLD.id);
|
|
368
|
+
END;
|
|
369
|
+
|
|
370
|
+
CREATE TRIGGER trg_bots_engine_restrict_update BEFORE UPDATE OF id ON bots
|
|
371
|
+
WHEN NEW.id IS NOT OLD.id
|
|
372
|
+
BEGIN
|
|
373
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: work_requests.target_agent_id')
|
|
374
|
+
WHERE EXISTS (SELECT 1 FROM work_requests WHERE target_agent_id = OLD.id);
|
|
375
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_bindings.agent_id')
|
|
376
|
+
WHERE EXISTS (SELECT 1 FROM session_bindings WHERE agent_id = OLD.id);
|
|
377
|
+
END;
|
|
378
|
+
|
|
379
|
+
-- Attempt kind and continuity agree: only a resume names a binding.
|
|
380
|
+
-- (Fresh schemas also carry this as a CHECK.)
|
|
381
|
+
CREATE TRIGGER trg_work_attempts_kind BEFORE INSERT ON work_attempts
|
|
382
|
+
WHEN (NEW.kind = 'resume') <> (NEW.resumed_session_binding_id IS NOT NULL)
|
|
383
|
+
BEGIN
|
|
384
|
+
SELECT RAISE(ABORT, 'work_attempts kind does not match resumed_session_binding_id');
|
|
385
|
+
END;
|
|
386
|
+
`)}},{version:4,name:"engine_event_purge_authority",up:e=>{e.exec(`
|
|
387
|
+
-- Purge authority no longer lives in data: any writer could insert
|
|
388
|
+
-- an engine_event_purges row and then delete single events. The
|
|
389
|
+
-- guard now asks engine_event_purge_authorized(), a connection
|
|
390
|
+
-- function that is true only while deleteEngineRecords removes that
|
|
391
|
+
-- request whole. Connections without it cannot delete events.
|
|
392
|
+
DROP TRIGGER trg_engine_events_no_delete;
|
|
393
|
+
DROP TABLE engine_event_purges;
|
|
394
|
+
CREATE TRIGGER trg_engine_events_no_delete BEFORE DELETE ON engine_events
|
|
395
|
+
BEGIN
|
|
396
|
+
SELECT RAISE(ABORT, 'engine_events are append-only')
|
|
397
|
+
WHERE NOT engine_event_purge_authorized(OLD.request_id);
|
|
398
|
+
END;
|
|
399
|
+
`)}},{version:5,name:"conversation_intakes",up:e=>{e.exec(`
|
|
400
|
+
-- NOT-465: one row per accepted conversation message, keyed by the
|
|
401
|
+
-- requester's idempotency key. It names the source event (message)
|
|
402
|
+
-- and the Work Requests created from it, so an exact retry replays
|
|
403
|
+
-- the original identifiers whether or not any request was created.
|
|
404
|
+
CREATE TABLE conversation_intakes (
|
|
405
|
+
requester_kind TEXT NOT NULL CHECK (requester_kind IN ('person', 'bot', 'service')),
|
|
406
|
+
requester_id TEXT NOT NULL,
|
|
407
|
+
idempotency_key TEXT NOT NULL CHECK (length(idempotency_key) > 0),
|
|
408
|
+
request_hash TEXT NOT NULL,
|
|
409
|
+
surface TEXT NOT NULL CHECK (surface IN ('ui', 'api')),
|
|
410
|
+
conversation_id TEXT NOT NULL,
|
|
411
|
+
source_event_id TEXT NOT NULL,
|
|
412
|
+
work_request_ids TEXT NOT NULL DEFAULT '[]',
|
|
413
|
+
created_at INTEGER NOT NULL,
|
|
414
|
+
PRIMARY KEY (requester_kind, requester_id, idempotency_key)
|
|
415
|
+
);
|
|
416
|
+
CREATE INDEX idx_conversation_intakes_conversation ON conversation_intakes(conversation_id);
|
|
417
|
+
`)}},{version:6,name:"attempt_output",up:e=>{e.exec(`
|
|
418
|
+
-- NOT-467: the runtime output an Attempt returned, recorded with
|
|
419
|
+
-- its terminal outcome (null while open or when none was returned).
|
|
420
|
+
ALTER TABLE work_attempts ADD COLUMN output TEXT;
|
|
421
|
+
`)}},{version:7,name:"wakes",up:e=>{e.exec(`
|
|
422
|
+
-- NOT-466: one row per Wake found in an Agent reply (lib/wake-router).
|
|
423
|
+
-- Every Wake is kept, including ones whose target is missing or
|
|
424
|
+
-- whose envelope is invalid, so nothing is silently dropped. An
|
|
425
|
+
-- accepted or blocked Wake names its one Work Request. Lineage is
|
|
426
|
+
-- durable: parent/root request and root Wake, never process memory.
|
|
427
|
+
CREATE TABLE wakes (
|
|
428
|
+
id TEXT PRIMARY KEY,
|
|
429
|
+
idempotency_key TEXT NOT NULL UNIQUE CHECK (length(idempotency_key) > 0),
|
|
430
|
+
source_conversation_id TEXT NOT NULL,
|
|
431
|
+
source_event_id TEXT NOT NULL,
|
|
432
|
+
position INTEGER NOT NULL CHECK (position >= 0),
|
|
433
|
+
syntax TEXT NOT NULL CHECK (syntax IN ('structured', 'legacy')),
|
|
434
|
+
payload TEXT NOT NULL,
|
|
435
|
+
requester_agent_id TEXT NOT NULL,
|
|
436
|
+
requested_target TEXT,
|
|
437
|
+
target_agent_id TEXT,
|
|
438
|
+
target_name_snapshot TEXT,
|
|
439
|
+
execution_kind TEXT CHECK (execution_kind IN ('conversation', 'implementation', 'review', 'revision')),
|
|
440
|
+
parent_request_id TEXT,
|
|
441
|
+
root_request_id TEXT,
|
|
442
|
+
root_wake_id TEXT NOT NULL,
|
|
443
|
+
depth INTEGER NOT NULL CHECK (depth >= 0),
|
|
444
|
+
status TEXT NOT NULL CHECK (status IN ('accepted', 'blocked', 'unavailable', 'rejected')),
|
|
445
|
+
reason_code TEXT,
|
|
446
|
+
reason TEXT,
|
|
447
|
+
work_request_id TEXT UNIQUE,
|
|
448
|
+
created_at INTEGER NOT NULL,
|
|
449
|
+
updated_at INTEGER NOT NULL,
|
|
450
|
+
UNIQUE (source_event_id, position),
|
|
451
|
+
CHECK ((status IN ('accepted', 'blocked')) = (work_request_id IS NOT NULL)),
|
|
452
|
+
CHECK (status = 'accepted' OR reason_code IS NOT NULL),
|
|
453
|
+
FOREIGN KEY (source_conversation_id) REFERENCES conversations(id),
|
|
454
|
+
FOREIGN KEY (work_request_id) REFERENCES work_requests(id),
|
|
455
|
+
FOREIGN KEY (parent_request_id) REFERENCES work_requests(id)
|
|
456
|
+
);
|
|
457
|
+
CREATE INDEX idx_wakes_conversation ON wakes(source_conversation_id, created_at);
|
|
458
|
+
CREATE INDEX idx_wakes_status ON wakes(status, created_at);
|
|
459
|
+
|
|
460
|
+
CREATE TRIGGER trg_wakes_fk BEFORE INSERT ON wakes
|
|
461
|
+
BEGIN
|
|
462
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: wakes.source_conversation_id')
|
|
463
|
+
WHERE NOT EXISTS (SELECT 1 FROM conversations WHERE id = NEW.source_conversation_id);
|
|
464
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: wakes.parent_request_id')
|
|
465
|
+
WHERE NEW.parent_request_id IS NOT NULL
|
|
466
|
+
AND NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.parent_request_id);
|
|
467
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: wakes.work_request_id')
|
|
468
|
+
WHERE NEW.work_request_id IS NOT NULL
|
|
469
|
+
AND NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.work_request_id);
|
|
470
|
+
END;
|
|
471
|
+
|
|
472
|
+
-- Source, payload, and lineage are fixed when the Wake is recorded.
|
|
473
|
+
CREATE TRIGGER trg_wakes_immutable BEFORE UPDATE OF
|
|
474
|
+
id, idempotency_key, source_conversation_id, source_event_id, position, syntax, payload,
|
|
475
|
+
requester_agent_id, requested_target, execution_kind, parent_request_id,
|
|
476
|
+
root_wake_id, depth, created_at
|
|
477
|
+
ON wakes
|
|
478
|
+
BEGIN
|
|
479
|
+
SELECT RAISE(ABORT, 'wakes source, payload, and lineage are immutable');
|
|
480
|
+
END;
|
|
481
|
+
|
|
482
|
+
-- Recovery only moves forward: an unavailable target may resolve
|
|
483
|
+
-- or turn out unroutable (rejected), a blocked request may become
|
|
484
|
+
-- accepted. The resolved target, Work
|
|
485
|
+
-- Request, and root request (for a Wake without a parent, its own
|
|
486
|
+
-- request) are set once.
|
|
487
|
+
CREATE TRIGGER trg_wakes_recovery BEFORE UPDATE ON wakes
|
|
488
|
+
BEGIN
|
|
489
|
+
SELECT RAISE(ABORT, 'invalid wakes status change')
|
|
490
|
+
WHERE NEW.status <> OLD.status
|
|
491
|
+
AND (OLD.status || '>' || NEW.status) NOT IN ('unavailable>accepted', 'unavailable>blocked', 'unavailable>rejected', 'blocked>accepted');
|
|
492
|
+
SELECT RAISE(ABORT, 'wakes target and work request are set once')
|
|
493
|
+
WHERE (OLD.target_agent_id IS NOT NULL AND NEW.target_agent_id IS NOT OLD.target_agent_id)
|
|
494
|
+
OR (OLD.target_name_snapshot IS NOT NULL AND NEW.target_name_snapshot IS NOT OLD.target_name_snapshot)
|
|
495
|
+
OR (OLD.work_request_id IS NOT NULL AND NEW.work_request_id IS NOT OLD.work_request_id)
|
|
496
|
+
OR (OLD.root_request_id IS NOT NULL AND NEW.root_request_id IS NOT OLD.root_request_id);
|
|
497
|
+
END;
|
|
498
|
+
`)}},{version:8,name:"conversation_events",up:e=>{e.exec(`
|
|
499
|
+
-- NOT-470: typed conversation projection of Wake and Work Request
|
|
500
|
+
-- lifecycle events (lib/conversation-projection). One row per
|
|
501
|
+
-- projected part of one engine event; the id is derived from the
|
|
502
|
+
-- engine event id and part, so replay and redelivery never add a
|
|
503
|
+
-- row. text is the human-facing line, data the machine-readable
|
|
504
|
+
-- meaning. sort_at never decreases within a request, so ordering
|
|
505
|
+
-- by (sort_at, request_created_at, request_id, request_sequence,
|
|
506
|
+
-- part) keeps each request's own order while requests interleave.
|
|
507
|
+
CREATE TABLE conversation_events (
|
|
508
|
+
id TEXT PRIMARY KEY,
|
|
509
|
+
conversation_id TEXT NOT NULL,
|
|
510
|
+
engine_event_id TEXT NOT NULL,
|
|
511
|
+
part INTEGER NOT NULL CHECK (part >= 0),
|
|
512
|
+
request_id TEXT NOT NULL,
|
|
513
|
+
request_sequence INTEGER NOT NULL,
|
|
514
|
+
attempt_id TEXT,
|
|
515
|
+
wake_id TEXT,
|
|
516
|
+
kind TEXT NOT NULL CHECK (kind IN (
|
|
517
|
+
'wake_accepted', 'wake_blocked', 'request_queued', 'request_blocked', 'request_running',
|
|
518
|
+
'request_waiting', 'request_completed', 'request_failed', 'request_cancelled',
|
|
519
|
+
'question', 'result', 'artifact'
|
|
520
|
+
)),
|
|
521
|
+
state TEXT CHECK (state IN (${eE})),
|
|
522
|
+
text TEXT NOT NULL,
|
|
523
|
+
data TEXT NOT NULL,
|
|
524
|
+
sort_at INTEGER NOT NULL,
|
|
525
|
+
request_created_at INTEGER NOT NULL,
|
|
526
|
+
created_at INTEGER NOT NULL,
|
|
527
|
+
UNIQUE (engine_event_id, part),
|
|
528
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
529
|
+
FOREIGN KEY (engine_event_id) REFERENCES engine_events(id),
|
|
530
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
531
|
+
);
|
|
532
|
+
CREATE INDEX idx_conversation_events_order
|
|
533
|
+
ON conversation_events(conversation_id, sort_at, request_created_at, request_id, request_sequence, part);
|
|
534
|
+
CREATE INDEX idx_conversation_events_request ON conversation_events(request_id);
|
|
535
|
+
|
|
536
|
+
-- Last engine event sequence the projector has read per request,
|
|
537
|
+
-- including events that project to nothing.
|
|
538
|
+
CREATE TABLE conversation_projection_cursors (
|
|
539
|
+
request_id TEXT PRIMARY KEY,
|
|
540
|
+
sequence INTEGER NOT NULL CHECK (sequence >= 0),
|
|
541
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
542
|
+
);
|
|
543
|
+
|
|
544
|
+
CREATE TRIGGER trg_conversation_events_immutable BEFORE UPDATE ON conversation_events
|
|
545
|
+
BEGIN
|
|
546
|
+
SELECT RAISE(ABORT, 'conversation_events are immutable');
|
|
547
|
+
END;
|
|
548
|
+
`)}},{version:9,name:"terminal_followups",up:e=>{e.exec(`
|
|
549
|
+
-- NOT-472: one row per canonical request that became terminal on
|
|
550
|
+
-- this schema, written in the same transaction as the terminal
|
|
551
|
+
-- transition. lib/coordinator-loop runs the follow-up (Wake
|
|
552
|
+
-- routing, coordinator continuation) and sets done_at; restart
|
|
553
|
+
-- recovery only replays rows still open. Requests that ended
|
|
554
|
+
-- before this migration get no row, so their replies are never
|
|
555
|
+
-- routed retroactively.
|
|
556
|
+
CREATE TABLE terminal_followups (
|
|
557
|
+
request_id TEXT PRIMARY KEY,
|
|
558
|
+
created_at INTEGER NOT NULL,
|
|
559
|
+
done_at INTEGER,
|
|
560
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
561
|
+
);
|
|
562
|
+
CREATE INDEX idx_terminal_followups_open ON terminal_followups(created_at) WHERE done_at IS NULL;
|
|
563
|
+
`)}},{version:10,name:"reviewed_git_finalization",up:e=>{e.exec(`
|
|
564
|
+
-- NOT-487: reviewed Git finalization through Agent Deck
|
|
565
|
+
-- (docs/design/2026-10-13-git-finalization-contract.md). Rows hold
|
|
566
|
+
-- only public Agent Deck identifiers, repository-relative paths,
|
|
567
|
+
-- digests, and modes: never file contents, host paths, or the
|
|
568
|
+
-- Agent Deck bearer.
|
|
569
|
+
--
|
|
570
|
+
-- Public baseline of a prepared edit Attempt, captured before model
|
|
571
|
+
-- work. Set once.
|
|
572
|
+
CREATE TABLE attempt_finalization_baselines (
|
|
573
|
+
attempt_id TEXT PRIMARY KEY,
|
|
574
|
+
request_id TEXT NOT NULL,
|
|
575
|
+
external_run_id TEXT NOT NULL,
|
|
576
|
+
baseline_ref TEXT NOT NULL,
|
|
577
|
+
baseline_digest TEXT NOT NULL,
|
|
578
|
+
created_at INTEGER NOT NULL,
|
|
579
|
+
FOREIGN KEY (attempt_id) REFERENCES work_attempts(id),
|
|
580
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
581
|
+
);
|
|
582
|
+
|
|
583
|
+
-- The ordered candidate manifest Agent Deck reported once the
|
|
584
|
+
-- prepared run was terminal: the immutable review evidence that a
|
|
585
|
+
-- finalization submits unchanged.
|
|
586
|
+
CREATE TABLE candidate_manifests (
|
|
587
|
+
id TEXT PRIMARY KEY,
|
|
588
|
+
attempt_id TEXT NOT NULL UNIQUE,
|
|
589
|
+
request_id TEXT NOT NULL,
|
|
590
|
+
conversation_id TEXT NOT NULL,
|
|
591
|
+
external_run_id TEXT NOT NULL,
|
|
592
|
+
baseline_ref TEXT NOT NULL,
|
|
593
|
+
baseline_digest TEXT NOT NULL,
|
|
594
|
+
base_commit TEXT NOT NULL,
|
|
595
|
+
manifest_digest TEXT NOT NULL,
|
|
596
|
+
files TEXT NOT NULL,
|
|
597
|
+
file_count INTEGER NOT NULL CHECK (file_count >= 0),
|
|
598
|
+
created_at INTEGER NOT NULL,
|
|
599
|
+
FOREIGN KEY (attempt_id) REFERENCES work_attempts(id),
|
|
600
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id),
|
|
601
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id)
|
|
602
|
+
);
|
|
603
|
+
|
|
604
|
+
-- One accepted finalization decision and its outcome. The request
|
|
605
|
+
-- body is exactly what was (or will be) submitted; the idempotency
|
|
606
|
+
-- key is derived from the explicit acceptance event, implementation
|
|
607
|
+
-- Attempt, review, and manifest. Replay and restart submit the same
|
|
608
|
+
-- request, while a later acceptance can retry a terminal non-commit.
|
|
609
|
+
CREATE TABLE finalizations (
|
|
610
|
+
id TEXT PRIMARY KEY,
|
|
611
|
+
idempotency_key TEXT NOT NULL UNIQUE CHECK (length(idempotency_key) > 0),
|
|
612
|
+
conversation_id TEXT NOT NULL,
|
|
613
|
+
decision_event_id TEXT NOT NULL,
|
|
614
|
+
decision_request_id TEXT NOT NULL,
|
|
615
|
+
coordinator_agent_id TEXT NOT NULL,
|
|
616
|
+
implementation_request_id TEXT NOT NULL,
|
|
617
|
+
implementation_attempt_id TEXT NOT NULL,
|
|
618
|
+
review_request_id TEXT NOT NULL,
|
|
619
|
+
review_attempt_id TEXT NOT NULL,
|
|
620
|
+
manifest_id TEXT NOT NULL,
|
|
621
|
+
external_run_id TEXT NOT NULL,
|
|
622
|
+
request_body TEXT NOT NULL,
|
|
623
|
+
request_hash TEXT NOT NULL,
|
|
624
|
+
state TEXT NOT NULL CHECK (state IN ('preparing', 'committed', 'blocked', 'failed', 'canceled')),
|
|
625
|
+
submitted_at INTEGER,
|
|
626
|
+
reason_code TEXT,
|
|
627
|
+
reason TEXT,
|
|
628
|
+
commit_id TEXT,
|
|
629
|
+
tree_id TEXT,
|
|
630
|
+
parent_commit TEXT,
|
|
631
|
+
result_manifest_digest TEXT,
|
|
632
|
+
file_count INTEGER,
|
|
633
|
+
created_at INTEGER NOT NULL,
|
|
634
|
+
updated_at INTEGER NOT NULL,
|
|
635
|
+
finished_at INTEGER,
|
|
636
|
+
CHECK ((state = 'preparing') = (finished_at IS NULL)),
|
|
637
|
+
CHECK (state <> 'committed' OR commit_id IS NOT NULL),
|
|
638
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
639
|
+
FOREIGN KEY (implementation_request_id) REFERENCES work_requests(id),
|
|
640
|
+
FOREIGN KEY (implementation_attempt_id) REFERENCES work_attempts(id),
|
|
641
|
+
FOREIGN KEY (review_request_id) REFERENCES work_requests(id),
|
|
642
|
+
FOREIGN KEY (manifest_id) REFERENCES candidate_manifests(id)
|
|
643
|
+
);
|
|
644
|
+
CREATE INDEX idx_finalizations_open ON finalizations(created_at) WHERE finished_at IS NULL;
|
|
645
|
+
CREATE INDEX idx_finalizations_attempt ON finalizations(implementation_attempt_id);
|
|
646
|
+
|
|
647
|
+
CREATE TRIGGER trg_attempt_finalization_baselines_fk BEFORE INSERT ON attempt_finalization_baselines
|
|
648
|
+
BEGIN
|
|
649
|
+
SELECT RAISE(ABORT, 'attempt finalization baseline does not match its Attempt')
|
|
650
|
+
WHERE NOT EXISTS (
|
|
651
|
+
SELECT 1 FROM work_attempts
|
|
652
|
+
WHERE id = NEW.attempt_id AND request_id = NEW.request_id AND external_run_id = NEW.external_run_id
|
|
653
|
+
);
|
|
654
|
+
END;
|
|
655
|
+
CREATE TRIGGER trg_attempt_finalization_baselines_immutable BEFORE UPDATE ON attempt_finalization_baselines
|
|
656
|
+
BEGIN
|
|
657
|
+
SELECT RAISE(ABORT, 'attempt_finalization_baselines are immutable');
|
|
658
|
+
END;
|
|
659
|
+
CREATE TRIGGER trg_candidate_manifests_fk BEFORE INSERT ON candidate_manifests
|
|
660
|
+
BEGIN
|
|
661
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: candidate_manifests.attempt_id')
|
|
662
|
+
WHERE NOT EXISTS (
|
|
663
|
+
SELECT 1 FROM work_attempts a
|
|
664
|
+
JOIN work_requests r ON r.id = a.request_id
|
|
665
|
+
JOIN attempt_finalization_baselines b ON b.attempt_id = a.id
|
|
666
|
+
WHERE a.id = NEW.attempt_id AND a.request_id = NEW.request_id
|
|
667
|
+
AND a.external_run_id = NEW.external_run_id
|
|
668
|
+
AND r.source_conversation_id = NEW.conversation_id
|
|
669
|
+
AND b.external_run_id = NEW.external_run_id
|
|
670
|
+
AND b.baseline_ref = NEW.baseline_ref AND b.baseline_digest = NEW.baseline_digest
|
|
671
|
+
);
|
|
672
|
+
END;
|
|
673
|
+
CREATE TRIGGER trg_candidate_manifests_immutable BEFORE UPDATE ON candidate_manifests
|
|
674
|
+
BEGIN
|
|
675
|
+
SELECT RAISE(ABORT, 'candidate_manifests are immutable');
|
|
676
|
+
END;
|
|
677
|
+
CREATE TRIGGER trg_finalizations_fk BEFORE INSERT ON finalizations
|
|
678
|
+
BEGIN
|
|
679
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: finalizations.manifest_id')
|
|
680
|
+
WHERE NOT EXISTS (
|
|
681
|
+
SELECT 1 FROM candidate_manifests m
|
|
682
|
+
JOIN work_attempts ia ON ia.id = NEW.implementation_attempt_id
|
|
683
|
+
JOIN work_attempts ra ON ra.id = NEW.review_attempt_id
|
|
684
|
+
JOIN work_requests ir ON ir.id = NEW.implementation_request_id
|
|
685
|
+
JOIN work_requests rr ON rr.id = NEW.review_request_id
|
|
686
|
+
JOIN work_requests dr ON dr.id = NEW.decision_request_id
|
|
687
|
+
WHERE m.id = NEW.manifest_id AND m.attempt_id = ia.id AND m.request_id = ir.id
|
|
688
|
+
AND m.external_run_id = NEW.external_run_id
|
|
689
|
+
AND ia.request_id = ir.id AND ra.request_id = rr.id
|
|
690
|
+
AND ir.source_conversation_id = NEW.conversation_id
|
|
691
|
+
AND rr.source_conversation_id = NEW.conversation_id
|
|
692
|
+
AND dr.source_conversation_id = NEW.conversation_id
|
|
693
|
+
AND dr.target_agent_id = NEW.coordinator_agent_id
|
|
694
|
+
);
|
|
695
|
+
END;
|
|
696
|
+
CREATE TRIGGER trg_finalizations_immutable BEFORE UPDATE OF
|
|
697
|
+
id, idempotency_key, conversation_id, decision_event_id, decision_request_id, coordinator_agent_id,
|
|
698
|
+
implementation_request_id, implementation_attempt_id, review_request_id, review_attempt_id,
|
|
699
|
+
manifest_id, external_run_id, request_body, request_hash, created_at
|
|
700
|
+
ON finalizations
|
|
701
|
+
BEGIN
|
|
702
|
+
SELECT RAISE(ABORT, 'finalizations decision and request are immutable');
|
|
703
|
+
END;
|
|
704
|
+
CREATE TRIGGER trg_finalizations_terminal BEFORE UPDATE ON finalizations
|
|
705
|
+
WHEN OLD.finished_at IS NOT NULL
|
|
706
|
+
BEGIN
|
|
707
|
+
SELECT RAISE(ABORT, 'finished finalizations are immutable');
|
|
708
|
+
END;
|
|
709
|
+
CREATE TRIGGER trg_finalizations_submitted BEFORE UPDATE OF submitted_at ON finalizations
|
|
710
|
+
WHEN OLD.submitted_at IS NOT NULL AND NEW.submitted_at IS NOT OLD.submitted_at
|
|
711
|
+
BEGIN
|
|
712
|
+
SELECT RAISE(ABORT, 'finalizations submitted_at is set once');
|
|
713
|
+
END;
|
|
714
|
+
|
|
715
|
+
-- Conversation projection gains the finalization lifecycle kinds.
|
|
716
|
+
-- SQLite cannot widen a CHECK in place, so the table is rebuilt
|
|
717
|
+
-- with every row kept.
|
|
718
|
+
CREATE TABLE conversation_events_v10 (
|
|
719
|
+
id TEXT PRIMARY KEY,
|
|
720
|
+
conversation_id TEXT NOT NULL,
|
|
721
|
+
engine_event_id TEXT NOT NULL,
|
|
722
|
+
part INTEGER NOT NULL CHECK (part >= 0),
|
|
723
|
+
request_id TEXT NOT NULL,
|
|
724
|
+
request_sequence INTEGER NOT NULL,
|
|
725
|
+
attempt_id TEXT,
|
|
726
|
+
wake_id TEXT,
|
|
727
|
+
kind TEXT NOT NULL CHECK (kind IN (
|
|
728
|
+
'wake_accepted', 'wake_blocked', 'request_queued', 'request_blocked', 'request_running',
|
|
729
|
+
'request_waiting', 'request_completed', 'request_failed', 'request_cancelled',
|
|
730
|
+
'question', 'result', 'artifact',
|
|
731
|
+
'finalization_preparing', 'finalization_committed', 'finalization_blocked',
|
|
732
|
+
'finalization_failed', 'finalization_canceled', 'finalization_rejected'
|
|
733
|
+
)),
|
|
734
|
+
state TEXT CHECK (state IN (${eE})),
|
|
735
|
+
text TEXT NOT NULL,
|
|
736
|
+
data TEXT NOT NULL,
|
|
737
|
+
sort_at INTEGER NOT NULL,
|
|
738
|
+
request_created_at INTEGER NOT NULL,
|
|
739
|
+
created_at INTEGER NOT NULL,
|
|
740
|
+
UNIQUE (engine_event_id, part),
|
|
741
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
742
|
+
FOREIGN KEY (engine_event_id) REFERENCES engine_events(id),
|
|
743
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
744
|
+
);
|
|
745
|
+
INSERT INTO conversation_events_v10 SELECT
|
|
746
|
+
id, conversation_id, engine_event_id, part, request_id, request_sequence, attempt_id, wake_id,
|
|
747
|
+
kind, state, text, data, sort_at, request_created_at, created_at
|
|
748
|
+
FROM conversation_events;
|
|
749
|
+
DROP TABLE conversation_events;
|
|
750
|
+
ALTER TABLE conversation_events_v10 RENAME TO conversation_events;
|
|
751
|
+
CREATE INDEX idx_conversation_events_order
|
|
752
|
+
ON conversation_events(conversation_id, sort_at, request_created_at, request_id, request_sequence, part);
|
|
753
|
+
CREATE INDEX idx_conversation_events_request ON conversation_events(request_id);
|
|
754
|
+
CREATE TRIGGER trg_conversation_events_immutable BEFORE UPDATE ON conversation_events
|
|
755
|
+
BEGIN
|
|
756
|
+
SELECT RAISE(ABORT, 'conversation_events are immutable');
|
|
757
|
+
END;
|
|
758
|
+
`)}},{version:11,name:"leased_dispatch",up:e=>{e.exec(`
|
|
759
|
+
-- NOT-469: leased dispatcher (lib/dispatcher). One row per request a
|
|
760
|
+
-- worker owns. The token is a fencing value: heartbeat, release, and
|
|
761
|
+
-- every fenced commit match it, so a worker whose lease was taken
|
|
762
|
+
-- over can no longer write. An expired row is not free: its run may
|
|
763
|
+
-- still be live, so it counts toward concurrency until a worker
|
|
764
|
+
-- takes it over and reconciles it.
|
|
765
|
+
CREATE TABLE dispatch_leases (
|
|
766
|
+
request_id TEXT PRIMARY KEY,
|
|
767
|
+
target_agent_id TEXT NOT NULL,
|
|
768
|
+
owner TEXT NOT NULL CHECK (length(owner) > 0),
|
|
769
|
+
token TEXT NOT NULL UNIQUE CHECK (length(token) > 0),
|
|
770
|
+
acquired_at INTEGER NOT NULL,
|
|
771
|
+
heartbeat_at INTEGER NOT NULL,
|
|
772
|
+
expires_at INTEGER NOT NULL,
|
|
773
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
774
|
+
);
|
|
775
|
+
CREATE INDEX idx_dispatch_leases_target ON dispatch_leases(target_agent_id);
|
|
776
|
+
CREATE INDEX idx_dispatch_leases_expiry ON dispatch_leases(expires_at);
|
|
777
|
+
|
|
778
|
+
-- Launch intent, written with the Attempt before any adapter call:
|
|
779
|
+
-- the exact start body (or null for a transport without external
|
|
780
|
+
-- runs), its idempotency key, and a non-secret fingerprint of the
|
|
781
|
+
-- launching grant. Reconciliation re-POSTs only this body, under
|
|
782
|
+
-- this key, with this grant (NOT-468 decision table A).
|
|
783
|
+
CREATE TABLE attempt_launch_intents (
|
|
784
|
+
attempt_id TEXT PRIMARY KEY,
|
|
785
|
+
request_id TEXT NOT NULL,
|
|
786
|
+
transport TEXT NOT NULL CHECK (length(transport) > 0),
|
|
787
|
+
idempotency_key TEXT,
|
|
788
|
+
body TEXT,
|
|
789
|
+
body_hash TEXT,
|
|
790
|
+
grant_fingerprint TEXT,
|
|
791
|
+
owner TEXT NOT NULL,
|
|
792
|
+
created_at INTEGER NOT NULL,
|
|
793
|
+
CHECK ((body IS NULL) = (body_hash IS NULL)),
|
|
794
|
+
CHECK (body IS NULL OR idempotency_key IS NOT NULL),
|
|
795
|
+
FOREIGN KEY (attempt_id) REFERENCES work_attempts(id),
|
|
796
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
797
|
+
);
|
|
798
|
+
CREATE TRIGGER trg_attempt_launch_intents_fk BEFORE INSERT ON attempt_launch_intents
|
|
799
|
+
BEGIN
|
|
800
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: attempt_launch_intents.attempt_id')
|
|
801
|
+
WHERE NOT EXISTS (SELECT 1 FROM work_attempts WHERE id = NEW.attempt_id AND request_id = NEW.request_id);
|
|
802
|
+
END;
|
|
803
|
+
CREATE TRIGGER trg_attempt_launch_intents_immutable BEFORE UPDATE ON attempt_launch_intents
|
|
804
|
+
BEGIN
|
|
805
|
+
SELECT RAISE(ABORT, 'attempt_launch_intents are immutable');
|
|
806
|
+
END;
|
|
807
|
+
|
|
808
|
+
-- Operator-attention flag, separate from the Attempt lifecycle. While
|
|
809
|
+
-- one is open for a request the dispatcher makes no automatic
|
|
810
|
+
-- launch, re-POST, retry, or resume for it. Only an operator clears
|
|
811
|
+
-- it (cleared_at).
|
|
812
|
+
CREATE TABLE dispatch_attention (
|
|
813
|
+
id TEXT PRIMARY KEY,
|
|
814
|
+
request_id TEXT NOT NULL,
|
|
815
|
+
attempt_id TEXT,
|
|
816
|
+
reason TEXT NOT NULL CHECK (length(reason) > 0),
|
|
817
|
+
detail TEXT,
|
|
818
|
+
created_at INTEGER NOT NULL,
|
|
819
|
+
cleared_at INTEGER,
|
|
820
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id),
|
|
821
|
+
FOREIGN KEY (attempt_id) REFERENCES work_attempts(id)
|
|
822
|
+
);
|
|
823
|
+
CREATE UNIQUE INDEX idx_dispatch_attention_open ON dispatch_attention(request_id) WHERE cleared_at IS NULL;
|
|
824
|
+
`)}},{version:12,name:"request_control",up:e=>{e.exec(`
|
|
825
|
+
-- NOT-473: cancellation, deadlines, and bounded retries
|
|
826
|
+
-- (lib/work-request-control, lib/request-policy). The deadline and
|
|
827
|
+
-- retry policy are fixed at intake; null on older rows means no
|
|
828
|
+
-- deadline and one Attempt. attempt_count counts claimed Attempts
|
|
829
|
+
-- and never decreases; a queued retry is not claimable before
|
|
830
|
+
-- next_eligible_at. The cancellation intent is recorded once.
|
|
831
|
+
ALTER TABLE work_requests ADD COLUMN deadline_at INTEGER;
|
|
832
|
+
ALTER TABLE work_requests ADD COLUMN retry_policy TEXT;
|
|
833
|
+
ALTER TABLE work_requests ADD COLUMN attempt_count INTEGER NOT NULL DEFAULT 0 CHECK (attempt_count >= 0);
|
|
834
|
+
ALTER TABLE work_requests ADD COLUMN next_eligible_at INTEGER;
|
|
835
|
+
ALTER TABLE work_requests ADD COLUMN cancel_requested_at INTEGER;
|
|
836
|
+
ALTER TABLE work_requests ADD COLUMN cancel_requested_by TEXT;
|
|
837
|
+
ALTER TABLE work_requests ADD COLUMN cancel_reason TEXT;
|
|
838
|
+
CREATE INDEX idx_work_requests_deadline ON work_requests(deadline_at) WHERE deadline_at IS NOT NULL;
|
|
839
|
+
|
|
840
|
+
CREATE TRIGGER trg_work_requests_control_immutable BEFORE UPDATE OF deadline_at, retry_policy ON work_requests
|
|
841
|
+
WHEN NEW.deadline_at IS NOT OLD.deadline_at OR NEW.retry_policy IS NOT OLD.retry_policy
|
|
842
|
+
BEGIN
|
|
843
|
+
SELECT RAISE(ABORT, 'work_requests deadline and retry policy are immutable');
|
|
844
|
+
END;
|
|
845
|
+
CREATE TRIGGER trg_work_requests_attempt_count BEFORE UPDATE OF attempt_count ON work_requests
|
|
846
|
+
WHEN NEW.attempt_count < OLD.attempt_count
|
|
847
|
+
BEGIN
|
|
848
|
+
SELECT RAISE(ABORT, 'work_requests attempt_count never decreases');
|
|
849
|
+
END;
|
|
850
|
+
CREATE TRIGGER trg_work_requests_cancel_once BEFORE UPDATE OF cancel_requested_at, cancel_requested_by, cancel_reason ON work_requests
|
|
851
|
+
WHEN OLD.cancel_requested_at IS NOT NULL AND (
|
|
852
|
+
NEW.cancel_requested_at IS NOT OLD.cancel_requested_at
|
|
853
|
+
OR NEW.cancel_requested_by IS NOT OLD.cancel_requested_by
|
|
854
|
+
OR NEW.cancel_reason IS NOT OLD.cancel_reason
|
|
855
|
+
)
|
|
856
|
+
BEGIN
|
|
857
|
+
SELECT RAISE(ABORT, 'work_requests cancellation intent is recorded once');
|
|
858
|
+
END;
|
|
859
|
+
|
|
860
|
+
-- Conversation projection gains the cancellation, timeout, and
|
|
861
|
+
-- retry kinds (rebuilt with every row kept, as in version 10).
|
|
862
|
+
CREATE TABLE conversation_events_v12 (
|
|
863
|
+
id TEXT PRIMARY KEY,
|
|
864
|
+
conversation_id TEXT NOT NULL,
|
|
865
|
+
engine_event_id TEXT NOT NULL,
|
|
866
|
+
part INTEGER NOT NULL CHECK (part >= 0),
|
|
867
|
+
request_id TEXT NOT NULL,
|
|
868
|
+
request_sequence INTEGER NOT NULL,
|
|
869
|
+
attempt_id TEXT,
|
|
870
|
+
wake_id TEXT,
|
|
871
|
+
kind TEXT NOT NULL CHECK (kind IN (
|
|
872
|
+
'wake_accepted', 'wake_blocked', 'request_queued', 'request_blocked', 'request_running',
|
|
873
|
+
'request_waiting', 'request_completed', 'request_failed', 'request_cancelled',
|
|
874
|
+
'question', 'result', 'artifact',
|
|
875
|
+
'finalization_preparing', 'finalization_committed', 'finalization_blocked',
|
|
876
|
+
'finalization_failed', 'finalization_canceled', 'finalization_rejected',
|
|
877
|
+
'request_cancel_requested', 'request_timed_out', 'request_retry_scheduled', 'request_retries_exhausted'
|
|
878
|
+
)),
|
|
879
|
+
state TEXT CHECK (state IN (${eE})),
|
|
880
|
+
text TEXT NOT NULL,
|
|
881
|
+
data TEXT NOT NULL,
|
|
882
|
+
sort_at INTEGER NOT NULL,
|
|
883
|
+
request_created_at INTEGER NOT NULL,
|
|
884
|
+
created_at INTEGER NOT NULL,
|
|
885
|
+
UNIQUE (engine_event_id, part),
|
|
886
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
887
|
+
FOREIGN KEY (engine_event_id) REFERENCES engine_events(id),
|
|
888
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
889
|
+
);
|
|
890
|
+
INSERT INTO conversation_events_v12 SELECT
|
|
891
|
+
id, conversation_id, engine_event_id, part, request_id, request_sequence, attempt_id, wake_id,
|
|
892
|
+
kind, state, text, data, sort_at, request_created_at, created_at
|
|
893
|
+
FROM conversation_events;
|
|
894
|
+
DROP TABLE conversation_events;
|
|
895
|
+
ALTER TABLE conversation_events_v12 RENAME TO conversation_events;
|
|
896
|
+
CREATE INDEX idx_conversation_events_order
|
|
897
|
+
ON conversation_events(conversation_id, sort_at, request_created_at, request_id, request_sequence, part);
|
|
898
|
+
CREATE INDEX idx_conversation_events_request ON conversation_events(request_id);
|
|
899
|
+
CREATE TRIGGER trg_conversation_events_immutable BEFORE UPDATE ON conversation_events
|
|
900
|
+
BEGIN
|
|
901
|
+
SELECT RAISE(ABORT, 'conversation_events are immutable');
|
|
902
|
+
END;
|
|
903
|
+
`)}},{version:13,name:"wake_safety",up:e=>{e.exec(`
|
|
904
|
+
-- NOT-475: Wake safety (docs/design/2026-10-14-wake-safety-contract.md,
|
|
905
|
+
-- lib/wake-safety). Lineage columns: wake_depth counts Agent-to-Agent
|
|
906
|
+
-- hops from the root (a continuation runs at the depth of the Agent it
|
|
907
|
+
-- continues) and the root principal is whoever started the lineage.
|
|
908
|
+
-- Both are fixed at intake.
|
|
909
|
+
ALTER TABLE work_requests ADD COLUMN wake_depth INTEGER NOT NULL DEFAULT 0 CHECK (wake_depth >= 0);
|
|
910
|
+
ALTER TABLE work_requests ADD COLUMN root_principal_kind TEXT;
|
|
911
|
+
ALTER TABLE work_requests ADD COLUMN root_principal_id TEXT;
|
|
912
|
+
|
|
913
|
+
-- Owner-approved edit grants for one (caller Agent, target Agent)
|
|
914
|
+
-- pair. Never seeded; revoked once, never rewritten or reused.
|
|
915
|
+
CREATE TABLE wake_grants (
|
|
916
|
+
id TEXT PRIMARY KEY,
|
|
917
|
+
caller_agent_id TEXT NOT NULL,
|
|
918
|
+
target_agent_id TEXT NOT NULL,
|
|
919
|
+
authority TEXT NOT NULL CHECK (authority = 'edit'),
|
|
920
|
+
granted_by_kind TEXT NOT NULL,
|
|
921
|
+
granted_by_id TEXT NOT NULL,
|
|
922
|
+
source_wake_id TEXT,
|
|
923
|
+
created_at INTEGER NOT NULL,
|
|
924
|
+
revoked_at INTEGER,
|
|
925
|
+
revoked_by_kind TEXT,
|
|
926
|
+
revoked_by_id TEXT,
|
|
927
|
+
CHECK ((revoked_at IS NULL) = (revoked_by_kind IS NULL) AND (revoked_at IS NULL) = (revoked_by_id IS NULL))
|
|
928
|
+
);
|
|
929
|
+
CREATE UNIQUE INDEX idx_wake_grants_active ON wake_grants(caller_agent_id, target_agent_id, authority) WHERE revoked_at IS NULL;
|
|
930
|
+
CREATE TRIGGER trg_wake_grants_immutable BEFORE UPDATE ON wake_grants
|
|
931
|
+
BEGIN
|
|
932
|
+
SELECT RAISE(ABORT, 'wake_grants are immutable except for one revocation')
|
|
933
|
+
WHERE OLD.revoked_at IS NOT NULL
|
|
934
|
+
OR NEW.id IS NOT OLD.id OR NEW.caller_agent_id IS NOT OLD.caller_agent_id
|
|
935
|
+
OR NEW.target_agent_id IS NOT OLD.target_agent_id OR NEW.authority IS NOT OLD.authority
|
|
936
|
+
OR NEW.granted_by_kind IS NOT OLD.granted_by_kind OR NEW.granted_by_id IS NOT OLD.granted_by_id
|
|
937
|
+
OR NEW.source_wake_id IS NOT OLD.source_wake_id OR NEW.created_at IS NOT OLD.created_at;
|
|
938
|
+
END;
|
|
939
|
+
|
|
940
|
+
-- One append-only row per safety evaluation of a Work Request: the
|
|
941
|
+
-- categorized caller principal, target, decision, matched grant rule
|
|
942
|
+
-- and grant, and the policy snapshot used. A request is runnable
|
|
943
|
+
-- only while its latest decision is allowed (lib/dispatcher). A
|
|
944
|
+
-- later policy change (a revoked grant, new limits) adds rows for
|
|
945
|
+
-- later evaluations and never rewrites these.
|
|
946
|
+
CREATE TABLE wake_safety_decisions (
|
|
947
|
+
id TEXT PRIMARY KEY,
|
|
948
|
+
request_id TEXT NOT NULL,
|
|
949
|
+
sequence INTEGER NOT NULL CHECK (sequence > 0),
|
|
950
|
+
wake_id TEXT,
|
|
951
|
+
principal_type TEXT NOT NULL CHECK (principal_type IN ('human_owner', 'api_principal', 'agent_principal', 'engine')),
|
|
952
|
+
principal_kind TEXT NOT NULL,
|
|
953
|
+
principal_id TEXT NOT NULL,
|
|
954
|
+
target_agent_id TEXT NOT NULL,
|
|
955
|
+
execution_kind TEXT NOT NULL,
|
|
956
|
+
decision TEXT NOT NULL CHECK (decision IN ('allowed', 'blocked', 'denied')),
|
|
957
|
+
reason_code TEXT,
|
|
958
|
+
grant_rule TEXT,
|
|
959
|
+
grant_id TEXT,
|
|
960
|
+
policy_snapshot TEXT NOT NULL,
|
|
961
|
+
created_at INTEGER NOT NULL,
|
|
962
|
+
UNIQUE (request_id, sequence),
|
|
963
|
+
CHECK (decision <> 'allowed' OR grant_rule IS NOT NULL),
|
|
964
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
965
|
+
);
|
|
966
|
+
CREATE TRIGGER trg_wake_safety_decisions_fk BEFORE INSERT ON wake_safety_decisions
|
|
967
|
+
BEGIN
|
|
968
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: wake_safety_decisions.request_id')
|
|
969
|
+
WHERE NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.request_id);
|
|
970
|
+
END;
|
|
971
|
+
CREATE TRIGGER trg_wake_safety_decisions_immutable BEFORE UPDATE ON wake_safety_decisions
|
|
972
|
+
BEGIN
|
|
973
|
+
SELECT RAISE(ABORT, 'wake_safety_decisions are append-only');
|
|
974
|
+
END;
|
|
975
|
+
|
|
976
|
+
-- Depth and root-budget refusals name the limit and what was seen.
|
|
977
|
+
ALTER TABLE wakes ADD COLUMN limit_value INTEGER;
|
|
978
|
+
ALTER TABLE wakes ADD COLUMN observed_value INTEGER;
|
|
979
|
+
|
|
980
|
+
-- Rejected Wakes project from the Wake row (no Work Request, no
|
|
981
|
+
-- engine event), and a stopped lineage projects as its own kind.
|
|
982
|
+
CREATE TABLE conversation_events_v13 (
|
|
983
|
+
id TEXT PRIMARY KEY,
|
|
984
|
+
conversation_id TEXT NOT NULL,
|
|
985
|
+
engine_event_id TEXT,
|
|
986
|
+
part INTEGER NOT NULL CHECK (part >= 0),
|
|
987
|
+
request_id TEXT,
|
|
988
|
+
request_sequence INTEGER NOT NULL,
|
|
989
|
+
attempt_id TEXT,
|
|
990
|
+
wake_id TEXT,
|
|
991
|
+
kind TEXT NOT NULL CHECK (kind IN (
|
|
992
|
+
'wake_accepted', 'wake_blocked', 'request_queued', 'request_blocked', 'request_running',
|
|
993
|
+
'request_waiting', 'request_completed', 'request_failed', 'request_cancelled',
|
|
994
|
+
'question', 'result', 'artifact',
|
|
995
|
+
'finalization_preparing', 'finalization_committed', 'finalization_blocked',
|
|
996
|
+
'finalization_failed', 'finalization_canceled', 'finalization_rejected',
|
|
997
|
+
'request_cancel_requested', 'request_timed_out', 'request_retry_scheduled', 'request_retries_exhausted',
|
|
998
|
+
'wake_rejected', 'lineage_stopped'
|
|
999
|
+
)),
|
|
1000
|
+
state TEXT CHECK (state IN (${eE})),
|
|
1001
|
+
text TEXT NOT NULL,
|
|
1002
|
+
data TEXT NOT NULL,
|
|
1003
|
+
sort_at INTEGER NOT NULL,
|
|
1004
|
+
request_created_at INTEGER NOT NULL,
|
|
1005
|
+
created_at INTEGER NOT NULL,
|
|
1006
|
+
UNIQUE (engine_event_id, part),
|
|
1007
|
+
CHECK ((engine_event_id IS NULL) = (request_id IS NULL)),
|
|
1008
|
+
CHECK (request_id IS NOT NULL OR wake_id IS NOT NULL),
|
|
1009
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
1010
|
+
FOREIGN KEY (engine_event_id) REFERENCES engine_events(id),
|
|
1011
|
+
FOREIGN KEY (request_id) REFERENCES work_requests(id)
|
|
1012
|
+
);
|
|
1013
|
+
INSERT INTO conversation_events_v13 SELECT
|
|
1014
|
+
id, conversation_id, engine_event_id, part, request_id, request_sequence, attempt_id, wake_id,
|
|
1015
|
+
kind, state, text, data, sort_at, request_created_at, created_at
|
|
1016
|
+
FROM conversation_events;
|
|
1017
|
+
DROP TABLE conversation_events;
|
|
1018
|
+
ALTER TABLE conversation_events_v13 RENAME TO conversation_events;
|
|
1019
|
+
CREATE INDEX idx_conversation_events_order
|
|
1020
|
+
ON conversation_events(conversation_id, sort_at, request_created_at, request_id, request_sequence, part);
|
|
1021
|
+
CREATE INDEX idx_conversation_events_request ON conversation_events(request_id);
|
|
1022
|
+
CREATE INDEX idx_conversation_events_wake ON conversation_events(wake_id);
|
|
1023
|
+
CREATE TRIGGER trg_conversation_events_immutable BEFORE UPDATE ON conversation_events
|
|
1024
|
+
BEGIN
|
|
1025
|
+
SELECT RAISE(ABORT, 'conversation_events are immutable');
|
|
1026
|
+
END;
|
|
1027
|
+
`),function(e){let t=e.prepare(`
|
|
1028
|
+
SELECT id, parent_request_id, root_request_id, wake_event_id, requester_kind, requester_id, policy_snapshot, state,
|
|
1029
|
+
target_agent_id, execution_kind, legacy_agent_request_id, created_at
|
|
1030
|
+
FROM work_requests ORDER BY created_at ASC, rowid ASC
|
|
1031
|
+
`).all(),n=new Map(t.map(e=>[e.id,e])),r=e=>{try{let t=JSON.parse(e.policy_snapshot);return t&&"object"==typeof t&&!Array.isArray(t)?t:{}}catch{return{}}},i=new Map,a=e=>{let t=i.get(e.id);if(void 0!==t)return t;let r=[],s=new Set,a=e,o=!1;for(;a&&!s.has(a.id)&&a.root_request_id===e.root_request_id;){let t=i.get(a.id);if(void 0!==t){o=t;break}if(s.add(a.id),r.push(a),null===a.parent_request_id){o=a.id===e.root_request_id;break}a=n.get(a.parent_request_id)}for(let e of r)i.set(e.id,o);return o},o=new Map,d=e=>{let t=o.get(e.id);if(void 0!==t)return t;let i=0,s=e.parent_request_id?n.get(e.parent_request_id):void 0;if(s){let t=d(s),n=r(e);i=e.wake_event_id?t+1:"coordinator_continuation"===n.source&&"result"===n.continues?Math.max(t-1,0):t}return o.set(e.id,i),i},u=e.prepare("UPDATE work_requests SET wake_depth = ?, root_principal_kind = ?, root_principal_id = ? WHERE id = ?"),l=e.prepare(`
|
|
1032
|
+
INSERT INTO wake_safety_decisions (
|
|
1033
|
+
id, request_id, sequence, wake_id, principal_type, principal_kind, principal_id, target_agent_id, execution_kind,
|
|
1034
|
+
decision, reason_code, grant_rule, grant_id, policy_snapshot, created_at
|
|
1035
|
+
) VALUES (?, ?, 1, ?, ?, ?, ?, ?, ?, 'allowed', NULL, 'pre_safety_migration', NULL, ?, ?)
|
|
1036
|
+
`);for(let i of(e.exec("DROP TRIGGER trg_work_requests_terminal"),t)){let e=n.get(i.root_request_id),t=!!e&&a(i),o=t?d(i):0,_=t&&e?{kind:e.requester_kind,id:e.requester_id}:{kind:"unknown",id:"unknown"};if(u.run(o,_.kind,_.id,i.id),null===i.legacy_agent_request_id&&["queued","running","waiting"].includes(i.state)){let e=r(i),t="wake"===e.source?"agent_principal":"coordinator_continuation"===e.source?"engine":"api"===e.surface?"api_principal":"human_owner";l.run((0,s.randomUUID)(),i.id,i.wake_event_id,t,i.requester_kind,i.requester_id,i.target_agent_id,i.execution_kind,JSON.stringify({safety_version:1,migrated:!0,root_principal:_,wake_depth:o,grant_rule:"pre_safety_migration"}),i.created_at)}}e.exec(`
|
|
1037
|
+
CREATE TRIGGER trg_work_requests_terminal BEFORE UPDATE ON work_requests
|
|
1038
|
+
WHEN OLD.state IN (${ec})
|
|
1039
|
+
BEGIN
|
|
1040
|
+
SELECT RAISE(ABORT, 'terminal work_requests are immutable');
|
|
1041
|
+
END;
|
|
1042
|
+
`)}(e),e.exec(`
|
|
1043
|
+
CREATE TRIGGER trg_work_requests_safety_immutable BEFORE UPDATE OF wake_depth, root_principal_kind, root_principal_id ON work_requests
|
|
1044
|
+
WHEN NEW.wake_depth IS NOT OLD.wake_depth
|
|
1045
|
+
OR NEW.root_principal_kind IS NOT OLD.root_principal_kind
|
|
1046
|
+
OR NEW.root_principal_id IS NOT OLD.root_principal_id
|
|
1047
|
+
BEGIN
|
|
1048
|
+
SELECT RAISE(ABORT, 'work_requests wake depth and root principal are immutable');
|
|
1049
|
+
END;
|
|
1050
|
+
`)}},{version:14,name:"retire_legacy_agent_requests",up:e=>{!function(e){let t=t=>!!e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(t);if(!t("agent_requests"))return;let n=t("agent_request_events"),r=e.prepare(`
|
|
1051
|
+
SELECT r.*, m.content AS content FROM agent_requests r
|
|
1052
|
+
JOIN conversations c ON c.id = r.conversation_id
|
|
1053
|
+
JOIN bots b ON b.id = r.target_bot_id
|
|
1054
|
+
JOIN messages m ON m.id = r.accepted_message_id AND m.conversation_id = r.conversation_id
|
|
1055
|
+
WHERE r.state IN ('completed', 'failed', 'accepted', 'dispatched')
|
|
1056
|
+
AND r.principal_kind IN ('person', 'bot', 'service')
|
|
1057
|
+
AND NOT EXISTS (SELECT 1 FROM work_requests w WHERE w.legacy_agent_request_id = r.id)
|
|
1058
|
+
ORDER BY r.created_at ASC, r.rowid ASC
|
|
1059
|
+
`).all(),i=e.prepare("SELECT 1 FROM work_requests WHERE requester_kind = ? AND requester_id = ? AND idempotency_key = ?"),a=n?e.prepare("SELECT type, data, created_at FROM agent_request_events WHERE request_id = ? ORDER BY created_at ASC, rowid ASC"):null,o=e.prepare(`
|
|
1060
|
+
INSERT INTO work_requests (
|
|
1061
|
+
id, source_conversation_id, source_event_id, requester_kind, requester_id, target_agent_id,
|
|
1062
|
+
intent, execution_kind, tool_profile, parent_request_id, root_request_id, wake_event_id, depth,
|
|
1063
|
+
idempotency_key, request_hash, policy_snapshot, state, state_reason, result, error_code, error_message,
|
|
1064
|
+
version, legacy_agent_request_id, created_at, updated_at, terminal_at, root_principal_kind, root_principal_id
|
|
1065
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, 'conversation', 'readonly', NULL, ?, NULL, 0, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?)
|
|
1066
|
+
`),d=e.prepare("INSERT INTO engine_events (id, request_id, sequence, attempt_id, type, data, created_at) VALUES (?, ?, ?, NULL, ?, ?, ?)"),u=Date.now();for(let e of r){if(i.get(e.principal_kind,e.principal_id,e.idempotency_key))continue;let t=(0,s.randomUUID)(),n=eh({sourceConversationId:e.conversation_id,sourceEventId:e.accepted_message_id,targetAgentId:e.target_bot_id,intent:e.content,executionKind:"conversation",toolProfile:"readonly"}),r="accepted"===e.state||"dispatched"===e.state,l=JSON.stringify({tool_profile:"readonly",source:"legacy_agent_requests",legacy_operation:e.operation,legacy_runtime:e.runtime,...r?{legacy_state:e.state}:{}}),_=r?Math.max(u,e.updated_at):e.updated_at;o.run(t,e.conversation_id,e.accepted_message_id,e.principal_kind,e.principal_id,e.target_bot_id,e.content,t,e.idempotency_key,n,l,r?"failed":e.state,r?eN:null,"completed"===e.state?JSON.stringify({reply_message_id:e.reply_message_id}):null,r?eN:"failed"===e.state?e.failure_code:null,r?eR:"failed"===e.state?e.failure_message:null,e.id,e.created_at,_,_,e.principal_kind,e.principal_id);let c=0;for(let n of a?.all(e.id)??[])d.run((0,s.randomUUID)(),t,++c,n.type,n.data,n.created_at);r&&d.run((0,s.randomUUID)(),t,++c,"state_changed",JSON.stringify({from:"accepted"===e.state?"queued":"running",to:"failed",reason:eN}),_),d.run((0,s.randomUUID)(),t,++c,"backfilled",JSON.stringify({legacy_agent_request_id:e.id}),_)}(function(e){let t=e.prepare(`
|
|
1067
|
+
SELECT w.id AS request_id, r.principal_kind, r.principal_id, r.idempotency_key, r.payload_hash,
|
|
1068
|
+
r.conversation_id, r.target_bot_id, r.accepted_message_id, r.created_at, m.content AS content
|
|
1069
|
+
FROM work_requests w
|
|
1070
|
+
JOIN agent_requests r ON r.id = w.legacy_agent_request_id
|
|
1071
|
+
JOIN messages m ON m.id = r.accepted_message_id
|
|
1072
|
+
WHERE r.operation = 'send_message'
|
|
1073
|
+
AND NOT EXISTS (
|
|
1074
|
+
SELECT 1 FROM conversation_intakes i
|
|
1075
|
+
WHERE i.requester_kind = r.principal_kind AND i.requester_id = r.principal_id AND i.idempotency_key = r.idempotency_key
|
|
1076
|
+
)
|
|
1077
|
+
`).all(),n=e.prepare(`
|
|
1078
|
+
INSERT INTO conversation_intakes (
|
|
1079
|
+
requester_kind, requester_id, idempotency_key, request_hash, surface,
|
|
1080
|
+
conversation_id, source_event_id, work_request_ids, created_at
|
|
1081
|
+
) VALUES (?, ?, ?, ?, 'api', ?, ?, ?, ?)
|
|
1082
|
+
`);for(let e of t){let t=[e.conversation_id,null].map(t=>[e.target_bot_id,t,e.content]).find(t=>ew(JSON.stringify(t))===e.payload_hash);t&&n.run(e.principal_kind,e.principal_id,e.idempotency_key,ew(JSON.stringify(["api",t])),e.conversation_id,e.accepted_message_id,JSON.stringify([e.request_id]),e.created_at)}})(e),t("legacy_agent_requests_archive")?e.exec("INSERT INTO legacy_agent_requests_archive SELECT * FROM agent_requests; DROP TABLE agent_requests;"):e.exec("ALTER TABLE agent_requests RENAME TO legacy_agent_requests_archive"),n&&(t("legacy_agent_request_events_archive")?e.exec("INSERT INTO legacy_agent_request_events_archive SELECT * FROM agent_request_events; DROP TABLE agent_request_events;"):e.exec("ALTER TABLE agent_request_events RENAME TO legacy_agent_request_events_archive"))}(e)}},{version:15,name:"ui_turns_on_work_requests",up:e=>{e.exec(`
|
|
1083
|
+
ALTER TABLE work_requests ADD COLUMN executor TEXT NOT NULL DEFAULT 'dispatcher'
|
|
1084
|
+
CHECK (executor IN ('dispatcher', 'ui_message', 'ui_continuation'));
|
|
1085
|
+
CREATE INDEX idx_work_requests_executor ON work_requests(executor, state, created_at);
|
|
1086
|
+
|
|
1087
|
+
-- Delegation accounting for one user message in one UI thread:
|
|
1088
|
+
-- handoffs (depth), delegated turns (budget), Stop, and the
|
|
1089
|
+
-- caller frames a delegate's reply returns to. One row per
|
|
1090
|
+
-- (conversation, user message); a later user message starts a
|
|
1091
|
+
-- fresh row.
|
|
1092
|
+
CREATE TABLE delegation_chains (
|
|
1093
|
+
conversation_id TEXT NOT NULL,
|
|
1094
|
+
user_message_id TEXT NOT NULL,
|
|
1095
|
+
handoffs INTEGER NOT NULL DEFAULT 0 CHECK (handoffs >= 0),
|
|
1096
|
+
turns INTEGER NOT NULL DEFAULT 0 CHECK (turns >= 0),
|
|
1097
|
+
stopped INTEGER NOT NULL DEFAULT 0 CHECK (stopped IN (0, 1)),
|
|
1098
|
+
frames TEXT NOT NULL DEFAULT '[]',
|
|
1099
|
+
created_at INTEGER NOT NULL,
|
|
1100
|
+
updated_at INTEGER NOT NULL,
|
|
1101
|
+
PRIMARY KEY (conversation_id, user_message_id),
|
|
1102
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id)
|
|
1103
|
+
);
|
|
1104
|
+
`),function(e){let t=t=>!!e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?").get(t);if(!t("processing_queue"))return;let n=new Set(e.prepare("PRAGMA table_info(processing_queue)").all().map(e=>e.name)).has("work_request_id")?"q.work_request_id":"NULL",r=e.prepare(`
|
|
1105
|
+
SELECT q.id, q.conversation_id, q.bot_id, q.status, ${n} AS work_request_id, q.created_at, q.started_at, q.completed_at
|
|
1106
|
+
FROM processing_queue q
|
|
1107
|
+
JOIN conversations c ON c.id = q.conversation_id
|
|
1108
|
+
JOIN bots b ON b.id = q.bot_id
|
|
1109
|
+
ORDER BY q.created_at ASC, q.rowid ASC
|
|
1110
|
+
`).all(),i=e.prepare("SELECT * FROM work_requests WHERE id = ?"),a=e.prepare(`
|
|
1111
|
+
UPDATE work_requests SET state = ?, state_reason = ?, version = version + 1, updated_at = ?,
|
|
1112
|
+
error_code = ?, error_message = ?, terminal_at = ?, executor = 'ui_message'
|
|
1113
|
+
WHERE id = ?
|
|
1114
|
+
`),o=e.prepare(`
|
|
1115
|
+
INSERT INTO engine_events (id, request_id, sequence, attempt_id, type, data, created_at)
|
|
1116
|
+
SELECT ?, ?, COALESCE(MAX(sequence), 0) + 1, NULL, ?, ?, ? FROM engine_events WHERE request_id = ?
|
|
1117
|
+
`),d=(e,t,n,r)=>o.run((0,s.randomUUID)(),e,t,JSON.stringify(n),r,e),u=e.prepare("SELECT id FROM messages WHERE conversation_id = ? AND created_at <= ? ORDER BY created_at DESC, rowid DESC LIMIT 1"),l=e.prepare(`
|
|
1118
|
+
INSERT INTO work_requests (
|
|
1119
|
+
id, source_conversation_id, source_event_id, requester_kind, requester_id, target_agent_id,
|
|
1120
|
+
intent, execution_kind, tool_profile, parent_request_id, root_request_id, wake_event_id, depth,
|
|
1121
|
+
idempotency_key, request_hash, policy_snapshot, state, version, created_at, updated_at,
|
|
1122
|
+
wake_depth, root_principal_kind, root_principal_id, executor
|
|
1123
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, 'conversation', 'readonly', NULL, ?, NULL, 0, ?, ?, ?, 'queued', 0, ?, ?, 0, ?, ?, 'ui_continuation')
|
|
1124
|
+
`),_=function(e){let t=F(e?{entryPoint:"wake",executionKind:"conversation",wakeSyntax:"legacy"}:{entryPoint:"ui",executionKind:"conversation"});if(!t.ok)throw new e_("invalid_input",t.reason);return t.policy}(!1),c=0;for(let t of r){if(t.work_request_id){let n=i.get(t.work_request_id);if(!n||"queued"!==n.state)continue;let r=t.started_at??t.created_at,s=Math.max(t.completed_at??r,r);if("pending"===t.status)e.prepare("UPDATE work_requests SET executor = 'ui_message' WHERE id = ?").run(n.id);else if("completed"===t.status||"failed"===t.status)a.run("running",null,r,null,null,null,n.id),d(n.id,"state_changed",{from:"queued",to:"running",reason:null,legacy_queue_id:t.id},r),a.run(t.status,"legacy_queue_turn",s,"failed"===t.status?"ui_turn_failed":null,"failed"===t.status?"The UI turn failed in the retired processing queue.":null,s,n.id),d(n.id,"state_changed",{from:"running",to:t.status,reason:"legacy_queue_turn",legacy_queue_id:t.id},s);else{let e=Math.max(Date.now(),r);a.run("running",null,r,null,null,null,n.id),d(n.id,"state_changed",{from:"queued",to:"running",reason:null,legacy_queue_id:t.id},r),a.run("failed",ek,e,ek,"The UI turn was interrupted before it finished; it is not run again.",e,n.id),d(n.id,"state_changed",{from:"running",to:"failed",reason:ek,error_code:ek,legacy_queue_id:t.id},e)}c++;continue}if("pending"!==t.status)continue;let n=(0,s.randomUUID)(),r=u.get(t.conversation_id,t.created_at)?.id??t.conversation_id,o={source:"legacy_processing_queue",legacy_queue_id:t.id},E=eh({sourceConversationId:t.conversation_id,sourceEventId:r,targetAgentId:t.bot_id,intent:"turn",executionKind:"conversation",toolProfile:"readonly",policy:{...o,execution_policy:_}});l.run(n,t.conversation_id,r,ev.kind,ev.id,t.bot_id,"turn",n,`legacy-queue:${t.id}`,E,JSON.stringify({...o,execution_policy:_,tool_profile:"readonly"}),t.created_at,t.created_at,ev.kind,ev.id),d(n,"accepted",{state:"queued",execution_kind:"conversation",tool_profile:"readonly"},t.created_at),d(n,"backfilled",{legacy_queue_id:t.id},t.created_at),c++}c+=e.prepare(`
|
|
1125
|
+
UPDATE work_requests SET executor = 'ui_message'
|
|
1126
|
+
WHERE state = 'queued' AND executor = 'dispatcher' AND legacy_agent_request_id IS NULL
|
|
1127
|
+
AND parent_request_id IS NULL AND wake_event_id IS NULL
|
|
1128
|
+
AND (
|
|
1129
|
+
(json_extract(policy_snapshot, '$.source') = 'conversation_intake' AND json_extract(policy_snapshot, '$.surface') = 'ui')
|
|
1130
|
+
OR EXISTS (
|
|
1131
|
+
SELECT 1 FROM conversation_intakes i, json_each(i.work_request_ids) r
|
|
1132
|
+
WHERE i.surface = 'ui' AND r.value = work_requests.id
|
|
1133
|
+
)
|
|
1134
|
+
)
|
|
1135
|
+
`).run().changes,t("legacy_processing_queue_archive")?e.exec("INSERT INTO legacy_processing_queue_archive SELECT * FROM processing_queue; DROP TABLE processing_queue;"):e.exec("ALTER TABLE processing_queue RENAME TO legacy_processing_queue_archive")}(e)}},{version:16,name:"session_exchanges",up:e=>{let t=er.flatMap(e=>es[e].map(t=>`'${e}>${t}'`)).join(", "),n=er.map(e=>`'${e}'`).join(", "),r=ei.map(e=>`'${e}'`).join(", ");e.exec(`
|
|
1136
|
+
-- One row per owner-requested exchange against one selected Session
|
|
1137
|
+
-- Binding. It names Botmancers rows only (binding, Work Requests,
|
|
1138
|
+
-- Attempts, messages): never a provider session id or credential.
|
|
1139
|
+
-- Hop Work Requests run through the dispatcher; the exchange state
|
|
1140
|
+
-- advances from their durable outcome.
|
|
1141
|
+
CREATE TABLE session_exchanges (
|
|
1142
|
+
id TEXT PRIMARY KEY,
|
|
1143
|
+
requester_kind TEXT NOT NULL CHECK (requester_kind IN ('person', 'bot', 'service')),
|
|
1144
|
+
requester_id TEXT NOT NULL,
|
|
1145
|
+
idempotency_key TEXT NOT NULL CHECK (length(idempotency_key) > 0),
|
|
1146
|
+
request_hash TEXT NOT NULL,
|
|
1147
|
+
mode TEXT NOT NULL CHECK (mode IN ('ask', 'continue')),
|
|
1148
|
+
origin_conversation_id TEXT NOT NULL,
|
|
1149
|
+
source_agent_id TEXT NOT NULL,
|
|
1150
|
+
source_binding_id TEXT NOT NULL,
|
|
1151
|
+
destination_agent_id TEXT,
|
|
1152
|
+
destination_conversation_id TEXT,
|
|
1153
|
+
destination_binding_id TEXT,
|
|
1154
|
+
instruction TEXT NOT NULL CHECK (length(instruction) BETWEEN 1 AND ${ea.instructionChars}),
|
|
1155
|
+
state TEXT NOT NULL CHECK (state IN (${n})),
|
|
1156
|
+
source_request_id TEXT,
|
|
1157
|
+
source_attempt_id TEXT,
|
|
1158
|
+
destination_request_id TEXT,
|
|
1159
|
+
destination_attempt_id TEXT,
|
|
1160
|
+
answer_message_id TEXT,
|
|
1161
|
+
packet TEXT CHECK (packet IS NULL OR length(packet) <= ${ea.packetChars}),
|
|
1162
|
+
failure_code TEXT,
|
|
1163
|
+
failure_message TEXT,
|
|
1164
|
+
cancel_requested_at INTEGER,
|
|
1165
|
+
cancel_requested_by TEXT,
|
|
1166
|
+
cancel_reason TEXT,
|
|
1167
|
+
version INTEGER NOT NULL DEFAULT 0,
|
|
1168
|
+
created_at INTEGER NOT NULL,
|
|
1169
|
+
updated_at INTEGER NOT NULL,
|
|
1170
|
+
terminal_at INTEGER,
|
|
1171
|
+
UNIQUE (requester_kind, requester_id, idempotency_key),
|
|
1172
|
+
CHECK ((state IN (${r})) = (terminal_at IS NOT NULL)),
|
|
1173
|
+
CHECK (state <> 'failed' OR failure_code IS NOT NULL),
|
|
1174
|
+
CHECK ((mode = 'continue') = (destination_agent_id IS NOT NULL AND destination_conversation_id IS NOT NULL)),
|
|
1175
|
+
CHECK (destination_agent_id IS NULL OR destination_agent_id <> source_agent_id),
|
|
1176
|
+
CHECK (mode = 'continue' OR (packet IS NULL AND destination_request_id IS NULL AND destination_binding_id IS NULL)),
|
|
1177
|
+
CHECK (mode = 'ask' OR answer_message_id IS NULL),
|
|
1178
|
+
CHECK (state = 'queued' OR state = 'failed' OR state = 'cancelled' OR source_request_id IS NOT NULL),
|
|
1179
|
+
CHECK (state <> 'delivering' OR (packet IS NOT NULL AND destination_request_id IS NOT NULL)),
|
|
1180
|
+
FOREIGN KEY (origin_conversation_id) REFERENCES conversations(id),
|
|
1181
|
+
FOREIGN KEY (source_agent_id) REFERENCES bots(id),
|
|
1182
|
+
FOREIGN KEY (source_binding_id) REFERENCES session_bindings(id),
|
|
1183
|
+
FOREIGN KEY (destination_agent_id) REFERENCES bots(id),
|
|
1184
|
+
FOREIGN KEY (destination_conversation_id) REFERENCES conversations(id),
|
|
1185
|
+
FOREIGN KEY (destination_binding_id) REFERENCES session_bindings(id),
|
|
1186
|
+
FOREIGN KEY (source_request_id) REFERENCES work_requests(id),
|
|
1187
|
+
FOREIGN KEY (source_attempt_id) REFERENCES work_attempts(id),
|
|
1188
|
+
FOREIGN KEY (destination_request_id) REFERENCES work_requests(id),
|
|
1189
|
+
FOREIGN KEY (destination_attempt_id) REFERENCES work_attempts(id),
|
|
1190
|
+
FOREIGN KEY (answer_message_id) REFERENCES messages(id)
|
|
1191
|
+
);
|
|
1192
|
+
CREATE INDEX idx_session_exchanges_open ON session_exchanges(created_at) WHERE terminal_at IS NULL;
|
|
1193
|
+
CREATE INDEX idx_session_exchanges_binding ON session_exchanges(source_binding_id);
|
|
1194
|
+
CREATE UNIQUE INDEX idx_session_exchanges_source_request ON session_exchanges(source_request_id) WHERE source_request_id IS NOT NULL;
|
|
1195
|
+
CREATE UNIQUE INDEX idx_session_exchanges_destination_request ON session_exchanges(destination_request_id) WHERE destination_request_id IS NOT NULL;
|
|
1196
|
+
|
|
1197
|
+
CREATE TABLE session_exchange_events (
|
|
1198
|
+
id TEXT PRIMARY KEY,
|
|
1199
|
+
exchange_id TEXT NOT NULL,
|
|
1200
|
+
sequence INTEGER NOT NULL CHECK (sequence >= 1),
|
|
1201
|
+
type TEXT NOT NULL CHECK (length(type) > 0),
|
|
1202
|
+
data TEXT,
|
|
1203
|
+
created_at INTEGER NOT NULL,
|
|
1204
|
+
UNIQUE (exchange_id, sequence),
|
|
1205
|
+
FOREIGN KEY (exchange_id) REFERENCES session_exchanges(id)
|
|
1206
|
+
);
|
|
1207
|
+
|
|
1208
|
+
CREATE TRIGGER trg_session_exchanges_fk BEFORE INSERT ON session_exchanges
|
|
1209
|
+
BEGIN
|
|
1210
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.origin_conversation_id')
|
|
1211
|
+
WHERE NOT EXISTS (SELECT 1 FROM conversations WHERE id = NEW.origin_conversation_id);
|
|
1212
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.source_agent_id')
|
|
1213
|
+
WHERE NOT EXISTS (SELECT 1 FROM bots WHERE id = NEW.source_agent_id);
|
|
1214
|
+
SELECT RAISE(ABORT, 'session exchange source binding does not belong to its source agent')
|
|
1215
|
+
WHERE NOT EXISTS (SELECT 1 FROM session_bindings WHERE id = NEW.source_binding_id AND agent_id = NEW.source_agent_id);
|
|
1216
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.destination_agent_id')
|
|
1217
|
+
WHERE NEW.destination_agent_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM bots WHERE id = NEW.destination_agent_id);
|
|
1218
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.destination_conversation_id')
|
|
1219
|
+
WHERE NEW.destination_conversation_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM conversations WHERE id = NEW.destination_conversation_id);
|
|
1220
|
+
SELECT RAISE(ABORT, 'a session exchange starts queued')
|
|
1221
|
+
WHERE NEW.state <> 'queued';
|
|
1222
|
+
END;
|
|
1223
|
+
|
|
1224
|
+
-- Identity, target, and instruction are fixed at creation.
|
|
1225
|
+
CREATE TRIGGER trg_session_exchanges_immutable BEFORE UPDATE OF
|
|
1226
|
+
id, requester_kind, requester_id, idempotency_key, request_hash, mode, origin_conversation_id,
|
|
1227
|
+
source_agent_id, source_binding_id, destination_agent_id, destination_conversation_id, instruction, created_at
|
|
1228
|
+
ON session_exchanges
|
|
1229
|
+
BEGIN
|
|
1230
|
+
SELECT RAISE(ABORT, 'session_exchanges identity and target are immutable');
|
|
1231
|
+
END;
|
|
1232
|
+
|
|
1233
|
+
CREATE TRIGGER trg_session_exchanges_transition BEFORE UPDATE OF state ON session_exchanges
|
|
1234
|
+
WHEN NEW.state <> OLD.state
|
|
1235
|
+
BEGIN
|
|
1236
|
+
SELECT RAISE(ABORT, 'invalid session_exchanges state transition')
|
|
1237
|
+
WHERE (OLD.state || '>' || NEW.state) NOT IN (${t})
|
|
1238
|
+
OR (OLD.mode = 'ask' AND NEW.state = 'delivering')
|
|
1239
|
+
OR (OLD.mode = 'continue' AND OLD.state = 'extracting' AND NEW.state = 'completed');
|
|
1240
|
+
END;
|
|
1241
|
+
|
|
1242
|
+
CREATE TRIGGER trg_session_exchanges_terminal BEFORE UPDATE ON session_exchanges
|
|
1243
|
+
WHEN OLD.state IN (${r})
|
|
1244
|
+
BEGIN
|
|
1245
|
+
SELECT RAISE(ABORT, 'terminal session_exchanges are immutable');
|
|
1246
|
+
END;
|
|
1247
|
+
|
|
1248
|
+
-- Causal references, the packet, and the cancellation intent are
|
|
1249
|
+
-- recorded once; a set reference must name an existing row.
|
|
1250
|
+
CREATE TRIGGER trg_session_exchanges_set_once BEFORE UPDATE ON session_exchanges
|
|
1251
|
+
BEGIN
|
|
1252
|
+
SELECT RAISE(ABORT, 'session_exchanges references are set once')
|
|
1253
|
+
WHERE (OLD.source_request_id IS NOT NULL AND NEW.source_request_id IS NOT OLD.source_request_id)
|
|
1254
|
+
OR (OLD.source_attempt_id IS NOT NULL AND NEW.source_attempt_id IS NOT OLD.source_attempt_id)
|
|
1255
|
+
OR (OLD.destination_request_id IS NOT NULL AND NEW.destination_request_id IS NOT OLD.destination_request_id)
|
|
1256
|
+
OR (OLD.destination_attempt_id IS NOT NULL AND NEW.destination_attempt_id IS NOT OLD.destination_attempt_id)
|
|
1257
|
+
OR (OLD.destination_binding_id IS NOT NULL AND NEW.destination_binding_id IS NOT OLD.destination_binding_id)
|
|
1258
|
+
OR (OLD.answer_message_id IS NOT NULL AND NEW.answer_message_id IS NOT OLD.answer_message_id)
|
|
1259
|
+
OR (OLD.packet IS NOT NULL AND NEW.packet IS NOT OLD.packet)
|
|
1260
|
+
OR (OLD.cancel_requested_at IS NOT NULL AND (NEW.cancel_requested_at IS NOT OLD.cancel_requested_at
|
|
1261
|
+
OR NEW.cancel_requested_by IS NOT OLD.cancel_requested_by OR NEW.cancel_reason IS NOT OLD.cancel_reason));
|
|
1262
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.source_request_id')
|
|
1263
|
+
WHERE NEW.source_request_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM work_requests WHERE id = NEW.source_request_id AND target_agent_id = NEW.source_agent_id);
|
|
1264
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.source_attempt_id')
|
|
1265
|
+
WHERE NEW.source_attempt_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM work_attempts WHERE id = NEW.source_attempt_id AND request_id = NEW.source_request_id);
|
|
1266
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.destination_request_id')
|
|
1267
|
+
WHERE NEW.destination_request_id IS NOT NULL AND NOT EXISTS (
|
|
1268
|
+
SELECT 1 FROM work_requests WHERE id = NEW.destination_request_id AND target_agent_id = NEW.destination_agent_id
|
|
1269
|
+
AND source_conversation_id = NEW.destination_conversation_id);
|
|
1270
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.destination_attempt_id')
|
|
1271
|
+
WHERE NEW.destination_attempt_id IS NOT NULL AND NOT EXISTS (SELECT 1 FROM work_attempts WHERE id = NEW.destination_attempt_id AND request_id = NEW.destination_request_id);
|
|
1272
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.destination_binding_id')
|
|
1273
|
+
WHERE NEW.destination_binding_id IS NOT NULL AND NOT EXISTS (
|
|
1274
|
+
SELECT 1 FROM session_bindings WHERE id = NEW.destination_binding_id AND agent_id = NEW.destination_agent_id
|
|
1275
|
+
AND request_id = NEW.destination_request_id AND id <> NEW.source_binding_id);
|
|
1276
|
+
-- The answer is the source Agent's message in the origin
|
|
1277
|
+
-- conversation, produced by the source hop request.
|
|
1278
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.answer_message_id')
|
|
1279
|
+
WHERE NEW.answer_message_id IS NOT NULL AND NOT EXISTS (
|
|
1280
|
+
SELECT 1 FROM messages WHERE id = NEW.answer_message_id AND conversation_id = NEW.origin_conversation_id
|
|
1281
|
+
AND sender_type = 'bot' AND sender_id = NEW.source_agent_id
|
|
1282
|
+
AND NEW.source_request_id IS NOT NULL AND request_id = NEW.source_request_id);
|
|
1283
|
+
END;
|
|
1284
|
+
|
|
1285
|
+
CREATE TRIGGER trg_session_exchange_events_fk BEFORE INSERT ON session_exchange_events
|
|
1286
|
+
BEGIN
|
|
1287
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchange_events.exchange_id')
|
|
1288
|
+
WHERE NOT EXISTS (SELECT 1 FROM session_exchanges WHERE id = NEW.exchange_id);
|
|
1289
|
+
END;
|
|
1290
|
+
CREATE TRIGGER trg_session_exchange_events_append_only BEFORE UPDATE ON session_exchange_events
|
|
1291
|
+
BEGIN
|
|
1292
|
+
SELECT RAISE(ABORT, 'session_exchange_events are append-only');
|
|
1293
|
+
END;
|
|
1294
|
+
-- Removed only with their exchange, by the aggregate cleanup
|
|
1295
|
+
-- (deleteSessionExchanges), under the same purge authority as
|
|
1296
|
+
-- engine events.
|
|
1297
|
+
CREATE TRIGGER trg_session_exchange_events_no_delete BEFORE DELETE ON session_exchange_events
|
|
1298
|
+
BEGIN
|
|
1299
|
+
SELECT RAISE(ABORT, 'session_exchange_events are append-only')
|
|
1300
|
+
WHERE NOT engine_event_purge_authorized(OLD.exchange_id);
|
|
1301
|
+
END;
|
|
1302
|
+
CREATE TRIGGER trg_session_exchanges_restrict BEFORE DELETE ON session_exchanges
|
|
1303
|
+
BEGIN
|
|
1304
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchange_events.exchange_id')
|
|
1305
|
+
WHERE EXISTS (SELECT 1 FROM session_exchange_events WHERE exchange_id = OLD.id);
|
|
1306
|
+
END;
|
|
1307
|
+
|
|
1308
|
+
-- Foreign keys (delete side): RESTRICT, as for the engine tables.
|
|
1309
|
+
CREATE TRIGGER trg_conversations_exchange_restrict BEFORE DELETE ON conversations
|
|
1310
|
+
BEGIN
|
|
1311
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.conversation')
|
|
1312
|
+
WHERE EXISTS (SELECT 1 FROM session_exchanges WHERE origin_conversation_id = OLD.id OR destination_conversation_id = OLD.id);
|
|
1313
|
+
END;
|
|
1314
|
+
CREATE TRIGGER trg_bots_exchange_restrict BEFORE DELETE ON bots
|
|
1315
|
+
BEGIN
|
|
1316
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.agent')
|
|
1317
|
+
WHERE EXISTS (SELECT 1 FROM session_exchanges WHERE source_agent_id = OLD.id OR destination_agent_id = OLD.id);
|
|
1318
|
+
END;
|
|
1319
|
+
CREATE TRIGGER trg_session_bindings_exchange_restrict BEFORE DELETE ON session_bindings
|
|
1320
|
+
BEGIN
|
|
1321
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.binding')
|
|
1322
|
+
WHERE EXISTS (SELECT 1 FROM session_exchanges WHERE source_binding_id = OLD.id OR destination_binding_id = OLD.id);
|
|
1323
|
+
END;
|
|
1324
|
+
CREATE TRIGGER trg_work_requests_exchange_restrict BEFORE DELETE ON work_requests
|
|
1325
|
+
BEGIN
|
|
1326
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.request')
|
|
1327
|
+
WHERE EXISTS (SELECT 1 FROM session_exchanges WHERE source_request_id = OLD.id OR destination_request_id = OLD.id);
|
|
1328
|
+
END;
|
|
1329
|
+
CREATE TRIGGER trg_messages_exchange_restrict BEFORE DELETE ON messages
|
|
1330
|
+
BEGIN
|
|
1331
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.answer_message_id')
|
|
1332
|
+
WHERE EXISTS (SELECT 1 FROM session_exchanges WHERE answer_message_id = OLD.id);
|
|
1333
|
+
END;
|
|
1334
|
+
CREATE TRIGGER trg_work_attempts_exchange_restrict BEFORE DELETE ON work_attempts
|
|
1335
|
+
BEGIN
|
|
1336
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: session_exchanges.attempt')
|
|
1337
|
+
WHERE EXISTS (SELECT 1 FROM session_exchanges WHERE source_attempt_id = OLD.id OR destination_attempt_id = OLD.id);
|
|
1338
|
+
END;
|
|
1339
|
+
`)}},{version:17,name:"provider_sessions",up:e=>{var t;e.exec(`
|
|
1340
|
+
-- One row per native runtime session Botmancers knows, under a
|
|
1341
|
+
-- stable Botmancers reference (id). provider_session_id is private:
|
|
1342
|
+
-- only the owner-only local debug disclosure ever returns it. A row
|
|
1343
|
+
-- linked to a Session Binding uses the binding's id as its id.
|
|
1344
|
+
-- availability/lifecycle/resumable/busy are independent provider
|
|
1345
|
+
-- facts; resumable NULL means the provider was never asked.
|
|
1346
|
+
CREATE TABLE provider_sessions (
|
|
1347
|
+
id TEXT PRIMARY KEY,
|
|
1348
|
+
agent_id TEXT NOT NULL,
|
|
1349
|
+
runtime_connection_id TEXT NOT NULL,
|
|
1350
|
+
provider_kind TEXT NOT NULL,
|
|
1351
|
+
provider_session_id TEXT NOT NULL,
|
|
1352
|
+
binding_id TEXT UNIQUE,
|
|
1353
|
+
origin TEXT NOT NULL CHECK (origin IN ('binding', 'discovered', 'started')),
|
|
1354
|
+
title TEXT,
|
|
1355
|
+
workspace TEXT,
|
|
1356
|
+
provider_created_at INTEGER,
|
|
1357
|
+
provider_updated_at INTEGER,
|
|
1358
|
+
availability TEXT NOT NULL DEFAULT 'available' CHECK (availability IN ('available', 'missing')),
|
|
1359
|
+
lifecycle TEXT NOT NULL DEFAULT 'open' CHECK (lifecycle IN ('open', 'archived')),
|
|
1360
|
+
resumable INTEGER CHECK (resumable IS NULL OR resumable IN (0, 1)),
|
|
1361
|
+
busy INTEGER NOT NULL DEFAULT 0 CHECK (busy IN (0, 1)),
|
|
1362
|
+
capabilities TEXT,
|
|
1363
|
+
last_synced_at INTEGER,
|
|
1364
|
+
created_at INTEGER NOT NULL,
|
|
1365
|
+
updated_at INTEGER NOT NULL,
|
|
1366
|
+
CHECK (origin <> 'binding' OR binding_id = id),
|
|
1367
|
+
FOREIGN KEY (agent_id) REFERENCES bots(id),
|
|
1368
|
+
FOREIGN KEY (binding_id) REFERENCES session_bindings(id)
|
|
1369
|
+
);
|
|
1370
|
+
-- Repeated discovery is idempotent: at most one unlinked row per
|
|
1371
|
+
-- (Agent, connection, provider session). The same provider id on
|
|
1372
|
+
-- another connection or Agent is another session.
|
|
1373
|
+
CREATE UNIQUE INDEX idx_provider_sessions_native
|
|
1374
|
+
ON provider_sessions(agent_id, runtime_connection_id, provider_session_id) WHERE binding_id IS NULL;
|
|
1375
|
+
CREATE INDEX idx_provider_sessions_lookup
|
|
1376
|
+
ON provider_sessions(agent_id, runtime_connection_id, provider_session_id);
|
|
1377
|
+
|
|
1378
|
+
-- One row per provider turn Botmancers started (start or send),
|
|
1379
|
+
-- keyed by the requester's idempotency key. provider_turn_id is
|
|
1380
|
+
-- private.
|
|
1381
|
+
CREATE TABLE provider_session_turns (
|
|
1382
|
+
id TEXT PRIMARY KEY,
|
|
1383
|
+
session_ref TEXT NOT NULL,
|
|
1384
|
+
agent_id TEXT NOT NULL,
|
|
1385
|
+
kind TEXT NOT NULL CHECK (kind IN ('start', 'send')),
|
|
1386
|
+
authority TEXT NOT NULL CHECK (authority IN ('read_only', 'workspace_write')),
|
|
1387
|
+
requester_kind TEXT NOT NULL,
|
|
1388
|
+
requester_id TEXT NOT NULL,
|
|
1389
|
+
idempotency_key TEXT NOT NULL,
|
|
1390
|
+
request_hash TEXT NOT NULL,
|
|
1391
|
+
provider_turn_id TEXT NOT NULL,
|
|
1392
|
+
state TEXT NOT NULL CHECK (state IN ('running', 'completed', 'failed', 'cancelled')),
|
|
1393
|
+
output TEXT,
|
|
1394
|
+
failure_code TEXT,
|
|
1395
|
+
correlation TEXT NOT NULL,
|
|
1396
|
+
created_at INTEGER NOT NULL,
|
|
1397
|
+
finished_at INTEGER,
|
|
1398
|
+
UNIQUE (agent_id, requester_kind, requester_id, idempotency_key),
|
|
1399
|
+
FOREIGN KEY (session_ref) REFERENCES provider_sessions(id)
|
|
1400
|
+
);
|
|
1401
|
+
CREATE INDEX idx_provider_session_turns_session ON provider_session_turns(session_ref, created_at);
|
|
1402
|
+
|
|
1403
|
+
-- Append-only audit of registry syncs and provider turns. Names
|
|
1404
|
+
-- Botmancers rows only, never a provider id.
|
|
1405
|
+
CREATE TABLE provider_session_events (
|
|
1406
|
+
id TEXT PRIMARY KEY,
|
|
1407
|
+
agent_id TEXT NOT NULL,
|
|
1408
|
+
session_ref TEXT,
|
|
1409
|
+
turn_id TEXT,
|
|
1410
|
+
type TEXT NOT NULL,
|
|
1411
|
+
detail TEXT NOT NULL,
|
|
1412
|
+
created_at INTEGER NOT NULL
|
|
1413
|
+
);
|
|
1414
|
+
CREATE INDEX idx_provider_session_events_agent ON provider_session_events(agent_id, created_at);
|
|
1415
|
+
|
|
1416
|
+
CREATE TRIGGER trg_provider_sessions_fk BEFORE INSERT ON provider_sessions
|
|
1417
|
+
BEGIN
|
|
1418
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: provider_sessions.agent_id')
|
|
1419
|
+
WHERE NOT EXISTS (SELECT 1 FROM bots WHERE id = NEW.agent_id);
|
|
1420
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: provider_sessions.binding_id')
|
|
1421
|
+
WHERE NEW.binding_id IS NOT NULL
|
|
1422
|
+
AND NOT EXISTS (SELECT 1 FROM session_bindings WHERE id = NEW.binding_id AND agent_id = NEW.agent_id);
|
|
1423
|
+
END;
|
|
1424
|
+
CREATE TRIGGER trg_provider_sessions_identity BEFORE UPDATE OF
|
|
1425
|
+
id, agent_id, runtime_connection_id, provider_kind, provider_session_id, origin, created_at
|
|
1426
|
+
ON provider_sessions
|
|
1427
|
+
BEGIN
|
|
1428
|
+
SELECT RAISE(ABORT, 'provider_sessions identity is immutable');
|
|
1429
|
+
END;
|
|
1430
|
+
CREATE TRIGGER trg_provider_session_turns_fk BEFORE INSERT ON provider_session_turns
|
|
1431
|
+
BEGIN
|
|
1432
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: provider_session_turns.session_ref')
|
|
1433
|
+
WHERE NOT EXISTS (SELECT 1 FROM provider_sessions WHERE id = NEW.session_ref AND agent_id = NEW.agent_id);
|
|
1434
|
+
END;
|
|
1435
|
+
CREATE TRIGGER trg_provider_session_events_append_only BEFORE UPDATE ON provider_session_events
|
|
1436
|
+
BEGIN
|
|
1437
|
+
SELECT RAISE(ABORT, 'provider_session_events are append-only');
|
|
1438
|
+
END;
|
|
1439
|
+
-- Delete side: the Agent and binding delete paths
|
|
1440
|
+
-- (deleteEngineRecordsForAgent / deleteEngineRecords) remove or
|
|
1441
|
+
-- unlink registry rows first; the catalog joins bots, so a raw
|
|
1442
|
+
-- delete never surfaces an orphan.
|
|
1443
|
+
CREATE TRIGGER trg_provider_sessions_restrict BEFORE DELETE ON provider_sessions
|
|
1444
|
+
BEGIN
|
|
1445
|
+
SELECT RAISE(ABORT, 'FOREIGN KEY constraint failed: provider_session_turns.session_ref')
|
|
1446
|
+
WHERE EXISTS (SELECT 1 FROM provider_session_turns WHERE session_ref = OLD.id);
|
|
1447
|
+
END;
|
|
1448
|
+
`),(t=e).prepare(`
|
|
1449
|
+
INSERT INTO provider_sessions (
|
|
1450
|
+
id, agent_id, runtime_connection_id, provider_kind, provider_session_id, binding_id, origin,
|
|
1451
|
+
availability, lifecycle, resumable, busy, created_at, updated_at
|
|
1452
|
+
)
|
|
1453
|
+
SELECT b.id, b.agent_id, ${em(t)}, b.adapter, b.external_session_id, b.id, 'binding',
|
|
1454
|
+
'available', 'open', NULL, 0, b.created_at, COALESCE(b.released_at, b.created_at)
|
|
1455
|
+
FROM session_bindings b
|
|
1456
|
+
JOIN bots bot ON bot.id = b.agent_id
|
|
1457
|
+
WHERE NOT EXISTS (SELECT 1 FROM provider_sessions p WHERE p.binding_id = b.id)
|
|
1458
|
+
ORDER BY b.created_at ASC, b.id ASC
|
|
1459
|
+
`).run()}},{version:18,name:"usage_samples",up:e=>{e.exec(`
|
|
1460
|
+
-- One row per Attempt or provider turn that reached a runtime,
|
|
1461
|
+
-- keyed by sample_key (attempt:<id> or turn:<id>), so a replayed
|
|
1462
|
+
-- terminal result, a reconciled Attempt after a restart, or a late
|
|
1463
|
+
-- result never adds a second row. Each metric is nullable: NULL is
|
|
1464
|
+
-- not reported, 0 is an explicit provider zero. breakdown holds
|
|
1465
|
+
-- whitelisted numeric counters only. Pre-existing Attempts get no
|
|
1466
|
+
-- row: their usage was never reported.
|
|
1467
|
+
CREATE TABLE usage_samples (
|
|
1468
|
+
id TEXT PRIMARY KEY,
|
|
1469
|
+
sample_key TEXT NOT NULL UNIQUE,
|
|
1470
|
+
agent_id TEXT NOT NULL,
|
|
1471
|
+
attempt_id TEXT,
|
|
1472
|
+
session_ref TEXT,
|
|
1473
|
+
turn_id TEXT,
|
|
1474
|
+
provider TEXT NOT NULL,
|
|
1475
|
+
source TEXT NOT NULL CHECK (source IN ('codex.turn_completed', 'result', 'normalized', 'none')),
|
|
1476
|
+
input_tokens INTEGER CHECK (input_tokens IS NULL OR input_tokens >= 0),
|
|
1477
|
+
output_tokens INTEGER CHECK (output_tokens IS NULL OR output_tokens >= 0),
|
|
1478
|
+
cost_usd REAL CHECK (cost_usd IS NULL OR cost_usd >= 0),
|
|
1479
|
+
breakdown TEXT,
|
|
1480
|
+
observed_at INTEGER NOT NULL,
|
|
1481
|
+
created_at INTEGER NOT NULL,
|
|
1482
|
+
updated_at INTEGER NOT NULL,
|
|
1483
|
+
CHECK (attempt_id IS NOT NULL OR turn_id IS NOT NULL)
|
|
1484
|
+
);
|
|
1485
|
+
CREATE INDEX idx_usage_samples_attempt ON usage_samples(attempt_id);
|
|
1486
|
+
CREATE INDEX idx_usage_samples_session ON usage_samples(session_ref);
|
|
1487
|
+
CREATE INDEX idx_usage_samples_agent ON usage_samples(agent_id);
|
|
1488
|
+
`)}},{version:19,name:"provider_turn_usage",up:e=>{e.exec(`
|
|
1489
|
+
ALTER TABLE provider_session_turns ADD COLUMN input_tokens INTEGER;
|
|
1490
|
+
ALTER TABLE provider_session_turns ADD COLUMN output_tokens INTEGER;
|
|
1491
|
+
ALTER TABLE provider_session_turns ADD COLUMN total_cost_usd REAL;
|
|
1492
|
+
`)}},{version:20,name:"session_pins",up:e=>{e.exec(`
|
|
1493
|
+
-- One row per pin. session_ref never changes after insert: a switch
|
|
1494
|
+
-- detaches this pin and creates another. action/authority record
|
|
1495
|
+
-- what the caller asked for (ask = read_only, resume =
|
|
1496
|
+
-- workspace_write after explicit approval); resolution how the
|
|
1497
|
+
-- session was chosen (exact, or for a registered-Agent message the
|
|
1498
|
+
-- home session, the newest eligible one, or a newly started one).
|
|
1499
|
+
CREATE TABLE session_pins (
|
|
1500
|
+
id TEXT PRIMARY KEY,
|
|
1501
|
+
requester_kind TEXT NOT NULL CHECK (requester_kind IN ('person', 'bot', 'service')),
|
|
1502
|
+
requester_id TEXT NOT NULL,
|
|
1503
|
+
idempotency_key TEXT NOT NULL,
|
|
1504
|
+
request_hash TEXT NOT NULL,
|
|
1505
|
+
agent_id TEXT NOT NULL,
|
|
1506
|
+
session_ref TEXT NOT NULL,
|
|
1507
|
+
action TEXT NOT NULL CHECK (action IN ('ask', 'resume')),
|
|
1508
|
+
authority TEXT NOT NULL CHECK (authority IN ('read_only', 'workspace_write')),
|
|
1509
|
+
resolution TEXT NOT NULL CHECK (resolution IN ('exact', 'home', 'newest', 'started')),
|
|
1510
|
+
route TEXT NOT NULL CHECK (route IN ('provider', 'engine')),
|
|
1511
|
+
conversation_id TEXT NOT NULL,
|
|
1512
|
+
approved_at INTEGER,
|
|
1513
|
+
state TEXT NOT NULL CHECK (state IN ('attached', 'detached')),
|
|
1514
|
+
detach_reason TEXT CHECK (detach_reason IS NULL OR detach_reason IN ('detached', 'switched')),
|
|
1515
|
+
replaced_by TEXT,
|
|
1516
|
+
created_at INTEGER NOT NULL,
|
|
1517
|
+
updated_at INTEGER NOT NULL,
|
|
1518
|
+
detached_at INTEGER,
|
|
1519
|
+
CHECK (authority = CASE action WHEN 'ask' THEN 'read_only' ELSE 'workspace_write' END),
|
|
1520
|
+
CHECK (action = 'ask' OR approved_at IS NOT NULL),
|
|
1521
|
+
CHECK ((state = 'attached') = (detached_at IS NULL)),
|
|
1522
|
+
UNIQUE (requester_kind, requester_id, idempotency_key)
|
|
1523
|
+
);
|
|
1524
|
+
CREATE INDEX idx_session_pins_session ON session_pins(session_ref);
|
|
1525
|
+
CREATE INDEX idx_session_pins_agent ON session_pins(agent_id);
|
|
1526
|
+
CREATE TRIGGER trg_session_pins_identity BEFORE UPDATE OF
|
|
1527
|
+
id, requester_kind, requester_id, idempotency_key, request_hash, agent_id, session_ref, action, authority, resolution, route, created_at
|
|
1528
|
+
ON session_pins
|
|
1529
|
+
BEGIN
|
|
1530
|
+
SELECT RAISE(ABORT, 'session_pins identity is immutable');
|
|
1531
|
+
END;
|
|
1532
|
+
|
|
1533
|
+
-- One row per turn sent through a pin, in order. Exactly one of
|
|
1534
|
+
-- exchange_id (engine route: an Ask exchange on the binding) and
|
|
1535
|
+
-- provider_turn_ref (provider route) is set.
|
|
1536
|
+
CREATE TABLE session_pin_turns (
|
|
1537
|
+
id TEXT PRIMARY KEY,
|
|
1538
|
+
pin_id TEXT NOT NULL,
|
|
1539
|
+
seq INTEGER NOT NULL,
|
|
1540
|
+
requester_kind TEXT NOT NULL,
|
|
1541
|
+
requester_id TEXT NOT NULL,
|
|
1542
|
+
idempotency_key TEXT NOT NULL,
|
|
1543
|
+
request_hash TEXT NOT NULL,
|
|
1544
|
+
content TEXT NOT NULL,
|
|
1545
|
+
exchange_id TEXT,
|
|
1546
|
+
provider_turn_ref TEXT,
|
|
1547
|
+
question_message_id TEXT,
|
|
1548
|
+
answer_message_id TEXT,
|
|
1549
|
+
created_at INTEGER NOT NULL,
|
|
1550
|
+
CHECK ((exchange_id IS NULL) <> (provider_turn_ref IS NULL)),
|
|
1551
|
+
UNIQUE (pin_id, seq),
|
|
1552
|
+
UNIQUE (requester_kind, requester_id, idempotency_key),
|
|
1553
|
+
FOREIGN KEY (pin_id) REFERENCES session_pins(id)
|
|
1554
|
+
);
|
|
1555
|
+
|
|
1556
|
+
-- Append-only audit of every pin decision: created (with the
|
|
1557
|
+
-- resolution), turn sent, turn refused (with the stable code; the
|
|
1558
|
+
-- target never changes), detached, switched.
|
|
1559
|
+
CREATE TABLE session_pin_events (
|
|
1560
|
+
id TEXT PRIMARY KEY,
|
|
1561
|
+
pin_id TEXT NOT NULL,
|
|
1562
|
+
sequence INTEGER NOT NULL,
|
|
1563
|
+
type TEXT NOT NULL,
|
|
1564
|
+
data TEXT NOT NULL,
|
|
1565
|
+
created_at INTEGER NOT NULL,
|
|
1566
|
+
UNIQUE (pin_id, sequence)
|
|
1567
|
+
);
|
|
1568
|
+
CREATE TRIGGER trg_session_pin_events_append_only BEFORE UPDATE ON session_pin_events
|
|
1569
|
+
BEGIN
|
|
1570
|
+
SELECT RAISE(ABORT, 'session_pin_events are append-only');
|
|
1571
|
+
END;
|
|
1572
|
+
`)}}];function em(e){return e.prepare("PRAGMA table_info(bots)").all().some(e=>"runtime_connection_id"===e.name)?"COALESCE(bot.runtime_connection_id, 'rc-local-' || b.adapter)":"'rc-local-' || b.adapter"}let ef=new WeakMap;function eT(e){let t=ef.get(e);if(!t){t=new Set,ef.set(e,t);let n=t;e.function("engine_event_purge_authorized",{deterministic:!1},e=>"string"==typeof e&&n.has(e)?1:0)}return t}function eg(e,t={}){eT(e),e.exec(`
|
|
1573
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
1574
|
+
version INTEGER PRIMARY KEY,
|
|
1575
|
+
name TEXT NOT NULL,
|
|
1576
|
+
applied_at INTEGER NOT NULL
|
|
1577
|
+
);
|
|
1578
|
+
`);let n=e.prepare("SELECT 1 FROM schema_migrations WHERE version = ?"),r=e.prepare("INSERT INTO schema_migrations (version, name, applied_at) VALUES (?, ?, ?)");for(let i of ep){if(void 0!==t.through&&i.version>t.through)return;e.transaction(()=>{n.get(i.version)||(i.up(e),r.run(i.version,i.name,Date.now()))}).immediate()}}function eh(e){return ew(JSON.stringify([e.sourceConversationId,e.sourceEventId,e.targetAgentId,e.intent,e.executionKind,e.toolProfile,e.parentRequestId??null,e.wakeEventId??null,e.policy??null]))}ep[ep.length-1].version;let eN="legacy_interrupted",eR="Accepted before NOT-465 by the retired agent_requests dispatcher; it never reached a terminal state.",ev=Object.freeze({kind:"service",id:"botmancers-ui-turns"}),ek="ui_turn_interrupted";function ey(e){return"string"==typeof e&&e.trim().length>0}function ew(e){return(0,s.createHash)("sha256").update(e).digest("hex")}function eL(e){return null==e?null:JSON.stringify(e)}function eO(e){eT(e);let t=e.prepare("SELECT * FROM work_requests WHERE id = ?"),n=e.prepare("SELECT * FROM work_requests WHERE requester_kind = ? AND requester_id = ? AND idempotency_key = ?"),r=e.prepare("SELECT * FROM work_attempts WHERE id = ?"),i=e.prepare(`
|
|
1579
|
+
INSERT INTO engine_events (id, request_id, sequence, attempt_id, type, data, created_at)
|
|
1580
|
+
SELECT ?, ?, COALESCE(MAX(sequence), 0) + 1, ?, ?, ?, ? FROM engine_events WHERE request_id = ?
|
|
1581
|
+
`),a=e.prepare("SELECT * FROM engine_events WHERE id = ?"),o=e.prepare("SELECT * FROM session_bindings WHERE id = ?");function d(e){let n=t.get(e);if(!n)throw new e_("not_found",`No work request ${e}.`);return n}function u(e){let t=r.get(e);if(!t)throw new e_("not_found",`No attempt ${e}.`);return t}function l(e,t,n,r,o){let d=(0,s.randomUUID)();return i.run(d,e,r,t,eL(n),o,e),a.get(d)}let _={transaction:t=>e.transaction(t).immediate(),createOrGetWorkRequest(r){if(!ey(r.sourceConversationId))throw new e_("invalid_input","sourceConversationId is required.");if(!ey(r.sourceEventId))throw new e_("invalid_input","sourceEventId is required.");if(!r.requester||!["person","bot","service"].includes(r.requester.kind)||!ey(r.requester.id))throw new e_("invalid_input","A requester principal is required.");if(!ey(r.targetAgentId))throw new e_("invalid_input","targetAgentId is required.");if("string"!=typeof r.intent)throw new e_("invalid_input","intent is required.");if(!D(r.executionKind))throw new e_("invalid_input","Unknown execution kind.");if(x[r.executionKind]!==r.toolProfile)throw new e_("invalid_input",`Execution kind ${r.executionKind} requires the ${x[r.executionKind]} tool profile.`);if(r.policy&&Object.prototype.hasOwnProperty.call(r.policy,"execution_policy"))throw new e_("invalid_input","The execution policy is passed as executionPolicy, never inside policy.");if(void 0!==r.executionPolicy){let e=M(r.executionPolicy);if(!e.ok)throw new e_("invalid_input",e.reason);if(e.policy.execution_kind!==r.executionKind||e.policy.tool_profile!==r.toolProfile)throw new e_("invalid_input","The execution policy does not match the requested execution kind and tool profile.")}if(!ey(r.idempotencyKey))throw new e_("invalid_input","idempotencyKey is required.");if(void 0!==r.executor&&!el.includes(r.executor))throw new e_("invalid_input","Unknown request executor.");if(r.initialState&&"queued"!==r.initialState&&"blocked"!==r.initialState)throw new e_("invalid_input","A work request starts queued or blocked.");if(void 0!==r.deadlineAt&&null!==r.deadlineAt&&!Number.isSafeInteger(r.deadlineAt))throw new e_("invalid_input","deadlineAt must be an epoch millisecond integer.");if(void 0!==r.retryPolicy){let e=$(r.retryPolicy);if(!e.ok)throw new e_("invalid_input",e.reason)}let i=r.executionPolicy?{...r.policy??{},execution_policy:r.executionPolicy}:r.policy,a=eh({...r,policy:i});return e.transaction(()=>{let o=n.get(r.requester.kind,r.requester.id,r.idempotencyKey);if(o){if(o.request_hash!==a)throw new e_("idempotency_conflict","The idempotency key was already used with a different request.");return{request:o,created:!1}}let u=r.now??Date.now(),c=(0,s.randomUUID)(),E=c,p=0,m=0,f=r.rootPrincipal??r.requester;if(r.parentRequestId){let e=t.get(r.parentRequestId);if(!e)throw new e_("not_found","Parent work request not found.");E=e.root_request_id,p=e.depth+1,m=r.wakeEventId?e.wake_depth+1:e.wake_depth,f={kind:e.root_principal_kind??"unknown",id:e.root_principal_id??"unknown"}}void 0!==r.wakeDepth&&(m=r.wakeDepth);let T=r.initialState??"queued",g=JSON.stringify({...i??{},...r.safetySnapshot??{},tool_profile:r.toolProfile}),h=G(),N=r.retryPolicy??h.retryPolicy,R=void 0!==r.deadlineAt?r.deadlineAt:null===h.deadlineMs?null:u+h.deadlineMs;return e.prepare(`
|
|
1582
|
+
INSERT INTO work_requests (
|
|
1583
|
+
id, source_conversation_id, source_event_id, requester_kind, requester_id, target_agent_id,
|
|
1584
|
+
intent, execution_kind, tool_profile, parent_request_id, root_request_id, wake_event_id, depth,
|
|
1585
|
+
idempotency_key, request_hash, policy_snapshot, state, state_reason, version, created_at, updated_at,
|
|
1586
|
+
deadline_at, retry_policy, wake_depth, root_principal_kind, root_principal_id, executor
|
|
1587
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1588
|
+
`).run(c,r.sourceConversationId,r.sourceEventId,r.requester.kind,r.requester.id,r.targetAgentId,r.intent,r.executionKind,r.toolProfile,r.parentRequestId??null,E,r.wakeEventId??null,p,r.idempotencyKey,a,g,T,r.stateReason??null,u,u,R,JSON.stringify(N),m,f.kind,f.id,r.executor??"dispatcher"),l(c,"accepted",{state:T,execution_kind:r.executionKind,tool_profile:r.toolProfile,deadline_at:R,retry_policy:N},null,u),r.executionPolicy&&l(c,"policy_selected",{...r.executionPolicy},null,u),"blocked"===T&&l(c,"state_changed",{from:"queued",to:"blocked",reason:r.stateReason??null},null,u),r.safety&&_.recordSafetyDecision(c,{...r.safety,now:r.safety.now??u}),{request:d(c),created:!0}}).immediate()},getWorkRequest:e=>t.get(e),recordSafetyDecision(t,n){if(!["human_owner","api_principal","agent_principal","engine"].includes(n.principalType))throw new e_("invalid_input","A categorized principal is required.");if(!ey(n.principal?.kind)||!ey(n.principal?.id))throw new e_("invalid_input","A principal is required.");if(!["allowed","blocked","denied"].includes(n.decision))throw new e_("invalid_input","Unknown safety decision.");if("allowed"===n.decision&&!ey(n.grantRule))throw new e_("invalid_input","An allowed decision names its grant rule.");return e.transaction(()=>{let r=d(t),i=(0,s.randomUUID)();return e.prepare(`
|
|
1589
|
+
INSERT INTO wake_safety_decisions (
|
|
1590
|
+
id, request_id, sequence, wake_id, principal_type, principal_kind, principal_id, target_agent_id, execution_kind,
|
|
1591
|
+
decision, reason_code, grant_rule, grant_id, policy_snapshot, created_at
|
|
1592
|
+
) SELECT ?, ?, COALESCE(MAX(sequence), 0) + 1, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? FROM wake_safety_decisions WHERE request_id = ?
|
|
1593
|
+
`).run(i,t,n.wakeId??null,n.principalType,n.principal.kind,n.principal.id,r.target_agent_id,r.execution_kind,n.decision,n.reasonCode??null,n.grantRule??null,n.grantId??null,JSON.stringify(n.snapshot),n.now??Date.now(),t),e.prepare("SELECT * FROM wake_safety_decisions WHERE id = ?").get(i)}).immediate()},listSafetyDecisions:t=>e.prepare("SELECT * FROM wake_safety_decisions WHERE request_id = ? ORDER BY sequence ASC").all(t),latestSafetyDecision:t=>e.prepare("SELECT * FROM wake_safety_decisions WHERE request_id = ? ORDER BY sequence DESC LIMIT 1").get(t),transitionWorkRequest(t,n){if(!eu[n.from]?.includes(n.to))throw new e_("invalid_transition",`Cannot move a work request from ${n.from} to ${n.to}.`);let r=ed.includes(n.to);return e.transaction(()=>{let i=d(t),s=n.now??Date.now();if(1!==e.prepare(`
|
|
1594
|
+
UPDATE work_requests SET
|
|
1595
|
+
state = ?, state_reason = ?, version = version + 1, updated_at = ?,
|
|
1596
|
+
result = ?, error_code = ?, error_message = ?, terminal_at = ?
|
|
1597
|
+
WHERE id = ? AND state = ? AND (? IS NULL OR version = ?)
|
|
1598
|
+
`).run(n.to,n.reason??null,s,r?eL(n.result):null,r?n.errorCode??null:null,r?n.errorMessage??null:null,r?s:null,t,n.from,n.expectedVersion??null,n.expectedVersion??null).changes)throw new e_("stale_state",`Work request ${t} is ${i.state} at version ${i.version}, not ${n.from}${void 0===n.expectedVersion?"":` at version ${n.expectedVersion}`}.`);return l(t,"state_changed",{...n.data??{},from:n.from,to:n.to,reason:n.reason??null,...n.errorCode?{error_code:n.errorCode}:{}},null,s),r&&null===i.legacy_agent_request_id&&"dispatcher"===i.executor&&e.prepare("INSERT OR IGNORE INTO terminal_followups (request_id, created_at) VALUES (?, ?)").run(t,s),d(t)}).immediate()},reblockWorkRequest:(t,n)=>e.transaction(()=>{let r=n.now??Date.now();if(1!==e.prepare("UPDATE work_requests SET state_reason = ?, version = version + 1, updated_at = ? WHERE id = ? AND state = 'blocked'").run(n.reason,r,t).changes)throw new e_("stale_state",`Work request ${t} is not blocked.`);return l(t,n.type,n.data??{},null,r),d(t)}).immediate(),appendEvent(t,n){if(!ey(n.type))throw new e_("invalid_input","Event type is required.");return e.transaction(()=>{if(d(t),n.attemptId&&u(n.attemptId).request_id!==t)throw new e_("invalid_input","The attempt belongs to another request.");return l(t,n.type,n.data,n.attemptId??null,n.now??Date.now())}).immediate()},listEvents:t=>e.prepare("SELECT * FROM engine_events WHERE request_id = ? ORDER BY sequence ASC").all(t),createAttempt(t,n){if("launch"!==n.kind&&"resume"!==n.kind)throw new e_("invalid_input","Unknown attempt kind.");if(!ey(n.adapter))throw new e_("invalid_input","adapter is required.");if("resume"===n.kind&&!n.resumedSessionBindingId)throw new e_("invalid_input","A resume attempt names the session binding it resumes.");if("launch"===n.kind&&n.resumedSessionBindingId)throw new e_("invalid_input","A launch attempt does not resume a session binding.");let r="string"==typeof n.launchSnapshot?n.launchSnapshot:JSON.stringify(n.launchSnapshot);if("string"!=typeof r||0===r.length)throw new e_("invalid_input","A launch snapshot is required.");return e.transaction(()=>{let i=d(t);if("running"!==i.state)throw new e_("attempt_conflict",`Attempts start only on running requests (request is ${i.state}).`);if(n.toolProfile!==i.tool_profile)throw new e_("invalid_input",`The attempt tool profile must be ${i.tool_profile}.`);if(e.prepare("SELECT id FROM work_attempts WHERE request_id = ? AND finished_at IS NULL").get(t))throw new e_("attempt_conflict","The request already has an open attempt.");if(n.resumedSessionBindingId){let e=o.get(n.resumedSessionBindingId);if(!e)throw new e_("not_found","Session binding not found.");if(null!==e.released_at)throw new e_("session_mismatch","The session binding was released.");if(e.agent_id!==i.target_agent_id||e.adapter!==n.adapter)throw new e_("session_mismatch","The session binding belongs to another Agent or adapter.");if(null!==e.conversation_id&&e.conversation_id!==i.source_conversation_id)throw new e_("session_mismatch","The session binding belongs to another conversation.");if(null!==e.request_id&&d(e.request_id).root_request_id!==i.root_request_id)throw new e_("session_mismatch","The session binding belongs to an unrelated work request.")}let a=n.now??Date.now(),_=(0,s.randomUUID)(),c=e.prepare("SELECT COALESCE(MAX(attempt_number), 0) + 1 AS n FROM work_attempts WHERE request_id = ?").get(t);return e.prepare(`
|
|
1599
|
+
INSERT INTO work_attempts (
|
|
1600
|
+
id, request_id, attempt_number, kind, adapter, tool_profile, launch_snapshot, launch_snapshot_hash,
|
|
1601
|
+
resumed_session_binding_id, external_run_id, external_session_id, started_at
|
|
1602
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1603
|
+
`).run(_,t,c.n,n.kind,n.adapter,n.toolProfile,r,ew(r),n.resumedSessionBindingId??null,n.externalRunId??null,n.externalSessionId??null,a),l(t,"attempt_started",{attempt_number:c.n,kind:n.kind,adapter:n.adapter},_,a),u(_)}).immediate()},recordAttemptExternalIds:(t,n)=>e.transaction(()=>{let r=u(t);if(null!==r.finished_at)throw new e_("attempt_conflict","The attempt is already finished.");return e.prepare("UPDATE work_attempts SET external_run_id = ?, external_session_id = ? WHERE id = ?").run(void 0===n.externalRunId?r.external_run_id:n.externalRunId,void 0===n.externalSessionId?r.external_session_id:n.externalSessionId,t),u(t)}).immediate(),finishAttempt(t,n){if(!["succeeded","failed","cancelled","interrupted","timed_out"].includes(n.outcome))throw new e_("invalid_input","Unknown attempt outcome.");return e.transaction(()=>{let r=u(t);if(null!==r.finished_at)throw new e_("attempt_conflict","The attempt is already finished.");let i=n.now??Date.now();return e.prepare(`
|
|
1604
|
+
UPDATE work_attempts SET outcome = ?, output = ?, error_category = ?, error_message = ?, artifacts = ?,
|
|
1605
|
+
external_run_id = ?, external_session_id = ?, finished_at = ?
|
|
1606
|
+
WHERE id = ? AND finished_at IS NULL
|
|
1607
|
+
`).run(n.outcome,n.output??null,n.errorCategory??null,n.errorMessage??null,JSON.stringify(n.artifacts??[]),void 0===n.externalRunId?r.external_run_id:n.externalRunId,void 0===n.externalSessionId?r.external_session_id:n.externalSessionId,i,t),l(r.request_id,"attempt_finished",{attempt_number:r.attempt_number,outcome:n.outcome,error_category:n.errorCategory??null},t,i),u(t)}).immediate()},recordAttemptUsage(t,n){let r=u(t);en(e,t,{agentId:d(r.request_id).target_agent_id,provider:r.adapter,usage:n.usage,observedAt:n.observedAt,now:n.now})},getAttempt:e=>r.get(e),listAttempts:t=>e.prepare("SELECT * FROM work_attempts WHERE request_id = ? ORDER BY attempt_number ASC").all(t),bindSession(t){if(!ey(t.agentId))throw new e_("invalid_input","agentId is required.");if(!ey(t.adapter))throw new e_("invalid_input","adapter is required.");if(!ey(t.externalSessionId))throw new e_("invalid_input","externalSessionId is required.");if(!t.conversationId&&!t.requestId)throw new e_("invalid_input","A session binding is scoped to a conversation or work request.");return e.transaction(()=>{let n=t.now??Date.now();if(!e.prepare("SELECT 1 FROM bots WHERE id = ?").get(t.agentId))throw new e_("not_found",`No agent ${t.agentId}.`);if(t.requestId){let e=d(t.requestId);if(e.target_agent_id!==t.agentId)throw new e_("session_mismatch","The work request targets another Agent.");if(t.conversationId&&e.source_conversation_id!==t.conversationId)throw new e_("session_mismatch","The work request belongs to another conversation.")}if(t.sourceAttemptId){let e=u(t.sourceAttemptId),n=d(e.request_id);if(e.adapter!==t.adapter||n.target_agent_id!==t.agentId)throw new e_("session_mismatch","The source attempt ran another Agent or adapter.");if(t.requestId&&e.request_id!==t.requestId)throw new e_("session_mismatch","The source attempt belongs to another work request.");if(t.conversationId&&n.source_conversation_id!==t.conversationId)throw new e_("session_mismatch","The source attempt belongs to another conversation.")}e.prepare(`
|
|
1608
|
+
UPDATE session_bindings SET released_at = ?
|
|
1609
|
+
WHERE agent_id = ? AND adapter = ? AND IFNULL(conversation_id, '') = ? AND IFNULL(request_id, '') = ?
|
|
1610
|
+
AND released_at IS NULL
|
|
1611
|
+
`).run(n,t.agentId,t.adapter,t.conversationId??"",t.requestId??"");let r=(0,s.randomUUID)();return e.prepare(`
|
|
1612
|
+
INSERT INTO session_bindings (id, agent_id, adapter, conversation_id, request_id, external_session_id, source_attempt_id, created_at)
|
|
1613
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
1614
|
+
`).run(r,t.agentId,t.adapter,t.conversationId??null,t.requestId??null,t.externalSessionId,t.sourceAttemptId??null,n),e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'provider_sessions'").get()&&e.prepare(`
|
|
1615
|
+
INSERT INTO provider_sessions (
|
|
1616
|
+
id, agent_id, runtime_connection_id, provider_kind, provider_session_id, binding_id, origin,
|
|
1617
|
+
availability, lifecycle, resumable, busy, created_at, updated_at
|
|
1618
|
+
)
|
|
1619
|
+
SELECT b.id, b.agent_id, ${em(e)}, b.adapter, b.external_session_id, b.id, 'binding',
|
|
1620
|
+
'available', 'open', NULL, 0, b.created_at, b.created_at
|
|
1621
|
+
FROM session_bindings b JOIN bots bot ON bot.id = b.agent_id
|
|
1622
|
+
WHERE b.id = ?
|
|
1623
|
+
`).run(r),t.requestId&&l(t.requestId,"session_bound",{binding_id:r,adapter:t.adapter},t.sourceAttemptId??null,n),o.get(r)}).immediate()},getActiveSessionBinding:t=>e.prepare(`
|
|
1624
|
+
SELECT * FROM session_bindings
|
|
1625
|
+
WHERE agent_id = ? AND adapter = ? AND IFNULL(conversation_id, '') = ? AND IFNULL(request_id, '') = ?
|
|
1626
|
+
AND released_at IS NULL
|
|
1627
|
+
`).get(t.agentId,t.adapter,t.conversationId??"",t.requestId??"")};return _}function eI(e,t){let n=(t,...n)=>e.prepare(t).all(...n).map(e=>e.id),r=new Set(n(t.requests,t.arg)),i=new Set,s=new Set(n(t.bindings,t.arg)),a=new Set,o=(e,t)=>{let n=!1;for(let r of t)e.has(r)||(e.add(r),n=!0);return n},d=e=>JSON.stringify([...e]),u="(SELECT value FROM json_each(?))";for(;;){let e=o(i,n(`SELECT id FROM session_exchanges WHERE (${t.exchanges})
|
|
1628
|
+
OR source_request_id IN ${u} OR destination_request_id IN ${u} OR source_attempt_id IN ${u}
|
|
1629
|
+
OR destination_attempt_id IN ${u} OR source_binding_id IN ${u} OR destination_binding_id IN ${u}`,t.arg,t.arg,d(r),d(r),d(a),d(a),d(s),d(s))),l=o(r,n(`SELECT source_request_id AS id FROM session_exchanges WHERE id IN ${u} AND source_request_id IS NOT NULL
|
|
1630
|
+
UNION SELECT destination_request_id AS id FROM session_exchanges WHERE id IN ${u} AND destination_request_id IS NOT NULL`,d(i),d(i))),_=o(r,n(`SELECT id FROM work_requests WHERE parent_request_id IN ${u} OR root_request_id IN ${u}`,d(r),d(r))),c=o(r,n(`SELECT request_id AS id FROM work_attempts WHERE id IN ${u}`,d(a))),E=o(a,n(`SELECT id FROM work_attempts WHERE request_id IN ${u} OR resumed_session_binding_id IN ${u}`,d(r),d(s))),p=o(s,n(`SELECT id FROM session_bindings WHERE request_id IN ${u} OR source_attempt_id IN ${u}`,d(r),d(a)));if(!e&&!l&&!_&&!c&&!E&&!p)break}(function(e,t,...n){let r=e.prepare(`SELECT id FROM session_exchanges WHERE ${t}`).all(...n).map(e=>e.id);if(0===r.length)return;let i=eT(e);for(let e of r)i.add(e);try{e.prepare("DELETE FROM session_exchange_events WHERE exchange_id IN (SELECT value FROM json_each(?))").run(JSON.stringify(r))}finally{i.clear()}e.prepare("DELETE FROM session_exchanges WHERE id IN (SELECT value FROM json_each(?))").run(JSON.stringify(r))})(e,`id IN ${u}`,d(i)),e.prepare(`DELETE FROM conversation_events WHERE request_id IN ${u}`).run(d(r)),e.prepare(`DELETE FROM finalizations WHERE implementation_request_id IN ${u} OR review_request_id IN ${u} OR decision_request_id IN ${u}`).run(d(r),d(r),d(r)),e.prepare(`DELETE FROM candidate_manifests WHERE request_id IN ${u}`).run(d(r)),e.prepare(`DELETE FROM attempt_finalization_baselines WHERE request_id IN ${u}`).run(d(r)),e.prepare(`DELETE FROM conversation_projection_cursors WHERE request_id IN ${u}`).run(d(r)),e.prepare(`DELETE FROM wake_safety_decisions WHERE request_id IN ${u}`).run(d(r)),e.prepare(`DELETE FROM dispatch_leases WHERE request_id IN ${u}`).run(d(r)),e.prepare(`DELETE FROM attempt_launch_intents WHERE request_id IN ${u}`).run(d(r)),e.prepare(`DELETE FROM dispatch_attention WHERE request_id IN ${u}`).run(d(r));let l=eT(e);for(let e of r)l.add(e);try{e.prepare(`DELETE FROM engine_events WHERE request_id IN ${u}`).run(d(r))}finally{l.clear()}for(eA(e,`origin = 'binding' AND binding_id IN ${u}`,d(s)),e.prepare(`UPDATE provider_sessions SET binding_id = NULL WHERE binding_id IN ${u}`).run(d(s)),e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'usage_samples'").get()&&e.prepare(`DELETE FROM usage_samples WHERE attempt_id IN ${u}`).run(d(a));a.size>0||s.size>0;){let t=n(`SELECT id FROM session_bindings WHERE id IN ${u}
|
|
1631
|
+
AND NOT EXISTS (SELECT 1 FROM work_attempts a WHERE a.resumed_session_binding_id = session_bindings.id)`,d(s));for(let n of t)e.prepare("DELETE FROM session_bindings WHERE id = ?").run(n),s.delete(n);let r=n(`SELECT id FROM work_attempts WHERE id IN ${u}
|
|
1632
|
+
AND NOT EXISTS (SELECT 1 FROM session_bindings b WHERE b.source_attempt_id = work_attempts.id)`,d(a));for(let t of r)e.prepare("DELETE FROM work_attempts WHERE id = ?").run(t),a.delete(t);if(0===t.length&&0===r.length)throw Error("Engine records could not be removed: unexpected attempt/binding reference cycle.")}for(let t of(e.prepare(`DELETE FROM conversation_events WHERE request_id IS NULL AND wake_id IN (SELECT id FROM wakes WHERE work_request_id IN ${u} OR parent_request_id IN ${u} OR root_request_id IN ${u})`).run(d(r),d(r),d(r)),e.prepare(`DELETE FROM wakes WHERE work_request_id IN ${u} OR parent_request_id IN ${u} OR root_request_id IN ${u}`).run(d(r),d(r),d(r)),e.prepare(`DELETE FROM terminal_followups WHERE request_id IN ${u}`).run(d(r)),n(`SELECT id FROM work_requests WHERE id IN ${u} ORDER BY depth DESC`,d(r))))e.prepare("DELETE FROM work_requests WHERE id = ?").run(t)}function eA(e,t,...n){if(!e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'provider_sessions'").get())return;let r=JSON.stringify(e.prepare(`SELECT id FROM provider_sessions WHERE ${t}`).all(...n).map(e=>e.id));e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'usage_samples'").get()&&e.prepare("DELETE FROM usage_samples WHERE session_ref IN (SELECT value FROM json_each(?))").run(r),e.prepare("DELETE FROM provider_session_events WHERE session_ref IN (SELECT value FROM json_each(?))").run(r),e.prepare("DELETE FROM provider_session_turns WHERE session_ref IN (SELECT value FROM json_each(?))").run(r),e.prepare("DELETE FROM provider_sessions WHERE id IN (SELECT value FROM json_each(?))").run(r)}function eS(e,t,...n){if(!e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'session_pins'").get())return;let r=JSON.stringify(e.prepare(`SELECT id FROM session_pins WHERE ${t}`).all(...n).map(e=>e.id));e.prepare("DELETE FROM session_pin_events WHERE pin_id IN (SELECT value FROM json_each(?))").run(r),e.prepare("DELETE FROM session_pin_turns WHERE pin_id IN (SELECT value FROM json_each(?))").run(r),e.prepare("DELETE FROM session_pins WHERE id IN (SELECT value FROM json_each(?))").run(r)}function eb(e,t){e.prepare("DELETE FROM conversation_intakes WHERE conversation_id = ?").run(t),e.prepare("DELETE FROM delegation_chains WHERE conversation_id = ?").run(t),e.prepare("DELETE FROM conversation_events WHERE conversation_id = ? AND request_id IS NULL").run(t),e.prepare("DELETE FROM wakes WHERE source_conversation_id = ?").run(t),eS(e,"conversation_id = ?",t),eI(e,{requests:"SELECT id FROM work_requests WHERE source_conversation_id = ?",bindings:"SELECT id FROM session_bindings WHERE conversation_id = ?",exchanges:"origin_conversation_id = ? OR destination_conversation_id = ?",arg:t})}function eq(e,t){e.prepare(`DELETE FROM conversation_events WHERE request_id IS NULL AND wake_id IN (
|
|
1633
|
+
SELECT id FROM wakes WHERE target_agent_id = ? OR (requester_agent_id = ? AND work_request_id IS NULL))`).run(t,t),e.prepare("DELETE FROM wakes WHERE target_agent_id = ? OR (requester_agent_id = ? AND work_request_id IS NULL)").run(t,t),e.prepare("DELETE FROM wake_grants WHERE caller_agent_id = ? OR target_agent_id = ?").run(t,t),eS(e,"agent_id = ?",t),eA(e,"agent_id = ?",t),e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'usage_samples'").get()&&e.prepare("DELETE FROM usage_samples WHERE agent_id = ?").run(t),e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'provider_session_events'").get()&&e.prepare("DELETE FROM provider_session_events WHERE agent_id = ?").run(t),eI(e,{requests:"SELECT id FROM work_requests WHERE target_agent_id = ?",bindings:"SELECT id FROM session_bindings WHERE agent_id = ?",exchanges:"source_agent_id = ? OR destination_agent_id = ?",arg:t})}e.s(["EXCHANGE_LIMITS",0,ea,"EXCHANGE_TERMINAL_STATES",0,ei,"EXCHANGE_TRANSITIONS",0,es,"EngineStoreError",0,e_,"TERMINAL_STATES",0,ed,"createEngineStore",0,eO,"deleteEngineRecordsForAgent",0,eq,"deleteEngineRecordsForConversation",0,eb,"migrateEngineSchema",0,eg],94057);let eC=/^[A-Za-z0-9][A-Za-z0-9._:@-]{0,127}$/,ex=/^[a-z][a-z0-9_.:-]{0,63}$/;function eD(e){return null==e||""===e?null:eC.test(e)?e:"[invalid]"}function eU(e,t){return e&&ex.test(e)?e:t}function eF(e){return String(e??"").trim()}function eW(e){return eF(e).normalize("NFC").toLowerCase().normalize("NFC")}class eM extends Error{code="agent_name_conflict";requestedName;conflictingAgentId;constructor(e,t){super(function(e){return`An Agent named "${eF(e)}" already exists. Agent names must be unique, ignoring case and surrounding spaces.`}(e)),this.name="AgentNameConflictError",this.requestedName=eF(e),this.conflictingAgentId=t}}function eH(e=process.env){let t=(e.BOTMANCERS_HOME||"").trim();return t?i.default.resolve(t):null}function eX(e=process.env){let t=(e.BOTMANCERS_DB_PATH||"").trim()||null;if(t)return t;let n=eH(e);return n?i.default.join(n,"data/botmancers.db"):"botmancers.db"}e.s(["botmancersHome",0,eH,"dbPath",0,eX],99684);let eG=eX();":memory:"!==eG&&r.default.mkdirSync(i.default.dirname(i.default.resolve(eG)),{recursive:!0});let e$=new n.default(eG);e$.pragma("journal_mode = WAL"),e$.exec(`
|
|
1634
|
+
CREATE TABLE IF NOT EXISTS bots (
|
|
1635
|
+
id TEXT PRIMARY KEY,
|
|
1636
|
+
name TEXT NOT NULL,
|
|
1637
|
+
title TEXT NOT NULL,
|
|
1638
|
+
description TEXT NOT NULL,
|
|
1639
|
+
avatar TEXT,
|
|
1640
|
+
created_at INTEGER NOT NULL
|
|
1641
|
+
);
|
|
1642
|
+
|
|
1643
|
+
CREATE TABLE IF NOT EXISTS groups (
|
|
1644
|
+
id TEXT PRIMARY KEY,
|
|
1645
|
+
name TEXT NOT NULL,
|
|
1646
|
+
created_at INTEGER NOT NULL
|
|
1647
|
+
);
|
|
1648
|
+
|
|
1649
|
+
CREATE TABLE IF NOT EXISTS group_members (
|
|
1650
|
+
group_id TEXT NOT NULL,
|
|
1651
|
+
bot_id TEXT NOT NULL,
|
|
1652
|
+
PRIMARY KEY (group_id, bot_id),
|
|
1653
|
+
FOREIGN KEY (group_id) REFERENCES groups(id),
|
|
1654
|
+
FOREIGN KEY (bot_id) REFERENCES bots(id)
|
|
1655
|
+
);
|
|
1656
|
+
|
|
1657
|
+
CREATE TABLE IF NOT EXISTS conversations (
|
|
1658
|
+
id TEXT PRIMARY KEY,
|
|
1659
|
+
type TEXT NOT NULL,
|
|
1660
|
+
bot_id TEXT,
|
|
1661
|
+
group_id TEXT,
|
|
1662
|
+
created_at INTEGER NOT NULL,
|
|
1663
|
+
FOREIGN KEY (bot_id) REFERENCES bots(id),
|
|
1664
|
+
FOREIGN KEY (group_id) REFERENCES groups(id)
|
|
1665
|
+
);
|
|
1666
|
+
|
|
1667
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
1668
|
+
id TEXT PRIMARY KEY,
|
|
1669
|
+
conversation_id TEXT NOT NULL,
|
|
1670
|
+
sender_type TEXT NOT NULL,
|
|
1671
|
+
sender_id TEXT,
|
|
1672
|
+
content TEXT NOT NULL,
|
|
1673
|
+
created_at INTEGER NOT NULL,
|
|
1674
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id)
|
|
1675
|
+
);
|
|
1676
|
+
|
|
1677
|
+
CREATE TABLE IF NOT EXISTS launch_snapshots (
|
|
1678
|
+
id TEXT PRIMARY KEY,
|
|
1679
|
+
bot_id TEXT NOT NULL,
|
|
1680
|
+
created_at INTEGER NOT NULL,
|
|
1681
|
+
hash TEXT NOT NULL,
|
|
1682
|
+
snapshot TEXT NOT NULL,
|
|
1683
|
+
FOREIGN KEY (bot_id) REFERENCES bots(id)
|
|
1684
|
+
);
|
|
1685
|
+
|
|
1686
|
+
CREATE INDEX IF NOT EXISTS idx_messages_conversation ON messages(conversation_id, created_at);
|
|
1687
|
+
CREATE INDEX IF NOT EXISTS idx_snapshots_bot ON launch_snapshots(bot_id, created_at DESC);
|
|
1688
|
+
|
|
1689
|
+
CREATE TABLE IF NOT EXISTS mcp_servers (
|
|
1690
|
+
id TEXT PRIMARY KEY,
|
|
1691
|
+
name TEXT NOT NULL,
|
|
1692
|
+
command TEXT NOT NULL,
|
|
1693
|
+
args TEXT NOT NULL,
|
|
1694
|
+
created_at INTEGER NOT NULL
|
|
1695
|
+
);
|
|
1696
|
+
|
|
1697
|
+
CREATE TABLE IF NOT EXISTS draft_actions (
|
|
1698
|
+
message_id TEXT PRIMARY KEY,
|
|
1699
|
+
status TEXT NOT NULL,
|
|
1700
|
+
recipient TEXT,
|
|
1701
|
+
acted_at INTEGER NOT NULL
|
|
1702
|
+
);
|
|
1703
|
+
|
|
1704
|
+
CREATE TABLE IF NOT EXISTS approvals (
|
|
1705
|
+
conversation_id TEXT NOT NULL,
|
|
1706
|
+
code TEXT NOT NULL,
|
|
1707
|
+
message_id TEXT,
|
|
1708
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
1709
|
+
created_at INTEGER NOT NULL,
|
|
1710
|
+
resolved_at INTEGER,
|
|
1711
|
+
PRIMARY KEY (conversation_id, code)
|
|
1712
|
+
);
|
|
1713
|
+
|
|
1714
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
1715
|
+
id TEXT PRIMARY KEY,
|
|
1716
|
+
bot_id TEXT NOT NULL,
|
|
1717
|
+
fact TEXT NOT NULL,
|
|
1718
|
+
created_at INTEGER NOT NULL,
|
|
1719
|
+
FOREIGN KEY (bot_id) REFERENCES bots(id)
|
|
1720
|
+
);
|
|
1721
|
+
|
|
1722
|
+
CREATE INDEX IF NOT EXISTS idx_memories_bot ON memories(bot_id, created_at);
|
|
1723
|
+
|
|
1724
|
+
CREATE TABLE IF NOT EXISTS one_shots (
|
|
1725
|
+
id TEXT PRIMARY KEY,
|
|
1726
|
+
conversation_id TEXT NOT NULL,
|
|
1727
|
+
bot_id TEXT NOT NULL,
|
|
1728
|
+
due_at INTEGER NOT NULL,
|
|
1729
|
+
fired INTEGER NOT NULL DEFAULT 0,
|
|
1730
|
+
created_at INTEGER NOT NULL
|
|
1731
|
+
);
|
|
1732
|
+
|
|
1733
|
+
CREATE TABLE IF NOT EXISTS routines (
|
|
1734
|
+
id TEXT PRIMARY KEY,
|
|
1735
|
+
conversation_id TEXT NOT NULL,
|
|
1736
|
+
bot_id TEXT NOT NULL,
|
|
1737
|
+
word TEXT NOT NULL,
|
|
1738
|
+
next_due_at INTEGER NOT NULL,
|
|
1739
|
+
every_ms INTEGER NOT NULL,
|
|
1740
|
+
created_at INTEGER NOT NULL
|
|
1741
|
+
);
|
|
1742
|
+
|
|
1743
|
+
CREATE TABLE IF NOT EXISTS pending_questions (
|
|
1744
|
+
id TEXT PRIMARY KEY,
|
|
1745
|
+
conversation_id TEXT NOT NULL,
|
|
1746
|
+
bot_id TEXT NOT NULL,
|
|
1747
|
+
question TEXT NOT NULL,
|
|
1748
|
+
task_message_id TEXT,
|
|
1749
|
+
task_content TEXT,
|
|
1750
|
+
question_message_id TEXT,
|
|
1751
|
+
answer_message_id TEXT,
|
|
1752
|
+
answer TEXT,
|
|
1753
|
+
status TEXT NOT NULL DEFAULT 'asked',
|
|
1754
|
+
created_at INTEGER NOT NULL,
|
|
1755
|
+
resolved_at INTEGER,
|
|
1756
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
1757
|
+
FOREIGN KEY (bot_id) REFERENCES bots(id)
|
|
1758
|
+
);
|
|
1759
|
+
|
|
1760
|
+
CREATE INDEX IF NOT EXISTS idx_pending_questions_conversation
|
|
1761
|
+
ON pending_questions(conversation_id, status, created_at);
|
|
1762
|
+
|
|
1763
|
+
CREATE TABLE IF NOT EXISTS approval_requests (
|
|
1764
|
+
id TEXT PRIMARY KEY,
|
|
1765
|
+
conversation_id TEXT NOT NULL,
|
|
1766
|
+
bot_id TEXT,
|
|
1767
|
+
code TEXT NOT NULL,
|
|
1768
|
+
action_type TEXT,
|
|
1769
|
+
action_args TEXT,
|
|
1770
|
+
message_id TEXT,
|
|
1771
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
1772
|
+
result TEXT,
|
|
1773
|
+
created_at INTEGER NOT NULL,
|
|
1774
|
+
resolved_at INTEGER,
|
|
1775
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
1776
|
+
FOREIGN KEY (bot_id) REFERENCES bots(id)
|
|
1777
|
+
);
|
|
1778
|
+
|
|
1779
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_approval_requests_conversation_code
|
|
1780
|
+
ON approval_requests(conversation_id, code);
|
|
1781
|
+
CREATE INDEX IF NOT EXISTS idx_approval_requests_conversation
|
|
1782
|
+
ON approval_requests(conversation_id, status, created_at);
|
|
1783
|
+
`);let eB=["#C6F54A","#F0A05A","#E85D75","#C9A0FF","#F2E36B"],eK="9e363764-e0d5-4fff-8ebd-ccbc46ba0ba5",eP="5fbe32c2-79cb-452e-9d9b-f8c9eb63b99b",ej=e$.prepare("PRAGMA table_info(bots)").all();ej.some(e=>"color"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN color TEXT"),ej.some(e=>"pinned"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN pinned INTEGER NOT NULL DEFAULT 0"),ej.some(e=>"last_seen"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN last_seen INTEGER"),ej.some(e=>"unread"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN unread INTEGER NOT NULL DEFAULT 0"),ej.some(e=>"hidden"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN hidden INTEGER NOT NULL DEFAULT 0"),ej.some(e=>"source_provider"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN source_provider TEXT"),ej.some(e=>"template_id"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN template_id TEXT"),ej.some(e=>"template_url"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN template_url TEXT"),ej.some(e=>"import_schema_version"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN import_schema_version TEXT"),ej.some(e=>"import_operation_id"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN import_operation_id TEXT"),ej.some(e=>"import_timestamp"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN import_timestamp INTEGER"),ej.some(e=>"hermes_profile"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN hermes_profile TEXT"),ej.some(e=>"persistent_runtime"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN persistent_runtime TEXT NOT NULL DEFAULT 'hermes'"),ej.some(e=>"coding_runtime"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN coding_runtime TEXT"),ej.some(e=>"deck_name"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN deck_name TEXT"),ej.some(e=>"working_directory"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN working_directory TEXT"),ej.some(e=>"runtime"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN runtime TEXT"),ej.some(e=>"agent_client"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN agent_client TEXT"),ej.some(e=>"deck_id"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN deck_id TEXT"),ej.some(e=>"needs_deck_reselection"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN needs_deck_reselection INTEGER NOT NULL DEFAULT 0"),ej.some(e=>"agent"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN agent TEXT"),ej.some(e=>"needs_deck_selection"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN needs_deck_selection INTEGER NOT NULL DEFAULT 0");{let e=e$.prepare("SELECT id, agent, runtime, agent_client, persistent_runtime, coding_runtime, deck_id, deck_name, working_directory, needs_deck_reselection, needs_deck_selection FROM bots WHERE agent IS NULL").all(),t=e$.prepare("UPDATE bots SET agent = ?, deck_id = ?, deck_name = ?, working_directory = ?, needs_deck_selection = ? WHERE id = ?");e$.transaction(e=>{for(let n of e){let e=g(n);t.run(e.agent,e.deck_id,e.deck_name,e.working_directory,+!!e.needs_deck_selection,n.id)}})(e)}for(let[e,t]of(ej.some(e=>"avatar_color"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN avatar_color TEXT"),ej.some(e=>"avatar_eyes"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN avatar_eyes TEXT"),ej.some(e=>"avatar_hands"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN avatar_hands TEXT"),ej.some(e=>"avatar_accessory"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN avatar_accessory TEXT"),e$.exec(`
|
|
1784
|
+
CREATE TABLE IF NOT EXISTS runtime_connections (
|
|
1785
|
+
id TEXT PRIMARY KEY,
|
|
1786
|
+
provider TEXT NOT NULL,
|
|
1787
|
+
label TEXT NOT NULL,
|
|
1788
|
+
host TEXT NOT NULL,
|
|
1789
|
+
created_at INTEGER NOT NULL
|
|
1790
|
+
);
|
|
1791
|
+
`),[["runtime_connection_id","TEXT"],["launch_profile","TEXT"],["session_scope_kind","TEXT"],["session_scope_items","TEXT"],["default_workspace","TEXT"],["policy_mode","TEXT"],["allow_new_sessions","INTEGER"],["allow_resume_with_edits","INTEGER"],["home_session_id","TEXT"]]))ej.some(t=>t.name===e)||e$.exec(`ALTER TABLE bots ADD COLUMN ${e} ${t}`);function eY(e,t=Date.now()){let n=y(e);return e$.prepare("INSERT OR IGNORE INTO runtime_connections (id, provider, label, host, created_at) VALUES (?, ?, ?, ?, ?)").run(n,e,w(e),v,t),n}for(let e of a)eY(e,0);e$.transaction(()=>{let e=e$.prepare("SELECT id, agent, deck_id, working_directory, needs_deck_selection, created_at FROM bots WHERE runtime_connection_id IS NULL").all(),t=e$.prepare(`UPDATE bots SET runtime_connection_id = ?, launch_profile = ?, session_scope_kind = ?, session_scope_items = ?,
|
|
1792
|
+
policy_mode = ?, allow_new_sessions = ?, allow_resume_with_edits = ? WHERE id = ?`);for(let n of e){let e=S(n);eY(e.provider,n.created_at),t.run(e.runtime_connection_id,e.launch_profile,e.session_scope_kind,e.session_scope_items,e.policy_mode,e.allow_new_sessions,e.allow_resume_with_edits,n.id)}})(),ej.some(e=>"name_key"===e.name)||e$.exec("ALTER TABLE bots ADD COLUMN name_key TEXT"),e$.exec(`
|
|
1793
|
+
CREATE TABLE IF NOT EXISTS agent_name_migrations (
|
|
1794
|
+
id TEXT PRIMARY KEY,
|
|
1795
|
+
bot_id TEXT NOT NULL,
|
|
1796
|
+
previous_name TEXT NOT NULL,
|
|
1797
|
+
new_name TEXT NOT NULL,
|
|
1798
|
+
name_key TEXT NOT NULL,
|
|
1799
|
+
kept_bot_id TEXT NOT NULL,
|
|
1800
|
+
reason TEXT NOT NULL,
|
|
1801
|
+
created_at INTEGER NOT NULL
|
|
1802
|
+
);
|
|
1803
|
+
`),e$.transaction(()=>{let e=function(e){let t=[...e].sort((e,t)=>e.created_at-t.created_at||(e.id<t.id?-1:+(e.id>t.id))),n=new Map,r=[],i=[];for(let e of t){let t=eW(e.name);if(n.has(t)){r.push(e);continue}n.set(t,e.id),e.name_key!==t&&i.push({id:e.id,name:e.name,name_key:t})}let s=[];for(let e of r){let t=eW(e.name),r=eF(e.name)||"Agent",a=2;for(;n.has(eW(`${r}-${a}`));)a++;let o=`${r}-${a}`,d=eW(o);n.set(d,e.id),i.push({id:e.id,name:o,name_key:d}),s.push({bot_id:e.id,previous_name:e.name,new_name:o,name_key:t,kept_bot_id:n.get(t)})}return{updates:i,renames:s}}(e$.prepare("SELECT id, name, created_at, name_key FROM bots").all());if(0===e.updates.length)return;let t=e$.prepare("UPDATE bots SET name_key = NULL WHERE id = ?");for(let n of e.updates)t.run(n.id);let n=e$.prepare("UPDATE bots SET name = ?, name_key = ? WHERE id = ?");for(let t of e.updates)n.run(t.name,t.name_key,t.id);let r=e$.prepare("INSERT INTO agent_name_migrations (id, bot_id, previous_name, new_name, name_key, kept_bot_id, reason, created_at) VALUES (?, ?, ?, ?, ?, ?, 'duplicate_name', ?)"),i=Date.now();for(let t of e.renames)r.run((0,s.randomUUID)(),t.bot_id,t.previous_name,t.new_name,t.name_key,t.kept_bot_id,i),console.warn(`[botmancers] Agent ${t.bot_id} renamed "${t.previous_name}" -> "${t.new_name}": name already used by Agent ${t.kept_bot_id}.`)})(),e$.exec("CREATE UNIQUE INDEX IF NOT EXISTS idx_bots_name_key ON bots(name_key)"),e$.exec(`
|
|
1804
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_bots_import_operation
|
|
1805
|
+
ON bots(import_operation_id) WHERE import_operation_id IS NOT NULL
|
|
1806
|
+
`),e$.prepare("UPDATE bots SET color = ? WHERE id = ?").run(eB[0],eK),e$.prepare("UPDATE bots SET color = ? WHERE id = ?").run(eB[1],eP);let ez=e$.prepare("SELECT id FROM bots WHERE id NOT IN (?, ?) ORDER BY created_at ASC").all(eK,eP),eJ=e$.prepare("UPDATE bots SET color = ? WHERE id = ?");function eV(e,t){let n=eF(e),r=eW(n),i=e$.prepare("SELECT id FROM bots WHERE name_key = ?").get(r);if(i&&i.id!==t)throw new eM(n,i.id);return{name:n,name_key:r}}function eQ(e,t){try{return t()}catch(t){if(t instanceof Error&&/UNIQUE constraint failed: bots\.name_key/.test(t.message)){let t=e$.prepare("SELECT id FROM bots WHERE name_key = ?").get(eW(e));throw new eM(e,t?.id??null)}throw t}}function eZ(){return eB[e$.prepare("SELECT COUNT(*) AS n FROM bots").get().n%eB.length]}ez.forEach((e,t)=>{eJ.run(eB[(t+2)%eB.length],e.id)});let e0=e$.prepare("PRAGMA table_info(messages)").all();e0.some(e=>"handoff_targets"===e.name)||e$.exec("ALTER TABLE messages ADD COLUMN handoff_targets TEXT"),e$.prepare("PRAGMA table_info(groups)").all().some(e=>"owner_bot_id"===e.name)||e$.exec("ALTER TABLE groups ADD COLUMN owner_bot_id TEXT"),e$.prepare("PRAGMA table_info(launch_snapshots)").all().some(e=>"transport"===e.name)||e$.exec("ALTER TABLE launch_snapshots ADD COLUMN transport TEXT NOT NULL DEFAULT 'hermes-gateway'");let e1=e$.prepare("PRAGMA table_info(conversations)").all();e1.some(e=>"origin_kind"===e.name)||e$.exec("ALTER TABLE conversations ADD COLUMN origin_kind TEXT"),e1.some(e=>"origin_id"===e.name)||e$.exec("ALTER TABLE conversations ADD COLUMN origin_id TEXT"),e0.some(e=>"sender_kind"===e.name)||e$.exec("ALTER TABLE messages ADD COLUMN sender_kind TEXT"),e0.some(e=>"request_id"===e.name)||e$.exec("ALTER TABLE messages ADD COLUMN request_id TEXT"),e$.exec(`
|
|
1807
|
+
CREATE TABLE IF NOT EXISTS conversation_participants (
|
|
1808
|
+
conversation_id TEXT NOT NULL,
|
|
1809
|
+
participant_kind TEXT NOT NULL,
|
|
1810
|
+
participant_id TEXT NOT NULL,
|
|
1811
|
+
joined_at INTEGER NOT NULL,
|
|
1812
|
+
PRIMARY KEY (conversation_id, participant_kind, participant_id),
|
|
1813
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id)
|
|
1814
|
+
);
|
|
1815
|
+
`),eg(e$);let e4=eO(e$);!function(e){e.prepare("SELECT * FROM work_requests WHERE id = ?"),e.prepare("SELECT * FROM work_attempts WHERE id = ?"),e.prepare("SELECT * FROM engine_events WHERE request_id = ? ORDER BY sequence ASC"),e.prepare("SELECT sequence FROM conversation_projection_cursors WHERE request_id = ?"),e.prepare(`
|
|
1816
|
+
INSERT INTO conversation_projection_cursors (request_id, sequence) VALUES (?, ?)
|
|
1817
|
+
ON CONFLICT (request_id) DO UPDATE SET sequence = excluded.sequence WHERE excluded.sequence > sequence
|
|
1818
|
+
`),e.prepare(`
|
|
1819
|
+
INSERT OR IGNORE INTO conversation_events (
|
|
1820
|
+
id, conversation_id, engine_event_id, part, request_id, request_sequence, attempt_id, wake_id,
|
|
1821
|
+
kind, state, text, data, sort_at, request_created_at, created_at
|
|
1822
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1823
|
+
`)}(e$);let e2=(e$.exec(`
|
|
1824
|
+
CREATE TABLE IF NOT EXISTS service_audit_events (
|
|
1825
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1826
|
+
at INTEGER NOT NULL,
|
|
1827
|
+
principal TEXT NOT NULL CHECK (length(principal) BETWEEN 1 AND 200),
|
|
1828
|
+
operation TEXT NOT NULL CHECK (length(operation) BETWEEN 1 AND 64),
|
|
1829
|
+
capability TEXT NOT NULL CHECK (length(capability) BETWEEN 1 AND 64),
|
|
1830
|
+
target_kind TEXT NOT NULL CHECK (target_kind IN ('grants', 'agent', 'session', 'conversation', 'exchange', 'request')),
|
|
1831
|
+
target_ref TEXT CHECK (target_ref IS NULL OR length(target_ref) <= 128),
|
|
1832
|
+
agent_id TEXT CHECK (agent_id IS NULL OR length(agent_id) <= 128),
|
|
1833
|
+
outcome TEXT NOT NULL CHECK (outcome IN ('allowed', 'denied', 'rejected', 'error')),
|
|
1834
|
+
code TEXT CHECK (code IS NULL OR length(code) <= 64)
|
|
1835
|
+
);
|
|
1836
|
+
CREATE INDEX IF NOT EXISTS idx_service_audit_principal ON service_audit_events(principal, id);
|
|
1837
|
+
CREATE TRIGGER IF NOT EXISTS trg_service_audit_no_update BEFORE UPDATE ON service_audit_events
|
|
1838
|
+
BEGIN
|
|
1839
|
+
SELECT RAISE(ABORT, 'service_audit_events are append-only');
|
|
1840
|
+
END;
|
|
1841
|
+
CREATE TRIGGER IF NOT EXISTS trg_service_audit_no_delete BEFORE DELETE ON service_audit_events
|
|
1842
|
+
BEGIN
|
|
1843
|
+
SELECT RAISE(ABORT, 'service_audit_events are append-only');
|
|
1844
|
+
END;
|
|
1845
|
+
`),t=e$.prepare(`
|
|
1846
|
+
INSERT INTO service_audit_events (at, principal, operation, capability, target_kind, target_ref, agent_id, outcome, code)
|
|
1847
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
1848
|
+
`),{append(e){let n=`${e.principal.kind}:${eD(e.principal.id)??"[invalid]"}`;t.run(e.at??Date.now(),n.slice(0,200),eU(e.operation,"unknown"),eU(e.capability,"none"),e.targetKind,eD(e.targetRef),eD(e.agentId),e.outcome,e.code?eU(e.code,"unknown"):null)},list(e={}){let t=Math.min(Math.max(1,e.limit??50),500);return e.principal?e$.prepare("SELECT * FROM service_audit_events WHERE principal = ? ORDER BY id DESC LIMIT ?").all(e.principal,t):e$.prepare("SELECT * FROM service_audit_events ORDER BY id DESC LIMIT ?").all(t)}}),e3="person",e6="local-owner",e9=e$.prepare("INSERT OR IGNORE INTO conversation_participants (conversation_id, participant_kind, participant_id, joined_at) VALUES (?, ?, ?, ?)");function e5(e,t,n){for(let r of(e$.prepare("UPDATE conversations SET origin_kind = ?, origin_id = ? WHERE id = ? AND origin_kind IS NULL").run(e3,e6,e),e9.run(e,e3,e6,n),t))e9.run(e,"bot",r,n)}e$.transaction(()=>{e$.exec("UPDATE messages SET sender_kind = 'person' WHERE sender_kind IS NULL AND sender_type = 'user'"),e$.exec("UPDATE messages SET sender_kind = 'bot' WHERE sender_kind IS NULL AND sender_type = 'bot'");let e=e$.prepare("SELECT id, type, bot_id, group_id, created_at FROM conversations WHERE origin_kind IS NULL AND type IN ('bot', 'group')").all(),t=e$.prepare("SELECT bot_id FROM group_members WHERE group_id = ?");for(let n of e){let e="bot"===n.type?n.bot_id?[n.bot_id]:[]:n.group_id?t.all(n.group_id).map(e=>e.bot_id):[];e5(n.id,e,n.created_at)}})();let e8={create:(e,t)=>{let n=eV(e.name),r={id:t?.id||(0,s.randomUUID)(),...e,...n,color:eZ(),created_at:t?.created_at??Date.now()};r.agent=r.agent||d,r.deck_id=r.deck_id||null,r.needs_deck_selection=!r.deck_id||r.needs_deck_selection?1:0;let i=S({...r,needs_deck_selection:r.needs_deck_selection});r.runtime_connection_id||(r.runtime_connection_id=eY(i.provider,r.created_at)),void 0===r.launch_profile&&(r.launch_profile=i.launch_profile),"direct"===r.launch_profile&&(r.deck_id=null,r.working_directory=null,r.needs_deck_selection=0),r.session_scope_kind||(r.session_scope_kind=i.session_scope_kind,r.session_scope_items=i.session_scope_items),r.policy_mode||(r.policy_mode=i.policy_mode,r.allow_new_sessions=i.allow_new_sessions,r.allow_resume_with_edits=i.allow_resume_with_edits),eQ(r.name,()=>e$.prepare(`INSERT INTO bots (id, name, name_key, title, description, avatar, color, hermes_profile, agent, deck_id, deck_name, working_directory, needs_deck_selection,
|
|
1849
|
+
runtime_connection_id, launch_profile, session_scope_kind, session_scope_items, default_workspace, policy_mode, allow_new_sessions, allow_resume_with_edits, home_session_id,
|
|
1850
|
+
avatar_color, avatar_eyes, avatar_hands, avatar_accessory, created_at)
|
|
1851
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.id,r.name,r.name_key,r.title,r.description,r.avatar||null,r.color,r.hermes_profile||null,r.agent,r.deck_id,r.deck_name||null,r.working_directory||null,r.needs_deck_selection,r.runtime_connection_id,r.launch_profile??null,r.session_scope_kind,r.session_scope_items??"[]",r.default_workspace||null,r.policy_mode,+!!r.allow_new_sessions,+!!r.allow_resume_with_edits,null,r.avatar_color||null,r.avatar_eyes||null,r.avatar_hands||null,r.avatar_accessory||null,r.created_at));let a=(0,s.randomUUID)();return e$.prepare("INSERT INTO conversations (id, type, bot_id, created_at) VALUES (?, ?, ?, ?)").run(a,"bot",r.id,r.created_at),e5(a,[r.id],r.created_at),r},createFromImport:(e,t)=>{let n=eV(e.name),r={id:(0,s.randomUUID)(),...e,...n,color:eZ(),created_at:Date.now(),agent:d,deck_id:null,deck_name:null,working_directory:null,needs_deck_selection:1,source_provider:t.source_provider,template_id:t.template_id,template_url:t.template_url,import_schema_version:t.import_schema_version,import_operation_id:t.import_operation_id,import_timestamp:t.import_timestamp},i=S(r);Object.assign(r,{runtime_connection_id:eY(i.provider,r.created_at),launch_profile:null,session_scope_kind:i.session_scope_kind,session_scope_items:i.session_scope_items,policy_mode:i.policy_mode,allow_new_sessions:i.allow_new_sessions,allow_resume_with_edits:i.allow_resume_with_edits}),eQ(r.name,()=>e$.prepare(`INSERT INTO bots (
|
|
1852
|
+
id, name, name_key, title, description, avatar, color, created_at,
|
|
1853
|
+
source_provider, template_id, template_url, import_schema_version,
|
|
1854
|
+
import_operation_id, import_timestamp,
|
|
1855
|
+
agent, deck_id, deck_name, working_directory,
|
|
1856
|
+
needs_deck_selection,
|
|
1857
|
+
runtime_connection_id, launch_profile, session_scope_kind, session_scope_items,
|
|
1858
|
+
policy_mode, allow_new_sessions, allow_resume_with_edits
|
|
1859
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(r.id,r.name,r.name_key,r.title,r.description,r.avatar||null,r.color,r.created_at,r.source_provider,r.template_id,r.template_url,r.import_schema_version,r.import_operation_id,r.import_timestamp,r.agent,r.deck_id,r.deck_name,r.working_directory,r.needs_deck_selection,r.runtime_connection_id,r.launch_profile,r.session_scope_kind,r.session_scope_items,r.policy_mode,r.allow_new_sessions,r.allow_resume_with_edits));let a=(0,s.randomUUID)();return e$.prepare("INSERT INTO conversations (id, type, bot_id, created_at) VALUES (?, ?, ?, ?)").run(a,"bot",r.id,r.created_at),e5(a,[r.id],r.created_at),r},getByImportOperationId:e=>e$.prepare("SELECT * FROM bots WHERE import_operation_id = ?").get(e),getAll:()=>e$.prepare("SELECT * FROM bots ORDER BY created_at DESC").all(),getById:e=>e$.prepare("SELECT * FROM bots WHERE id = ?").get(e),setAvatar:(e,t)=>{e$.prepare("UPDATE bots SET avatar = ? WHERE id = ?").run(t,e)},getByName:e=>{let t=eW(e);if(t)return e$.prepare("SELECT * FROM bots WHERE name_key = ?").get(t)},updateIdentity:(e,t,n,r)=>{let i=eV(t,e);eQ(i.name,()=>e$.prepare("UPDATE bots SET name = ?, name_key = ?, title = ?, description = ? WHERE id = ?").run(i.name,i.name_key,n,r,e))},setPinned:(e,t)=>{e$.prepare("UPDATE bots SET pinned = ? WHERE id = ?").run(+!!t,e)},setHidden:(e,t)=>{e$.prepare("UPDATE bots SET hidden = ? WHERE id = ?").run(+!!t,e)},setHermesProfile:(e,t)=>{let n=t&&t.trim()?t.trim():null;e$.prepare("UPDATE bots SET hermes_profile = ? WHERE id = ?").run(n,e)},updateRegistration:(e,t,n)=>{let r=e8.getById(e);if(!r)return;let i=A(n),s="agent_deck"===n.launch_profile&&n.deck_id?null:r.deck_name??null;e$.prepare(`UPDATE bots SET agent = ?, deck_name = ?, runtime_connection_id = ?, launch_profile = ?, deck_id = ?, working_directory = ?,
|
|
1860
|
+
session_scope_kind = ?, session_scope_items = ?, default_workspace = ?, policy_mode = ?, allow_new_sessions = ?,
|
|
1861
|
+
allow_resume_with_edits = ?, home_session_id = ?, needs_deck_selection = ? WHERE id = ?`).run(t,s,i.runtime_connection_id,i.launch_profile,i.deck_id,i.working_directory,i.session_scope_kind,i.session_scope_items,i.default_workspace,i.policy_mode,i.allow_new_sessions,i.allow_resume_with_edits,i.home_session_id,i.needs_deck_selection,e)},updateAgentSelection:(e,t)=>{var n;let r,i=e8.getById(e);if(!i)return;let s=h(i,t),o=void 0!==t.deck_id?"agent_deck":i.launch_profile??null,d=i.runtime_connection_id?(n=i.runtime_connection_id,(r=e$.prepare("SELECT * FROM runtime_connections WHERE id = ?").get(n))&&a.includes(r.provider)?r:void 0):void 0,u=d&&d.provider===s.agent?d.id:eY(s.agent);e$.prepare("UPDATE bots SET agent = ?, deck_id = ?, deck_name = ?, working_directory = ?, needs_deck_selection = ?, launch_profile = ?, runtime_connection_id = ? WHERE id = ?").run(s.agent,"direct"===o?null:s.deck_id,s.deck_name,"direct"===o?null:s.working_directory,"direct"===o?0:+!!s.needs_deck_selection,o,u,e)},updateAvatarConfig:(e,t)=>{let n=e8.getById(e);if(!n)return;let r=(e,t)=>void 0===e?t||null:e&&String(e).trim()?String(e).trim():null;e$.prepare("UPDATE bots SET avatar_color = ?, avatar_eyes = ?, avatar_hands = ?, avatar_accessory = ? WHERE id = ?").run(r(t.avatar_color,n.avatar_color),r(t.avatar_eyes,n.avatar_eyes),r(t.avatar_hands,n.avatar_hands),r(t.avatar_accessory,n.avatar_accessory),e)},touchSeen:()=>{e$.prepare("UPDATE bots SET last_seen = ?").run(Date.now())},markUnread:e=>{e$.prepare("UPDATE bots SET unread = 1 WHERE id = ?").run(e)},markRead:e=>{e$.prepare("UPDATE bots SET unread = 0 WHERE id = ?").run(e)},remove:e=>{e8.removeMany([e])},deletionPreview:e=>{var t;let n=new Set(e),r=[],i=[],s=[],a=new Set(te());for(let t of e){let e=e8.getById(t);if(!e){i.push(t);continue}r.push({id:e.id,name:e.name}),b(e.name)?s.push({id:e.id,name:e.name,reason:"chief"}):a.has(e.id)&&s.push({id:e.id,name:e.name,reason:"active"})}return{agents:r,groups:0===(t=n).size?[]:e$.prepare(`SELECT DISTINCT g.id, g.name, g.owner_bot_id, g.created_at FROM groups g
|
|
1862
|
+
JOIN group_members gm ON gm.group_id = g.id
|
|
1863
|
+
WHERE gm.bot_id IN (${[...t].map(()=>"?").join(", ")})
|
|
1864
|
+
ORDER BY g.created_at ASC, g.id ASC`).all(...t).map(e=>{let n=e$.prepare(`SELECT b.id, b.name FROM bots b JOIN group_members gm ON gm.bot_id = b.id
|
|
1865
|
+
WHERE gm.group_id = ? ORDER BY b.created_at ASC, b.id ASC`).all(e.id).filter(e=>!t.has(e.id));return n.length<2?{id:e.id,name:e.name,outcome:"removed",remaining:n.length,newOwner:null}:e.owner_bot_id&&t.has(e.owner_bot_id)?{id:e.id,name:e.name,outcome:"reassigned",remaining:n.length,newOwner:n[0]}:{id:e.id,name:e.name,outcome:"shrunk",remaining:n.length,newOwner:null}}),missing:i,blocked:s}},removeMany:(e,t)=>e$.transaction(()=>{let n=e8.deletionPreview(e);if(n.missing.length>0||n.blocked.length>0)throw new e7(n);let r=new Set(e);for(let e of n.groups){if("removed"===e.outcome){var i=e.id;for(let e of e$.prepare("SELECT id FROM conversations WHERE group_id = ?").all(i))tr(e.id);e$.prepare("DELETE FROM group_members WHERE group_id = ?").run(i),e$.prepare("DELETE FROM groups WHERE id = ?").run(i);continue}let t=e$.prepare("SELECT id FROM conversations WHERE group_id = ?").all(e.id).map(e=>e.id);for(let n of r)for(let r of(e$.prepare("DELETE FROM group_members WHERE group_id = ? AND bot_id = ?").run(e.id,n),t))e$.prepare("DELETE FROM conversation_participants WHERE conversation_id = ? AND participant_kind = 'bot' AND participant_id = ?").run(r,n);e.newOwner&&e$.prepare("UPDATE groups SET owner_bot_id = ? WHERE id = ?").run(e.newOwner.id,e.id)}for(let n of e){for(let e of e$.prepare("SELECT id FROM conversations WHERE bot_id = ?").all(n))tr(e.id);eq(e$,n),tn("bot_id",n),e$.prepare("DELETE FROM launch_snapshots WHERE bot_id = ?").run(n),e$.prepare("DELETE FROM group_members WHERE bot_id = ?").run(n),e$.prepare("DELETE FROM conversation_participants WHERE participant_kind = 'bot' AND participant_id = ? AND conversation_id IN (SELECT id FROM conversations WHERE type = 'group')").run(n),e$.prepare("DELETE FROM memories WHERE bot_id = ?").run(n),e$.prepare("DELETE FROM one_shots WHERE bot_id = ?").run(n),e$.prepare("DELETE FROM routines WHERE bot_id = ?").run(n),e$.prepare("DELETE FROM pending_questions WHERE bot_id = ?").run(n),e$.prepare("DELETE FROM approval_requests WHERE bot_id = ?").run(n),e$.prepare("DELETE FROM wake_targets WHERE target_bot_id = ?").run(n),e$.prepare("DELETE FROM bots WHERE id = ?").run(n),t?.onAgentDeleted?.(n)}return n})(),managementRows:()=>{let e=e$.prepare("SELECT * FROM bots ORDER BY created_at DESC, id ASC").all(),t=new Set(te()),n=new Map,r=e=>{for(let t of e)t.id&&t.at&&(n.get(t.id)??0)<t.at&&n.set(t.id,t.at)};return r(e$.prepare("SELECT c.bot_id AS id, MAX(m.created_at) AS at FROM messages m JOIN conversations c ON c.id = m.conversation_id WHERE c.type = 'bot' GROUP BY c.bot_id").all()),r(e$.prepare("SELECT sender_id AS id, MAX(created_at) AS at FROM messages WHERE sender_type = 'bot' AND sender_id IS NOT NULL GROUP BY sender_id").all()),e.map(e=>({bot:e,last_activity:n.get(e.id)??null,blocked:b(e.name)?"chief":t.has(e.id)?"active":null}))}};class e7 extends Error{preview;constructor(e){super(e.missing.length>0?"Agent not found":"Some agents cannot be deleted"),this.preview=e}}function te(){return e$.prepare(`
|
|
1866
|
+
SELECT DISTINCT target_agent_id AS bot_id FROM work_requests
|
|
1867
|
+
WHERE (executor <> 'dispatcher' AND state IN ('queued', 'running'))
|
|
1868
|
+
OR (executor = 'dispatcher' AND state = 'running' AND json_extract(policy_snapshot, '$.surface') = 'ui')
|
|
1869
|
+
`).all().map(e=>e.bot_id)}function tt(){return new Set(e$.prepare("SELECT name FROM sqlite_master WHERE type = 'table' AND name IN ('legacy_agent_requests_archive', 'legacy_agent_request_events_archive', 'legacy_processing_queue_archive')").all().map(e=>e.name))}function tn(e,t){tt().has("legacy_processing_queue_archive")&&e$.prepare(`DELETE FROM legacy_processing_queue_archive WHERE ${e} = ?`).run(t)}function tr(e){let t;eb(e$,e),e$.prepare("DELETE FROM draft_actions WHERE message_id IN (SELECT id FROM messages WHERE conversation_id = ?)").run(e),t=tt(),tn("conversation_id",e),t.has("legacy_agent_request_events_archive")&&t.has("legacy_agent_requests_archive")&&e$.prepare("DELETE FROM legacy_agent_request_events_archive WHERE request_id IN (SELECT id FROM legacy_agent_requests_archive WHERE conversation_id = ?)").run(e),t.has("legacy_agent_requests_archive")&&e$.prepare("DELETE FROM legacy_agent_requests_archive WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM messages WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM pending_questions WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM approvals WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM approval_requests WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM one_shots WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM routines WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM wake_targets WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM conversation_participants WHERE conversation_id = ?").run(e),e$.prepare("DELETE FROM conversations WHERE id = ?").run(e)}e$.exec(`
|
|
1870
|
+
CREATE TABLE IF NOT EXISTS wake_targets (
|
|
1871
|
+
id TEXT PRIMARY KEY,
|
|
1872
|
+
conversation_id TEXT NOT NULL,
|
|
1873
|
+
source_bot_id TEXT,
|
|
1874
|
+
source_message_id TEXT,
|
|
1875
|
+
requested_target TEXT NOT NULL,
|
|
1876
|
+
target_bot_id TEXT NOT NULL,
|
|
1877
|
+
target_name_snapshot TEXT NOT NULL,
|
|
1878
|
+
created_at INTEGER NOT NULL,
|
|
1879
|
+
FOREIGN KEY (conversation_id) REFERENCES conversations(id),
|
|
1880
|
+
FOREIGN KEY (target_bot_id) REFERENCES bots(id)
|
|
1881
|
+
);
|
|
1882
|
+
|
|
1883
|
+
CREATE INDEX IF NOT EXISTS idx_wake_targets_conversation
|
|
1884
|
+
ON wake_targets(conversation_id, created_at);
|
|
1885
|
+
CREATE INDEX IF NOT EXISTS idx_wake_targets_target
|
|
1886
|
+
ON wake_targets(target_bot_id, created_at);
|
|
1887
|
+
`),e$.exec(`
|
|
1888
|
+
CREATE TABLE IF NOT EXISTS workspace_settings (
|
|
1889
|
+
key TEXT PRIMARY KEY,
|
|
1890
|
+
value TEXT NOT NULL,
|
|
1891
|
+
updated_at INTEGER NOT NULL
|
|
1892
|
+
);
|
|
1893
|
+
`),e.s(["bots",0,e8,"default",0,e$,"engine",0,e4,"resolveWakeTarget",0,function(e){let t=eW(e);if(!t)return{ok:!1,reason:"not_found",requested:String(e??"")};let n=e$.prepare("SELECT id, name FROM bots WHERE name_key = ? LIMIT 2").all(t);return 0===n.length?{ok:!1,reason:"not_found",requested:e}:n.length>1?{ok:!1,reason:"ambiguous",requested:e}:{ok:!0,agentId:n[0].id,displayName:n[0].name}},"serviceAudit",0,e2,"workspaceSettings",0,{get:e=>{let t=e$.prepare("SELECT value FROM workspace_settings WHERE key = ?").get(e);return t?t.value:null},set:(e,t)=>{e$.prepare("INSERT INTO workspace_settings (key, value, updated_at) VALUES (?, ?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at").run(e,t,Date.now())},clearForTests:()=>{e$.prepare("DELETE FROM workspace_settings").run()}}],99904);let ti=["read_only","workspace_write"];function ts(e){let t;if(!e||"object"!=typeof e)return null;let n=e=>"number"==typeof e&&Number.isInteger(e)&&e>=0?e:null;return{input_tokens:n(e.input_tokens),output_tokens:n(e.output_tokens),..."cached_input_tokens"in e?{cached_input_tokens:n(e.cached_input_tokens)}:{},cost_usd:"number"==typeof(t=e.cost_usd)&&Number.isFinite(t)&&t>=0?t:null}}function ta(e,t){return{ok:!1,error:{code:e,message:t.slice(0,500)}}}function to(e){return{ok:!0,value:e}}let td=new Map,tu=new Map,tl=new Map;function t_(e,t){tl.set(e,t)}e.s(["normalizeCapabilities",0,function(e){let t=Number(e?.max_page_size);return{list:!0===e?.list,search:!0===e?.search,read:!0===e?.read,resume:!0===e?.resume,start:!0===e?.start,cancel:!0===e?.cancel,usage:!0===e?.usage,authorities:ti.filter(t=>Array.isArray(e?.authorities)&&e.authorities.includes(t)),max_page_size:Number.isInteger(t)&&t>0?Math.min(t,100):25}},"normalizeUsage",0,ts,"providerError",0,ta,"providerOk",0,to,"registerBuiltinSessionProvider",0,t_,"registerSessionProvider",0,function(e,t){let n="connectionId"in e?td:tu,r="connectionId"in e?e.connectionId:e.provider;t?n.set(r,t):n.delete(r)},"sessionProviderFor",0,function(e){if(!e)return null;let t=td.get(e.id)??tu.get(e.provider)??tl.get(e.provider);return t?t(e):null}],74455);var tc=e.i(33405);let tE="Botmancers-Session-Context",tp="BOTMANCERS_SESSION_CONTEXT",tm="BOTMANCERS_SESSION_CONTEXT_TOKEN",tf="botmancers",tT="botmancers_share_current_session",tg=`mcp__${tf}__${tT}`;function th(e){let t={};for(let[n,r]of Object.entries(e))void 0!==r&&n!==tp&&n!==tm&&(t[n]=r);return t}let tN={enabled_tools:[tT],tools:{[tT]:{approval_mode:"approve"}}};function tR(e){return{mcp_servers:{[tf]:{url:e.url,http_headers:{[tE]:e.token},...tN}}}}var tv=e.i(46786);let tk=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function ty(e){return"string"==typeof e&&tk.test(e)}function tw(e){return e.replace(/[^a-zA-Z0-9]/g,"-")}function tL(e){return i.default.join(e,"projects")}function tO(e){try{return r.default.readdirSync(e)}catch{return[]}}function tI(e){let t=new Set([tw(e.replace(/\/+$/,""))]);try{t.add(tw(r.default.realpathSync(e)))}catch{}return[...t]}function tA(e,t){if(!ty(t))return null;for(let n of tO(tL(e))){let s=i.default.join(tL(e),n,`${t}.jsonl`);try{if(r.default.statSync(s).isFile())return s}catch{}}return null}function tS(e){let t;try{t=r.default.readFileSync(e,"utf8")}catch{return null}let n=[],i=0;for(let e of t.split("\n"))if(e.trim())try{let t=JSON.parse(e);t&&"object"==typeof t&&!Array.isArray(t)?n.push(t):i++}catch{i++}return{records:n,malformed:i}}function tb(e){let t="string"==typeof e.timestamp?Date.parse(e.timestamp):NaN;return Number.isFinite(t)?t:null}function tq(e){let t=e.message;if(!t||"object"!=typeof t)return null;let n=t.content;return"string"==typeof n||Array.isArray(n)?n:null}function tC(e){return("user"===e.type||"assistant"===e.type)&&!0!==e.isSidechain&&!0!==e.isMeta}function tx(e){let t=tS(e.file);if(!t)return null;let{records:n,malformed:r}=t,i=null,s=null,a=null,o=null,d=null,u=null,l=null,_=0;for(let t of n){if(void 0!==t.sessionId&&t.sessionId!==e.id)continue;null===i&&"string"==typeof t.cwd&&t.cwd.startsWith("/")&&(i=t.cwd),"string"==typeof t.version&&(l=t.version);let n=tb(t);null!==n&&(d=null===d?n:Math.min(d,n),u=null===u?n:Math.max(u,n)),"custom-title"===t.type&&"string"==typeof t.customTitle&&(s=t.customTitle),"ai-title"===t.type&&"string"==typeof t.aiTitle&&(a=t.aiTitle),"summary"===t.type&&"string"==typeof t.summary&&(o=t.summary),tC(t)&&_++}return null===i?null:{id:e.id,workspace:i,title:s??a??o??function(e){for(let t of e){if("user"!==t.type||!tC(t))continue;let e=tq(t),n="string"==typeof e?e:Array.isArray(e)?e.map(e=>e&&"object"==typeof e&&"text"===e.type?String(e.text??""):"").join(""):"";if(n.trim()&&!n.trim().startsWith("<"))return n.trim()}return null}(n),created_at:d,updated_at:u??Math.floor(e.mtime_ms),messages:_,claude_code_version:l,malformed:r}}function tD(e){try{let t=JSON.parse(r.default.readFileSync(i.default.join(e,"settings.json"),"utf8")),n=Number(t.cleanupPeriodDays);return Number.isFinite(n)&&n>0?n:30}catch{return 30}}function tU(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function tF(e){let{events:t,malformed:n}=function(e){let t=[],n=0;for(let r of(e.endsWith("\n")?e:e.slice(0,e.lastIndexOf("\n")+1)).split("\n"))if(r.trim())try{let e=JSON.parse(r);tU(e)&&"string"==typeof e.type?t.push(e):n++}catch{n++}return{events:t,malformed:n}}(e),r={session_id:null,claude_code_version:null,result:null,rate_limit_rejected:!1,malformed:n};for(let e of t)"system"===e.type&&"init"===e.subtype&&null===r.session_id?("string"==typeof e.session_id&&(r.session_id=e.session_id),"string"==typeof e.claude_code_version&&(r.claude_code_version=e.claude_code_version)):"result"===e.type&&null===r.result?r.result=e:"rate_limit_event"===e.type&&tU(e.rate_limit_info)&&"rejected"===e.rate_limit_info.status&&(r.rate_limit_rejected=!0);return r}let tW=e=>"number"==typeof e&&Number.isInteger(e)&&e>=0?e:null,tM=/no conversation found/i,tH=/not logged in|please run \/login|\/login|invalid api key|authentication|unauthori[sz]ed|oauth token|credentials? (?:expired|missing|invalid)/i,tX=/usage limit|rate limit|limit reached|quota|credit balance/i;function tG(e){return!0!==e.is_error&&"success"===e.subtype}function t$(e,t){let n=function(e){let t=[];if(Array.isArray(e.errors))for(let n of e.errors)"string"==typeof n&&t.push(n);return!0===e.is_error&&"string"==typeof e.result&&t.push(e.result),t.join("\n").slice(0,2e3)}(e),r="number"==typeof e.api_error_status?e.api_error_status:null,i=Array.isArray(e.permission_denials)?e.permission_denials.length:0;return{code:tM.test(n)?"session_missing":401===r||403===r||tH.test(n)?"auth_required":429===r||t.rate_limit_rejected||tX.test(n)?"usage_limit":i>0?"permission_denied":"runtime_error",message:n||`Claude Code reported ${String(e.subtype??"an error")}.`}}let tB="2.1.0",tK={read_only:{permission_mode:"dontAsk",tools:["Read","Glob","Grep"]},workspace_write:{permission_mode:"acceptEdits",tools:["Read","Glob","Grep","Edit","Write","NotebookEdit"]}},tP={list:!0,search:!0,read:!0,resume:!0,start:!0,cancel:!0,usage:!0,authorities:["read_only","workspace_write"],max_page_size:25},tj=new Map;function tY(e){try{return process.kill(e,0),!0}catch(e){return"EPERM"===e.code}}function tz(e,t=null){let n={};for(let[t,r]of Object.entries(th(e)))/^AGENT_DECK/.test(t)||void 0===r||(n[t]=r);return null!==t&&(n[tp]=t),n}let tJ={session_missing:"not_found",auth_required:"auth_required",permission_denied:"permission_denied",usage_limit:"usage_limit",incompatible_version:"incompatible_version",session_mismatch:"not_resumable",process_exited:"unavailable",cancelled:"cancelled",runtime_error:"unavailable"};e.s(["createClaudeSessionProvider",0,function(e={}){let t=e.env??process.env,n=e.bin??((t.BOTMANCERS_CLAUDE_BIN||"").trim()||"claude"),a=e.configDir??function(e=process.env){let t=(e.CLAUDE_CONFIG_DIR||"").trim();return t?i.default.resolve(t):i.default.join(tv.default.homedir(),".claude")}(t),o=e.stateDir??function(e=process.env){let t=(e.BOTMANCERS_CLAUDE_STATE_DIR||"").trim();return t?i.default.resolve(t):i.default.join(i.default.dirname(i.default.resolve(eX(e))),"claude-provider")}(t),d=e.spawn??tc.spawn,u=e.isPidAlive??tY,l=e.startupTimeoutMs??6e4,_=e.exitGraceMs??1e4,c=e.pollMs??100,E=e.now??Date.now,p=i.default.join(o,"turns"),m=i.default.join(o,"keys"),f=(e,t)=>i.default.join(p,`${e}.${t}`),T=e=>{if(!/^ct-[0-9a-f-]{36}$/.test(e))return null;try{return JSON.parse(r.default.readFileSync(f(e,"json"),"utf8"))}catch{return null}},g=e=>{let t=f(e.id,`json.${process.pid}.tmp`);r.default.writeFileSync(t,JSON.stringify(e)),r.default.renameSync(t,f(e.id,"json"))},h=e=>{try{return r.default.readFileSync(e,"utf8")}catch{return""}};function N(e,t,n,r){return{provider_session_id:e.id,title:e.title,workspace:e.workspace,created_at:e.created_at,updated_at:e.updated_at,lifecycle:null!==e.updated_at&&n-e.updated_at>r?"archived":"open",resumable:e.messages>0,busy:t.has(e.id)}}function R(){return new Set([...function(e,t){let n=new Set,s=i.default.join(e,"sessions");for(let e of tO(s))if(/^\d+\.json$/.test(e))try{let a=JSON.parse(r.default.readFileSync(i.default.join(s,e),"utf8"));ty(a.sessionId)&&"number"==typeof a.pid&&t(a.pid)&&n.add(a.sessionId)}catch{}return n}(a,u),...function(){let e=new Set;for(let t of r.default.existsSync(p)?r.default.readdirSync(p):[]){if(!t.endsWith(".json"))continue;let n=T(t.slice(0,-5));n&&"running"===n.state&&!v(n)&&e.add(n.session_id)}return e}()])}function v(e){var t;let n,r,i=tF(h(f(e.id,"out.jsonl"))),s=e.finished_at??Date.now(),a={provider_session_id:e.session_id,usage:{input_tokens:tW((n=(t=i.result)&&tU(t.usage)?t.usage:{}).input_tokens)??tW(n.inputTokens),output_tokens:tW(n.output_tokens)??tW(n.outputTokens),total_cost_usd:t&&"number"==typeof(r=t.total_cost_usd)&&Number.isFinite(r)&&r>=0?r:null},finished_at:s};if(null!==i.session_id&&i.session_id!==e.session_id)return{...a,status:"failed",output:null,failure:{code:"session_mismatch",message:"Claude Code ran a different session than the one requested."}};if(i.result)return tG(i.result)?{...a,status:"completed",output:"string"==typeof i.result.result?i.result.result:null,failure:null}:{...a,status:"failed",output:null,failure:t$(i.result,i)};if("cancelled"===e.state)return{...a,status:"cancelled",output:null,failure:{code:"cancelled",message:"Cancelled."}};if(!("exited"===e.state||"spawn_failed"===e.state||null===e.pid||!u(e.pid)))return null;let o=h(f(e.id,"err.log")),d=/unknown option|unrecognized option|invalid option/i.test(o);return{...a,status:"failed",output:null,failure:d?{code:"incompatible_version",message:"The installed Claude Code rejected the non-interactive flag set."}:{code:"process_exited",message:`Claude Code exited without a result${null===e.exit_code?"":` (exit ${e.exit_code})`}.`}}}let k=e=>i.default.join(m,e.replace(/[^a-zA-Z0-9_-]/g,"_"));async function y(e,i,a,o){let u,_=`ct-${(0,s.randomUUID)()}`;r.default.mkdirSync(p,{recursive:!0});let E=i.session_context?.mint({kind:"claude_turn",ref:_})??null,m=E?f(_,"mcp.json"):null;E&&m&&function(e,t){r.default.rmSync(e,{force:!0});let n=r.default.openSync(e,"wx",384);try{r.default.writeFileSync(n,JSON.stringify({mcpServers:{[tf]:{type:"http",url:t,headers:{[tE]:`\${${tp}}`}}}}))}finally{r.default.closeSync(n)}r.default.chmodSync(e,384)}(m,E.url);let N={id:_,session_id:a,kind:e,authority:i.authority,workspace:o,pid:null,state:"running",exit_code:null,created_at:Date.now(),finished_at:null},R=r.default.openSync(f(_,"out.jsonl"),"a"),k=r.default.openSync(f(_,"err.log"),"a"),y=null;try{u=d(n,function(e,t,n=null){let r=tK[e],i=n?[...r.tools,tg]:r.tools;return["-p","--output-format","stream-json","--verbose","--input-format","text","--permission-mode",r.permission_mode,"--permission-prompts","none","--tools",r.tools.join(","),"--allowedTools",i.join(","),"--strict-mcp-config",...n?["--mcp-config",n]:[],..."resume"in t?["--resume",t.resume]:["--session-id",t.sessionId]]}(i.authority,"send"===e?{resume:a}:{sessionId:a},m),{cwd:o,env:tz(t,E?.token??null),stdio:["pipe",R,k],detached:!0})}finally{r.default.closeSync(R),r.default.closeSync(k)}u.on("error",e=>{y=e}),N.pid=u.pid??null,g(N),u.on("exit",e=>{let t=T(_);t&&"running"===t.state&&g({...t,state:"exited",exit_code:e,finished_at:Date.now()})}),u.stdin?.on("error",()=>{}),u.stdin?.end(i.prompt),u.unref();let L=Date.now()+l;for(;;){let e=T(_),t=tF(h(f(_,"out.jsonl")));if(y)return g({...e,state:"spawn_failed",finished_at:Date.now()}),{turn:null,error:ta("unavailable",`Claude Code could not start: ${y.message}`)};if(null!==t.session_id&&t.session_id!==a)return w(e),g({...e,state:"cancelled",finished_at:Date.now()}),{turn:null,error:ta("not_resumable","Claude Code started a different session; it was stopped.")};if(null===t.session_id&&t.result&&!tG(t.result)){let e=t$(t.result,t);return{turn:null,error:ta(tJ[e.code],e.message)}}if(null!==t.session_id||t.result)return{turn:e,error:null};let n=v(e);if(n){let e=n.failure?.code;return{turn:null,error:ta(e?tJ[e]??"unavailable":"unavailable",n.failure?.message??"Claude Code exited.")}}if(Date.now()>=L)return{turn:e,error:null};await new Promise(e=>setTimeout(e,Math.min(c,25)))}}function w(e){if(null!==e.pid)for(let t of[-e.pid,e.pid])try{process.kill(t,"SIGTERM");return}catch{}}async function L(e,s,a,o){if(!tK[s.authority])return ta("unsupported_authority",`No Claude Code mode for ${String(s.authority)}.`);let d=function(e){r.default.mkdirSync(m,{recursive:!0});let t=i.default.join(m,e.replace(/[^a-zA-Z0-9_-]/g,"_"));try{return r.default.writeFileSync(t,"",{flag:"wx"}),{existing:null,claimed:!0}}catch{let e=h(t).trim();return{existing:e?T(e):null,claimed:!1}}}(s.idempotency_key);if(!d.claimed)return d.existing?to({provider_turn_id:d.existing.id,provider_session_id:d.existing.session_id}):ta("busy","A turn with this idempotency key is starting.");let u=()=>r.default.rmSync(k(s.idempotency_key),{force:!0}),l=function(){let e,r=tj.get(n);if(r)return r;try{let r=(0,tc.execFileSync)(n,["--version"],{env:tz(t),encoding:"utf8",timeout:2e4,stdio:["ignore","pipe","pipe"]}),i=/(\d+\.\d+\.\d+)/.exec(r)?.[1]??null;e=i?0>function(e,t){let n=e.split(".").map(Number),r=t.split(".").map(Number);for(let e=0;e<3;e++)if((n[e]??0)!==(r[e]??0))return(n[e]??0)-(r[e]??0);return 0}(i,tB)?{ok:!1,code:"incompatible_version",message:`Claude Code ${i} is older than ${tB}.`}:{ok:!0,version:i}:{ok:!1,code:"incompatible_version",message:"Claude Code did not report a version."}}catch(e){return{ok:!1,code:"unavailable",message:`Claude Code is not runnable: ${e.message}`}}return tj.set(n,e),e}();if(!l.ok)return u(),ta(l.code,l.message);let _=await y(e,s,a,o);return _.turn?(r.default.writeFileSync(k(s.idempotency_key),_.turn.id),to({provider_turn_id:_.turn.id,provider_session_id:a})):(u(),_.error)}return{kind:"claude-code",capabilities:()=>({...tP,authorities:[...tP.authorities]}),async listSessions(e){let t=e.scope;if("workspaces"===t.kind&&0===t.workspaces.length)return to({items:[],next_cursor:null});let n="sessions"===t.kind?t.provider_session_ids.map(e=>tA(a,e)).filter(e=>!!e).map(e=>({id:i.default.basename(e,".jsonl"),file:e,mtime_ms:r.default.statSync(e).mtimeMs})):function(e,t){let n=t?t.flatMap(tI):null,s=[];for(let t of tO(tL(e))){if(n&&!n.some(e=>t===e||t.startsWith(`${e}-`)))continue;let a=i.default.join(tL(e),t);for(let e of tO(a)){if(!e.endsWith(".jsonl"))continue;let t=e.slice(0,-6);if(ty(t))try{let n=r.default.statSync(i.default.join(a,e));n.isFile()&&s.push({id:t,file:i.default.join(a,e),mtime_ms:n.mtimeMs})}catch{}}}return s.sort((e,t)=>t.mtime_ms-e.mtime_ms||e.id.localeCompare(t.id))}(a,"workspaces"===t.kind?t.workspaces:null),s=Math.max(0,Number(e.cursor??0)||0),o=(e.query??"").trim().toLowerCase(),d=R(),u=E(),l=864e5*tD(a),_=[],c=20*e.limit,p=s;for(;p<n.length&&_.length<e.limit&&p-s<c;p++){if(e.signal?.aborted)return ta("cancelled","list aborted");let r=tx(n[p]);r&&function(e,t){return"all_provider_sessions"===e.kind||("sessions"===e.kind?e.provider_session_ids.includes(t.id):null!==t.workspace&&e.workspaces.some(e=>{var n;let r;return n=t.workspace,n===(r=e.replace(/\/+$/,"")||"/")||n.startsWith("/"===r?"/":`${r}/`)}))}(t,r)&&(!o||`${r.title??""}
|
|
1894
|
+
${r.workspace??""}`.toLowerCase().includes(o))&&_.push(N(r,d,u,l))}return to({items:_,next_cursor:p<n.length?String(p):null})},async getSession(e){let t=tA(a,e.provider_session_id);if(!t)return to(null);let n=tx({id:e.provider_session_id,file:t,mtime_ms:r.default.statSync(t).mtimeMs});return to(n?N(n,R(),E(),864e5*tD(a)):null)},async readTranscript(e){let t=tA(a,e.provider_session_id),n=t?function(e,t){let n=tS(e);if(!n)return null;let r=[],i=(e,t,n)=>{t.trim()&&r.push({seq:r.length+1,role:e,text:t.length>4e3?`${t.slice(0,3999)}…`:t,at:n})};for(let e of n.records){if(!tC(e)||void 0!==e.sessionId&&e.sessionId!==t)continue;let n=tb(e),r=tq(e),s="user"===e.type?"user":"assistant";if("string"==typeof r){i(s,r,n);continue}for(let e of r??[])if(e&&"object"==typeof e){if("text"===e.type)i(s,String(e.text??""),n);else if("tool_use"===e.type)i("tool",`tool call: ${String(e.name??"unknown")}`,n);else if("tool_result"===e.type){let t="string"==typeof e.content?e.content:Array.isArray(e.content)?e.content.map(e=>e&&"object"==typeof e&&"text"===e.type?String(e.text??""):"").join("\n"):"";i("tool",`tool result: ${t||"(no text)"}`,n)}}}return r}(t,e.provider_session_id):null;if(!n)return ta("not_found","Claude Code has no such session.");let r=Math.max(0,Number(e.cursor??0)||0);return to({items:n.slice(r,r+e.limit),next_cursor:r+e.limit<n.length?String(r+e.limit):null})},async startSession(e){let t=null;try{t=r.default.statSync(e.workspace)}catch{t=null}return t?.isDirectory()?L("start",e,(0,s.randomUUID)(),e.workspace):ta("invalid_input","The workspace is not a directory here.")},async sendTurn(e){if(!ty(e.provider_session_id))return ta("not_found","Not a Claude Code session id.");let t=tA(a,e.provider_session_id);if(!t)return ta("not_found","Claude Code has no such session.");let n=tx({id:e.provider_session_id,file:t,mtime_ms:r.default.statSync(t).mtimeMs});if(!n||0===n.messages||!n.workspace)return ta("not_resumable","The session has no conversation to resume.");if(R().has(n.id)){let t,n=(t=h(k(e.idempotency_key)).trim())?T(t):null;return n?to({provider_turn_id:n.id,provider_session_id:n.session_id}):ta("busy","The session is open in a running Claude Code process.")}return L("send",e,n.id,n.workspace)},async observeTurn(e){let t=null;for(;;){let n=T(e.provider_turn_id);if(!n)return ta("not_found","No such turn.");let i=v(n);if(i&&"running"===n.state&&null!==n.pid&&u(n.pid)&&(t??=Date.now(),Date.now()-t<_&&!e.signal?.aborted&&!("number"==typeof e.deadline_at&&Date.now()>=e.deadline_at))){await new Promise(e=>setTimeout(e,c));continue}if(i)return"running"===n.state&&g({...n,state:"exited",finished_at:i.finished_at}),r.default.rmSync(f(n.id,"mcp.json"),{force:!0}),to(i);if(e.signal?.aborted)return ta("cancelled","observe aborted");if("number"==typeof e.deadline_at&&Date.now()>=e.deadline_at)return ta("timed_out","observe deadline");await new Promise(e=>setTimeout(e,c))}},async cancelTurn(e){let t=T(e.provider_turn_id);return t?v(t)?to("already_terminal"):(w(t),g({...t,state:"cancelled",finished_at:Date.now()}),r.default.rmSync(f(t.id,"mcp.json"),{force:!0}),to("cancelled")):ta("not_found","No such turn.")}}}],71711);let tV={name:"botmancers",version:"1"},tQ={list:!0,search:!0,read:!0,resume:!0,start:!0,cancel:!0,usage:!0,authorities:["read_only","workspace_write"],max_page_size:50},tZ={list:!1,search:!1,read:!1,resume:!1,start:!1,cancel:!1,usage:!1,authorities:[],max_page_size:50};function t0(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:null}function t1(e){return"string"==typeof e&&e.length>0?e:null}function t4(e){return"number"==typeof e&&Number.isFinite(e)&&e>=0?e:null}function t2(e){if("string"!=typeof e)return null;let t=Date.parse(e);return Number.isFinite(t)?t:null}function t3(e,t="durable"){let n=t0(e),r=t1(n?.sessionId);if(!n||!r||"subagent"===n.kind)return null;let i=t1(n.workspaceRoot),s=t1(n.status);return{provider_session_id:r,title:t1(n.title)??t1(n.firstUserPrompt)??t1(n.name),workspace:i&&i.startsWith("/")?i:null,created_at:t2(n.createdAt),updated_at:t2(n.lastActivityAt)??t2(n.updatedAt),lifecycle:"open",resumable:"durable"===t&&"string"==typeof n.path&&n.path.length>0,busy:"running"===s||null!==t1(n.activeTurnId)}}function t6(e,t){if(!Array.isArray(e))return null;let n=e.map(t0).filter(e=>!!e&&"agentMessage"===e.kind&&e.turnId===t&&!0!==e.retracted).map(e=>t1(e.text)).filter(e=>null!==e);return n.length>0?n.join("\n"):null}function t9(e){return 0===e.length||e.some(e=>null===e)?null:e.reduce((e,t)=>e+t,0)}function t5(e){let t="string"==typeof e?/^(\d+)\.(\d+)\.(\d+)/.exec(e.trim()):null;return t?[Number(t[1]),Number(t[2]),Number(t[3])]:null}let t8=/login is no longer valid|authentication failed|missing \w+ credentials|api key .*rejected|unauthenticated|unauthori[sz]ed|not (signed|logged) in|\b401\b|\b403\b|forbidden|authRequired/i,t7=/rate[\s_-]*limit|usage[\s_-]*limit|quota|\b429\b|rate_limited/i;function ne(e=Date.now()){let t=Buffer.alloc(16),n=Math.floor(e);for(let e=5;e>=0;e--)t[e]=n%256,n=Math.floor(n/256);(0,s.randomBytes)(10).copy(t,6),t[6]=112|15&t[6],t[8]=128|63&t[8];let r=t.toString("hex");return`${r.slice(0,8)}-${r.slice(8,12)}-${r.slice(12,16)}-${r.slice(16,20)}-${r.slice(20)}`}function nt(e){let t=e.lastIndexOf(":");return t<=0||t===e.length-1?null:{sessionId:e.slice(0,t),turnId:e.slice(t+1)}}class nn{options;authority;child;buffer;seq;pending;listeners;ready;loaded;turns;info;constructor(e,t){this.options=e,this.authority=t,this.child=null,this.buffer="",this.seq=0,this.pending=new Map,this.listeners=new Set,this.ready=null,this.loaded=new Set,this.turns=new Map,this.info=null}alive(){return null!==this.child}start(){return this.ready&&this.child||(this.ready=this.spawnAndInitialize()),this.ready}async spawnAndInitialize(){let e,t="read_only"===this.authority?["--disable-write","--disable-shell"]:[];try{e=(0,tc.spawn)(this.options.command,[...this.options.commandArgs,"serve",...t,...this.options.serveArgs],{cwd:tv.default.homedir(),stdio:["pipe","pipe","pipe"],env:{...process.env,...this.options.env}})}catch{return{code:"unavailable",message:"spawn_failed"}}this.child=e;let n=null,r="";e.on("error",t=>{n="ENOENT"===t.code?"binary_missing":"spawn_failed",this.drop(e)}),e.stdin.on("error",()=>this.drop(e)),e.stderr.on("data",e=>{r=`${r}${e.toString()}`.slice(-2e3)}),e.stdout.on("data",t=>this.onData(e,t)),e.on("close",()=>this.drop(e));let i=await this.request("initialize",{clientInfo:{...tV}});if(!i.ok)return(this.close(),n)?{code:"unavailable",message:n}:t8.test(r)?{code:"unavailable",message:"auth_required (host exited)"}:i.error;let s=t0(i.result.serverInfo),a=t0(i.result.schema);this.info={muse_version:t1(s?.version),schema_version:"number"==typeof a?.version?a.version:null,schema_fingerprint:t1(a?.fingerprint),durability:t1(i.result.sessionDurability)??"durable"};try{e.stdin.write(`${JSON.stringify({jsonrpc:"2.0",method:"initialized",params:{}})}
|
|
1895
|
+
`)}catch{return this.close(),{code:"unavailable",message:"transport_error"}}return null}onData(e,t){let n;if(e===this.child){if(this.buffer+=t.toString(),this.buffer.length>0x1000000)return void this.close();for(;(n=this.buffer.indexOf("\n"))>=0;){let e=this.buffer.slice(0,n);this.buffer=this.buffer.slice(n+1),this.onLine(e)}}}onLine(e){let t=null;try{t=t0(JSON.parse(e))}catch{return}if(!t)return;if("number"==typeof t.id&&this.pending.has(t.id)){let e,n,r,i=this.pending.get(t.id);this.pending.delete(t.id);let s=t0(t.error);i(s?{ok:!1,error:(e="number"==typeof s.code?s.code:null,n=t1(t0(s.data)?.kind)??"unknown",r=`${n} ${"string"==typeof s.message?s.message:""}`,t8.test(r)||401===e||403===e?{code:"unavailable",message:`auth_required (${n})`}:-32601===e||"methodNotFound"===n||"experimentalRequired"===n||"capabilityRequired"===n||-32010===e?{code:"unsupported",message:`unsupported (${n})`}:-32020===e||-32011===e||"sessionNotFound"===n||"notFound"===n?{code:"not_found",message:`not_found (${n})`}:-32021===e||"sessionInUse"===n?{code:"busy",message:`busy (${n})`}:-32602===e||-32002===e||"invalidParams"===n||"inputTooLarge"===n?{code:"invalid_input",message:`invalid_input (${n})`}:{code:"unavailable",message:`provider_error (${n})`})}:{ok:!0,result:t0(t.result)??{}});return}if("string"!=typeof t.method||void 0!==t.id||"turn/completed"!==t.method&&"session/tokenUsage"!==t.method)return;let n=t0(t.params),r=t1(n?.turnId),i=t1(n?.sessionId);if(!n||!r||!i)return;let s=this.turns.get(r);s||(s={sessionId:i,completed:null,usageRecords:[]},this.turns.set(r,s)),"turn/completed"===t.method?(s.completed=n,this.notify()):"session/tokenUsage"===t.method&&s.usageRecords.push(n.usage)}notify(){for(let e of[...this.listeners])e()}async waitFor(e,t,n){for(;;){if(e())return"done";if(!this.alive())return"dead";if(t?.aborted)return"cancelled";let r="number"==typeof n?n-Date.now():1e3;if(r<=0)return"timed_out";await new Promise(e=>{let n=()=>{clearTimeout(i),t?.removeEventListener("abort",n),this.listeners.delete(n),e()},i=setTimeout(n,Math.min(r,1e3));this.listeners.add(n),t?.addEventListener("abort",n,{once:!0})})}}request(e,t){let n=this.child;if(!n)return Promise.resolve({ok:!1,error:{code:"unavailable",message:"host_not_running"}});let r=++this.seq;return new Promise(i=>{let s=setTimeout(()=>{this.pending.delete(r),i({ok:!1,error:{code:"unavailable",message:`rpc_timeout (${e})`}})},this.options.rpcTimeoutMs);this.pending.set(r,e=>{clearTimeout(s),i(e)});try{n.stdin.write(`${JSON.stringify({jsonrpc:"2.0",id:r,method:e,params:t})}
|
|
1896
|
+
`)}catch{this.pending.delete(r),clearTimeout(s),i({ok:!1,error:{code:"unavailable",message:"transport_error"}})}})}drop(e){if(e===this.child){for(let e of(this.child=null,this.ready=null,this.loaded.clear(),this.pending.values()))e({ok:!1,error:{code:"unavailable",message:"host_exited"}});this.pending.clear(),this.notify()}}close(){let e=this.child;if(e){this.drop(e);try{e.kill("SIGTERM")}catch{}}}runningTurns(){let e=0;for(let t of this.turns.values())!t.completed&&e++;return e}}let nr=new Map;function ni(e,t){let n=e??{muse_version:null,schema_version:null,schema_fingerprint:null,durability:null};if(t){let e=/^auth_required/.test(t.message)?"auth_required":"unsupported"===t.code?"unsupported":"unavailable";return{...n,status:e,reason:t.message,capabilities:{...tZ}}}let r=t5(n.muse_version);if(1!==n.schema_version)return{...n,status:"unsupported",reason:`msp_schema_${n.schema_version??"unknown"}`,capabilities:{...tZ}};if(!r||!function(e,t){for(let n=0;n<3;n++)if(e[n]!==t[n])return e[n]>t[n];return!0}(r,t5("1.4.0")))return{...n,status:"unsupported",reason:`muse_version_${n.muse_version??"unknown"}`,capabilities:{...tZ}};let i="durable"===n.durability;return{...n,status:"ready",reason:null,capabilities:i?{...tQ,authorities:[...tQ.authorities]}:{...tQ,list:!1,search:!1,read:!1,resume:!1,authorities:[...tQ.authorities]}}}process.once("exit",()=>(function(){for(let e of nr.values())for(let t of Object.values(e.hosts))t?.close();nr.clear()})()),e.s(["createMuseSessionProvider",0,function(e,t={}){let n,r=((n=nr.get(e))||(n={hosts:{},probe:null,startKeys:new Map},nr.set(e,n)),n),i={command:t.command??process.env.BOTMANCERS_MUSE_BIN??"muse",commandArgs:t.commandArgs??[],serveArgs:t.serveArgs??function(){let e=process.env.BOTMANCERS_MUSE_SERVE_ARGS;if(!e)return[];try{let t=JSON.parse(e);return Array.isArray(t)?t.filter(e=>"string"==typeof e):[]}catch{return[]}}(),env:t.env??{},rpcTimeoutMs:t.rpcTimeoutMs??3e4},s=t.cancelSettleMs??1e4;async function a(e){let t=r.hosts[e];t||(t=new nn(i,e),r.hosts[e]=t);let n=await t.start();return(r.probe=ni(t.info,n),n)?{ok:!1,error:n}:"ready"!==r.probe.status?(t.close(),{ok:!1,error:{code:"unsupported",message:r.probe.reason??"unsupported"}}):{ok:!0,host:t}}function o(){return a(["read_only","workspace_write"].find(e=>r.hosts[e]?.alive())??"read_only")}async function d(e,t,n){return e.request(t,n)}async function u(e,t){let n=await o();return n.ok?d(n.host,"session/read",{sessionId:e,excludeItems:!t}):n}function l(){return r.probe?.durability??"durable"}async function _(e,t){for(let n of Object.values(r.hosts))if(n&&n!==e&&n.loaded.has(t)){if(n.runningTurns()>0)return{ok:!1,error:{code:"busy",message:"busy (loaded by another host)"}};n.close()}if(e.loaded.has(t)){let n=await d(e,"session/read",{sessionId:t,excludeItems:!0});return n.ok?{ok:!0,session:t0(n.result.session)??{}}:n}let n=await d(e,"session/resume",{commandId:ne(),sessionId:t,excludeItems:!0});return n.ok?(e.loaded.add(t),{ok:!0,session:t0(n.result.session)??{}}):n}async function c(e,t,n){let r=await d(e,"turn/start",{commandId:ne(),sessionId:t,input:[{type:"text",text:n}]});if(!r.ok)return r;let i=t1(r.result.turnId);return i?(e.turns.has(i)||e.turns.set(i,{sessionId:t,completed:null,usageRecords:[]}),to(i)):ta("unavailable","provider_error (turn/start without turnId)")}async function E(e,t,n,r,i,s,a){let o,d,l,_,c=a;if(void 0===c){let t=await u(e,!0);c=t.ok?t0(t.result.history)?.items:null}let E="completed"===n?"completed":"cancelled"===n?"cancelled":"failed";return{status:E,provider_session_id:e,output:t6(c,t),failure:"completed"===E?null:"cancelled"===E?{code:"cancelled",message:t1(i)??"cancelled"}:(o=t0(r),d=t1(o?.kind)??"",l=(t1(o?.message)??t1(i)??d)||"turn failed",_=`${d} ${l}`,{code:t8.test(_)?"auth":t7.test(_)||o?.quota?"usage_cap":d||"failed",message:l.slice(0,500)}),usage:s?{input_tokens:s.input_tokens,output_tokens:s.output_tokens}:null,finished_at:Date.now()}}function p(e){for(let t of Object.values(r.hosts)){let n=t?.alive()?t.turns.get(e):void 0;if(t&&n)return{host:t,track:n}}return null}async function m(e,t,n,r){for(;;){let i=await u(e,!0);if(!i.ok)return i;let s=t0(i.result.session),a=t0(i.result.lastTurn),o=t0(i.result.history)?.items;if(a&&a.turnId===t)return to(await E(e,t,a.terminal,a.error,a.reason,null,o));if(s?.activeTurnId!==t)return to({status:"failed",provider_session_id:e,output:t6(o,t),failure:{code:"host_lost",message:"The Muse host running this turn exited before it finished."},usage:null,finished_at:Date.now()});if(n?.aborted)return ta("cancelled","observe aborted");if("number"==typeof r&&Date.now()>=r)return ta("timed_out","observe deadline");await new Promise(e=>setTimeout(e,500))}}return{kind:"muse-msp",capabilities(){let e=r.probe?.capabilities??tQ;return{...e,authorities:[...e.authorities]}},async probe(){let e=await o();return r.probe??ni(null,e.ok?null:e.error)},async listSessions(e){let t=await o();if(!t.ok)return t;let n={},r="sessions"===e.scope.kind?e.scope.provider_session_ids:null;if(r){if(0===r.length)return to({items:[],next_cursor:null});n.sessionId={anyOf:r.slice(0,200)}}let i=(e.query??"").trim().split(/\s+/).filter(Boolean).slice(0,16);i.length>0&&(n.text={allOf:i,fields:["name","title"]});let s=await d(t.host,"session/list",{limit:Math.min(Math.max(1,e.limit),50),...e.cursor?{cursor:e.cursor}:{},...Object.keys(n).length>0?{filter:n}:{}});if(!s.ok)return s;let a=t0(s.result.appliedFilter);return n.text&&!t0(a?.text)?ta("unsupported","unsupported (session/list text filter)"):to({items:(Array.isArray(s.result.sessions)?s.result.sessions:[]).map(e=>t3(e,l())).filter(e=>null!==e).filter(e=>!r||r.includes(e.provider_session_id)),next_cursor:t1(s.result.nextCursor)})},async getSession(e){let t=await u(e.provider_session_id,!1);if(!t.ok)return"not_found"===t.error.code?to(null):t;let n=t3(t.result.session,l());return to(n&&n.provider_session_id===e.provider_session_id?n:null)},async readTranscript(e){let t=await u(e.provider_session_id,!0);if(!t.ok)return t;let n=t0(t.result.history);if(n?.mode!=="inline")return ta("unavailable",`history_${t1(n?.mode)??"missing"}`);let r=function(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=t0(n);if(!e||!0===e.retracted)continue;let r="userMessage"===e.kind?"user":"agentMessage"===e.kind?"assistant":null,i=t1(e.text)??("user"===r?t1(e.displayText):null);r&&i&&t.push({seq:t.length+1,role:r,text:i,at:t2(e.recordedAt)})}return t}(n.items),i=e.cursor&&/^\d+$/.test(e.cursor)?Number(e.cursor):0;return to({items:r.slice(i,i+e.limit),next_cursor:i+e.limit<r.length?String(i+e.limit):null})},async startSession(e){var t;let n=r.startKeys.get(e.idempotency_key);if(n)return to(n);let i=await a(e.authority);if(!i.ok)return i;let s=await d(i.host,"session/start",{commandId:ne(),workspaceRoot:e.workspace,approvalMode:"denyUnmatched"});if(!s.ok)return s;let o=t1(t0(s.result.session)?.sessionId);if(!o)return ta("unavailable","provider_error (session/start without sessionId)");i.host.loaded.add(o);let u=await c(i.host,o,e.prompt);if(!u.ok)return u;let l={provider_session_id:o,provider_turn_id:(t=u.value,`${o}:${t}`)};return r.startKeys.set(e.idempotency_key,l),to(l)},async sendTurn(e){var t,n;let i=r.startKeys.get(e.idempotency_key);if(i)return to(i);let s=await a(e.authority);if(!s.ok)return s;let o=await _(s.host,e.provider_session_id);if(!o.ok)return o;if("running"===o.session.status||t1(o.session.activeTurnId))return ta("busy","busy (turn in flight)");let d=await c(s.host,e.provider_session_id,e.prompt);if(!d.ok)return d;let u={provider_session_id:e.provider_session_id,provider_turn_id:(t=e.provider_session_id,n=d.value,`${t}:${n}`)};return r.startKeys.set(e.idempotency_key,u),to(u)},async observeTurn(e){let t=nt(e.provider_turn_id);if(!t)return ta("not_found","not_found (turn handle)");let n=p(t.turnId);if(n){let r=await n.host.waitFor(()=>null!==n.track.completed,e.signal,e.deadline_at);if("cancelled"===r)return ta("cancelled","observe aborted");if("timed_out"===r)return ta("timed_out","observe deadline");let i=n.track.completed;if(i)return to(await E(t.sessionId,t.turnId,i.terminal,i.error,i.reason,function(e,t=[]){let n=t0(e);if(n)return{input_tokens:t4(n.inputTokens),output_tokens:t4(n.outputTokens),cost_usd:null};let r=t.map(t0).filter(e=>null!==e);return 0===r.length?null:{input_tokens:t9(r.map(e=>t4(e.inputTokens))),output_tokens:t9(r.map(e=>t4(e.outputTokens))),cost_usd:null}}(i.usage,n.track.usageRecords)))}return m(t.sessionId,t.turnId,e.signal,e.deadline_at)},async cancelTurn(e){let t=nt(e.provider_turn_id);if(!t)return ta("not_found","not_found (turn handle)");let n=p(t.turnId);if(!n){let e=await u(t.sessionId,!1);return e.ok?t0(e.result.session)?.activeTurnId===t.turnId?ta("unavailable","turn runs in another Muse host"):to("already_terminal"):e}if(n.track.completed)return to("already_terminal");let r=await d(n.host,"turn/cancel",{commandId:ne(),sessionId:t.sessionId,turnId:t.turnId});if(!r.ok)return r;await n.host.waitFor(()=>null!==n.track.completed,null,Date.now()+s);let i=n.track.completed?.terminal;return to(void 0===i||"cancelled"===i?"cancelled":"already_terminal")}}}],23325);class ns{defaultTimeoutMs;transport;pending;listeners;closeListeners;nextId;serverRequestHandler;closed;closeReason;constructor(e,t=3e4){this.defaultTimeoutMs=t,this.pending=new Map,this.listeners=new Set,this.closeListeners=new Set,this.nextId=1,this.serverRequestHandler=null,this.closed=!1,this.closeReason=null,this.transport=e,e.onLine(e=>this.receive(e)),e.onClose(e=>{for(let[t,n]of(this.closed=!0,this.closeReason=e,this.pending))this.pending.delete(t),n.cleanup(),n.resolve({ok:!1,kind:"closed",error:{code:-1,message:e}});for(let t of this.closeListeners)t(e)})}request(e,t,n={}){if(this.closed)return Promise.resolve({ok:!1,kind:"closed",error:{code:-1,message:this.closeReason??"closed"}});let r=this.nextId++;return new Promise(i=>{let s=n.signal??null,a=()=>l({ok:!1,kind:"aborted",error:{code:-1,message:"aborted"}}),o=n.timeoutMs??this.defaultTimeoutMs,d=o>0?setTimeout(()=>l({ok:!1,kind:"timeout",error:{code:-1,message:`${e} timed out`}}),o):null,u=()=>{d&&clearTimeout(d),s?.removeEventListener("abort",a)},l=e=>{this.pending.has(r)&&(this.pending.delete(r),u(),i(e))};if(this.pending.set(r,{resolve:e=>i(e),timer:d,cleanup:u}),s?.aborted)return a();s?.addEventListener("abort",a,{once:!0}),this.transport.send(JSON.stringify({id:r,method:e,params:t}))})}notify(e,t){this.transport.send(JSON.stringify(void 0===t?{method:e}:{method:e,params:t}))}onNotification(e){return this.listeners.add(e),()=>this.listeners.delete(e)}onClose(e){return this.closeListeners.add(e),()=>this.closeListeners.delete(e)}handleServerRequests(e){this.serverRequestHandler=e}close(){this.transport.close()}receive(e){let t;try{t=JSON.parse(e)}catch{return}if(!t||"object"!=typeof t)return;let n="number"==typeof t.id||"string"==typeof t.id;if(n&&"string"==typeof t.method){let e=this.serverRequestHandler?this.serverRequestHandler(t.method,t.params??{}):{error:{code:-32601,message:"not handled"}};this.transport.send(JSON.stringify({id:t.id,...e}));return}if(n){let e=this.pending.get(Number(t.id));if(!e)return;if(this.pending.delete(Number(t.id)),e.cleanup(),t.error&&"object"==typeof t.error){let n=t.error;e.resolve({ok:!1,kind:"rpc",error:{code:Number(n.code??-32603),message:String(n.message??"")}})}else e.resolve({ok:!0,result:t.result});return}if("string"==typeof t.method){let e={method:t.method,params:t.params??{}};for(let t of this.listeners)t(e)}}}function na(e){let t=[];for(let n of e.split("\n")){let e=n.trim();if(e)try{let n=JSON.parse(e);n&&"object"==typeof n&&!Array.isArray(n)&&t.push(n)}catch{}}return t}let no=e=>"number"==typeof e&&Number.isFinite(e)&&e>=0?Math.trunc(e):null;function nd(e,t,n){return null===e&&null===n?null:{input_tokens:e,output_tokens:n,cached_input_tokens:t,cost_usd:null}}function nu(e){let t=null,n=null,r=null,i=null;for(let s of e)if("thread.started"===s.type&&"string"==typeof s.thread_id)t=s.thread_id;else if("item.completed"===s.type&&s.item&&"object"==typeof s.item){let e=s.item;"agent_message"===e.type&&"string"==typeof e.text&&e.text&&(n=e.text)}else if("turn.completed"===s.type)r="completed";else if("turn.failed"===s.type||"error"===s.type){r="failed";let e=s.error;i="string"==typeof e?e:e&&"object"==typeof e&&"string"==typeof e.message?e.message:"string"==typeof s.message?s.message:"codex turn failed"}return{thread_id:t,terminal:r,output:n,error:i,usage:function(e){for(let t=e.length-1;t>=0;t--){let n=e[t];if("turn.completed"!==n.type)continue;let r=n.usage;if(!r||"object"!=typeof r)break;return nd(no(r.input_tokens),no(r.cached_input_tokens),no(r.output_tokens))}return null}(e)}}let nl=["cli","vscode","exec","appServer"],n_=["thread/list","thread/read","thread/items/list","thread/turns/list","thread/start","thread/resume","turn/start","turn/interrupt"],nc={"thread/list":{limit:"probe"},"thread/read":{threadId:0},"thread/items/list":{threadId:0},"thread/turns/list":{threadId:0},"thread/start":{cwd:0},"thread/resume":{threadId:0},"turn/start":{threadId:0},"turn/interrupt":{threadId:0}},nE=Object.fromEntries(n_.map(e=>[e,!1]));function np(e,t,n){return`codex:${e}:${t}:${n}`}function nm(e){let t=e.split(":");return 4===t.length&&"codex"===t[0]&&("as"===t[1]||"ex"===t[1])&&t[2]&&t[3]?{kind:t[1],threadId:t[2],id:t[3]}:null}function nf(e){return Buffer.from(JSON.stringify(e)).toString("base64url")}function nT(e){if(!e)return null;try{let t=JSON.parse(Buffer.from(e,"base64url").toString("utf8"));return t&&"object"==typeof t?t:null}catch{return null}}let ng=e=>"number"==typeof e&&Number.isFinite(e)?Math.round(1e3*e):null;function nh(e,t){let n="string"==typeof e.cwd&&e.cwd.startsWith("/")?e.cwd:null,i=e.status?.type,s="string"==typeof e.name&&e.name.trim()?e.name:null,a="string"==typeof e.preview&&e.preview.trim()?e.preview:null;return{provider_session_id:e.id,title:s??a,workspace:n,created_at:ng(e.createdAt),updated_at:ng(e.updatedAt),lifecycle:t??("string"==typeof e.path&&e.path.split(/[\\/]/).includes("archived_sessions")?"archived":"open"),resumable:!0!==e.ephemeral&&"systemError"!==i&&null!==n&&r.default.existsSync(n),busy:"active"===i}}function nN(e,t,n){if("userMessage"===e.type)return{seq:t,role:"user",text:(Array.isArray(e.content)?e.content:[]).map(e=>e&&"object"==typeof e&&"text"===e.type?String(e.text??""):"").join("").trim(),at:n};return"agentMessage"===e.type&&"string"==typeof e.text?{seq:t,role:"assistant",text:e.text,at:n}:"commandExecution"===e.type&&"string"==typeof e.command?{seq:t,role:"tool",text:`$ ${e.command}`,at:n}:null}function nR(e){let t=null,n=null;for(let r of e??[])r?.type==="agentMessage"&&"string"==typeof r.text&&r.text&&(t=r.text,"final_answer"===r.phase&&(n=r.text));return n??t}function nv(e){return"workspace_write"===e?"workspace-write":"read-only"}function nk(e){return!e.ok&&"rpc"===e.kind&&/thread not (found|loaded)|no rollout|invalid thread id|not found/i.test(e.error.message)}function ny(e,t){return"timeout"===e.kind?ta("timed_out",`${t} timed out`):"aborted"===e.kind?ta("cancelled",`${t} aborted`):"closed"===e.kind?ta("unavailable",`${t}: app-server closed`):ta("invalid_input",`${t} refused (${e.error.code})`)}class nw{options;client;connecting;probe;trackers;keys;idleTimer;loads;command;env;constructor(e={}){this.options=e,this.client=null,this.connecting=null,this.probe=null,this.trackers=new Map,this.keys=new Map,this.idleTimer=null,this.loads=new Map,this.command=e.command??[process.env.BOTMANCERS_CODEX_BIN||"codex"],this.env=e.env??process.env}get runsDir(){return this.options.runsDir??i.default.join(i.default.dirname(i.default.resolve(eX(this.env))),"codex-exec-runs")}capabilities(){let e=this.probe?.status==="ready"?this.probe:null,t=e?.methods??nE,n=!!e?.exec_fallback,r=t["thread/start"]&&t["turn/start"],i=t["thread/resume"]&&t["turn/start"];return{list:t["thread/list"],search:t["thread/list"],read:t["thread/items/list"]||t["thread/turns/list"],resume:i||n&&t["thread/read"],start:r||n,cancel:t["turn/interrupt"]||n&&(!r||!i),usage:!!e,authorities:e?["read_only","workspace_write"]:[],max_page_size:25}}selection(){let e=this.capabilities(),t=this.probe?.methods??nE;return{start:e.start?t["thread/start"]&&t["turn/start"]?"app-server":"exec":null,resume:e.resume?t["thread/resume"]&&t["turn/start"]?"app-server":"exec":null}}async ready(){let e=await this.connect();return"ready"===e.status?to(void 0):ta("auth_required"===e.status?"auth_required":"unsupported"===e.status?"unsupported":"unavailable",e.detail)}async connect(){return this.client&&!this.client.closed&&this.probe?.status==="ready"?this.probe:(this.connecting||(this.connecting=this.doConnect().finally(()=>{this.connecting=null})),this.connecting)}cliVersion(){return new Promise(e=>{(0,tc.execFile)(this.command[0],[...this.command.slice(1),"--version"],{env:this.env,timeout:1e4},(t,n)=>{if(t)return e(null);let r=/(\d+\.\d+\.\d+[0-9A-Za-z.+-]*)/.exec(String(n));e(r?r[1]:null)})})}async doConnect(){let e=await this.cliVersion(),t=(t,n)=>(this.probe={status:t,cli_version:e,methods:{...nE},exec_fallback:!1,detail:n},this.probe);this.client?.close(),this.client=null;let n=new ns((this.options.transport??((e,t)=>(function(e,t={}){let n,r=[],i=[],s=!1,a=e=>{if(!s)for(let t of(s=!0,i))t(e)};try{n=(0,tc.spawn)(e[0],e.slice(1),{stdio:["pipe","pipe","pipe"],env:t.env??process.env,cwd:t.cwd})}catch(e){return queueMicrotask(()=>a(`spawn failed: ${e.message}`)),{send:()=>{},onLine:e=>r.push(e),onClose:e=>i.push(e),close:()=>{}}}let o="";return n.stdout?.setEncoding("utf8"),n.stdout?.on("data",e=>{let t;for(o+=e;(t=o.indexOf("\n"))>=0;){let e=o.slice(0,t).trim();if(o=o.slice(t+1),e)for(let t of r)t(e)}}),n.stderr?.resume(),n.stdin?.on("error",()=>{}),n.on("error",e=>a(`spawn failed: ${e.code??e.message}`)),n.on("exit",(e,t)=>a(`exited (${t??e})`)),{send(e){!s&&n.stdin?.writable&&n.stdin.write(`${e}
|
|
1897
|
+
`)},onLine:e=>r.push(e),onClose:e=>i.push(e),close(){s||(n.stdin?.end(),n.kill("SIGTERM"))}}})([...e,"app-server"],{env:th(t)})))(this.command,this.env),this.options.requestTimeoutMs??3e4),r=await n.request("initialize",{clientInfo:{name:"botmancers",title:"Botmancers",version:"1"},capabilities:null},{timeoutMs:2e4});if(!r.ok)return(n.close(),null===e)?t("unavailable",`codex is not installed or did not start (${r.error.message})`):t("rpc"===r.kind?"unsupported":"unavailable",`codex ${e}: app-server initialize failed (${r.error.message})`);n.notify("initialized");let i=await Promise.all(n_.map(e=>n.request(e,nc[e],{timeoutMs:1e4}))),s={...nE};if(n_.forEach((e,t)=>{var n;let r=i[t];s[e]=r.ok||"rpc"===r.kind&&(n=r.error,!(!(-32601!==n.code||/not supported yet/i.test(n.message))||n.message.includes(`unknown variant \`${e}\``)))}),!s["thread/list"])return n.close(),t("unsupported",`codex ${e??"unknown"}: app-server has no thread/list`);let a=await n.request("account/read",{},{timeoutMs:1e4});return a.ok&&a.result&&null==a.result.account&&!0===a.result.requiresOpenaiAuth?(n.close(),t("auth_required","codex is not signed in")):(this.attach(n),this.probe={status:"ready",cli_version:e,methods:s,exec_fallback:!1!==this.options.execFallback&&null!==e,detail:`codex ${e??"unknown"} app-server`},this.probe)}attach(e){this.client=e;let t=new Map;this.loads=t,e.onClose(()=>{for(let e of t.values())e?.end("app_server_exit");t.clear()}),e.handleServerRequests(e=>"item/commandExecution/requestApproval"===e||"item/fileChange/requestApproval"===e?{result:{decision:"decline"}}:"applyPatchApproval"===e||"execCommandApproval"===e?{result:{decision:{denied:{rejection:"Botmancers turns run with a fixed authority."}}}}:{error:{code:-32601,message:"not supported by Botmancers"}}),e.onNotification(({method:e,params:n})=>{if("thread/closed"===e&&"string"==typeof n.threadId){t.get(n.threadId)?.end("thread_unload"),t.delete(n.threadId);return}let r="string"==typeof n.turnId?n.turnId:n.turn&&"string"==typeof n.turn.id?n.turn.id:null;if(!r||"string"!=typeof n.threadId)return;let i=this.tracker(r,n.threadId);if("item/completed"===e){let e=n.item;e?.type==="agentMessage"&&"string"==typeof e.text&&e.text&&(i.output=e.text,"final_answer"===e.phase&&(i.finalOutput=e.text))}else if("thread/tokenUsage/updated"===e){var s;i.usage=function(e,t){if(!e)return t;if(!t)return e;let n=(e,t)=>null==e&&null==t?null:(e??0)+(t??0);return{input_tokens:n(e.input_tokens,t.input_tokens),output_tokens:n(e.output_tokens,t.output_tokens),cached_input_tokens:n(e.cached_input_tokens,t.cached_input_tokens),cost_usd:null}}(i.usage,(s=n.tokenUsage?.last)&&"object"==typeof s?nd(no(s.inputTokens),no(s.cachedInputTokens),no(s.outputTokens)):null)}else if("turn/completed"===e){let e=n.turn;this.settle(i,e)}}),e.onClose(()=>{for(let e of this.trackers.values())"inProgress"===e.status&&(e.status="lost",e.error="the Codex app-server exited during the turn",e.finishedAt=Date.now(),e.waiters.splice(0).forEach(e=>e()))})}tracker(e,t){let n=this.trackers.get(e);return n||(n={threadId:t,status:"inProgress",output:null,finalOutput:null,usage:null,error:null,finishedAt:null,waiters:[]},this.trackers.set(e,n)),n}settle(e,t){"inProgress"!==t.status&&"inProgress"===e.status&&(e.status="completed"===t.status?"completed":"interrupted"===t.status?"interrupted":"failed",e.output=e.finalOutput??e.output??nR(t.items),e.error=t.error?.message??("failed"===e.status?"codex turn failed":null),e.finishedAt=ng(t.completedAt)??Date.now(),e.waiters.splice(0).forEach(e=>e()),this.scheduleIdle())}scheduleIdle(){this.idleTimer&&clearTimeout(this.idleTimer);let e=this.options.idleMs??3e5;this.idleTimer=setTimeout(()=>{if([...this.trackers.values()].some(e=>"inProgress"===e.status))return this.scheduleIdle();this.client?.close()},e),this.idleTimer.unref?.()}async rpc(e,t,n){let r=await this.connect();return"ready"===r.status&&this.client?(this.scheduleIdle(),this.client.request(e,t,{signal:n.signal??null})):{ok:!1,kind:"closed",error:{code:-1,message:r.detail}}}isLoaded(e){return!!this.client&&!this.client.closed&&this.loads.has(e)}markLoaded(e,t){this.loads.has(e)?t?.end("launch_failed"):this.loads.set(e,t)}mintLoad(e){return e?.mint({kind:"codex_thread_load",ref:`load-${(0,s.randomUUID)()}`,processBound:!0})??null}has(e){return!!this.probe?.methods[e]}shutdown(){this.idleTimer&&clearTimeout(this.idleTimer),this.client?.close(),this.client=null,this.probe=null}async listSessions(e){let t=nT(e.cursor);if("sessions"===e.scope.kind){let n=Number(t?.i??0),r=e.scope.provider_session_ids.slice(n,n+e.limit),i=[];for(let t of r){let n=await this.getSession({...e,provider_session_id:t});if(!n.ok)return n;n.value&&i.push(n.value)}return to({items:i,next_cursor:n+e.limit<e.scope.provider_session_ids.length?nf({i:n+e.limit}):null})}let n=t?.phase==="archived"?"archived":"open",r=await this.rpc("thread/list",{limit:e.limit,cursor:"string"==typeof t?.c?t.c:null,archived:"archived"===n,sourceKinds:nl,sortKey:"updated_at",...e.query?{searchTerm:e.query}:{}},e);if(!r.ok)return ny(r,"thread/list");let i=(Array.isArray(r.result?.data)?r.result.data:[]).filter(e=>e&&"string"==typeof e.id&&!0!==e.ephemeral&&!e.parentThreadId).map(e=>nh(e,n)).filter(t=>"all_provider_sessions"===e.scope.kind||null!==t.workspace&&e.scope.workspaces.some(e=>O(e,t.workspace))),s=r.result?.nextCursor??null;return to({items:i,next_cursor:s?nf({phase:n,c:s}):"open"===n?nf({phase:"archived"}):null})}async getSession(e){let t=await this.rpc("thread/read",{threadId:e.provider_session_id},e);if(!t.ok)return nk(t)?to(null):ny(t,"thread/read");let n=t.result?.thread;return to(n&&"string"==typeof n.id?nh(n):null)}async readTranscript(e){let t=nT(e.cursor)??{},n=Number(t.n??0),r=e.provider_session_id;if("turns"!==t.mode&&this.has("thread/items/list")){let i=await this.rpc("thread/items/list",{threadId:r,cursor:"string"==typeof t.c?t.c:null,limit:e.limit,sortDirection:"asc"},e);if(i.ok){let t=(i.result?.data??[]).slice(0,e.limit);return to({items:t.map((e,t)=>nN(e.item??{},n+t+1,e.completedAtMs??e.startedAtMs??null)).filter(e=>null!==e),next_cursor:i.result?.nextCursor?nf({c:i.result.nextCursor,n:n+t.length}):null})}if(nk(i))return ta("not_found","no such thread");if("rpc"!==i.kind||-32601!==i.error.code)return ny(i,"thread/items/list")}if(!this.has("thread/turns/list"))return ta("unsupported","no transcript method");let i="string"==typeof t.c?t.c:null,s=Number(t.skip??0),a=await this.rpc("thread/turns/list",{threadId:r,cursor:i,limit:1,sortDirection:"asc",itemsView:"full"},e);if(!a.ok)return nk(a)?ta("not_found","no such thread"):ny(a,"thread/turns/list");let o=(a.result?.data??[])[0];if(!o)return to({items:[],next_cursor:null});let d=Array.isArray(o.items)?o.items:[],u=d.slice(s,s+e.limit),l=u.map((e,t)=>nN(e,n+t+1,null)).filter(e=>null!==e),_=n+u.length;return to({items:l,next_cursor:s+e.limit<d.length?nf({mode:"turns",c:i,skip:s+e.limit,n:_}):a.result?.nextCursor?nf({mode:"turns",c:a.result.nextCursor,skip:0,n:_}):null})}turnInput(e){return[{type:"text",text:e,text_elements:[]}]}async beginTurn(e,t,n){var r;let i=await this.rpc("turn/start",{threadId:e,input:this.turnInput(n.prompt),cwd:t,approvalPolicy:"never",sandboxPolicy:(r=n.authority,"workspace_write"===r?{type:"workspaceWrite",writableRoots:[t],networkAccess:!1,excludeTmpdirEnvVar:!1,excludeSlashTmp:!1}:{type:"readOnly",networkAccess:!1}),clientUserMessageId:n.idempotency_key},n);if(!i.ok)return nk(i)?ta("not_found","no such thread"):ny(i,"turn/start");let s=i.result?.turn;if(!s||"string"!=typeof s.id)return ta("unavailable","turn/start returned no turn");let a=this.tracker(s.id,e);this.settle(a,s);let o={provider_turn_id:np("as",e,s.id),provider_session_id:e};return this.keys.set(n.idempotency_key,o),to(o)}async startSession(e){let t=this.keys.get(e.idempotency_key)??this.execRunByKey(e.idempotency_key);if(t)return to(t);let n=this.selection().start;if(null===n)return ta("unsupported","this Codex cannot start sessions");if("exec"===n)return this.execStart(null,e.workspace,e);let r=this.mintLoad(e.session_context),i=await this.rpc("thread/start",{cwd:e.workspace,approvalPolicy:"never",sandbox:nv(e.authority),ephemeral:!1,...r?{config:tR(r)}:{}},e),s=i.ok?i.result?.thread?.id:void 0;return("string"!=typeof s&&r?.end("launch_failed"),i.ok)?"string"!=typeof s?ta("unavailable","thread/start returned no thread"):(this.markLoaded(s,r),this.beginTurn(s,e.workspace,e)):ny(i,"thread/start")}async findKeyedTurn(e,t,n){if(!this.has("thread/turns/list"))return null;let r=await this.rpc("thread/turns/list",{threadId:e,limit:5,sortDirection:"desc",itemsView:"full"},n);if(!r.ok)return null;for(let e of r.result?.data??[])if((e.items??[]).some(e=>e?.type==="userMessage"&&e.clientId===t))return e.id;return null}async sendTurn(e){let t=this.keys.get(e.idempotency_key)??this.execRunByKey(e.idempotency_key);if(t)return to(t);let n=e.provider_session_id,i=this.selection().resume;if(null===i)return ta("unsupported","this Codex cannot resume sessions");if("exec"===i){let t=await this.getSession(e);return t.ok?t.value?t.value.resumable&&t.value.workspace?this.execStart(n,t.value.workspace,e):ta("not_resumable","the thread cannot be resumed"):ta("not_found","no such thread"):t}await this.connect();let s=this.isLoaded(n)?null:this.mintLoad(e.session_context),a=await this.rpc("thread/resume",{threadId:n,approvalPolicy:"never",sandbox:nv(e.authority),excludeTurns:!0,...s?{config:tR(s)}:{}},e);if(!a.ok)return s?.end("launch_failed"),nk(a)?ta("not_found","no such thread"):ny(a,"thread/resume");this.isLoaded(n)||this.markLoaded(n,s);let o="string"==typeof a.result?.cwd?a.result.cwd:a.result?.thread?.cwd;if(!o||!r.default.existsSync(o))return ta("not_resumable","the thread workspace no longer exists");let d=await this.findKeyedTurn(n,e.idempotency_key,e);if(d){let t={provider_turn_id:np("as",n,d),provider_session_id:n};return this.keys.set(e.idempotency_key,t),to(t)}return a.result?.thread?.status?.type==="active"?ta("busy","the thread has a turn in flight"):this.beginTurn(n,o,e)}result(e){let t="completed"===e.status?"completed":"interrupted"===e.status?"cancelled":"failed";return{status:t,provider_session_id:e.threadId,output:e.output,failure:"completed"===t?null:"cancelled"===t?{code:"cancelled",message:"interrupted"}:{code:"lost"===e.status?"interrupted":"codex_turn_failed",message:e.error??"codex turn failed"},usage:e.usage,finished_at:e.finishedAt??Date.now()}}async recover(e,t,n){let r=null;for(let i=0;i<10;i++){let i=await this.rpc("thread/turns/list",{threadId:e,cursor:r,limit:10,sortDirection:"desc",itemsView:"full"},n);if(!i.ok)return nk(i)?ta("not_found","no such thread"):ny(i,"thread/turns/list");let s=(i.result?.data??[]).find(e=>e.id===t);if(s){let r=this.tracker(t,e);if("inProgress"!==s.status)return this.settle(r,s),to(r);let i=await this.rpc("thread/read",{threadId:e},n);if(i.ok&&i.result?.thread?.status?.type==="active")return(await this.rpc("thread/resume",{threadId:e,excludeTurns:!0},n)).ok&&!this.isLoaded(e)&&this.markLoaded(e,null),to(r);return r.status="lost",r.output=nR(s.items),r.error="the turn ended without a result (its Codex app-server exited)",r.finishedAt=Date.now(),to(r)}if(!(r=i.result?.nextCursor??null))break}return ta("not_found","no such turn")}async liveTracker(e,t,n){let r=this.trackers.get(t);return r&&("inProgress"!==r.status||this.client&&!this.client.closed)?to(r):this.has("thread/turns/list")||(await this.connect(),this.has("thread/turns/list"))?this.recover(e,t,n):ta("unsupported","cannot read turn history")}async observeTurn(e){let t=nm(e.provider_turn_id);if(!t)return ta("not_found","unknown turn handle");if("ex"===t.kind)return this.execObserve(t.threadId,t.id,e);let n=await this.liveTracker(t.threadId,t.id,e);if(!n.ok)return n;let r=n.value;for(;"inProgress"===r.status;){let t=await new Promise(t=>{let n=()=>o("done"),i=()=>o("aborted"),s="number"==typeof e.deadline_at?Math.max(0,e.deadline_at-Date.now()):null,a=null===s?null:setTimeout(()=>o("deadline"),s);function o(s){a&&clearTimeout(a),e.signal?.removeEventListener("abort",i);let o=r.waiters.indexOf(n);o>=0&&r.waiters.splice(o,1),t(s)}if(e.signal?.aborted)return o("aborted");r.waiters.push(n),e.signal?.addEventListener("abort",i,{once:!0})});if("aborted"===t)return ta("cancelled","observe aborted");if("deadline"===t)return ta("timed_out","observe deadline")}return to(this.result(r))}async cancelTurn(e){let t=nm(e.provider_turn_id);if(!t)return ta("not_found","unknown turn handle");if("ex"===t.kind)return this.execCancel(t.id);let n=await this.liveTracker(t.threadId,t.id,e);if(!n.ok)return n;let r=n.value;if("inProgress"!==r.status)return to("already_terminal");if(!this.has("turn/interrupt"))return ta("unsupported","this Codex cannot interrupt turns");let i=await this.rpc("turn/interrupt",{threadId:t.threadId,turnId:t.id},e);if(!i.ok)return"inProgress"!==r.status?to("already_terminal"):ny(i,"turn/interrupt");let s=Date.now()+1e4;for(;"inProgress"===r.status&&Date.now()<s;)await new Promise(e=>setTimeout(e,20));return"inProgress"===r.status||"interrupted"===r.status?(r.status="interrupted",r.finishedAt=r.finishedAt??Date.now(),r.waiters.splice(0).forEach(e=>e()),to("cancelled")):to("already_terminal")}runPath(e,t){return i.default.join(this.runsDir,`${e.replace(/[^A-Za-z0-9-]/g,"")}.${t}`)}readMeta(e){try{return JSON.parse(r.default.readFileSync(this.runPath(e,"json"),"utf8"))}catch{return null}}execRunByKey(e){if(!r.default.existsSync(this.runsDir))return null;for(let t of r.default.readdirSync(this.runsDir)){if(!t.endsWith(".json"))continue;let n=this.readMeta(t.slice(0,-5));if(n?.key===e&&"string"==typeof n.thread_id)return{provider_turn_id:np("ex",n.thread_id,String(n.run_id)),provider_session_id:n.thread_id}}return null}async execStart(e,t,n){let i,a;r.default.mkdirSync(this.runsDir,{recursive:!0});let o=(0,s.randomUUID)(),d=n.session_context?.mint({kind:"codex_exec",ref:o})??null,u=["-c",`sandbox_mode="${nv(n.authority)}"`,"-c",'approval_policy="never"',...d?(a=`mcp_servers.${tf}`,["-c",`${a}.url=${JSON.stringify(d.url)}`,"-c",`${a}.env_http_headers={ ${JSON.stringify(tE)} = ${JSON.stringify(tm)} }`,"-c",`${a}.enabled_tools=[${JSON.stringify(tT)}]`,"-c",`${a}.tools.${tT}.approval_mode="approve"`]):[]],l=th(this.env);d&&(l[tm]=d.token);let _=e?[...this.command.slice(1),"exec","resume","--json",...u,e,"-"]:[...this.command.slice(1),"exec","--json","-C",t,...u,"-"],c=r.default.openSync(this.runPath(o,"jsonl"),"a");try{i=(0,tc.spawn)(this.command[0],_,{cwd:t,env:l,detached:!0,stdio:["pipe",c,"ignore"]})}catch(e){return r.default.closeSync(c),d?.end("launch_failed"),ta("unavailable",`codex exec did not start: ${e.message}`)}r.default.closeSync(c);let E=new Promise(e=>i.once("error",t=>e(t.message)));i.stdin?.on("error",()=>{}),i.stdin?.end(n.prompt);let p={run_id:o,pid:i.pid??null,thread_id:e,key:n.idempotency_key,authority:n.authority,cwd:t,correlation:n.correlation??{},cancelled:!1,started_at:Date.now()};if(r.default.writeFileSync(this.runPath(o,"json"),JSON.stringify(p)),i.unref(),!e){let e=Date.now()+3e4,t=null;for(E.then(e=>{t=e});;){let n=nu(na(this.readLog(o)));if(n.thread_id){p.thread_id=n.thread_id,r.default.writeFileSync(this.runPath(o,"json"),JSON.stringify(p));break}if(t||n.terminal||Date.now()>e||p.pid&&!nL(p.pid))return ta("unavailable",`codex exec reported no thread${t?`: ${t}`:""}`);await new Promise(e=>setTimeout(e,25))}}return to({provider_turn_id:np("ex",p.thread_id,o),provider_session_id:p.thread_id})}readLog(e){try{return r.default.readFileSync(this.runPath(e,"jsonl"),"utf8")}catch{return""}}execResult(e,t){let n=this.readMeta(t);if(!n)return null;let r=nu(na(this.readLog(t))),i="number"==typeof n.pid&&nL(n.pid);if(!r.terminal&&i&&!n.cancelled)return null;let s=n.cancelled&&"completed"!==r.terminal?"cancelled":"completed"===r.terminal?"completed":"failed";return{status:s,provider_session_id:e,output:r.output,failure:"completed"===s?null:"cancelled"===s?{code:"cancelled",message:"interrupted"}:{code:r.terminal?"codex_turn_failed":"interrupted",message:r.error??"codex exec ended without a result"},usage:r.usage,finished_at:Number(n.finished_at??Date.now())}}async execObserve(e,t,n){if(!this.readMeta(t))return ta("not_found","no such run");for(;;){let r=this.execResult(e,t);if(r)return to(r);if(n.signal?.aborted)return ta("cancelled","observe aborted");if("number"==typeof n.deadline_at&&Date.now()>=n.deadline_at)return ta("timed_out","observe deadline");await new Promise(e=>setTimeout(e,25))}}execCancel(e){let t=this.readMeta(e);if(!t)return ta("not_found","no such run");let n=nu(na(this.readLog(e)));if(t.cancelled||n.terminal||"number"!=typeof t.pid||!nL(t.pid))return to("already_terminal");try{process.kill(t.pid,"SIGINT")}catch{return to("already_terminal")}return r.default.writeFileSync(this.runPath(e,"json"),JSON.stringify({...t,cancelled:!0,finished_at:Date.now()})),to("cancelled")}}function nL(e){try{return process.kill(e,0),!0}catch{return!1}}let nO=null;"off"!==process.env.BOTMANCERS_CODEX_PROVIDER&&t_("codex",()=>{var e;return nO||(nO=new nw),e=nO,{kind:"codex-direct",capabilities:()=>e.capabilities(),ready:()=>e.ready(),listSessions:t=>e.listSessions(t),getSession:t=>e.getSession(t),readTranscript:t=>e.readTranscript(t),startSession:t=>e.startSession(t),sendTurn:t=>e.sendTurn(t),observeTurn:t=>e.observeTurn(t),cancelTurn:t=>e.cancelTurn(t)}}),e.s([],78636);let nI="cursor",nA=/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/,nS=new Map,nb=`
|
|
1898
|
+
import { createRequire } from 'module';
|
|
1899
|
+
import { pathToFileURL } from 'url';
|
|
1900
|
+
import path from 'path';
|
|
1901
|
+
const [op, spec, ...rest] = process.argv.slice(1);
|
|
1902
|
+
const out = value => process.stdout.write(JSON.stringify(value) + '\\n');
|
|
1903
|
+
async function load() {
|
|
1904
|
+
const abs = path.isAbsolute(spec) ? spec : createRequire(path.join(process.cwd(), 'package.json')).resolve(spec);
|
|
1905
|
+
const mod = await import(pathToFileURL(abs).href);
|
|
1906
|
+
return mod.default && mod.default.Agent ? mod.default : mod;
|
|
1907
|
+
}
|
|
1908
|
+
try {
|
|
1909
|
+
const sdk = await load();
|
|
1910
|
+
const Agent = sdk.Agent;
|
|
1911
|
+
if (op === 'probe') {
|
|
1912
|
+
out({ resume: typeof Agent?.resume === 'function', create: typeof Agent?.create === 'function', list: typeof Agent?.list === 'function', version: typeof sdk.version === 'string' ? sdk.version : null });
|
|
1913
|
+
} else if (op === 'create') {
|
|
1914
|
+
const chat = await Agent.create({ cwd: rest[0] });
|
|
1915
|
+
out({ id: chat && chat.id });
|
|
1916
|
+
} else if (op === 'list') {
|
|
1917
|
+
out(await Agent.list({}));
|
|
1918
|
+
} else if (op === 'turn') {
|
|
1919
|
+
const [id, cwd, mode, prompt] = rest;
|
|
1920
|
+
const agent = await Agent.resume(id, { cwd, mode: mode === '-' ? null : mode });
|
|
1921
|
+
for await (const event of agent.stream(prompt)) out(event);
|
|
1922
|
+
} else {
|
|
1923
|
+
process.exit(2);
|
|
1924
|
+
}
|
|
1925
|
+
} catch (error) {
|
|
1926
|
+
if (op === 'turn') out({ type: 'result', subtype: 'sdk_error', is_error: true, result: null });
|
|
1927
|
+
process.exit(op === 'probe' ? 3 : 1);
|
|
1928
|
+
}
|
|
1929
|
+
`;function nq(e,t,n){return["--input-type=module","-e",nb,e,t.sdkModule,...n]}function nC(e){return"string"==typeof e?e:null}function nx(e,t){let n=e.env??process.env,r=e.stateDir??(n.BOTMANCERS_CURSOR_STATE_DIR?.trim()||i.default.join(i.default.dirname(i.default.resolve(eX(n))),"providers","cursor"));return{cliPath:e.cliPath??(n.BOTMANCERS_CURSOR_CLI?.trim()||"cursor-agent"),sdkModule:e.sdkModule??(n.BOTMANCERS_CURSOR_SDK_MODULE?.trim()||"@cursor/sdk"),stateDir:i.default.join(r,t.replace(/[^A-Za-z0-9._-]/g,"_")),pollMs:e.pollMs??100,env:void 0!==n[tp]||void 0!==n[tm]?th(n):n}}function nD(e){return i.default.join(e.stateDir,"state.json")}function nU(e,t,n){return i.default.join(e.stateDir,"turns",`${t}.${n}`)}function nF(e){try{let t=JSON.parse(r.default.readFileSync(nD(e),"utf8"));if(t&&1===t.version)return t}catch{}return{version:1,chats:{},turns:{},keys:{}}}function nW(e,t){r.default.mkdirSync(i.default.join(e.stateDir,"turns"),{recursive:!0});let n=`${nD(e)}.${process.pid}.${(0,s.randomUUID)()}.tmp`;r.default.writeFileSync(n,JSON.stringify(t)),r.default.renameSync(n,nD(e))}function nM(e){try{return r.default.readFileSync(e,"utf8")}catch{return null}}function nH(e){if(!e)return!1;try{return process.kill(e,0),!0}catch(e){return"EPERM"===e.code}}function nX(e){try{return r.default.realpathSync(e)}catch{return i.default.resolve(e)}}function nG(e){try{return r.default.statSync(e).isDirectory()}catch{return!1}}function n$(e,t,n,r){return{state:"terminal",parsed:n,result:{status:"failed",provider_session_id:e.chat,output:null,failure:{code:t,message:t},usage:n.result?.usage??null,finished_at:r}}}function nB(e,t){let n=nM(nU(e,t.id,"exit")),r=null!==n||!nH(t.pid),i=function(e,t=!1){let n={init:null,steps:[],result:null,result_events:0,malformed:0},r=e.split("\n");for(let e of(t||r.pop(),r)){let t,r=e.trim();if(!r)continue;try{let e=JSON.parse(r);if(!e||"object"!=typeof e||Array.isArray(e))throw Error("not an object");t=e}catch{n.malformed++;continue}let i="number"==typeof t.timestamp_ms?t.timestamp_ms:null;if("system"!==t.type||"init"!==t.subtype||n.init)if("assistant"===t.type){let e=function(e){let t=e?.content;if("string"==typeof t)return t;if(!Array.isArray(t))return null;let n=t.map(e=>e&&"text"===e.type?nC(e.text):null).filter(e=>null!==e);return n.length?n.join(""):null}(t.message);e&&n.steps.push({role:"assistant",text:e,at:i})}else"tool_call"===t.type&&"completed"===t.subtype?n.steps.push({role:"tool",text:`${function(e){let t=Object.keys(e.tool_call&&"object"==typeof e.tool_call?e.tool_call:{}).find(e=>/ToolCall$/.test(e));return t?t.replace(/ToolCall$/,""):"tool"}(t)} (completed)`,at:i}):"result"===t.type&&(n.result_events++,n.result||(n.result={ok:!1===t.is_error&&"success"===t.subtype,subtype:nC(t.subtype),text:nC(t.result),usage:function(e){let t=e.usage&&"object"==typeof e.usage?e.usage:null,n=e.total_cost_usd??t?.costUsd??t?.cost_usd;return t||void 0!==n?ts({input_tokens:t?.inputTokens??t?.input_tokens,output_tokens:t?.outputTokens??t?.output_tokens,cost_usd:n}):null}(t)}));else n.init={session_id:nC(t.session_id),cwd:nC(t.cwd)}}return n}(nM(nU(e,t.id,"out"))??"",r),s=Date.now();if(i.init){if(i.init.session_id!==t.chat)return n$(t,"session_mismatch",i,s);if(null!==i.init.cwd&&nX(i.init.cwd)!==nX(t.workspace))return n$(t,"workspace_mismatch",i,s)}if(i.result){if(!i.result.ok)return n$(t,`cursor_${(i.result.subtype??"error").replace(/[^A-Za-z0-9_]/g,"_").slice(0,40)}`,i,s);let e=i.result.text??(i.steps.filter(e=>"assistant"===e.role).map(e=>e.text).join("\n")||null);return{state:"terminal",parsed:i,result:{status:"completed",provider_session_id:t.chat,output:e,failure:null,usage:i.result.usage,finished_at:s}}}return null!==t.cancel_requested_at?{state:"terminal",parsed:i,result:{status:"cancelled",provider_session_id:t.chat,output:null,failure:{code:"cancelled",message:"cancelled"},usage:null,finished_at:t.cancel_requested_at}}:null!==n?n$(t,`exit_${String(Number.parseInt(n,10))}`,i,s):nH(t.pid)?{state:"running",parsed:i}:n$(t,"process_lost",i,s)}function nK(e,t,n,r,i){return new Promise(s=>{let a=(0,tc.spawn)(e,t,{cwd:n,env:r.env,stdio:["ignore","pipe","ignore"]}),o="",d=setTimeout(()=>a.kill("SIGKILL"),i);a.stdout?.on("data",e=>{o+=String(e)}),a.on("error",()=>{clearTimeout(d),s({status:null,stdout:o})}),a.on("close",e=>{clearTimeout(d),s({status:e,stdout:o})})})}async function nP(e,t,n){let r="cli"===t?await nK(e.cliPath,["create-chat"],n,e,6e4):await nK(process.execPath,nq("create",e,[n]),n,e,6e4);if(0!==r.status)return null;let i=r.stdout.trim().split("\n").pop()?.trim()??"",s=i;if("sdk"===t)try{s=JSON.parse(i).id}catch{s=null}return"string"==typeof s&&nA.test(s)?s:null}function nj(e){if("number"==typeof e&&Number.isFinite(e))return e;if("string"==typeof e){let t=Date.parse(e);return Number.isFinite(t)?t:null}return null}async function nY(e,t){let n;r.default.mkdirSync(e.stateDir,{recursive:!0});let s="cli"===t?await nK(e.cliPath,["ls","--output-format","json"],e.stateDir,e,6e4):await nK(process.execPath,nq("list",e,[]),e.stateDir,e,6e4);if(0!==s.status)return null;try{n=JSON.parse(s.stdout.trim())}catch{return null}let a=Array.isArray(n)?n:n?.sessions??n?.chats;if(!Array.isArray(a))return null;let o=[];for(let e of a){if(!e||"object"!=typeof e)continue;let t=nC(e.id)??nC(e.chatId)??nC(e.session_id);if(!t||!nA.test(t))continue;let n=nC(e.cwd)??nC(e.workspace);o.push({id:t,workspace:n&&i.default.isAbsolute(n)?n:null,title:nC(e.title)??nC(e.name),created_at:nj(e.createdAt??e.created_at),updated_at:nj(e.updatedAt??e.updated_at)})}return o}e.s(["CURSOR_PROVIDER_KIND",0,nI,"cursorSessionProviderFactory",0,function(e){return function(e,t={}){let n=nx(t,e.id),a=()=>(function(e={}){let t=nx(e,"probe"),n=`${t.cliPath}
|
|
1930
|
+
${t.sdkModule}
|
|
1931
|
+
${t.env===process.env?"":JSON.stringify(t.env)}`,r=nS.get(n);if(r&&Date.now()-r.at<3e5)return r.probe;let i=function(e){let t=(0,tc.spawnSync)(e.cliPath,["--version"],{encoding:"utf8",timeout:15e3,env:e.env,stdio:["ignore","pipe","pipe"]}),n=0===t.status?String(t.stdout??"").trim().split("\n").pop()?.trim()??"":"";if(!/^[0-9][\w.+-]{0,80}$/.test(n))return{available:!1,version:null,list:!1};let r=(0,tc.spawnSync)(e.cliPath,["ls","--help"],{encoding:"utf8",timeout:15e3,env:e.env,stdio:["ignore","pipe","pipe"]});return{available:!0,version:n,list:0===r.status&&/--output-format\b[^\n]*\bjson\b/.test(String(r.stdout??""))}}(t),s=i.available?{available:!1,version:null,list:!1}:function(e){let t=(0,tc.spawnSync)(process.execPath,nq("probe",e,[]),{encoding:"utf8",timeout:15e3,env:e.env,stdio:["ignore","pipe","pipe"]});if(0!==t.status)return{available:!1,version:null,list:!1};try{let e=JSON.parse(String(t.stdout).trim().split("\n").pop()??""),n=!0===e.resume&&!0===e.create;return{available:n,version:n&&"string"==typeof e.version?e.version.slice(0,80):null,list:n&&!0===e.list}}catch{return{available:!1,version:null,list:!1}}}(t),a={backend:i.available?"cli":s.available?"sdk":null,cli:i,sdk:s};return nS.set(n,{at:Date.now(),probe:a}),a})(t),o=()=>{var e;let t;return t=null!==(e=a()).backend,{list:"cli"===e.backend?e.cli.list:"sdk"===e.backend&&e.sdk.list,search:!1,read:t,resume:t,start:t,cancel:t,usage:t,authorities:t?["read_only","workspace_write"]:[],max_page_size:50}},d=e=>ta(null===a().backend?"unavailable":"unsupported",`Cursor ${e} is not available.`);function u(e,t,r){let i=r.turns.some(t=>e.turns[t]&&"running"===nB(n,e.turns[t]).state),s=r.turns.length?e.turns[r.turns[r.turns.length-1]]?.started_at??r.updated_at:r.updated_at;return{provider_session_id:t,title:r.title,workspace:r.workspace,created_at:r.created_at,updated_at:Math.max(r.updated_at,s),lifecycle:"open",resumable:!0,busy:i}}async function l(e){let t=await nY(n,e);return t?to(t):ta("unavailable","Cursor session listing failed.")}function _(e,t,a,o){let d=e.chats[a],u={id:`ct-${(0,s.randomUUID)()}`,chat:a,workspace:d.workspace,prompt:o.prompt,authority:o.authority,backend:t,pid:null,started_at:Date.now(),cancel_requested_at:null,correlation:{...o.correlation}};return e.turns[u.id]=u,e.keys[o.idempotency_key]=u.id,d.turns.push(u.id),nW(n,e),u.pid=function(e,t){r.default.mkdirSync(i.default.join(e.stateDir,"turns"),{recursive:!0});let[n,s]="cli"===t.backend?[e.cliPath,["--print","--output-format","stream-json","--trust","--workspace",t.workspace,..."read_only"===t.authority?["--mode","ask"]:[],"--resume",t.chat,t.prompt]]:[process.execPath,nq("turn",e,[t.chat,t.workspace,"read_only"===t.authority?"ask":"-",t.prompt])];try{let r=(0,tc.spawn)("/bin/sh",["-c",'"$@" >"$BM_OUT" 2>"$BM_ERR" </dev/null; echo $? >"$BM_EXIT.tmp" && mv "$BM_EXIT.tmp" "$BM_EXIT"',"sh",n,...s],{cwd:t.workspace,detached:!0,stdio:"ignore",env:{...e.env,BM_OUT:nU(e,t.id,"out"),BM_ERR:nU(e,t.id,"err"),BM_EXIT:nU(e,t.id,"exit"),BOTMANCERS_CORRELATION:JSON.stringify(t.correlation)}});return r.on("error",()=>{}),r.unref(),r.pid??null}catch{return null}}(n,u),nW(n,e),to({provider_turn_id:u.id,provider_session_id:a})}function c(e,t){let n=e.keys[t];return n&&e.turns[n]?to({provider_turn_id:n,provider_session_id:e.turns[n].chat}):null}return{kind:nI,probe:a,capabilities:o,async listSessions(e){let t=a().backend;if(!t||!o().list)return d("session listing");let r=await l(t);if(!r.ok)return r;let i=nF(n),s=r.value.filter(t=>{var n,r,i;return n=e.scope,r=t.id,i=t.workspace,"all_provider_sessions"===n.kind||("sessions"===n.kind?n.provider_session_ids.includes(r):null!==i&&n.workspaces.some(e=>i===e||i.startsWith(`${e.replace(/\/+$/,"")}/`)))}),_=e.cursor&&/^\d+$/.test(e.cursor)?Number(e.cursor):0,c=s.slice(_,_+Math.min(e.limit,50)),E=Date.now();for(let e of c)!i.chats[e.id]&&e.workspace&&(i.chats[e.id]={workspace:e.workspace,title:e.title,origin:"listed",created_at:e.created_at??E,updated_at:e.updated_at??E,turns:[]});return nW(n,i),to({items:c.map(e=>i.chats[e.id]?{...u(i,e.id,i.chats[e.id]),title:e.title??i.chats[e.id].title}:{provider_session_id:e.id,title:e.title,workspace:null,created_at:e.created_at,updated_at:e.updated_at,lifecycle:"open",resumable:!1,busy:!1}),next_cursor:_+c.length<s.length?String(_+c.length):null})},async getSession(e){let t=a().backend;if(!t)return d("sessions");let r=nF(n),i=r.chats[e.provider_session_id];if(!i)return to(null);if(o().list){let n=await l(t);if(!n.ok)return n;if(!n.value.some(t=>t.id===e.provider_session_id))return to(null)}return to(u(r,e.provider_session_id,i))},async importSession(e){let t=a().backend;if(!t)return d("sessions");if(!nA.test(e.provider_session_id))return ta("invalid_input","Not a Cursor session id.");if(!i.default.isAbsolute(e.workspace)||!nG(e.workspace))return ta("invalid_input","workspace must be an existing absolute directory.");let r=nF(n),s=r.chats[e.provider_session_id];if(s)return to(u(r,e.provider_session_id,s));let _=e.workspace,c=null;if(o().list){let n=await l(t);if(!n.ok)return n;let r=n.value.find(t=>t.id===e.provider_session_id);if(!r)return ta("not_found","Cursor does not list that session.");_=r.workspace??_,c=r.title}let E=Date.now();return r.chats[e.provider_session_id]={workspace:_,title:c,origin:o().list?"listed":"imported",created_at:E,updated_at:E,turns:[]},nW(n,r),to(u(r,e.provider_session_id,r.chats[e.provider_session_id]))},async readTranscript(e){if(!a().backend)return d("transcripts");let t=nF(n),r=t.chats[e.provider_session_id];if(!r)return ta("not_found","Unknown Cursor session.");let i=[];for(let e of r.turns){let r=t.turns[e];if(r)for(let e of(i.push({seq:i.length+1,role:"user",text:r.prompt,at:r.started_at}),nB(n,r).parsed.steps))i.push({seq:i.length+1,role:e.role,text:e.text,at:e.at})}let s=e.cursor&&/^\d+$/.test(e.cursor)?Number(e.cursor):0,o=i.slice(s,s+Math.min(e.limit,50));return to({items:o,next_cursor:s+o.length<i.length?String(s+o.length):null})},async startSession(e){let t=a().backend;if(!t)return d("sessions");let r=c(nF(n),e.idempotency_key);if(r)return r;if(!i.default.isAbsolute(e.workspace)||!nG(e.workspace))return ta("invalid_input","workspace must be an existing absolute directory.");let s=await nP(n,t,e.workspace);if(!s)return ta("unavailable","Cursor did not create a chat.");let o=nF(n),u=Date.now();return o.chats[s]={workspace:e.workspace,title:null,origin:"created",created_at:u,updated_at:u,turns:[]},_(o,t,s,e)},async sendTurn(e){let t=a().backend;if(!t)return d("sessions");let r=nF(n),i=c(r,e.idempotency_key);if(i)return i;let s=r.chats[e.provider_session_id];return s?s.turns.some(e=>r.turns[e]&&"running"===nB(n,r.turns[e]).state)?ta("busy","A turn is in flight."):_(r,t,e.provider_session_id,e):ta("not_found","Unknown Cursor session.")},async observeTurn(e){for(;;){let t=nF(n).turns[e.provider_turn_id];if(!t)return ta("not_found","Unknown Cursor turn.");let r=nB(n,t);if("terminal"===r.state)return to(r.result);if(e.signal?.aborted)return ta("cancelled","observe aborted");if("number"==typeof e.deadline_at&&Date.now()>=e.deadline_at)return ta("timed_out","observe deadline");await new Promise(e=>setTimeout(e,n.pollMs))}},async cancelTurn(e){let t=nF(n),r=t.turns[e.provider_turn_id];if(!r)return ta("not_found","Unknown Cursor turn.");if("terminal"===nB(n,r).state)return to("already_terminal");if(r.cancel_requested_at=Date.now(),nW(n,t),r.pid){try{process.kill(-r.pid,"SIGTERM")}catch{}let e=r.pid;setTimeout(()=>{try{process.kill(-e,"SIGKILL")}catch{}},2e3).unref()}return to("cancelled")}}}(e)}],48758)},72414,1537,69312,e=>{"use strict";e.s(["serviceRedactor",()=>j],72414),e.s(["ProviderSessionError",()=>R,"getProviderTurn",()=>W,"observeProviderTurn",()=>F,"privateProviderIds",()=>M,"sendProviderTurn",()=>x],69312),e.s(["attachSessionContextsToTurn",()=>T,"bindSessionContext",()=>f,"endSessionContext",()=>N,"endTurnSessionContexts",()=>h,"mintSessionContext",()=>m],1537);var t=e.i(46786),n=e.i(99904),r=e.i(54799),i=e.i(98307),s=e.i(74455),a=e.i(71711),o=e.i(23325);e.i(78636);var d=e.i(98596),u=e.i(46632),l=e.i(48758),_=e.i(89443);Object.freeze({kind:"service",id:"botmancers-session-context"}),n.default.exec(`
|
|
1932
|
+
CREATE TABLE IF NOT EXISTS session_contexts (
|
|
1933
|
+
id TEXT PRIMARY KEY CHECK (id LIKE 'sctx_%'),
|
|
1934
|
+
token_sha256 TEXT NOT NULL UNIQUE CHECK (length(token_sha256) = 64),
|
|
1935
|
+
agent_id TEXT NOT NULL,
|
|
1936
|
+
-- The public session_ref the context names; null until a started
|
|
1937
|
+
-- session is recorded (then bound once).
|
|
1938
|
+
session_ref TEXT,
|
|
1939
|
+
-- The registry row whose turns keep the context live (the same ref, or
|
|
1940
|
+
-- the provider row behind a binding).
|
|
1941
|
+
registry_ref TEXT,
|
|
1942
|
+
launch_kind TEXT NOT NULL CHECK (launch_kind IN ('claude_turn', 'codex_thread_load', 'codex_exec')),
|
|
1943
|
+
launch_digest TEXT NOT NULL,
|
|
1944
|
+
-- Set for a launch that cannot outlive the Botmancers process (a thread
|
|
1945
|
+
-- load in its app-server child).
|
|
1946
|
+
process_ref TEXT,
|
|
1947
|
+
-- The Botmancers turn whose launch this is (a Claude turn process, a
|
|
1948
|
+
-- codex exec run); null for a Codex thread load, which outlives a turn.
|
|
1949
|
+
turn_ref TEXT,
|
|
1950
|
+
state TEXT NOT NULL CHECK (state IN ('live', 'ended', 'revoked')),
|
|
1951
|
+
end_reason TEXT,
|
|
1952
|
+
created_at INTEGER NOT NULL,
|
|
1953
|
+
ended_at INTEGER,
|
|
1954
|
+
updated_at INTEGER NOT NULL
|
|
1955
|
+
);
|
|
1956
|
+
CREATE INDEX IF NOT EXISTS idx_session_contexts_launch ON session_contexts(launch_digest, state);
|
|
1957
|
+
CREATE INDEX IF NOT EXISTS idx_session_contexts_agent ON session_contexts(agent_id, state);
|
|
1958
|
+
CREATE INDEX IF NOT EXISTS idx_session_contexts_turn ON session_contexts(turn_ref, state);
|
|
1959
|
+
`);let c=e=>(0,r.createHash)("sha256").update(e,"utf8").digest("hex");function E(e){let t=n.default.prepare("SELECT id FROM provider_sessions WHERE id = ?").get(e);if(t)return t.id;let r=n.default.prepare("SELECT id FROM provider_sessions WHERE binding_id = ?").get(e);return r?.id??null}function p(e){let t=n.default.prepare("SELECT agent_id FROM session_bindings WHERE id = ?").get(e);if(t)return t.agent_id;let r=n.default.prepare("SELECT agent_id FROM provider_sessions WHERE id = ?").get(e);return r?.agent_id??null}function m(e){var t,i;if(function(){let e=n.default.prepare("SELECT DISTINCT agent_id FROM session_contexts WHERE state = 'live'").all();for(let{agent_id:t}of e)n.bots.getById(t)&&(0,_.shareFromTurnEnabled)(t)||function(e){let t=Date.now();n.default.prepare("UPDATE session_contexts SET state = 'revoked', end_reason = 'owner_off', ended_at = ?, updated_at = ? WHERE agent_id = ? AND state = 'live'").run(t,t,e).changes}(t)}(),!n.bots.getById(e.agentId)||!(0,_.shareFromTurnEnabled)(e.agentId)||null!==e.sessionRef&&p(e.sessionRef)!==e.agentId)return null;let s=`bmsc_${(0,r.randomBytes)(32).toString("base64url")}`,a=`sctx_${(0,r.randomBytes)(16).toString("base64url")}`,o=Date.now();return n.default.prepare(`
|
|
1960
|
+
INSERT INTO session_contexts (id, token_sha256, agent_id, session_ref, registry_ref, launch_kind, launch_digest, process_ref, state, created_at, updated_at)
|
|
1961
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'live', ?, ?)
|
|
1962
|
+
`).run(a,c(s),e.agentId,e.sessionRef,null===e.sessionRef?null:E(e.sessionRef),e.launch.kind,(t=e.launch.kind,i=e.launch.ref,c(`botmancers-session-launch
|
|
1963
|
+
${t}
|
|
1964
|
+
${i}`)),e.processBound?`${process.pid}:${Math.round(performance.timeOrigin)}`:null,o,o),{id:a,token:s,url:function(e=process.env){let t=(e.BOTMANCERS_SESSION_CONTEXT_URL||"").trim();if(t)return t;let n=/^\d{1,5}$/.test((e.PORT||"").trim())?e.PORT.trim():"3333";return`http://127.0.0.1:${n}/api/v0/mcp`}(e.env)}}function f(e,t){return n.default.transaction(()=>{var r;let i=(r=e,n.default.prepare("SELECT * FROM session_contexts WHERE id = ?").get(r));return!!i&&"live"===i.state&&(null!==i.session_ref?i.session_ref===t:p(t)!==i.agent_id?(g(i.id,"ended","session_changed"),!1):(n.default.prepare("UPDATE session_contexts SET session_ref = ?, registry_ref = ?, updated_at = ? WHERE id = ? AND session_ref IS NULL").run(t,E(t),Date.now(),e),!0))}).immediate()}function T(e,t){let r=n.default.prepare("UPDATE session_contexts SET turn_ref = ?, updated_at = ? WHERE id = ? AND state = 'live' AND turn_ref IS NULL"),i=Date.now();for(let n of e)r.run(t,i,n)}function g(e,t,r){let i=Date.now();return n.default.prepare("UPDATE session_contexts SET state = ?, end_reason = ?, ended_at = ?, updated_at = ? WHERE id = ? AND state = 'live'").run(t,r,i,i,e).changes}function h(e,t="turn_end"){let r=Date.now();return n.default.prepare(`
|
|
1965
|
+
UPDATE session_contexts SET state = 'ended', end_reason = ?, ended_at = ?, updated_at = ?
|
|
1966
|
+
WHERE turn_ref = ? AND state = 'live' AND launch_kind IN ('claude_turn', 'codex_exec')
|
|
1967
|
+
`).run(t,r,r,e).changes}function N(e,t){return 1===g(e,"ended",t)}(0,s.registerBuiltinSessionProvider)("claude",()=>(0,a.createClaudeSessionProvider)()),(0,s.registerSessionProvider)({provider:l.CURSOR_PROVIDER_KIND},l.cursorSessionProviderFactory),(0,s.registerBuiltinSessionProvider)("muse",e=>(0,o.createMuseSessionProvider)(e.id));class R extends Error{code;constructor(e,t){super(t),this.name="ProviderSessionError",this.code=e}}function v(e,t){let n=e.prepare(`
|
|
1968
|
+
SELECT id, runtime_connection_id, session_scope_kind, session_scope_items, policy_mode, allow_new_sessions, allow_resume_with_edits
|
|
1969
|
+
FROM bots WHERE id = ?
|
|
1970
|
+
`).get(t);if(!n)throw new R("agent_not_found","No such Agent.");let r=n.runtime_connection_id?e.prepare("SELECT id, provider FROM runtime_connections WHERE id = ?").get(n.runtime_connection_id):void 0,a=r?(0,s.sessionProviderFor)(r):null;if(!r||!a)throw new R("provider_unavailable","The Agent's runtime connection has no session provider.");return{agentId:t,connection:r,provider:a,capabilities:(0,s.normalizeCapabilities)(a.capabilities()),scope:(0,i.readStoredScope)(n),policy:(0,i.readStoredPolicy)(n)}}async function k(e,t,n={}){let r=v(e,t);if(!r.provider.ready)return r;let i=await r.provider.ready(w(n));return i.ok||y(i.error),{...r,capabilities:(0,s.normalizeCapabilities)(r.provider.capabilities())}}function y(e,t="provider_failed"){throw new R("unsupported"===e.code?"unsupported":"unsupported_authority"===e.code?"authority_not_allowed":"not_found"===e.code?"session_missing":"busy"===e.code?"busy":"not_resumable"===e.code?"not_resumable":"invalid_input"===e.code?"invalid_input":"unavailable"===e.code?"provider_unavailable":"auth_required"===e.code||"permission_denied"===e.code||"incompatible_version"===e.code||"usage_limit"===e.code?e.code:t,`The session provider refused the call (${e.code}).`)}function w(e){return{correlation:{...e.correlation??{}},signal:e.signal??null,deadline_at:e.deadlineAt??null}}let L="SELECT * FROM provider_sessions";function O(e,t,n){let r=e.prepare(`${L} WHERE id = ? AND agent_id = ?`).get(n,t);if(!r)throw new R("session_not_found","No session with that reference.");return r}function I(e,t){e.prepare("INSERT INTO provider_session_events (id, agent_id, session_ref, turn_id, type, detail, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)").run((0,r.randomUUID)(),t.agentId,t.sessionRef??null,t.turnId??null,t.type,JSON.stringify(t.detail??{}),t.now)}function A(e,t,n){"missing"===t.availability?e.prepare("UPDATE provider_sessions SET last_synced_at = ? WHERE id = ?").run(n,t.id):(e.prepare("UPDATE provider_sessions SET availability = 'missing', busy = 0, last_synced_at = ?, updated_at = ? WHERE id = ?").run(n,n,t.id),I(e,{agentId:t.agent_id,sessionRef:t.id,type:"session_missing",now:n}))}async function S(e,t,n,r={}){let i=await k(e,t,r),s=O(e,t,n);if(s.runtime_connection_id!==i.connection.id)throw new R("provider_unavailable","The session belongs to another runtime connection.");let a=await i.provider.getSession({...w(r),provider_session_id:s.provider_session_id});a.ok||y(a.error);let o=r.now??Date.now();return e.transaction(()=>{var n,r,d,u,l,_;let c;null===a.value?A(e,s,o):(n=e,r=i,d=s.id,u=a.value,l=o,n.prepare(`
|
|
1971
|
+
UPDATE provider_sessions SET title = COALESCE(?, title), workspace = COALESCE(?, workspace),
|
|
1972
|
+
provider_created_at = COALESCE(?, provider_created_at), provider_updated_at = COALESCE(?, provider_updated_at),
|
|
1973
|
+
availability = 'available', lifecycle = ?, resumable = ?, busy = ?, capabilities = ?, last_synced_at = ?, updated_at = ?
|
|
1974
|
+
WHERE id = ?
|
|
1975
|
+
`).run((c=(u.title??"").split("\n").map(e=>e.trim()).find(e=>e.length>0))?c.length>80?`${c.slice(0,79).trimEnd()}…`:c:null,"string"==typeof(_=u.workspace)&&_.startsWith("/")?_:null,u.created_at,u.updated_at,"archived"===u.lifecycle?"archived":"open",+!!u.resumable,+!!u.busy,JSON.stringify(r.capabilities),l,l,d),I(e,{agentId:t,sessionRef:s.id,type:"session_synced",now:o}))}).immediate(),O(e,t,n)}function b(e,t,n){return e.prepare("SELECT * FROM provider_session_turns WHERE agent_id = ? AND requester_kind = ? AND requester_id = ? AND idempotency_key = ?").get(t,n.requester.kind,n.requester.id,n.idempotencyKey)}function q(e,t){if(e){if(e.request_hash!==t)throw new R("idempotency_conflict","That idempotency key was used for a different turn.");return e}}function C(e,t){let n=function(e,t=[]){let n=[e.provider_session_id,...t].filter(e=>e.length>0).sort((e,t)=>t.length-e.length);return e=>n.reduce((e,t)=>e.split(t).join("[redacted]"),e)}(e.prepare(`${L} WHERE id = ?`).get(t.session_ref),[t.provider_turn_id]);return{turn_ref:t.id,session_ref:t.session_ref,kind:t.kind,authority:t.authority,state:t.state,output:null===t.output?null:n(t.output),failure_code:t.failure_code,usage:"running"===t.state?null:{input_tokens:t.input_tokens??null,output_tokens:t.output_tokens??null,total_cost_usd:t.total_cost_usd??null},created_at:t.created_at,finished_at:t.finished_at}}async function x(e,t,n,s){let a;if("string"!=typeof s.prompt||!s.prompt.trim())throw new R("invalid_input","prompt is required.");if(s.prompt.length>2e4)throw new R("invalid_input","prompt is longer than 20000 characters.");if("read_only"!==s.authority&&"workspace_write"!==s.authority)throw new R("invalid_input","authority must be read_only or workspace_write.");if("string"!=typeof s.idempotencyKey||!s.idempotencyKey.trim()||s.idempotencyKey.length>200)throw new R("invalid_input","idempotencyKey is required.");if(!s.requester||!["person","bot","service"].includes(s.requester.kind)||!s.requester.id)throw new R("invalid_input","requester is required.");v(e,t);let o=O(e,t,n),d=(_={kind:"send",ref:n,prompt:s.prompt,authority:s.authority},(0,r.createHash)("sha256").update(JSON.stringify(_)).digest("hex")),u=q(b(e,t,s),d);if(u)return{turn:C(e,u),replayed:!0};let l=await k(e,t,s);var _,c,E,p="resume";if(!l.capabilities[p])throw new R("unsupported",`The session provider does not support ${p}.`);if(o.runtime_connection_id!==l.connection.id)throw new R("provider_unavailable","The session belongs to another runtime connection.");let g=function(e){if(!e.scope)throw new R("scope_missing","The Agent has no session scope.");return e.scope}(l);if("binding"!==o.origin&&!("all_provider_sessions"===g.kind||"sessions"===g.kind&&g.sessions.includes(o.id)||"workspaces"===g.kind&&null!==o.workspace&&g.workspaces.some(e=>(0,i.workspaceContains)(e,o.workspace))))throw new R("out_of_scope","The session is outside the Agent's session scope.");var h=s.authority;if(!l.capabilities.authorities.includes(h))throw new R("authority_not_allowed",`The session provider cannot enforce ${h}.`);if(!l.policy)throw new R("authority_not_allowed","The Agent has no launch policy.");if("workspace_write"===h){if("workspace_write"!==l.policy.mode)throw new R("authority_not_allowed","The Agent's policy is read only.");if(!l.policy.allow_resume_with_edits)throw new R("authority_not_allowed","The Agent's policy does not allow resuming with edits.")}let L=await S(e,t,n,s);if("missing"===L.availability)throw new R("session_missing","The provider no longer has this session.");if(1!==L.resumable)throw new R("not_resumable","The provider cannot resume this session.");let A=e.prepare("SELECT 1 FROM provider_session_turns WHERE session_ref = ? AND state = 'running'").get(n);if(1===L.busy||A)throw new R("busy","The session has a turn in flight.");let x={minted:a=[],minter:{mint:e=>{let r=m({agentId:t,sessionRef:n,launch:{kind:e.kind,ref:e.ref},processBound:!0===e.processBound});if(!r)return null;a.push(r.id);let i=r.id;return{token:r.token,url:r.url,end:e=>{N(i,e)}}}},record:(e,t)=>{for(let t of a)f(t,e);T(a,t)},abandon:()=>{for(let e of a)N(e,"launch_failed")}},D=await l.provider.sendTurn({...w(s),provider_session_id:o.provider_session_id,prompt:s.prompt,authority:s.authority,idempotency_key:(c=s.requester,E=s.idempotencyKey,`bm-${(0,r.createHash)("sha256").update(`${t}
|
|
1976
|
+
${c.kind}
|
|
1977
|
+
${c.id}
|
|
1978
|
+
${E}`).digest("hex").slice(0,32)}`),session_context:x.minter});D.ok||(x.abandon(),y(D.error));let U=s.now??Date.now();try{let i=e.transaction(()=>{var i;return i={id:(0,r.randomUUID)(),session_ref:n,agent_id:t,kind:"send",authority:s.authority,requester_kind:s.requester.kind,requester_id:s.requester.id,idempotency_key:s.idempotencyKey,request_hash:d,provider_turn_id:D.value.provider_turn_id,correlation:JSON.stringify(s.correlation??{}),created_at:U},e.prepare(`
|
|
1979
|
+
INSERT INTO provider_session_turns (
|
|
1980
|
+
id, session_ref, agent_id, kind, authority, requester_kind, requester_id, idempotency_key, request_hash,
|
|
1981
|
+
provider_turn_id, state, output, failure_code, correlation, created_at, finished_at
|
|
1982
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'running', NULL, NULL, ?, ?, NULL)
|
|
1983
|
+
`).run(i.id,i.session_ref,i.agent_id,i.kind,i.authority,i.requester_kind,i.requester_id,i.idempotency_key,i.request_hash,i.provider_turn_id,i.correlation,i.created_at),e.prepare("UPDATE provider_sessions SET busy = 1, updated_at = ? WHERE id = ?").run(i.created_at,i.session_ref),I(e,{agentId:i.agent_id,sessionRef:i.session_ref,turnId:i.id,type:"turn_started",detail:{kind:i.kind,authority:i.authority},now:i.created_at}),e.prepare("SELECT * FROM provider_session_turns WHERE id = ?").get(i.id)}).immediate();return x.record(n,i.id),{turn:C(e,i),replayed:!1}}catch(n){if(x.abandon(),n instanceof Error&&/UNIQUE constraint failed: provider_session_turns/.test(n.message))return{turn:C(e,q(b(e,t,s),d)),replayed:!0};throw n}}function D(e,t,n){let r=e.prepare("SELECT * FROM provider_session_turns WHERE id = ? AND agent_id = ?").get(n,t);if(!r)throw new R("turn_not_found","No turn with that reference.");return r}function U(e){return"number"==typeof e&&Number.isInteger(e)&&e>=0?e:null}async function F(e,t,n,r={}){var i,a;let o=D(e,t,n);if("running"!==o.state)return C(e,o);let l=await k(e,t,r),_=await l.provider.observeTurn({...w(r),provider_turn_id:o.provider_turn_id});if(!_.ok){if("cancelled"===_.error.code||"timed_out"===_.error.code)return C(e,D(e,t,n));y(_.error)}return i=_.value,a=r.now??Date.now(),e.transaction(()=>{var t;let n="completed"===i.status?"completed":"cancelled"===i.status?"cancelled":"failed",r=i.usage??null;if(0===e.prepare(`
|
|
1984
|
+
UPDATE provider_session_turns SET state = ?, output = ?, failure_code = ?, finished_at = ?, input_tokens = ?, output_tokens = ?, total_cost_usd = ?
|
|
1985
|
+
WHERE id = ? AND state = 'running'
|
|
1986
|
+
`).run(n,"string"==typeof i.output?i.output:null,i.failure?String(i.failure.code).slice(0,100):null,"number"==typeof i.finished_at?i.finished_at:a,U(r?.input_tokens),U(r?.output_tokens),"number"==typeof(t=r?.total_cost_usd)&&Number.isFinite(t)&&t>=0?t:null,o.id).changes)return;if(h(o.id),i.failure?.code==="session_missing"){let t=e.prepare(`${L} WHERE id = ?`).get(o.session_ref);A(e,t,a)}let l=e.prepare("SELECT provider_kind FROM provider_sessions WHERE id = ?").get(o.session_ref);(0,u.recordTurnUsageSample)(e,o.id,o.session_ref,{agentId:o.agent_id,provider:l?.provider_kind??"unknown",usage:function(e){try{return(0,d.usageFromEvent)(e)}catch{return null}}(i.usage),observedAt:"number"==typeof i.finished_at?i.finished_at:a,now:a}),e.prepare(`
|
|
1987
|
+
UPDATE provider_sessions SET busy = CASE WHEN EXISTS (
|
|
1988
|
+
SELECT 1 FROM provider_session_turns WHERE session_ref = ? AND state = 'running') THEN 1 ELSE 0 END,
|
|
1989
|
+
provider_updated_at = ?, updated_at = ? WHERE id = ?
|
|
1990
|
+
`).run(o.session_ref,a,a,o.session_ref);let _=(0,s.normalizeUsage)(r&&void 0===r.cost_usd&&"total_cost_usd"in r?{...r,cost_usd:r.total_cost_usd}:r);I(e,{agentId:o.agent_id,sessionRef:o.session_ref,turnId:o.id,type:`turn_${n}`,detail:_?{usage:_}:{},now:a})}).immediate(),C(e,D(e,t,n))}function W(e,t,n){let r=e.prepare("SELECT * FROM provider_session_turns WHERE id = ? AND agent_id = ?").get(n,t);return r?C(e,r):void 0}function M(e){return e.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'provider_sessions'").get()?[...e.prepare("SELECT provider_session_id AS id FROM provider_sessions").all(),...e.prepare("SELECT provider_turn_id AS id FROM provider_session_turns").all()].map(e=>e.id):[]}let H=/^(cwd|working_directory|workspace|default_workspace|workspaces|deck|deck_id|deck_name|hermes_profile|hermes_profile_path)$/,X=/(KEY|TOKEN|SECRET|PASSWORD|CREDENTIAL)/i,G=/^(id|ref|session_ref|sessionRef|kind)$|(request|conversation|agent|message|attempt|exchange|event|wake|grant|binding|finalization|bot|participant|sender|requester|origin|group)_?id$/i;function $(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function B(e){try{return JSON.parse(e)}catch{return null}}function K(e,t,n=!1){if("string"==typeof e)n&&t.add(e);else if(Array.isArray(e))for(let r of e)K(r,t,n);else if($(e))for(let[r,i]of Object.entries(e))K(i,t,n||H.test(r))}function P(e,t,n){return t.reduce((e,t)=>t.length>=6?e.includes(t)?e.split(t).join(n):e:e.includes(t)?e.replace(RegExp(`(?<![A-Za-z0-9])${t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(?![A-Za-z0-9])`,"g"),n):e,e)}function j(){let e,r=function(){let e=new Set;for(let t of n.default.prepare("SELECT external_session_id AS id FROM session_bindings").all())e.add(t.id);for(let t of M(n.default))e.add(t);for(let t of n.default.prepare("SELECT external_session_id, external_run_id FROM work_attempts WHERE external_session_id IS NOT NULL OR external_run_id IS NOT NULL").all())t.external_session_id&&e.add(t.external_session_id),t.external_run_id&&e.add(t.external_run_id);return[...e].filter(e=>e.length>0).sort((e,t)=>t.length-e.length)}(),i=function(){let e=new Set;for(let t of n.bots.getAll())K(t,e),"string"==typeof t.session_scope_items&&K(B(t.session_scope_items),e,!0);if(n.default.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'provider_sessions'").get())for(let t of n.default.prepare("SELECT workspace FROM provider_sessions WHERE workspace IS NOT NULL").all())e.add(t.workspace);for(let n of[...e]){var r;let i="~"===(r=n)?t.default.homedir():r.startsWith("~/")?`${t.default.homedir()}/${r.slice(2)}`:null;i&&e.add(i),n.length>1&&n.endsWith("/")&&e.add(n.replace(/\/+$/,""))}for(let t of n.default.prepare(`
|
|
1991
|
+
SELECT launch_snapshot AS snapshot FROM work_attempts WHERE launch_snapshot IS NOT NULL
|
|
1992
|
+
UNION ALL SELECT snapshot FROM launch_snapshots
|
|
1993
|
+
`).all())K(B(t.snapshot),e);return[...new Set([...[...e].filter(e=>e.trim().length>=4),...Object.entries(process.env).filter(([e,t])=>X.test(e)&&"string"==typeof t).flatMap(([,e])=>[e,...e.split(/[\s,=]+/)]).filter(e=>e.length>=8)])].sort((e,t)=>t.length-e.length)}(),s=(e=t.default.homedir().replace(/\/+$/,"")).length<4?null:RegExp(`${e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}(?=$|[/\\s"'\`)\\]}>,;:])[^\\s"'\`)\\]}>,;]*`,"g"),a=e=>{let t=P(P(e,r,"[redacted runtime id]"),i,"[redacted]");return s?t.replace(s,"[redacted]"):t},o=(e,t)=>"string"==typeof e?null!==t&&G.test(t)?e:a(e):Array.isArray(e)?e.map(e=>o(e,null)):$(e)?Object.fromEntries(Object.entries(e).map(([e,t])=>[e,o(t,e)])):e;return{text:a,deep:e=>o(e,null)}}},89443,e=>{"use strict";e.s(["SHARE_LIMITS",()=>tQ,"ShareAskError",()=>nd,"ShareError",()=>t0,"askShare",()=>nc,"audienceAllowed",()=>nt,"loadSessionSharesConfig",()=>ne,"shareAnswer",()=>nE,"shareFromTurnEnabled",()=>nn,"shareRow",()=>nr,"shareState",()=>ni,"sweepExpiredShares",()=>no],89443);var t=e.i(22734),n=e.i(14747),r=e.i(54799),i=e.i(99904),s=e.i(99684),a=e.i(72414),o=e.i(46786);e.i(98307);var d=e.i(94057),u=e.i(89965);e.i(46632);var l=e.i(69312),_=e.i(76422),c=e.i(34923);let E=Object.freeze({maxWakeDepth:3,rootBudget:12,maxContinuations:24,globalConcurrency:4,perTargetConcurrency:1}),p={maxWakeDepth:"BOTMANCERS_WAKE_MAX_DEPTH",rootBudget:"BOTMANCERS_WAKE_ROOT_BUDGET"};function m(e=process.env){let t=(t,n)=>{let r=e[p[t]]?.trim(),i=r&&/^\d+$/.test(r)?Number(r):NaN;return Number.isSafeInteger(i)&&i>=n&&i<E[t]?i:E[t]},n=t("rootBudget",1);return{...E,maxWakeDepth:t("maxWakeDepth",0),rootBudget:n,maxContinuations:2*n}}let f=Object.freeze({kind:"person",id:"local-owner"}),T=Object.freeze({kind:"service",id:"botmancers-exchanges"}),g=["ask","continue"],h={invalid_request:400,authority_not_allowed:403,recursive_exchange:403,conversation_not_found:404,agent_not_found:404,session_not_found:404,session_ended:409,session_not_resumable:409,source_session_busy:409,agent_unavailable:409,destination_invalid:400,idempotency_conflict:409,exchange_not_found:404,exchange_terminal:409,invalid_transition:409};class N extends Error{code;constructor(e,t){super(t),this.name="ExchangeError",this.code=e}get status(){return h[this.code]}}let R=["decisions","constraints","artifacts","open_questions"];function v(e){return"string"==typeof e&&e.trim().length>0}function k(e,...t){return t.reduce((e,t)=>t?e.split(t).join("[redacted session id]"):e,e)}let y="\n[truncated]";function w(e,t){return e.length<=t?{content:e,truncated:!1}:t<=y.length?{content:e.slice(0,t),truncated:!0}:{content:`${e.slice(0,t-y.length)}${y}`,truncated:!0}}let L="This is a read-only turn: do not edit files, change state, start other work, or emit Wakes.";function O(e,t){return`${e}:
|
|
1994
|
+
${t.length>0?t.map(e=>`- ${e}`).join("\n"):"(none)"}`}function I(e){let t;if(e.requester_kind!==T.kind||e.requester_id!==T.id)return null;try{t=JSON.parse(e.policy_snapshot)}catch{return null}return t&&"session_exchange"===t.source&&"string"==typeof t.exchange_id&&("ask"===t.hop||"extract"===t.hop||"deliver"===t.hop)?{exchangeId:t.exchange_id,hop:t.hop,resumeBindingId:"string"==typeof t.resume_session_binding?t.resume_session_binding:null}:null}let A="/v1/chat/completions";class S extends Error{code;status;constructor(e,t,n){super(t),this.name="HermesError",this.code=e,this.status=n}}function b(e=process.env){var t;let n,r=(e.HERMES_API_SERVER_KEY||"").trim();if(!r)return null;let i=(e.HERMES_BASE_URL||"").trim()||"http://127.0.0.1:8642",s=(e.HERMES_SESSION_PREFIX||"").trim()||"botmancer-specialist-",a=(e.HERMES_MODEL||"").trim()||"hermes";return{baseUrl:i.replace(/\/+$/,""),apiKey:r,timeoutMs:(n=Number(t=e.HERMES_TIMEOUT_MS),void 0!==t&&""!==t&&Number.isFinite(n)&&n>0?Math.floor(n):24e4),sessionPrefix:s,model:a}}function q(e,t){return`${t.sessionPrefix}${e}`}function C(e,t){return new S("aborted","Hermes request aborted")}async function x(e){var t;let n,r,{config:i,profilePath:s,sessionId:a,messages:o,signal:d}=e,u=e.fetchImpl||((e,t)=>fetch(e,t)),l=(t=i.baseUrl,n=t.replace(/\/+$/,""),r=s.startsWith("/")?s:`/${s}`,`${n}${r}`),_=new AbortController,c=!1,E=setTimeout(()=>{c=!0,_.abort()},i.timeoutMs);E.unref&&E.unref();let p=()=>_.abort();if(d){if(d.aborted)throw clearTimeout(E),C(d,i.timeoutMs);d.addEventListener("abort",p,{once:!0})}try{let e,t;try{e=await u(l,{method:"POST",headers:{Authorization:`Bearer ${i.apiKey}`,"Content-Type":"application/json","X-Hermes-Session-Id":a},body:JSON.stringify({model:i.model,stream:!1,messages:o}),signal:_.signal})}catch(e){if(c)throw new S("timeout",`Hermes request timed out after ${i.timeoutMs} ms`);if(_.signal.aborted)throw C(d??_.signal,i.timeoutMs);throw new S("network",`Hermes request failed: ${String(e)}`)}let n="";try{n=await e.text()}catch{n=""}if(!e.ok){let t=`Hermes turn failed with status ${e.status}`;try{let e=JSON.parse(n);e?.error?.message&&(t=e.error.message)}catch{let e=n.trim().slice(0,120);e&&(t=`${t}: ${e}`)}throw new S("http",t,e.status)}try{t=JSON.parse(n)}catch{throw new S("protocol","Hermes reply was not JSON",e.status)}return t.choices?.[0]?.message?.content?.trim()||"No response"}finally{clearTimeout(E),d&&d.removeEventListener("abort",p)}}function D(e,t,n=null){return{category:e,code:n,message:t.slice(0,500)}}function U(e){let t=null,n=null;return{promise:new Promise(r=>{if(e.signal&&(n=()=>r(D("cancelled","The attempt was cancelled.")),e.signal.aborted?n():e.signal.addEventListener("abort",n,{once:!0})),"number"==typeof e.deadlineAt){let n=e.deadlineAt,i=()=>{let e=n-Date.now();e<=0?r(D("timed_out","The attempt passed its deadline.")):(t=setTimeout(i,Math.min(e,0x7fffffff))).unref&&t.unref()};i()}}),dispose:()=>{t&&clearTimeout(t),n&&e.signal&&e.signal.removeEventListener("abort",n)}}}function F(e){return e.signal?.aborted?D("cancelled","The attempt was cancelled before launch."):"number"==typeof e.deadlineAt&&Date.now()>=e.deadlineAt?D("timed_out","The attempt passed its deadline before launch."):null}let W="http://127.0.0.1:1111";class M extends Error{code="invalid-agent-deck-server-url";constructor(e){super(`Invalid Agent Deck server URL: ${JSON.stringify(String(e??""))}. Expected an http(s) URL such as ${W}.`)}}function H(e){if(e&&e.trim())return e;let t=(process.env.HOME??"").trim();return t||o.default.homedir()}let X="AGENT_DECK_RUN_TOKEN",G=["ended","error","died","canceled"],$=["starting","running","ended","error","died","canceled"];class B extends Error{code;status;deckCode;constructor(e,t,n=null,r=null){super(t.slice(0,300)),this.name="AgentDeckApiError",this.code=e,this.status=n,this.deckCode=r}}let K={agent_deck_token_missing:`Agent Deck API token is not configured on the Botmancers server (set ${X}).`,agent_deck_unauthorized:`Agent Deck rejected the Botmancers run token (check ${X} and that its grant is not revoked or expired).`,agent_deck_forbidden:"Agent Deck refused this run for the Botmancers grant (enable runs and finalization on the grant and allow this deck).",agent_deck_unreachable:"The Agent Deck server is unreachable at the workspace Agent Deck URL (start it or correct the URL).",agent_deck_rejected:"Agent Deck rejected the request.",agent_deck_invalid_response:"Agent Deck returned an unexpected response."};function P(){let e=process.env[X];return"string"==typeof e&&e.trim().length>0?e.trim():null}function j(){let e=P();return e?(0,r.createHash)("sha256").update(`botmancers-grant-v1:${e}`).digest("hex").slice(0,16):null}function Y(e){return e&&"object"==typeof e&&!Array.isArray(e)?e:null}function z(e){return"string"==typeof e&&e.length>0?e:null}async function J(e,t,n={}){var r,s,a;let o,d=P();if(!d)throw new B("agent_deck_token_missing",K.agent_deck_token_missing);let u={authorization:`Bearer ${d}`,accept:"application/json"};n.idempotencyKey&&(u["idempotency-key"]=n.idempotencyKey),void 0!==n.body&&(u["content-type"]="application/json");let l=`${function(){try{let e,t=i.workspaceSettings.get("agent_deck_server_url");if(null===t)return W;if("string"!=typeof t)throw new M(t);let n=t.trim();if(!n)throw new M(t);try{e=new URL(n)}catch{throw new M(t)}if("http:"!==e.protocol&&"https:"!==e.protocol||!e.hostname)throw new M(t);return e.toString().replace(/\/+$/,"")}catch{return W}}()}${t}`;try{o=await (r={method:e,headers:u,...void 0!==n.body?{body:JSON.stringify(n.body)}:{},...n.signal?{signal:n.signal}:{}},fetch(l,r).then(e=>({status:e.status,json:()=>e.json()})))}catch{throw new B("agent_deck_unreachable",K.agent_deck_unreachable)}let _=null;try{_=Y(await o.json())}catch{_=null}if(o.status<200||o.status>=300||_?.success!==!0){let e,t;if(o.status>=200&&o.status<300)throw new B("agent_deck_invalid_response",K.agent_deck_invalid_response,o.status);throw s=o.status,a=_,t=(e=z(a?.error_code))&&/^[A-Z][A-Z0-9_]{0,63}$/.test(e)?e:null,401===s?new B("agent_deck_unauthorized",K.agent_deck_unauthorized,s,t):403===s?new B("agent_deck_forbidden",`${K.agent_deck_forbidden}${t?` (${t})`:""}`,s,t):new B("agent_deck_rejected",`Agent Deck rejected the request (${s}${t?` ${t}`:""}).`,s,t)}let c=Y(_.data);if(!c)throw new B("agent_deck_invalid_response",K.agent_deck_invalid_response,o.status);return c}function V(e){return new B("agent_deck_invalid_response",`${K.agent_deck_invalid_response} (${e})`)}function Q(e){if("string"!=typeof e||!$.includes(e))throw V("run state");return e}let Z=/^[0-9a-f]{64}$/,ee=/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/,et=/^bl_[0-9a-f]{24}$/;function en(e){var t;let n=Y(e);if(!n||Object.keys(n).some(e=>!["path","sha256","mode"].includes(e)))throw V("manifest entry");if(!(!("string"!=typeof(t=n.path)||0===t.length||t.length>1024||t.startsWith("/")||t.includes("\\")||/^[A-Za-z]:/.test(t)||t.includes("\0"))&&t.split("/").every(e=>e.length>0&&"."!==e&&".."!==e&&".git"!==e)))throw V("manifest path");let r=null===n.sha256&&null===n.mode,i="string"==typeof n.sha256&&Z.test(n.sha256)&&("100644"===n.mode||"100755"===n.mode);if(!r&&!i)throw V("manifest digest or mode");return{path:n.path,sha256:n.sha256,mode:n.mode}}async function er(e,t){let n=await J("POST","/api/agent-runs",{body:e,idempotencyKey:t}),r=z(n.runId);if(!r)throw V("runId");return{runId:r,state:Q(n.state)}}async function ei(e){let t=await J("GET",`/api/agent-runs/${encodeURIComponent(e)}`);if(!z(t.runId)||!z(t.deckId)||!z(t.client)||"edit"!==t.tools&&"readonly"!==t.tools)throw V("run status");return{runId:z(t.runId),deckId:z(t.deckId),client:z(t.client),tools:t.tools,state:Q(t.state),sessionId:z(t.sessionId),finalization:function(e){if(null==e)return null;let t=Y(e);if(!t||"string"!=typeof t.baselineRef||!et.test(t.baselineRef)||"string"!=typeof t.baselineDigest||!Z.test(t.baselineDigest)||!["prepared","finalizing","finalized"].includes(String(t.state)))throw V("finalization status");let n="string"==typeof t.commit&&ee.test(t.commit)?t.commit:null;return{baselineRef:t.baselineRef,baselineDigest:t.baselineDigest,state:t.state,commit:n}}(t.finalization)}}async function es(e,t){let n=t?`?after=${encodeURIComponent(t)}`:"",r=await J("GET",`/api/agent-runs/${encodeURIComponent(e)}/events${n}`);if(!Array.isArray(r.events))throw V("events");return{runId:z(r.runId)??e,state:Q(r.state),events:r.events.filter(e=>!!Y(e)&&"string"==typeof e.type),nextCursor:"string"==typeof r.nextCursor?r.nextCursor:t??"0"}}async function ea(e){return Q((await J("POST",`/api/agent-runs/${encodeURIComponent(e)}/cancel`)).state)}async function eo(e){let t=await J("GET",`/api/agent-runs/${encodeURIComponent(e)}/changes`);if("string"!=typeof t.baselineRef||!et.test(t.baselineRef))throw V("baselineRef");if("string"!=typeof t.baselineDigest||!Z.test(t.baselineDigest))throw V("baselineDigest");if("string"!=typeof t.baseCommit||!ee.test(t.baseCommit))throw V("baseCommit");if("string"!=typeof t.manifestDigest||!Z.test(t.manifestDigest))throw V("manifestDigest");if(!Array.isArray(t.files))throw V("files");return{runId:z(t.runId)??e,baselineRef:t.baselineRef,baselineDigest:t.baselineDigest,baseCommit:t.baseCommit,files:t.files.map(en),manifestDigest:t.manifestDigest}}async function ed(e,t,n){let r=await J("POST",`/api/agent-runs/${encodeURIComponent(e)}/finalize`,{body:t,idempotencyKey:n});if("finalized"!==r.finalizationState||"string"!=typeof r.commit||!ee.test(r.commit)||"string"!=typeof r.tree||!ee.test(r.tree)||"string"!=typeof r.manifestDigest||!Z.test(r.manifestDigest))throw V("finalize result");return{runId:z(r.runId)??e,finalizationState:"finalized",commit:r.commit,tree:r.tree,..."string"==typeof r.parent&&ee.test(r.parent)?{parent:r.parent}:{},manifestDigest:r.manifestDigest,..."number"==typeof r.fileCount?{fileCount:r.fileCount}:{},..."string"==typeof r.reviewId?{reviewId:r.reviewId}:{}}}e.i(33405);let eu=["codex","claude","cursor","muse"];class el extends Error{code="invalid-runtime";constructor(e){super(`Invalid agent-deck runtime: ${JSON.stringify(String(e))}. Expected one of ${eu.join("|")}.`)}}var e_=e.i(98596);class ec extends Error{code;constructor(e,t){super(t),this.name="ControlError",this.code=e}}let eE=["queued","blocked","running","waiting"];function ep(e){try{let t=JSON.parse(e.launch_snapshot);return t&&"object"==typeof t?t:{}}catch{return{}}}let em="'grant_requested', 'grant_approved', 'grant_denied', 'grant_revoked'",ef=Object.freeze({maxGlobal:4,maxPerTarget:1,leaseMs:6e4,heartbeatMs:15e3,deferMs:5e3,cancelGraceMs:3e4}),eT={maxGlobal:"BOTMANCERS_DISPATCH_MAX_GLOBAL",maxPerTarget:"BOTMANCERS_DISPATCH_MAX_PER_TARGET",leaseMs:"BOTMANCERS_DISPATCH_LEASE_MS",heartbeatMs:"BOTMANCERS_DISPATCH_HEARTBEAT_MS",deferMs:"BOTMANCERS_DISPATCH_DEFER_MS",cancelGraceMs:"BOTMANCERS_DISPATCH_CANCEL_GRACE_MS"},eg=Object.freeze({maxGlobal:ef.maxGlobal,maxPerTarget:ef.maxPerTarget});class eh extends Error{requestId;constructor(e){super(`The dispatch lease for ${e} is no longer held.`),this.name="LeaseLostError",this.requestId=e}}let eN=[{status:400,code:/.*/},{status:404,code:/^DECK_NOT_FOUND$/},{status:422,code:/^(WORKSPACE_[A-Z0-9_]+|PROFILE_UNSUPPORTED|RESUME_UNVERIFIED|FINALIZATION_INVALID)$/},{status:409,code:/^INDEX_DIRTY$/},{status:503,code:/^CLIENT_UNAVAILABLE$/}];function eR(e){let t=e.correlation.attemptId;return t?`botmancers-attempt-${t}`:`botmancers-direct-${(0,r.randomUUID)()}`}function ev(e,t){if(e instanceof B)return D(e instanceof B?"agent_deck_token_missing"===e.code||"agent_deck_unauthorized"===e.code||"agent_deck_forbidden"===e.code||"agent_deck_unreachable"===e.code?"unavailable":"agent_deck_invalid_response"===e.code?"result_contract":t:t,`[${e.code}${e.deckCode?` ${e.deckCode}`:""}] ${e.message}`,e.code);return D(t,e instanceof Error?e.message:String(e))}let ek=e=>G.includes(e);async function ey(e){let t={state:"starting",result:null,resultMismatch:null,sessionId:null,usage:null},n=[],r=null;for(;;){let i=await es(e,r);for(let e of i.events)(0,e_.usageFromEvent)(e)&&n.push(e),"sessionId"in e&&"string"==typeof e.sessionId&&e.sessionId&&(t.sessionId=e.sessionId),"result"===e.type&&("string"==typeof e.result&&e.result.length>0?(t.result=e.result,t.resultMismatch=null):(t.result=null,t.resultMismatch=null===e.result?"null":Array.isArray(e.result)?"array":""===e.result?"empty string":typeof e.result));t.state=i.state;let s=i.nextCursor!==(r??"0")&&i.events.length>0;if(r=i.nextCursor,ek(i.state)&&!s)return t.usage=(0,e_.usageFromEvents)(n),t;s||await new Promise(e=>setTimeout(e,1e3))}}async function ew(e,t){if(!t?.finalization)return{baselineRef:null,baselineDigest:null,candidate:{ok:!1,code:"FINALIZATION_NOT_PREPARED",message:"The run reported no finalization baseline."}};let n={baselineRef:t.finalization.baselineRef,baselineDigest:t.finalization.baselineDigest};try{let r=await eo(e);if(r.baselineRef!==t.finalization.baselineRef||r.baselineDigest!==t.finalization.baselineDigest)return{...n,candidate:{ok:!1,code:"BASELINE_MISMATCH",message:"Agent Deck returned candidate evidence for a different baseline."}};return{...n,candidate:{ok:!0,manifest:{baselineRef:r.baselineRef,baselineDigest:r.baselineDigest,baseCommit:r.baseCommit,manifestDigest:r.manifestDigest,files:r.files}}}}catch(r){let e=r instanceof B?r.deckCode??r.code:"agent_deck_invalid_response",t=r instanceof B?r.message:"The candidate manifest could not be read.";return{...n,candidate:{ok:!1,code:e,message:t}}}}function eL(e){let t;if("readonly"!==e.toolProfile&&"edit"!==e.toolProfile)return{ok:!1,failure:D("unsupported_authority",`Unsupported tool profile: ${JSON.stringify(String(e.toolProfile))}.`)};if(e.prepareFinalization&&"edit"!==e.toolProfile)return{ok:!1,failure:D("unsupported_authority","Only an edit Attempt can prepare Git finalization.")};if(!e.deck)return{ok:!1,failure:D("unavailable","An Agent Deck run requires a deck.")};if(!e.cwd)return{ok:!1,failure:D("unavailable","An Agent Deck run requires a working directory.")};try{t=function(e){if("string"==typeof e&&eu.includes(e))return e;throw new el(e)}(e.target.agent)}catch(e){return{ok:!1,failure:D("unavailable",e instanceof Error?e.message:String(e))}}let n=e.sessionBinding?.externalSessionId??null;return{ok:!0,body:{deckId:e.deck,client:t,cwd:e.cwd,prompt:function(e){if("text"===e.kind)return e.text;let t=e.history.map(e=>`[${e.fromAgent?"you":e.speakerLabel}] ${e.content}`).join("\n\n");return`${e.system}
|
|
1995
|
+
|
|
1996
|
+
Conversation so far (reply to the last message):
|
|
1997
|
+
|
|
1998
|
+
${t}`}(e.prompt),tools:e.toolProfile,...n?{resumeSessionId:n}:{},...!0===e.prepareFinalization?{prepareFinalization:!0}:{}}}}function eO(e){if(!(e instanceof B))return{kind:"rejected",status:null,code:null};switch(e.code){case"agent_deck_token_missing":return{kind:"no_grant"};case"agent_deck_unauthorized":return{kind:"unauthorized"};case"agent_deck_forbidden":return{kind:"forbidden"};case"agent_deck_unreachable":return{kind:"unreachable"};default:if(404===e.status&&("RUN_NOT_FOUND"===e.deckCode||null===e.deckCode))return{kind:"not_found"};return{kind:"rejected",status:e.status,code:e.deckCode}}}let eI="agent-deck-api";function eA(e){let t=t=>({adapter:eI,externalRunId:null,externalSessionId:null,output:null,artifacts:[],startedAt:e,finishedAt:Date.now(),failure:null,...t});return{result:t,failed:(e,n={})=>t({status:"failed",failure:e,...n})}}async function eS(e,t,n,r){let{result:i,failed:s}=eA(r),a=t.resumeSessionId,o=t.prepareFinalization,d=U({signal:t.signal??null,deadlineAt:t.deadlineAt}),u={externalRunId:e};try{if(o)try{let t=await ei(e);t.finalization&&n?.({type:"progress",adapter:eI,at:Date.now(),detail:{phase:"finalization_prepared",baseline_ref:t.finalization.baselineRef,baseline_digest:t.finalization.baselineDigest}})}catch{}let t=ey(e);t.catch(()=>{});let r=await Promise.race([t.then(e=>({observed:e}),e=>({error:e})),d.promise.then(e=>({interrupted:e}))]);if("interrupted"in r){let t="requested";try{await ea(e)}catch{t="failed"}return s(r.interrupted,{...u,externalCancel:t})}if("error"in r){let t="requested";try{await ea(e)}catch{t="failed"}return s(ev(r.error,"runtime_failed"),{...u,externalCancel:t})}let{observed:l}=r,_=null;try{_=await ei(e)}catch(e){if(!o)return s(ev(e,"runtime_failed"),{...u,usage:l.usage})}let c=_?.sessionId??l.sessionId,E=o?await ew(e,_):void 0,p={...u,externalSessionId:c,usage:l.usage,...E?{finalization:E}:{}};if("canceled"===l.state)return s(D("cancelled",`Agent Deck run ${e} was canceled.`),p);if("ended"!==l.state)return s(D("runtime_failed",`Agent Deck run ${e} ended in state ${l.state}.`),p);if(null===l.result)return s(D("result_contract",`Agent Deck run ${e} result contract mismatch: expected a non-empty string result, got ${l.resultMismatch??"no result event"}.`),p);if(a&&null!==c&&c!==a)return s(D("session_mismatch",`resume run ${e} forked the session (expected ${a}, got ${c}); failing closed.`),p);let m=E?.candidate?.ok?E.candidate.manifest:null;return i({status:"completed",...p,externalSessionId:c??a,output:l.result,artifacts:m?[{kind:"candidate_manifest",ref:m.manifestDigest}]:[]})}finally{d.dispose()}}let eb={currentGrantFingerprint:j,async inspect(e){try{let t=await ei(e);return{kind:"run",state:t.state}}catch(e){return eO(e)}},async repost(e){let t;try{t=JSON.parse(e.body)}catch{return{kind:"rejected",status:null,code:"INTENT_UNREADABLE"}}try{let n=await er(t,e.idempotencyKey);return{kind:"accepted",runId:n.runId}}catch(e){return eO(e)}},follow:(e,t,n)=>eS(e,t,n,Date.now()),async evidence(e){let t=null;try{t=await ei(e)}catch{}return ew(e,t)},async cancel(e){try{return await ea(e),"requested"}catch{return"failed"}}};class eq extends Error{code;constructor(e,t){super(t),this.name="DispatchFailure",this.code=e}}let eC={"hermes-gateway":()=>(function(e={}){let t="hermes-gateway";return{name:t,async run(n,i){var s,a;let o=Date.now(),d=(e,n=null)=>({status:"failed",adapter:t,externalRunId:null,externalSessionId:n,output:null,artifacts:[],startedAt:o,finishedAt:Date.now(),failure:e});if("readonly"!==n.toolProfile)return d(D("unsupported_authority",`The Hermes gateway does not support the ${n.toolProfile} tool profile.`));let u=(e.loadConfig??b)();if(!u)return d(D("unavailable","The Hermes gateway is not configured."));let l=F(n);if(l)return d(l);if(n.freshSession&&n.sessionBinding)return d(D("session_mismatch","A fresh-session turn cannot resume a session."));let _=n.sessionBinding?.externalSessionId??(n.freshSession?(s=n.target.agentId,`${q(s,u)}-x-${(0,r.randomUUID)()}`):q(n.target.agentId,u)),c=new AbortController,E=U(n),p=null;E.promise.then(e=>{p=e,c.abort()}),i?.({type:"started",adapter:t,at:Date.now(),externalRunId:null,externalSessionId:_});try{let r=await x({config:u,profilePath:n.target.hermesProfilePath||A,sessionId:_,messages:(a=n.prompt,"text"===a.kind?[{role:"user",content:a.text}]:[{role:"system",content:a.system},...a.history.map(e=>e.fromAgent?{role:"assistant",content:e.content}:{role:"user",content:`[From ${e.speakerLabel}] ${e.content}`})]),signal:c.signal,...e.fetchImpl?{fetchImpl:e.fetchImpl}:{}});return{status:"completed",adapter:t,externalRunId:null,externalSessionId:_,output:r,artifacts:[],startedAt:o,finishedAt:Date.now(),failure:null}}catch(r){let e=r instanceof S?r.code:"unknown";if(p)return d({...p,code:e},_);let t="timeout"===e?"timed_out":"runtime_failed",n=r instanceof S&&void 0!==r.status?` ${r.status}`:"";return d(D(t,`The Hermes gateway did not complete the turn (${e}${n}).`,e),_)}finally{E.dispose()}}}})({fetchImpl:null}),"agent-deck-run":()=>({name:eI,reconciler:eb,externalCancel:!0,launchIntent(e){let t=eL(e);return t.ok?{idempotencyKey:eR(e),body:JSON.stringify(t.body),grantFingerprint:j()}:null},async run(e,t){let n,r=Date.now(),{failed:i}=eA(r),s=eL(e);if(!s.ok)return i(s.failure);let a=F(e);if(a)return i(a);try{n=(await er(s.body,eR(e))).runId}catch(t){let e=function(e){switch(e.kind){case"no_grant":case"unauthorized":case"forbidden":return!0;case"rejected":return eN.some(t=>t.status===e.status&&t.code.test(e.code??""));default:return!1}}(eO(t));return i(ev(t,"launch_failed"),e?{}:{launchUnconfirmed:!0})}return t?.({type:"started",adapter:eI,at:Date.now(),externalRunId:n,externalSessionId:null}),eS(n,{resumeSessionId:e.sessionBinding?.externalSessionId??null,prepareFinalization:!0===e.prepareFinalization,deadlineAt:e.deadlineAt??null,signal:e.signal??null},t,r)}})},ex=["agent_deck_token_missing","agent_deck_unauthorized","agent_deck_forbidden","agent_deck_unreachable"];function eD(e){return"completed"===e.status?"succeeded":e.failure?.category==="cancelled"?"cancelled":e.failure?.category==="timed_out"?"timed_out":"failed"}function eU(e,t,n){(function(e){if(e.usage||"completed"===e.status||e.externalRunId)return!0;let t=e.failure?.category;return void 0!==t&&!["unavailable","unsupported_authority","launch_failed"].includes(t)})(n)&&e.recordAttemptUsage(t,{usage:n.usage??null,observedAt:n.finishedAt})}function eF(e,t,n,r=Date.now()){eU(e,t.id,n);let i=e.getWorkRequest(t.request_id);e.appendEvent(t.request_id,{type:"late_result_recorded",attemptId:t.id,data:{attempt_number:t.attempt_number,attempt_outcome:t.outcome,result_status:n.status,result_outcome:eD(n),error_category:n.failure?.category??null,external_run_id:n.externalRunId,output:n.output,request_state:i?.state??null},now:r})}async function eW(e,t,n,r={}){let i,s=!1,a=!1;try{i=await n.run(t.input,n=>{var i,o;if("started"===n.type&&(a=!0),s||(i=t.attempt,o=r.fence,!e.transaction(()=>(!o||!!o())&&("started"===n.type?((n.externalRunId||n.externalSessionId)&&e.recordAttemptExternalIds(i.id,{...n.externalRunId?{externalRunId:n.externalRunId}:{},...n.externalSessionId?{externalSessionId:n.externalSessionId}:{}}),e.appendEvent(i.request_id,{type:"runtime_started",attemptId:i.id,data:{adapter:n.adapter,external_run_id:n.externalRunId},now:n.at})):e.appendEvent(i.request_id,{type:"runtime_progress",attemptId:i.id,data:{adapter:n.adapter,...n.detail},now:n.at}),!0)))){s=!0;return}r.onEvent?.(n)})}catch(r){let e=Date.now();i={status:"failed",adapter:n.name,externalRunId:null,externalSessionId:null,output:null,artifacts:[],startedAt:t.attempt.started_at,finishedAt:e,failure:D("runtime_failed",r instanceof Error?r.message:String(r))}}return r.sanitize&&(i=r.sanitize(i)),e.transaction(()=>{var s,o,d,u,l;let _,c,E=e.getAttempt(t.attempt.id);if(E&&null!==E.finished_at)return eF(e,E,i),{attempt:E,result:i,projected:void 0,late:!0,abandoned:null};let p=a?function(e,t,n,r){if("failed"!==r.status)return null;let i=r.failure?.category,s="failed"===r.externalCancel,a={requestId:e.request_id,attemptId:e.id,externalRunId:r.externalRunId,transport:t.name};return"cancelled"!==i&&"timed_out"!==i?s?{...a,reason:"observation_lost",externalCancel:"failed"}:null:("cancelled"!==i||n?.aborted)&&(!t.externalCancel||s)?{...a,reason:i,externalCancel:s?"failed":null}:null}(t.attempt,n,t.input.signal??null,i):null,m=p?(d=e,u=p,l=i,eU(d,u.attemptId,l),_="failed"===u.externalCancel?"The runtime did not accept the cancel request":"The runtime cannot stop the run",c=d.finishAttempt(u.attemptId,{outcome:eD(l),errorCategory:"abandoned",errorMessage:`${l.failure?.message??"The attempt was interrupted."} ${_}; it may continue and a later result is not awaited.`.slice(0,500),artifacts:l.artifacts,...l.externalRunId?{externalRunId:l.externalRunId}:{},...l.externalSessionId?{externalSessionId:l.externalSessionId}:{},now:l.finishedAt}),u.externalRunId=c.external_run_id,d.appendEvent(u.requestId,{type:"attempt_abandoned",attemptId:u.attemptId,data:{reason:u.reason,attempt_number:c.attempt_number,external_run_id:c.external_run_id,transport:u.transport,local_only:!0,error_code:l.failure?.code??null,external_cancel:u.externalCancel},now:l.finishedAt}),c):(eU(e,s=t.attempt.id,o=i),e.finishAttempt(s,{outcome:eD(o),output:o.output,errorCategory:o.failure?.category??null,errorMessage:o.failure?.message??null,artifacts:o.artifacts,...o.externalRunId?{externalRunId:o.externalRunId}:{},...o.externalSessionId?{externalSessionId:o.externalSessionId}:{},now:o.finishedAt})),f=r.project?r.project(i,m):void 0;return{attempt:m,result:i,projected:f,late:!1,abandoned:p}})}let eM=new Set(["version","target","executionKind","objective","contextWorkRequests","resumeWorkRequest","limits"]),eH=new Set(["maxAttempts","deadlineSeconds"]),eX=new Set(["conversation","implementation","review","revision"]);function eG(e,t){return"string"==typeof e&&e.trim().length>0&&e.length<=t}function e$(e,t,n){return Number.isInteger(e)&&e>=t&&e<=n}function eB(e){if(!e||"object"!=typeof e||Array.isArray(e))return{ok:!1,reason:"envelope must be a JSON object"};let t=Object.keys(e).filter(e=>!eM.has(e));if(t.length>0)return{ok:!1,reason:`unknown field ${t.join(", ")}`};if(1!==e.version)return{ok:!1,reason:"version must be 1"};if(!eG(e.target,120))return{ok:!1,reason:"target must be a non-empty Agent name (max 120 characters)"};if("string"!=typeof e.executionKind||!eX.has(e.executionKind))return{ok:!1,reason:"unknown executionKind"};if(!eG(e.objective,2e4))return{ok:!1,reason:"objective must be non-empty (max 20000 characters)"};let n={version:1,target:e.target.trim(),executionKind:e.executionKind,objective:e.objective.trim()};if(void 0!==e.contextWorkRequests){let t=e.contextWorkRequests;if(!Array.isArray(t)||t.length>8||t.some(e=>!eG(e,160)))return{ok:!1,reason:"contextWorkRequests must be at most 8 Work Request references"};if(new Set(t).size!==t.length)return{ok:!1,reason:"contextWorkRequests must be unique"};n.contextWorkRequests=[...t]}let r=Object.prototype.hasOwnProperty.call(e,"resumeWorkRequest");if("revision"===n.executionKind){if(!r||!eG(e.resumeWorkRequest,160))return{ok:!1,reason:"revision requires resumeWorkRequest"};n.resumeWorkRequest=e.resumeWorkRequest}else if(r)return{ok:!1,reason:"resumeWorkRequest is revision-only"};if(void 0!==e.limits){let t=e.limits;if(!t||"object"!=typeof t||Array.isArray(t))return{ok:!1,reason:"limits must be an object"};if(Object.keys(t).some(e=>!eH.has(e)))return{ok:!1,reason:"unknown limits field"};if(void 0!==t.maxAttempts&&!e$(t.maxAttempts,1,10))return{ok:!1,reason:"limits.maxAttempts must be 1-10"};if(void 0!==t.deadlineSeconds&&!e$(t.deadlineSeconds,1,86400))return{ok:!1,reason:"limits.deadlineSeconds must be 1-86400"};n.limits={},void 0!==t.maxAttempts&&(n.limits.maxAttempts=t.maxAttempts),void 0!==t.deadlineSeconds&&(n.limits.deadlineSeconds=t.deadlineSeconds)}return{ok:!0,envelope:n}}let eK=/```botmancers-wake[^\S\r\n]*\r?\n([\s\S]*?)```/g,eP=/WAKE\s+([A-Za-z0-9_-]+)\s*:/gi;function ej(e){return JSON.stringify(function e(t){return Array.isArray(t)?t.map(e):t&&"object"==typeof t?Object.fromEntries(Object.keys(t).sort().map(n=>[n,e(t[n])])):t}(e.validation.ok?{syntax:e.syntax,envelope:e.validation.envelope}:{syntax:e.syntax,raw:e.raw}))}m().maxWakeDepth,m().rootBudget;class eY extends Error{code;constructor(e,t){super(t),this.name="WakeRouterError",this.code=e}}let ez=i.default.prepare("SELECT * FROM wakes WHERE id = ?"),eJ=i.default.prepare("SELECT * FROM wakes WHERE idempotency_key = ?"),eV=i.default.prepare("SELECT * FROM wakes WHERE source_event_id = ? AND position = ?");function eQ(e,t){return{wake:e,request:e.work_request_id?i.engine.getWorkRequest(e.work_request_id)??null:null,created:t}}function eZ(e){return"accepted"===e.status||"blocked"===e.status}function e0(e){return i.default.prepare("SELECT COUNT(*) AS n FROM work_requests WHERE root_request_id = ? AND wake_event_id IS NOT NULL").get(e).n}let e1=new Set(["version","decision","implementationAttemptId","reviewAttemptId","commitMessage"]);function e4(e){return"string"==typeof e&&e.trim().length>0&&e.length<=160}let e2=/```botmancers-finalize[^\S\r\n]*\r?\n([\s\S]*?)```/g;function e3(e){return(0,r.createHash)("sha256").update(e).digest("hex")}function e6(e){try{let t=JSON.parse(e.policy_snapshot);return t&&"object"==typeof t&&!Array.isArray(t)?t:{}}catch{return{}}}let e9=["implementation","revision"];function e5(e){return i.default.prepare("SELECT * FROM work_attempts WHERE request_id = ? ORDER BY attempt_number DESC LIMIT 1").get(e)}function e8(e){return i.default.prepare("SELECT * FROM candidate_manifests WHERE attempt_id = ?").get(e)}function e7(e){return i.default.prepare("SELECT * FROM finalizations WHERE id = ?").get(e)}function te(e){return JSON.parse(e.files)}function tt(e,t,n=Date.now()){let r=i.engine.getAttempt(e);if(!r?.external_run_id)return!1;let s=i.default.prepare("SELECT baseline_ref, baseline_digest FROM attempt_finalization_baselines WHERE attempt_id = ?").get(e);return s?s.baseline_ref===t.baselineRef&&s.baseline_digest===t.baselineDigest:(i.default.prepare(`
|
|
1999
|
+
INSERT OR IGNORE INTO attempt_finalization_baselines (attempt_id, request_id, external_run_id, baseline_ref, baseline_digest, created_at)
|
|
2000
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
2001
|
+
`).run(e,r.request_id,r.external_run_id,t.baselineRef,t.baselineDigest,n),!0)}function tn(e,t,n,r){return`botmancers-finalize-v1-${e3([e,t,n,r].join(":")).slice(0,48)}`}function tr(e,t){return{finalization_id:e.id,decision_event_id:e.decision_event_id,coordinator_agent_id:e.coordinator_agent_id,implementation_request_id:e.implementation_request_id,implementation_attempt_id:e.implementation_attempt_id,review_request_id:e.review_request_id,review_attempt_id:e.review_attempt_id,external_run_id:e.external_run_id,manifest_id:e.manifest_id,manifest_digest:t?.manifest_digest??null,baseline_digest:t?.baseline_digest??null,base_commit:t?.base_commit??null,file_count:t?.file_count??null}}let ti=new Set(["BASE_MISMATCH","INDEX_DIRTY","BASELINE_MISMATCH","PATH_INVALID","PATH_UNEXPECTED","DIGEST_MISMATCH","IDEMPOTENCY_CONFLICT","GIT_LOCK_CONFLICT","REF_RACE","FINALIZATION_NOT_PREPARED","RUN_NOT_TERMINAL","FINALIZATION_INVALID","RUN_NOT_FOUND"]);function ts(e,t,n,r){return i.engine.transaction(()=>{let s=i.default.prepare(`
|
|
2002
|
+
UPDATE finalizations SET state = ?, reason_code = ?, reason = ?, commit_id = ?, tree_id = ?, parent_commit = ?,
|
|
2003
|
+
result_manifest_digest = ?, file_count = ?, updated_at = ?, finished_at = ?
|
|
2004
|
+
WHERE id = ? AND finished_at IS NULL
|
|
2005
|
+
`).run(t,n.reasonCode??null,n.reason?.slice(0,300)??null,n.commit??null,n.tree??null,n.parent??null,n.manifestDigest??null,n.fileCount??null,r,r,e.id),a=e7(e.id);if(1!==s.changes)return a;let o=i.default.prepare("SELECT * FROM candidate_manifests WHERE id = ?").get(e.manifest_id);return i.engine.appendEvent(e.implementation_request_id,{type:`finalization_${t}`,attemptId:e.implementation_attempt_id,data:{...tr(a,o),reason_code:a.reason_code,reason:a.reason,commit:a.commit_id,tree:a.tree_id,parent:a.parent_commit,result_manifest_digest:a.result_manifest_digest},now:r}),a})}function ta(e,t=!1){if(!(e instanceof B))return{state:t?null:"failed",reasonCode:"finalization_failed",reason:"The finalization outcome is unknown; retrying with the same idempotency key is safe."};if("agent_deck_unreachable"===e.code||t&&"agent_deck_invalid_response"===e.code)return{state:null,reasonCode:e.code,reason:e.message};if("agent_deck_rejected"!==e.code)return{state:"failed",reasonCode:e.code,reason:e.message};let n=e.deckCode??"";return"FINALIZATION_CANCELED"===n?{state:"canceled",reasonCode:n.toLowerCase(),reason:e.message}:ti.has(n)?{state:"blocked",reasonCode:n.toLowerCase(),reason:e.message}:t&&(!n||null!==e.status&&e.status>=500)?{state:null,reasonCode:n?n.toLowerCase():"finalization_failed",reason:"The finalization outcome is unknown; retrying with the same idempotency key is safe."}:{state:"failed",reasonCode:n?n.toLowerCase():"finalization_failed",reason:e.message}}function to(e,t,n,r){return i.engine.appendEvent(e.implementation_request_id,{type:"finalization_retry_pending",attemptId:e.implementation_attempt_id,data:{finalization_id:e.id,external_run_id:e.external_run_id,reason_code:t,reason:n},now:r}),e7(e.id)}async function td(e){let t=e7(e);if(!t||"preparing"!==t.state)return t;if(null===P())return ts(t,"failed",{reasonCode:"agent_deck_token_missing",reason:K.agent_deck_token_missing},Date.now());let n=JSON.parse(t.request_body),r=i.default.prepare("SELECT * FROM candidate_manifests WHERE id = ?").get(t.manifest_id);if(null===t.submitted_at){try{var s,a;let e=await eo(t.external_run_id);if(e.manifestDigest!==r.manifest_digest||e.baselineDigest!==r.baseline_digest||e.baseCommit!==r.base_commit||(s=e.files,a=n.files,JSON.stringify(s)!==JSON.stringify(a)))return ts(t,"blocked",{reasonCode:"manifest_changed",reason:`The workspace changed after review (candidate manifest ${e.manifestDigest}, reviewed ${r.manifest_digest}); nothing was committed.`},Date.now())}catch(n){let e=ta(n);if(!e.state)return to(t,e.reasonCode,e.reason,Date.now());return ts(t,e.state,{reasonCode:e.reasonCode,reason:e.reason},Date.now())}i.default.prepare("UPDATE finalizations SET submitted_at = ?, updated_at = ? WHERE id = ? AND submitted_at IS NULL AND finished_at IS NULL").run(Date.now(),Date.now(),t.id),t=e7(e)}try{let e=await ed(t.external_run_id,n,t.idempotency_key);if(e.manifestDigest!==r.manifest_digest||void 0!==e.fileCount&&e.fileCount!==r.file_count||void 0!==e.reviewId&&e.reviewId!==t.review_request_id||void 0!==e.parent&&e.parent!==r.base_commit)return ts(t,"failed",{reasonCode:"agent_deck_invalid_response",reason:"Agent Deck returned commit evidence that does not match the persisted finalization request."},Date.now());return ts(t,"committed",{commit:e.commit,tree:e.tree,parent:e.parent??r.base_commit,manifestDigest:e.manifestDigest,fileCount:e.fileCount??r.file_count},Date.now())}catch(n){let e=ta(n,!0);if(!e.state)return to(t,e.reasonCode,e.reason,Date.now());return ts(t,e.state,{reasonCode:e.reasonCode,reason:e.reason},Date.now())}}m().maxContinuations;let tu={kind:"service",id:"botmancers-engine"},tl="Botmancers";function t_(e){try{let t=JSON.parse(e.policy_snapshot);return t&&"object"==typeof t&&!Array.isArray(t)?t:{}}catch{return{}}}function tc(e){return i.bots.getById(e)?.name??`agent:${e}`}function tE(e){let t;if("completed"!==e.state||!e.result)return null;try{t=JSON.parse(e.result).reply_message_id}catch{return null}if("string"!=typeof t)return null;let n=i.default.prepare("SELECT * FROM messages WHERE id = ?").get(t);return n&&"bot"===n.sender_type&&n.sender_id===e.target_agent_id?n:null}function tp(e,t=!1){let n=i.engine.listAttempts(e.id),r=n.length>0?n[n.length-1]:null,s=[`Work Request: ${e.id}`,...r?[`Attempt: ${r.id}`]:[],`Agent: ${tc(e.target_agent_id)}`,`Execution kind: ${e.execution_kind}`,`State: ${e.state}`],a=tE(e);if(a){var o;s.push(t?`Result: the ${tc(e.target_agent_id)} reply above.`:`Result:
|
|
2006
|
+
${(o=a.content).length>8e3?`${o.slice(0,8e3)}
|
|
2007
|
+
[truncated]`:o}`)}else"failed"===e.state||"cancelled"===e.state?s.push(`Failure: ${e.error_code??e.state}${e.error_message?` - ${e.error_message}`:""}`):null===e.terminal_at&&s.push("Result: not finished yet.");let d=function(e){if(!e9.includes(e.execution_kind))return null;let t=e5(e.id);if(!t)return null;let n=e8(t.id);if(n){let e=te(n),t=e.slice(0,50).map(e=>`- ${e.path} ${e.sha256?`sha256=${e.sha256} mode=${e.mode}`:"deleted"}`);return e.length>50&&t.push(`- ... ${e.length-50} more`),[`Candidate manifest: ${n.manifest_digest} (${e.length} ${1===e.length?"file":"files"}, base commit ${n.base_commit}, baseline ${n.baseline_digest})`,...t].join("\n")}let r=i.default.prepare("SELECT data FROM engine_events WHERE request_id = ? AND attempt_id = ? AND type = 'candidate_manifest_unavailable' ORDER BY sequence DESC LIMIT 1").get(e.id,t.id);if(r){let e=JSON.parse(r.data);return`Candidate manifest: unavailable (${e.reason_code??"unknown"}); this work cannot be finalized.`}return null}(e);return d&&s.push(d),s.join("\n")}let tm='You coordinate this work. Decide the next step yourself: reply to the person, ask a question, or emit a botmancers-wake block (one per Agent). Reference earlier work with "contextWorkRequests"; a revision names the implementation it resumes in "resumeWorkRequest". Never report a review that did not run.',tf=i.default.prepare("SELECT * FROM work_requests WHERE requester_kind = ? AND requester_id = ? AND idempotency_key = ?");function tT(e){let t=tf.get(tu.kind,tu.id,e.key);if(t)return t;if(!i.bots.getById(e.coordinatorId)||!i.default.prepare("SELECT 1 FROM conversations WHERE id = ?").get(e.conversationId))return null;let n=i.default.prepare("SELECT COUNT(*) AS n FROM work_requests WHERE root_request_id = ? AND requester_kind = ? AND requester_id = ?").get(e.parent.root_request_id,tu.kind,tu.id),r=m().maxContinuations;if(n.n>=r)return i.default.prepare("SELECT 1 FROM engine_events WHERE request_id = ? AND type = 'lineage_stopped'").get(e.parent.id)||i.engine.appendEvent(e.parent.id,{type:"lineage_stopped",data:{reason:"continuation_budget_exhausted",limit:r,observed:n.n,continues:e.continues,coordinator_agent_id:e.coordinatorId},now:e.now}),null;let s=(0,_.selectExecutionPolicy)({entryPoint:"continuation",executionKind:"conversation"});if(!s.ok)return null;let a="result"===e.continues?Math.max(e.parent.wake_depth-1,0):e.parent.wake_depth,o={safety_version:1,root_principal:{kind:e.parent.root_principal_kind??"unknown",id:e.parent.root_principal_id??"unknown"},wake_depth:a,grant_rule:"readonly_default",grant_id:null,continuations:{used:n.n+1,limit:r}};return i.engine.createOrGetWorkRequest({sourceConversationId:e.conversationId,sourceEventId:e.sourceEventId,requester:tu,targetAgentId:e.coordinatorId,intent:e.intent,executionKind:s.policy.execution_kind,toolProfile:s.policy.tool_profile,idempotencyKey:e.key,parentRequestId:e.parent.id,policy:{source:"coordinator_continuation",continues:e.continues,work_requests:e.subjects},executionPolicy:s.policy,wakeDepth:a,safetySnapshot:o,safety:{principalType:"engine",principal:tu,decision:"allowed",grantRule:"readonly_default",snapshot:o,now:e.now},now:e.now}).request}let tg=i.default.prepare("SELECT 1 FROM terminal_followups WHERE request_id = ? AND done_at IS NULL"),th=i.default.prepare("UPDATE terminal_followups SET done_at = ? WHERE request_id = ? AND done_at IS NULL");function tN(e,t,n,r){i.engine.transaction(()=>{t&&i.engine.finishAttempt(t,{outcome:"failed",errorCategory:n,errorMessage:r});let s=i.engine.getWorkRequest(e);s&&("queued"===s.state||"running"===s.state)&&i.engine.transitionWorkRequest(e,{from:s.state,to:"failed",errorCode:n,errorMessage:r})})}let tR=function(e,t,n={}){let i=n.owner??`${o.default.hostname()}:${process.pid}:${(0,r.randomUUID)().slice(0,8)}`,s={...function(e=process.env){let t={...ef};for(let n of Object.keys(eT)){let r=e[eT[n]];if(void 0===r||!/^\d+$/.test(r.trim()))continue;let i=Number(r.trim());Number.isSafeInteger(i)&&i>0&&(t[n]=i)}return t.maxGlobal=Math.min(t.maxGlobal,eg.maxGlobal),t.maxPerTarget=Math.min(t.maxPerTarget,eg.maxPerTarget),t}(),...n.config??{}},a=n.now??Date.now,u=function(e,t,n={}){let i=n.now??Date.now,s=n.cancelGraceMs??3e4,a=e.prepare("SELECT * FROM work_attempts WHERE request_id = ? AND finished_at IS NULL"),o=e.prepare("SELECT COUNT(*) AS n FROM work_attempts WHERE request_id = ?"),u=e.prepare("SELECT owner, token, expires_at FROM dispatch_leases WHERE request_id = ?"),l=e.prepare("SELECT 1 FROM engine_events WHERE attempt_id = ? AND type = 'runtime_started' LIMIT 1");function _(e){let n=t.getWorkRequest(e);if(!n)throw new ec("not_found",`No work request ${e}.`);return n}function E(e,t,n,r){if(r&&(!e||!r(e,t,n)))throw new ec("forbidden",`Not allowed to ${n} this request.`)}function p(e){return Math.max(e.attempt_count,o.get(e.id).n)}function m(t,n){e.prepare("UPDATE dispatch_attention SET cleared_at = ? WHERE request_id = ? AND cleared_at IS NULL").run(n,t)}function f(n,r,i){let s=u.get(n);s&&(e.prepare("DELETE FROM dispatch_leases WHERE request_id = ?").run(n),t.appendEvent(n,{type:"dispatch_released",data:{owner:s.owner,outcome:r,forced:!0},now:i}))}function T(e,n,r){let i=a.get(e.id);if(!i)return null;let s=ep(i).transport;return t.finishAttempt(i.id,{outcome:"timed_out"===n?"timed_out":"cancelled"===n?"cancelled":"interrupted",errorCategory:"abandoned",errorMessage:{cancelled:"The request was cancelled while this Attempt was open; its result is no longer awaited.",timed_out:"The Attempt passed its deadline; its result is no longer awaited.",retried:"An operator retried the request; this Attempt is superseded."}[n],now:r}),t.appendEvent(e.id,{type:"attempt_abandoned",attemptId:i.id,data:{reason:n,attempt_number:i.attempt_number,external_run_id:i.external_run_id,transport:"string"==typeof s?s:null},now:r}),{requestId:e.id,attemptId:i.id,externalRunId:i.external_run_id,transport:"string"==typeof s?s:null,reason:n,launched:!!i.external_run_id||!!i.external_session_id||!!l.get(i.id)}}function g(n,r,i,s){let a=r?`${r.kind}:${r.id}`:null;e.prepare("UPDATE work_requests SET cancel_requested_at = ?, cancel_requested_by = ?, cancel_reason = ?, updated_at = ? WHERE id = ? AND cancel_requested_at IS NULL").run(s,a,i,s,n.id),t.appendEvent(n.id,{type:"cancel_requested",data:{by:a,reason:i,state:n.state},now:s})}function h(e,n,r={}){return t.transitionWorkRequest(e.id,{from:e.state,to:"cancelled",reason:"cancel_requested",errorCode:"cancelled",errorMessage:e.cancel_reason??"The request was cancelled.",data:r,now:n})}function N(e,n,r={}){return t.transitionWorkRequest(e.id,{from:e.state,to:"failed",reason:"timed_out",errorCode:"timed_out",errorMessage:"The request passed its deadline.",data:{...r,deadline_at:e.deadline_at},now:n})}function R(n,i,s){let a=(0,c.storedRetryPolicy)(n.retry_policy),o=(0,c.classifyFailure)(i.category,i.code),d=p(n),u=(0,c.decideRetry)({policy:a,attemptCount:d,disposition:o,deadlineAt:n.deadline_at,now:s}),l=i.attention&&"retry"===u.action?{action:"attention"}:u,_={category:i.category,disposition:o,attempt_count:d,max_attempts:a.max_attempts};switch(l.action){case"retry":{e.prepare("UPDATE work_requests SET next_eligible_at = ? WHERE id = ?").run(l.nextEligibleAt,n.id);let r=t.transitionWorkRequest(n.id,{from:"running",to:"queued",reason:"retry_scheduled",data:{..._,retry:l.retry,delay_ms:l.delayMs,next_eligible_at:l.nextEligibleAt,error_code:i.errorCode},now:s});return{outcome:"retry_scheduled",decision:l,request:r}}case"deadline":return{outcome:"timed_out",decision:l,request:N(n,s,_)};case"attention":{let a=i.attention??`failure:${i.category??"unknown"}`;return e.prepare("INSERT INTO dispatch_attention (id, request_id, attempt_id, reason, detail, created_at) VALUES (?, ?, NULL, ?, ?, ?)").run((0,r.randomUUID)(),n.id,a,i.code,s),t.appendEvent(n.id,{type:"attention_set",data:{reason:a,detail:i.code},now:s}),{outcome:"attention",decision:l,request:t.transitionWorkRequest(n.id,{from:"running",to:"waiting",reason:`manual_attention:${i.attention??i.category??"unknown"}`,data:_,now:s})}}case"exhausted":if(a.max_attempts>1)return{outcome:"retries_exhausted",decision:l,request:t.transitionWorkRequest(n.id,{from:"running",to:"failed",reason:"retries_exhausted",errorCode:i.errorCode,errorMessage:i.errorMessage,data:_,now:s})};case"fail":return{outcome:"failed",decision:l,request:t.transitionWorkRequest(n.id,{from:"running",to:"failed",errorCode:i.errorCode,errorMessage:i.errorMessage,data:"fail"===l.action?_:{},now:s})}}}let v={now:i,cancelGraceMs:s,cancel:(e,n={})=>t.transaction(()=>{let t=_(e);if(E(n.actor,t,"cancel",n.authorize),d.TERMINAL_STATES.includes(t.state))return{outcome:"already_terminal",state:t.state,replayed:!0,abandoned:null};let r=n.now??i();if("running"===t.state)return null!==t.cancel_requested_at?{outcome:"cancel_requested",state:"running",replayed:!0,abandoned:null}:(g(t,n.actor,n.reason??null,r),{outcome:"cancel_requested",state:"running",replayed:!1,abandoned:null});null===t.cancel_requested_at&&g(t,n.actor,n.reason??null,r);let s=_(e),a=T(s,"cancelled",r);return m(e,r),f(e,"cancelled",r),{outcome:"cancelled",state:h(s,r,{from_state:t.state}).state,replayed:!1,abandoned:a}}),retry:(n,r={})=>t.transaction(()=>{let s=_(n);if(E(r.actor,s,"retry",r.authorize),d.TERMINAL_STATES.includes(s.state))return{outcome:"already_terminal",state:s.state,abandoned:null};if("queued"===s.state)return{outcome:"already_queued",state:"queued",abandoned:null};if("waiting"!==s.state||null!==s.cancel_requested_at)return{outcome:"not_retryable",state:s.state,abandoned:null};let a=(0,c.storedRetryPolicy)(s.retry_policy),o=p(s);if(o>=a.max_attempts)return{outcome:"retries_exhausted",state:s.state,abandoned:null};let u=r.now??i();if(null!==s.deadline_at&&u>=s.deadline_at)return{outcome:"not_retryable",state:s.state,abandoned:null};let l=T(s,"retried",u);return m(n,u),e.prepare("UPDATE work_requests SET next_eligible_at = ? WHERE id = ?").run(u,n),{outcome:"retry_scheduled",state:t.transitionWorkRequest(n,{from:"waiting",to:"queued",reason:"retry_scheduled",data:{manual:!0,by:r.actor?`${r.actor.kind}:${r.actor.id}`:null,attempt_count:o,max_attempts:a.max_attempts,retry:o,delay_ms:0,next_eligible_at:u},now:u}).state,abandoned:l}}),timeOut:(e,n)=>t.transaction(()=>{let r=t.getWorkRequest(e),s=n??i();if(!r||!eE.includes(r.state)||null===r.deadline_at||s<r.deadline_at)return null;let a=T(r,"timed_out",s);return m(e,s),f(e,"timed_out",s),N(r,s,{from_state:r.state}),{requestId:e,outcome:"timed_out",abandoned:a}}),settleFailure:(e,n,r)=>t.transaction(()=>{let t=_(e);if("running"!==t.state)throw new d.EngineStoreError("stale_state",`Work request ${e} is ${t.state}, not running.`);return R(t,n,r??i())}),enforceRequest:(e,n,r={})=>t.transaction(()=>{let o,d=t.getWorkRequest(e),l=n??i();if(!d||!eE.includes(d.state)||null!==d.legacy_agent_request_id)return null;if(null!==d.deadline_at&&l>=d.deadline_at)return v.timeOut(e,l);if("running"!==d.state)return null;if(null!==d.cancel_requested_at){let t=u.get(e);if(!(!0===r.force||!t||t.expires_at<=l)&&l-d.cancel_requested_at<s)return null;let n=T(d,"cancelled",l);return f(e,"cancelled",l),h(d,l,{abandoned:null!==n}),{requestId:e,outcome:"cancelled",abandoned:n}}let c=a.get(e),E=c&&"number"==typeof(o=ep(c).deadline_at)?o:null;if(!c||null===E||l<E)return null;let p=T(d,"timed_out",l);f(e,"attempt_timed_out",l);let m=R(_(e),{category:"timed_out",code:null,errorCode:"timed_out",errorMessage:"The Attempt passed its deadline."},l);return{requestId:e,outcome:m.outcome,abandoned:p}}),dueRequests(t){let n=t??i();return e.prepare(`
|
|
2008
|
+
SELECT id FROM work_requests
|
|
2009
|
+
WHERE state IN ('queued', 'blocked', 'running', 'waiting') AND legacy_agent_request_id IS NULL AND executor = 'dispatcher'
|
|
2010
|
+
AND ((deadline_at IS NOT NULL AND deadline_at <= ?) OR state = 'running')
|
|
2011
|
+
ORDER BY created_at ASC, id ASC
|
|
2012
|
+
`).all(n).map(e=>e.id)},enforceDue(e){let t=e??i(),n=[];for(let e of v.dueRequests(t)){let r=v.enforceRequest(e,t);r&&n.push(r)}return n},attemptDeadlineFor:(e,t)=>(0,c.attemptDeadline)((0,c.storedRetryPolicy)(e.retry_policy),e.deadline_at,t),attemptsUsed:p};return v}(e,t,{now:a,cancelGraceMs:s.cancelGraceMs}),l=e.prepare("SELECT COUNT(*) AS n FROM dispatch_leases"),_=e.prepare("SELECT COUNT(*) AS n FROM dispatch_leases WHERE target_agent_id = ?"),E=e.prepare("SELECT * FROM dispatch_attention WHERE request_id = ? AND cleared_at IS NULL"),p=e.prepare(`SELECT type, data FROM engine_events WHERE request_id = ? AND type NOT IN (${em}) ORDER BY sequence DESC LIMIT 1`),m=e.prepare(`
|
|
2013
|
+
SELECT w.id FROM work_requests w
|
|
2014
|
+
WHERE w.state = 'queued' AND w.executor = 'dispatcher'
|
|
2015
|
+
AND (SELECT e.type FROM engine_events e WHERE e.request_id = w.id AND e.type NOT IN (${em}) ORDER BY e.sequence DESC LIMIT 1) = 'dispatch_deferred'
|
|
2016
|
+
ORDER BY w.created_at ASC, w.id ASC
|
|
2017
|
+
`),f=e.prepare("SELECT 1 FROM dispatch_leases WHERE request_id = ? AND token = ?"),T=e.prepare("SELECT decision FROM wake_safety_decisions WHERE request_id = ? ORDER BY sequence DESC LIMIT 1"),g=e.prepare("SELECT status FROM wakes WHERE id = ?"),h=e.prepare(`
|
|
2018
|
+
SELECT w.id FROM work_requests w
|
|
2019
|
+
WHERE w.state = 'queued' AND w.legacy_agent_request_id IS NULL AND w.executor = 'dispatcher' AND w.id <> ?
|
|
2020
|
+
AND (w.created_at < ? OR (w.created_at = ? AND w.rowid < (SELECT rowid FROM work_requests WHERE id = ?)))
|
|
2021
|
+
AND (w.next_eligible_at IS NULL OR w.next_eligible_at <= ?)
|
|
2022
|
+
AND (w.deadline_at IS NULL OR w.deadline_at > ?)
|
|
2023
|
+
AND NOT EXISTS (SELECT 1 FROM dispatch_attention a WHERE a.request_id = w.id AND a.cleared_at IS NULL)
|
|
2024
|
+
AND (SELECT d.decision FROM wake_safety_decisions d WHERE d.request_id = w.id ORDER BY d.sequence DESC LIMIT 1) = 'allowed'
|
|
2025
|
+
AND (w.wake_event_id IS NULL OR EXISTS (SELECT 1 FROM wakes k WHERE k.id = w.wake_event_id AND k.status = 'accepted'))
|
|
2026
|
+
AND (SELECT COUNT(*) FROM dispatch_leases l WHERE l.target_agent_id = w.target_agent_id) < ?
|
|
2027
|
+
ORDER BY w.created_at ASC, w.rowid ASC
|
|
2028
|
+
LIMIT 1
|
|
2029
|
+
`);function N(e,n,r,i){let o=p.get(e.id);return(o?.type==="dispatch_deferred"&&o.data?JSON.parse(o.data).reason:null)!==n&&t.appendEvent(e.id,{type:"dispatch_deferred",data:{reason:n,active_global:r.global,active_target:r.target,max_global:s.maxGlobal,max_per_target:s.maxPerTarget,...i?{waiting_behind:i}:{}},now:a()}),i?{ok:!1,reason:n,blockedBy:i}:{ok:!1,reason:n}}function R(e){if(!f.get(e.requestId,e.token))throw new eh(e.requestId)}let v={owner:i,config:s,now:a,control:u,claim:(n,o={})=>t.transaction(()=>{let d=t.getWorkRequest(n);if(!d||"queued"!==d.state||void 0!==o.expectedVersion&&d.version!==o.expectedVersion)return{ok:!1,reason:"not_queued"};let p=a();if(null!==d.deadline_at&&p>=d.deadline_at)return u.timeOut(n,p),{ok:!1,reason:"timed_out"};if(null!==d.next_eligible_at&&p<d.next_eligible_at)return{ok:!1,reason:"not_eligible"};if(E.get(n))return{ok:!1,reason:"attention"};let m=function(e){let t=T.get(e.id);if(t?.decision!=="allowed")return"The request has no allowed safety decision.";if(null!==e.wake_event_id){let t=g.get(e.wake_event_id);if(t?.status!=="accepted")return"The Wake that created this request was not accepted."}return null}(d);if(m)return t.transitionWorkRequest(n,{from:"queued",to:"failed",reason:"not_authorized",expectedVersion:d.version,errorCode:"not_authorized",errorMessage:m,now:p}),{ok:!1,reason:"not_authorized"};let f=(0,c.storedRetryPolicy)(d.retry_policy),R=u.attemptsUsed(d);if(R>=f.max_attempts)return t.transitionWorkRequest(n,{from:"queued",to:"failed",reason:"retries_exhausted",expectedVersion:d.version,errorCode:"retries_exhausted",errorMessage:"No Attempt is left in the retry budget.",data:{attempt_count:R,max_attempts:f.max_attempts},now:p}),{ok:!1,reason:"exhausted"};let v=l.get().n,k=_.get(d.target_agent_id).n;if(v>=s.maxGlobal)return N(d,"global_limit",{global:v,target:k});if(k>=s.maxPerTarget)return N(d,"target_limit",{global:v,target:k});let y=h.get(n,d.created_at,d.created_at,n,p,p,s.maxPerTarget);if(y)return N(d,"older_waiting",{global:v,target:k},y.id);let w={requestId:n,owner:i,token:(0,r.randomUUID)(),expiresAt:p+s.leaseMs};return e.prepare(`
|
|
2030
|
+
INSERT INTO dispatch_leases (request_id, target_agent_id, owner, token, acquired_at, heartbeat_at, expires_at)
|
|
2031
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
2032
|
+
`).run(n,d.target_agent_id,i,w.token,p,p,w.expiresAt),t.appendEvent(n,{type:"dispatch_claimed",data:{owner:i,lease_expires_at:w.expiresAt,active_global:v+1,active_target:k+1,attempt_number:R+1,max_attempts:f.max_attempts},now:p}),e.prepare("UPDATE work_requests SET attempt_count = ?, next_eligible_at = NULL WHERE id = ?").run(R+1,n),{ok:!0,lease:w,request:t.transitionWorkRequest(n,{from:"queued",to:"running",expectedVersion:d.version,data:o.data,now:p})}}),claimNext(t){let n=t??e.prepare(`
|
|
2033
|
+
SELECT id FROM work_requests WHERE state = 'queued' AND legacy_agent_request_id IS NULL AND executor = 'dispatcher'
|
|
2034
|
+
AND (next_eligible_at IS NULL OR next_eligible_at <= ?)
|
|
2035
|
+
ORDER BY created_at ASC, rowid ASC
|
|
2036
|
+
`).all(a()).map(e=>e.id),r="not_queued";for(let e of n){let t=v.claim(e);if(t.ok||"global_limit"===t.reason)return t;("target_limit"===t.reason||"older_waiting"===t.reason)&&(r=t.reason)}return{ok:!1,reason:r}},recordLaunchIntent:(n,s,o,d)=>t.transaction(()=>{R(n);let u=a(),l=d?(0,r.createHash)("sha256").update(d.body).digest("hex"):null;return e.prepare(`
|
|
2037
|
+
INSERT INTO attempt_launch_intents (attempt_id, request_id, transport, idempotency_key, body, body_hash, grant_fingerprint, owner, created_at)
|
|
2038
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2039
|
+
`).run(s,n.requestId,o,d?.idempotencyKey??null,d?.body??null,l,d?.grantFingerprint??null,i,u),t.appendEvent(n.requestId,{type:"launch_intent_recorded",attemptId:s,data:{transport:o,idempotency_key:d?.idempotencyKey??null,body_hash:l,grant_fingerprint:d?.grantFingerprint??null},now:u}),v.launchIntent(s)}),launchIntent:t=>e.prepare("SELECT * FROM attempt_launch_intents WHERE attempt_id = ?").get(t),heartbeat(t){let n=a(),r=n+s.leaseMs,i=1===e.prepare("UPDATE dispatch_leases SET heartbeat_at = ?, expires_at = ? WHERE request_id = ? AND token = ?").run(n,r,t.requestId,t.token).changes;return i&&(t.expiresAt=r),i},holds:e=>!!f.get(e.requestId,e.token),assertHeld(e){R(e)},release(n,r){t.transaction(()=>{R(n),e.prepare("DELETE FROM dispatch_leases WHERE request_id = ? AND token = ?").run(n.requestId,n.token),t.appendEvent(n.requestId,{type:"dispatch_released",data:{owner:i,outcome:r},now:a()})})},defer(n,r,o=null){t.transaction(()=>{R(n);let d=a();n.expiresAt=d+s.deferMs,e.prepare("UPDATE dispatch_leases SET heartbeat_at = ?, expires_at = ? WHERE request_id = ? AND token = ?").run(d,n.expiresAt,n.requestId,n.token),t.appendEvent(n.requestId,{type:"reconcile_deferred",attemptId:o,data:{owner:i,reason:r,retry_at:n.expiresAt},now:d})})},setAttention:(n,s)=>t.transaction(()=>{R(n);let o=a(),d=(0,r.randomUUID)();e.prepare("INSERT INTO dispatch_attention (id, request_id, attempt_id, reason, detail, created_at) VALUES (?, ?, ?, ?, ?, ?)").run(d,n.requestId,s.attemptId,s.reason,s.detail??null,o),t.appendEvent(n.requestId,{type:"attention_set",attemptId:s.attemptId,data:{reason:s.reason,detail:s.detail??null},now:o});let u=t.getWorkRequest(n.requestId);return u?.state==="running"&&t.transitionWorkRequest(n.requestId,{from:"running",to:"waiting",reason:`manual_attention:${s.reason}`,now:o}),e.prepare("DELETE FROM dispatch_leases WHERE request_id = ? AND token = ?").run(n.requestId,n.token),t.appendEvent(n.requestId,{type:"dispatch_released",data:{owner:i,outcome:"attention"},now:o}),E.get(n.requestId)}),attention:e=>E.get(e),recoverable(){let t=a(),n=[];for(let r of e.prepare("SELECT request_id, owner, token, expires_at FROM dispatch_leases ORDER BY acquired_at ASC, request_id ASC").all()){if(r.owner===i&&r.expires_at>t)continue;let e=r.expires_at<=t?"lease_expired":!function(e){let t=/^(.*):(\d+):[^:]+$/.exec(e);if(!t||t[1]!==o.default.hostname())return!1;let n=Number(t[2]);if(n===process.pid)return!1;try{return process.kill(n,0),!1}catch(e){return"ESRCH"===e.code}}(r.owner)?null:"owner_exited";e&&n.push({requestId:r.request_id,reason:e,priorToken:r.token,priorOwner:r.owner})}for(let t of e.prepare(`
|
|
2040
|
+
SELECT w.id FROM work_requests w
|
|
2041
|
+
WHERE w.state = 'running' AND w.legacy_agent_request_id IS NULL AND w.executor = 'dispatcher'
|
|
2042
|
+
AND NOT EXISTS (SELECT 1 FROM dispatch_leases l WHERE l.request_id = w.id)
|
|
2043
|
+
AND NOT EXISTS (SELECT 1 FROM dispatch_attention a WHERE a.request_id = w.id AND a.cleared_at IS NULL)
|
|
2044
|
+
ORDER BY w.updated_at ASC, w.id ASC
|
|
2045
|
+
`).all())n.push({requestId:t.id,reason:"unleased_running",priorToken:null,priorOwner:null});return n},takeOver:n=>t.transaction(()=>{let o=a(),d={requestId:n.requestId,owner:i,token:(0,r.randomUUID)(),expiresAt:o+s.leaseMs};if(n.priorToken){let t="lease_expired"===n.reason?"AND expires_at <= ?":"",r=[i,d.token,o,o,d.expiresAt,n.requestId,n.priorToken];if(t&&r.push(o),1!==e.prepare(`
|
|
2046
|
+
UPDATE dispatch_leases SET owner = ?, token = ?, acquired_at = ?, heartbeat_at = ?, expires_at = ?
|
|
2047
|
+
WHERE request_id = ? AND token = ? ${t}
|
|
2048
|
+
`).run(...r).changes)return null}else{let r=t.getWorkRequest(n.requestId);if(!r||"running"!==r.state||e.prepare("SELECT 1 FROM dispatch_leases WHERE request_id = ?").get(n.requestId)||E.get(n.requestId))return null;e.prepare(`
|
|
2049
|
+
INSERT INTO dispatch_leases (request_id, target_agent_id, owner, token, acquired_at, heartbeat_at, expires_at)
|
|
2050
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
2051
|
+
`).run(n.requestId,r.target_agent_id,i,d.token,o,o,d.expiresAt)}return t.appendEvent(n.requestId,{type:"dispatch_lease_taken_over",data:{owner:i,previous_owner:n.priorOwner,reason:n.reason},now:o}),d}),deferredRequestIds:()=>m.all().map(e=>e.id),leaseOf:t=>e.prepare("SELECT owner, token, expires_at FROM dispatch_leases WHERE request_id = ?").get(t)};return v}(i.default,i.engine);class tv extends Error{reason;constructor(e){super(`Commit deferred: ${e}`),this.reason=e}}async function tk(e){let t=await ty(e);var n=e,s=t||i.engine.getWorkRequest(e)?.state!=="queued";for(let e of function(e,t=Date.now()){return i.engine.transaction(()=>{var n;if(!tg.get(e))return[];let s=i.engine.getWorkRequest(e);if(!s||null===s.terminal_at||null!==s.legacy_agent_request_id)return[];th.run(t,e);let a=[],o=e=>{e&&"queued"===e.state&&a.push(e.id)},d=tE(s);if(d){let e,n,a=[],l=null;try{a=function(e){if("string"!=typeof e.sourceEventId||!e.sourceEventId.trim())throw new eY("invalid_input","sourceEventId is required.");return i.default.transaction(()=>{let t=i.default.prepare("SELECT * FROM messages WHERE id = ?").get(e.sourceEventId);if(!t)throw new eY("source_not_found",`No conversation event ${e.sourceEventId}.`);if("bot"!==t.sender_type||!t.sender_id||!i.bots.getById(t.sender_id))throw new eY("invalid_input","Wakes are routed only from an Agent message.");let n=null;if(e.parentRequestId){if(!(n=i.engine.getWorkRequest(e.parentRequestId)??null))throw new eY("not_found",`No parent Work Request ${e.parentRequestId}.`);if(n.target_agent_id!==t.sender_id||n.source_conversation_id!==t.conversation_id)throw new eY("parent_mismatch","The parent Work Request was not run by this Agent in this conversation.")}let s=e.now??Date.now();return(function(e){let t=[],n=0,r=(n,r)=>{var i,s;let a;for(let o of(i=e.slice(n,r),(a=[...i.matchAll(eP)]).map((e,t)=>{let r=t+1<a.length?a[t+1].index:i.length,s=i.slice(e.index,r);return{at:n+e.index,raw:s.trim(),target:e[1],message:s.slice(e[0].length).trim()}}))){let e="GROUP"===o.target.toUpperCase()?{ok:!1,reason:"group wakes are not supported; wake one Agent by name"}:0===o.message.length?{ok:!1,reason:"objective must be non-empty (max 20000 characters)"}:eB((s=o.target,{version:1,target:s,executionKind:"conversation",objective:o.message}));t.push({at:o.at,syntax:"legacy",raw:o.raw,validation:e})}};for(let i of e.matchAll(eK)){let e,s=i.index;r(n,s);try{e=eB(JSON.parse(i[1]))}catch{e={ok:!1,reason:"block is not valid JSON"}}t.push({at:s,syntax:"structured",raw:i[0],validation:e}),n=s+i[0].length}return r(n,e.length),t.sort((e,t)=>e.at-t.at).map((e,t)=>({position:t,syntax:e.syntax,raw:e.raw,validation:e.validation}))})(t.content).map(e=>(function(e,t,n,s,a){var o,d;let l,c,E=(o=t.id,c=(0,r.createHash)("sha256").update(ej(e)).digest("hex").slice(0,32),`wake:v1:${o}:${e.position}:${c}`),p=eJ.get(E);if(p)return eQ(p,!1);if(eV.get(t.id,e.position))throw new eY("idempotency_conflict",`Wake ${e.position} of event ${t.id} was already recorded with a different payload.`);let T=(0,r.randomUUID)(),g=s?.wake_event_id?(d=s.wake_event_id,ez.get(d)):void 0,h={id:T,idempotency_key:E,source_conversation_id:t.conversation_id,source_event_id:t.id,requester_agent_id:n,parent_request_id:s?.id??null,root_wake_id:g?.root_wake_id??T,syntax:e.syntax},N=null;if(e.validation.ok)if(s){let r=function(e,t,n){for(let r of[...e.contextWorkRequests??[],...e.resumeWorkRequest?[e.resumeWorkRequest]:[]]){let e=i.engine.getWorkRequest(r);if(!(e&&(n?e.root_request_id===n.root_request_id:e.source_conversation_id===t)))return`Work Request ${r} is not in this conversation lineage.`}return null}(N=e.validation.envelope,t.conversation_id,s);l=r?{status:"rejected",code:"invalid_reference",reason:r}:function(e){let{maxWakeDepth:t}=m(),n=e.wake_depth+1;return n>t?{status:"rejected",code:"depth_exceeded",limit:t,observed:n,reason:`This work is already ${e.wake_depth} Wakes deep (limit ${t}).`}:function(e){let{rootBudget:t}=m(),n=e0(e);return n<t?null:{status:"rejected",code:"root_budget_exhausted",limit:t,observed:n,reason:`This work already used ${n} Wakes (limit ${t}).`}}(e.root_request_id)}(s)??function(e,t,n){let r=(0,i.resolveWakeTarget)(e.target);if(!r.ok){var s;return"ambiguous"===r.reason?{status:"unavailable",code:"target_ambiguous",reason:`More than one Agent is named ${e.target}; rename one to restore routing.`}:(s=e.target,i.default.prepare("SELECT 1 FROM groups WHERE lower(trim(name)) = lower(trim(?))").get(s))?{status:"rejected",code:"target_is_group",reason:`${e.target} is a Group; wake one Agent by name.`}:{status:"unavailable",code:"target_not_found",reason:`No Agent is named ${e.target}.`}}return function(e,t,n,r){let s=r.parent?.root_request_id??null,a=(0,_.selectExecutionPolicy)({entryPoint:"wake",executionKind:e.executionKind,wakeSyntax:t,resumesWorkRequest:!!e.resumeWorkRequest});if(!a.ok)return{status:"rejected",code:"unsupported_policy",reason:a.reason,target:n};let o=a.policy;if(e.resumeWorkRequest){let t=i.engine.getWorkRequest(e.resumeWorkRequest);if(!t||t.target_agent_id!==n.id||!["implementation","revision"].includes(t.execution_kind))return{status:"rejected",code:"invalid_reference",reason:"A revision resumes an implementation Work Request of the same Agent.",target:n}}if("review"===e.executionKind&&((e.contextWorkRequests??[]).some(e=>{let t=i.engine.getWorkRequest(e);return t&&["implementation","revision"].includes(t.execution_kind)&&t.target_agent_id===n.id})||null!==s&&i.default.prepare("SELECT 1 FROM work_requests WHERE root_request_id = ? AND target_agent_id = ? AND execution_kind IN ('implementation', 'revision') LIMIT 1").get(s,n.id)))return{status:"rejected",code:"reviewer_not_independent",reason:`${n.name} did the work under review; wake a different reviewer or ask the person.`,target:n};let d=function(e,t,n){var r,s,a;if("implementation"!==(r=e.executionKind)&&"revision"!==r)return{rule:"readonly_default",id:null};if(function(e,t,n){var r;let s=n.parent;if("implementation"!==e.executionKind||t.id!==n.agentId||!s||null!==s.wake_event_id||0!==s.wake_depth||null!==s.parent_request_id||s.target_agent_id!==n.agentId||(r={kind:s.root_principal_kind??"",id:s.root_principal_id??""},r.kind!==f.kind||r.id!==f.id))return!1;let a=i.engine.listSafetyDecisions(s.id)[0];return a?.principal_type==="human_owner"}(e,t,n))return{rule:"owner_direct_self_wake",id:null};let o=(s=n.agentId,a=t.id,i.default.prepare("SELECT * FROM wake_grants WHERE caller_agent_id = ? AND target_agent_id = ? AND authority = 'edit' AND revoked_at IS NULL").get(s,a));return o?{rule:"edit_grant",id:o.id}:null}(e,n,r);return d?function(e,t,n){var r;let s=i.bots.getById(e.id),a=(0,u.resolveAgent)(s);if(!a.launchable)return{status:"blocked",code:"target_unconfigured",reason:"launch_profile"===a.launch_blocker?`${e.name} has no Agent Deck selected and no launch profile chosen.`:"session_scope"===a.launch_blocker?`${e.name} has no session scope.`:"direct_runtime"===a.launch_blocker?`${e.name} launches directly; direct ${a.agent} sessions are not available yet.`:a.needs_deck_selection?`${e.name} has no Agent Deck selected.`:`${e.name} has an unsupported Agent type.`,target:e,policy:t,grant:n};let o=(r=s,"hermes-gateway"===(0,u.agentTransport)((0,u.resolveAgent)(r).agent)?b()?{available:!0}:{available:!1,reason:"The Hermes gateway is not configured (HERMES_API_SERVER_KEY is unset)."}:{available:!0});return o.available?{status:"accepted",code:null,reason:null,target:e,policy:t,grant:n}:{status:"blocked",code:"target_unavailable",reason:o.reason,target:e,policy:t,grant:n}}(n,o,d):{status:"blocked",code:"grant_required",reason:`${n.name} needs your approval for edit work.`,target:n,policy:o,grant:null}}(e,t,{id:r.agentId,name:r.displayName},n)}(N,e.syntax,{agentId:n,parent:s})}else N=e.validation.envelope,l={status:"rejected",code:"untracked_lineage",reason:"Its source turn is not tracked work, so the Wake cannot start a lineage."};else l={status:"rejected",code:"invalid_envelope",reason:e.validation.reason};let R=N&&eZ(l)?function(e,t,n,r){var s,a,o,d,u,l;let _,c,E=e.parent_request_id?i.engine.getWorkRequest(e.parent_request_id)??null:null;if(!E)throw new eY("invalid_input","A Wake creates work only in a tracked lineage.");let p=(s={rootPrincipal:{kind:E.root_principal_kind??"unknown",id:E.root_principal_id??"unknown"},wakeDepth:E.wake_depth+1,grant:n.grant,rootRequestId:E.root_request_id,counting:!0},_=m(),c=s.rootRequestId?e0(s.rootRequestId):0,{safety_version:1,root_principal:s.rootPrincipal,wake_depth:s.wakeDepth,grant_rule:s.grant?.rule??null,grant_id:s.grant?.id??null,root_budget:{used:c+ +!!s.counting,limit:_.rootBudget},safety_limits:{max_wake_depth:_.maxWakeDepth,root_budget:_.rootBudget}}),{request:f}=i.engine.createOrGetWorkRequest({sourceConversationId:e.source_conversation_id,sourceEventId:e.source_event_id,requester:{kind:"bot",id:e.requester_agent_id},targetAgentId:n.target.id,intent:t.objective,executionKind:n.policy.execution_kind,toolProfile:n.policy.tool_profile,idempotencyKey:e.idempotency_key,parentRequestId:e.parent_request_id,wakeEventId:e.id,policy:{source:"wake",wake_version:1,wake_syntax:e.syntax,root_wake_id:e.root_wake_id,requested_target:t.target,target_name_snapshot:n.target.name,context_work_requests:t.contextWorkRequests??[],resume_work_request:t.resumeWorkRequest??null,limits:t.limits??{},return_to:{agent_id:e.requester_agent_id,conversation_id:e.source_conversation_id}},executionPolicy:n.policy,initialState:"blocked"===n.status?"blocked":"queued",stateReason:"blocked"===n.status?`${n.code}: ${n.reason}`:null,safetySnapshot:p,safety:(a=e.id,o=e.requester_agent_id,{principalType:"agent_principal",principal:{kind:"bot",id:o},decision:"accepted"===n.status?"allowed":"blocked",reasonCode:n.code,grantRule:n.grant?.rule??null,grantId:n.grant?.id??null,wakeId:a,snapshot:p,now:r}),now:r});return"grant_required"===n.code&&(d=f,u=e.id,l=r,i.engine.appendEvent(d.id,{type:"grant_requested",data:{wake_id:u,caller_agent_id:d.requester_id,target_agent_id:d.target_agent_id,authority:"edit",execution_kind:d.execution_kind},now:l})),f}(h,N,l,a):null;return i.default.prepare(`
|
|
2052
|
+
INSERT INTO wakes (
|
|
2053
|
+
id, idempotency_key, source_conversation_id, source_event_id, position, syntax, payload,
|
|
2054
|
+
requester_agent_id, requested_target, target_agent_id, target_name_snapshot, execution_kind,
|
|
2055
|
+
parent_request_id, root_request_id, root_wake_id, depth, status, reason_code, reason,
|
|
2056
|
+
work_request_id, limit_value, observed_value, created_at, updated_at
|
|
2057
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2058
|
+
`).run(T,E,t.conversation_id,t.id,e.position,e.syntax,ej(e),n,N?.target??null,l.target?.id??null,l.target?.name??null,N?.executionKind??null,s?.id??null,R?.root_request_id??s?.root_request_id??null,h.root_wake_id,R?.wake_depth??(s?s.wake_depth+1:0),l.status,l.code,l.reason,R?.id??null,eZ(l)?null:l.limit??null,eZ(l)?null:l.observed??null,a,a),eQ(ez.get(T),!0)})(e,t,t.sender_id,n,s))}).immediate()}({sourceEventId:d.id,parentRequestId:s.id,now:t})}catch(e){if(!(e instanceof eY))throw e;console.error(`Wakes of ${d.id} could not be routed:`,e.message),l=e}for(let e of a)o(e.request);let c=(function(e,t,n=Date.now()){let s=[...e.content.matchAll(e2)].map((e,t)=>{let n;try{n=function(e){if(!e||"object"!=typeof e||Array.isArray(e))return{ok:!1,reason:"decision must be a JSON object"};let t=Object.keys(e).filter(e=>!e1.has(e));if(t.length>0)return{ok:!1,reason:`unknown field ${t.join(", ")} (the manifest is never supplied in a decision)`};if(1!==e.version)return{ok:!1,reason:"version must be 1"};if("accept"!==e.decision&&"reject"!==e.decision)return{ok:!1,reason:'decision must be "accept" or "reject"'};if(!e4(e.implementationAttemptId))return{ok:!1,reason:"implementationAttemptId must name an Attempt"};if(!e4(e.reviewAttemptId))return{ok:!1,reason:"reviewAttemptId must name an Attempt"};let n={version:1,decision:e.decision,implementationAttemptId:e.implementationAttemptId.trim(),reviewAttemptId:e.reviewAttemptId.trim()};if(void 0!==e.commitMessage){if("string"!=typeof e.commitMessage||0===e.commitMessage.trim().length||e.commitMessage.length>2e3||e.commitMessage.includes("\0"))return{ok:!1,reason:"commitMessage must be non-empty text (max 2000 characters)"};n.commitMessage=e.commitMessage.trim()}return{ok:!0,decision:n}}(JSON.parse(e[1]))}catch{n={ok:!1,reason:"block is not valid JSON"}}return{position:t,validation:n}});return 0===s.length?[]:i.engine.transaction(()=>s.map(s=>{let a={position:s.position,finalizationId:null,reasonCode:null,reason:null,implementationRequestId:null,reviewRequestId:null},o=(r,o)=>(i.engine.appendEvent(t.id,{type:"finalization_rejected",data:{decision_event_id:e.id,position:s.position,reason_code:r,reason:o,implementation_request_id:a.implementationRequestId,review_request_id:a.reviewRequestId},now:n}),{...a,reasonCode:r,reason:o});if(!s.validation.ok)return o("invalid_decision",s.validation.reason);let d=s.validation.decision,u=i.engine.getAttempt(d.implementationAttemptId),l=i.engine.getAttempt(d.reviewAttemptId);if(a.implementationRequestId=u?.request_id??null,a.reviewRequestId=l?.request_id??null,"reject"===d.decision)return o("review_rejected","The coordinator rejected the review; nothing was finalized.");let _=function(e,t,n){let r=t.target_agent_id,s=(e,t)=>({ok:!1,code:e,reason:t}),a=i.engine.getAttempt(e.implementationAttemptId),o=a?i.engine.getWorkRequest(a.request_id):void 0;if(!o||!e9.includes(o.execution_kind))return s("invalid_implementation",`Attempt ${e.implementationAttemptId} is not an implementation or revision Attempt.`);let d=i.engine.getAttempt(e.reviewAttemptId),u=d?i.engine.getWorkRequest(d.request_id):void 0;if(!u||"review"!==u.execution_kind||"readonly"!==u.tool_profile)return s("invalid_review",`Attempt ${e.reviewAttemptId} is not a readonly review Attempt.`);if(o.source_conversation_id!==n||u.source_conversation_id!==n)return s("cross_conversation","The implementation and review must belong to this conversation.");for(let e of[o,u])if(e.root_request_id!==t.root_request_id||function(e){if(!e.wake_event_id)return null;let t=e6(e).return_to;return t&&"string"==typeof t.agent_id?t.agent_id:null}(e)!==r)return s("lineage_mismatch",`Work Request ${e.id} was not woken by this coordinator in this lineage.`);if("completed"!==o.state)return s("implementation_not_completed",`Implementation ${o.id} is ${o.state}, not completed.`);let l=e5(o.id);if(!l||l.id!==a?.id||"succeeded"!==l.outcome)return s("implementation_not_completed",`Implementation ${o.id} has no successful Attempt.`);let _=e8(l.id);if(!_)return s("not_finalizable",`Implementation ${o.id} has no candidate manifest to finalize.`);let c=e6(u).context_work_requests;if(!Array.isArray(c)||!c.includes(o.id))return s("review_not_linked",`Review ${u.id} does not reference implementation ${o.id}.`);if(u.target_agent_id===o.target_agent_id)return s("reviewer_not_independent","The reviewer did the work under review.");let E=e5(u.id);if("completed"!==u.state||!E||E.id!==d?.id||"succeeded"!==E.outcome)return s("review_not_completed",`Review ${u.id} did not complete.`);if(u.created_at<=_.created_at)return s("stale_manifest",`Review ${u.id} was requested before the candidate manifest was recorded.`);let p=i.default.prepare(`
|
|
2059
|
+
SELECT candidate.id FROM work_requests candidate
|
|
2060
|
+
WHERE root_request_id = ? AND target_agent_id = ? AND execution_kind IN ('implementation', 'revision')
|
|
2061
|
+
AND id <> ? AND (
|
|
2062
|
+
created_at > ? OR (created_at = ? AND candidate.rowid > (SELECT rowid FROM work_requests WHERE id = ?))
|
|
2063
|
+
) LIMIT 1
|
|
2064
|
+
`).get(o.root_request_id,o.target_agent_id,o.id,o.created_at,o.created_at,o.id);if(p)return s("stale_manifest",`A later edit (${p.id}) replaced the manifest of ${o.id}.`);let m=i.default.prepare("SELECT id FROM finalizations WHERE implementation_attempt_id = ? AND state IN ('preparing', 'committed') LIMIT 1").get(l.id);return{ok:!0,chain:{implementation:o,implementationAttempt:l,review:u,reviewAttempt:E,manifest:_},existing:m?.id??null}}(d,t,e.conversation_id);if(!_.ok)return o(_.code,_.reason);let c=tn(e.id,_.chain.implementationAttempt.id,_.chain.reviewAttempt.id,_.chain.manifest.manifest_digest),E=i.default.prepare("SELECT id FROM finalizations WHERE idempotency_key = ?").get(c);if(_.existing&&!E)return o("already_finalized",`Implementation ${_.chain.implementation.id} already has a finalization (${_.existing}).`);let{row:p}=function(e,t,n,s,a){var o,d;let u,l,_=tn(s.id,e.implementationAttempt.id,e.reviewAttempt.id,e.manifest.manifest_digest),c=i.default.prepare("SELECT * FROM finalizations WHERE idempotency_key = ?").get(_);if(c)return{row:c,created:!1};let E=JSON.stringify({baselineDigest:e.manifest.baseline_digest,expectedBaseCommit:e.manifest.base_commit,reviewId:e.review.id,commitMessage:(o=e.implementation,d=e.review,u=t.commitMessage??`Botmancers: ${(o.intent.split("\n").find(e=>e.trim())??"reviewed change").trim().slice(0,60)}`,l=`
|
|
2065
|
+
|
|
2066
|
+
Botmancers-Work-Request: ${o.id}
|
|
2067
|
+
Botmancers-Review: ${d.id}`,`${u.slice(0,4e3-l.length)}${l}`),files:te(e.manifest)}),p=(0,r.randomUUID)();i.default.prepare(`
|
|
2068
|
+
INSERT INTO finalizations (
|
|
2069
|
+
id, idempotency_key, conversation_id, decision_event_id, decision_request_id, coordinator_agent_id,
|
|
2070
|
+
implementation_request_id, implementation_attempt_id, review_request_id, review_attempt_id,
|
|
2071
|
+
manifest_id, external_run_id, request_body, request_hash, state, created_at, updated_at
|
|
2072
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'preparing', ?, ?)
|
|
2073
|
+
`).run(p,_,s.conversation_id,s.id,n.id,n.target_agent_id,e.implementation.id,e.implementationAttempt.id,e.review.id,e.reviewAttempt.id,e.manifest.id,e.manifest.external_run_id,E,e3(E),a,a);let m=e7(p);return i.engine.appendEvent(e.implementation.id,{type:"finalization_preparing",attemptId:e.implementationAttempt.id,data:tr(m,e.manifest),now:a}),{row:m,created:!0}}(_.chain,d,t,e,n);return{...a,finalizationId:p.id}}))})(d,s,t).filter(e=>null!==e.reasonCode&&"review_rejected"!==e.reasonCode);c.length>0&&o(tT({key:`continuation:v1:finalize-decision:${d.id}`,coordinatorId:s.target_agent_id,conversationId:d.conversation_id,sourceEventId:d.id,parent:s,intent:(e=c.map(e=>`- Decision ${e.position+1}: ${e.reasonCode} - ${e.reason}`),[`[Finalization not started] ${1===c.length?"One finalization decision":`${c.length} finalization decisions`} from your last message committed nothing:`,e.join("\n"),tm].join("\n\n")),continues:"finalize_decision",subjects:c.flatMap(e=>e.implementationRequestId?[e.implementationRequestId]:[]),now:t}));let E=a.filter(e=>"rejected"===e.wake.status||"unavailable"===e.wake.status);(l||E.length>0)&&o(tT({key:`continuation:v1:wakes:${d.id}`,coordinatorId:s.target_agent_id,conversationId:d.conversation_id,sourceEventId:d.id,parent:s,intent:l?["[Wake not started] The Wakes in your last message could not be routed, so no work started:",l.message,tm].join("\n\n"):(n=E.map(({wake:e})=>{let t=e.target_name_snapshot??e.requested_target??"an unnamed target",n=e.execution_kind??"unknown",r="blocked"===e.status?"is waiting (blocked)":`was ${e.status}`;return`- Wake ${e.position+1} (${n}) to ${t} ${r}: ${e.reason??e.reason_code??"no reason recorded"}`+(e.work_request_id?` Work Request: ${e.work_request_id}.`:" No Work Request was created.")}),[`[Wake not started] ${1===E.length?"One Wake":`${E.length} Wakes`} from your last message did not start any work:`,n.join("\n"),tm].join("\n\n")),continues:"wake_outcome",subjects:E.flatMap(e=>e.wake.work_request_id?[e.wake.work_request_id]:[]),now:t}))}let l=function(e){if(!e.wake_event_id)return null;let t=t_(e).return_to;return t&&"string"==typeof t.agent_id&&"string"==typeof t.conversation_id?{agentId:t.agent_id,conversationId:t.conversation_id}:null}(s);return l&&o(tT({key:`continuation:v1:result:${s.id}`,coordinatorId:l.agentId,conversationId:l.conversationId,sourceEventId:d?.id??s.source_event_id,parent:s,intent:(n=d?.conversation_id===l.conversationId,[`[Work Request result] ${tc(s.target_agent_id)} finished the ${s.execution_kind} you requested.`,tp(s,n),..."review"===s.execution_kind&&"completed"===s.state?['If this review satisfies you and the implementation has a candidate manifest, you may commit it by emitting a botmancers-finalize block: {"version": 1, "decision": "accept", "implementationAttemptId": "<id>", "reviewAttemptId": "<id>", "commitMessage": "<optional>"}, or "decision": "reject". Botmancers commits exactly the reviewed manifest; never list files or digests.']:[],tm].join("\n\n")),continues:"result",subjects:[s.id],now:t})),a})}(n))tA(e);for(let e of(function(e){let t=tb.forHopRequest(e);if(t)try{for(let e of tb.advance(t.id))tA(e)}catch(e){console.error("Exchange advance failed:",e instanceof Error?e.message:"unknown error")}}(n),i.default.prepare("SELECT id FROM finalizations WHERE state = 'preparing' ORDER BY created_at ASC, id ASC").all().map(e=>e.id)))tS.has(e)||function(e){let t=`finalization:${e}`;if(tI.get(t))return;tS.add(e);let n=td(e).then(e=>{if(e&&"preparing"!==e.state)for(let t of function(e,t=Date.now()){return i.engine.transaction(()=>{let n,r=e7(e);if(!r||"preparing"===r.state)return[];let s=i.engine.getWorkRequest(r.decision_request_id);if(!s)return[];let a=tT({key:`continuation:v1:finalization:${r.id}`,coordinatorId:r.coordinator_agent_id,conversationId:r.conversation_id,sourceEventId:r.decision_event_id,parent:s,intent:["committed"===r.state?"[Finalization committed] The reviewed manifest was committed.":`[Finalization ${r.state}] The reviewed manifest was not committed.`,(n=[`Finalization: ${r.id}`,`Implementation: ${r.implementation_request_id}`,`Review: ${r.review_request_id}`,`State: ${r.state}`],"committed"===r.state?n.push(`Commit: ${r.commit_id}`,`Tree: ${r.tree_id}`,`Manifest: ${r.result_manifest_digest}`,`Files: ${r.file_count}`):r.reason_code&&n.push(`Reason: ${r.reason_code}${r.reason?` - ${r.reason}`:""}`),n.join("\n")),tm].join("\n\n"),continues:"finalization",subjects:[r.implementation_request_id,r.review_request_id],now:t});return a&&"queued"===a.state?[a.id]:[]})}(e.id))tA(t)}).catch(e=>{console.error("Finalization failed unexpectedly:",e instanceof Error?e.message:"unknown error")}).finally(()=>{tI.delete(t)});tI.set(t,n)}(e);s&&function(){for(let e of tR.deferredRequestIds())tI.has(e)||tA(e)}()}async function ty(e){let s,a,o=i.engine.getWorkRequest(e);if(!o||"queued"!==o.state||null!==o.next_eligible_at&&tR.now()<o.next_eligible_at)return!1;let l=i.bots.getById(o.target_agent_id);if(!l)return tN(e,null,"agent_unavailable","The agent is no longer registered."),!1;let c=(0,_.authorizeWorkRequest)(o);if(!c.ok){try{i.engine.transitionWorkRequest(e,{from:"queued",to:"failed",expectedVersion:o.version,reason:"policy_rejected",errorCode:c.code,errorMessage:c.reason})}catch(e){if(!(e instanceof d.EngineStoreError&&"stale_state"===e.code))throw e}return!1}let E=c.policy,p=(0,u.resolveAgent)(l).agent,m=tb.resumeFor(o,p)??function(e,t){if("revision"!==e.execution_kind)return{ok:!0,binding:null};let n=t_(e).resume_work_request,r="string"==typeof n?i.engine.getWorkRequest(n):void 0;if(!r||r.root_request_id!==e.root_request_id||r.target_agent_id!==e.target_agent_id||!["implementation","revision"].includes(r.execution_kind))return{ok:!1,reason:"The revision does not reference an implementation of this Agent in this lineage."};let s=i.engine.getActiveSessionBinding({agentId:e.target_agent_id,adapter:t,conversationId:r.source_conversation_id,requestId:r.id});return s?{ok:!0,binding:s}:{ok:!1,reason:"The session of the referenced implementation is not available to resume."}}(o,p);if(!m.ok){try{i.engine.transitionWorkRequest(e,{from:"queued",to:"failed",expectedVersion:o.version,reason:"session_unavailable",errorCode:"session_unavailable",errorMessage:m.reason})}catch(e){if(!(e instanceof d.EngineStoreError&&"stale_state"===e.code))throw e}return!1}let f=null,T=null;try{f=function(e){var r,i,s,a;let o,d,l=(0,u.resolveAgent)(e.bot);if(!l.launchable||"agent_deck"===l.launch_profile&&!l.deck_id)throw new eq("agent_unavailable","launch_profile"===(r=l.launch_blocker)?"The agent has no launch profile chosen.":"session_scope"===r?"The agent has no session scope.":"direct_runtime"===r?"Direct launch is not available for this agent yet.":"The agent has no Agent Deck selected.");let c={prompt:{kind:"conversation",system:(d=(i=e.bot).title?`${i.name} (${i.title})`:i.name,`You are ${d}.
|
|
2074
|
+
${i.description}`),history:e.history},deck:l.deck_id,toolProfile:e.toolProfile??_.TOOL_PROFILE_FOR_KIND.conversation,sessionBinding:e.sessionBinding??null,correlation:{},...e.freshSession?{freshSession:!0}:{}};if("hermes-gateway"===(0,u.agentTransport)(l.agent))return{agent:l.agent,adapter:eC["hermes-gateway"](),input:{...c,target:{agentId:e.bot.id,agent:l.agent,hermesProfilePath:function(e){let t=(e.hermes_profile||"").trim();if(!t)return A;let n=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"");return n?`/p/${n}${A}`:A}(e.bot)},cwd:null}};try{let r;s=e.bot.id,a=l.working_directory,r=function(e,t,r){let i="string"==typeof t?t.trim():"";if(i)return"~"===i?H(r):i.startsWith("~/")||i.startsWith("~\\")?n.default.join(H(r),i.slice(2)):i;let s=String(e??"").trim();if(!s)throw Error("defaultBotWorkdir requires a bot id.");let a=H(r);return n.default.resolve(a,".botmancers",s)}(s,a,void 0),t.default.mkdirSync(r,{recursive:!0}),o=r}catch{throw new eq("agent_unavailable","The agent working directory is unavailable.")}return{agent:l.agent,adapter:eC["agent-deck-run"](),input:{...c,target:{agentId:e.bot.id,agent:l.agent},cwd:o,...e.prepareFinalization&&"edit"===c.toolProfile&&function(e){let r=n.default.resolve(e);for(;;){if(t.default.existsSync(n.default.join(r,".git")))return!0;let e=n.default.dirname(r);if(e===r)return!1;r=e}}(o)?{prepareFinalization:!0}:{}}}}({bot:l,history:[...i.default.prepare(`SELECT * FROM messages WHERE conversation_id = ?
|
|
2075
|
+
AND rowid <= (SELECT rowid FROM messages WHERE id = ?)
|
|
2076
|
+
ORDER BY rowid ASC`).all(o.source_conversation_id,o.source_event_id).map(e=>({speakerLabel:function(e){if("bot"===e.sender_kind&&e.sender_id){let t=i.bots.getById(e.sender_id);return t?t.name:`bot:${e.sender_id}`}return`${e.sender_kind??"person"}:${e.sender_id??"unknown"}`}(e),fromAgent:"bot"===e.sender_kind&&e.sender_id===l.id,content:e.content})),...function(e){if(e.requester_kind===tu.kind&&e.requester_id===tu.id&&"coordinator_continuation"===t_(e).source)return[{speakerLabel:tl,fromAgent:!1,content:e.intent}];if(!e.wake_event_id)return[];let t=t_(e),n=Array.isArray(t.context_work_requests)?t.context_work_requests.filter(e=>"string"==typeof e):[],r=[`[${e.execution_kind} Wake from ${tc(e.requester_id)}] Work Request: ${e.id}`,`Objective:
|
|
2077
|
+
${e.intent}`];for(let s of("string"==typeof t.resume_work_request&&r.push(`This revision continues your session from Work Request ${t.resume_work_request}.`),n)){let t=i.engine.getWorkRequest(s);t&&t.root_request_id===e.root_request_id&&r.push(`Context:
|
|
2078
|
+
${tp(t)}`)}return[{speakerLabel:tl,fromAgent:!1,content:r.join("\n\n")}]}(o),...tb.turnContext(o)??[]],toolProfile:E.tool_profile,sessionBinding:m.binding?{bindingId:m.binding.id,externalSessionId:m.binding.external_session_id}:null,..."freshSession"in m&&m.freshSession?{freshSession:!0}:{},prepareFinalization:"implementation"===E.execution_kind||"revision"===E.execution_kind})}catch(e){T=e instanceof eq?e:new eq("runtime_failed","The agent runtime did not complete the turn.")}let g={agent:p,agent_id:l.id,execution_kind:E.execution_kind,tool_profile:E.tool_profile,policy_rule:E.rule},h=new AbortController;try{s=i.engine.transaction(()=>{let t=tR.claim(e,{expectedVersion:o.version,data:{agent:p}});if(!t.ok)return a=t.blockedBy,null;if(f){let n=tR.now(),s=tR.control.attemptDeadlineFor(t.request,n),a={...f.input,deadlineAt:s,signal:h.signal},o=function(e,t,n){var i;let s=n.input.sessionBinding;if(s&&!s.bindingId)throw new d.EngineStoreError("invalid_input","A persisted resume attempt names its Session Binding.");if(s&&n.input.freshSession)throw new d.EngineStoreError("invalid_input","A fresh-session attempt cannot resume a Session Binding.");let a=e.createAttempt(t,{kind:s?"resume":"launch",adapter:n.agent,toolProfile:n.input.toolProfile,launchSnapshot:function(e){let{input:t}=e;return{...e.snapshot??{},agent:e.agent,agent_id:t.target.agentId,transport:e.adapter.name,deck:t.deck,cwd:t.cwd,tool_profile:t.toolProfile,hermes_profile_path:t.target.hermesProfilePath??null,prompt_kind:t.prompt.kind,prompt_hash:(0,r.createHash)("sha256").update(JSON.stringify(t.prompt)).digest("hex"),session_binding_id:t.sessionBinding?.bindingId??null,prepare_finalization:!0===t.prepareFinalization,fresh_session:!0===t.freshSession,deadline_at:t.deadlineAt??null}}(n),resumedSessionBindingId:s?.bindingId??null,now:n.now});return{attempt:a,input:Object.freeze({...i={...n.input,correlation:{...n.input.correlation,requestId:t,attemptId:a.id}},target:Object.freeze({...i.target}),prompt:Object.freeze("text"===i.prompt.kind?{...i.prompt}:{...i.prompt,history:Object.freeze(i.prompt.history.map(e=>Object.freeze({...e})))}),sessionBinding:i.sessionBinding?Object.freeze({...i.sessionBinding}):null,correlation:Object.freeze({...i.correlation})})}}(i.engine,e,{agent:p,adapter:f.adapter,input:a,snapshot:g,now:n});return tR.recordLaunchIntent(t.lease,o.attempt.id,f.adapter.name,f.adapter.launchIntent?.(o.input)??null),tb.hopClaimed(e,o.attempt.id,n),{lease:t.lease,attempt:o}}let n=i.engine.createAttempt(e,{kind:"launch",adapter:p,toolProfile:E.tool_profile,launchSnapshot:g});return tb.hopClaimed(e,n.id,n.started_at),{lease:t.lease,attempt:n.id}})}catch(e){if(e instanceof d.EngineStoreError&&"stale_state"===e.code)return!1;throw e}if(!s)return a&&tA(a),!1;let{lease:N}=s;if(!f||"string"==typeof s.attempt){let t=T??new eq("runtime_failed","The agent runtime did not complete the turn."),n="string"==typeof s.attempt?s.attempt:s.attempt.attempt.id;return i.engine.transaction(()=>{tR.assertHeld(N),tN(e,n,t.code,t.message),tR.release(N,"failed")}),!0}let R=s.attempt.attempt.id;return tw.set(e,{attemptId:R,controller:h}),await tO(N,async()=>{try{var t,n;let a,d=await eW(i.engine,s.attempt,f.adapter,{fence:()=>tR.holds(N),onEvent:e=>{e.type,function(e,t,n){if("progress"===n.type&&"finalization_prepared"===n.detail.phase&&"string"==typeof n.detail.baseline_ref&&"string"==typeof n.detail.baseline_digest){let r={baselineRef:n.detail.baseline_ref,baselineDigest:n.detail.baseline_digest};i.engine.transaction(()=>{tR.holds(e)&&tt(t,r,n.at)})}}(N,R,e)},sanitize:e=>tb.sanitizeHopResult(o,e),project:(e,t)=>(function(e,t,n,s){if(t.id,tR.assertHeld(e),"failed"===s.status&&s.failure?.code==="agent_deck_unreachable"&&n.external_run_id)throw new tv("unreachable");if("failed"===s.status&&s.launchUnconfirmed&&!n.external_run_id)throw new tv("launch_unconfirmed");let a=t.id,o=tR.now();!function(e,t,n,s=Date.now()){let a=n.finalization;if(!a||!t.external_run_id||!e9.includes(e.execution_kind)||"edit"!==e.tool_profile)return;if(a.baselineRef&&a.baselineDigest&&!tt(t.id,{baselineRef:a.baselineRef,baselineDigest:a.baselineDigest},s))return i.engine.appendEvent(e.id,{type:"candidate_manifest_unavailable",attemptId:t.id,data:{external_run_id:t.external_run_id,reason_code:"BASELINE_MISMATCH",reason:"The terminal baseline did not match the baseline captured at launch."},now:s});let o=a.candidate;if(!o)return;if(!o.ok)return i.engine.appendEvent(e.id,{type:"candidate_manifest_unavailable",attemptId:t.id,data:{external_run_id:t.external_run_id,reason_code:o.code,reason:o.message.slice(0,300)},now:s});let d=o.manifest;if(e8(t.id))return;let u=(0,r.randomUUID)();i.default.prepare(`
|
|
2079
|
+
INSERT INTO candidate_manifests (
|
|
2080
|
+
id, attempt_id, request_id, conversation_id, external_run_id, baseline_ref, baseline_digest,
|
|
2081
|
+
base_commit, manifest_digest, files, file_count, created_at
|
|
2082
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2083
|
+
`).run(u,t.id,e.id,e.source_conversation_id,t.external_run_id,d.baselineRef,d.baselineDigest,d.baseCommit,d.manifestDigest,JSON.stringify(d.files),d.files.length,s),i.engine.appendEvent(e.id,{type:"candidate_manifest_recorded",attemptId:t.id,data:{manifest_id:u,external_run_id:t.external_run_id,baseline_ref:d.baselineRef,baseline_digest:d.baselineDigest,base_commit:d.baseCommit,manifest_digest:d.manifestDigest,file_count:d.files.length},now:s})}(t,n,s,o);let d=i.engine.getWorkRequest(a)??t,u=null!==d.cancel_requested_at;if(u||null!==d.deadline_at&&o>=d.deadline_at)return u?i.engine.transitionWorkRequest(a,{from:"running",to:"cancelled",reason:"cancel_requested",errorCode:"cancelled",errorMessage:d.cancel_reason??"The request was cancelled.",data:{attempt_outcome:n.outcome},now:o}):i.engine.transitionWorkRequest(a,{from:"running",to:"failed",reason:"timed_out",errorCode:"timed_out",errorMessage:"The request passed its deadline.",data:{deadline_at:d.deadline_at,attempt_outcome:n.outcome},now:o}),"completed"===s.status&&eF(i.engine,n,s,o),tR.release(e,u?"cancelled":"timed_out"),{retryAt:null};if("completed"!==s.status||null===s.output){let t=function(e){var t;let n,r=e.failure?.category??"runtime_failed";if("hermes-gateway"===e.adapter)return"unavailable"===r?new eq("agent_unavailable","The agent runtime is not configured."):new eq("runtime_failed",`The agent runtime did not complete the turn (${e.failure?.code??"unknown"}).`);let i="agent-deck-api"===e.adapter?(t=e,(n=t.failure?.code)&&ex.includes(n)?n:null):null;return i?new eq("agent_unavailable",`${K[i]} [${i}]`):"unavailable"===r?new eq("agent_unavailable","The agent runtime is not available."):"cancelled"===r?new eq("runtime_failed","The agent run was cancelled."):"launch_failed"===r?new eq("runtime_failed","The agent runtime did not start the turn."):new eq("runtime_failed","The agent runtime did not complete the turn.")}(s),n=tR.control.settleFailure(a,{category:"completed"===s.status?"result_contract":s.failure?.category??"runtime_failed",code:s.failure?.code??null,errorCode:t.code,errorMessage:t.message,..."failed"===s.externalCancel?{attention:"external_cancel_failed"}:{}},o);return tR.release(e,n.outcome),{retryAt:"retry"===n.decision.action?n.decision.nextEligibleAt:null}}let l=I(t);if(l){let r=tb.commitHop(t,n,s,o);return i.engine.transitionWorkRequest(a,{from:"running",to:"completed",result:r,now:o}),tR.release(e,"completed"),tb.advance(l.exchangeId,o),{retryAt:null}}let _=(0,r.randomUUID)();return i.default.prepare("INSERT INTO messages (id, conversation_id, sender_type, sender_id, sender_kind, request_id, content, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)").run(_,t.source_conversation_id,"bot",t.target_agent_id,"bot",a,s.output,o),"edit"===t.tool_profile&&s.externalSessionId&&i.engine.bindSession({agentId:t.target_agent_id,adapter:n.adapter,externalSessionId:s.externalSessionId,conversationId:t.source_conversation_id,requestId:a,sourceAttemptId:n.id,now:o}),i.engine.transitionWorkRequest(a,{from:"running",to:"completed",result:{reply_message_id:_},now:o}),tR.release(e,"completed"),{retryAt:null}})(N,o,t,e)});d.abandoned&&await tL(d.abandoned,{localSignalled:!0,launched:!0}),d.projected?.retryAt!=null&&(t=e,n=d.projected.retryAt,(a=setTimeout(()=>{tA(t)},Math.max(0,n-tR.now()))).unref&&a.unref())}catch(e){!function(e,t,n){if(!(n instanceof eh)){if(n instanceof tv){try{tR.defer(e,n.reason,t)}catch(e){if(!(e instanceof eh))throw e}return}throw n}}(N,R,e)}},h),tw.get(e)?.attemptId===R&&tw.delete(e),!0}let tw=new Map;async function tL(e,t){var n;let r,s=e.transport?("hermes-gateway"===(n=e.transport)?eC["hermes-gateway"]():"agent-deck-api"===n?eC["agent-deck-run"]():null)?.reconciler??null:null;r="failed"===e.externalCancel?"failed":e.externalRunId?s?.cancel?await s.cancel(e.externalRunId):"unsupported":t.launched?"unsupported":"not_launched",i.engine.appendEvent(e.requestId,{type:"external_cancel",attemptId:e.attemptId,data:{status:r,reason:e.reason,external_run_id:e.externalRunId,transport:e.transport,local_signalled:t.localSignalled},now:tR.now()})}async function tO(e,t,n){let r=setInterval(()=>{try{tR.heartbeat(e);let t=i.engine.getWorkRequest(e.requestId);n&&t&&(null!==t.cancel_requested_at||d.TERMINAL_STATES.includes(t.state))&&n.abort()}catch(e){console.error("Dispatch heartbeat failed:",e)}},tR.config.heartbeatMs);r.unref&&r.unref();try{return await t()}finally{clearInterval(r)}}let tI=new Map;function tA(e){let t=tI.get(e);if(t)return t;let n=tk(e).catch(e=>{console.error("Agent dispatch failed unexpectedly:",e)}).finally(()=>{tI.get(e)===n&&tI.delete(e)});return tI.set(e,n),n}let tS=new Set,tb=function(e,t){let n=e.prepare("SELECT * FROM session_exchanges WHERE id = ?"),i=e.prepare("SELECT * FROM session_exchanges WHERE requester_kind = ? AND requester_id = ? AND idempotency_key = ?"),s=e.prepare("SELECT * FROM session_exchanges WHERE source_request_id = ? OR destination_request_id = ?"),a=e.prepare("SELECT * FROM session_bindings WHERE id = ?"),o=e.prepare("SELECT * FROM bots WHERE id = ?"),l=e.prepare(`
|
|
2084
|
+
INSERT INTO session_exchange_events (id, exchange_id, sequence, type, data, created_at)
|
|
2085
|
+
SELECT ?, ?, COALESCE(MAX(sequence), 0) + 1, ?, ?, ? FROM session_exchange_events WHERE exchange_id = ?
|
|
2086
|
+
`);function E(e){let t=n.get(e);if(!t)throw new N("exchange_not_found",`No exchange ${e}.`);return t}function p(e,t,n,i){l.run((0,r.randomUUID)(),e,t,null==n?null:JSON.stringify(n),i,e)}function m(e){return e?o.get(e)?.name??null:null}function f(e){return d.EXCHANGE_TERMINAL_STATES.includes(e)}function h(t,n,r,i={}){if(!d.EXCHANGE_TRANSITIONS[t.state].includes(n))throw new N("invalid_transition",`Cannot move an exchange from ${t.state} to ${n}.`);let s=f(n);if(1!==e.prepare(`
|
|
2087
|
+
UPDATE session_exchanges SET state = ?, version = version + 1, updated_at = ?, terminal_at = ?,
|
|
2088
|
+
failure_code = ?, failure_message = ?
|
|
2089
|
+
WHERE id = ? AND state = ? AND version = ?
|
|
2090
|
+
`).run(n,r,s?r:null,"failed"===n?i.failureCode??"failed":t.failure_code,"failed"===n?i.failureMessage??"The exchange failed.":t.failure_message,t.id,t.state,t.version).changes)throw new N("invalid_transition",`Exchange ${t.id} changed concurrently.`);return p(t.id,"state_changed",{from:t.state,to:n,reason:i.reason??null,..."failed"===n?{failure_code:i.failureCode??"failed"}:{}},r),E(t.id)}function y(t,n,r){let i=Object.keys(n);if(0===i.length)return t;if(1!==e.prepare(`UPDATE session_exchanges SET ${i.map(e=>`${e} = ?`).join(", ")}, version = version + 1, updated_at = ? WHERE id = ? AND version = ?`).run(...i.map(e=>n[e]??null),r,t.id,t.version).changes)throw new N("invalid_transition",`Exchange ${t.id} changed concurrently.`);return E(t.id)}function A(e,n,r){let i,s={kind:e.requester_kind,id:e.requester_id},a=`exchange:${e.id}:${n}`;if(r.intent.length>d.EXCHANGE_LIMITS.promptChars)throw new N("invalid_request",`The ${n} prompt exceeds ${d.EXCHANGE_LIMITS.promptChars} characters.`);return t.createOrGetWorkRequest({sourceConversationId:r.conversationId,sourceEventId:a,requester:T,targetAgentId:r.targetAgentId,intent:r.intent,executionKind:"conversation",toolProfile:"readonly",idempotencyKey:a,parentRequestId:r.parentRequestId,policy:{source:"session_exchange",exchange_id:e.id,hop:n,...r.resumeBindingId?{resume_session_binding:r.resumeBindingId}:{}},executionPolicy:function(){let e=(0,_.selectExecutionPolicy)({entryPoint:"exchange",executionKind:"conversation"});if(!e.ok)throw Error(e.reason);return e.policy}(),rootPrincipal:s,retryPolicy:{...c.DEFAULT_RETRY_POLICY},...{safetySnapshot:i={safety_version:1,root_principal:{kind:s.kind,id:s.id},grant_rule:"readonly_default",grant_id:null,exchange:!0},safety:{principalType:"service"===s.kind?"api_principal":"human_owner",principal:s,decision:"allowed",grantRule:"readonly_default",snapshot:i}},now:r.now}).request}function S(e,t){let n=o.get(e);if(!n)throw new N("agent_not_found",`No ${t} Agent ${e}.`);let r=(0,u.resolveAgent)(n);if(!r.launchable){let e="launch_profile"===r.launch_blocker?"has no launch profile chosen":"session_scope"===r.launch_blocker?"has no session scope":"direct_runtime"===r.launch_blocker?"launches directly, which is not available yet":"has no Agent Deck selected";throw new N("agent_unavailable",`The ${t} Agent ${n.name} ${e}.`)}return{id:n.id,name:n.name,agent:r.agent}}function b(t,n,r){if(!e.prepare("SELECT 1 FROM conversations WHERE id = ?").get(t)||!e.prepare("SELECT 1 FROM conversation_participants WHERE conversation_id = ? AND participant_kind = ? AND participant_id = ?").get(t,n.kind,n.id))throw new N("conversation_not_found",`No ${r} conversation ${t} is visible to the owner.`)}let q={create(n){var s;if(!n.requester||!v(n.requester.id)||!["person","bot","service"].includes(n.requester.kind))throw new N("invalid_request","A requester principal is required.");let u="service"===n.requester.kind&&!0===n.serviceGrant&&n.requester.id!==T.id;if("person"!==n.requester.kind&&!u)throw new N("recursive_exchange","Exchanges are started by the owner; an Agent or exchange hop cannot start another exchange.");if(!v(n.idempotencyKey)||n.idempotencyKey.length>200)throw new N("invalid_request","An idempotency key (1-200 characters) is required.");if(!g.includes(n.mode))throw new N("invalid_request",'mode must be "ask" or "continue".');if(!v(n.originConversationId))throw new N("invalid_request","origin_conversation_id is required.");if(!v(n.sourceAgentId))throw new N("invalid_request","source.agent_id is required.");if(!v(n.sessionRef))throw new N("invalid_request","source.session_ref is required.");if(!v(n.instruction))throw new N("invalid_request","instruction is required.");if(n.instruction.length>d.EXCHANGE_LIMITS.instructionChars)throw new N("invalid_request",`instruction exceeds ${d.EXCHANGE_LIMITS.instructionChars} characters.`);if(void 0!==n.executionKind){let e=(0,_.selectExecutionPolicy)({entryPoint:"exchange",executionKind:n.executionKind});if(!e.ok)throw new N("authority_not_allowed",`${e.reason} An exchange never requests edit authority.`)}if("ask"===n.mode&&(null!=n.destinationAgentId||null!=n.destinationConversationId))throw new N("destination_invalid","An Ask returns to the origin conversation and takes no destination.");if("continue"===n.mode){if(!v(n.destinationAgentId))throw new N("destination_invalid","A Continue names destination.agent_id.");if(n.destinationAgentId===n.sourceAgentId)throw new N("destination_invalid","A Continue hands off to another Agent; the destination cannot be the source Agent.");if(null!=n.destinationConversationId&&!v(n.destinationConversationId))throw new N("destination_invalid","destination.conversation_id must be a non-empty string when present.")}let l=(s=JSON.stringify([n.mode,n.originConversationId,n.sourceAgentId,n.sessionRef,n.destinationAgentId??null,n.destinationConversationId??null,n.instruction]),(0,r.createHash)("sha256").update(s).digest("hex"));return e.transaction(()=>{var s,u;let _=i.get(n.requester.kind,n.requester.id,n.idempotencyKey);if(_){if(_.request_hash!==l)throw new N("idempotency_conflict","The idempotency key was already used with a different exchange.");return{exchange:_,created:!1}}let c=n.now??Date.now();if(b(n.originConversationId,n.requester,"origin"),!o.get(n.sourceAgentId))throw new N("agent_not_found",`No source Agent ${n.sourceAgentId}.`);let m=a.get(n.sessionRef);if(!m||m.agent_id!==n.sourceAgentId)throw new N("session_not_found",`Session ${n.sessionRef} is not a session of Agent ${n.sourceAgentId}.`);if(null!==m.released_at)throw new N("session_ended",`Session ${m.id} has ended and cannot be resumed.`);let f=S(n.sourceAgentId,"source");if(m.adapter!==f.agent)throw new N("session_not_resumable",`Session ${m.id} was bound under ${m.adapter}; ${f.name} now runs ${f.agent}.`);let T=m.conversation_id?m.conversation_id:m.request_id?t.getWorkRequest(m.request_id)?.source_conversation_id??null:null;if(!T)throw new N("session_not_resumable",`Session ${m.id} has no conversation to resume in.`);if(e.prepare("SELECT 1 FROM session_exchanges WHERE source_binding_id = ? AND terminal_at IS NULL").get(m.id))throw new N("source_session_busy",`Session ${m.id} already has an exchange in progress; wait for it or cancel it.`);let g=null,h=null;if("continue"===n.mode)if(g=S(n.destinationAgentId,"destination"),n.destinationConversationId)b(n.destinationConversationId,n.requester,"destination"),h=n.destinationConversationId;else if("service"===n.requester.kind)throw new N("destination_invalid","A service-started Continue names destination.conversation_id.");else{let t=e.prepare("SELECT id FROM conversations WHERE bot_id = ?").get(g.id);if(!t)throw new N("destination_invalid",`${g.name} has no direct thread; name destination.conversation_id.`);h=t.id}let R=(0,r.randomUUID)();e.prepare(`
|
|
2091
|
+
INSERT INTO session_exchanges (
|
|
2092
|
+
id, requester_kind, requester_id, idempotency_key, request_hash, mode, origin_conversation_id,
|
|
2093
|
+
source_agent_id, source_binding_id, destination_agent_id, destination_conversation_id, instruction,
|
|
2094
|
+
state, created_at, updated_at
|
|
2095
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'queued', ?, ?)
|
|
2096
|
+
`).run(R,n.requester.kind,n.requester.id,n.idempotencyKey,l,n.mode,n.originConversationId,n.sourceAgentId,m.id,g?.id??null,h,n.instruction,c,c),p(R,"created",{mode:n.mode,source_agent_id:n.sourceAgentId,source_binding_id:m.id,destination_agent_id:g?.id??null,destination_conversation_id:h},c);let v=E(R),k="ask"===n.mode?"ask":"extract",w=A(v,k,{conversationId:T,targetAgentId:n.sourceAgentId,intent:"ask"===k?function(e,t,n="the owner"){return`[Session Ask from ${n}] Exchange: ${e}
|
|
2097
|
+
|
|
2098
|
+
Answer one question from the context of this session. ${L} Reply with the answer only.
|
|
2099
|
+
|
|
2100
|
+
Question:
|
|
2101
|
+
${t}`}(R,n.instruction,"service"===v.requester_kind?`service ${v.requester_id}`:"the owner"):(s=g?.name??"another Agent",u=n.instruction,`[Session Continue handoff from the owner] Exchange: ${R}
|
|
2102
|
+
|
|
2103
|
+
The owner is handing this session's work to ${s}, who starts a fresh session and cannot see this one. ${L}
|
|
2104
|
+
|
|
2105
|
+
Reply with exactly one JSON object and nothing else:
|
|
2106
|
+
|
|
2107
|
+
{"objective": string, "decisions": [string], "constraints": [string], "artifacts": [string], "open_questions": [string]}
|
|
2108
|
+
|
|
2109
|
+
objective: what ${s} should achieve. decisions: what was decided and why. constraints: requirements and limits to respect. artifacts: files, branches, Work Requests, and other references. open_questions: what is still unresolved.
|
|
2110
|
+
|
|
2111
|
+
Limits: objective at most ${d.EXCHANGE_LIMITS.packetObjectiveChars} characters; each list at most ${d.EXCHANGE_LIMITS.packetListItems} entries of at most ${d.EXCHANGE_LIMITS.packetItemChars} characters.
|
|
2112
|
+
|
|
2113
|
+
Owner instruction:
|
|
2114
|
+
${u}`),parentRequestId:m.request_id,resumeBindingId:m.id,now:c}),O=y(v,{source_request_id:w.id},c);return p(R,"hop_queued",{hop:k,request_id:w.id},c),{exchange:O,created:!0}}).immediate()},get:e=>n.get(e),require:E,listEvents:t=>e.prepare("SELECT * FROM session_exchange_events WHERE exchange_id = ? ORDER BY sequence ASC").all(t),forHopRequest:e=>s.get(e,e),resumeFor(e,t){let n=I(e);if(!n)return null;if("deliver"===n.hop)return{ok:!0,binding:null,freshSession:!0};let r=q.get(n.exchangeId),i=n.resumeBindingId?a.get(n.resumeBindingId):void 0;return r&&i&&r.source_binding_id===i.id&&r.source_request_id===e.id?null!==i.released_at?{ok:!1,reason:"The selected session has ended."}:i.agent_id!==e.target_agent_id||i.adapter!==t?{ok:!1,reason:"The selected session belongs to another Agent or runtime."}:{ok:!0,binding:i}:{ok:!1,reason:"The exchange does not name this session."}},turnContext:e=>I(e)?[{speakerLabel:"Botmancers",fromAgent:!1,content:e.intent}]:null,hopClaimed(e,t,n){let r=q.forHopRequest(e);if(!(!r||f(r.state))){if(r.source_request_id===e){let i=r.source_attempt_id?r:y(r,{source_attempt_id:t},n);"queued"===i.state&&h(i,"extracting",n,{reason:"hop_started"}),p(r.id,"hop_started",{hop:"ask"===r.mode?"ask":"extract",request_id:e,attempt_id:t},n);return}r.destination_attempt_id||y(r,{destination_attempt_id:t},n),p(r.id,"hop_started",{hop:"deliver",request_id:e,attempt_id:t},n)}},sanitizeHopResult(e,t){let n=I(e),r=n?q.get(n.exchangeId):void 0;if(!n||!r)return t;let i=a.get(r.source_binding_id)?.external_session_id??null,s="ask"===n.hop?d.EXCHANGE_LIMITS.answerChars:"extract"===n.hop?d.EXCHANGE_LIMITS.extractionOutputChars:d.EXCHANGE_LIMITS.replyChars,o=t.externalSessionId??null,u=null===t.output?null:w(k(t.output,i,o),s);return{...t,output:u?u.content:null,outputTruncated:!0===t.outputTruncated||u?.truncated===!0,failure:t.failure?{...t.failure,message:k(t.failure.message,i,o)}:null}},commitHop(n,i,s,o){let u=I(n),l=u?q.get(u.exchangeId):void 0;if(!u||!l)return{exchange_id:u?.exchangeId??null,discarded:"exchange_missing"};if(f(l.state)||null!==l.cancel_requested_at)return p(l.id,"hop_result_discarded",{hop:u.hop,request_id:n.id,reason:f(l.state)?l.state:"cancel_requested"},o),{exchange_id:l.id,discarded:"cancel_requested"};let _=s.output??"",c=a.get(l.source_binding_id)?.external_session_id??null;if("ask"===u.hop){let t=w(k(_,c),d.EXCHANGE_LIMITS.answerChars),{content:a}=t,u=t.truncated||!0===s.outputTruncated,E=(0,r.randomUUID)();return e.prepare("INSERT INTO messages (id, conversation_id, sender_type, sender_id, sender_kind, request_id, content, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)").run(E,l.origin_conversation_id,"bot",l.source_agent_id,"bot",n.id,a,o),y(l,{answer_message_id:E},o),p(l.id,"answer_returned",{request_id:n.id,attempt_id:i.id,message_id:E,conversation_id:l.origin_conversation_id,truncated:u},o),{exchange_id:l.id,answer_message_id:E}}if("extract"===u.hop){var E;let e=s.outputTruncated?{ok:!1,reason:`The extraction output exceeds ${d.EXCHANGE_LIMITS.extractionOutputChars} characters.`}:function(e){let t;if(e.length>d.EXCHANGE_LIMITS.extractionOutputChars)return{ok:!1,reason:`The extraction output exceeds ${d.EXCHANGE_LIMITS.extractionOutputChars} characters.`};let n=/```(?:json)?\s*([\s\S]*?)```/.exec(e),r=(n?n[1]:e).trim(),i=r.indexOf("{"),s=r.lastIndexOf("}");if(i<0||s<i)return{ok:!1,reason:"The handoff packet is not a JSON object."};try{t=JSON.parse(r.slice(i,s+1))}catch{return{ok:!1,reason:"The handoff packet is not valid JSON."}}if(!t||"object"!=typeof t||Array.isArray(t))return{ok:!1,reason:"The handoff packet is not a JSON object."};let a=t;if(!v(a.objective))return{ok:!1,reason:"The handoff packet has no objective."};if(a.objective.length>d.EXCHANGE_LIMITS.packetObjectiveChars)return{ok:!1,reason:`The handoff packet objective exceeds ${d.EXCHANGE_LIMITS.packetObjectiveChars} characters.`};let o={objective:a.objective.trim(),decisions:[],constraints:[],artifacts:[],open_questions:[]};for(let e of R){let t=a[e]??[];if(!Array.isArray(t)||t.some(e=>"string"!=typeof e))return{ok:!1,reason:`The handoff packet field ${e} must be a list of strings.`};if(t.length>d.EXCHANGE_LIMITS.packetListItems)return{ok:!1,reason:`The handoff packet field ${e} has ${t.length} entries (limit ${d.EXCHANGE_LIMITS.packetListItems}).`};if(t.some(e=>e.length>d.EXCHANGE_LIMITS.packetItemChars))return{ok:!1,reason:`An entry of the handoff packet field ${e} exceeds ${d.EXCHANGE_LIMITS.packetItemChars} characters.`};o[e]=t.map(e=>e.trim()).filter(e=>e.length>0)}return JSON.stringify(o).length>d.EXCHANGE_LIMITS.packetChars?{ok:!1,reason:`The handoff packet exceeds ${d.EXCHANGE_LIMITS.packetChars} characters.`}:{ok:!0,packet:o}}(_);if(!e.ok)return p(l.id,"packet_rejected",{request_id:n.id,attempt_id:i.id,reason:e.reason},o),h(l,"failed",o,{reason:"packet_invalid",failureCode:"packet_invalid",failureMessage:e.reason}),{exchange_id:l.id,packet:"rejected"};let t=(E=e.packet,{objective:k(E.objective,c),decisions:E.decisions.map(e=>k(e,c)),constraints:E.constraints.map(e=>k(e,c)),artifacts:E.artifacts.map(e=>k(e,c)),open_questions:E.open_questions.map(e=>k(e,c))});return y(l,{packet:JSON.stringify(t)},o),p(l.id,"packet_extracted",{request_id:n.id,attempt_id:i.id,size:JSON.stringify(t).length,counts:Object.fromEntries(R.map(e=>[e,t[e].length]))},o),{exchange_id:l.id,packet:"stored"}}let m=s.externalSessionId??null,T=!1;try{T=!0===JSON.parse(i.launch_snapshot).fresh_session}catch{T=!1}if(!(T&&m&&m!==c&&!e.prepare("SELECT 1 FROM session_bindings WHERE external_session_id = ?").get(m)&&!e.prepare("SELECT 1 FROM work_attempts WHERE external_session_id = ? AND id != ?").get(m,i.id))){let e=T?m?"reused":"not_reported":"not_fresh_launch";return p(l.id,"destination_session_rejected",{request_id:n.id,attempt_id:i.id,reason:e},o),h(l,"failed",o,{reason:"destination_session_invalid",failureCode:"destination_session_invalid",failureMessage:m?"The destination Agent reported a session that is not new; the hand-off needs a fresh destination-owned session.":"The destination Agent reported no session; the hand-off needs a fresh destination-owned session."}),{exchange_id:l.id,destination_session:"rejected"}}let g=(0,r.randomUUID)(),N=l.destination_conversation_id,L=w(k(_,c,m),d.EXCHANGE_LIMITS.replyChars),{content:O}=L,A=L.truncated||!0===s.outputTruncated;e.prepare("INSERT INTO messages (id, conversation_id, sender_type, sender_id, sender_kind, request_id, content, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)").run(g,N,"bot",n.target_agent_id,"bot",n.id,O,o);let S=t.bindSession({agentId:n.target_agent_id,adapter:i.adapter,externalSessionId:m,conversationId:N,requestId:n.id,sourceAttemptId:i.id,now:o}).id;return y(l,{destination_binding_id:S},o),p(l.id,"destination_replied",{request_id:n.id,attempt_id:i.id,message_id:g,conversation_id:N,session_ref:S,truncated:A},o),{exchange_id:l.id,destination_message_id:g}},advance:(n,r=Date.now())=>e.transaction(()=>{let i=q.get(n);if(!i||f(i.state))return[];if("queued"===i.state||"extracting"===i.state){var s,a,o,u;let n=i.source_request_id?t.getWorkRequest(i.source_request_id):void 0;if(!n)return h(i,"failed",r,{reason:"hop_missing",failureCode:"hop_missing",failureMessage:"The source session turn is missing."}),[];if(!d.TERMINAL_STATES.includes(n.state))return"queued"!==n.state&&"queued"===i.state&&h(i,"extracting",r,{reason:"hop_started"}),"queued"===n.state&&null===i.cancel_requested_at?[n.id]:[];if(null!==i.cancel_requested_at||"cancelled"===n.state)return h(i,"cancelled",r,{reason:null!==i.cancel_requested_at?"cancel_requested":"hop_cancelled"}),[];if("failed"===n.state)return h(i,"failed",r,{reason:"hop_failed",failureCode:"source_turn_failed",failureMessage:`The source session turn failed (${n.error_code??"failed"}): ${n.error_message??"no detail"}`}),[];if("queued"===i.state&&(i=h(i,"extracting",r,{reason:"hop_started"})),"ask"===i.mode)return i.answer_message_id?h(i,"completed",r,{reason:"answered"}):h(i,"failed",r,{reason:"answer_missing",failureCode:"answer_missing",failureMessage:"The source session turn returned no answer."}),[];if(!i.packet)return h(i,"failed",r,{reason:"packet_missing",failureCode:"packet_missing",failureMessage:"The source session turn returned no handoff packet."}),[];let l=JSON.parse(i.packet),_=i.destination_conversation_id,c=i.destination_agent_id;s={kind:"bot",id:c},e.prepare("INSERT OR IGNORE INTO conversation_participants (conversation_id, participant_kind, participant_id, joined_at) VALUES (?, ?, ?, ?)").run(_,s.kind,s.id,r);let E=A(i,"deliver",{conversationId:_,targetAgentId:c,intent:(a=i.id,o=m(i.source_agent_id)??"the source Agent",u=i.instruction,[`Continue from ${o}: ${function(e,t=80){let n=e.split("\n").map(e=>e.trim()).find(e=>e.length>0)??"";return n.length>t?`${n.slice(0,t-1).trimEnd()}…`:n}(l.objective)}`,`[Session Continue] Exchange: ${a}`,`The owner handed you this work from ${o}'s session. You start a fresh session of your own: ${o}'s session is not available to you, and this handoff packet is everything carried over.`,`Objective:
|
|
2115
|
+
${l.objective}`,O("Decisions",l.decisions),O("Constraints",l.constraints),O("Artifacts and references",l.artifacts),O("Open questions",l.open_questions),`Owner instruction:
|
|
2116
|
+
${u}`].join("\n\n")),parentRequestId:null,resumeBindingId:null,now:r});return p((i=y(i,{destination_request_id:E.id},r)).id,"hop_queued",{hop:"deliver",request_id:E.id},r),h(i,"delivering",r,{reason:"packet_extracted"}),[E.id]}let l=i.destination_request_id?t.getWorkRequest(i.destination_request_id):void 0;return l?d.TERMINAL_STATES.includes(l.state)?(null!==i.cancel_requested_at||"cancelled"===l.state?h(i,"cancelled",r,{reason:null!==i.cancel_requested_at?"cancel_requested":"hop_cancelled"}):"failed"===l.state?h(i,"failed",r,{reason:"hop_failed",failureCode:"destination_turn_failed",failureMessage:`The destination turn failed (${l.error_code??"failed"}): ${l.error_message??"no detail"}`}):i.destination_binding_id?h(i,"completed",r,{reason:"delivered"}):h(i,"failed",r,{reason:"destination_session_missing",failureCode:"destination_session_invalid",failureMessage:"The destination turn bound no fresh destination-owned session."}),[]):"queued"===l.state&&null===i.cancel_requested_at?[l.id]:[]:(h(i,"failed",r,{reason:"hop_missing",failureCode:"hop_missing",failureMessage:"The destination turn is missing."}),[])}).immediate(),requestCancel:(t,n,r,i=Date.now())=>e.transaction(()=>{let s=E(t);if(f(s.state))throw new N("exchange_terminal",`Exchange ${t} is already ${s.state}; it cannot be cancelled.`);let a="delivering"===s.state?s.destination_request_id:s.source_request_id;return null!==s.cancel_requested_at?{exchange:s,hopRequestId:a,replayed:!0}:(e.prepare("UPDATE session_exchanges SET cancel_requested_at = ?, cancel_requested_by = ?, cancel_reason = ?, version = version + 1, updated_at = ? WHERE id = ? AND cancel_requested_at IS NULL").run(i,`${n.kind}:${n.id}`,r,i,t),p(t,"cancel_requested",{by:`${n.kind}:${n.id}`,reason:r,state:s.state,request_id:a},i),{exchange:E(t),hopRequestId:a,replayed:!1})}).immediate(),openIds:()=>e.prepare("SELECT id FROM session_exchanges WHERE terminal_at IS NULL ORDER BY created_at ASC, id ASC").all().map(e=>e.id),view(n){let r=E(n),i=(e,n)=>{let r=e?t.getWorkRequest(e):void 0;return r?{request_id:r.id,attempt_id:n,state:r.state,execution_kind:r.execution_kind,tool_profile:r.tool_profile}:null},s=r.answer_message_id?e.prepare("SELECT id, conversation_id, content FROM messages WHERE id = ?").get(r.answer_message_id):void 0;return{id:r.id,mode:r.mode,state:r.state,requester:{kind:r.requester_kind,id:r.requester_id},origin_conversation_id:r.origin_conversation_id,instruction:r.instruction,source:{agent_id:r.source_agent_id,agent_name:m(r.source_agent_id),session_ref:r.source_binding_id},destination:r.destination_agent_id&&r.destination_conversation_id?{agent_id:r.destination_agent_id,agent_name:m(r.destination_agent_id),conversation_id:r.destination_conversation_id,session_ref:r.destination_binding_id}:null,hops:{source:i(r.source_request_id,r.source_attempt_id),destination:i(r.destination_request_id,r.destination_attempt_id)},answer:s?{message_id:s.id,conversation_id:s.conversation_id,content:s.content}:null,packet:r.packet?JSON.parse(r.packet):null,failure:"failed"===r.state?{code:r.failure_code??"failed",message:r.failure_message??""}:null,cancel:null!==r.cancel_requested_at?{requested_at:r.cancel_requested_at,reason:r.cancel_reason}:null,events:q.listEvents(r.id).map(e=>({sequence:e.sequence,type:e.type,at:e.created_at,data:e.data?JSON.parse(e.data):null})),limits:d.EXCHANGE_LIMITS,created_at:r.created_at,updated_at:r.updated_at,terminal_at:r.terminal_at}}};return q}(i.default,i.engine),tq={session_missing:"choose_session",session_ended:"choose_session",session_not_resumable:"choose_session",source_session_busy:"retry_later",action_unavailable:"choose_action",authority_not_allowed:"ask_owner",workspace_required:"ask_owner",no_eligible_session:"ask_owner",grant_required:"ask_owner",agent_unavailable:"ask_owner",approval_required:"approve_write",pin_not_found:"pin_again",pin_detached:"pin_again",provider_failed:"retry_later",rate_limited:"retry_later",session_context_required:"choose_session"},tC={invalid_request:400,agent_not_found:404,session_not_found:404,conversation_not_found:404,pin_not_found:404,pin_detached:409,workspace_required:409,no_eligible_session:409,session_missing:410,session_ended:409,session_not_resumable:409,source_session_busy:409,action_unavailable:409,approval_required:403,authority_not_allowed:403,agent_unavailable:409,grant_required:403,provider_failed:502,idempotency_conflict:409};class tx extends Error{code;recovery;constructor(e,t){super(t),this.name="PinError",this.code=e,this.recovery=function(e){return Object.prototype.hasOwnProperty.call(tq,e)?tq[e]:null}(e)}get status(){return tC[this.code]}}function tD(e){return"string"==typeof e&&e.trim().length>0}function tU(e,t,n,s){i.default.prepare(`
|
|
2117
|
+
INSERT INTO session_pin_events (id, pin_id, sequence, type, data, created_at)
|
|
2118
|
+
SELECT ?, ?, COALESCE(MAX(sequence), 0) + 1, ?, ?, ? FROM session_pin_events WHERE pin_id = ?
|
|
2119
|
+
`).run((0,r.randomUUID)(),e,t,JSON.stringify(n),s,e)}function tF(e){return i.default.prepare("SELECT * FROM session_pins WHERE id = ?").get(e)}function tW(e,t){return i.default.prepare("SELECT * FROM session_pin_turns WHERE requester_kind = ? AND requester_id = ? AND idempotency_key = ?").get(e.kind,e.id,t)}function tM(e,t){let n="string"==typeof t&&t.length<=200?tF(t):void 0;if(!n||n.requester_kind!==e.kind||n.requester_id!==e.id)throw new tx("pin_not_found","No pin with that reference is visible to this requester.");return n}function tH(e,t,n,s){let a=(0,r.randomUUID)();return i.default.prepare("INSERT INTO messages (id, conversation_id, sender_type, sender_id, sender_kind, request_id, content, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)").run(a,e,t.type,t.id,t.kind,null,n,s),a}function tX(e){if(e.provider_turn_ref){let t=tF(e.pin_id),n=(0,l.getProviderTurn)(i.default,t.agent_id,e.provider_turn_ref);return n?{state:n.state,answer:"completed"===n.state?n.output:null,failure:"failed"===n.state||"cancelled"===n.state?{code:n.failure_code??n.state}:null,finished_at:n.finished_at}:{state:"failed",answer:null,failure:{code:"turn_missing"},finished_at:null}}let t=tb.get(e.exchange_id);if(!t)return{state:"failed",answer:null,failure:{code:"turn_missing"},finished_at:null};let n="completed"===t.state?"completed":"failed"===t.state?"failed":"cancelled"===t.state?"cancelled":"running",r=t.answer_message_id?i.default.prepare("SELECT content FROM messages WHERE id = ?").get(t.answer_message_id)?.content??null:null;return{state:n,answer:"completed"===n?r:null,failure:"failed"===n?{code:t.failure_code??"failed"}:"cancelled"===n?{code:"cancelled"}:null,finished_at:t.terminal_at}}function tG(e,t){let n=tX(t);return{turn_ref:t.id,seq:t.seq,state:n.state,authority:e.authority,content:t.content,answer:n.answer,failure:n.failure,exchange_id:t.exchange_id,created_at:t.created_at,finished_at:n.finished_at}}function t$(e,t,n){let r=t;try{if(t instanceof tx)throw t;if(t instanceof l.ProviderSessionError)throw function(e){switch(e.code){case"agent_not_found":return new tx("agent_not_found","No such Agent.");case"session_not_found":return new tx("session_not_found","No session with that reference.");case"session_missing":return new tx("session_missing","The runtime no longer has this session. The pin stays on it; detach it or switch to another session.");case"not_resumable":return new tx("session_not_resumable","The runtime cannot resume this session now. The pin stays on it; detach it or switch to another session.");case"out_of_scope":return new tx("session_not_resumable","The session is outside the Agent’s session scope.");case"busy":return new tx("source_session_busy","A turn is already running in this session; wait for it, then send again.");case"authority_not_allowed":return new tx("authority_not_allowed",`The Agent’s policy or runtime refused this authority: ${e.message}`);case"new_sessions_not_allowed":return new tx("no_eligible_session","The Agent’s policy does not allow new sessions.");case"unsupported":return new tx("action_unavailable","The Agent’s runtime does not support this action.");case"scope_missing":return new tx("agent_unavailable","The Agent has no session scope; the owner must choose one.");case"provider_unavailable":return new tx("agent_unavailable","The Agent’s runtime connection is not available.");case"idempotency_conflict":return new tx("idempotency_conflict","That idempotency key was used for a different turn.");case"invalid_input":return new tx("invalid_request",e.message);default:return new tx("provider_failed","The runtime failed this turn. The pin stays on the same session; retry later.")}}(t);if(t instanceof N)throw function(e){switch(e.code){case"session_not_found":return new tx("session_not_found","No session with that reference.");case"agent_not_found":return new tx("agent_not_found","No such Agent.");case"conversation_not_found":return new tx("conversation_not_found","No conversation with that id is visible.");case"session_ended":return new tx("session_ended","This session has ended. The pin stays on it; detach it or switch to another session.");case"session_not_resumable":return new tx("session_not_resumable","Botmancers cannot resume this session under the Agent’s current runtime.");case"source_session_busy":return new tx("source_session_busy","This session already has a turn in progress; wait for it, then send again.");case"agent_unavailable":return new tx("agent_unavailable",e.message);case"idempotency_conflict":return new tx("idempotency_conflict","That idempotency key was used for a different turn.");default:return new tx("invalid_request",e.message)}}(t);throw t}catch(e){r=e}if(r instanceof tx){let t=r.code;i.default.transaction(()=>tU(e.id,"turn_refused",{code:t,session_ref:e.session_ref},n)).immediate()}throw r}function tB(e,t){return`pin-${(0,r.createHash)("sha256").update(`${e}
|
|
2120
|
+
${t}`).digest("hex").slice(0,40)}`}function tK(e,t,n,s,a,o,d){var u;let l=(0,r.randomUUID)(),_=o.exchangeId?null:tH(e.conversation_id,{type:"user",id:t.id,kind:t.kind},a,d);return i.default.prepare(`
|
|
2121
|
+
INSERT INTO session_pin_turns (
|
|
2122
|
+
id, pin_id, seq, requester_kind, requester_id, idempotency_key, request_hash, content, exchange_id, provider_turn_ref,
|
|
2123
|
+
question_message_id, answer_message_id, created_at
|
|
2124
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?)
|
|
2125
|
+
`).run(l,e.id,(u=e.id,(i.default.prepare("SELECT MAX(seq) AS n FROM session_pin_turns WHERE pin_id = ?").get(u).n??0)+1),t.kind,t.id,n,s,a,o.exchangeId??null,o.providerTurnRef??null,_,d),i.default.prepare("UPDATE session_pins SET updated_at = ? WHERE id = ?").run(d,e.id),tU(e.id,"turn_sent",{turn_ref:l,session_ref:e.session_ref,authority:e.authority,route:e.route},d),i.default.prepare("SELECT * FROM session_pin_turns WHERE id = ?").get(l)}function tP(e){i.default.transaction(()=>{let t=i.default.prepare("SELECT * FROM session_pin_turns WHERE id = ?").get(e);if(!t||!t.provider_turn_ref||t.answer_message_id)return;let n=tF(t.pin_id),r=(0,l.getProviderTurn)(i.default,n.agent_id,t.provider_turn_ref);if(r&&"running"!==r.state&&"completed"===r.state&&null!==r.output){let e=Date.now(),s=tH(n.conversation_id,{type:"bot",id:n.agent_id,kind:"bot"},r.output,e);i.default.prepare("UPDATE session_pin_turns SET answer_message_id = ? WHERE id = ? AND answer_message_id IS NULL").run(s,t.id),tU(n.id,"turn_answered",{turn_ref:t.id},e)}}).immediate()}async function tj(e,t,n){if(t.provider_turn_ref)try{let r=await (0,l.observeProviderTurn)(i.default,e.agent_id,t.provider_turn_ref,null===n?{}:{deadlineAt:Date.now()+n});"running"!==r.state&&tP(t.id)}catch(e){console.error("Pin turn observe failed:",e instanceof Error?e.message:"unknown error")}}async function tY(e,t,n,s,a,o,d){var u;let _;if("provider"===e.route){let r;try{r=await (0,l.sendProviderTurn)(i.default,e.agent_id,e.session_ref,{prompt:a,authority:e.authority,idempotencyKey:tB(e.id,n),requester:t})}catch(t){t$(e,t,o)}let u=i.default.transaction(()=>{let i=tW(t,n);if(i)return i;let u=tK(e,t,n,s,a,{providerTurnRef:r.turn.turn_ref},o);return d?.(e,u),u}).immediate();return{pin:tF(e.id),turn:tG(e,u),replayed:!1,settled:tj(e,u,null)}}try{_=i.default.transaction(()=>{let u=tW(t,n);if(u)return u;let{exchange:l}=tb.create({requester:t,serviceGrant:"service"===t.kind,idempotencyKey:tB(e.id,n),mode:"ask",originConversationId:e.conversation_id,sourceAgentId:e.agent_id,sessionRef:e.session_ref,instruction:a,now:o});i.default.prepare("INSERT INTO messages (id, conversation_id, sender_type, sender_id, sender_kind, request_id, content, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?)").run((0,r.randomUUID)(),e.conversation_id,"user",t.id,t.kind,l.source_request_id,a,o);let _=tK(e,t,n,s,a,{exchangeId:l.id},o);return d?.(e,_),_}).immediate()}catch(t){t$(e,t,o)}return{pin:tF(e.id),turn:tG(e,_),replayed:!1,settled:(u=_.exchange_id,Promise.all(tb.advance(u).map(tA)).then(()=>void 0))}}async function tz(e){var t;let n=`turn:${function(e){if(!tD(e)||e.length>200)throw new tx("invalid_request","An idempotency key (1-200 characters) is required.");return e}(e.idempotencyKey)}`,i=function(e){if(!tD(e))throw new tx("invalid_request","content is required.");if(e.length>d.EXCHANGE_LIMITS.instructionChars)throw new tx("invalid_request",`content exceeds ${d.EXCHANGE_LIMITS.instructionChars} characters.`);return e}(e.content),s=tM(e.requester,e.pinRef),a=(t=["turn",s.id,i],(0,r.createHash)("sha256").update(JSON.stringify(t)).digest("hex")),o=tW(e.requester,n);if(o){if(o.request_hash!==a)throw new tx("idempotency_conflict","That idempotency key was used for a different turn.");return{pin:s,turn:tG(s,o),replayed:!0,settled:Promise.resolve()}}if("attached"!==s.state)throw new tx("pin_detached",`This pin was ${"switched"===s.detach_reason?"switched to another pin":"detached"}; it no longer sends. Pin a session again.`);return tY(s,e.requester,n,a,i,e.now??Date.now(),e.onCommit)}async function tJ(e,t){let n=tM(e,t),r=i.default.prepare("SELECT * FROM session_pin_turns WHERE pin_id = ? ORDER BY seq DESC LIMIT ?").all(n.id,20).reverse();for(let e of r)e.provider_turn_ref&&!e.answer_message_id&&("running"===tX(e).state?await tj(n,e,25):tP(e.id));return{pin:n,turns:r.map(e=>tG(n,i.default.prepare("SELECT * FROM session_pin_turns WHERE id = ?").get(e.id)))}}let tV=Object.freeze({kind:"service",id:"botmancers-session-share"}),tQ=Object.freeze({ttl:Object.freeze({min:300,default:3600,max:86400}),turns:Object.freeze({min:1,default:20,max:100}),questionChars:4e3,replyChars:3e3}),tZ={invalid_request:400,session_not_found:404,share_not_found:404,share_expired:410,share_revoked:410,share_turn_in_progress:409,share_turn_limit:409,audience_not_allowed:403,idempotency_conflict:409};class t0 extends Error{code;constructor(e,t){super(t),this.name="ShareError",this.code=e}get status(){return tZ[this.code]}}i.default.exec(`
|
|
2126
|
+
CREATE TABLE IF NOT EXISTS session_shares (
|
|
2127
|
+
id TEXT PRIMARY KEY CHECK (id LIKE 'shr_%'),
|
|
2128
|
+
creator_kind TEXT NOT NULL,
|
|
2129
|
+
creator_id TEXT NOT NULL,
|
|
2130
|
+
idempotency_key TEXT NOT NULL,
|
|
2131
|
+
request_hash TEXT NOT NULL,
|
|
2132
|
+
agent_id TEXT NOT NULL,
|
|
2133
|
+
session_ref TEXT NOT NULL,
|
|
2134
|
+
pin_ref TEXT NOT NULL UNIQUE,
|
|
2135
|
+
authority TEXT NOT NULL CHECK (authority = 'ask'),
|
|
2136
|
+
audience_kind TEXT NOT NULL CHECK (audience_kind = 'slack'),
|
|
2137
|
+
audience_team_id TEXT NOT NULL,
|
|
2138
|
+
audience_channel_id TEXT NOT NULL,
|
|
2139
|
+
created_via TEXT NOT NULL CHECK (created_via IN ('session_ref', 'current_session')),
|
|
2140
|
+
ttl_seconds INTEGER NOT NULL CHECK (ttl_seconds BETWEEN 300 AND 86400),
|
|
2141
|
+
max_turns INTEGER NOT NULL CHECK (max_turns BETWEEN 1 AND 100),
|
|
2142
|
+
turns_used INTEGER NOT NULL DEFAULT 0 CHECK (turns_used >= 0 AND turns_used <= max_turns),
|
|
2143
|
+
state TEXT NOT NULL CHECK (state IN ('active', 'revoked')),
|
|
2144
|
+
inflight_key TEXT,
|
|
2145
|
+
inflight_owner TEXT,
|
|
2146
|
+
inflight_turn_ref TEXT,
|
|
2147
|
+
created_at INTEGER NOT NULL,
|
|
2148
|
+
expires_at INTEGER NOT NULL,
|
|
2149
|
+
revoked_at INTEGER,
|
|
2150
|
+
updated_at INTEGER NOT NULL,
|
|
2151
|
+
UNIQUE (creator_kind, creator_id, idempotency_key)
|
|
2152
|
+
);
|
|
2153
|
+
CREATE INDEX IF NOT EXISTS idx_session_shares_creator ON session_shares(creator_kind, creator_id, created_at);
|
|
2154
|
+
CREATE TABLE IF NOT EXISTS session_share_events (
|
|
2155
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
2156
|
+
share_ref TEXT NOT NULL REFERENCES session_shares(id),
|
|
2157
|
+
sequence INTEGER NOT NULL,
|
|
2158
|
+
type TEXT NOT NULL CHECK (type IN ('created', 'revoked', 'turn_sent', 'turn_refused')),
|
|
2159
|
+
turn_ref TEXT,
|
|
2160
|
+
code TEXT,
|
|
2161
|
+
at INTEGER NOT NULL,
|
|
2162
|
+
UNIQUE (share_ref, sequence)
|
|
2163
|
+
);
|
|
2164
|
+
-- Idempotent turn accounting: a turn is counted once, whatever replays it.
|
|
2165
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_session_share_turn_sent ON session_share_events(share_ref, turn_ref) WHERE type = 'turn_sent';
|
|
2166
|
+
CREATE TRIGGER IF NOT EXISTS trg_session_share_events_no_update BEFORE UPDATE ON session_share_events
|
|
2167
|
+
BEGIN
|
|
2168
|
+
SELECT RAISE(ABORT, 'session_share_events are append-only');
|
|
2169
|
+
END;
|
|
2170
|
+
CREATE TRIGGER IF NOT EXISTS trg_session_share_events_no_delete BEFORE DELETE ON session_share_events
|
|
2171
|
+
BEGIN
|
|
2172
|
+
SELECT RAISE(ABORT, 'session_share_events are append-only');
|
|
2173
|
+
END;
|
|
2174
|
+
`);let t1=(0,r.randomBytes)(9).toString("base64url"),t4=new Set,t2=/^T[A-Z0-9]{2,20}$/,t3=/^[CG][A-Z0-9]{2,20}$/,t6=/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/;class t9 extends Error{constructor(e){super(e),this.name="SessionSharesConfigError"}}function t5(e){return!!e&&"object"==typeof e&&!Array.isArray(e)}function t8(e,t,n){let r=Object.keys(e).find(e=>!t.includes(e));if(void 0!==r)throw new t9(`${n} has an unknown field "${r}".`)}let t7=null;function ne(e=process.env){let a,o=function(e=process.env){let t=(e.BOTMANCERS_SESSION_SHARES_PATH||"").trim();if(t)return n.default.resolve(t);let r=(0,s.botmancersHome)(e);return r?n.default.join(r,"config/session-shares.json"):null}(e);if(!o)return{state:"absent",path:null};try{a=t.default.statSync(o)}catch(e){if("ENOENT"===e.code)return{state:"absent",path:o};return{state:"invalid",path:o,reason:"The document cannot be read."}}let d=new Set(i.default.prepare("SELECT id FROM bots").all().map(e=>e.id)),u=(0,r.createHash)("sha256").update([...d].sort().join("\n"),"utf8").digest("hex"),l=[o,a.ino,a.size,a.mode,a.uid,a.mtimeMs,u].join(":");if(t7&&t7.key===l)return t7.state;let _=function(e,n,r){let i;if(!n.isFile())return{state:"invalid",path:e,reason:"The document is not a regular file."};if("function"==typeof process.getuid&&n.uid!==process.getuid())return{state:"invalid",path:e,reason:"The document must be owned by the user running Botmancers."};if((63&n.mode)!=0)return{state:"invalid",path:e,reason:"The document must not be readable or writable by group or others (chmod 600)."};if(n.size>65536)return{state:"invalid",path:e,reason:"The document exceeds 65536 bytes."};try{i=t.default.readFileSync(e,"utf8")}catch{return{state:"invalid",path:e,reason:"The document cannot be read."}}try{return{state:"loaded",path:e,config:function(e,t){let n;try{n=JSON.parse(e)}catch{throw new t9("The document is not valid JSON.")}if(!t5(n))throw new t9("The document must be a JSON object.");if(t8(n,["version","audiences","agents"],"The document"),1!==n.version)throw new t9("version must be 1.");let r=n.audiences??[],i=n.agents??[];if(!Array.isArray(r))throw new t9("audiences must be a list.");if(!Array.isArray(i))throw new t9("agents must be a list.");if(r.length>512||i.length>512)throw new t9("A list has more than 512 entries.");let s=new Set,a=r.map((e,t)=>{let n=`audiences[${t}]`;if(!t5(e))throw new t9(`${n} must be an object.`);if(t8(e,["kind","team_id","channel_id"],n),!(t5(e)&&Object.keys(e).every(e=>["kind","team_id","channel_id"].includes(e))&&"slack"===e.kind&&"string"==typeof e.team_id&&t2.test(e.team_id)&&"string"==typeof e.channel_id&&t3.test(e.channel_id)))throw new t9(`${n} must be { kind: "slack", team_id: "T…", channel_id: "C…" } with exact ids; wildcards are not allowed.`);let r=`${e.team_id}:${e.channel_id}`;if(s.has(r))throw new t9(`${n} repeats an audience.`);return s.add(r),Object.freeze({kind:"slack",team_id:e.team_id,channel_id:e.channel_id})}),o=new Set,d=new Set;return i.forEach((e,n)=>{let r=`agents[${n}]`;if(!t5(e))throw new t9(`${r} must be an object.`);if(t8(e,["agent","share_from_turn"],r),"string"!=typeof e.agent||!t6.test(e.agent))throw new t9(`${r}.agent must be one Agent id; wildcards are not allowed.`);if(t&&!t.has(e.agent))throw new t9(`${r}.agent is not a registered Agent.`);if("boolean"!=typeof e.share_from_turn)throw new t9(`${r}.share_from_turn must be true or false.`);if(d.has(e.agent))throw new t9(`${r} repeats that Agent.`);d.add(e.agent),e.share_from_turn&&o.add(e.agent)}),{audiences:Object.freeze(a),shareFromTurn:o}}(i,r)}}catch(t){if(t instanceof t9)return{state:"invalid",path:e,reason:t.message};throw t}}(o,a,d);return t7={key:l,state:_},_}function nt(e){let t=ne();return"loaded"===t.state&&t.config.audiences.some(t=>t.team_id===e.team_id&&t.channel_id===e.channel_id)}function nn(e){let t=ne();return"loaded"===t.state&&t.config.shareFromTurn.has(e)}function nr(e){if("string"==typeof e&&0!==e.length&&!(e.length>200))return i.default.prepare("SELECT * FROM session_shares WHERE id = ?").get(e)}function ni(e,t=Date.now()){return"revoked"===e.state?"revoked":t>=e.expires_at?"expired":"active"}function ns(e,t=Date.now()){return{share_ref:e.id,agent_id:e.agent_id,session_ref:e.session_ref,authority:"ask",state:ni(e,t),audience:{kind:"slack",team_id:e.audience_team_id,channel_id:e.audience_channel_id},created_via:e.created_via,created_at:e.created_at,expires_at:e.expires_at,revoked_at:e.revoked_at,max_turns:e.max_turns,turns_used:e.turns_used}}function na(e,t,n,r={}){i.default.prepare(`
|
|
2175
|
+
INSERT INTO session_share_events (share_ref, sequence, type, turn_ref, code, at)
|
|
2176
|
+
SELECT ?, COALESCE(MAX(sequence), 0) + 1, ?, ?, ?, ? FROM session_share_events WHERE share_ref = ?
|
|
2177
|
+
`).run(e,t,r.turnRef??null,r.code??null,n,e)}function no(){let e=Date.now(),t=i.default.prepare(`
|
|
2178
|
+
SELECT s.id FROM session_shares s JOIN session_pins p ON p.id = s.pin_ref
|
|
2179
|
+
WHERE s.state = 'active' AND s.expires_at <= ? AND p.state = 'attached'
|
|
2180
|
+
ORDER BY s.expires_at, s.id LIMIT 500
|
|
2181
|
+
`).all(e),n=[];for(let{id:r}of t)i.default.transaction(()=>{let t=nr(r);if(!t||"expired"!==ni(t,e))return;let{replayed:s}=function(e,t,n={}){return i.default.transaction(()=>{var r;let s=tM(e,t);if("detached"===s.state)return n.onCommit?.(s),{pin:s,replayed:!0};r=n.now??Date.now(),i.default.prepare("UPDATE session_pins SET state = 'detached', detach_reason = ?, replaced_by = ?, detached_at = ?, updated_at = ? WHERE id = ? AND state = 'attached'").run("detached",null,r,r,s.id),tU(s.id,"detached",{},r);let a=tF(s.id);return n.onCommit?.(a),{pin:a,replayed:!1}}).immediate()}(tV,t.pin_ref,{now:e});s||(i.serviceAudit.append({principal:tV,operation:"shares.expire",capability:"shares:ask",targetKind:"session",targetRef:t.session_ref,agentId:t.agent_id,outcome:"allowed",code:"expired"}),n.push(r))}).immediate();return{swept:n}}class nd extends Error{code;status;constructor(e,t,n){super(t),this.name="ShareAskError",this.code=e,this.status=n}}function nu(e){return{turn_ref:e.turn_ref,state:e.state,answer:"completed"===e.state?function(e){if(null===e)return null;let t=(0,a.serviceRedactor)().text(e);return t.length>tQ.replyChars?`${t.slice(0,tQ.replyChars-1)}…`:t}(e.answer):null,failure:e.failure?{code:e.failure.code}:null}}async function nl(e,t){let{turns:n}=await tJ(tV,e.pin_ref);return n.find(e=>e.turn_ref===t)??null}async function n_(e){if(e.inflight_turn_ref){let t=await nl(e,e.inflight_turn_ref);if(t&&"running"===t.state)return"busy";i.default.prepare("UPDATE session_shares SET inflight_turn_ref = NULL WHERE id = ? AND inflight_turn_ref = ?").run(e.id,e.inflight_turn_ref)}if(e.inflight_key){if(e.inflight_owner===t1&&t4.has(e.id))return"busy";i.default.prepare("UPDATE session_shares SET inflight_key = NULL, inflight_owner = NULL WHERE id = ? AND inflight_key = ?").run(e.id,e.inflight_key)}return"free"}async function nc(e){var t,n,r;let s=nr(e.shareRef),a=(e,t)=>i.serviceAudit.append({principal:tV,operation:"shares.ask",capability:"shares:ask",targetKind:"session",targetRef:s?.session_ref??null,agentId:s?.agent_id??null,outcome:e,code:t}),o=(e,t,n)=>{let r="invalid_request"===e||"idempotency_conflict"===e?"rejected":"denied";throw i.default.transaction(()=>{a(r,e),s&&na(s.id,"turn_refused",Date.now(),{code:e})}).immediate(),new nd(e,t,n)},d=(e,t)=>o(e,t,tZ[e]);s||d("share_not_found","No share with that reference."),("string"!=typeof e.messageKey||0===e.messageKey.trim().length||e.messageKey.length>200)&&d("invalid_request","A question key (1-200 characters) is required."),("string"!=typeof e.question||0===e.question.trim().length||e.question.length>tQ.questionChars)&&d("invalid_request",`The question must be 1-${tQ.questionChars} characters.`);let u=ni(s);"revoked"===u&&d("share_revoked","This share was revoked."),"expired"===u&&d("share_expired","This share has expired.");let l=()=>tz({requester:tV,pinRef:s.pin_ref,content:e.question,idempotencyKey:e.messageKey,onCommit:(e,t)=>{let n=Date.now();if(1!==i.default.prepare(`
|
|
2182
|
+
UPDATE session_shares SET turns_used = turns_used + 1, inflight_turn_ref = ?, inflight_key = NULL, inflight_owner = NULL, updated_at = ?
|
|
2183
|
+
WHERE id = ? AND turns_used < max_turns
|
|
2184
|
+
`).run(t.id,n,s.id).changes)throw new t0("share_turn_limit","This share has used all of its questions.");na(s.id,"turn_sent",n,{turnRef:t.id}),a("allowed",null)}}),_=e=>{if(e instanceof nd)throw e;throw e instanceof t0&&d(e.code,e.message),e instanceof tx&&(("pin_detached"===e.code||"pin_not_found"===e.code)&&d("share_revoked","This share was revoked."),o(e.code,e.message,e.status)),e};if(t=e.messageKey,i.default.prepare("SELECT pin_id FROM session_pin_turns WHERE requester_kind = ? AND requester_id = ? AND idempotency_key = ?").get(tV.kind,tV.id,`turn:${t}`)){let e;try{e=await l()}catch(e){return _(e)}return e.replayed&&a("allowed","replayed"),{share:ns(nr(s.id)),turn:nu(e.turn),replayed:e.replayed,settled:e.settled}}if(s.turns_used>=s.max_turns&&d("share_turn_limit","This share has used all of its questions."),await n_(s)==="busy"&&d("share_turn_in_progress","A question on this share is still being answered."),1!==i.default.prepare(`
|
|
2185
|
+
UPDATE session_shares SET inflight_key = ?, inflight_owner = ?
|
|
2186
|
+
WHERE id = ? AND state = 'active' AND inflight_key IS NULL AND inflight_turn_ref IS NULL AND turns_used < max_turns
|
|
2187
|
+
`).run(e.messageKey,t1,s.id).changes){let e=nr(s.id);"revoked"===ni(e)&&d("share_revoked","This share was revoked."),e.turns_used>=e.max_turns&&d("share_turn_limit","This share has used all of its questions."),d("share_turn_in_progress","A question on this share is still being answered.")}t4.add(s.id);try{let e=await l();return{share:ns(nr(s.id)),turn:nu(e.turn),replayed:e.replayed,settled:e.settled}}catch(t){return n=s.id,r=e.messageKey,i.default.prepare("UPDATE session_shares SET inflight_key = NULL, inflight_owner = NULL WHERE id = ? AND inflight_key = ? AND inflight_turn_ref IS NULL").run(n,r),_(t)}finally{t4.delete(s.id)}}async function nE(e,t){let n=nr(e);if(!n)throw new t0("share_not_found","No share with that reference.");let r=await nl(n,t);if(!r)throw new t0("share_not_found","No turn with that reference on this share.");return"running"===r.state?null:(i.default.prepare("UPDATE session_shares SET inflight_turn_ref = NULL WHERE id = ? AND inflight_turn_ref = ?").run(n.id,t),nu(r))}}];
|
|
2188
|
+
|
|
2189
|
+
//# sourceMappingURL=lib_15adnlz._.js.map
|