@aitne/daemon 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/adapters/composite-dashboard-stream.d.ts +42 -0
- package/dist/adapters/composite-dashboard-stream.d.ts.map +1 -0
- package/dist/adapters/composite-dashboard-stream.js +49 -0
- package/dist/adapters/composite-dashboard-stream.js.map +1 -0
- package/dist/adapters/dashboard-adapter.d.ts +104 -0
- package/dist/adapters/dashboard-adapter.d.ts.map +1 -0
- package/dist/adapters/dashboard-adapter.js +216 -0
- package/dist/adapters/dashboard-adapter.js.map +1 -0
- package/dist/adapters/discord.d.ts +77 -0
- package/dist/adapters/discord.d.ts.map +1 -0
- package/dist/adapters/discord.js +339 -0
- package/dist/adapters/discord.js.map +1 -0
- package/dist/adapters/docs-qa-adapter.d.ts +123 -0
- package/dist/adapters/docs-qa-adapter.d.ts.map +1 -0
- package/dist/adapters/docs-qa-adapter.js +218 -0
- package/dist/adapters/docs-qa-adapter.js.map +1 -0
- package/dist/adapters/message-hub.d.ts +70 -0
- package/dist/adapters/message-hub.d.ts.map +1 -0
- package/dist/adapters/message-hub.js +359 -0
- package/dist/adapters/message-hub.js.map +1 -0
- package/dist/adapters/notification-manager.d.ts +99 -0
- package/dist/adapters/notification-manager.d.ts.map +1 -0
- package/dist/adapters/notification-manager.js +498 -0
- package/dist/adapters/notification-manager.js.map +1 -0
- package/dist/adapters/outbound-text.d.ts +28 -0
- package/dist/adapters/outbound-text.d.ts.map +1 -0
- package/dist/adapters/outbound-text.js +58 -0
- package/dist/adapters/outbound-text.js.map +1 -0
- package/dist/adapters/slack-adapter.d.ts +82 -0
- package/dist/adapters/slack-adapter.d.ts.map +1 -0
- package/dist/adapters/slack-adapter.js +359 -0
- package/dist/adapters/slack-adapter.js.map +1 -0
- package/dist/adapters/telegram-adapter.d.ts +107 -0
- package/dist/adapters/telegram-adapter.d.ts.map +1 -0
- package/dist/adapters/telegram-adapter.js +477 -0
- package/dist/adapters/telegram-adapter.js.map +1 -0
- package/dist/adapters/types.d.ts +92 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +2 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/adapters/whatsapp-adapter.d.ts +213 -0
- package/dist/adapters/whatsapp-adapter.d.ts.map +1 -0
- package/dist/adapters/whatsapp-adapter.js +1216 -0
- package/dist/adapters/whatsapp-adapter.js.map +1 -0
- package/dist/api/chat-binding-query.d.ts +36 -0
- package/dist/api/chat-binding-query.d.ts.map +1 -0
- package/dist/api/chat-binding-query.js +63 -0
- package/dist/api/chat-binding-query.js.map +1 -0
- package/dist/api/chat-session-resume.d.ts +12 -0
- package/dist/api/chat-session-resume.d.ts.map +1 -0
- package/dist/api/chat-session-resume.js +21 -0
- package/dist/api/chat-session-resume.js.map +1 -0
- package/dist/api/delegated-proxy-helper.d.ts +33 -0
- package/dist/api/delegated-proxy-helper.d.ts.map +1 -0
- package/dist/api/delegated-proxy-helper.js +54 -0
- package/dist/api/delegated-proxy-helper.js.map +1 -0
- package/dist/api/directory-picker.d.ts +38 -0
- package/dist/api/directory-picker.d.ts.map +1 -0
- package/dist/api/directory-picker.js +278 -0
- package/dist/api/directory-picker.js.map +1 -0
- package/dist/api/env-writer.d.ts +25 -0
- package/dist/api/env-writer.d.ts.map +1 -0
- package/dist/api/env-writer.js +421 -0
- package/dist/api/env-writer.js.map +1 -0
- package/dist/api/integration-route-gate.d.ts +60 -0
- package/dist/api/integration-route-gate.d.ts.map +1 -0
- package/dist/api/integration-route-gate.js +83 -0
- package/dist/api/integration-route-gate.js.map +1 -0
- package/dist/api/json-body.d.ts +29 -0
- package/dist/api/json-body.d.ts.map +1 -0
- package/dist/api/json-body.js +87 -0
- package/dist/api/json-body.js.map +1 -0
- package/dist/api/routes/activity-sources.d.ts +20 -0
- package/dist/api/routes/activity-sources.d.ts.map +1 -0
- package/dist/api/routes/activity-sources.js +18 -0
- package/dist/api/routes/activity-sources.js.map +1 -0
- package/dist/api/routes/agent.d.ts +4 -0
- package/dist/api/routes/agent.d.ts.map +1 -0
- package/dist/api/routes/agent.js +619 -0
- package/dist/api/routes/agent.js.map +1 -0
- package/dist/api/routes/apple-calendar.d.ts +31 -0
- package/dist/api/routes/apple-calendar.d.ts.map +1 -0
- package/dist/api/routes/apple-calendar.js +310 -0
- package/dist/api/routes/apple-calendar.js.map +1 -0
- package/dist/api/routes/attachments.d.ts +36 -0
- package/dist/api/routes/attachments.d.ts.map +1 -0
- package/dist/api/routes/attachments.js +305 -0
- package/dist/api/routes/attachments.js.map +1 -0
- package/dist/api/routes/backends.d.ts +4 -0
- package/dist/api/routes/backends.d.ts.map +1 -0
- package/dist/api/routes/backends.js +1132 -0
- package/dist/api/routes/backends.js.map +1 -0
- package/dist/api/routes/books.d.ts +63 -0
- package/dist/api/routes/books.d.ts.map +1 -0
- package/dist/api/routes/books.js +467 -0
- package/dist/api/routes/books.js.map +1 -0
- package/dist/api/routes/calendar.d.ts +36 -0
- package/dist/api/routes/calendar.d.ts.map +1 -0
- package/dist/api/routes/calendar.js +351 -0
- package/dist/api/routes/calendar.js.map +1 -0
- package/dist/api/routes/commands.d.ts +4 -0
- package/dist/api/routes/commands.d.ts.map +1 -0
- package/dist/api/routes/commands.js +251 -0
- package/dist/api/routes/commands.js.map +1 -0
- package/dist/api/routes/context.d.ts +57 -0
- package/dist/api/routes/context.d.ts.map +1 -0
- package/dist/api/routes/context.js +1765 -0
- package/dist/api/routes/context.js.map +1 -0
- package/dist/api/routes/dashboard.d.ts +29 -0
- package/dist/api/routes/dashboard.d.ts.map +1 -0
- package/dist/api/routes/dashboard.js +2062 -0
- package/dist/api/routes/dashboard.js.map +1 -0
- package/dist/api/routes/delegated-sync.d.ts +4 -0
- package/dist/api/routes/delegated-sync.d.ts.map +1 -0
- package/dist/api/routes/delegated-sync.js +192 -0
- package/dist/api/routes/delegated-sync.js.map +1 -0
- package/dist/api/routes/delegated.d.ts +42 -0
- package/dist/api/routes/delegated.d.ts.map +1 -0
- package/dist/api/routes/delegated.js +250 -0
- package/dist/api/routes/delegated.js.map +1 -0
- package/dist/api/routes/docs.d.ts +34 -0
- package/dist/api/routes/docs.d.ts.map +1 -0
- package/dist/api/routes/docs.js +580 -0
- package/dist/api/routes/docs.js.map +1 -0
- package/dist/api/routes/entities.d.ts +9 -0
- package/dist/api/routes/entities.d.ts.map +1 -0
- package/dist/api/routes/entities.js +176 -0
- package/dist/api/routes/entities.js.map +1 -0
- package/dist/api/routes/git-accounts.d.ts +23 -0
- package/dist/api/routes/git-accounts.d.ts.map +1 -0
- package/dist/api/routes/git-accounts.js +227 -0
- package/dist/api/routes/git-accounts.js.map +1 -0
- package/dist/api/routes/git-templates.d.ts +50 -0
- package/dist/api/routes/git-templates.d.ts.map +1 -0
- package/dist/api/routes/git-templates.js +276 -0
- package/dist/api/routes/git-templates.js.map +1 -0
- package/dist/api/routes/git.d.ts +34 -0
- package/dist/api/routes/git.d.ts.map +1 -0
- package/dist/api/routes/git.js +126 -0
- package/dist/api/routes/git.js.map +1 -0
- package/dist/api/routes/github.d.ts +34 -0
- package/dist/api/routes/github.d.ts.map +1 -0
- package/dist/api/routes/github.js +465 -0
- package/dist/api/routes/github.js.map +1 -0
- package/dist/api/routes/health.d.ts +4 -0
- package/dist/api/routes/health.d.ts.map +1 -0
- package/dist/api/routes/health.js +257 -0
- package/dist/api/routes/health.js.map +1 -0
- package/dist/api/routes/integrations-reconcile.d.ts +33 -0
- package/dist/api/routes/integrations-reconcile.d.ts.map +1 -0
- package/dist/api/routes/integrations-reconcile.js +463 -0
- package/dist/api/routes/integrations-reconcile.js.map +1 -0
- package/dist/api/routes/integrations.d.ts +19 -0
- package/dist/api/routes/integrations.d.ts.map +1 -0
- package/dist/api/routes/integrations.js +1384 -0
- package/dist/api/routes/integrations.js.map +1 -0
- package/dist/api/routes/knowledge.d.ts +4 -0
- package/dist/api/routes/knowledge.d.ts.map +1 -0
- package/dist/api/routes/knowledge.js +224 -0
- package/dist/api/routes/knowledge.js.map +1 -0
- package/dist/api/routes/mail.d.ts +39 -0
- package/dist/api/routes/mail.d.ts.map +1 -0
- package/dist/api/routes/mail.js +1406 -0
- package/dist/api/routes/mail.js.map +1 -0
- package/dist/api/routes/managed-tasks.d.ts +48 -0
- package/dist/api/routes/managed-tasks.d.ts.map +1 -0
- package/dist/api/routes/managed-tasks.js +844 -0
- package/dist/api/routes/managed-tasks.js.map +1 -0
- package/dist/api/routes/mcp.d.ts +50 -0
- package/dist/api/routes/mcp.d.ts.map +1 -0
- package/dist/api/routes/mcp.js +470 -0
- package/dist/api/routes/mcp.js.map +1 -0
- package/dist/api/routes/metrics.d.ts +13 -0
- package/dist/api/routes/metrics.d.ts.map +1 -0
- package/dist/api/routes/metrics.js +117 -0
- package/dist/api/routes/metrics.js.map +1 -0
- package/dist/api/routes/notion.d.ts +35 -0
- package/dist/api/routes/notion.d.ts.map +1 -0
- package/dist/api/routes/notion.js +442 -0
- package/dist/api/routes/notion.js.map +1 -0
- package/dist/api/routes/observations.d.ts +4 -0
- package/dist/api/routes/observations.d.ts.map +1 -0
- package/dist/api/routes/observations.js +177 -0
- package/dist/api/routes/observations.js.map +1 -0
- package/dist/api/routes/obsidian.d.ts +16 -0
- package/dist/api/routes/obsidian.d.ts.map +1 -0
- package/dist/api/routes/obsidian.js +321 -0
- package/dist/api/routes/obsidian.js.map +1 -0
- package/dist/api/routes/profile-questions.d.ts +17 -0
- package/dist/api/routes/profile-questions.d.ts.map +1 -0
- package/dist/api/routes/profile-questions.js +115 -0
- package/dist/api/routes/profile-questions.js.map +1 -0
- package/dist/api/routes/receipts.d.ts +4 -0
- package/dist/api/routes/receipts.d.ts.map +1 -0
- package/dist/api/routes/receipts.js +155 -0
- package/dist/api/routes/receipts.js.map +1 -0
- package/dist/api/routes/recurring-schedules.d.ts +4 -0
- package/dist/api/routes/recurring-schedules.d.ts.map +1 -0
- package/dist/api/routes/recurring-schedules.js +137 -0
- package/dist/api/routes/recurring-schedules.js.map +1 -0
- package/dist/api/routes/repositories.d.ts +40 -0
- package/dist/api/routes/repositories.d.ts.map +1 -0
- package/dist/api/routes/repositories.js +857 -0
- package/dist/api/routes/repositories.js.map +1 -0
- package/dist/api/routes/setup-migrate.d.ts +74 -0
- package/dist/api/routes/setup-migrate.d.ts.map +1 -0
- package/dist/api/routes/setup-migrate.js +944 -0
- package/dist/api/routes/setup-migrate.js.map +1 -0
- package/dist/api/routes/setup.d.ts +4 -0
- package/dist/api/routes/setup.d.ts.map +1 -0
- package/dist/api/routes/setup.js +443 -0
- package/dist/api/routes/setup.js.map +1 -0
- package/dist/api/routes/skill-curation.d.ts +5 -0
- package/dist/api/routes/skill-curation.d.ts.map +1 -0
- package/dist/api/routes/skill-curation.js +728 -0
- package/dist/api/routes/skill-curation.js.map +1 -0
- package/dist/api/routes/skills.d.ts +52 -0
- package/dist/api/routes/skills.d.ts.map +1 -0
- package/dist/api/routes/skills.js +429 -0
- package/dist/api/routes/skills.js.map +1 -0
- package/dist/api/routes/sot-bindings.d.ts +20 -0
- package/dist/api/routes/sot-bindings.d.ts.map +1 -0
- package/dist/api/routes/sot-bindings.js +163 -0
- package/dist/api/routes/sot-bindings.js.map +1 -0
- package/dist/api/routes/sse.d.ts +86 -0
- package/dist/api/routes/sse.d.ts.map +1 -0
- package/dist/api/routes/sse.js +378 -0
- package/dist/api/routes/sse.js.map +1 -0
- package/dist/api/routes/system.d.ts +4 -0
- package/dist/api/routes/system.d.ts.map +1 -0
- package/dist/api/routes/system.js +207 -0
- package/dist/api/routes/system.js.map +1 -0
- package/dist/api/routes/task-flows.d.ts +30 -0
- package/dist/api/routes/task-flows.d.ts.map +1 -0
- package/dist/api/routes/task-flows.js +155 -0
- package/dist/api/routes/task-flows.js.map +1 -0
- package/dist/api/routes/travel-bookings.d.ts +4 -0
- package/dist/api/routes/travel-bookings.d.ts.map +1 -0
- package/dist/api/routes/travel-bookings.js +142 -0
- package/dist/api/routes/travel-bookings.js.map +1 -0
- package/dist/api/routes/travel-time.d.ts +8 -0
- package/dist/api/routes/travel-time.d.ts.map +1 -0
- package/dist/api/routes/travel-time.js +87 -0
- package/dist/api/routes/travel-time.js.map +1 -0
- package/dist/api/routes/triggers.d.ts +4 -0
- package/dist/api/routes/triggers.d.ts.map +1 -0
- package/dist/api/routes/triggers.js +101 -0
- package/dist/api/routes/triggers.js.map +1 -0
- package/dist/api/routes/voice.d.ts +48 -0
- package/dist/api/routes/voice.d.ts.map +1 -0
- package/dist/api/routes/voice.js +232 -0
- package/dist/api/routes/voice.js.map +1 -0
- package/dist/api/server.d.ts +428 -0
- package/dist/api/server.d.ts.map +1 -0
- package/dist/api/server.js +558 -0
- package/dist/api/server.js.map +1 -0
- package/dist/config.d.ts +136 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +699 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-core.d.ts +517 -0
- package/dist/core/agent-core.d.ts.map +1 -0
- package/dist/core/agent-core.js +102 -0
- package/dist/core/agent-core.js.map +1 -0
- package/dist/core/alerts.d.ts +86 -0
- package/dist/core/alerts.d.ts.map +1 -0
- package/dist/core/alerts.js +304 -0
- package/dist/core/alerts.js.map +1 -0
- package/dist/core/atomic-write.d.ts +51 -0
- package/dist/core/atomic-write.d.ts.map +1 -0
- package/dist/core/atomic-write.js +135 -0
- package/dist/core/atomic-write.js.map +1 -0
- package/dist/core/backends/api-key-probe.d.ts +40 -0
- package/dist/core/backends/api-key-probe.d.ts.map +1 -0
- package/dist/core/backends/api-key-probe.js +116 -0
- package/dist/core/backends/api-key-probe.js.map +1 -0
- package/dist/core/backends/auth-health-monitor.d.ts +373 -0
- package/dist/core/backends/auth-health-monitor.d.ts.map +1 -0
- package/dist/core/backends/auth-health-monitor.js +950 -0
- package/dist/core/backends/auth-health-monitor.js.map +1 -0
- package/dist/core/backends/auth-recovery.d.ts +263 -0
- package/dist/core/backends/auth-recovery.d.ts.map +1 -0
- package/dist/core/backends/auth-recovery.js +1086 -0
- package/dist/core/backends/auth-recovery.js.map +1 -0
- package/dist/core/backends/auth-telemetry.d.ts +81 -0
- package/dist/core/backends/auth-telemetry.d.ts.map +1 -0
- package/dist/core/backends/auth-telemetry.js +108 -0
- package/dist/core/backends/auth-telemetry.js.map +1 -0
- package/dist/core/backends/backend-router.d.ts +272 -0
- package/dist/core/backends/backend-router.d.ts.map +1 -0
- package/dist/core/backends/backend-router.js +759 -0
- package/dist/core/backends/backend-router.js.map +1 -0
- package/dist/core/backends/claude-code-core.d.ts +299 -0
- package/dist/core/backends/claude-code-core.d.ts.map +1 -0
- package/dist/core/backends/claude-code-core.js +2541 -0
- package/dist/core/backends/claude-code-core.js.map +1 -0
- package/dist/core/backends/claude-credentials-store.d.ts +83 -0
- package/dist/core/backends/claude-credentials-store.d.ts.map +1 -0
- package/dist/core/backends/claude-credentials-store.js +243 -0
- package/dist/core/backends/claude-credentials-store.js.map +1 -0
- package/dist/core/backends/cli-utils.d.ts +95 -0
- package/dist/core/backends/cli-utils.d.ts.map +1 -0
- package/dist/core/backends/cli-utils.js +464 -0
- package/dist/core/backends/cli-utils.js.map +1 -0
- package/dist/core/backends/codex-core.d.ts +127 -0
- package/dist/core/backends/codex-core.d.ts.map +1 -0
- package/dist/core/backends/codex-core.js +1693 -0
- package/dist/core/backends/codex-core.js.map +1 -0
- package/dist/core/backends/gemini-cli-core.d.ts +367 -0
- package/dist/core/backends/gemini-cli-core.d.ts.map +1 -0
- package/dist/core/backends/gemini-cli-core.js +2331 -0
- package/dist/core/backends/gemini-cli-core.js.map +1 -0
- package/dist/core/backends/idle-watchdog.d.ts +77 -0
- package/dist/core/backends/idle-watchdog.d.ts.map +1 -0
- package/dist/core/backends/idle-watchdog.js +94 -0
- package/dist/core/backends/idle-watchdog.js.map +1 -0
- package/dist/core/backends/install-methods.d.ts +93 -0
- package/dist/core/backends/install-methods.d.ts.map +1 -0
- package/dist/core/backends/install-methods.js +267 -0
- package/dist/core/backends/install-methods.js.map +1 -0
- package/dist/core/backends/model-registry.d.ts +58 -0
- package/dist/core/backends/model-registry.d.ts.map +1 -0
- package/dist/core/backends/model-registry.js +539 -0
- package/dist/core/backends/model-registry.js.map +1 -0
- package/dist/core/backends/plan-presets.d.ts +123 -0
- package/dist/core/backends/plan-presets.d.ts.map +1 -0
- package/dist/core/backends/plan-presets.js +235 -0
- package/dist/core/backends/plan-presets.js.map +1 -0
- package/dist/core/backends/price-fetcher.d.ts +48 -0
- package/dist/core/backends/price-fetcher.d.ts.map +1 -0
- package/dist/core/backends/price-fetcher.js +248 -0
- package/dist/core/backends/price-fetcher.js.map +1 -0
- package/dist/core/backends/process-config-cascade.d.ts +68 -0
- package/dist/core/backends/process-config-cascade.d.ts.map +1 -0
- package/dist/core/backends/process-config-cascade.js +173 -0
- package/dist/core/backends/process-config-cascade.js.map +1 -0
- package/dist/core/backends/prompt-utils.d.ts +6 -0
- package/dist/core/backends/prompt-utils.d.ts.map +1 -0
- package/dist/core/backends/prompt-utils.js +80 -0
- package/dist/core/backends/prompt-utils.js.map +1 -0
- package/dist/core/backends/proxy-model-registry.d.ts +110 -0
- package/dist/core/backends/proxy-model-registry.d.ts.map +1 -0
- package/dist/core/backends/proxy-model-registry.js +195 -0
- package/dist/core/backends/proxy-model-registry.js.map +1 -0
- package/dist/core/backends/silent-api-error-detector.d.ts +31 -0
- package/dist/core/backends/silent-api-error-detector.d.ts.map +1 -0
- package/dist/core/backends/silent-api-error-detector.js +44 -0
- package/dist/core/backends/silent-api-error-detector.js.map +1 -0
- package/dist/core/bang-commands/commands-cost.d.ts +13 -0
- package/dist/core/bang-commands/commands-cost.d.ts.map +1 -0
- package/dist/core/bang-commands/commands-cost.js +91 -0
- package/dist/core/bang-commands/commands-cost.js.map +1 -0
- package/dist/core/bang-commands/commands-report.d.ts +18 -0
- package/dist/core/bang-commands/commands-report.d.ts.map +1 -0
- package/dist/core/bang-commands/commands-report.js +105 -0
- package/dist/core/bang-commands/commands-report.js.map +1 -0
- package/dist/core/bang-commands/commands-stop-start.d.ts +4 -0
- package/dist/core/bang-commands/commands-stop-start.d.ts.map +1 -0
- package/dist/core/bang-commands/commands-stop-start.js +88 -0
- package/dist/core/bang-commands/commands-stop-start.js.map +1 -0
- package/dist/core/bang-commands/format-utils.d.ts +34 -0
- package/dist/core/bang-commands/format-utils.d.ts.map +1 -0
- package/dist/core/bang-commands/format-utils.js +118 -0
- package/dist/core/bang-commands/format-utils.js.map +1 -0
- package/dist/core/bang-commands/index.d.ts +20 -0
- package/dist/core/bang-commands/index.d.ts.map +1 -0
- package/dist/core/bang-commands/index.js +31 -0
- package/dist/core/bang-commands/index.js.map +1 -0
- package/dist/core/bang-commands/registry.d.ts +72 -0
- package/dist/core/bang-commands/registry.d.ts.map +1 -0
- package/dist/core/bang-commands/registry.js +174 -0
- package/dist/core/bang-commands/registry.js.map +1 -0
- package/dist/core/bang-commands/user-commands.d.ts +86 -0
- package/dist/core/bang-commands/user-commands.d.ts.map +1 -0
- package/dist/core/bang-commands/user-commands.js +212 -0
- package/dist/core/bang-commands/user-commands.js.map +1 -0
- package/dist/core/channel-timeline.d.ts +28 -0
- package/dist/core/channel-timeline.d.ts.map +1 -0
- package/dist/core/channel-timeline.js +117 -0
- package/dist/core/channel-timeline.js.map +1 -0
- package/dist/core/character-block.d.ts +37 -0
- package/dist/core/character-block.d.ts.map +1 -0
- package/dist/core/character-block.js +162 -0
- package/dist/core/character-block.js.map +1 -0
- package/dist/core/context/activity-sources.d.ts +37 -0
- package/dist/core/context/activity-sources.d.ts.map +1 -0
- package/dist/core/context/activity-sources.js +69 -0
- package/dist/core/context/activity-sources.js.map +1 -0
- package/dist/core/context/activity-view-reconciler.d.ts +110 -0
- package/dist/core/context/activity-view-reconciler.d.ts.map +1 -0
- package/dist/core/context/activity-view-reconciler.js +252 -0
- package/dist/core/context/activity-view-reconciler.js.map +1 -0
- package/dist/core/context/activity-view-runner.d.ts +38 -0
- package/dist/core/context/activity-view-runner.d.ts.map +1 -0
- package/dist/core/context/activity-view-runner.js +402 -0
- package/dist/core/context/activity-view-runner.js.map +1 -0
- package/dist/core/context/default-schedules-reconciler.d.ts +85 -0
- package/dist/core/context/default-schedules-reconciler.d.ts.map +1 -0
- package/dist/core/context/default-schedules-reconciler.js +153 -0
- package/dist/core/context/default-schedules-reconciler.js.map +1 -0
- package/dist/core/context/default-schedules-runner.d.ts +40 -0
- package/dist/core/context/default-schedules-runner.d.ts.map +1 -0
- package/dist/core/context/default-schedules-runner.js +233 -0
- package/dist/core/context/default-schedules-runner.js.map +1 -0
- package/dist/core/context/domain-index-reconciler.d.ts +81 -0
- package/dist/core/context/domain-index-reconciler.d.ts.map +1 -0
- package/dist/core/context/domain-index-reconciler.js +199 -0
- package/dist/core/context/domain-index-reconciler.js.map +1 -0
- package/dist/core/context/domain-index-runner.d.ts +35 -0
- package/dist/core/context/domain-index-runner.d.ts.map +1 -0
- package/dist/core/context/domain-index-runner.js +223 -0
- package/dist/core/context/domain-index-runner.js.map +1 -0
- package/dist/core/context/entity-mirror.d.ts +227 -0
- package/dist/core/context/entity-mirror.d.ts.map +1 -0
- package/dist/core/context/entity-mirror.js +629 -0
- package/dist/core/context/entity-mirror.js.map +1 -0
- package/dist/core/context/entity-source-rename.d.ts +61 -0
- package/dist/core/context/entity-source-rename.d.ts.map +1 -0
- package/dist/core/context/entity-source-rename.js +237 -0
- package/dist/core/context/entity-source-rename.js.map +1 -0
- package/dist/core/context/index-reconciler.d.ts +61 -0
- package/dist/core/context/index-reconciler.d.ts.map +1 -0
- package/dist/core/context/index-reconciler.js +329 -0
- package/dist/core/context/index-reconciler.js.map +1 -0
- package/dist/core/context/policy-index-reconciler.d.ts +102 -0
- package/dist/core/context/policy-index-reconciler.d.ts.map +1 -0
- package/dist/core/context/policy-index-reconciler.js +202 -0
- package/dist/core/context/policy-index-reconciler.js.map +1 -0
- package/dist/core/context/policy-index-runner.d.ts +66 -0
- package/dist/core/context/policy-index-runner.d.ts.map +1 -0
- package/dist/core/context/policy-index-runner.js +406 -0
- package/dist/core/context/policy-index-runner.js.map +1 -0
- package/dist/core/context/reconciler-runner.d.ts +44 -0
- package/dist/core/context/reconciler-runner.d.ts.map +1 -0
- package/dist/core/context/reconciler-runner.js +273 -0
- package/dist/core/context/reconciler-runner.js.map +1 -0
- package/dist/core/context-builder.d.ts +115 -0
- package/dist/core/context-builder.d.ts.map +1 -0
- package/dist/core/context-builder.js +1148 -0
- package/dist/core/context-builder.js.map +1 -0
- package/dist/core/context-frontmatter-backfill.d.ts +33 -0
- package/dist/core/context-frontmatter-backfill.d.ts.map +1 -0
- package/dist/core/context-frontmatter-backfill.js +111 -0
- package/dist/core/context-frontmatter-backfill.js.map +1 -0
- package/dist/core/context-frontmatter.d.ts +13 -0
- package/dist/core/context-frontmatter.d.ts.map +1 -0
- package/dist/core/context-frontmatter.js +325 -0
- package/dist/core/context-frontmatter.js.map +1 -0
- package/dist/core/context-health.d.ts +51 -0
- package/dist/core/context-health.d.ts.map +1 -0
- package/dist/core/context-health.js +304 -0
- package/dist/core/context-health.js.map +1 -0
- package/dist/core/context-paths.d.ts +183 -0
- package/dist/core/context-paths.d.ts.map +1 -0
- package/dist/core/context-paths.js +241 -0
- package/dist/core/context-paths.js.map +1 -0
- package/dist/core/context-staleness.d.ts +45 -0
- package/dist/core/context-staleness.d.ts.map +1 -0
- package/dist/core/context-staleness.js +88 -0
- package/dist/core/context-staleness.js.map +1 -0
- package/dist/core/custom-routine-scheduler.d.ts +151 -0
- package/dist/core/custom-routine-scheduler.d.ts.map +1 -0
- package/dist/core/custom-routine-scheduler.js +335 -0
- package/dist/core/custom-routine-scheduler.js.map +1 -0
- package/dist/core/daemon-api-cli.d.ts +33 -0
- package/dist/core/daemon-api-cli.d.ts.map +1 -0
- package/dist/core/daemon-api-cli.js +614 -0
- package/dist/core/daemon-api-cli.js.map +1 -0
- package/dist/core/dashboard-session-cleanup.d.ts +39 -0
- package/dist/core/dashboard-session-cleanup.d.ts.map +1 -0
- package/dist/core/dashboard-session-cleanup.js +108 -0
- package/dist/core/dashboard-session-cleanup.js.map +1 -0
- package/dist/core/dashboard-session-controls.d.ts +41 -0
- package/dist/core/dashboard-session-controls.d.ts.map +1 -0
- package/dist/core/dashboard-session-controls.js +154 -0
- package/dist/core/dashboard-session-controls.js.map +1 -0
- package/dist/core/delegated-connector-health.d.ts +63 -0
- package/dist/core/delegated-connector-health.d.ts.map +1 -0
- package/dist/core/delegated-connector-health.js +157 -0
- package/dist/core/delegated-connector-health.js.map +1 -0
- package/dist/core/dispatcher.d.ts +999 -0
- package/dist/core/dispatcher.d.ts.map +1 -0
- package/dist/core/dispatcher.js +4378 -0
- package/dist/core/dispatcher.js.map +1 -0
- package/dist/core/dm-freshness-metrics.d.ts +73 -0
- package/dist/core/dm-freshness-metrics.d.ts.map +1 -0
- package/dist/core/dm-freshness-metrics.js +138 -0
- package/dist/core/dm-freshness-metrics.js.map +1 -0
- package/dist/core/docs/citation-validator.d.ts +73 -0
- package/dist/core/docs/citation-validator.d.ts.map +1 -0
- package/dist/core/docs/citation-validator.js +195 -0
- package/dist/core/docs/citation-validator.js.map +1 -0
- package/dist/core/docs/extract-terms.d.ts +78 -0
- package/dist/core/docs/extract-terms.d.ts.map +1 -0
- package/dist/core/docs/extract-terms.js +147 -0
- package/dist/core/docs/extract-terms.js.map +1 -0
- package/dist/core/docs/indexer.d.ts +104 -0
- package/dist/core/docs/indexer.d.ts.map +1 -0
- package/dist/core/docs/indexer.js +340 -0
- package/dist/core/docs/indexer.js.map +1 -0
- package/dist/core/drift-effects.d.ts +30 -0
- package/dist/core/drift-effects.d.ts.map +1 -0
- package/dist/core/drift-effects.js +384 -0
- package/dist/core/drift-effects.js.map +1 -0
- package/dist/core/event-bus.d.ts +56 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +135 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/git-project-docs.d.ts +77 -0
- package/dist/core/git-project-docs.d.ts.map +1 -0
- package/dist/core/git-project-docs.js +439 -0
- package/dist/core/git-project-docs.js.map +1 -0
- package/dist/core/health-monitor.d.ts +57 -0
- package/dist/core/health-monitor.d.ts.map +1 -0
- package/dist/core/health-monitor.js +137 -0
- package/dist/core/health-monitor.js.map +1 -0
- package/dist/core/heartbeat.d.ts +26 -0
- package/dist/core/heartbeat.d.ts.map +1 -0
- package/dist/core/heartbeat.js +48 -0
- package/dist/core/heartbeat.js.map +1 -0
- package/dist/core/integration-health.d.ts +49 -0
- package/dist/core/integration-health.d.ts.map +1 -0
- package/dist/core/integration-health.js +89 -0
- package/dist/core/integration-health.js.map +1 -0
- package/dist/core/integration-lifecycle.d.ts +79 -0
- package/dist/core/integration-lifecycle.d.ts.map +1 -0
- package/dist/core/integration-lifecycle.js +153 -0
- package/dist/core/integration-lifecycle.js.map +1 -0
- package/dist/core/integration-main-backend.d.ts +36 -0
- package/dist/core/integration-main-backend.d.ts.map +1 -0
- package/dist/core/integration-main-backend.js +59 -0
- package/dist/core/integration-main-backend.js.map +1 -0
- package/dist/core/integration-probe.d.ts +98 -0
- package/dist/core/integration-probe.d.ts.map +1 -0
- package/dist/core/integration-probe.js +152 -0
- package/dist/core/integration-probe.js.map +1 -0
- package/dist/core/management-md-write-lock.d.ts +68 -0
- package/dist/core/management-md-write-lock.d.ts.map +1 -0
- package/dist/core/management-md-write-lock.js +93 -0
- package/dist/core/management-md-write-lock.js.map +1 -0
- package/dist/core/management-md.d.ts +186 -0
- package/dist/core/management-md.d.ts.map +1 -0
- package/dist/core/management-md.js +652 -0
- package/dist/core/management-md.js.map +1 -0
- package/dist/core/management-registry.d.ts +245 -0
- package/dist/core/management-registry.d.ts.map +1 -0
- package/dist/core/management-registry.js +906 -0
- package/dist/core/management-registry.js.map +1 -0
- package/dist/core/management-telemetry.d.ts +100 -0
- package/dist/core/management-telemetry.d.ts.map +1 -0
- package/dist/core/management-telemetry.js +156 -0
- package/dist/core/management-telemetry.js.map +1 -0
- package/dist/core/message-recorder.d.ts +38 -0
- package/dist/core/message-recorder.d.ts.map +1 -0
- package/dist/core/message-recorder.js +88 -0
- package/dist/core/message-recorder.js.map +1 -0
- package/dist/core/metrics.d.ts +338 -0
- package/dist/core/metrics.d.ts.map +1 -0
- package/dist/core/metrics.js +747 -0
- package/dist/core/metrics.js.map +1 -0
- package/dist/core/migration-backup.d.ts +218 -0
- package/dist/core/migration-backup.d.ts.map +1 -0
- package/dist/core/migration-backup.js +934 -0
- package/dist/core/migration-backup.js.map +1 -0
- package/dist/core/overview-write-lock.d.ts +48 -0
- package/dist/core/overview-write-lock.d.ts.map +1 -0
- package/dist/core/overview-write-lock.js +56 -0
- package/dist/core/overview-write-lock.js.map +1 -0
- package/dist/core/path-compat.d.ts +22 -0
- package/dist/core/path-compat.d.ts.map +1 -0
- package/dist/core/path-compat.js +67 -0
- package/dist/core/path-compat.js.map +1 -0
- package/dist/core/path-rewrite.d.ts +58 -0
- package/dist/core/path-rewrite.d.ts.map +1 -0
- package/dist/core/path-rewrite.js +141 -0
- package/dist/core/path-rewrite.js.map +1 -0
- package/dist/core/policy-files.d.ts +108 -0
- package/dist/core/policy-files.d.ts.map +1 -0
- package/dist/core/policy-files.js +198 -0
- package/dist/core/policy-files.js.map +1 -0
- package/dist/core/profile-questions/seed.d.ts +44 -0
- package/dist/core/profile-questions/seed.d.ts.map +1 -0
- package/dist/core/profile-questions/seed.js +173 -0
- package/dist/core/profile-questions/seed.js.map +1 -0
- package/dist/core/profile-questions/slot-filled.d.ts +51 -0
- package/dist/core/profile-questions/slot-filled.d.ts.map +1 -0
- package/dist/core/profile-questions/slot-filled.js +118 -0
- package/dist/core/profile-questions/slot-filled.js.map +1 -0
- package/dist/core/prompts.d.ts +111 -0
- package/dist/core/prompts.d.ts.map +1 -0
- package/dist/core/prompts.js +267 -0
- package/dist/core/prompts.js.map +1 -0
- package/dist/core/quiet-hours-sync.d.ts +15 -0
- package/dist/core/quiet-hours-sync.d.ts.map +1 -0
- package/dist/core/quiet-hours-sync.js +51 -0
- package/dist/core/quiet-hours-sync.js.map +1 -0
- package/dist/core/read-sensitive-token-manager.d.ts +19 -0
- package/dist/core/read-sensitive-token-manager.d.ts.map +1 -0
- package/dist/core/read-sensitive-token-manager.js +29 -0
- package/dist/core/read-sensitive-token-manager.js.map +1 -0
- package/dist/core/recurrence.d.ts +24 -0
- package/dist/core/recurrence.d.ts.map +1 -0
- package/dist/core/recurrence.js +162 -0
- package/dist/core/recurrence.js.map +1 -0
- package/dist/core/reinstall.d.ts +107 -0
- package/dist/core/reinstall.d.ts.map +1 -0
- package/dist/core/reinstall.js +163 -0
- package/dist/core/reinstall.js.map +1 -0
- package/dist/core/release-assets.d.ts +106 -0
- package/dist/core/release-assets.d.ts.map +1 -0
- package/dist/core/release-assets.js +434 -0
- package/dist/core/release-assets.js.map +1 -0
- package/dist/core/repository-management-docs.d.ts +216 -0
- package/dist/core/repository-management-docs.d.ts.map +1 -0
- package/dist/core/repository-management-docs.js +855 -0
- package/dist/core/repository-management-docs.js.map +1 -0
- package/dist/core/retention.d.ts +164 -0
- package/dist/core/retention.d.ts.map +1 -0
- package/dist/core/retention.js +1008 -0
- package/dist/core/retention.js.map +1 -0
- package/dist/core/review-context.d.ts +48 -0
- package/dist/core/review-context.d.ts.map +1 -0
- package/dist/core/review-context.js +282 -0
- package/dist/core/review-context.js.map +1 -0
- package/dist/core/roadmap-horizon.d.ts +48 -0
- package/dist/core/roadmap-horizon.d.ts.map +1 -0
- package/dist/core/roadmap-horizon.js +213 -0
- package/dist/core/roadmap-horizon.js.map +1 -0
- package/dist/core/roadmap-ids.d.ts +57 -0
- package/dist/core/roadmap-ids.d.ts.map +1 -0
- package/dist/core/roadmap-ids.js +118 -0
- package/dist/core/roadmap-ids.js.map +1 -0
- package/dist/core/roadmap-merge.d.ts +7 -0
- package/dist/core/roadmap-merge.d.ts.map +1 -0
- package/dist/core/roadmap-merge.js +187 -0
- package/dist/core/roadmap-merge.js.map +1 -0
- package/dist/core/roadmap-refresh-triggers.d.ts +32 -0
- package/dist/core/roadmap-refresh-triggers.d.ts.map +1 -0
- package/dist/core/roadmap-refresh-triggers.js +51 -0
- package/dist/core/roadmap-refresh-triggers.js.map +1 -0
- package/dist/core/roadmap-truncate.d.ts +49 -0
- package/dist/core/roadmap-truncate.d.ts.map +1 -0
- package/dist/core/roadmap-truncate.js +152 -0
- package/dist/core/roadmap-truncate.js.map +1 -0
- package/dist/core/roadmap-validate.d.ts +31 -0
- package/dist/core/roadmap-validate.d.ts.map +1 -0
- package/dist/core/roadmap-validate.js +403 -0
- package/dist/core/roadmap-validate.js.map +1 -0
- package/dist/core/roadmap-write-lock.d.ts +53 -0
- package/dist/core/roadmap-write-lock.d.ts.map +1 -0
- package/dist/core/roadmap-write-lock.js +59 -0
- package/dist/core/roadmap-write-lock.js.map +1 -0
- package/dist/core/schedule-insert-helper.d.ts +46 -0
- package/dist/core/schedule-insert-helper.d.ts.map +1 -0
- package/dist/core/schedule-insert-helper.js +52 -0
- package/dist/core/schedule-insert-helper.js.map +1 -0
- package/dist/core/schedule-maintenance.d.ts +22 -0
- package/dist/core/schedule-maintenance.d.ts.map +1 -0
- package/dist/core/schedule-maintenance.js +57 -0
- package/dist/core/schedule-maintenance.js.map +1 -0
- package/dist/core/scheduler.d.ts +208 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +896 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/semaphore.d.ts +13 -0
- package/dist/core/semaphore.d.ts.map +1 -0
- package/dist/core/semaphore.js +31 -0
- package/dist/core/semaphore.js.map +1 -0
- package/dist/core/session-gate.d.ts +37 -0
- package/dist/core/session-gate.d.ts.map +1 -0
- package/dist/core/session-gate.js +69 -0
- package/dist/core/session-gate.js.map +1 -0
- package/dist/core/session-manager.d.ts +252 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +716 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/core/signal-detector.d.ts +97 -0
- package/dist/core/signal-detector.d.ts.map +1 -0
- package/dist/core/signal-detector.js +215 -0
- package/dist/core/signal-detector.js.map +1 -0
- package/dist/core/skeleton.d.ts +83 -0
- package/dist/core/skeleton.d.ts.map +1 -0
- package/dist/core/skeleton.js +255 -0
- package/dist/core/skeleton.js.map +1 -0
- package/dist/core/skill-curation/apply-proposal.d.ts +71 -0
- package/dist/core/skill-curation/apply-proposal.d.ts.map +1 -0
- package/dist/core/skill-curation/apply-proposal.js +175 -0
- package/dist/core/skill-curation/apply-proposal.js.map +1 -0
- package/dist/core/skill-curation/auto-revert.d.ts +43 -0
- package/dist/core/skill-curation/auto-revert.d.ts.map +1 -0
- package/dist/core/skill-curation/auto-revert.js +155 -0
- package/dist/core/skill-curation/auto-revert.js.map +1 -0
- package/dist/core/skill-curation/classify-diff.d.ts +27 -0
- package/dist/core/skill-curation/classify-diff.d.ts.map +1 -0
- package/dist/core/skill-curation/classify-diff.js +0 -0
- package/dist/core/skill-curation/classify-diff.js.map +1 -0
- package/dist/core/skill-curation/declarations.d.ts +32 -0
- package/dist/core/skill-curation/declarations.d.ts.map +1 -0
- package/dist/core/skill-curation/declarations.js +171 -0
- package/dist/core/skill-curation/declarations.js.map +1 -0
- package/dist/core/skill-curation/knowledge-map.d.ts +26 -0
- package/dist/core/skill-curation/knowledge-map.d.ts.map +1 -0
- package/dist/core/skill-curation/knowledge-map.js +154 -0
- package/dist/core/skill-curation/knowledge-map.js.map +1 -0
- package/dist/core/skill-curation/orphan-overlay.d.ts +35 -0
- package/dist/core/skill-curation/orphan-overlay.d.ts.map +1 -0
- package/dist/core/skill-curation/orphan-overlay.js +167 -0
- package/dist/core/skill-curation/orphan-overlay.js.map +1 -0
- package/dist/core/skill-curation/overlay-store.d.ts +41 -0
- package/dist/core/skill-curation/overlay-store.d.ts.map +1 -0
- package/dist/core/skill-curation/overlay-store.js +143 -0
- package/dist/core/skill-curation/overlay-store.js.map +1 -0
- package/dist/core/skill-curation/render/convention-notes.d.ts +4 -0
- package/dist/core/skill-curation/render/convention-notes.d.ts.map +1 -0
- package/dist/core/skill-curation/render/convention-notes.js +13 -0
- package/dist/core/skill-curation/render/convention-notes.js.map +1 -0
- package/dist/core/skill-curation/render/cross-references.d.ts +4 -0
- package/dist/core/skill-curation/render/cross-references.d.ts.map +1 -0
- package/dist/core/skill-curation/render/cross-references.js +10 -0
- package/dist/core/skill-curation/render/cross-references.js.map +1 -0
- package/dist/core/skill-curation/render/frontmatter-schema.d.ts +4 -0
- package/dist/core/skill-curation/render/frontmatter-schema.d.ts.map +1 -0
- package/dist/core/skill-curation/render/frontmatter-schema.js +25 -0
- package/dist/core/skill-curation/render/frontmatter-schema.js.map +1 -0
- package/dist/core/skill-curation/render/index.d.ts +5 -0
- package/dist/core/skill-curation/render/index.d.ts.map +1 -0
- package/dist/core/skill-curation/render/index.js +42 -0
- package/dist/core/skill-curation/render/index.js.map +1 -0
- package/dist/core/skill-curation/render/knowledge-layout.d.ts +4 -0
- package/dist/core/skill-curation/render/knowledge-layout.d.ts.map +1 -0
- package/dist/core/skill-curation/render/knowledge-layout.js +36 -0
- package/dist/core/skill-curation/render/knowledge-layout.js.map +1 -0
- package/dist/core/skill-curation/render/routing-table.d.ts +4 -0
- package/dist/core/skill-curation/render/routing-table.d.ts.map +1 -0
- package/dist/core/skill-curation/render/routing-table.js +37 -0
- package/dist/core/skill-curation/render/routing-table.js.map +1 -0
- package/dist/core/skill-curation/render/search-recipes.d.ts +4 -0
- package/dist/core/skill-curation/render/search-recipes.d.ts.map +1 -0
- package/dist/core/skill-curation/render/search-recipes.js +39 -0
- package/dist/core/skill-curation/render/search-recipes.js.map +1 -0
- package/dist/core/skill-curation/run-token.d.ts +27 -0
- package/dist/core/skill-curation/run-token.d.ts.map +1 -0
- package/dist/core/skill-curation/run-token.js +81 -0
- package/dist/core/skill-curation/run-token.js.map +1 -0
- package/dist/core/skill-curation/signals.d.ts +49 -0
- package/dist/core/skill-curation/signals.d.ts.map +1 -0
- package/dist/core/skill-curation/signals.js +149 -0
- package/dist/core/skill-curation/signals.js.map +1 -0
- package/dist/core/skill-curation/smoke-test.d.ts +39 -0
- package/dist/core/skill-curation/smoke-test.d.ts.map +1 -0
- package/dist/core/skill-curation/smoke-test.js +313 -0
- package/dist/core/skill-curation/smoke-test.js.map +1 -0
- package/dist/core/skill-curation/splicer.d.ts +16 -0
- package/dist/core/skill-curation/splicer.d.ts.map +1 -0
- package/dist/core/skill-curation/splicer.js +78 -0
- package/dist/core/skill-curation/splicer.js.map +1 -0
- package/dist/core/skill-curation/workdir.d.ts +40 -0
- package/dist/core/skill-curation/workdir.d.ts.map +1 -0
- package/dist/core/skill-curation/workdir.js +242 -0
- package/dist/core/skill-curation/workdir.js.map +1 -0
- package/dist/core/skills-compiler.d.ts +391 -0
- package/dist/core/skills-compiler.d.ts.map +1 -0
- package/dist/core/skills-compiler.js +1271 -0
- package/dist/core/skills-compiler.js.map +1 -0
- package/dist/core/skills-manifest.d.ts +8 -0
- package/dist/core/skills-manifest.d.ts.map +1 -0
- package/dist/core/skills-manifest.js +408 -0
- package/dist/core/skills-manifest.js.map +1 -0
- package/dist/core/system-reset.d.ts +268 -0
- package/dist/core/system-reset.d.ts.map +1 -0
- package/dist/core/system-reset.js +816 -0
- package/dist/core/system-reset.js.map +1 -0
- package/dist/core/template-store.d.ts +170 -0
- package/dist/core/template-store.d.ts.map +1 -0
- package/dist/core/template-store.js +388 -0
- package/dist/core/template-store.js.map +1 -0
- package/dist/core/template-versions.d.ts +95 -0
- package/dist/core/template-versions.d.ts.map +1 -0
- package/dist/core/template-versions.js +175 -0
- package/dist/core/template-versions.js.map +1 -0
- package/dist/core/today-agent-plan.d.ts +33 -0
- package/dist/core/today-agent-plan.d.ts.map +1 -0
- package/dist/core/today-agent-plan.js +120 -0
- package/dist/core/today-agent-plan.js.map +1 -0
- package/dist/core/today-direct-writer.d.ts +62 -0
- package/dist/core/today-direct-writer.d.ts.map +1 -0
- package/dist/core/today-direct-writer.js +132 -0
- package/dist/core/today-direct-writer.js.map +1 -0
- package/dist/core/today-write-lock.d.ts +89 -0
- package/dist/core/today-write-lock.d.ts.map +1 -0
- package/dist/core/today-write-lock.js +154 -0
- package/dist/core/today-write-lock.js.map +1 -0
- package/dist/core/trigger-dispatch.d.ts +31 -0
- package/dist/core/trigger-dispatch.d.ts.map +1 -0
- package/dist/core/trigger-dispatch.js +100 -0
- package/dist/core/trigger-dispatch.js.map +1 -0
- package/dist/core/trigger-evaluator.d.ts +59 -0
- package/dist/core/trigger-evaluator.d.ts.map +1 -0
- package/dist/core/trigger-evaluator.js +243 -0
- package/dist/core/trigger-evaluator.js.map +1 -0
- package/dist/core/workdir.d.ts +241 -0
- package/dist/core/workdir.d.ts.map +1 -0
- package/dist/core/workdir.js +565 -0
- package/dist/core/workdir.js.map +1 -0
- package/dist/db/automation-triggers.d.ts +90 -0
- package/dist/db/automation-triggers.d.ts.map +1 -0
- package/dist/db/automation-triggers.js +199 -0
- package/dist/db/automation-triggers.js.map +1 -0
- package/dist/db/client.d.ts +6 -0
- package/dist/db/client.d.ts.map +1 -0
- package/dist/db/client.js +47 -0
- package/dist/db/client.js.map +1 -0
- package/dist/db/entities-store.d.ts +92 -0
- package/dist/db/entities-store.d.ts.map +1 -0
- package/dist/db/entities-store.js +180 -0
- package/dist/db/entities-store.js.map +1 -0
- package/dist/db/hourly-check-signals.d.ts +78 -0
- package/dist/db/hourly-check-signals.d.ts.map +1 -0
- package/dist/db/hourly-check-signals.js +289 -0
- package/dist/db/hourly-check-signals.js.map +1 -0
- package/dist/db/integration-probe-store.d.ts +27 -0
- package/dist/db/integration-probe-store.d.ts.map +1 -0
- package/dist/db/integration-probe-store.js +75 -0
- package/dist/db/integration-probe-store.js.map +1 -0
- package/dist/db/integrations-store.d.ts +19 -0
- package/dist/db/integrations-store.d.ts.map +1 -0
- package/dist/db/integrations-store.js +85 -0
- package/dist/db/integrations-store.js.map +1 -0
- package/dist/db/managed-tasks-store.d.ts +130 -0
- package/dist/db/managed-tasks-store.d.ts.map +1 -0
- package/dist/db/managed-tasks-store.js +238 -0
- package/dist/db/managed-tasks-store.js.map +1 -0
- package/dist/db/management-parse-failures-store.d.ts +45 -0
- package/dist/db/management-parse-failures-store.d.ts.map +1 -0
- package/dist/db/management-parse-failures-store.js +36 -0
- package/dist/db/management-parse-failures-store.js.map +1 -0
- package/dist/db/observations.d.ts +145 -0
- package/dist/db/observations.d.ts.map +1 -0
- package/dist/db/observations.js +287 -0
- package/dist/db/observations.js.map +1 -0
- package/dist/db/recurring-schedules.d.ts +70 -0
- package/dist/db/recurring-schedules.d.ts.map +1 -0
- package/dist/db/recurring-schedules.js +213 -0
- package/dist/db/recurring-schedules.js.map +1 -0
- package/dist/db/repositories-store.d.ts +296 -0
- package/dist/db/repositories-store.d.ts.map +1 -0
- package/dist/db/repositories-store.js +754 -0
- package/dist/db/repositories-store.js.map +1 -0
- package/dist/db/runtime-state.d.ts +61 -0
- package/dist/db/runtime-state.d.ts.map +1 -0
- package/dist/db/runtime-state.js +104 -0
- package/dist/db/runtime-state.js.map +1 -0
- package/dist/db/schema.d.ts +4 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +1338 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/sot-bindings-store.d.ts +41 -0
- package/dist/db/sot-bindings-store.d.ts.map +1 -0
- package/dist/db/sot-bindings-store.js +64 -0
- package/dist/db/sot-bindings-store.js.map +1 -0
- package/dist/db/test-schemas.d.ts +23 -0
- package/dist/db/test-schemas.d.ts.map +1 -0
- package/dist/db/test-schemas.js +111 -0
- package/dist/db/test-schemas.js.map +1 -0
- package/dist/db/voice-transcripts-store.d.ts +28 -0
- package/dist/db/voice-transcripts-store.d.ts.map +1 -0
- package/dist/db/voice-transcripts-store.js +43 -0
- package/dist/db/voice-transcripts-store.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2913 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +7 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +32 -0
- package/dist/init.js.map +1 -0
- package/dist/log-buffer.d.ts +71 -0
- package/dist/log-buffer.d.ts.map +1 -0
- package/dist/log-buffer.js +201 -0
- package/dist/log-buffer.js.map +1 -0
- package/dist/logging.d.ts +5 -0
- package/dist/logging.d.ts.map +1 -0
- package/dist/logging.js +130 -0
- package/dist/logging.js.map +1 -0
- package/dist/management-rules.d.ts +2 -0
- package/dist/management-rules.d.ts.map +1 -0
- package/dist/management-rules.js +62 -0
- package/dist/management-rules.js.map +1 -0
- package/dist/messaging/constants.d.ts +33 -0
- package/dist/messaging/constants.d.ts.map +1 -0
- package/dist/messaging/constants.js +52 -0
- package/dist/messaging/constants.js.map +1 -0
- package/dist/messaging/magic-phrase.d.ts +16 -0
- package/dist/messaging/magic-phrase.d.ts.map +1 -0
- package/dist/messaging/magic-phrase.js +103 -0
- package/dist/messaging/magic-phrase.js.map +1 -0
- package/dist/messaging/owner-channels.d.ts +20 -0
- package/dist/messaging/owner-channels.d.ts.map +1 -0
- package/dist/messaging/owner-channels.js +41 -0
- package/dist/messaging/owner-channels.js.map +1 -0
- package/dist/observers/calendar-poller.d.ts +51 -0
- package/dist/observers/calendar-poller.d.ts.map +1 -0
- package/dist/observers/calendar-poller.js +128 -0
- package/dist/observers/calendar-poller.js.map +1 -0
- package/dist/observers/context-index-reconciler-observer.d.ts +72 -0
- package/dist/observers/context-index-reconciler-observer.d.ts.map +1 -0
- package/dist/observers/context-index-reconciler-observer.js +253 -0
- package/dist/observers/context-index-reconciler-observer.js.map +1 -0
- package/dist/observers/delegated-probe-observer.d.ts +83 -0
- package/dist/observers/delegated-probe-observer.d.ts.map +1 -0
- package/dist/observers/delegated-probe-observer.js +237 -0
- package/dist/observers/delegated-probe-observer.js.map +1 -0
- package/dist/observers/delegated-sync-worker.d.ts +375 -0
- package/dist/observers/delegated-sync-worker.d.ts.map +1 -0
- package/dist/observers/delegated-sync-worker.js +1087 -0
- package/dist/observers/delegated-sync-worker.js.map +1 -0
- package/dist/observers/entity-mirror-observer.d.ts +55 -0
- package/dist/observers/entity-mirror-observer.d.ts.map +1 -0
- package/dist/observers/entity-mirror-observer.js +73 -0
- package/dist/observers/entity-mirror-observer.js.map +1 -0
- package/dist/observers/git-delegated-cron.d.ts +41 -0
- package/dist/observers/git-delegated-cron.d.ts.map +1 -0
- package/dist/observers/git-delegated-cron.js +159 -0
- package/dist/observers/git-delegated-cron.js.map +1 -0
- package/dist/observers/git-event-classifier.d.ts +52 -0
- package/dist/observers/git-event-classifier.d.ts.map +1 -0
- package/dist/observers/git-event-classifier.js +70 -0
- package/dist/observers/git-event-classifier.js.map +1 -0
- package/dist/observers/git-watcher.d.ts +162 -0
- package/dist/observers/git-watcher.d.ts.map +1 -0
- package/dist/observers/git-watcher.js +768 -0
- package/dist/observers/git-watcher.js.map +1 -0
- package/dist/observers/github-poller-classifier.d.ts +101 -0
- package/dist/observers/github-poller-classifier.d.ts.map +1 -0
- package/dist/observers/github-poller-classifier.js +199 -0
- package/dist/observers/github-poller-classifier.js.map +1 -0
- package/dist/observers/github-poller.d.ts +291 -0
- package/dist/observers/github-poller.d.ts.map +1 -0
- package/dist/observers/github-poller.js +609 -0
- package/dist/observers/github-poller.js.map +1 -0
- package/dist/observers/imminent-event-scheduler.d.ts +34 -0
- package/dist/observers/imminent-event-scheduler.d.ts.map +1 -0
- package/dist/observers/imminent-event-scheduler.js +125 -0
- package/dist/observers/imminent-event-scheduler.js.map +1 -0
- package/dist/observers/mail-poller.d.ts +133 -0
- package/dist/observers/mail-poller.d.ts.map +1 -0
- package/dist/observers/mail-poller.js +563 -0
- package/dist/observers/mail-poller.js.map +1 -0
- package/dist/observers/mail-reconciliation.d.ts +87 -0
- package/dist/observers/mail-reconciliation.d.ts.map +1 -0
- package/dist/observers/mail-reconciliation.js +241 -0
- package/dist/observers/mail-reconciliation.js.map +1 -0
- package/dist/observers/manager.d.ts +67 -0
- package/dist/observers/manager.d.ts.map +1 -0
- package/dist/observers/manager.js +136 -0
- package/dist/observers/manager.js.map +1 -0
- package/dist/observers/notion-poller.d.ts +43 -0
- package/dist/observers/notion-poller.d.ts.map +1 -0
- package/dist/observers/notion-poller.js +184 -0
- package/dist/observers/notion-poller.js.map +1 -0
- package/dist/observers/observation-summarizer/index.d.ts +13 -0
- package/dist/observers/observation-summarizer/index.d.ts.map +1 -0
- package/dist/observers/observation-summarizer/index.js +13 -0
- package/dist/observers/observation-summarizer/index.js.map +1 -0
- package/dist/observers/observation-summarizer/pre-filter.d.ts +62 -0
- package/dist/observers/observation-summarizer/pre-filter.d.ts.map +1 -0
- package/dist/observers/observation-summarizer/pre-filter.js +189 -0
- package/dist/observers/observation-summarizer/pre-filter.js.map +1 -0
- package/dist/observers/observation-summarizer/response-parser.d.ts +30 -0
- package/dist/observers/observation-summarizer/response-parser.d.ts.map +1 -0
- package/dist/observers/observation-summarizer/response-parser.js +106 -0
- package/dist/observers/observation-summarizer/response-parser.js.map +1 -0
- package/dist/observers/observation-summarizer/summarizer-client.d.ts +83 -0
- package/dist/observers/observation-summarizer/summarizer-client.d.ts.map +1 -0
- package/dist/observers/observation-summarizer/summarizer-client.js +185 -0
- package/dist/observers/observation-summarizer/summarizer-client.js.map +1 -0
- package/dist/observers/observation-summarizer/summarizer-prompts.d.ts +51 -0
- package/dist/observers/observation-summarizer/summarizer-prompts.d.ts.map +1 -0
- package/dist/observers/observation-summarizer/summarizer-prompts.js +286 -0
- package/dist/observers/observation-summarizer/summarizer-prompts.js.map +1 -0
- package/dist/observers/observation-summarizer/worker.d.ts +106 -0
- package/dist/observers/observation-summarizer/worker.d.ts.map +1 -0
- package/dist/observers/observation-summarizer/worker.js +311 -0
- package/dist/observers/observation-summarizer/worker.js.map +1 -0
- package/dist/observers/obsidian-watcher.d.ts +90 -0
- package/dist/observers/obsidian-watcher.d.ts.map +1 -0
- package/dist/observers/obsidian-watcher.js +166 -0
- package/dist/observers/obsidian-watcher.js.map +1 -0
- package/dist/observers/primary-vault-watcher.d.ts +73 -0
- package/dist/observers/primary-vault-watcher.d.ts.map +1 -0
- package/dist/observers/primary-vault-watcher.js +115 -0
- package/dist/observers/primary-vault-watcher.js.map +1 -0
- package/dist/observers/repository-management-cron.d.ts +70 -0
- package/dist/observers/repository-management-cron.d.ts.map +1 -0
- package/dist/observers/repository-management-cron.js +166 -0
- package/dist/observers/repository-management-cron.js.map +1 -0
- package/dist/observers/skill-curation-walker.d.ts +33 -0
- package/dist/observers/skill-curation-walker.d.ts.map +1 -0
- package/dist/observers/skill-curation-walker.js +216 -0
- package/dist/observers/skill-curation-walker.js.map +1 -0
- package/dist/safety/absolute-block-audit.d.ts +22 -0
- package/dist/safety/absolute-block-audit.d.ts.map +1 -0
- package/dist/safety/absolute-block-audit.js +32 -0
- package/dist/safety/absolute-block-audit.js.map +1 -0
- package/dist/safety/agent-write-tracker.d.ts +42 -0
- package/dist/safety/agent-write-tracker.d.ts.map +1 -0
- package/dist/safety/agent-write-tracker.js +82 -0
- package/dist/safety/agent-write-tracker.js.map +1 -0
- package/dist/safety/always-disallowed.d.ts +66 -0
- package/dist/safety/always-disallowed.d.ts.map +1 -0
- package/dist/safety/always-disallowed.js +347 -0
- package/dist/safety/always-disallowed.js.map +1 -0
- package/dist/safety/audit.d.ts +118 -0
- package/dist/safety/audit.d.ts.map +1 -0
- package/dist/safety/audit.js +324 -0
- package/dist/safety/audit.js.map +1 -0
- package/dist/safety/integration-write-tracker.d.ts +58 -0
- package/dist/safety/integration-write-tracker.d.ts.map +1 -0
- package/dist/safety/integration-write-tracker.js +41 -0
- package/dist/safety/integration-write-tracker.js.map +1 -0
- package/dist/safety/risk-classifier.d.ts +65 -0
- package/dist/safety/risk-classifier.d.ts.map +1 -0
- package/dist/safety/risk-classifier.js +763 -0
- package/dist/safety/risk-classifier.js.map +1 -0
- package/dist/scheduler/hourly-check-gate.d.ts +73 -0
- package/dist/scheduler/hourly-check-gate.d.ts.map +1 -0
- package/dist/scheduler/hourly-check-gate.js +128 -0
- package/dist/scheduler/hourly-check-gate.js.map +1 -0
- package/dist/secrets/backend-api-key-env.d.ts +104 -0
- package/dist/secrets/backend-api-key-env.d.ts.map +1 -0
- package/dist/secrets/backend-api-key-env.js +197 -0
- package/dist/secrets/backend-api-key-env.js.map +1 -0
- package/dist/secrets/codex-home-materializer.d.ts +35 -0
- package/dist/secrets/codex-home-materializer.d.ts.map +1 -0
- package/dist/secrets/codex-home-materializer.js +76 -0
- package/dist/secrets/codex-home-materializer.js.map +1 -0
- package/dist/secrets/encrypted-blob-store.d.ts +20 -0
- package/dist/secrets/encrypted-blob-store.d.ts.map +1 -0
- package/dist/secrets/encrypted-blob-store.js +80 -0
- package/dist/secrets/encrypted-blob-store.js.map +1 -0
- package/dist/secrets/platform-secret-store.d.ts +17 -0
- package/dist/secrets/platform-secret-store.d.ts.map +1 -0
- package/dist/secrets/platform-secret-store.js +37 -0
- package/dist/secrets/platform-secret-store.js.map +1 -0
- package/dist/secrets/redaction.d.ts +2 -0
- package/dist/secrets/redaction.d.ts.map +1 -0
- package/dist/secrets/redaction.js +2 -0
- package/dist/secrets/redaction.js.map +1 -0
- package/dist/secrets/secret-broker.d.ts +61 -0
- package/dist/secrets/secret-broker.d.ts.map +1 -0
- package/dist/secrets/secret-broker.js +160 -0
- package/dist/secrets/secret-broker.js.map +1 -0
- package/dist/secrets/secret-names.d.ts +34 -0
- package/dist/secrets/secret-names.d.ts.map +1 -0
- package/dist/secrets/secret-names.js +39 -0
- package/dist/secrets/secret-names.js.map +1 -0
- package/dist/secrets/secret-store.d.ts +8 -0
- package/dist/secrets/secret-store.d.ts.map +1 -0
- package/dist/secrets/secret-store.js +2 -0
- package/dist/secrets/secret-store.js.map +1 -0
- package/dist/secrets/types.d.ts +7 -0
- package/dist/secrets/types.d.ts.map +1 -0
- package/dist/secrets/types.js +2 -0
- package/dist/secrets/types.js.map +1 -0
- package/dist/services/apple-calendar/caldav-client.d.ts +48 -0
- package/dist/services/apple-calendar/caldav-client.d.ts.map +1 -0
- package/dist/services/apple-calendar/caldav-client.js +86 -0
- package/dist/services/apple-calendar/caldav-client.js.map +1 -0
- package/dist/services/apple-calendar/caldav-codec.d.ts +67 -0
- package/dist/services/apple-calendar/caldav-codec.d.ts.map +1 -0
- package/dist/services/apple-calendar/caldav-codec.js +341 -0
- package/dist/services/apple-calendar/caldav-codec.js.map +1 -0
- package/dist/services/apple-calendar/index.d.ts +3 -0
- package/dist/services/apple-calendar/index.d.ts.map +1 -0
- package/dist/services/apple-calendar/index.js +2 -0
- package/dist/services/apple-calendar/index.js.map +1 -0
- package/dist/services/apple-calendar/service.d.ts +75 -0
- package/dist/services/apple-calendar/service.d.ts.map +1 -0
- package/dist/services/apple-calendar/service.js +374 -0
- package/dist/services/apple-calendar/service.js.map +1 -0
- package/dist/services/apple-calendar/types.d.ts +78 -0
- package/dist/services/apple-calendar/types.d.ts.map +1 -0
- package/dist/services/apple-calendar/types.js +17 -0
- package/dist/services/apple-calendar/types.js.map +1 -0
- package/dist/services/attachments/hardlink.d.ts +11 -0
- package/dist/services/attachments/hardlink.d.ts.map +1 -0
- package/dist/services/attachments/hardlink.js +56 -0
- package/dist/services/attachments/hardlink.js.map +1 -0
- package/dist/services/attachments/sanitize.d.ts +21 -0
- package/dist/services/attachments/sanitize.d.ts.map +1 -0
- package/dist/services/attachments/sanitize.js +128 -0
- package/dist/services/attachments/sanitize.js.map +1 -0
- package/dist/services/attachments/store.d.ts +146 -0
- package/dist/services/attachments/store.d.ts.map +1 -0
- package/dist/services/attachments/store.js +477 -0
- package/dist/services/attachments/store.js.map +1 -0
- package/dist/services/calendar/outlook/graph-calendar-client.d.ts +114 -0
- package/dist/services/calendar/outlook/graph-calendar-client.d.ts.map +1 -0
- package/dist/services/calendar/outlook/graph-calendar-client.js +146 -0
- package/dist/services/calendar/outlook/graph-calendar-client.js.map +1 -0
- package/dist/services/calendar.d.ts +115 -0
- package/dist/services/calendar.d.ts.map +1 -0
- package/dist/services/calendar.js +281 -0
- package/dist/services/calendar.js.map +1 -0
- package/dist/services/delegated-backend-invoker.d.ts +414 -0
- package/dist/services/delegated-backend-invoker.d.ts.map +1 -0
- package/dist/services/delegated-backend-invoker.js +2372 -0
- package/dist/services/delegated-backend-invoker.js.map +1 -0
- package/dist/services/delegated-proxy-config.d.ts +93 -0
- package/dist/services/delegated-proxy-config.d.ts.map +1 -0
- package/dist/services/delegated-proxy-config.js +98 -0
- package/dist/services/delegated-proxy-config.js.map +1 -0
- package/dist/services/delegated-task-result-cache.d.ts +176 -0
- package/dist/services/delegated-task-result-cache.d.ts.map +1 -0
- package/dist/services/delegated-task-result-cache.js +0 -0
- package/dist/services/delegated-task-result-cache.js.map +1 -0
- package/dist/services/delegated-task-runtime.d.ts +346 -0
- package/dist/services/delegated-task-runtime.d.ts.map +1 -0
- package/dist/services/delegated-task-runtime.js +589 -0
- package/dist/services/delegated-task-runtime.js.map +1 -0
- package/dist/services/delegated-task-session-pool.d.ts +182 -0
- package/dist/services/delegated-task-session-pool.d.ts.map +1 -0
- package/dist/services/delegated-task-session-pool.js +292 -0
- package/dist/services/delegated-task-session-pool.js.map +1 -0
- package/dist/services/delegated-tool-runtime.d.ts +50 -0
- package/dist/services/delegated-tool-runtime.d.ts.map +1 -0
- package/dist/services/delegated-tool-runtime.js +120 -0
- package/dist/services/delegated-tool-runtime.js.map +1 -0
- package/dist/services/fts5.d.ts +40 -0
- package/dist/services/fts5.d.ts.map +1 -0
- package/dist/services/fts5.js +54 -0
- package/dist/services/fts5.js.map +1 -0
- package/dist/services/git-account-registry.d.ts +164 -0
- package/dist/services/git-account-registry.d.ts.map +1 -0
- package/dist/services/git-account-registry.js +297 -0
- package/dist/services/git-account-registry.js.map +1 -0
- package/dist/services/github.d.ts +49 -0
- package/dist/services/github.d.ts.map +1 -0
- package/dist/services/github.js +123 -0
- package/dist/services/github.js.map +1 -0
- package/dist/services/gmail-classifier.d.ts +62 -0
- package/dist/services/gmail-classifier.d.ts.map +1 -0
- package/dist/services/gmail-classifier.js +221 -0
- package/dist/services/gmail-classifier.js.map +1 -0
- package/dist/services/gmail.d.ts +192 -0
- package/dist/services/gmail.d.ts.map +1 -0
- package/dist/services/gmail.js +678 -0
- package/dist/services/gmail.js.map +1 -0
- package/dist/services/google-auth.d.ts +16 -0
- package/dist/services/google-auth.d.ts.map +1 -0
- package/dist/services/google-auth.js +37 -0
- package/dist/services/google-auth.js.map +1 -0
- package/dist/services/google-maps.d.ts +35 -0
- package/dist/services/google-maps.d.ts.map +1 -0
- package/dist/services/google-maps.js +82 -0
- package/dist/services/google-maps.js.map +1 -0
- package/dist/services/integrations/extract-write-item-id.d.ts +64 -0
- package/dist/services/integrations/extract-write-item-id.d.ts.map +1 -0
- package/dist/services/integrations/extract-write-item-id.js +188 -0
- package/dist/services/integrations/extract-write-item-id.js.map +1 -0
- package/dist/services/integrations/reconcile.d.ts +136 -0
- package/dist/services/integrations/reconcile.d.ts.map +1 -0
- package/dist/services/integrations/reconcile.js +218 -0
- package/dist/services/integrations/reconcile.js.map +1 -0
- package/dist/services/integrations/snapshot-partitions.d.ts +40 -0
- package/dist/services/integrations/snapshot-partitions.d.ts.map +1 -0
- package/dist/services/integrations/snapshot-partitions.js +113 -0
- package/dist/services/integrations/snapshot-partitions.js.map +1 -0
- package/dist/services/journal/render.d.ts +15 -0
- package/dist/services/journal/render.d.ts.map +1 -0
- package/dist/services/journal/render.js +17 -0
- package/dist/services/journal/render.js.map +1 -0
- package/dist/services/journal/writer.d.ts +26 -0
- package/dist/services/journal/writer.d.ts.map +1 -0
- package/dist/services/journal/writer.js +50 -0
- package/dist/services/journal/writer.js.map +1 -0
- package/dist/services/mail/account-registry.d.ts +208 -0
- package/dist/services/mail/account-registry.d.ts.map +1 -0
- package/dist/services/mail/account-registry.js +554 -0
- package/dist/services/mail/account-registry.js.map +1 -0
- package/dist/services/mail/gmail/auth-failure-classifier.d.ts +24 -0
- package/dist/services/mail/gmail/auth-failure-classifier.d.ts.map +1 -0
- package/dist/services/mail/gmail/auth-failure-classifier.js +67 -0
- package/dist/services/mail/gmail/auth-failure-classifier.js.map +1 -0
- package/dist/services/mail/gmail/gmail-provider.d.ts +58 -0
- package/dist/services/mail/gmail/gmail-provider.d.ts.map +1 -0
- package/dist/services/mail/gmail/gmail-provider.js +434 -0
- package/dist/services/mail/gmail/gmail-provider.js.map +1 -0
- package/dist/services/mail/gmail/legacy-row.d.ts +24 -0
- package/dist/services/mail/gmail/legacy-row.d.ts.map +1 -0
- package/dist/services/mail/gmail/legacy-row.js +71 -0
- package/dist/services/mail/gmail/legacy-row.js.map +1 -0
- package/dist/services/mail/gmail/poll-cursor.d.ts +12 -0
- package/dist/services/mail/gmail/poll-cursor.d.ts.map +1 -0
- package/dist/services/mail/gmail/poll-cursor.js +32 -0
- package/dist/services/mail/gmail/poll-cursor.js.map +1 -0
- package/dist/services/mail/html-to-plaintext.d.ts +27 -0
- package/dist/services/mail/html-to-plaintext.d.ts.map +1 -0
- package/dist/services/mail/html-to-plaintext.js +163 -0
- package/dist/services/mail/html-to-plaintext.js.map +1 -0
- package/dist/services/mail/imap/app-password.d.ts +27 -0
- package/dist/services/mail/imap/app-password.d.ts.map +1 -0
- package/dist/services/mail/imap/app-password.js +86 -0
- package/dist/services/mail/imap/app-password.js.map +1 -0
- package/dist/services/mail/imap/auth-failure-classifier.d.ts +21 -0
- package/dist/services/mail/imap/auth-failure-classifier.d.ts.map +1 -0
- package/dist/services/mail/imap/auth-failure-classifier.js +54 -0
- package/dist/services/mail/imap/auth-failure-classifier.js.map +1 -0
- package/dist/services/mail/imap/capabilities.d.ts +30 -0
- package/dist/services/mail/imap/capabilities.d.ts.map +1 -0
- package/dist/services/mail/imap/capabilities.js +70 -0
- package/dist/services/mail/imap/capabilities.js.map +1 -0
- package/dist/services/mail/imap/client.d.ts +15 -0
- package/dist/services/mail/imap/client.d.ts.map +1 -0
- package/dist/services/mail/imap/client.js +60 -0
- package/dist/services/mail/imap/client.js.map +1 -0
- package/dist/services/mail/imap/cursor.d.ts +19 -0
- package/dist/services/mail/imap/cursor.d.ts.map +1 -0
- package/dist/services/mail/imap/cursor.js +47 -0
- package/dist/services/mail/imap/cursor.js.map +1 -0
- package/dist/services/mail/imap/folder-resolver.d.ts +24 -0
- package/dist/services/mail/imap/folder-resolver.d.ts.map +1 -0
- package/dist/services/mail/imap/folder-resolver.js +58 -0
- package/dist/services/mail/imap/folder-resolver.js.map +1 -0
- package/dist/services/mail/imap/icloud-provider.d.ts +5 -0
- package/dist/services/mail/imap/icloud-provider.d.ts.map +1 -0
- package/dist/services/mail/imap/icloud-provider.js +5 -0
- package/dist/services/mail/imap/icloud-provider.js.map +1 -0
- package/dist/services/mail/imap/imap-provider-base.d.ts +173 -0
- package/dist/services/mail/imap/imap-provider-base.d.ts.map +1 -0
- package/dist/services/mail/imap/imap-provider-base.js +1004 -0
- package/dist/services/mail/imap/imap-provider-base.js.map +1 -0
- package/dist/services/mail/imap/query-translator.d.ts +13 -0
- package/dist/services/mail/imap/query-translator.d.ts.map +1 -0
- package/dist/services/mail/imap/query-translator.js +114 -0
- package/dist/services/mail/imap/query-translator.js.map +1 -0
- package/dist/services/mail/imap/reconcile-planner.d.ts +56 -0
- package/dist/services/mail/imap/reconcile-planner.d.ts.map +1 -0
- package/dist/services/mail/imap/reconcile-planner.js +52 -0
- package/dist/services/mail/imap/reconcile-planner.js.map +1 -0
- package/dist/services/mail/imap/reply-mime.d.ts +24 -0
- package/dist/services/mail/imap/reply-mime.d.ts.map +1 -0
- package/dist/services/mail/imap/reply-mime.js +77 -0
- package/dist/services/mail/imap/reply-mime.js.map +1 -0
- package/dist/services/mail/imap/yahoo-provider.d.ts +5 -0
- package/dist/services/mail/imap/yahoo-provider.d.ts.map +1 -0
- package/dist/services/mail/imap/yahoo-provider.js +5 -0
- package/dist/services/mail/imap/yahoo-provider.js.map +1 -0
- package/dist/services/mail/mail-search.d.ts +35 -0
- package/dist/services/mail/mail-search.d.ts.map +1 -0
- package/dist/services/mail/mail-search.js +59 -0
- package/dist/services/mail/mail-search.js.map +1 -0
- package/dist/services/mail/outlook/auth-failure-classifier.d.ts +38 -0
- package/dist/services/mail/outlook/auth-failure-classifier.d.ts.map +1 -0
- package/dist/services/mail/outlook/auth-failure-classifier.js +91 -0
- package/dist/services/mail/outlook/auth-failure-classifier.js.map +1 -0
- package/dist/services/mail/outlook/client-config.d.ts +34 -0
- package/dist/services/mail/outlook/client-config.d.ts.map +1 -0
- package/dist/services/mail/outlook/client-config.js +58 -0
- package/dist/services/mail/outlook/client-config.js.map +1 -0
- package/dist/services/mail/outlook/delta-cursor.d.ts +66 -0
- package/dist/services/mail/outlook/delta-cursor.d.ts.map +1 -0
- package/dist/services/mail/outlook/delta-cursor.js +85 -0
- package/dist/services/mail/outlook/delta-cursor.js.map +1 -0
- package/dist/services/mail/outlook/graph-client.d.ts +98 -0
- package/dist/services/mail/outlook/graph-client.d.ts.map +1 -0
- package/dist/services/mail/outlook/graph-client.js +198 -0
- package/dist/services/mail/outlook/graph-client.js.map +1 -0
- package/dist/services/mail/outlook/msal-app-factory.d.ts +20 -0
- package/dist/services/mail/outlook/msal-app-factory.d.ts.map +1 -0
- package/dist/services/mail/outlook/msal-app-factory.js +62 -0
- package/dist/services/mail/outlook/msal-app-factory.js.map +1 -0
- package/dist/services/mail/outlook/msal-cache-plugin.d.ts +19 -0
- package/dist/services/mail/outlook/msal-cache-plugin.d.ts.map +1 -0
- package/dist/services/mail/outlook/msal-cache-plugin.js +30 -0
- package/dist/services/mail/outlook/msal-cache-plugin.js.map +1 -0
- package/dist/services/mail/outlook/oauth-device-code.d.ts +26 -0
- package/dist/services/mail/outlook/oauth-device-code.d.ts.map +1 -0
- package/dist/services/mail/outlook/oauth-device-code.js +32 -0
- package/dist/services/mail/outlook/oauth-device-code.js.map +1 -0
- package/dist/services/mail/outlook/oauth-loopback.d.ts +41 -0
- package/dist/services/mail/outlook/oauth-loopback.d.ts.map +1 -0
- package/dist/services/mail/outlook/oauth-loopback.js +223 -0
- package/dist/services/mail/outlook/oauth-loopback.js.map +1 -0
- package/dist/services/mail/outlook/outlook-provider.d.ts +100 -0
- package/dist/services/mail/outlook/outlook-provider.d.ts.map +1 -0
- package/dist/services/mail/outlook/outlook-provider.js +619 -0
- package/dist/services/mail/outlook/outlook-provider.js.map +1 -0
- package/dist/services/mail/outlook/query-translator.d.ts +10 -0
- package/dist/services/mail/outlook/query-translator.d.ts.map +1 -0
- package/dist/services/mail/outlook/query-translator.js +103 -0
- package/dist/services/mail/outlook/query-translator.js.map +1 -0
- package/dist/services/mail/provider.d.ts +267 -0
- package/dist/services/mail/provider.d.ts.map +1 -0
- package/dist/services/mail/provider.js +34 -0
- package/dist/services/mail/provider.js.map +1 -0
- package/dist/services/mail/query-utils.d.ts +13 -0
- package/dist/services/mail/query-utils.d.ts.map +1 -0
- package/dist/services/mail/query-utils.js +18 -0
- package/dist/services/mail/query-utils.js.map +1 -0
- package/dist/services/mail-classifier.d.ts +25 -0
- package/dist/services/mail-classifier.d.ts.map +1 -0
- package/dist/services/mail-classifier.js +52 -0
- package/dist/services/mail-classifier.js.map +1 -0
- package/dist/services/mail-ingestion.d.ts +139 -0
- package/dist/services/mail-ingestion.d.ts.map +1 -0
- package/dist/services/mail-ingestion.js +223 -0
- package/dist/services/mail-ingestion.js.map +1 -0
- package/dist/services/mcp/auto-probe.d.ts +76 -0
- package/dist/services/mcp/auto-probe.d.ts.map +1 -0
- package/dist/services/mcp/auto-probe.js +147 -0
- package/dist/services/mcp/auto-probe.js.map +1 -0
- package/dist/services/mcp/generators/claude.d.ts +18 -0
- package/dist/services/mcp/generators/claude.d.ts.map +1 -0
- package/dist/services/mcp/generators/claude.js +90 -0
- package/dist/services/mcp/generators/claude.js.map +1 -0
- package/dist/services/mcp/generators/codex.d.ts +22 -0
- package/dist/services/mcp/generators/codex.d.ts.map +1 -0
- package/dist/services/mcp/generators/codex.js +102 -0
- package/dist/services/mcp/generators/codex.js.map +1 -0
- package/dist/services/mcp/generators/gemini.d.ts +20 -0
- package/dist/services/mcp/generators/gemini.d.ts.map +1 -0
- package/dist/services/mcp/generators/gemini.js +97 -0
- package/dist/services/mcp/generators/gemini.js.map +1 -0
- package/dist/services/mcp/generators/index.d.ts +20 -0
- package/dist/services/mcp/generators/index.d.ts.map +1 -0
- package/dist/services/mcp/generators/index.js +29 -0
- package/dist/services/mcp/generators/index.js.map +1 -0
- package/dist/services/mcp/generators/types.d.ts +47 -0
- package/dist/services/mcp/generators/types.d.ts.map +1 -0
- package/dist/services/mcp/generators/types.js +40 -0
- package/dist/services/mcp/generators/types.js.map +1 -0
- package/dist/services/mcp/probe.d.ts +31 -0
- package/dist/services/mcp/probe.d.ts.map +1 -0
- package/dist/services/mcp/probe.js +437 -0
- package/dist/services/mcp/probe.js.map +1 -0
- package/dist/services/mcp/registry.d.ts +84 -0
- package/dist/services/mcp/registry.d.ts.map +1 -0
- package/dist/services/mcp/registry.js +387 -0
- package/dist/services/mcp/registry.js.map +1 -0
- package/dist/services/mcp/risk.d.ts +82 -0
- package/dist/services/mcp/risk.d.ts.map +1 -0
- package/dist/services/mcp/risk.js +126 -0
- package/dist/services/mcp/risk.js.map +1 -0
- package/dist/services/mcp/session-materializer.d.ts +123 -0
- package/dist/services/mcp/session-materializer.d.ts.map +1 -0
- package/dist/services/mcp/session-materializer.js +361 -0
- package/dist/services/mcp/session-materializer.js.map +1 -0
- package/dist/services/mcp/tool-audit.d.ts +53 -0
- package/dist/services/mcp/tool-audit.d.ts.map +1 -0
- package/dist/services/mcp/tool-audit.js +74 -0
- package/dist/services/mcp/tool-audit.js.map +1 -0
- package/dist/services/mcp/types.d.ts +88 -0
- package/dist/services/mcp/types.d.ts.map +1 -0
- package/dist/services/mcp/types.js +94 -0
- package/dist/services/mcp/types.js.map +1 -0
- package/dist/services/notion.d.ts +134 -0
- package/dist/services/notion.d.ts.map +1 -0
- package/dist/services/notion.js +350 -0
- package/dist/services/notion.js.map +1 -0
- package/dist/services/obsidian.d.ts +116 -0
- package/dist/services/obsidian.d.ts.map +1 -0
- package/dist/services/obsidian.js +305 -0
- package/dist/services/obsidian.js.map +1 -0
- package/dist/services/service-registry.d.ts +31 -0
- package/dist/services/service-registry.d.ts.map +1 -0
- package/dist/services/service-registry.js +15 -0
- package/dist/services/service-registry.js.map +1 -0
- package/dist/services/voice/transcriber-impl.d.ts +15 -0
- package/dist/services/voice/transcriber-impl.d.ts.map +1 -0
- package/dist/services/voice/transcriber-impl.js +129 -0
- package/dist/services/voice/transcriber-impl.js.map +1 -0
- package/dist/services/voice/transcriber.d.ts +117 -0
- package/dist/services/voice/transcriber.d.ts.map +1 -0
- package/dist/services/voice/transcriber.js +201 -0
- package/dist/services/voice/transcriber.js.map +1 -0
- package/dist/settings/runtime-settings.d.ts +232 -0
- package/dist/settings/runtime-settings.d.ts.map +1 -0
- package/dist/settings/runtime-settings.js +769 -0
- package/dist/settings/runtime-settings.js.map +1 -0
- package/dist/settings/settings-store.d.ts +13 -0
- package/dist/settings/settings-store.d.ts.map +1 -0
- package/dist/settings/settings-store.js +87 -0
- package/dist/settings/settings-store.js.map +1 -0
- package/package.json +85 -0
|
@@ -0,0 +1,2372 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
import { filterDeniedToolsForBackend, getAgentDayDateStr, } from "@aitne/shared";
|
|
5
|
+
import { createLogger } from "../logging.js";
|
|
6
|
+
import { DelegatedProxyTimeoutError, DelegatedToolUnsupportedError, } from "../core/agent-core.js";
|
|
7
|
+
import { readIntegrations } from "../db/integrations-store.js";
|
|
8
|
+
import { proxyModelIsKnown, resolveCanonicalDelegatedModel, resolveProcessKeyModel, } from "../core/backends/proxy-model-registry.js";
|
|
9
|
+
import { DELEGATED_PROXY_DEFAULTS } from "./delegated-proxy-config.js";
|
|
10
|
+
import { buildRetryFollowup, buildTaskPrompt, classifyStructuredOutput, compileSchema, detectConfirmationEnvelope, detectErrorEnvelope, extractAndValidateResult, hashTaskArgs, resolveAllowedToolPatterns, resolveDestructiveToolPatterns, resolveRunWriteClassToolPatterns, resolveWriteClassToolPatterns, wrapSchemaForStructuredOutput, } from "./delegated-task-runtime.js";
|
|
11
|
+
import { DelegatedTaskResultCache, execScope, integrationVersionFor, runScope, } from "./delegated-task-result-cache.js";
|
|
12
|
+
import { DelegatedTaskSessionPool, SESSION_POOL_TEMPDIR_PREFIX, } from "./delegated-task-session-pool.js";
|
|
13
|
+
import { readRuntimeState, writeRuntimeState, } from "../db/runtime-state.js";
|
|
14
|
+
const logger = createLogger("delegated-proxy-invoker");
|
|
15
|
+
export class DelegatedBackendInvoker {
|
|
16
|
+
deps;
|
|
17
|
+
defaults;
|
|
18
|
+
now;
|
|
19
|
+
/** Inflight permit count (acquired from `maxConcurrent`). */
|
|
20
|
+
inflight = 0;
|
|
21
|
+
/** FIFO waiters parked when `inflight === maxConcurrent`. */
|
|
22
|
+
waiters = [];
|
|
23
|
+
/**
|
|
24
|
+
* DELEGATED-TASK-MODE-DESIGN.md §13 Phase 3.3 — result cache.
|
|
25
|
+
* Constructed lazily on first task() / run() so a daemon that never
|
|
26
|
+
* fires task mode does not hold the LRU map. `null` until the first
|
|
27
|
+
* call observes `delegatedTaskCacheEnabled === true`.
|
|
28
|
+
*/
|
|
29
|
+
resultCache = null;
|
|
30
|
+
/**
|
|
31
|
+
* §13 Phase 3.2 — session-dir pool. Lazy-constructed for the same
|
|
32
|
+
* reason as `resultCache`. Pool is per-invoker so concurrent task
|
|
33
|
+
* runs see a coherent set of idle entries.
|
|
34
|
+
*/
|
|
35
|
+
sessionPool = null;
|
|
36
|
+
constructor(deps) {
|
|
37
|
+
this.deps = deps;
|
|
38
|
+
this.defaults = { ...DELEGATED_PROXY_DEFAULTS, ...(deps.defaults ?? {}) };
|
|
39
|
+
this.now = deps.now ?? Date.now;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* §13 Phase 3.3 — return the cache, instantiating it if missing or
|
|
43
|
+
* recreating it when the live config has flipped TTL or capacity.
|
|
44
|
+
* Returns null when caching is disabled, in which case callers MUST
|
|
45
|
+
* skip every cache code path (no insertions either, otherwise an
|
|
46
|
+
* emergency disable would still serve from a stale local map).
|
|
47
|
+
*/
|
|
48
|
+
getResultCache() {
|
|
49
|
+
if (!this.deps.config.delegatedTaskCacheEnabled) {
|
|
50
|
+
if (this.resultCache) {
|
|
51
|
+
// Killing the cache mid-window: drop entries so they don't
|
|
52
|
+
// resurface if the flag flips back on.
|
|
53
|
+
this.resultCache.clear();
|
|
54
|
+
this.resultCache = null;
|
|
55
|
+
}
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const ttlMs = Math.max(1, this.deps.config.delegatedTaskCacheTtlSeconds) * 1000;
|
|
59
|
+
const maxEntries = Math.max(1, this.deps.config.delegatedTaskCacheMaxEntries);
|
|
60
|
+
if (!this.resultCache
|
|
61
|
+
|| this.resultCache.stats().ttlMs !== ttlMs
|
|
62
|
+
|| this.resultCache.stats().maxEntries !== maxEntries) {
|
|
63
|
+
this.resultCache = new DelegatedTaskResultCache({
|
|
64
|
+
ttlMs,
|
|
65
|
+
maxEntries,
|
|
66
|
+
now: this.now,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return this.resultCache;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* §13 Phase 3.2 — return the pool, instantiating if missing. Returns
|
|
73
|
+
* null when the kill switch is off; the caller falls through to the
|
|
74
|
+
* legacy `makeTempdir` + `cleanupTempdir` path.
|
|
75
|
+
*/
|
|
76
|
+
getSessionPool() {
|
|
77
|
+
if (!this.deps.config.delegatedTaskSubprocessPoolEnabled) {
|
|
78
|
+
if (this.sessionPool) {
|
|
79
|
+
// Killing the pool mid-window: rm idle dirs so we don't strand
|
|
80
|
+
// them past the disable.
|
|
81
|
+
this.sessionPool.evictAll();
|
|
82
|
+
this.sessionPool = null;
|
|
83
|
+
}
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const ttlMs = Math.max(1, this.deps.config.delegatedTaskSubprocessPoolTtlSeconds)
|
|
87
|
+
* 1000;
|
|
88
|
+
const maxIdle = this.maxConcurrent;
|
|
89
|
+
if (!this.sessionPool
|
|
90
|
+
|| this.sessionPool.stats().ttlMs !== ttlMs
|
|
91
|
+
|| this.sessionPool.stats().maxIdle !== maxIdle) {
|
|
92
|
+
// Pool config changed — drop the old one so its dirs get rm'd
|
|
93
|
+
// before we start handing out new leases under the new shape.
|
|
94
|
+
this.sessionPool?.evictAll();
|
|
95
|
+
this.sessionPool = new DelegatedTaskSessionPool({
|
|
96
|
+
ttlMs,
|
|
97
|
+
maxIdle,
|
|
98
|
+
materializer: (sessionDir, backendId) => this.materializeProxySession(sessionDir, backendId),
|
|
99
|
+
tempdirPrefix: SESSION_POOL_TEMPDIR_PREFIX,
|
|
100
|
+
sessionsRoot: this.sessionsRoot(),
|
|
101
|
+
now: this.now,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
return this.sessionPool;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* §13 Phase 3.2 — release-or-create wrapper. Returns either a pool
|
|
108
|
+
* lease (when pooling is on) or a one-shot synthetic lease (when
|
|
109
|
+
* pooling is off — preserves the legacy makeTempdir + cleanupTempdir
|
|
110
|
+
* flow). Either way the caller follows the lease's release/discard
|
|
111
|
+
* lifecycle.
|
|
112
|
+
*
|
|
113
|
+
* The legacy synthetic lease wraps `makeTempdir()` + the existing
|
|
114
|
+
* janitor cleanup so the rest of the task() / run() body doesn't have
|
|
115
|
+
* to branch on pooling state.
|
|
116
|
+
*/
|
|
117
|
+
acquireSessionDir(args) {
|
|
118
|
+
const pool = this.getSessionPool();
|
|
119
|
+
if (pool) {
|
|
120
|
+
return pool.acquire({
|
|
121
|
+
backendId: args.backendId,
|
|
122
|
+
integrationKey: args.integrationKey,
|
|
123
|
+
modelId: args.modelId,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
const sessionDir = this.makeTempdir();
|
|
127
|
+
try {
|
|
128
|
+
this.materializeProxySession(sessionDir, args.backendId);
|
|
129
|
+
}
|
|
130
|
+
catch (err) {
|
|
131
|
+
try {
|
|
132
|
+
rmSync(sessionDir, { recursive: true, force: true });
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
/* ignore */
|
|
136
|
+
}
|
|
137
|
+
throw err;
|
|
138
|
+
}
|
|
139
|
+
return new LegacyOneShotLease(sessionDir, () => this.cleanupTempdir(sessionDir));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Effective concurrency cap — read live so a runtime PATCH /api/config
|
|
143
|
+
* (Phase C5) takes effect on the next call without a daemon restart.
|
|
144
|
+
*/
|
|
145
|
+
get maxConcurrent() {
|
|
146
|
+
const cfg = this.deps.config.delegatedProxyMaxConcurrent;
|
|
147
|
+
return typeof cfg === "number" && cfg > 0
|
|
148
|
+
? cfg
|
|
149
|
+
: this.defaults.defaultMaxConcurrent;
|
|
150
|
+
}
|
|
151
|
+
/** Visibility for tests + future /health.metrics.delegatedProxy facet. */
|
|
152
|
+
get queueDepth() {
|
|
153
|
+
return this.waiters.length;
|
|
154
|
+
}
|
|
155
|
+
get inflightCount() {
|
|
156
|
+
return this.inflight;
|
|
157
|
+
}
|
|
158
|
+
async invoke(params) {
|
|
159
|
+
// Pre-permit fast path. Avoid spending one of the (default 4) permits —
|
|
160
|
+
// and a potential 60s queue wait — on a request that is obviously
|
|
161
|
+
// invalid right now. No `agent_actions` row is written: the request
|
|
162
|
+
// never held a slot, never spawned, never blocked anyone.
|
|
163
|
+
const fastCheck = this.resolvePreconditions(params.integrationKey, params.modelOverride);
|
|
164
|
+
if (!fastCheck.ok) {
|
|
165
|
+
return {
|
|
166
|
+
ok: false,
|
|
167
|
+
errorClass: "precondition",
|
|
168
|
+
message: fastCheck.message,
|
|
169
|
+
...(fastCheck.backendId ? { backendId: fastCheck.backendId } : {}),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const acquired = await this.acquirePermit();
|
|
173
|
+
if (!acquired.ok) {
|
|
174
|
+
// Queue saturation — surfaces as 503 in the route handler. Don't
|
|
175
|
+
// create a tempdir, don't materialize anything. Cost row is still
|
|
176
|
+
// written (zero-cost) so the dashboard sees a saturation event.
|
|
177
|
+
this.recordAction({
|
|
178
|
+
backendId: fastCheck.backendId,
|
|
179
|
+
modelId: fastCheck.modelId,
|
|
180
|
+
params,
|
|
181
|
+
result: "failed",
|
|
182
|
+
errorClass: "delegated_proxy_busy",
|
|
183
|
+
cost: zeroCost(),
|
|
184
|
+
startedAt: new Date(this.now()).toISOString(),
|
|
185
|
+
completedAt: new Date(this.now()).toISOString(),
|
|
186
|
+
errorMessage: acquired.message,
|
|
187
|
+
});
|
|
188
|
+
return {
|
|
189
|
+
ok: false,
|
|
190
|
+
errorClass: "delegated_proxy_busy",
|
|
191
|
+
message: acquired.message,
|
|
192
|
+
backendId: fastCheck.backendId,
|
|
193
|
+
modelId: fastCheck.modelId,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
// Post-permit re-check. Integration state may have been flipped (mode,
|
|
197
|
+
// delegatedBackend, or delegatedModel) while this request waited up to
|
|
198
|
+
// 60s in the FIFO queue. Running with stale state would materialize the
|
|
199
|
+
// wrong instruction file (e.g. CLAUDE.md against a freshly-switched
|
|
200
|
+
// codex backend) or invoke a core the user just unregistered. We DO
|
|
201
|
+
// record this row — unlike the pre-permit path it consumed a slot and
|
|
202
|
+
// blocked others, so the dashboard should surface the queue waste.
|
|
203
|
+
const liveCheck = this.resolvePreconditions(params.integrationKey, params.modelOverride);
|
|
204
|
+
if (!liveCheck.ok) {
|
|
205
|
+
this.releasePermit();
|
|
206
|
+
const nowIso = new Date(this.now()).toISOString();
|
|
207
|
+
const message = `integration state changed during queue wait: ${liveCheck.message}`;
|
|
208
|
+
this.recordAction({
|
|
209
|
+
backendId: liveCheck.backendId ?? fastCheck.backendId,
|
|
210
|
+
modelId: fastCheck.modelId,
|
|
211
|
+
params,
|
|
212
|
+
result: "failed",
|
|
213
|
+
errorClass: "precondition",
|
|
214
|
+
cost: zeroCost(),
|
|
215
|
+
startedAt: nowIso,
|
|
216
|
+
completedAt: nowIso,
|
|
217
|
+
errorMessage: message,
|
|
218
|
+
});
|
|
219
|
+
return {
|
|
220
|
+
ok: false,
|
|
221
|
+
errorClass: "precondition",
|
|
222
|
+
message,
|
|
223
|
+
backendId: liveCheck.backendId ?? fastCheck.backendId,
|
|
224
|
+
modelId: fastCheck.modelId,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const { state, backendId, core, modelId } = liveCheck;
|
|
228
|
+
const maxTurns = this.resolveMaxTurns(state);
|
|
229
|
+
const sessionDir = this.makeTempdir();
|
|
230
|
+
const startMs = this.now();
|
|
231
|
+
const startedAtIso = new Date(startMs).toISOString();
|
|
232
|
+
let toolResult = null;
|
|
233
|
+
let unimplemented = false;
|
|
234
|
+
let unhandledMessage = null;
|
|
235
|
+
// Default-classify any unhandled exception as a subprocess crash; the
|
|
236
|
+
// wall-clock timeout callback flips this to "timeout" before aborting
|
|
237
|
+
// so the route handler can map to 504 (vs 502/500). Distinct enums
|
|
238
|
+
// also keep failure-rate metrics honest.
|
|
239
|
+
let unhandledClass = "subprocess_crashed";
|
|
240
|
+
try {
|
|
241
|
+
this.materializeProxySession(sessionDir, backendId);
|
|
242
|
+
// Build the abort plumbing — combine caller's signal with our own
|
|
243
|
+
// wall-clock timeout so the core sees one signal. Backend-specific
|
|
244
|
+
// overrides (see `callTimeoutMsByBackend` in delegated-proxy-config.ts)
|
|
245
|
+
// win when present so gemini's slower CLI cold-start gets headroom.
|
|
246
|
+
const ac = new AbortController();
|
|
247
|
+
const callTimeoutMs = this.defaults.callTimeoutMsByBackend[backendId]
|
|
248
|
+
?? this.defaults.callTimeoutMs;
|
|
249
|
+
const timeout = setTimeout(() => {
|
|
250
|
+
unhandledClass = "timeout";
|
|
251
|
+
ac.abort(new DelegatedProxyTimeoutError());
|
|
252
|
+
}, callTimeoutMs);
|
|
253
|
+
timeout.unref?.();
|
|
254
|
+
const callerListener = () => ac.abort(params.abortSignal?.reason);
|
|
255
|
+
if (params.abortSignal) {
|
|
256
|
+
if (params.abortSignal.aborted) {
|
|
257
|
+
ac.abort(params.abortSignal.reason);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
params.abortSignal.addEventListener("abort", callerListener, {
|
|
261
|
+
once: true,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
toolResult = await core.runDelegatedTool({
|
|
267
|
+
integrationKey: params.integrationKey,
|
|
268
|
+
toolName: params.toolName,
|
|
269
|
+
toolArgs: params.toolArgs,
|
|
270
|
+
modelId,
|
|
271
|
+
maxTurns,
|
|
272
|
+
maxBudgetUsd: this.defaults.maxBudgetUsd,
|
|
273
|
+
sessionDir,
|
|
274
|
+
abortSignal: ac.signal,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
catch (err) {
|
|
278
|
+
if (err instanceof DelegatedToolUnsupportedError) {
|
|
279
|
+
unimplemented = true;
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
unhandledMessage =
|
|
283
|
+
err instanceof Error ? err.message : String(err);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
finally {
|
|
287
|
+
clearTimeout(timeout);
|
|
288
|
+
params.abortSignal?.removeEventListener("abort", callerListener);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
finally {
|
|
292
|
+
this.cleanupTempdir(sessionDir);
|
|
293
|
+
this.releasePermit();
|
|
294
|
+
}
|
|
295
|
+
const completedAtIso = new Date(this.now()).toISOString();
|
|
296
|
+
if (unimplemented) {
|
|
297
|
+
this.recordAction({
|
|
298
|
+
backendId,
|
|
299
|
+
modelId,
|
|
300
|
+
params,
|
|
301
|
+
result: "failed",
|
|
302
|
+
errorClass: "unimplemented",
|
|
303
|
+
cost: zeroCost(),
|
|
304
|
+
startedAt: startedAtIso,
|
|
305
|
+
completedAt: completedAtIso,
|
|
306
|
+
errorMessage: "runDelegatedTool not implemented on this backend (Phase A stub)",
|
|
307
|
+
});
|
|
308
|
+
return {
|
|
309
|
+
ok: false,
|
|
310
|
+
errorClass: "unimplemented",
|
|
311
|
+
message: "delegated proxy backend has not been wired yet — Phase B will land per-backend stream extraction",
|
|
312
|
+
backendId,
|
|
313
|
+
modelId,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
if (unhandledMessage !== null) {
|
|
317
|
+
this.recordAction({
|
|
318
|
+
backendId,
|
|
319
|
+
modelId,
|
|
320
|
+
params,
|
|
321
|
+
result: "failed",
|
|
322
|
+
errorClass: unhandledClass,
|
|
323
|
+
cost: zeroCost(),
|
|
324
|
+
startedAt: startedAtIso,
|
|
325
|
+
completedAt: completedAtIso,
|
|
326
|
+
errorMessage: unhandledMessage,
|
|
327
|
+
});
|
|
328
|
+
return {
|
|
329
|
+
ok: false,
|
|
330
|
+
errorClass: unhandledClass,
|
|
331
|
+
message: unhandledMessage,
|
|
332
|
+
backendId,
|
|
333
|
+
modelId,
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
if (!toolResult) {
|
|
337
|
+
// Defensive: should not happen unless runDelegatedTool resolved with
|
|
338
|
+
// null/undefined, which violates the contract.
|
|
339
|
+
this.recordAction({
|
|
340
|
+
backendId,
|
|
341
|
+
modelId,
|
|
342
|
+
params,
|
|
343
|
+
result: "failed",
|
|
344
|
+
errorClass: "parse_error",
|
|
345
|
+
cost: zeroCost(),
|
|
346
|
+
startedAt: startedAtIso,
|
|
347
|
+
completedAt: completedAtIso,
|
|
348
|
+
errorMessage: "core returned null DelegatedToolResult",
|
|
349
|
+
});
|
|
350
|
+
return {
|
|
351
|
+
ok: false,
|
|
352
|
+
errorClass: "parse_error",
|
|
353
|
+
message: "delegated proxy core returned null",
|
|
354
|
+
backendId,
|
|
355
|
+
modelId,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (toolResult.ok) {
|
|
359
|
+
this.recordAction({
|
|
360
|
+
backendId,
|
|
361
|
+
modelId,
|
|
362
|
+
params,
|
|
363
|
+
result: "success",
|
|
364
|
+
cost: toolResult.cost,
|
|
365
|
+
startedAt: startedAtIso,
|
|
366
|
+
completedAt: completedAtIso,
|
|
367
|
+
});
|
|
368
|
+
return {
|
|
369
|
+
ok: true,
|
|
370
|
+
toolResult: toolResult.toolResult,
|
|
371
|
+
cost: toolResult.cost,
|
|
372
|
+
backendId,
|
|
373
|
+
modelId,
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
this.recordAction({
|
|
377
|
+
backendId,
|
|
378
|
+
modelId,
|
|
379
|
+
params,
|
|
380
|
+
result: "failed",
|
|
381
|
+
errorClass: toolResult.errorClass,
|
|
382
|
+
cost: toolResult.cost,
|
|
383
|
+
startedAt: startedAtIso,
|
|
384
|
+
completedAt: completedAtIso,
|
|
385
|
+
errorMessage: toolResult.message,
|
|
386
|
+
});
|
|
387
|
+
return {
|
|
388
|
+
ok: false,
|
|
389
|
+
errorClass: toolResult.errorClass,
|
|
390
|
+
message: toolResult.message,
|
|
391
|
+
cost: toolResult.cost,
|
|
392
|
+
backendId,
|
|
393
|
+
modelId,
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
// ── Preconditions ───────────────────────────────────────────────────────
|
|
397
|
+
/**
|
|
398
|
+
* Resolve the live integration state to a backend + core + model. Called
|
|
399
|
+
* twice per invocation: once before acquiring a permit (fast-fail without
|
|
400
|
+
* spending a slot) and again after the permit (defends against the user
|
|
401
|
+
* flipping mode/backend during a 60s queue wait — the post-permit re-check
|
|
402
|
+
* is the only place we'd notice).
|
|
403
|
+
*/
|
|
404
|
+
resolvePreconditions(integrationKey, modelOverride) {
|
|
405
|
+
const state = readIntegrations(this.deps.db)[integrationKey];
|
|
406
|
+
if (!state || state.mode !== "delegated" || !state.delegatedBackend) {
|
|
407
|
+
return {
|
|
408
|
+
ok: false,
|
|
409
|
+
message: `integration '${integrationKey}' is not in delegated mode (mode=${state?.mode ?? "missing"}, delegatedBackend=${state?.delegatedBackend ?? "null"})`,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
const backendId = state.delegatedBackend;
|
|
413
|
+
const core = this.deps.cores[backendId];
|
|
414
|
+
if (!core) {
|
|
415
|
+
return {
|
|
416
|
+
ok: false,
|
|
417
|
+
message: `no agent core registered for backend '${backendId}'`,
|
|
418
|
+
backendId,
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
const modelId = this.resolveModel(state, integrationKey, backendId, modelOverride);
|
|
422
|
+
return { ok: true, state, backendId, core, modelId };
|
|
423
|
+
}
|
|
424
|
+
// ── Concurrency primitives ──────────────────────────────────────────────
|
|
425
|
+
async acquirePermit() {
|
|
426
|
+
if (this.inflight < this.maxConcurrent) {
|
|
427
|
+
this.inflight++;
|
|
428
|
+
return { ok: true };
|
|
429
|
+
}
|
|
430
|
+
return new Promise((resolve) => {
|
|
431
|
+
const waiter = {
|
|
432
|
+
// Resolved by `releasePermit` when this waiter is at the head.
|
|
433
|
+
// Must INCREMENT inflight at resolve time (not queue time) so that
|
|
434
|
+
// concurrent acquires don't all see the same low inflight count.
|
|
435
|
+
wake: () => {
|
|
436
|
+
if (waiter.settled)
|
|
437
|
+
return;
|
|
438
|
+
waiter.settled = true;
|
|
439
|
+
clearTimeout(waiter.timer);
|
|
440
|
+
this.inflight++;
|
|
441
|
+
resolve({ ok: true });
|
|
442
|
+
},
|
|
443
|
+
timer: setTimeout(() => {
|
|
444
|
+
if (waiter.settled)
|
|
445
|
+
return;
|
|
446
|
+
waiter.settled = true;
|
|
447
|
+
// Remove from queue so releasePermit doesn't try to wake us.
|
|
448
|
+
const idx = this.waiters.indexOf(waiter);
|
|
449
|
+
if (idx >= 0)
|
|
450
|
+
this.waiters.splice(idx, 1);
|
|
451
|
+
resolve({
|
|
452
|
+
ok: false,
|
|
453
|
+
message: `delegated proxy queue wait exceeded ${this.defaults.queueWaitTimeoutMs}ms`,
|
|
454
|
+
});
|
|
455
|
+
}, this.defaults.queueWaitTimeoutMs),
|
|
456
|
+
settled: false,
|
|
457
|
+
};
|
|
458
|
+
waiter.timer.unref?.();
|
|
459
|
+
this.waiters.push(waiter);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
releasePermit() {
|
|
463
|
+
this.inflight--;
|
|
464
|
+
// Wake the head of the FIFO queue if any. The wake() handler
|
|
465
|
+
// re-increments inflight, so the net change is zero.
|
|
466
|
+
while (this.waiters.length > 0) {
|
|
467
|
+
const next = this.waiters.shift();
|
|
468
|
+
if (!next.settled) {
|
|
469
|
+
next.wake();
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
// ── Tempdir + materialization ───────────────────────────────────────────
|
|
475
|
+
/**
|
|
476
|
+
* Path layout matches existing event sessions for filesystem locality —
|
|
477
|
+
* the DELEGATED-PROXY design says "same root as existing event-driven
|
|
478
|
+
* sessions" (§4.4); the actual root in this codebase is `agent-sessions/`.
|
|
479
|
+
*/
|
|
480
|
+
sessionsRoot() {
|
|
481
|
+
return join(this.deps.config.dataDir, "agent-sessions");
|
|
482
|
+
}
|
|
483
|
+
makeTempdir() {
|
|
484
|
+
const dir = join(this.sessionsRoot(), `${this.defaults.tempdirPrefix}${randomUUID()}`);
|
|
485
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
486
|
+
return dir;
|
|
487
|
+
}
|
|
488
|
+
cleanupTempdir(sessionDir) {
|
|
489
|
+
try {
|
|
490
|
+
rmSync(sessionDir, { recursive: true, force: true });
|
|
491
|
+
}
|
|
492
|
+
catch (err) {
|
|
493
|
+
logger.warn({ err, sessionDir }, "proxy tempdir cleanup failed");
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Materialize the minimal proxy session: just the proxy profile rendered
|
|
498
|
+
* into the backend-specific instruction file (CLAUDE.md / AGENTS.md /
|
|
499
|
+
* GEMINI.md). No skills, no MCP config, no character block — the proxy
|
|
500
|
+
* profile itself is the entire instruction. Per-backend tool-listing
|
|
501
|
+
* for the connector is the core's responsibility (it knows its native
|
|
502
|
+
* MCP namespace).
|
|
503
|
+
*/
|
|
504
|
+
materializeProxySession(sessionDir, backendId) {
|
|
505
|
+
const profilePath = join(this.deps.config.workspaceDir, "agent-assets", "agent-profiles", "proxy.md");
|
|
506
|
+
let body;
|
|
507
|
+
try {
|
|
508
|
+
body = readFileSyncIfExists(profilePath)
|
|
509
|
+
?? FALLBACK_PROXY_PROFILE;
|
|
510
|
+
}
|
|
511
|
+
catch {
|
|
512
|
+
body = FALLBACK_PROXY_PROFILE;
|
|
513
|
+
}
|
|
514
|
+
const filename = backendId === "claude" ? "CLAUDE.md"
|
|
515
|
+
: backendId === "codex" ? "AGENTS.md"
|
|
516
|
+
: "GEMINI.md";
|
|
517
|
+
const target = join(sessionDir, filename);
|
|
518
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
519
|
+
writeFileSync(target, body, "utf-8");
|
|
520
|
+
}
|
|
521
|
+
// ── Cost / agent_actions persistence ────────────────────────────────────
|
|
522
|
+
recordAction(args) {
|
|
523
|
+
const detail = {
|
|
524
|
+
integrationKey: args.params.integrationKey,
|
|
525
|
+
toolName: args.params.toolName,
|
|
526
|
+
toolArgsHash: hashArgs(args.params.toolArgs),
|
|
527
|
+
...(args.errorClass ? { errorClass: args.errorClass } : {}),
|
|
528
|
+
};
|
|
529
|
+
try {
|
|
530
|
+
this.deps.db
|
|
531
|
+
.prepare(
|
|
532
|
+
// datetime(@started_at) coerces ISO-8601 input into SQLite's
|
|
533
|
+
// canonical 'YYYY-MM-DD HH:MM:SS' so this row sorts correctly
|
|
534
|
+
// alongside rows written via datetime('now') elsewhere — without
|
|
535
|
+
// it, mixed formats break ORDER BY started_at.
|
|
536
|
+
`INSERT INTO agent_actions (
|
|
537
|
+
event_id, action_type, trigger, model_used,
|
|
538
|
+
cost_usd, tokens_input, tokens_output,
|
|
539
|
+
cache_creation_tokens, cache_read_tokens,
|
|
540
|
+
duration_ms, num_turns, result, detail,
|
|
541
|
+
started_at, completed_at, error, backend, cost_source
|
|
542
|
+
) VALUES (
|
|
543
|
+
@event_id, 'delegated_proxy.invoke', @trigger, @model_used,
|
|
544
|
+
@cost_usd, @tokens_input, @tokens_output,
|
|
545
|
+
@cache_creation_tokens, @cache_read_tokens,
|
|
546
|
+
@duration_ms, @num_turns, @result, @detail,
|
|
547
|
+
datetime(@started_at), datetime(@completed_at), @error, @backend, 'sdk'
|
|
548
|
+
)`)
|
|
549
|
+
.run({
|
|
550
|
+
event_id: args.params.parentEventId ?? null,
|
|
551
|
+
trigger: args.params.parentProcessKey ?? null,
|
|
552
|
+
model_used: args.modelId,
|
|
553
|
+
cost_usd: args.cost.costUsd,
|
|
554
|
+
tokens_input: args.cost.tokensInput,
|
|
555
|
+
tokens_output: args.cost.tokensOutput,
|
|
556
|
+
cache_creation_tokens: args.cost.cacheCreationTokens,
|
|
557
|
+
cache_read_tokens: args.cost.cacheReadTokens,
|
|
558
|
+
duration_ms: args.cost.durationMs,
|
|
559
|
+
num_turns: args.cost.numTurns,
|
|
560
|
+
result: args.result,
|
|
561
|
+
detail: JSON.stringify(detail),
|
|
562
|
+
started_at: args.startedAt,
|
|
563
|
+
completed_at: args.completedAt,
|
|
564
|
+
error: args.errorMessage ?? null,
|
|
565
|
+
backend: args.backendId,
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
catch (err) {
|
|
569
|
+
logger.error({ err, integrationKey: args.params.integrationKey }, "failed to record delegated_proxy.invoke action");
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
// ── Model resolution ────────────────────────────────────────────────────
|
|
573
|
+
resolveModel(state, integrationKey, backendId, modelOverride) {
|
|
574
|
+
// Caller-side override (cadence path passes medium tier — see
|
|
575
|
+
// `delegated-sync-worker.ts`). Wins above the user pin so an operator
|
|
576
|
+
// who pinned Haiku for synchronous skill calls does not also force the
|
|
577
|
+
// cadence onto Haiku. Falls through to the standard cascade if the
|
|
578
|
+
// override is not registered for this backend (e.g. operator hand-edited
|
|
579
|
+
// an unknown model id).
|
|
580
|
+
if (modelOverride
|
|
581
|
+
&& proxyModelIsKnown(this.deps.db, backendId, modelOverride)) {
|
|
582
|
+
return modelOverride;
|
|
583
|
+
}
|
|
584
|
+
if (this.deps.resolveProxyModel) {
|
|
585
|
+
return this.deps.resolveProxyModel(integrationKey, backendId);
|
|
586
|
+
}
|
|
587
|
+
// DELEGATED-PROXY-API-DESIGN.md §4.2 — user pin wins iff still
|
|
588
|
+
// resolvable for the current backend. After a `delegatedBackend`
|
|
589
|
+
// swap a leftover Claude model id silently falls through to the
|
|
590
|
+
// canonical light-tier pick; the dashboard surfaces the staleness
|
|
591
|
+
// with a "Reset to default" affordance.
|
|
592
|
+
const pinned = state.delegatedModel ?? null;
|
|
593
|
+
if (pinned && proxyModelIsKnown(this.deps.db, backendId, pinned)) {
|
|
594
|
+
return pinned;
|
|
595
|
+
}
|
|
596
|
+
const canonical = resolveCanonicalDelegatedModel(backendId, this.deps.db);
|
|
597
|
+
if (canonical)
|
|
598
|
+
return canonical;
|
|
599
|
+
// Registry has no lite-tier entry for this backend — fall back to the
|
|
600
|
+
// first model the live core advertises. Keeps the proxy callable when
|
|
601
|
+
// a backend's model registry is mid-redaction (e.g. a deprecated-only
|
|
602
|
+
// listing during a model rotation).
|
|
603
|
+
const core = this.deps.cores[backendId];
|
|
604
|
+
const models = core?.listModels?.() ?? [];
|
|
605
|
+
if (models.length > 0) {
|
|
606
|
+
const lite = models.find((m) => m.tier === "lite");
|
|
607
|
+
return (lite ?? models[0]).modelId;
|
|
608
|
+
}
|
|
609
|
+
return "auto";
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Per-call maxTurns. Reads `state.delegatedMaxTurns` when set, otherwise
|
|
613
|
+
* the registry default (DELEGATED_PROXY_DEFAULTS.maxTurns = 2).
|
|
614
|
+
*
|
|
615
|
+
* v0.1 surfaces no dashboard UI for `delegatedMaxTurns` (DELEGATED-PROXY-
|
|
616
|
+
* API-DESIGN.md §4.2 / §13 Q3) but the daemon writes the integrations
|
|
617
|
+
* blob to `~/.personal-agent/integrations.md` for hand-edit, so a user
|
|
618
|
+
* who needs more turns for a connector that does a tool-list lookup
|
|
619
|
+
* before the call (e.g. `list_labels` then `apply_labels`) can edit the
|
|
620
|
+
* file and have it respected without waiting for UI to land.
|
|
621
|
+
*
|
|
622
|
+
* Schema bound is 1..10; defensively clamp here in case a hand-edit
|
|
623
|
+
* slipped through (the schema runs in withDefaults, but a future zod
|
|
624
|
+
* relaxation shouldn't silently let an unbounded value through to the
|
|
625
|
+
* subprocess core).
|
|
626
|
+
*/
|
|
627
|
+
resolveMaxTurns(state) {
|
|
628
|
+
const pinned = state.delegatedMaxTurns;
|
|
629
|
+
if (typeof pinned !== "number" || !Number.isFinite(pinned)) {
|
|
630
|
+
return this.defaults.maxTurns;
|
|
631
|
+
}
|
|
632
|
+
if (pinned < 1)
|
|
633
|
+
return 1;
|
|
634
|
+
if (pinned > 10)
|
|
635
|
+
return 10;
|
|
636
|
+
return Math.floor(pinned);
|
|
637
|
+
}
|
|
638
|
+
// ── Task mode ─────────────────────────────────────────────────────────────
|
|
639
|
+
/**
|
|
640
|
+
* DELEGATED-TASK-MODE-DESIGN.md §4.1 — task-mode chokepoint. Mirrors
|
|
641
|
+
* `invoke()`'s lifecycle (preconditions → permit → spawn → audit) but:
|
|
642
|
+
* - resolves model + allowed tools via the runtime helpers
|
|
643
|
+
* - writes a `delegated_task.exec` header row BEFORE spawning so step
|
|
644
|
+
* rows can FK back to its `id`
|
|
645
|
+
* - applies the §6.2 single-retry rule (only when no destructive /
|
|
646
|
+
* write-class tool ran)
|
|
647
|
+
* - returns a structured envelope (result OR confirmation OR error)
|
|
648
|
+
*/
|
|
649
|
+
async task(params) {
|
|
650
|
+
if (!this.deps.config.delegatedTaskModeEnabled) {
|
|
651
|
+
return {
|
|
652
|
+
ok: false,
|
|
653
|
+
errorClass: "task_mode_disabled",
|
|
654
|
+
message: "Task mode is currently disabled (config.delegatedTaskModeEnabled=false). Re-enable via PATCH /api/config { delegatedTaskModeEnabled: true }, or flip an integration to delegated to auto-enable.",
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
// Daily quota check — pre-permit so a 429 doesn't burn a slot.
|
|
658
|
+
const today = getAgentDayDateStr(this.deps.config.timezone, this.deps.config.dayBoundaryHour);
|
|
659
|
+
const quotaCap = this.deps.config.delegatedTaskMaxPerDay;
|
|
660
|
+
const quotaCount = this.readTaskCount(today);
|
|
661
|
+
if (quotaCap > 0 && quotaCount >= quotaCap) {
|
|
662
|
+
return {
|
|
663
|
+
ok: false,
|
|
664
|
+
errorClass: "task_quota_exhausted",
|
|
665
|
+
message: `Daily task-mode quota reached (${quotaCount}/${quotaCap}); resets at the next agent-day boundary.`,
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
// Phase 1.5 landed Codex /exec — `runDelegatedTask` is now wired on
|
|
669
|
+
// CodexCore via daemon-side stream pre-emption. The previous
|
|
670
|
+
// `delegatedBackend === "codex"` short-circuit (501
|
|
671
|
+
// task_mode_unsupported) is gone; the same fastCheck below resolves
|
|
672
|
+
// the Codex core and lets the call flow through.
|
|
673
|
+
const fastCheck = this.resolvePreconditions(params.integrationKey);
|
|
674
|
+
if (!fastCheck.ok) {
|
|
675
|
+
return {
|
|
676
|
+
ok: false,
|
|
677
|
+
errorClass: "precondition",
|
|
678
|
+
message: fastCheck.message,
|
|
679
|
+
...(fastCheck.backendId ? { backendId: fastCheck.backendId } : {}),
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
// §13 Phase 3.3 — opportunistic cache lookup BEFORE acquiring a permit.
|
|
683
|
+
// A cache hit completes in microseconds; making it queue behind in-flight
|
|
684
|
+
// tasks would defeat the latency win. We still write an audit row on
|
|
685
|
+
// hit (cost 0, detail.cacheHit=true) so dashboard accounting stays
|
|
686
|
+
// accurate. Only attempted when the caller opted in AND the operation
|
|
687
|
+
// is read-only by intent (`allowDestructive: false`) — destructive
|
|
688
|
+
// confirm flows must always re-plan.
|
|
689
|
+
if (params.cacheable === true
|
|
690
|
+
&& params.allowDestructive === false) {
|
|
691
|
+
const cache = this.getResultCache();
|
|
692
|
+
if (cache) {
|
|
693
|
+
const cacheKey = {
|
|
694
|
+
scope: execScope(params.integrationKey),
|
|
695
|
+
task: params.task,
|
|
696
|
+
outputSchema: params.outputSchema,
|
|
697
|
+
modelId: fastCheck.modelId,
|
|
698
|
+
backendId: fastCheck.backendId,
|
|
699
|
+
allowDestructive: params.allowDestructive,
|
|
700
|
+
integrationVersion: integrationVersionFor(fastCheck.state),
|
|
701
|
+
};
|
|
702
|
+
const hit = cache.get(cacheKey);
|
|
703
|
+
if (hit) {
|
|
704
|
+
return this.buildCacheHitTaskResult({
|
|
705
|
+
params,
|
|
706
|
+
hit,
|
|
707
|
+
backendId: fastCheck.backendId,
|
|
708
|
+
modelId: fastCheck.modelId,
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
const acquired = await this.acquirePermit();
|
|
714
|
+
if (!acquired.ok) {
|
|
715
|
+
return {
|
|
716
|
+
ok: false,
|
|
717
|
+
errorClass: "delegated_proxy_busy",
|
|
718
|
+
message: acquired.message,
|
|
719
|
+
backendId: fastCheck.backendId,
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
// Post-permit re-check (mirrors invoke()).
|
|
723
|
+
const liveCheck = this.resolvePreconditions(params.integrationKey);
|
|
724
|
+
if (!liveCheck.ok) {
|
|
725
|
+
this.releasePermit();
|
|
726
|
+
return {
|
|
727
|
+
ok: false,
|
|
728
|
+
errorClass: "precondition",
|
|
729
|
+
message: `integration state changed during queue wait: ${liveCheck.message}`,
|
|
730
|
+
backendId: liveCheck.backendId ?? fastCheck.backendId,
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
// Codex /exec is supported (Phase 1.5+); no backend-specific
|
|
734
|
+
// short-circuit is needed here. The post-permit re-check above
|
|
735
|
+
// already handles state changes that might have invalidated the
|
|
736
|
+
// resolved core.
|
|
737
|
+
const { state, backendId, core } = liveCheck;
|
|
738
|
+
// Resolve allowed + destructive tool patterns.
|
|
739
|
+
const denyPatterns = state.deniedTools ?? [];
|
|
740
|
+
const expandedDeny = filterDeniedToolsForBackend(params.integrationKey, backendId, denyPatterns).active;
|
|
741
|
+
const allowedTools = resolveAllowedToolPatterns({
|
|
742
|
+
integrationKey: params.integrationKey,
|
|
743
|
+
delegatedBackend: backendId,
|
|
744
|
+
allowDestructive: params.allowDestructive,
|
|
745
|
+
deniedTools: expandedDeny,
|
|
746
|
+
});
|
|
747
|
+
if (allowedTools.length === 0) {
|
|
748
|
+
this.releasePermit();
|
|
749
|
+
return {
|
|
750
|
+
ok: false,
|
|
751
|
+
errorClass: "denied_tool",
|
|
752
|
+
message: `Every tool in the ${params.integrationKey} connector is denied — task mode has no surface to plan against.`,
|
|
753
|
+
backendId,
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
const destructiveToolPatterns = resolveDestructiveToolPatterns(params.integrationKey, backendId);
|
|
757
|
+
// §6.2 / §7.4 — superset of destructiveTools used by the cores to
|
|
758
|
+
// detect write-class tool calls (e.g. `create_draft`, `update_draft`,
|
|
759
|
+
// `respond_to_event`) that should suppress the single retry. These
|
|
760
|
+
// are NOT removed from `allowedTools` even when allowDestructive=false
|
|
761
|
+
// because they are reversible — the user asked for the action — but
|
|
762
|
+
// a fresh subprocess re-running them on retry would create a second
|
|
763
|
+
// draft / second RSVP / etc.
|
|
764
|
+
const writeClassToolPatterns = resolveWriteClassToolPatterns(params.integrationKey, backendId);
|
|
765
|
+
// Resolve model. Heavy is opt-in via config; otherwise fall back to
|
|
766
|
+
// light (canonical proxy model). The §17 rationale is in the design
|
|
767
|
+
// doc — we never let the request body select the tier.
|
|
768
|
+
const heavy = !!params.heavy && this.deps.config.delegatedTaskHeavyEnabled;
|
|
769
|
+
const modelId = this.resolveTaskModel(backendId, heavy);
|
|
770
|
+
// Compile schema once; reused across the §6.2 retry.
|
|
771
|
+
const validator = compileSchema(params.outputSchema);
|
|
772
|
+
// §13 Phase 3.1 — schema bound to Claude SDK `outputFormat`. The
|
|
773
|
+
// wrap-helper currently returns the user schema verbatim (see
|
|
774
|
+
// `prepareStructuredOutputSchema` rationale in delegated-task-runtime.ts):
|
|
775
|
+
// top-level `oneOf` admitting confirmation/error envelopes is unverified
|
|
776
|
+
// against Anthropic's stricter validator, so we picked the conservative
|
|
777
|
+
// shape. When the SDK rejects the model's emission and exhausts its
|
|
778
|
+
// internal retries, the model's raw text fallback flows back through
|
|
779
|
+
// `rawAssistantText`, where `detectConfirmationEnvelope` /
|
|
780
|
+
// `detectErrorEnvelope` route it correctly. Cores that don't support
|
|
781
|
+
// structured output (Gemini, Codex) ignore the field.
|
|
782
|
+
const structuredOutputEnabled = this.deps.config.delegatedTaskStructuredOutputEnabled === true;
|
|
783
|
+
const wrappedSchema = structuredOutputEnabled
|
|
784
|
+
? wrapSchemaForStructuredOutput(params.outputSchema)
|
|
785
|
+
: undefined;
|
|
786
|
+
// Render system prompt.
|
|
787
|
+
const systemPrompt = buildTaskPrompt({
|
|
788
|
+
task: params.task,
|
|
789
|
+
outputSchema: params.outputSchema,
|
|
790
|
+
allowedToolPatterns: allowedTools,
|
|
791
|
+
destructiveToolNamespaced: destructiveToolPatterns,
|
|
792
|
+
maxToolCalls: params.maxToolCalls,
|
|
793
|
+
timeoutMs: params.timeoutMs,
|
|
794
|
+
maxBudgetUsd: params.maxBudgetUsd,
|
|
795
|
+
allowDestructive: params.allowDestructive,
|
|
796
|
+
});
|
|
797
|
+
// §13 Phase 3.2 — acquire a session dir from the pool when enabled,
|
|
798
|
+
// else materialize a fresh tempdir. Either path returns a lease the
|
|
799
|
+
// task() loop releases (or discards on subprocess failure) in the
|
|
800
|
+
// outer `finally`.
|
|
801
|
+
let sessionLease;
|
|
802
|
+
try {
|
|
803
|
+
sessionLease = this.acquireSessionDir({
|
|
804
|
+
backendId,
|
|
805
|
+
integrationKey: params.integrationKey,
|
|
806
|
+
modelId,
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
catch (err) {
|
|
810
|
+
this.releasePermit();
|
|
811
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
812
|
+
return {
|
|
813
|
+
ok: false,
|
|
814
|
+
errorClass: "subprocess_crashed",
|
|
815
|
+
message: `failed to materialize session directory: ${message}`,
|
|
816
|
+
backendId,
|
|
817
|
+
modelId,
|
|
818
|
+
};
|
|
819
|
+
}
|
|
820
|
+
const sessionDir = sessionLease.sessionDir;
|
|
821
|
+
const startMs = this.now();
|
|
822
|
+
const startedAtIso = new Date(startMs).toISOString();
|
|
823
|
+
const taskHash = hashTaskArgs(params.task);
|
|
824
|
+
const schemaHash = hashTaskArgs(params.outputSchema);
|
|
825
|
+
// §11.1 — write header row BEFORE spawn so step rows can FK to its id.
|
|
826
|
+
const headerId = this.recordTaskHeaderInProgress({
|
|
827
|
+
actionType: "delegated_task.exec",
|
|
828
|
+
backendId,
|
|
829
|
+
modelId,
|
|
830
|
+
...(params.parentEventId !== undefined ? { parentEventId: params.parentEventId } : {}),
|
|
831
|
+
...(params.parentProcessKey !== undefined
|
|
832
|
+
? { parentProcessKey: params.parentProcessKey }
|
|
833
|
+
: {}),
|
|
834
|
+
startedAt: startedAtIso,
|
|
835
|
+
detail: {
|
|
836
|
+
integrationKey: params.integrationKey,
|
|
837
|
+
delegatedBackend: backendId,
|
|
838
|
+
taskHash,
|
|
839
|
+
schemaHash,
|
|
840
|
+
},
|
|
841
|
+
});
|
|
842
|
+
// Build abort plumbing — task mode uses the request-body timeout
|
|
843
|
+
// (clamped at hard cap) as the wall-clock; backend-specific
|
|
844
|
+
// overrides do not apply here.
|
|
845
|
+
const ac = new AbortController();
|
|
846
|
+
const timeout = setTimeout(() => {
|
|
847
|
+
ac.abort(new DelegatedProxyTimeoutError("delegated task wall-clock timeout"));
|
|
848
|
+
}, params.timeoutMs);
|
|
849
|
+
timeout.unref?.();
|
|
850
|
+
const callerListener = () => ac.abort(params.abortSignal?.reason);
|
|
851
|
+
if (params.abortSignal) {
|
|
852
|
+
if (params.abortSignal.aborted) {
|
|
853
|
+
ac.abort(params.abortSignal.reason);
|
|
854
|
+
}
|
|
855
|
+
else {
|
|
856
|
+
params.abortSignal.addEventListener("abort", callerListener, {
|
|
857
|
+
once: true,
|
|
858
|
+
});
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
let attempt = 0;
|
|
862
|
+
const maxAttempts = 2;
|
|
863
|
+
let aggregatedTrace = [];
|
|
864
|
+
let aggregatedCost = zeroCost();
|
|
865
|
+
let writeClassToolFiredEver = false;
|
|
866
|
+
let lastRaw;
|
|
867
|
+
let outcome = null;
|
|
868
|
+
let retried = false;
|
|
869
|
+
try {
|
|
870
|
+
while (attempt < maxAttempts) {
|
|
871
|
+
attempt += 1;
|
|
872
|
+
let coreResult;
|
|
873
|
+
try {
|
|
874
|
+
// §6.2 — on the retry, we must re-send the entire system
|
|
875
|
+
// prompt (task + schema + tool list) AND the retry instruction.
|
|
876
|
+
// Each `runDelegatedTask` spawns a fresh subprocess with no
|
|
877
|
+
// session memory; sending only the retry follow-up would leave
|
|
878
|
+
// the model without the original task or schema, guaranteeing
|
|
879
|
+
// another validation failure. Append the retry instruction to
|
|
880
|
+
// the original prompt so the model recovers from the same
|
|
881
|
+
// context it had on attempt #1.
|
|
882
|
+
const retryClass = outcome?.ok === false
|
|
883
|
+
&& (outcome.errorClass === "parse_error"
|
|
884
|
+
|| outcome.errorClass === "schema_violation")
|
|
885
|
+
? outcome.errorClass
|
|
886
|
+
: "parse_error";
|
|
887
|
+
const promptForAttempt = attempt === 1
|
|
888
|
+
? systemPrompt
|
|
889
|
+
: `${systemPrompt}\n\n## Retry\n\n${buildRetryFollowup({
|
|
890
|
+
errorClass: retryClass,
|
|
891
|
+
message: outcome?.ok === false ? outcome.message : "",
|
|
892
|
+
})}`;
|
|
893
|
+
coreResult = await core.runDelegatedTask({
|
|
894
|
+
integrationKey: params.integrationKey,
|
|
895
|
+
systemPrompt: promptForAttempt,
|
|
896
|
+
validate: validator,
|
|
897
|
+
validatorErrorMessage: () => (validator.errors ?? [])
|
|
898
|
+
.map((e) => `${e.instancePath || "/"} ${e.message ?? "invalid"}`)
|
|
899
|
+
.join("; "),
|
|
900
|
+
allowedTools,
|
|
901
|
+
destructiveTools: destructiveToolPatterns,
|
|
902
|
+
writeClassTools: writeClassToolPatterns,
|
|
903
|
+
modelId,
|
|
904
|
+
maxToolCalls: params.maxToolCalls,
|
|
905
|
+
maxBudgetUsd: params.maxBudgetUsd,
|
|
906
|
+
timeoutMs: params.timeoutMs,
|
|
907
|
+
allowDestructive: params.allowDestructive,
|
|
908
|
+
sessionDir,
|
|
909
|
+
abortSignal: ac.signal,
|
|
910
|
+
// §13 Phase 3.1 — structured output. Cores that don't honor
|
|
911
|
+
// the flag (Gemini, Codex) ignore both fields and fall back
|
|
912
|
+
// to text emission, which the invoker then parses + validates.
|
|
913
|
+
structuredOutputEnabled,
|
|
914
|
+
...(wrappedSchema ? { wrappedSchema } : {}),
|
|
915
|
+
onToolStep: (step) => {
|
|
916
|
+
this.recordTaskToolStep({
|
|
917
|
+
parentTaskActionId: headerId,
|
|
918
|
+
backendId,
|
|
919
|
+
modelId,
|
|
920
|
+
integrationKey: params.integrationKey,
|
|
921
|
+
step,
|
|
922
|
+
});
|
|
923
|
+
},
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
catch (err) {
|
|
927
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
928
|
+
coreResult = {
|
|
929
|
+
ok: false,
|
|
930
|
+
errorClass: "subprocess_crashed",
|
|
931
|
+
message,
|
|
932
|
+
cost: zeroCost(),
|
|
933
|
+
trace: [],
|
|
934
|
+
writeClassToolFired: false,
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
aggregatedTrace = aggregatedTrace.concat(coreResult.trace);
|
|
938
|
+
aggregatedCost = mergeCost(aggregatedCost, coreResult.cost);
|
|
939
|
+
writeClassToolFiredEver =
|
|
940
|
+
writeClassToolFiredEver || coreResult.writeClassToolFired;
|
|
941
|
+
if (!coreResult.ok) {
|
|
942
|
+
outcome = {
|
|
943
|
+
ok: false,
|
|
944
|
+
errorClass: coreResult.errorClass,
|
|
945
|
+
message: coreResult.message,
|
|
946
|
+
...(coreResult.rawAssistantText
|
|
947
|
+
? { raw: coreResult.rawAssistantText }
|
|
948
|
+
: {}),
|
|
949
|
+
cost: aggregatedCost,
|
|
950
|
+
trace: aggregatedTrace,
|
|
951
|
+
backendId,
|
|
952
|
+
modelId,
|
|
953
|
+
retried,
|
|
954
|
+
};
|
|
955
|
+
break;
|
|
956
|
+
}
|
|
957
|
+
lastRaw = coreResult.rawAssistantText;
|
|
958
|
+
// §13 Phase 3.1 — when the core supplied a pre-validated
|
|
959
|
+
// `structuredOutput`, classify it directly and skip the text
|
|
960
|
+
// extraction path. The wrapper schema admits the §7.2 confirmation
|
|
961
|
+
// envelope and §5.1 error envelopes, so `classifyStructuredOutput`
|
|
962
|
+
// routes them to the same outcomes the text path would.
|
|
963
|
+
const classification = coreResult.structuredOutput !== undefined
|
|
964
|
+
? classifyStructuredOutput(coreResult.structuredOutput, validator)
|
|
965
|
+
: null;
|
|
966
|
+
if (classification && classification.ok && "envelope" in classification) {
|
|
967
|
+
if (classification.envelope === "confirmation") {
|
|
968
|
+
const conf = detectConfirmationEnvelope(classification.value);
|
|
969
|
+
outcome = {
|
|
970
|
+
ok: true,
|
|
971
|
+
result: classification.value,
|
|
972
|
+
needsConfirmation: true,
|
|
973
|
+
confirmationPlan: conf?.plan ?? "",
|
|
974
|
+
cost: aggregatedCost,
|
|
975
|
+
trace: aggregatedTrace,
|
|
976
|
+
backendId,
|
|
977
|
+
modelId,
|
|
978
|
+
retried,
|
|
979
|
+
};
|
|
980
|
+
break;
|
|
981
|
+
}
|
|
982
|
+
if (classification.envelope === "error") {
|
|
983
|
+
const env = detectErrorEnvelope(classification.value);
|
|
984
|
+
outcome = {
|
|
985
|
+
ok: false,
|
|
986
|
+
errorClass: env?.errorClass ?? "tool_failed",
|
|
987
|
+
message: env?.message ?? "subprocess returned error envelope",
|
|
988
|
+
raw: JSON.stringify(classification.value),
|
|
989
|
+
cost: aggregatedCost,
|
|
990
|
+
trace: aggregatedTrace,
|
|
991
|
+
backendId,
|
|
992
|
+
modelId,
|
|
993
|
+
retried,
|
|
994
|
+
};
|
|
995
|
+
break;
|
|
996
|
+
}
|
|
997
|
+
// envelope === "result" — happy path
|
|
998
|
+
outcome = {
|
|
999
|
+
ok: true,
|
|
1000
|
+
result: classification.value,
|
|
1001
|
+
needsConfirmation: false,
|
|
1002
|
+
confirmationPlan: null,
|
|
1003
|
+
cost: aggregatedCost,
|
|
1004
|
+
trace: aggregatedTrace,
|
|
1005
|
+
backendId,
|
|
1006
|
+
modelId,
|
|
1007
|
+
retried,
|
|
1008
|
+
};
|
|
1009
|
+
break;
|
|
1010
|
+
}
|
|
1011
|
+
if (classification && !classification.ok) {
|
|
1012
|
+
// SDK validated against wrapped schema but our narrower user
|
|
1013
|
+
// schema rejected — bias toward post-write failure when
|
|
1014
|
+
// applicable, otherwise fall through to retry path with the
|
|
1015
|
+
// SDK-supplied error class. We fall through to the existing
|
|
1016
|
+
// extraction path below by setting `parsed` so the same retry
|
|
1017
|
+
// / write-class logic applies.
|
|
1018
|
+
if (writeClassToolFiredEver) {
|
|
1019
|
+
outcome = {
|
|
1020
|
+
ok: false,
|
|
1021
|
+
errorClass: "post_write_format_failure",
|
|
1022
|
+
message: classification.message,
|
|
1023
|
+
raw: classification.raw,
|
|
1024
|
+
cost: aggregatedCost,
|
|
1025
|
+
trace: aggregatedTrace,
|
|
1026
|
+
backendId,
|
|
1027
|
+
modelId,
|
|
1028
|
+
retried,
|
|
1029
|
+
};
|
|
1030
|
+
break;
|
|
1031
|
+
}
|
|
1032
|
+
if (attempt < maxAttempts) {
|
|
1033
|
+
retried = true;
|
|
1034
|
+
outcome = {
|
|
1035
|
+
ok: false,
|
|
1036
|
+
errorClass: classification.errorClass,
|
|
1037
|
+
message: classification.message,
|
|
1038
|
+
raw: classification.raw,
|
|
1039
|
+
cost: aggregatedCost,
|
|
1040
|
+
trace: aggregatedTrace,
|
|
1041
|
+
backendId,
|
|
1042
|
+
modelId,
|
|
1043
|
+
retried,
|
|
1044
|
+
};
|
|
1045
|
+
continue;
|
|
1046
|
+
}
|
|
1047
|
+
outcome = {
|
|
1048
|
+
ok: false,
|
|
1049
|
+
errorClass: classification.errorClass,
|
|
1050
|
+
message: classification.message,
|
|
1051
|
+
raw: classification.raw,
|
|
1052
|
+
cost: aggregatedCost,
|
|
1053
|
+
trace: aggregatedTrace,
|
|
1054
|
+
backendId,
|
|
1055
|
+
modelId,
|
|
1056
|
+
retried,
|
|
1057
|
+
};
|
|
1058
|
+
break;
|
|
1059
|
+
}
|
|
1060
|
+
// §6.2 — extract + validate. On parse/schema failure, retry once
|
|
1061
|
+
// ONLY if no write-class tool ran. Confirmation envelope and
|
|
1062
|
+
// error envelope short-circuit before validation.
|
|
1063
|
+
const stripped = coreResult.rawAssistantText;
|
|
1064
|
+
let parsed;
|
|
1065
|
+
try {
|
|
1066
|
+
parsed = JSON.parse(stripCodeFences(stripped));
|
|
1067
|
+
}
|
|
1068
|
+
catch {
|
|
1069
|
+
parsed = null;
|
|
1070
|
+
}
|
|
1071
|
+
const confirmation = parsed != null
|
|
1072
|
+
? detectConfirmationEnvelope(parsed)
|
|
1073
|
+
: null;
|
|
1074
|
+
if (confirmation) {
|
|
1075
|
+
outcome = {
|
|
1076
|
+
ok: true,
|
|
1077
|
+
result: parsed,
|
|
1078
|
+
needsConfirmation: true,
|
|
1079
|
+
confirmationPlan: confirmation.plan,
|
|
1080
|
+
cost: aggregatedCost,
|
|
1081
|
+
trace: aggregatedTrace,
|
|
1082
|
+
backendId,
|
|
1083
|
+
modelId,
|
|
1084
|
+
retried,
|
|
1085
|
+
};
|
|
1086
|
+
break;
|
|
1087
|
+
}
|
|
1088
|
+
const errorEnvelope = parsed != null
|
|
1089
|
+
? detectErrorEnvelope(parsed)
|
|
1090
|
+
: null;
|
|
1091
|
+
if (errorEnvelope) {
|
|
1092
|
+
outcome = {
|
|
1093
|
+
ok: false,
|
|
1094
|
+
errorClass: errorEnvelope.errorClass,
|
|
1095
|
+
message: errorEnvelope.message,
|
|
1096
|
+
raw: stripped,
|
|
1097
|
+
cost: aggregatedCost,
|
|
1098
|
+
trace: aggregatedTrace,
|
|
1099
|
+
backendId,
|
|
1100
|
+
modelId,
|
|
1101
|
+
retried,
|
|
1102
|
+
};
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1105
|
+
const extraction = extractAndValidateResult(stripped, validator);
|
|
1106
|
+
if (extraction.ok) {
|
|
1107
|
+
outcome = {
|
|
1108
|
+
ok: true,
|
|
1109
|
+
result: extraction.value,
|
|
1110
|
+
needsConfirmation: false,
|
|
1111
|
+
confirmationPlan: null,
|
|
1112
|
+
cost: aggregatedCost,
|
|
1113
|
+
trace: aggregatedTrace,
|
|
1114
|
+
backendId,
|
|
1115
|
+
modelId,
|
|
1116
|
+
retried,
|
|
1117
|
+
};
|
|
1118
|
+
break;
|
|
1119
|
+
}
|
|
1120
|
+
// Validation failure path.
|
|
1121
|
+
if (writeClassToolFiredEver) {
|
|
1122
|
+
// §7.4 idempotency rule — no retry after a write.
|
|
1123
|
+
outcome = {
|
|
1124
|
+
ok: false,
|
|
1125
|
+
errorClass: "post_write_format_failure",
|
|
1126
|
+
message: extraction.message,
|
|
1127
|
+
raw: extraction.raw,
|
|
1128
|
+
cost: aggregatedCost,
|
|
1129
|
+
trace: aggregatedTrace,
|
|
1130
|
+
backendId,
|
|
1131
|
+
modelId,
|
|
1132
|
+
retried,
|
|
1133
|
+
};
|
|
1134
|
+
break;
|
|
1135
|
+
}
|
|
1136
|
+
if (attempt < maxAttempts) {
|
|
1137
|
+
retried = true;
|
|
1138
|
+
outcome = {
|
|
1139
|
+
ok: false,
|
|
1140
|
+
errorClass: extraction.errorClass,
|
|
1141
|
+
message: extraction.message,
|
|
1142
|
+
raw: extraction.raw,
|
|
1143
|
+
cost: aggregatedCost,
|
|
1144
|
+
trace: aggregatedTrace,
|
|
1145
|
+
backendId,
|
|
1146
|
+
modelId,
|
|
1147
|
+
retried,
|
|
1148
|
+
};
|
|
1149
|
+
// Loop again for the single retry.
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
outcome = {
|
|
1153
|
+
ok: false,
|
|
1154
|
+
errorClass: extraction.errorClass,
|
|
1155
|
+
message: extraction.message,
|
|
1156
|
+
raw: extraction.raw,
|
|
1157
|
+
cost: aggregatedCost,
|
|
1158
|
+
trace: aggregatedTrace,
|
|
1159
|
+
backendId,
|
|
1160
|
+
modelId,
|
|
1161
|
+
retried,
|
|
1162
|
+
};
|
|
1163
|
+
break;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
finally {
|
|
1167
|
+
clearTimeout(timeout);
|
|
1168
|
+
params.abortSignal?.removeEventListener("abort", callerListener);
|
|
1169
|
+
// §13 Phase 3.2 — release the lease back to the pool when pooling
|
|
1170
|
+
// is enabled (otherwise the synthetic lease cleans up its tempdir).
|
|
1171
|
+
// We DISCARD instead of release when a write-class tool fired
|
|
1172
|
+
// mid-task: the dir is fine to reuse, but if a future invariant
|
|
1173
|
+
// change adds per-task state on disk (e.g. cached MCP tool
|
|
1174
|
+
// listings keyed by allowDestructive), the discard path stays
|
|
1175
|
+
// safe. Currently no per-task state lands on disk, so release
|
|
1176
|
+
// would also be correct — but discard is the conservative choice.
|
|
1177
|
+
if (writeClassToolFiredEver) {
|
|
1178
|
+
sessionLease.discard();
|
|
1179
|
+
}
|
|
1180
|
+
else {
|
|
1181
|
+
sessionLease.release();
|
|
1182
|
+
}
|
|
1183
|
+
this.releasePermit();
|
|
1184
|
+
}
|
|
1185
|
+
const completedAtIso = new Date(this.now()).toISOString();
|
|
1186
|
+
// §8.3 — bump the per-day task quota counter on every settled task
|
|
1187
|
+
// (success and failure both consumed the budget).
|
|
1188
|
+
this.incrementTaskCount(today);
|
|
1189
|
+
// §13 Phase 3.3 — write to cache when:
|
|
1190
|
+
// - caller opted in (`cacheable: true`)
|
|
1191
|
+
// - the cache is enabled live
|
|
1192
|
+
// - the outcome is a clean read-only success (no confirmation, no
|
|
1193
|
+
// write-class tool fired). Confirmation envelopes and write-class
|
|
1194
|
+
// touches MUST NOT be cached — see the §6.2/§7.4 idempotency rule.
|
|
1195
|
+
if (params.cacheable === true
|
|
1196
|
+
&& params.allowDestructive === false
|
|
1197
|
+
&& outcome?.ok === true
|
|
1198
|
+
&& outcome.needsConfirmation === false
|
|
1199
|
+
&& writeClassToolFiredEver === false) {
|
|
1200
|
+
const cache = this.getResultCache();
|
|
1201
|
+
if (cache) {
|
|
1202
|
+
const cacheKey = {
|
|
1203
|
+
scope: execScope(params.integrationKey),
|
|
1204
|
+
task: params.task,
|
|
1205
|
+
outputSchema: params.outputSchema,
|
|
1206
|
+
modelId,
|
|
1207
|
+
backendId,
|
|
1208
|
+
allowDestructive: params.allowDestructive,
|
|
1209
|
+
// Use the live state (post-permit) so a deniedTools mutation
|
|
1210
|
+
// mid-task invalidates the entry on the very next call.
|
|
1211
|
+
integrationVersion: integrationVersionFor(state),
|
|
1212
|
+
};
|
|
1213
|
+
const entry = {
|
|
1214
|
+
result: outcome.result,
|
|
1215
|
+
needsConfirmation: false,
|
|
1216
|
+
confirmationPlan: null,
|
|
1217
|
+
cost: aggregatedCost,
|
|
1218
|
+
trace: aggregatedTrace,
|
|
1219
|
+
backendId,
|
|
1220
|
+
modelId,
|
|
1221
|
+
retried: false,
|
|
1222
|
+
};
|
|
1223
|
+
cache.set(cacheKey, entry);
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
// §11.1 — finalise the header row.
|
|
1227
|
+
this.completeTaskHeader({
|
|
1228
|
+
headerId,
|
|
1229
|
+
result: outcome?.ok ? "success" : "failed",
|
|
1230
|
+
cost: aggregatedCost,
|
|
1231
|
+
completedAt: completedAtIso,
|
|
1232
|
+
errorClass: outcome?.ok === false ? outcome.errorClass : null,
|
|
1233
|
+
errorMessage: outcome?.ok === false ? outcome.message : null,
|
|
1234
|
+
retried,
|
|
1235
|
+
toolCallCount: aggregatedTrace.length,
|
|
1236
|
+
detail: {
|
|
1237
|
+
integrationKey: params.integrationKey,
|
|
1238
|
+
delegatedBackend: backendId,
|
|
1239
|
+
taskHash,
|
|
1240
|
+
schemaHash,
|
|
1241
|
+
toolCallCount: aggregatedTrace.length,
|
|
1242
|
+
retried,
|
|
1243
|
+
// §11.2 metric `delegated_task_destructive_blocked` keys off this
|
|
1244
|
+
// flag — true when allowDestructive=false and the subprocess
|
|
1245
|
+
// returned a confirmation envelope instead of executing the
|
|
1246
|
+
// destructive tool.
|
|
1247
|
+
needsConfirmation: outcome?.ok === true && outcome.needsConfirmation === true,
|
|
1248
|
+
...(outcome?.ok === false ? { errorClass: outcome.errorClass } : {}),
|
|
1249
|
+
},
|
|
1250
|
+
});
|
|
1251
|
+
// §11.3 — one INFO line per task summarizing the outcome.
|
|
1252
|
+
logger.info({
|
|
1253
|
+
integrationKey: params.integrationKey,
|
|
1254
|
+
backendId,
|
|
1255
|
+
modelId,
|
|
1256
|
+
taskLen: params.task.length,
|
|
1257
|
+
toolCallCount: aggregatedTrace.length,
|
|
1258
|
+
costUsd: aggregatedCost.costUsd,
|
|
1259
|
+
durationMs: aggregatedCost.durationMs,
|
|
1260
|
+
result: outcome?.ok ? "success" : "failed",
|
|
1261
|
+
...(outcome?.ok === false ? { errorClass: outcome.errorClass } : {}),
|
|
1262
|
+
...(outcome?.ok === true && outcome.needsConfirmation === true
|
|
1263
|
+
? { needsConfirmation: true }
|
|
1264
|
+
: {}),
|
|
1265
|
+
retried,
|
|
1266
|
+
}, "delegated task complete");
|
|
1267
|
+
if (!outcome) {
|
|
1268
|
+
// Defensive: should not happen.
|
|
1269
|
+
return {
|
|
1270
|
+
ok: false,
|
|
1271
|
+
errorClass: "subprocess_crashed",
|
|
1272
|
+
message: "task settled without producing an outcome",
|
|
1273
|
+
backendId,
|
|
1274
|
+
modelId,
|
|
1275
|
+
cost: aggregatedCost,
|
|
1276
|
+
trace: aggregatedTrace,
|
|
1277
|
+
retried,
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
if (lastRaw && outcome.ok && outcome.confirmationPlan === null) {
|
|
1281
|
+
// Successful path — drop the raw text from the response.
|
|
1282
|
+
}
|
|
1283
|
+
return outcome;
|
|
1284
|
+
}
|
|
1285
|
+
/**
|
|
1286
|
+
* §13 Phase 3.3 — synthesize a `TaskInvokeResult` from a cache hit and
|
|
1287
|
+
* write the corresponding `delegated_task.exec` audit row with cost 0
|
|
1288
|
+
* and `detail.cacheHit=true`. Cache hits do not consume the per-day
|
|
1289
|
+
* quota (the quota counts subprocess invocations) and do not acquire a
|
|
1290
|
+
* concurrency permit (looked up before `acquirePermit`).
|
|
1291
|
+
*/
|
|
1292
|
+
buildCacheHitTaskResult(args) {
|
|
1293
|
+
const nowIso = new Date(this.now()).toISOString();
|
|
1294
|
+
const taskHash = hashTaskArgs(args.params.task);
|
|
1295
|
+
const schemaHash = hashTaskArgs(args.params.outputSchema);
|
|
1296
|
+
this.recordCacheHitAuditRow({
|
|
1297
|
+
actionType: "delegated_task.exec",
|
|
1298
|
+
backendId: args.backendId,
|
|
1299
|
+
modelId: args.modelId,
|
|
1300
|
+
...(args.params.parentEventId !== undefined
|
|
1301
|
+
? { parentEventId: args.params.parentEventId }
|
|
1302
|
+
: {}),
|
|
1303
|
+
...(args.params.parentProcessKey !== undefined
|
|
1304
|
+
? { parentProcessKey: args.params.parentProcessKey }
|
|
1305
|
+
: {}),
|
|
1306
|
+
timestamp: nowIso,
|
|
1307
|
+
toolCallCount: args.hit.trace.length,
|
|
1308
|
+
detail: {
|
|
1309
|
+
integrationKey: args.params.integrationKey,
|
|
1310
|
+
delegatedBackend: args.backendId,
|
|
1311
|
+
taskHash,
|
|
1312
|
+
schemaHash,
|
|
1313
|
+
cacheHit: true,
|
|
1314
|
+
toolCallCount: args.hit.trace.length,
|
|
1315
|
+
retried: false,
|
|
1316
|
+
// §11.2 — cache hits are gated on the original outcome being
|
|
1317
|
+
// non-confirmation (see Phase 3.3 cache guard); record this
|
|
1318
|
+
// explicitly so the metric aggregator's schema stays uniform
|
|
1319
|
+
// across live + cache-hit rows.
|
|
1320
|
+
needsConfirmation: false,
|
|
1321
|
+
},
|
|
1322
|
+
});
|
|
1323
|
+
return {
|
|
1324
|
+
ok: true,
|
|
1325
|
+
result: args.hit.result,
|
|
1326
|
+
needsConfirmation: false,
|
|
1327
|
+
confirmationPlan: null,
|
|
1328
|
+
cost: zeroCost(),
|
|
1329
|
+
trace: args.hit.trace,
|
|
1330
|
+
backendId: args.backendId,
|
|
1331
|
+
modelId: args.modelId,
|
|
1332
|
+
retried: false,
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
/**
|
|
1336
|
+
* DELEGATED-TASK-MODE-DESIGN.md §4.2 — Phase 2 generic task mode.
|
|
1337
|
+
* Mirror of `task()` but with no `integrationKey`: the caller pins
|
|
1338
|
+
* `delegatedBackend` and `allowedTools` patterns directly. Designed
|
|
1339
|
+
* for unregistered MCPs the user installed via `gemini mcp add` /
|
|
1340
|
+
* `claude mcp add` (etc.) that lack an `INTEGRATION_DESCRIPTORS` entry.
|
|
1341
|
+
*
|
|
1342
|
+
* Differences from `task()`:
|
|
1343
|
+
* - No registry / `INTEGRATION_DESCRIPTORS` lookup. The caller's
|
|
1344
|
+
* `allowedTools` is the only scoping signal.
|
|
1345
|
+
* - `destructiveTools = []` — the registry has no destructive list
|
|
1346
|
+
* to consult. Per §7.1 the caller takes responsibility for that
|
|
1347
|
+
* classification; the absolute-block layer is still applied at
|
|
1348
|
+
* the core.
|
|
1349
|
+
* - Write-class set is derived from `allowedTools` via
|
|
1350
|
+
* {@link resolveRunWriteClassToolPatterns} (verb-segment heuristic
|
|
1351
|
+
* biased toward false-positive write-class). Phase 2 keeps the
|
|
1352
|
+
* §6.2 retry rule honest without a connector descriptor.
|
|
1353
|
+
* - Model tier is fixed `light` server-side (§4.2 last bullet);
|
|
1354
|
+
* no `heavy` field on the request body.
|
|
1355
|
+
* - Action type is `'delegated_task.run'` so dashboard filters can
|
|
1356
|
+
* separate generic Phase 2 traffic from registered-integration
|
|
1357
|
+
* Phase 1 traffic.
|
|
1358
|
+
*
|
|
1359
|
+
* Risk tier (route-side): Approve. The route handler is the chokepoint
|
|
1360
|
+
* that enforces Bearer auth — see §13 Phase 2 deliverables.
|
|
1361
|
+
*/
|
|
1362
|
+
async run(params) {
|
|
1363
|
+
if (!this.deps.config.delegatedTaskModeEnabled) {
|
|
1364
|
+
return {
|
|
1365
|
+
ok: false,
|
|
1366
|
+
errorClass: "task_mode_disabled",
|
|
1367
|
+
message: "Task mode is currently disabled (config.delegatedTaskModeEnabled=false). Re-enable via PATCH /api/config { delegatedTaskModeEnabled: true }, or flip an integration to delegated to auto-enable.",
|
|
1368
|
+
};
|
|
1369
|
+
}
|
|
1370
|
+
// §8.3 — quota counter is shared across /exec + /run; both kinds of
|
|
1371
|
+
// task consume the same per-day budget so a runaway /run loop cannot
|
|
1372
|
+
// starve /exec or vice versa.
|
|
1373
|
+
const today = getAgentDayDateStr(this.deps.config.timezone, this.deps.config.dayBoundaryHour);
|
|
1374
|
+
const quotaCap = this.deps.config.delegatedTaskMaxPerDay;
|
|
1375
|
+
const quotaCount = this.readTaskCount(today);
|
|
1376
|
+
if (quotaCap > 0 && quotaCount >= quotaCap) {
|
|
1377
|
+
return {
|
|
1378
|
+
ok: false,
|
|
1379
|
+
errorClass: "task_quota_exhausted",
|
|
1380
|
+
message: `Daily task-mode quota reached (${quotaCount}/${quotaCap}); resets at the next agent-day boundary.`,
|
|
1381
|
+
};
|
|
1382
|
+
}
|
|
1383
|
+
// Phase 1.5 landed Codex /run support — no backend-specific
|
|
1384
|
+
// short-circuit needed. The core resolution below surfaces the
|
|
1385
|
+
// backend-not-registered case as `subprocess_crashed`.
|
|
1386
|
+
const backendId = params.delegatedBackend;
|
|
1387
|
+
const core = this.deps.cores[backendId];
|
|
1388
|
+
if (!core) {
|
|
1389
|
+
// Boot ordering: the requested backend is not registered with this
|
|
1390
|
+
// invoker (e.g. claude-only deployment). Surface as
|
|
1391
|
+
// subprocess_crashed so the route returns 500 rather than a
|
|
1392
|
+
// misleading auth_error. The dashboard surfaces the underlying
|
|
1393
|
+
// backend wiring on /api/health.
|
|
1394
|
+
return {
|
|
1395
|
+
ok: false,
|
|
1396
|
+
errorClass: "subprocess_crashed",
|
|
1397
|
+
message: `no agent core registered for backend '${backendId}'`,
|
|
1398
|
+
backendId,
|
|
1399
|
+
};
|
|
1400
|
+
}
|
|
1401
|
+
// §13 Phase 3.3 — opportunistic cache lookup BEFORE permit acquisition.
|
|
1402
|
+
// The /run path uses `runScope(allowedTools)` so two callers with the
|
|
1403
|
+
// same MCP allowedTools share a cache slot; different patterns force
|
|
1404
|
+
// a miss. Same constraints as /exec: caller must opt in AND the
|
|
1405
|
+
// operation must be read-only by intent (allowDestructive=false).
|
|
1406
|
+
const runModelId = this.resolveTaskModel(backendId, /* heavy */ false);
|
|
1407
|
+
if (params.cacheable === true && params.allowDestructive === false) {
|
|
1408
|
+
const cache = this.getResultCache();
|
|
1409
|
+
if (cache) {
|
|
1410
|
+
const cacheKey = {
|
|
1411
|
+
scope: runScope(params.allowedTools),
|
|
1412
|
+
task: params.task,
|
|
1413
|
+
outputSchema: params.outputSchema,
|
|
1414
|
+
modelId: runModelId,
|
|
1415
|
+
backendId,
|
|
1416
|
+
allowDestructive: params.allowDestructive,
|
|
1417
|
+
// /run has no integration state — empty version stamps the
|
|
1418
|
+
// cache slot but never invalidates from external mutation.
|
|
1419
|
+
// Caller-controlled allowedTools changes already invalidate via
|
|
1420
|
+
// the `runScope` hash above.
|
|
1421
|
+
integrationVersion: "",
|
|
1422
|
+
};
|
|
1423
|
+
const hit = cache.get(cacheKey);
|
|
1424
|
+
if (hit) {
|
|
1425
|
+
return this.buildCacheHitRunResult({
|
|
1426
|
+
params,
|
|
1427
|
+
hit,
|
|
1428
|
+
backendId,
|
|
1429
|
+
modelId: runModelId,
|
|
1430
|
+
});
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
const acquired = await this.acquirePermit();
|
|
1435
|
+
if (!acquired.ok) {
|
|
1436
|
+
return {
|
|
1437
|
+
ok: false,
|
|
1438
|
+
errorClass: "delegated_proxy_busy",
|
|
1439
|
+
message: acquired.message,
|
|
1440
|
+
backendId,
|
|
1441
|
+
};
|
|
1442
|
+
}
|
|
1443
|
+
// No mid-flight precondition re-check — there is no integration
|
|
1444
|
+
// state to flip during the queue wait. The kill switch is the only
|
|
1445
|
+
// mutable gate, and we tolerate it silently because: (a) the §6.2
|
|
1446
|
+
// retry would already be in-flight; (b) the boot janitor cleans up
|
|
1447
|
+
// any orphan in-progress rows; (c) the cost is bounded by the
|
|
1448
|
+
// wall-clock and budget caps the request already pinned.
|
|
1449
|
+
// Caller-supplied allowedTools is the entire scoping surface. We
|
|
1450
|
+
// do NOT subtract anything — there is no per-integration deniedTools
|
|
1451
|
+
// to enforce. The absolute-block layer is applied at the core's
|
|
1452
|
+
// `disallowedTools` (Claude SDK) or admin-policy TOML (Gemini).
|
|
1453
|
+
const allowedTools = [...params.allowedTools];
|
|
1454
|
+
// §7.1 — destructive set is empty by design (the caller owns that
|
|
1455
|
+
// classification for unregistered MCPs). We still pass an array so
|
|
1456
|
+
// the core's admin-policy / disallowedTools synthesis lands on a
|
|
1457
|
+
// stable shape; an empty array is a no-op for both backends.
|
|
1458
|
+
const destructiveToolPatterns = [];
|
|
1459
|
+
// §6.2 / §7.4 — write-class derivation from the caller's allowedTools
|
|
1460
|
+
// patterns. Verb-segment heuristic biased toward false-positive
|
|
1461
|
+
// write-class; documented in `resolveRunWriteClassToolPatterns`.
|
|
1462
|
+
const writeClassToolPatterns = resolveRunWriteClassToolPatterns(params.allowedTools);
|
|
1463
|
+
// §4.2 last bullet — model tier is fixed `light` server-side.
|
|
1464
|
+
// Heavy is intentionally not selectable per request to prevent a
|
|
1465
|
+
// prompt-injected DM from escalating cost. Reuse the modelId
|
|
1466
|
+
// resolved earlier for the cache lookup so a slow model resolver
|
|
1467
|
+
// isn't called twice.
|
|
1468
|
+
const modelId = runModelId;
|
|
1469
|
+
// Compile schema once; reused across the §6.2 retry.
|
|
1470
|
+
const validator = compileSchema(params.outputSchema);
|
|
1471
|
+
// §13 Phase 3.1 — same structured-output bridge as task(): the helper
|
|
1472
|
+
// returns the user schema verbatim today. Cores that don't honor the
|
|
1473
|
+
// flag (Gemini, Codex) fall back to text emission, which the invoker
|
|
1474
|
+
// parses + validates below.
|
|
1475
|
+
const structuredOutputEnabled = this.deps.config.delegatedTaskStructuredOutputEnabled === true;
|
|
1476
|
+
const wrappedSchema = structuredOutputEnabled
|
|
1477
|
+
? wrapSchemaForStructuredOutput(params.outputSchema)
|
|
1478
|
+
: undefined;
|
|
1479
|
+
const systemPrompt = buildTaskPrompt({
|
|
1480
|
+
task: params.task,
|
|
1481
|
+
outputSchema: params.outputSchema,
|
|
1482
|
+
allowedToolPatterns: allowedTools,
|
|
1483
|
+
// §5.1 — the destructive list is empty for /run; the prompt
|
|
1484
|
+
// template renders a "(none)" sentinel and falls through to the
|
|
1485
|
+
// generic destructive-confirmation prose when allowDestructive=false.
|
|
1486
|
+
destructiveToolNamespaced: destructiveToolPatterns,
|
|
1487
|
+
maxToolCalls: params.maxToolCalls,
|
|
1488
|
+
timeoutMs: params.timeoutMs,
|
|
1489
|
+
maxBudgetUsd: params.maxBudgetUsd,
|
|
1490
|
+
allowDestructive: params.allowDestructive,
|
|
1491
|
+
});
|
|
1492
|
+
// §13 Phase 3.2 — pool acquisition with `integrationKey: null` since
|
|
1493
|
+
// /run has no registered integration scope.
|
|
1494
|
+
let sessionLease;
|
|
1495
|
+
try {
|
|
1496
|
+
sessionLease = this.acquireSessionDir({
|
|
1497
|
+
backendId,
|
|
1498
|
+
integrationKey: null,
|
|
1499
|
+
modelId,
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
catch (err) {
|
|
1503
|
+
this.releasePermit();
|
|
1504
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1505
|
+
return {
|
|
1506
|
+
ok: false,
|
|
1507
|
+
errorClass: "subprocess_crashed",
|
|
1508
|
+
message: `failed to materialize session directory: ${message}`,
|
|
1509
|
+
backendId,
|
|
1510
|
+
modelId,
|
|
1511
|
+
};
|
|
1512
|
+
}
|
|
1513
|
+
const sessionDir = sessionLease.sessionDir;
|
|
1514
|
+
const startMs = this.now();
|
|
1515
|
+
const startedAtIso = new Date(startMs).toISOString();
|
|
1516
|
+
const taskHash = hashTaskArgs(params.task);
|
|
1517
|
+
const schemaHash = hashTaskArgs(params.outputSchema);
|
|
1518
|
+
const allowedToolsHash = hashTaskArgs(allowedTools);
|
|
1519
|
+
// §11.1 — header row BEFORE spawn so step rows can FK to it.
|
|
1520
|
+
const headerId = this.recordTaskHeaderInProgress({
|
|
1521
|
+
actionType: "delegated_task.run",
|
|
1522
|
+
backendId,
|
|
1523
|
+
modelId,
|
|
1524
|
+
...(params.parentEventId !== undefined ? { parentEventId: params.parentEventId } : {}),
|
|
1525
|
+
...(params.parentProcessKey !== undefined
|
|
1526
|
+
? { parentProcessKey: params.parentProcessKey }
|
|
1527
|
+
: {}),
|
|
1528
|
+
startedAt: startedAtIso,
|
|
1529
|
+
detail: {
|
|
1530
|
+
delegatedBackend: backendId,
|
|
1531
|
+
taskHash,
|
|
1532
|
+
schemaHash,
|
|
1533
|
+
allowedToolsHash,
|
|
1534
|
+
allowedToolsCount: allowedTools.length,
|
|
1535
|
+
},
|
|
1536
|
+
});
|
|
1537
|
+
const ac = new AbortController();
|
|
1538
|
+
const timeout = setTimeout(() => {
|
|
1539
|
+
ac.abort(new DelegatedProxyTimeoutError("delegated task wall-clock timeout"));
|
|
1540
|
+
}, params.timeoutMs);
|
|
1541
|
+
timeout.unref?.();
|
|
1542
|
+
const callerListener = () => ac.abort(params.abortSignal?.reason);
|
|
1543
|
+
if (params.abortSignal) {
|
|
1544
|
+
if (params.abortSignal.aborted) {
|
|
1545
|
+
ac.abort(params.abortSignal.reason);
|
|
1546
|
+
}
|
|
1547
|
+
else {
|
|
1548
|
+
params.abortSignal.addEventListener("abort", callerListener, {
|
|
1549
|
+
once: true,
|
|
1550
|
+
});
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
let attempt = 0;
|
|
1554
|
+
const maxAttempts = 2;
|
|
1555
|
+
let aggregatedTrace = [];
|
|
1556
|
+
let aggregatedCost = zeroCost();
|
|
1557
|
+
let writeClassToolFiredEver = false;
|
|
1558
|
+
let outcome = null;
|
|
1559
|
+
let retried = false;
|
|
1560
|
+
try {
|
|
1561
|
+
while (attempt < maxAttempts) {
|
|
1562
|
+
attempt += 1;
|
|
1563
|
+
let coreResult;
|
|
1564
|
+
try {
|
|
1565
|
+
const retryClass = outcome?.ok === false
|
|
1566
|
+
&& (outcome.errorClass === "parse_error"
|
|
1567
|
+
|| outcome.errorClass === "schema_violation")
|
|
1568
|
+
? outcome.errorClass
|
|
1569
|
+
: "parse_error";
|
|
1570
|
+
const promptForAttempt = attempt === 1
|
|
1571
|
+
? systemPrompt
|
|
1572
|
+
: `${systemPrompt}\n\n## Retry\n\n${buildRetryFollowup({
|
|
1573
|
+
errorClass: retryClass,
|
|
1574
|
+
message: outcome?.ok === false ? outcome.message : "",
|
|
1575
|
+
})}`;
|
|
1576
|
+
coreResult = await core.runDelegatedTask({
|
|
1577
|
+
// No integrationKey — runtime helpers tolerate undefined; cores
|
|
1578
|
+
// do not consult this field.
|
|
1579
|
+
systemPrompt: promptForAttempt,
|
|
1580
|
+
validate: validator,
|
|
1581
|
+
validatorErrorMessage: () => (validator.errors ?? [])
|
|
1582
|
+
.map((e) => `${e.instancePath || "/"} ${e.message ?? "invalid"}`)
|
|
1583
|
+
.join("; "),
|
|
1584
|
+
allowedTools,
|
|
1585
|
+
destructiveTools: destructiveToolPatterns,
|
|
1586
|
+
writeClassTools: writeClassToolPatterns,
|
|
1587
|
+
modelId,
|
|
1588
|
+
maxToolCalls: params.maxToolCalls,
|
|
1589
|
+
maxBudgetUsd: params.maxBudgetUsd,
|
|
1590
|
+
timeoutMs: params.timeoutMs,
|
|
1591
|
+
allowDestructive: params.allowDestructive,
|
|
1592
|
+
sessionDir,
|
|
1593
|
+
abortSignal: ac.signal,
|
|
1594
|
+
structuredOutputEnabled,
|
|
1595
|
+
...(wrappedSchema ? { wrappedSchema } : {}),
|
|
1596
|
+
onToolStep: (step) => {
|
|
1597
|
+
this.recordTaskToolStep({
|
|
1598
|
+
parentTaskActionId: headerId,
|
|
1599
|
+
backendId,
|
|
1600
|
+
modelId,
|
|
1601
|
+
step,
|
|
1602
|
+
});
|
|
1603
|
+
},
|
|
1604
|
+
});
|
|
1605
|
+
}
|
|
1606
|
+
catch (err) {
|
|
1607
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1608
|
+
coreResult = {
|
|
1609
|
+
ok: false,
|
|
1610
|
+
errorClass: "subprocess_crashed",
|
|
1611
|
+
message,
|
|
1612
|
+
cost: zeroCost(),
|
|
1613
|
+
trace: [],
|
|
1614
|
+
writeClassToolFired: false,
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
aggregatedTrace = aggregatedTrace.concat(coreResult.trace);
|
|
1618
|
+
aggregatedCost = mergeCost(aggregatedCost, coreResult.cost);
|
|
1619
|
+
writeClassToolFiredEver =
|
|
1620
|
+
writeClassToolFiredEver || coreResult.writeClassToolFired;
|
|
1621
|
+
if (!coreResult.ok) {
|
|
1622
|
+
outcome = {
|
|
1623
|
+
ok: false,
|
|
1624
|
+
errorClass: coreResult.errorClass,
|
|
1625
|
+
message: coreResult.message,
|
|
1626
|
+
...(coreResult.rawAssistantText
|
|
1627
|
+
? { raw: coreResult.rawAssistantText }
|
|
1628
|
+
: {}),
|
|
1629
|
+
cost: aggregatedCost,
|
|
1630
|
+
trace: aggregatedTrace,
|
|
1631
|
+
backendId,
|
|
1632
|
+
modelId,
|
|
1633
|
+
retried,
|
|
1634
|
+
};
|
|
1635
|
+
break;
|
|
1636
|
+
}
|
|
1637
|
+
// §13 Phase 3.1 — structured-output-first path mirrors task().
|
|
1638
|
+
const classification = coreResult.structuredOutput !== undefined
|
|
1639
|
+
? classifyStructuredOutput(coreResult.structuredOutput, validator)
|
|
1640
|
+
: null;
|
|
1641
|
+
if (classification && classification.ok && "envelope" in classification) {
|
|
1642
|
+
if (classification.envelope === "confirmation") {
|
|
1643
|
+
const conf = detectConfirmationEnvelope(classification.value);
|
|
1644
|
+
outcome = {
|
|
1645
|
+
ok: true,
|
|
1646
|
+
result: classification.value,
|
|
1647
|
+
needsConfirmation: true,
|
|
1648
|
+
confirmationPlan: conf?.plan ?? "",
|
|
1649
|
+
cost: aggregatedCost,
|
|
1650
|
+
trace: aggregatedTrace,
|
|
1651
|
+
backendId,
|
|
1652
|
+
modelId,
|
|
1653
|
+
retried,
|
|
1654
|
+
};
|
|
1655
|
+
break;
|
|
1656
|
+
}
|
|
1657
|
+
if (classification.envelope === "error") {
|
|
1658
|
+
const env = detectErrorEnvelope(classification.value);
|
|
1659
|
+
outcome = {
|
|
1660
|
+
ok: false,
|
|
1661
|
+
errorClass: env?.errorClass ?? "tool_failed",
|
|
1662
|
+
message: env?.message ?? "subprocess returned error envelope",
|
|
1663
|
+
raw: JSON.stringify(classification.value),
|
|
1664
|
+
cost: aggregatedCost,
|
|
1665
|
+
trace: aggregatedTrace,
|
|
1666
|
+
backendId,
|
|
1667
|
+
modelId,
|
|
1668
|
+
retried,
|
|
1669
|
+
};
|
|
1670
|
+
break;
|
|
1671
|
+
}
|
|
1672
|
+
outcome = {
|
|
1673
|
+
ok: true,
|
|
1674
|
+
result: classification.value,
|
|
1675
|
+
needsConfirmation: false,
|
|
1676
|
+
confirmationPlan: null,
|
|
1677
|
+
cost: aggregatedCost,
|
|
1678
|
+
trace: aggregatedTrace,
|
|
1679
|
+
backendId,
|
|
1680
|
+
modelId,
|
|
1681
|
+
retried,
|
|
1682
|
+
};
|
|
1683
|
+
break;
|
|
1684
|
+
}
|
|
1685
|
+
if (classification && !classification.ok) {
|
|
1686
|
+
if (writeClassToolFiredEver) {
|
|
1687
|
+
outcome = {
|
|
1688
|
+
ok: false,
|
|
1689
|
+
errorClass: "post_write_format_failure",
|
|
1690
|
+
message: classification.message,
|
|
1691
|
+
raw: classification.raw,
|
|
1692
|
+
cost: aggregatedCost,
|
|
1693
|
+
trace: aggregatedTrace,
|
|
1694
|
+
backendId,
|
|
1695
|
+
modelId,
|
|
1696
|
+
retried,
|
|
1697
|
+
};
|
|
1698
|
+
break;
|
|
1699
|
+
}
|
|
1700
|
+
if (attempt < maxAttempts) {
|
|
1701
|
+
retried = true;
|
|
1702
|
+
outcome = {
|
|
1703
|
+
ok: false,
|
|
1704
|
+
errorClass: classification.errorClass,
|
|
1705
|
+
message: classification.message,
|
|
1706
|
+
raw: classification.raw,
|
|
1707
|
+
cost: aggregatedCost,
|
|
1708
|
+
trace: aggregatedTrace,
|
|
1709
|
+
backendId,
|
|
1710
|
+
modelId,
|
|
1711
|
+
retried,
|
|
1712
|
+
};
|
|
1713
|
+
continue;
|
|
1714
|
+
}
|
|
1715
|
+
outcome = {
|
|
1716
|
+
ok: false,
|
|
1717
|
+
errorClass: classification.errorClass,
|
|
1718
|
+
message: classification.message,
|
|
1719
|
+
raw: classification.raw,
|
|
1720
|
+
cost: aggregatedCost,
|
|
1721
|
+
trace: aggregatedTrace,
|
|
1722
|
+
backendId,
|
|
1723
|
+
modelId,
|
|
1724
|
+
retried,
|
|
1725
|
+
};
|
|
1726
|
+
break;
|
|
1727
|
+
}
|
|
1728
|
+
// Text-extraction fallback (Gemini, or Claude with structured
|
|
1729
|
+
// output disabled).
|
|
1730
|
+
const stripped = coreResult.rawAssistantText;
|
|
1731
|
+
let parsed;
|
|
1732
|
+
try {
|
|
1733
|
+
parsed = JSON.parse(stripCodeFences(stripped));
|
|
1734
|
+
}
|
|
1735
|
+
catch {
|
|
1736
|
+
parsed = null;
|
|
1737
|
+
}
|
|
1738
|
+
const confirmation = parsed != null
|
|
1739
|
+
? detectConfirmationEnvelope(parsed)
|
|
1740
|
+
: null;
|
|
1741
|
+
if (confirmation) {
|
|
1742
|
+
outcome = {
|
|
1743
|
+
ok: true,
|
|
1744
|
+
result: parsed,
|
|
1745
|
+
needsConfirmation: true,
|
|
1746
|
+
confirmationPlan: confirmation.plan,
|
|
1747
|
+
cost: aggregatedCost,
|
|
1748
|
+
trace: aggregatedTrace,
|
|
1749
|
+
backendId,
|
|
1750
|
+
modelId,
|
|
1751
|
+
retried,
|
|
1752
|
+
};
|
|
1753
|
+
break;
|
|
1754
|
+
}
|
|
1755
|
+
const errorEnvelope = parsed != null
|
|
1756
|
+
? detectErrorEnvelope(parsed)
|
|
1757
|
+
: null;
|
|
1758
|
+
if (errorEnvelope) {
|
|
1759
|
+
outcome = {
|
|
1760
|
+
ok: false,
|
|
1761
|
+
errorClass: errorEnvelope.errorClass,
|
|
1762
|
+
message: errorEnvelope.message,
|
|
1763
|
+
raw: stripped,
|
|
1764
|
+
cost: aggregatedCost,
|
|
1765
|
+
trace: aggregatedTrace,
|
|
1766
|
+
backendId,
|
|
1767
|
+
modelId,
|
|
1768
|
+
retried,
|
|
1769
|
+
};
|
|
1770
|
+
break;
|
|
1771
|
+
}
|
|
1772
|
+
const extraction = extractAndValidateResult(stripped, validator);
|
|
1773
|
+
if (extraction.ok) {
|
|
1774
|
+
outcome = {
|
|
1775
|
+
ok: true,
|
|
1776
|
+
result: extraction.value,
|
|
1777
|
+
needsConfirmation: false,
|
|
1778
|
+
confirmationPlan: null,
|
|
1779
|
+
cost: aggregatedCost,
|
|
1780
|
+
trace: aggregatedTrace,
|
|
1781
|
+
backendId,
|
|
1782
|
+
modelId,
|
|
1783
|
+
retried,
|
|
1784
|
+
};
|
|
1785
|
+
break;
|
|
1786
|
+
}
|
|
1787
|
+
if (writeClassToolFiredEver) {
|
|
1788
|
+
outcome = {
|
|
1789
|
+
ok: false,
|
|
1790
|
+
errorClass: "post_write_format_failure",
|
|
1791
|
+
message: extraction.message,
|
|
1792
|
+
raw: extraction.raw,
|
|
1793
|
+
cost: aggregatedCost,
|
|
1794
|
+
trace: aggregatedTrace,
|
|
1795
|
+
backendId,
|
|
1796
|
+
modelId,
|
|
1797
|
+
retried,
|
|
1798
|
+
};
|
|
1799
|
+
break;
|
|
1800
|
+
}
|
|
1801
|
+
if (attempt < maxAttempts) {
|
|
1802
|
+
retried = true;
|
|
1803
|
+
outcome = {
|
|
1804
|
+
ok: false,
|
|
1805
|
+
errorClass: extraction.errorClass,
|
|
1806
|
+
message: extraction.message,
|
|
1807
|
+
raw: extraction.raw,
|
|
1808
|
+
cost: aggregatedCost,
|
|
1809
|
+
trace: aggregatedTrace,
|
|
1810
|
+
backendId,
|
|
1811
|
+
modelId,
|
|
1812
|
+
retried,
|
|
1813
|
+
};
|
|
1814
|
+
continue;
|
|
1815
|
+
}
|
|
1816
|
+
outcome = {
|
|
1817
|
+
ok: false,
|
|
1818
|
+
errorClass: extraction.errorClass,
|
|
1819
|
+
message: extraction.message,
|
|
1820
|
+
raw: extraction.raw,
|
|
1821
|
+
cost: aggregatedCost,
|
|
1822
|
+
trace: aggregatedTrace,
|
|
1823
|
+
backendId,
|
|
1824
|
+
modelId,
|
|
1825
|
+
retried,
|
|
1826
|
+
};
|
|
1827
|
+
break;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
finally {
|
|
1831
|
+
clearTimeout(timeout);
|
|
1832
|
+
params.abortSignal?.removeEventListener("abort", callerListener);
|
|
1833
|
+
// §13 Phase 3.2 — same release/discard rule as task().
|
|
1834
|
+
if (writeClassToolFiredEver) {
|
|
1835
|
+
sessionLease.discard();
|
|
1836
|
+
}
|
|
1837
|
+
else {
|
|
1838
|
+
sessionLease.release();
|
|
1839
|
+
}
|
|
1840
|
+
this.releasePermit();
|
|
1841
|
+
}
|
|
1842
|
+
const completedAtIso = new Date(this.now()).toISOString();
|
|
1843
|
+
// §8.3 — bump the shared per-day quota counter.
|
|
1844
|
+
this.incrementTaskCount(today);
|
|
1845
|
+
// §13 Phase 3.3 — cache write mirrors task(), with `runScope` keyed
|
|
1846
|
+
// off the caller's allowedTools.
|
|
1847
|
+
if (params.cacheable === true
|
|
1848
|
+
&& params.allowDestructive === false
|
|
1849
|
+
&& outcome?.ok === true
|
|
1850
|
+
&& outcome.needsConfirmation === false
|
|
1851
|
+
&& writeClassToolFiredEver === false) {
|
|
1852
|
+
const cache = this.getResultCache();
|
|
1853
|
+
if (cache) {
|
|
1854
|
+
const cacheKey = {
|
|
1855
|
+
scope: runScope(params.allowedTools),
|
|
1856
|
+
task: params.task,
|
|
1857
|
+
outputSchema: params.outputSchema,
|
|
1858
|
+
modelId,
|
|
1859
|
+
backendId,
|
|
1860
|
+
allowDestructive: params.allowDestructive,
|
|
1861
|
+
integrationVersion: "",
|
|
1862
|
+
};
|
|
1863
|
+
cache.set(cacheKey, {
|
|
1864
|
+
result: outcome.result,
|
|
1865
|
+
needsConfirmation: false,
|
|
1866
|
+
confirmationPlan: null,
|
|
1867
|
+
cost: aggregatedCost,
|
|
1868
|
+
trace: aggregatedTrace,
|
|
1869
|
+
backendId,
|
|
1870
|
+
modelId,
|
|
1871
|
+
retried: false,
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
// §11.1 — finalise the header row.
|
|
1876
|
+
this.completeTaskHeader({
|
|
1877
|
+
headerId,
|
|
1878
|
+
result: outcome?.ok ? "success" : "failed",
|
|
1879
|
+
cost: aggregatedCost,
|
|
1880
|
+
completedAt: completedAtIso,
|
|
1881
|
+
errorClass: outcome?.ok === false ? outcome.errorClass : null,
|
|
1882
|
+
errorMessage: outcome?.ok === false ? outcome.message : null,
|
|
1883
|
+
retried,
|
|
1884
|
+
toolCallCount: aggregatedTrace.length,
|
|
1885
|
+
detail: {
|
|
1886
|
+
delegatedBackend: backendId,
|
|
1887
|
+
taskHash,
|
|
1888
|
+
schemaHash,
|
|
1889
|
+
allowedToolsHash,
|
|
1890
|
+
allowedToolsCount: allowedTools.length,
|
|
1891
|
+
toolCallCount: aggregatedTrace.length,
|
|
1892
|
+
retried,
|
|
1893
|
+
// §11.2 — see /exec equivalent above.
|
|
1894
|
+
needsConfirmation: outcome?.ok === true && outcome.needsConfirmation === true,
|
|
1895
|
+
...(outcome?.ok === false ? { errorClass: outcome.errorClass } : {}),
|
|
1896
|
+
},
|
|
1897
|
+
});
|
|
1898
|
+
// §11.3 — one INFO line per /run task.
|
|
1899
|
+
logger.info({
|
|
1900
|
+
backendId,
|
|
1901
|
+
modelId,
|
|
1902
|
+
taskLen: params.task.length,
|
|
1903
|
+
toolCallCount: aggregatedTrace.length,
|
|
1904
|
+
costUsd: aggregatedCost.costUsd,
|
|
1905
|
+
durationMs: aggregatedCost.durationMs,
|
|
1906
|
+
allowedToolsCount: allowedTools.length,
|
|
1907
|
+
result: outcome?.ok ? "success" : "failed",
|
|
1908
|
+
...(outcome?.ok === false ? { errorClass: outcome.errorClass } : {}),
|
|
1909
|
+
...(outcome?.ok === true && outcome.needsConfirmation === true
|
|
1910
|
+
? { needsConfirmation: true }
|
|
1911
|
+
: {}),
|
|
1912
|
+
retried,
|
|
1913
|
+
}, "delegated run task complete");
|
|
1914
|
+
if (!outcome) {
|
|
1915
|
+
return {
|
|
1916
|
+
ok: false,
|
|
1917
|
+
errorClass: "subprocess_crashed",
|
|
1918
|
+
message: "task settled without producing an outcome",
|
|
1919
|
+
backendId,
|
|
1920
|
+
modelId,
|
|
1921
|
+
cost: aggregatedCost,
|
|
1922
|
+
trace: aggregatedTrace,
|
|
1923
|
+
retried,
|
|
1924
|
+
};
|
|
1925
|
+
}
|
|
1926
|
+
return outcome;
|
|
1927
|
+
}
|
|
1928
|
+
/**
|
|
1929
|
+
* §13 Phase 3.3 — cache-hit synthesizer for `/run`. Same shape as
|
|
1930
|
+
* `buildCacheHitTaskResult` but writes a `delegated_task.run` audit row.
|
|
1931
|
+
*/
|
|
1932
|
+
buildCacheHitRunResult(args) {
|
|
1933
|
+
const nowIso = new Date(this.now()).toISOString();
|
|
1934
|
+
const taskHash = hashTaskArgs(args.params.task);
|
|
1935
|
+
const schemaHash = hashTaskArgs(args.params.outputSchema);
|
|
1936
|
+
const allowedToolsHash = hashTaskArgs(args.params.allowedTools);
|
|
1937
|
+
this.recordCacheHitAuditRow({
|
|
1938
|
+
actionType: "delegated_task.run",
|
|
1939
|
+
backendId: args.backendId,
|
|
1940
|
+
modelId: args.modelId,
|
|
1941
|
+
...(args.params.parentEventId !== undefined
|
|
1942
|
+
? { parentEventId: args.params.parentEventId }
|
|
1943
|
+
: {}),
|
|
1944
|
+
...(args.params.parentProcessKey !== undefined
|
|
1945
|
+
? { parentProcessKey: args.params.parentProcessKey }
|
|
1946
|
+
: {}),
|
|
1947
|
+
timestamp: nowIso,
|
|
1948
|
+
toolCallCount: args.hit.trace.length,
|
|
1949
|
+
detail: {
|
|
1950
|
+
delegatedBackend: args.backendId,
|
|
1951
|
+
taskHash,
|
|
1952
|
+
schemaHash,
|
|
1953
|
+
allowedToolsHash,
|
|
1954
|
+
allowedToolsCount: args.params.allowedTools.length,
|
|
1955
|
+
cacheHit: true,
|
|
1956
|
+
toolCallCount: args.hit.trace.length,
|
|
1957
|
+
retried: false,
|
|
1958
|
+
// §11.2 — see /exec equivalent.
|
|
1959
|
+
needsConfirmation: false,
|
|
1960
|
+
},
|
|
1961
|
+
});
|
|
1962
|
+
return {
|
|
1963
|
+
ok: true,
|
|
1964
|
+
result: args.hit.result,
|
|
1965
|
+
needsConfirmation: false,
|
|
1966
|
+
confirmationPlan: null,
|
|
1967
|
+
cost: zeroCost(),
|
|
1968
|
+
trace: args.hit.trace,
|
|
1969
|
+
backendId: args.backendId,
|
|
1970
|
+
modelId: args.modelId,
|
|
1971
|
+
retried: false,
|
|
1972
|
+
};
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* Resolve the model for a task-mode call.
|
|
1976
|
+
*
|
|
1977
|
+
* §8.1 resolution order — first match wins:
|
|
1978
|
+
* 1. `process_backend_config(delegated_task | delegated_task_heavy)`
|
|
1979
|
+
* with `main_backend == backendId` — honors dashboard-configured
|
|
1980
|
+
* per-process model pins (e.g. user pins Haiku 4.5 for
|
|
1981
|
+
* `delegated_task` on Claude). The ProcessKey constants
|
|
1982
|
+
* `delegated_task` / `delegated_task_heavy` exist in
|
|
1983
|
+
* `packages/shared/src/process-key.ts:51-52` precisely so the
|
|
1984
|
+
* dashboard's process-config surface can target them.
|
|
1985
|
+
* 2. Heavy: first registered heavy-tier model for the backend.
|
|
1986
|
+
* Light: canonical proxy model (`backend_global_defaults` →
|
|
1987
|
+
* registry default).
|
|
1988
|
+
* 3. First registered model on the live core (`auto` if none — keeps
|
|
1989
|
+
* the call alive when a backend's registry is mid-rotation).
|
|
1990
|
+
*
|
|
1991
|
+
* Heavy is opt-in via `config.delegatedTaskHeavyEnabled`; when the
|
|
1992
|
+
* config flag is `false` the heavy ProcessKey falls through to light.
|
|
1993
|
+
*/
|
|
1994
|
+
resolveTaskModel(backendId, heavy) {
|
|
1995
|
+
const useHeavy = heavy && this.deps.config.delegatedTaskHeavyEnabled;
|
|
1996
|
+
const processKey = useHeavy ? "delegated_task_heavy" : "delegated_task";
|
|
1997
|
+
// Step 1: dashboard / process_backend_config override.
|
|
1998
|
+
const pinned = resolveProcessKeyModel(this.deps.db, processKey, backendId);
|
|
1999
|
+
if (pinned)
|
|
2000
|
+
return pinned;
|
|
2001
|
+
// Step 2: heavy-task fallback to first registered high-tier model.
|
|
2002
|
+
if (useHeavy) {
|
|
2003
|
+
const core = this.deps.cores[backendId];
|
|
2004
|
+
const models = core?.listModels?.() ?? [];
|
|
2005
|
+
const highModel = models.find((m) => m.tier === "high");
|
|
2006
|
+
if (highModel)
|
|
2007
|
+
return highModel.modelId;
|
|
2008
|
+
}
|
|
2009
|
+
// Step 3: canonical lite-tier delegated model (registry + global default).
|
|
2010
|
+
const canonical = resolveCanonicalDelegatedModel(backendId, this.deps.db);
|
|
2011
|
+
if (canonical)
|
|
2012
|
+
return canonical;
|
|
2013
|
+
// Step 4: live-core fallback.
|
|
2014
|
+
const core = this.deps.cores[backendId];
|
|
2015
|
+
const models = core?.listModels?.() ?? [];
|
|
2016
|
+
if (models.length > 0) {
|
|
2017
|
+
const lite = models.find((m) => m.tier === "lite");
|
|
2018
|
+
return (lite ?? models[0]).modelId;
|
|
2019
|
+
}
|
|
2020
|
+
return "auto";
|
|
2021
|
+
}
|
|
2022
|
+
// ── Per-day task-mode quota counter ───────────────────────────────────────
|
|
2023
|
+
readTaskCount(today) {
|
|
2024
|
+
const state = readRuntimeState(this.deps.db, DELEGATED_TASK_COUNT_STATE_KEY);
|
|
2025
|
+
if (!state || state.date !== today)
|
|
2026
|
+
return 0;
|
|
2027
|
+
return state.count;
|
|
2028
|
+
}
|
|
2029
|
+
incrementTaskCount(today) {
|
|
2030
|
+
try {
|
|
2031
|
+
const state = readRuntimeState(this.deps.db, DELEGATED_TASK_COUNT_STATE_KEY);
|
|
2032
|
+
const nextCount = state && state.date === today ? state.count + 1 : 1;
|
|
2033
|
+
writeRuntimeState(this.deps.db, DELEGATED_TASK_COUNT_STATE_KEY, {
|
|
2034
|
+
date: today,
|
|
2035
|
+
count: nextCount,
|
|
2036
|
+
});
|
|
2037
|
+
}
|
|
2038
|
+
catch (err) {
|
|
2039
|
+
logger.warn({ err }, "failed to increment delegated task quota counter");
|
|
2040
|
+
}
|
|
2041
|
+
}
|
|
2042
|
+
// ── agent_actions header / step persistence ───────────────────────────────
|
|
2043
|
+
/**
|
|
2044
|
+
* §13 Phase 3.3 — single-shot INSERT for cache-hit audit rows. Cache
|
|
2045
|
+
* hits don't go through the in-progress → complete two-step lifecycle
|
|
2046
|
+
* (the outcome is known synchronously), so this writes one row with
|
|
2047
|
+
* `result='success'`, `cost_usd=0`, `cost_source='cache'` for clean
|
|
2048
|
+
* dashboard cost-source filtering.
|
|
2049
|
+
*/
|
|
2050
|
+
recordCacheHitAuditRow(args) {
|
|
2051
|
+
try {
|
|
2052
|
+
const result = this.deps.db
|
|
2053
|
+
.prepare(`INSERT INTO agent_actions (
|
|
2054
|
+
event_id, action_type, trigger, model_used,
|
|
2055
|
+
cost_usd, tokens_input, tokens_output,
|
|
2056
|
+
cache_creation_tokens, cache_read_tokens,
|
|
2057
|
+
duration_ms, num_turns, result, detail,
|
|
2058
|
+
started_at, completed_at, error, backend, cost_source
|
|
2059
|
+
) VALUES (
|
|
2060
|
+
@event_id, @action_type, @trigger, @model_used,
|
|
2061
|
+
0, 0, 0, 0, 0,
|
|
2062
|
+
0, @num_turns, 'success', @detail,
|
|
2063
|
+
datetime(@ts), datetime(@ts), NULL, @backend, 'cache'
|
|
2064
|
+
)`)
|
|
2065
|
+
.run({
|
|
2066
|
+
event_id: args.parentEventId ?? null,
|
|
2067
|
+
action_type: args.actionType,
|
|
2068
|
+
trigger: args.parentProcessKey ?? null,
|
|
2069
|
+
model_used: args.modelId,
|
|
2070
|
+
num_turns: args.toolCallCount,
|
|
2071
|
+
detail: JSON.stringify(args.detail),
|
|
2072
|
+
ts: args.timestamp,
|
|
2073
|
+
backend: args.backendId,
|
|
2074
|
+
});
|
|
2075
|
+
return Number(result.lastInsertRowid);
|
|
2076
|
+
}
|
|
2077
|
+
catch (err) {
|
|
2078
|
+
logger.error({ err, actionType: args.actionType, detail: args.detail }, "failed to write delegated_task cache-hit audit row");
|
|
2079
|
+
return -1;
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
recordTaskHeaderInProgress(args) {
|
|
2083
|
+
try {
|
|
2084
|
+
const result = this.deps.db
|
|
2085
|
+
.prepare(`INSERT INTO agent_actions (
|
|
2086
|
+
event_id, action_type, trigger, model_used,
|
|
2087
|
+
cost_usd, tokens_input, tokens_output,
|
|
2088
|
+
cache_creation_tokens, cache_read_tokens,
|
|
2089
|
+
duration_ms, num_turns, result, detail,
|
|
2090
|
+
started_at, completed_at, error, backend, cost_source
|
|
2091
|
+
) VALUES (
|
|
2092
|
+
@event_id, @action_type, @trigger, @model_used,
|
|
2093
|
+
0, 0, 0, 0, 0,
|
|
2094
|
+
0, 0, 'in_progress', @detail,
|
|
2095
|
+
datetime(@started_at), NULL, NULL, @backend, 'sdk'
|
|
2096
|
+
)`)
|
|
2097
|
+
.run({
|
|
2098
|
+
event_id: args.parentEventId ?? null,
|
|
2099
|
+
action_type: args.actionType,
|
|
2100
|
+
trigger: args.parentProcessKey ?? null,
|
|
2101
|
+
model_used: args.modelId,
|
|
2102
|
+
detail: JSON.stringify(args.detail),
|
|
2103
|
+
started_at: args.startedAt,
|
|
2104
|
+
backend: args.backendId,
|
|
2105
|
+
});
|
|
2106
|
+
return Number(result.lastInsertRowid);
|
|
2107
|
+
}
|
|
2108
|
+
catch (err) {
|
|
2109
|
+
logger.error({ err, actionType: args.actionType, detail: args.detail }, "failed to write delegated_task header row");
|
|
2110
|
+
return -1;
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
completeTaskHeader(args) {
|
|
2114
|
+
if (args.headerId < 0)
|
|
2115
|
+
return;
|
|
2116
|
+
try {
|
|
2117
|
+
this.deps.db
|
|
2118
|
+
.prepare(`UPDATE agent_actions SET
|
|
2119
|
+
result = @result,
|
|
2120
|
+
cost_usd = @cost_usd,
|
|
2121
|
+
tokens_input = @tokens_input,
|
|
2122
|
+
tokens_output = @tokens_output,
|
|
2123
|
+
cache_creation_tokens = @cache_creation_tokens,
|
|
2124
|
+
cache_read_tokens = @cache_read_tokens,
|
|
2125
|
+
duration_ms = @duration_ms,
|
|
2126
|
+
num_turns = @num_turns,
|
|
2127
|
+
completed_at = datetime(@completed_at),
|
|
2128
|
+
error = @error,
|
|
2129
|
+
detail = @detail
|
|
2130
|
+
WHERE id = @id`)
|
|
2131
|
+
.run({
|
|
2132
|
+
id: args.headerId,
|
|
2133
|
+
result: args.result,
|
|
2134
|
+
cost_usd: args.cost.costUsd,
|
|
2135
|
+
tokens_input: args.cost.tokensInput,
|
|
2136
|
+
tokens_output: args.cost.tokensOutput,
|
|
2137
|
+
cache_creation_tokens: args.cost.cacheCreationTokens,
|
|
2138
|
+
cache_read_tokens: args.cost.cacheReadTokens,
|
|
2139
|
+
duration_ms: args.cost.durationMs,
|
|
2140
|
+
num_turns: args.cost.numTurns,
|
|
2141
|
+
completed_at: args.completedAt,
|
|
2142
|
+
error: args.errorMessage,
|
|
2143
|
+
detail: JSON.stringify(args.detail),
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2146
|
+
catch (err) {
|
|
2147
|
+
logger.error({ err, headerId: args.headerId }, "failed to update delegated_task.exec header row");
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
recordTaskToolStep(args) {
|
|
2151
|
+
try {
|
|
2152
|
+
this.deps.db
|
|
2153
|
+
.prepare(`INSERT INTO agent_actions (
|
|
2154
|
+
action_type, trigger, model_used,
|
|
2155
|
+
cost_usd, tokens_input, tokens_output,
|
|
2156
|
+
cache_creation_tokens, cache_read_tokens,
|
|
2157
|
+
duration_ms, num_turns, result, detail,
|
|
2158
|
+
started_at, completed_at, error, backend, cost_source
|
|
2159
|
+
) VALUES (
|
|
2160
|
+
'delegated_task.tool_step', NULL, @model_used,
|
|
2161
|
+
@cost_usd, @tokens_input, @tokens_output,
|
|
2162
|
+
0, 0,
|
|
2163
|
+
@duration_ms, 1, @result, @detail,
|
|
2164
|
+
datetime('now'), datetime('now'), @error, @backend, 'sdk'
|
|
2165
|
+
)`)
|
|
2166
|
+
.run({
|
|
2167
|
+
model_used: args.modelId,
|
|
2168
|
+
cost_usd: args.step.costUsd,
|
|
2169
|
+
tokens_input: args.step.tokensInput,
|
|
2170
|
+
tokens_output: args.step.tokensOutput,
|
|
2171
|
+
duration_ms: args.step.durationMs,
|
|
2172
|
+
result: args.step.status === "ok" ? "success" : "failed",
|
|
2173
|
+
detail: JSON.stringify({
|
|
2174
|
+
...(args.integrationKey ? { integrationKey: args.integrationKey } : {}),
|
|
2175
|
+
toolName: args.step.toolName,
|
|
2176
|
+
toolArgsHash: hashTaskArgs(args.step.toolArgs),
|
|
2177
|
+
toolStatus: args.step.status,
|
|
2178
|
+
parentTaskActionId: args.parentTaskActionId,
|
|
2179
|
+
}),
|
|
2180
|
+
error: args.step.status === "error" ? "tool_step_error" : null,
|
|
2181
|
+
backend: args.backendId,
|
|
2182
|
+
});
|
|
2183
|
+
}
|
|
2184
|
+
catch (err) {
|
|
2185
|
+
logger.warn({ err, parentTaskActionId: args.parentTaskActionId }, "failed to write delegated_task.tool_step row");
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
/**
|
|
2190
|
+
* §13 Phase 3.2 — synthetic lease used when pooling is disabled. Implements
|
|
2191
|
+
* the same `release()` / `discard()` shape as `SessionPoolLease` so the
|
|
2192
|
+
* task() / run() loop doesn't have to branch on whether pooling is active.
|
|
2193
|
+
* Both methods clean up the tempdir (no TTL semantics — there's no pool
|
|
2194
|
+
* to return to).
|
|
2195
|
+
*/
|
|
2196
|
+
class LegacyOneShotLease {
|
|
2197
|
+
sessionDir;
|
|
2198
|
+
cleanup;
|
|
2199
|
+
fromPool = false;
|
|
2200
|
+
released = false;
|
|
2201
|
+
constructor(sessionDir, cleanup) {
|
|
2202
|
+
this.sessionDir = sessionDir;
|
|
2203
|
+
this.cleanup = cleanup;
|
|
2204
|
+
}
|
|
2205
|
+
release() {
|
|
2206
|
+
if (this.released)
|
|
2207
|
+
return;
|
|
2208
|
+
this.released = true;
|
|
2209
|
+
this.cleanup();
|
|
2210
|
+
}
|
|
2211
|
+
discard() {
|
|
2212
|
+
if (this.released)
|
|
2213
|
+
return;
|
|
2214
|
+
this.released = true;
|
|
2215
|
+
this.cleanup();
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
const FALLBACK_PROXY_PROFILE = `# Delegated Proxy
|
|
2219
|
+
|
|
2220
|
+
Call the named tool exactly once with the JSON arguments given verbatim.
|
|
2221
|
+
Do not narrate, do not summarize, do not call any other tool — with one
|
|
2222
|
+
exception: if the named tool's schema is not yet loaded, call ToolSearch
|
|
2223
|
+
to load it, then immediately call the named tool. Do not browse other
|
|
2224
|
+
tools. If the tool errors, return the error verbatim.
|
|
2225
|
+
`;
|
|
2226
|
+
function readFileSyncIfExists(path) {
|
|
2227
|
+
if (!existsSync(path))
|
|
2228
|
+
return null;
|
|
2229
|
+
return readFileSync(path, "utf-8");
|
|
2230
|
+
}
|
|
2231
|
+
function hashArgs(args) {
|
|
2232
|
+
try {
|
|
2233
|
+
const serialized = JSON.stringify(args ?? null);
|
|
2234
|
+
return createHash("sha256")
|
|
2235
|
+
.update(serialized)
|
|
2236
|
+
.digest("hex")
|
|
2237
|
+
.slice(0, 16);
|
|
2238
|
+
}
|
|
2239
|
+
catch {
|
|
2240
|
+
return "unhashable";
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
function zeroCost() {
|
|
2244
|
+
return {
|
|
2245
|
+
tokensInput: 0,
|
|
2246
|
+
tokensOutput: 0,
|
|
2247
|
+
cacheCreationTokens: 0,
|
|
2248
|
+
cacheReadTokens: 0,
|
|
2249
|
+
costUsd: 0,
|
|
2250
|
+
durationMs: 0,
|
|
2251
|
+
numTurns: 0,
|
|
2252
|
+
};
|
|
2253
|
+
}
|
|
2254
|
+
function mergeCost(a, b) {
|
|
2255
|
+
return {
|
|
2256
|
+
tokensInput: a.tokensInput + b.tokensInput,
|
|
2257
|
+
tokensOutput: a.tokensOutput + b.tokensOutput,
|
|
2258
|
+
cacheCreationTokens: a.cacheCreationTokens + b.cacheCreationTokens,
|
|
2259
|
+
cacheReadTokens: a.cacheReadTokens + b.cacheReadTokens,
|
|
2260
|
+
costUsd: a.costUsd + b.costUsd,
|
|
2261
|
+
durationMs: a.durationMs + b.durationMs,
|
|
2262
|
+
numTurns: a.numTurns + b.numTurns,
|
|
2263
|
+
};
|
|
2264
|
+
}
|
|
2265
|
+
/**
|
|
2266
|
+
* Local copy of the runtime helper's fence stripper to avoid cycle —
|
|
2267
|
+
* `delegated-task-runtime.ts` already exports the canonical version, but
|
|
2268
|
+
* importing it here would cycle (the runtime imports types from this
|
|
2269
|
+
* file's `agent-core.ts` chain). Tiny duplication is the cleanest fix.
|
|
2270
|
+
*/
|
|
2271
|
+
function stripCodeFences(input) {
|
|
2272
|
+
let s = input.trim();
|
|
2273
|
+
const fenceRe = /^```(?:json|JSON|jsonc|JSONC)?\s*\r?\n([\s\S]*?)\r?\n```$/;
|
|
2274
|
+
const m = s.match(fenceRe);
|
|
2275
|
+
if (m)
|
|
2276
|
+
return m[1];
|
|
2277
|
+
s = s.replace(/^```(?:json|JSON|jsonc|JSONC)?\s*\r?\n/, "");
|
|
2278
|
+
s = s.replace(/\r?\n```\s*$/, "");
|
|
2279
|
+
return s;
|
|
2280
|
+
}
|
|
2281
|
+
/**
|
|
2282
|
+
* DELEGATED-TASK-MODE-DESIGN.md §8.3 — runtime_state key for the per-day
|
|
2283
|
+
* task-mode quota counter. Resets at the agent-day boundary; mirrors the
|
|
2284
|
+
* Gemini per-day request counter shape.
|
|
2285
|
+
*/
|
|
2286
|
+
const DELEGATED_TASK_COUNT_STATE_KEY = "delegated_task_count_today";
|
|
2287
|
+
/**
|
|
2288
|
+
* DELEGATED-TASK-MODE-DESIGN.md §11.1 crash safety — boot-time janitor
|
|
2289
|
+
* that flips orphaned `delegated_task.exec` rows older than `maxAgeMs`
|
|
2290
|
+
* (default 5 min) from `result='in_progress'` to `result='failed'` with
|
|
2291
|
+
* `error='subprocess_orphaned'`. Without this, a daemon crash mid-task
|
|
2292
|
+
* leaves the row in flight forever and poisons the dashboard's "in-flight
|
|
2293
|
+
* task" counter.
|
|
2294
|
+
*
|
|
2295
|
+
* Returns the number of rows updated.
|
|
2296
|
+
*/
|
|
2297
|
+
export function runDelegatedTaskOrphanJanitor(db, options = {}) {
|
|
2298
|
+
const maxAgeMs = options.maxAgeMs ?? DELEGATED_PROXY_DEFAULTS.janitorMaxAgeMs;
|
|
2299
|
+
const cutoffMs = (options.now?.() ?? Date.now()) - maxAgeMs;
|
|
2300
|
+
const cutoffIso = new Date(cutoffMs).toISOString();
|
|
2301
|
+
try {
|
|
2302
|
+
const result = db
|
|
2303
|
+
.prepare(`UPDATE agent_actions SET
|
|
2304
|
+
result = 'failed',
|
|
2305
|
+
error = 'subprocess_orphaned',
|
|
2306
|
+
completed_at = datetime('now')
|
|
2307
|
+
WHERE action_type IN ('delegated_task.exec', 'delegated_task.run', 'delegated_task.tool_step')
|
|
2308
|
+
AND result = 'in_progress'
|
|
2309
|
+
AND started_at < datetime(?)`)
|
|
2310
|
+
.run(cutoffIso);
|
|
2311
|
+
if (result.changes > 0) {
|
|
2312
|
+
logger.info({ changes: result.changes }, "delegated task janitor: closed orphaned in-progress rows");
|
|
2313
|
+
}
|
|
2314
|
+
return result.changes;
|
|
2315
|
+
}
|
|
2316
|
+
catch (err) {
|
|
2317
|
+
logger.warn({ err }, "delegated task janitor: SQL update failed");
|
|
2318
|
+
return 0;
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Boot-time janitor — scans the sessions root for orphan `proxy-*` dirs
|
|
2323
|
+
* older than the configured threshold and removes them. Covers the SIGKILL
|
|
2324
|
+
* mid-call case the per-call `finally` cannot. Safe to call before any
|
|
2325
|
+
* invocations have happened.
|
|
2326
|
+
*
|
|
2327
|
+
* Returns the number of directories removed (for logging at startup).
|
|
2328
|
+
*/
|
|
2329
|
+
export function runProxyTempdirJanitor(dataDir, options = {}) {
|
|
2330
|
+
const now = options.now ?? Date.now;
|
|
2331
|
+
const maxAgeMs = options.maxAgeMs ?? DELEGATED_PROXY_DEFAULTS.janitorMaxAgeMs;
|
|
2332
|
+
const root = join(dataDir, "agent-sessions");
|
|
2333
|
+
if (!existsSync(root))
|
|
2334
|
+
return 0;
|
|
2335
|
+
let removed = 0;
|
|
2336
|
+
let entries;
|
|
2337
|
+
try {
|
|
2338
|
+
entries = readdirSync(root);
|
|
2339
|
+
}
|
|
2340
|
+
catch (err) {
|
|
2341
|
+
logger.warn({ err, root }, "proxy janitor: readdir failed");
|
|
2342
|
+
return 0;
|
|
2343
|
+
}
|
|
2344
|
+
for (const entry of entries) {
|
|
2345
|
+
if (!entry.startsWith(DELEGATED_PROXY_DEFAULTS.tempdirPrefix))
|
|
2346
|
+
continue;
|
|
2347
|
+
const path = join(root, entry);
|
|
2348
|
+
let stat;
|
|
2349
|
+
try {
|
|
2350
|
+
stat = statSync(path);
|
|
2351
|
+
}
|
|
2352
|
+
catch {
|
|
2353
|
+
continue;
|
|
2354
|
+
}
|
|
2355
|
+
if (!stat.isDirectory())
|
|
2356
|
+
continue;
|
|
2357
|
+
if (now() - stat.mtimeMs < maxAgeMs)
|
|
2358
|
+
continue;
|
|
2359
|
+
try {
|
|
2360
|
+
rmSync(path, { recursive: true, force: true });
|
|
2361
|
+
removed++;
|
|
2362
|
+
}
|
|
2363
|
+
catch (err) {
|
|
2364
|
+
logger.warn({ err, path }, "proxy janitor: rm failed");
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
if (removed > 0) {
|
|
2368
|
+
logger.info({ removed }, "proxy janitor: removed orphan tempdirs");
|
|
2369
|
+
}
|
|
2370
|
+
return removed;
|
|
2371
|
+
}
|
|
2372
|
+
//# sourceMappingURL=delegated-backend-invoker.js.map
|