@capybara-hq/kernel 0.0.0-stage → 0.1.0-rc.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 +202 -0
- package/NOTICE +2 -0
- package/README.md +20 -2
- package/bootstrap.json +22 -0
- package/dist/admin/admin.controller.d.ts +139 -0
- package/dist/admin/admin.controller.js +238 -0
- package/dist/admin/extensions.controller.d.ts +100 -0
- package/dist/admin/extensions.controller.js +226 -0
- package/dist/admin/setup.controller.d.ts +36 -0
- package/dist/admin/setup.controller.js +106 -0
- package/dist/admin/setup.service.d.ts +47 -0
- package/dist/admin/setup.service.js +90 -0
- package/dist/agents/agents.controller.d.ts +205 -0
- package/dist/agents/agents.controller.js +144 -0
- package/dist/agents/agents.service.d.ts +177 -0
- package/dist/agents/agents.service.js +677 -0
- package/dist/agents/definition.d.ts +198 -0
- package/dist/agents/definition.js +152 -0
- package/dist/agents/models.controller.d.ts +13 -0
- package/dist/agents/models.controller.js +31 -0
- package/dist/agents/templates.controller.d.ts +15 -0
- package/dist/agents/templates.controller.js +37 -0
- package/dist/agents/templates.d.ts +83 -0
- package/dist/agents/templates.js +173 -0
- package/dist/catalog/admin-catalog.controller.d.ts +143 -0
- package/dist/catalog/admin-catalog.controller.js +245 -0
- package/dist/catalog/catalog.service.d.ts +430 -0
- package/dist/catalog/catalog.service.js +882 -0
- package/dist/catalog/claude/agents.d.ts +27 -0
- package/dist/catalog/claude/agents.js +270 -0
- package/dist/catalog/claude/commands.d.ts +50 -0
- package/dist/catalog/claude/commands.js +179 -0
- package/dist/catalog/claude/manifest.d.ts +69 -0
- package/dist/catalog/claude/manifest.js +134 -0
- package/dist/catalog/claude/marketplace.d.ts +35 -0
- package/dist/catalog/claude/marketplace.js +194 -0
- package/dist/catalog/claude/mcp.d.ts +33 -0
- package/dist/catalog/claude/mcp.js +226 -0
- package/dist/catalog/claude/report.d.ts +86 -0
- package/dist/catalog/claude/report.js +121 -0
- package/dist/catalog/claude/translate.d.ts +56 -0
- package/dist/catalog/claude/translate.js +857 -0
- package/dist/catalog/cli.d.ts +46 -0
- package/dist/catalog/cli.js +211 -0
- package/dist/catalog/git-source.d.ts +127 -0
- package/dist/catalog/git-source.js +520 -0
- package/dist/catalog/marketplace-fetch.d.ts +99 -0
- package/dist/catalog/marketplace-fetch.js +203 -0
- package/dist/catalog/marketplaces.controller.d.ts +97 -0
- package/dist/catalog/marketplaces.controller.js +197 -0
- package/dist/catalog/marketplaces.service.d.ts +340 -0
- package/dist/catalog/marketplaces.service.js +1217 -0
- package/dist/catalog/org-catalog.controller.d.ts +128 -0
- package/dist/catalog/org-catalog.controller.js +277 -0
- package/dist/catalog/org-catalog.service.d.ts +246 -0
- package/dist/catalog/org-catalog.service.js +625 -0
- package/dist/catalog/plugin-import.d.ts +436 -0
- package/dist/catalog/plugin-import.js +1069 -0
- package/dist/catalog/plugin-install.d.ts +447 -0
- package/dist/catalog/plugin-install.js +1333 -0
- package/dist/catalog/plugin-package.d.ts +143 -0
- package/dist/catalog/plugin-package.js +382 -0
- package/dist/catalog/plugin-upgrade.d.ts +222 -0
- package/dist/catalog/plugin-upgrade.js +1219 -0
- package/dist/catalog/requests.service.d.ts +162 -0
- package/dist/catalog/requests.service.js +504 -0
- package/dist/catalog/schema-path.d.ts +7 -0
- package/dist/catalog/schema-path.js +63 -0
- package/dist/catalog/upgrade-targets.d.ts +59 -0
- package/dist/catalog/upgrade-targets.js +90 -0
- package/dist/catalog/versions.d.ts +31 -0
- package/dist/catalog/versions.js +44 -0
- package/dist/channels/actions.d.ts +37 -0
- package/dist/channels/actions.js +121 -0
- package/dist/channels/cards.d.ts +44 -0
- package/dist/channels/cards.js +156 -0
- package/dist/channels/connections.controller.d.ts +59 -0
- package/dist/channels/connections.controller.js +115 -0
- package/dist/channels/connections.service.d.ts +187 -0
- package/dist/channels/connections.service.js +534 -0
- package/dist/channels/features.d.ts +12 -0
- package/dist/channels/features.js +22 -0
- package/dist/channels/inbound.d.ts +120 -0
- package/dist/channels/inbound.js +332 -0
- package/dist/channels/outbound.d.ts +140 -0
- package/dist/channels/outbound.js +1125 -0
- package/dist/channels/phrases.d.ts +100 -0
- package/dist/channels/phrases.js +81 -0
- package/dist/channels/supervisor.d.ts +182 -0
- package/dist/channels/supervisor.js +625 -0
- package/dist/channels/threads.d.ts +29 -0
- package/dist/channels/threads.js +104 -0
- package/dist/channels/webhook-url.d.ts +16 -0
- package/dist/channels/webhook-url.js +34 -0
- package/dist/channels/webhook.controller.d.ts +19 -0
- package/dist/channels/webhook.controller.js +72 -0
- package/dist/channels/webhook.d.ts +73 -0
- package/dist/channels/webhook.js +274 -0
- package/dist/config/docs.d.ts +9 -0
- package/dist/config/docs.js +85 -0
- package/dist/config/env.d.ts +6 -0
- package/dist/config/env.js +73 -0
- package/dist/config/fields.d.ts +42 -0
- package/dist/config/fields.js +214 -0
- package/dist/config/file-source.d.ts +3 -0
- package/dist/config/file-source.js +31 -0
- package/dist/config/load.d.ts +20 -0
- package/dist/config/load.js +98 -0
- package/dist/config/nacos-source.d.ts +31 -0
- package/dist/config/nacos-source.js +229 -0
- package/dist/config/schema.d.ts +223 -0
- package/dist/config/schema.js +1151 -0
- package/dist/config/sources.d.ts +18 -0
- package/dist/config/sources.js +59 -0
- package/dist/config/types.d.ts +9 -0
- package/dist/config/types.js +7 -0
- package/dist/conversations/artifacts.d.ts +52 -0
- package/dist/conversations/artifacts.js +137 -0
- package/dist/conversations/attachments.controller.d.ts +28 -0
- package/dist/conversations/attachments.controller.js +96 -0
- package/dist/conversations/attachments.service.d.ts +180 -0
- package/dist/conversations/attachments.service.js +578 -0
- package/dist/conversations/conversations.controller.d.ts +288 -0
- package/dist/conversations/conversations.controller.js +607 -0
- package/dist/conversations/conversations.service.d.ts +321 -0
- package/dist/conversations/conversations.service.js +754 -0
- package/dist/conversations/event-log.d.ts +122 -0
- package/dist/conversations/event-log.js +259 -0
- package/dist/conversations/events.d.ts +856 -0
- package/dist/conversations/events.js +639 -0
- package/dist/conversations/files.d.ts +92 -0
- package/dist/conversations/files.js +213 -0
- package/dist/conversations/outputs-read.d.ts +34 -0
- package/dist/conversations/outputs-read.js +37 -0
- package/dist/conversations/queue.d.ts +169 -0
- package/dist/conversations/queue.js +527 -0
- package/dist/conversations/sandbox-status.d.ts +21 -0
- package/dist/conversations/sandbox-status.js +24 -0
- package/dist/conversations/selection.d.ts +46 -0
- package/dist/conversations/selection.js +75 -0
- package/dist/conversations/titles.d.ts +93 -0
- package/dist/conversations/titles.js +422 -0
- package/dist/ctx/bus.d.ts +16 -0
- package/dist/ctx/bus.js +101 -0
- package/dist/ctx/create-ctx.d.ts +109 -0
- package/dist/ctx/create-ctx.js +592 -0
- package/dist/ctx/kv.d.ts +4 -0
- package/dist/ctx/kv.js +31 -0
- package/dist/ctx/lock.d.ts +4 -0
- package/dist/ctx/lock.js +39 -0
- package/dist/ctx/namespace.d.ts +6 -0
- package/dist/ctx/namespace.js +12 -0
- package/dist/ctx/queue.d.ts +25 -0
- package/dist/ctx/queue.js +150 -0
- package/dist/ctx/secrets.d.ts +45 -0
- package/dist/ctx/secrets.js +175 -0
- package/dist/db/kernel-schema.d.ts +1122 -0
- package/dist/db/kernel-schema.js +5 -0
- package/dist/db/migrator.d.ts +28 -0
- package/dist/db/migrator.js +140 -0
- package/dist/db/pool.d.ts +21 -0
- package/dist/db/pool.js +28 -0
- package/dist/db/sql-statements.d.ts +34 -0
- package/dist/db/sql-statements.js +168 -0
- package/dist/errors.d.ts +210 -0
- package/dist/errors.js +212 -0
- package/dist/evals/budget.d.ts +61 -0
- package/dist/evals/budget.js +181 -0
- package/dist/evals/diff.d.ts +55 -0
- package/dist/evals/diff.js +133 -0
- package/dist/evals/judge.d.ts +53 -0
- package/dist/evals/judge.js +149 -0
- package/dist/evals/plan.d.ts +47 -0
- package/dist/evals/plan.js +77 -0
- package/dist/evals/reconstruct.d.ts +137 -0
- package/dist/evals/reconstruct.js +322 -0
- package/dist/evals/recorded-tools.d.ts +54 -0
- package/dist/evals/recorded-tools.js +167 -0
- package/dist/evals/run-replay.d.ts +86 -0
- package/dist/evals/run-replay.js +502 -0
- package/dist/evals/runs.controller.d.ts +100 -0
- package/dist/evals/runs.controller.js +199 -0
- package/dist/evals/runs.service.d.ts +275 -0
- package/dist/evals/runs.service.js +836 -0
- package/dist/evals/sets.controller.d.ts +61 -0
- package/dist/evals/sets.controller.js +183 -0
- package/dist/evals/sets.service.d.ts +128 -0
- package/dist/evals/sets.service.js +558 -0
- package/dist/evals/snapshot.d.ts +76 -0
- package/dist/evals/snapshot.js +207 -0
- package/dist/evals/step-replay.d.ts +113 -0
- package/dist/evals/step-replay.js +181 -0
- package/dist/evals/trajectory.controller.d.ts +41 -0
- package/dist/evals/trajectory.controller.js +88 -0
- package/dist/evals/trajectory.d.ts +144 -0
- package/dist/evals/trajectory.js +338 -0
- package/dist/evals/trajectory.service.d.ts +108 -0
- package/dist/evals/trajectory.service.js +323 -0
- package/dist/evals/worker.d.ts +101 -0
- package/dist/evals/worker.js +789 -0
- package/dist/extensions/admin-ops.d.ts +105 -0
- package/dist/extensions/admin-ops.js +353 -0
- package/dist/extensions/admin-view.d.ts +79 -0
- package/dist/extensions/admin-view.js +327 -0
- package/dist/extensions/approvals.d.ts +119 -0
- package/dist/extensions/approvals.js +205 -0
- package/dist/extensions/blobs.d.ts +45 -0
- package/dist/extensions/blobs.js +160 -0
- package/dist/extensions/bootstrap.d.ts +149 -0
- package/dist/extensions/bootstrap.js +441 -0
- package/dist/extensions/cli.d.ts +61 -0
- package/dist/extensions/cli.js +165 -0
- package/dist/extensions/config-json-schema.d.ts +9 -0
- package/dist/extensions/config-json-schema.js +73 -0
- package/dist/extensions/deployment-config.d.ts +138 -0
- package/dist/extensions/deployment-config.js +394 -0
- package/dist/extensions/enabled.d.ts +31 -0
- package/dist/extensions/enabled.js +55 -0
- package/dist/extensions/hooks.d.ts +161 -0
- package/dist/extensions/hooks.js +425 -0
- package/dist/extensions/host.d.ts +577 -0
- package/dist/extensions/host.js +2071 -0
- package/dist/extensions/inflight.d.ts +69 -0
- package/dist/extensions/inflight.js +277 -0
- package/dist/extensions/installs.d.ts +166 -0
- package/dist/extensions/installs.js +253 -0
- package/dist/extensions/instance.d.ts +167 -0
- package/dist/extensions/instance.js +329 -0
- package/dist/extensions/ledger.d.ts +30 -0
- package/dist/extensions/ledger.js +50 -0
- package/dist/extensions/lifecycle.d.ts +80 -0
- package/dist/extensions/lifecycle.js +152 -0
- package/dist/extensions/migrate-lock.d.ts +51 -0
- package/dist/extensions/migrate-lock.js +100 -0
- package/dist/extensions/org-config.controller.d.ts +24 -0
- package/dist/extensions/org-config.controller.js +59 -0
- package/dist/extensions/org-config.d.ts +169 -0
- package/dist/extensions/org-config.js +520 -0
- package/dist/extensions/package.d.ts +115 -0
- package/dist/extensions/package.js +246 -0
- package/dist/extensions/permission-set.d.ts +117 -0
- package/dist/extensions/permission-set.js +184 -0
- package/dist/extensions/permission-view.d.ts +194 -0
- package/dist/extensions/permission-view.js +284 -0
- package/dist/extensions/registry.d.ts +24 -0
- package/dist/extensions/registry.js +56 -0
- package/dist/extensions/resolve.d.ts +12 -0
- package/dist/extensions/resolve.js +71 -0
- package/dist/extensions/sources.d.ts +69 -0
- package/dist/extensions/sources.js +120 -0
- package/dist/extensions/sync.d.ts +40 -0
- package/dist/extensions/sync.js +242 -0
- package/dist/files/previewers.controller.d.ts +46 -0
- package/dist/files/previewers.controller.js +105 -0
- package/dist/files/previewers.d.ts +100 -0
- package/dist/files/previewers.js +250 -0
- package/dist/http/api.module.d.ts +114 -0
- package/dist/http/api.module.js +448 -0
- package/dist/http/app.d.ts +77 -0
- package/dist/http/app.js +170 -0
- package/dist/http/error.filter.d.ts +21 -0
- package/dist/http/error.filter.js +85 -0
- package/dist/http/gateway.module.d.ts +15 -0
- package/dist/http/gateway.module.js +13 -0
- package/dist/http/health.controller.d.ts +26 -0
- package/dist/http/health.controller.js +79 -0
- package/dist/http/nest-logger.d.ts +20 -0
- package/dist/http/nest-logger.js +28 -0
- package/dist/http/plugin-dispatch.d.ts +68 -0
- package/dist/http/plugin-dispatch.js +200 -0
- package/dist/http/tokens.d.ts +131 -0
- package/dist/http/tokens.js +131 -0
- package/dist/http/zod.pipe.d.ts +8 -0
- package/dist/http/zod.pipe.js +14 -0
- package/dist/identity/accounts.d.ts +93 -0
- package/dist/identity/accounts.js +367 -0
- package/dist/identity/api-tokens.d.ts +73 -0
- package/dist/identity/api-tokens.js +197 -0
- package/dist/identity/audit.d.ts +23 -0
- package/dist/identity/audit.js +41 -0
- package/dist/identity/auth.controller.d.ts +40 -0
- package/dist/identity/auth.controller.js +130 -0
- package/dist/identity/auth.guard.d.ts +41 -0
- package/dist/identity/auth.guard.js +162 -0
- package/dist/identity/binding.d.ts +47 -0
- package/dist/identity/binding.js +84 -0
- package/dist/identity/cookies.d.ts +16 -0
- package/dist/identity/cookies.js +32 -0
- package/dist/identity/credential-check.d.ts +17 -0
- package/dist/identity/credential-check.js +24 -0
- package/dist/identity/enterprise-admin.d.ts +14 -0
- package/dist/identity/enterprise-admin.js +27 -0
- package/dist/identity/external.d.ts +106 -0
- package/dist/identity/external.js +337 -0
- package/dist/identity/hash.d.ts +2 -0
- package/dist/identity/hash.js +3 -0
- package/dist/identity/login.d.ts +6 -0
- package/dist/identity/login.js +20 -0
- package/dist/identity/me.controller.d.ts +61 -0
- package/dist/identity/me.controller.js +159 -0
- package/dist/identity/passwords.d.ts +6 -0
- package/dist/identity/passwords.js +37 -0
- package/dist/identity/principal.d.ts +56 -0
- package/dist/identity/principal.js +38 -0
- package/dist/identity/rate-limit.d.ts +55 -0
- package/dist/identity/rate-limit.js +121 -0
- package/dist/identity/sessions.d.ts +84 -0
- package/dist/identity/sessions.js +306 -0
- package/dist/identity/settings.d.ts +121 -0
- package/dist/identity/settings.js +248 -0
- package/dist/identity/sso.controller.d.ts +59 -0
- package/dist/identity/sso.controller.js +192 -0
- package/dist/identity/sso.d.ts +83 -0
- package/dist/identity/sso.js +202 -0
- package/dist/inbox/inbox.service.d.ts +43 -0
- package/dist/inbox/inbox.service.js +57 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +65 -0
- package/dist/kernel.d.ts +256 -0
- package/dist/kernel.js +1326 -0
- package/dist/log.d.ts +48 -0
- package/dist/log.js +229 -0
- package/dist/models/prices.d.ts +53 -0
- package/dist/models/prices.js +121 -0
- package/dist/models/purposes.controller.d.ts +19 -0
- package/dist/models/purposes.controller.js +56 -0
- package/dist/models/purposes.d.ts +140 -0
- package/dist/models/purposes.js +267 -0
- package/dist/net/proxy.d.ts +44 -0
- package/dist/net/proxy.js +162 -0
- package/dist/net/public-address.d.ts +60 -0
- package/dist/net/public-address.js +271 -0
- package/dist/net/safe-fetch.d.ts +38 -0
- package/dist/net/safe-fetch.js +140 -0
- package/dist/orgs/directory-sync.controller.d.ts +14 -0
- package/dist/orgs/directory-sync.controller.js +40 -0
- package/dist/orgs/directory-sync.d.ts +166 -0
- package/dist/orgs/directory-sync.js +558 -0
- package/dist/orgs/invitations.controller.d.ts +58 -0
- package/dist/orgs/invitations.controller.js +137 -0
- package/dist/orgs/invitations.service.d.ts +80 -0
- package/dist/orgs/invitations.service.js +217 -0
- package/dist/orgs/members.service.d.ts +63 -0
- package/dist/orgs/members.service.js +234 -0
- package/dist/orgs/offboarding.d.ts +141 -0
- package/dist/orgs/offboarding.js +398 -0
- package/dist/orgs/org-lock.d.ts +32 -0
- package/dist/orgs/org-lock.js +46 -0
- package/dist/orgs/org.guard.d.ts +35 -0
- package/dist/orgs/org.guard.js +95 -0
- package/dist/orgs/orgs.controller.d.ts +78 -0
- package/dist/orgs/orgs.controller.js +192 -0
- package/dist/orgs/orgs.service.d.ts +61 -0
- package/dist/orgs/orgs.service.js +209 -0
- package/dist/orgs/roles.d.ts +13 -0
- package/dist/orgs/roles.js +58 -0
- package/dist/orgs/settings.controller.d.ts +20 -0
- package/dist/orgs/settings.controller.js +53 -0
- package/dist/orgs/settings.service.d.ts +120 -0
- package/dist/orgs/settings.service.js +178 -0
- package/dist/packages/npm.d.ts +50 -0
- package/dist/packages/npm.js +218 -0
- package/dist/packages/provenance.d.ts +47 -0
- package/dist/packages/provenance.js +147 -0
- package/dist/packages/tgz.d.ts +76 -0
- package/dist/packages/tgz.js +225 -0
- package/dist/runtime/abort.d.ts +32 -0
- package/dist/runtime/abort.js +71 -0
- package/dist/runtime/checkpointer.d.ts +32 -0
- package/dist/runtime/checkpointer.js +243 -0
- package/dist/runtime/context/build.d.ts +254 -0
- package/dist/runtime/context/build.js +693 -0
- package/dist/runtime/context/claude-tools.d.ts +11 -0
- package/dist/runtime/context/claude-tools.js +24 -0
- package/dist/runtime/context/compaction.d.ts +26 -0
- package/dist/runtime/context/compaction.js +195 -0
- package/dist/runtime/context/pairing.d.ts +11 -0
- package/dist/runtime/context/pairing.js +82 -0
- package/dist/runtime/context/reminders.d.ts +5 -0
- package/dist/runtime/context/reminders.js +11 -0
- package/dist/runtime/context/skills.d.ts +105 -0
- package/dist/runtime/context/skills.js +283 -0
- package/dist/runtime/context/tokens.d.ts +19 -0
- package/dist/runtime/context/tokens.js +104 -0
- package/dist/runtime/conversation-lock.d.ts +40 -0
- package/dist/runtime/conversation-lock.js +97 -0
- package/dist/runtime/hook-calls.d.ts +84 -0
- package/dist/runtime/hook-calls.js +136 -0
- package/dist/runtime/langgraph-loop.d.ts +52 -0
- package/dist/runtime/langgraph-loop.js +247 -0
- package/dist/runtime/loop.d.ts +93 -0
- package/dist/runtime/loop.js +7 -0
- package/dist/runtime/maintenance.d.ts +80 -0
- package/dist/runtime/maintenance.js +147 -0
- package/dist/runtime/media-cache.d.ts +21 -0
- package/dist/runtime/media-cache.js +51 -0
- package/dist/runtime/model-call.d.ts +176 -0
- package/dist/runtime/model-call.js +1049 -0
- package/dist/runtime/providers.d.ts +86 -0
- package/dist/runtime/providers.js +224 -0
- package/dist/runtime/quota.d.ts +29 -0
- package/dist/runtime/quota.js +70 -0
- package/dist/runtime/run-finish.d.ts +45 -0
- package/dist/runtime/run-finish.js +69 -0
- package/dist/runtime/run-queue.d.ts +121 -0
- package/dist/runtime/run-queue.js +493 -0
- package/dist/runtime/run-worker.d.ts +138 -0
- package/dist/runtime/run-worker.js +805 -0
- package/dist/runtime/stream.controller.d.ts +34 -0
- package/dist/runtime/stream.controller.js +122 -0
- package/dist/runtime/stream.d.ts +63 -0
- package/dist/runtime/stream.js +262 -0
- package/dist/runtime/subagents/child.d.ts +80 -0
- package/dist/runtime/subagents/child.js +225 -0
- package/dist/runtime/subagents/definition.d.ts +103 -0
- package/dist/runtime/subagents/definition.js +392 -0
- package/dist/runtime/subagents/dispatch.d.ts +69 -0
- package/dist/runtime/subagents/dispatch.js +502 -0
- package/dist/runtime/subagents/limits.d.ts +23 -0
- package/dist/runtime/subagents/limits.js +34 -0
- package/dist/runtime/subagents/org-agents.d.ts +50 -0
- package/dist/runtime/subagents/org-agents.js +70 -0
- package/dist/runtime/subagents/preamble.d.ts +7 -0
- package/dist/runtime/subagents/preamble.js +11 -0
- package/dist/runtime/subagents/progress.d.ts +26 -0
- package/dist/runtime/subagents/progress.js +36 -0
- package/dist/runtime/subagents/roster.d.ts +55 -0
- package/dist/runtime/subagents/roster.js +111 -0
- package/dist/runtime/subagents/skill-fork.d.ts +123 -0
- package/dist/runtime/subagents/skill-fork.js +259 -0
- package/dist/runtime/usage-report.d.ts +163 -0
- package/dist/runtime/usage-report.js +550 -0
- package/dist/runtime/waits.d.ts +233 -0
- package/dist/runtime/waits.js +883 -0
- package/dist/sandbox/leases.d.ts +169 -0
- package/dist/sandbox/leases.js +515 -0
- package/dist/sandbox/lifecycle.d.ts +21 -0
- package/dist/sandbox/lifecycle.js +68 -0
- package/dist/sandbox/sandbox.service.d.ts +249 -0
- package/dist/sandbox/sandbox.service.js +908 -0
- package/dist/skills/catalog.d.ts +149 -0
- package/dist/skills/catalog.js +405 -0
- package/dist/skills/changes.controller.d.ts +56 -0
- package/dist/skills/changes.controller.js +136 -0
- package/dist/skills/changes.service.d.ts +175 -0
- package/dist/skills/changes.service.js +805 -0
- package/dist/skills/invocable.controller.d.ts +23 -0
- package/dist/skills/invocable.controller.js +50 -0
- package/dist/skills/invocation-keys.d.ts +23 -0
- package/dist/skills/invocation-keys.js +44 -0
- package/dist/skills/invoke.d.ts +135 -0
- package/dist/skills/invoke.js +286 -0
- package/dist/skills/package.d.ts +87 -0
- package/dist/skills/package.js +227 -0
- package/dist/skills/skills.controller.d.ts +40 -0
- package/dist/skills/skills.controller.js +110 -0
- package/dist/skills/skills.service.d.ts +192 -0
- package/dist/skills/skills.service.js +567 -0
- package/dist/storage/prefix.d.ts +36 -0
- package/dist/storage/prefix.js +104 -0
- package/dist/storage/purge.d.ts +27 -0
- package/dist/storage/purge.js +75 -0
- package/dist/storage/storage.service.d.ts +44 -0
- package/dist/storage/storage.service.js +145 -0
- package/dist/text.d.ts +13 -0
- package/dist/text.js +13 -0
- package/dist/tools/approvals.controller.d.ts +53 -0
- package/dist/tools/approvals.controller.js +128 -0
- package/dist/tools/approvals.service.d.ts +172 -0
- package/dist/tools/approvals.service.js +568 -0
- package/dist/tools/breaker.d.ts +28 -0
- package/dist/tools/breaker.js +72 -0
- package/dist/tools/builtins/agent.d.ts +81 -0
- package/dist/tools/builtins/agent.js +223 -0
- package/dist/tools/builtins/ask-user.d.ts +28 -0
- package/dist/tools/builtins/ask-user.js +139 -0
- package/dist/tools/builtins/read-tool-output.d.ts +18 -0
- package/dist/tools/builtins/read-tool-output.js +108 -0
- package/dist/tools/builtins/sandbox/bash.d.ts +16 -0
- package/dist/tools/builtins/sandbox/bash.js +137 -0
- package/dist/tools/builtins/sandbox/common.d.ts +114 -0
- package/dist/tools/builtins/sandbox/common.js +304 -0
- package/dist/tools/builtins/sandbox/deliver.d.ts +5 -0
- package/dist/tools/builtins/sandbox/deliver.js +180 -0
- package/dist/tools/builtins/sandbox/edit.d.ts +4 -0
- package/dist/tools/builtins/sandbox/edit.js +98 -0
- package/dist/tools/builtins/sandbox/glob-match.d.ts +25 -0
- package/dist/tools/builtins/sandbox/glob-match.js +240 -0
- package/dist/tools/builtins/sandbox/glob.d.ts +4 -0
- package/dist/tools/builtins/sandbox/glob.js +104 -0
- package/dist/tools/builtins/sandbox/grep.d.ts +9 -0
- package/dist/tools/builtins/sandbox/grep.js +133 -0
- package/dist/tools/builtins/sandbox/index.d.ts +12 -0
- package/dist/tools/builtins/sandbox/index.js +27 -0
- package/dist/tools/builtins/sandbox/names.d.ts +7 -0
- package/dist/tools/builtins/sandbox/names.js +20 -0
- package/dist/tools/builtins/sandbox/read.d.ts +8 -0
- package/dist/tools/builtins/sandbox/read.js +121 -0
- package/dist/tools/builtins/sandbox/write.d.ts +4 -0
- package/dist/tools/builtins/sandbox/write.js +88 -0
- package/dist/tools/builtins/skill-load.d.ts +53 -0
- package/dist/tools/builtins/skill-load.js +446 -0
- package/dist/tools/builtins/skill-write.d.ts +59 -0
- package/dist/tools/builtins/skill-write.js +244 -0
- package/dist/tools/builtins/tool-search.d.ts +31 -0
- package/dist/tools/builtins/tool-search.js +171 -0
- package/dist/tools/connector-content.controller.d.ts +34 -0
- package/dist/tools/connector-content.controller.js +78 -0
- package/dist/tools/connector-content.d.ts +104 -0
- package/dist/tools/connector-content.js +267 -0
- package/dist/tools/connectors.controller.d.ts +210 -0
- package/dist/tools/connectors.controller.js +234 -0
- package/dist/tools/connectors.service.d.ts +303 -0
- package/dist/tools/connectors.service.js +1102 -0
- package/dist/tools/credentials.d.ts +139 -0
- package/dist/tools/credentials.js +351 -0
- package/dist/tools/drift.d.ts +141 -0
- package/dist/tools/drift.js +539 -0
- package/dist/tools/elicitation.d.ts +81 -0
- package/dist/tools/elicitation.js +266 -0
- package/dist/tools/endpoint.d.ts +18 -0
- package/dist/tools/endpoint.js +115 -0
- package/dist/tools/info.d.ts +67 -0
- package/dist/tools/info.js +113 -0
- package/dist/tools/naming.d.ts +27 -0
- package/dist/tools/naming.js +47 -0
- package/dist/tools/oauth/discovery.d.ts +65 -0
- package/dist/tools/oauth/discovery.js +307 -0
- package/dist/tools/oauth/flow.d.ts +63 -0
- package/dist/tools/oauth/flow.js +237 -0
- package/dist/tools/oauth/oauth.controller.d.ts +31 -0
- package/dist/tools/oauth/oauth.controller.js +95 -0
- package/dist/tools/oauth/tokens.d.ts +111 -0
- package/dist/tools/oauth/tokens.js +258 -0
- package/dist/tools/outputs.d.ts +61 -0
- package/dist/tools/outputs.js +156 -0
- package/dist/tools/pipeline.d.ts +322 -0
- package/dist/tools/pipeline.js +1236 -0
- package/dist/tools/policy.d.ts +60 -0
- package/dist/tools/policy.js +236 -0
- package/dist/tools/questions.controller.d.ts +24 -0
- package/dist/tools/questions.controller.js +58 -0
- package/dist/tools/questions.service.d.ts +103 -0
- package/dist/tools/questions.service.js +295 -0
- package/dist/tools/redact.d.ts +20 -0
- package/dist/tools/redact.js +60 -0
- package/dist/tools/registry.d.ts +246 -0
- package/dist/tools/registry.js +481 -0
- package/dist/tools/resources.d.ts +16 -0
- package/dist/tools/resources.js +76 -0
- package/dist/tools/specs.d.ts +14 -0
- package/dist/tools/specs.js +31 -0
- package/dist/tools/validate.d.ts +20 -0
- package/dist/tools/validate.js +183 -0
- package/dist/tools/view.d.ts +43 -0
- package/dist/tools/view.js +225 -0
- package/dist/ui/embed-token.d.ts +31 -0
- package/dist/ui/embed-token.js +132 -0
- package/dist/ui/registry.d.ts +58 -0
- package/dist/ui/registry.js +90 -0
- package/dist/ui/ui-stream.d.ts +37 -0
- package/dist/ui/ui-stream.js +162 -0
- package/dist/ui/views.controller.d.ts +81 -0
- package/dist/ui/views.controller.js +261 -0
- package/dist/ui/views.d.ts +155 -0
- package/dist/ui/views.js +306 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +6 -0
- package/package.json +67 -3
- package/src/migrations/0001_init.sql +8 -0
- package/src/migrations/0002_secrets.sql +8 -0
- package/src/migrations/0003_identity.sql +117 -0
- package/src/migrations/0004_plugin_org_config_nullable.sql +3 -0
- package/src/migrations/0005_agents.sql +27 -0
- package/src/migrations/0006_conversations.sql +37 -0
- package/src/migrations/0007_checkpoints.sql +26 -0
- package/src/migrations/0008_runs_trigger_seq.sql +3 -0
- package/src/migrations/0009_runs_active_unique.sql +4 -0
- package/src/migrations/0010_tools.sql +125 -0
- package/src/migrations/0011_approvals_spec.sql +10 -0
- package/src/migrations/0012_run_waits.sql +24 -0
- package/src/migrations/0013_app_tools_source.sql +4 -0
- package/src/migrations/0014_tool_specs.sql +8 -0
- package/src/migrations/0015_tool_drift.sql +20 -0
- package/src/migrations/0016_plugin_permissions.sql +11 -0
- package/src/migrations/0017_identity_sources.sql +6 -0
- package/src/migrations/0018_channels.sql +74 -0
- package/src/migrations/0019_identity_trust.sql +17 -0
- package/src/migrations/0020_channel_card_lookup.sql +10 -0
- package/src/migrations/0021_org_storage_purge.sql +9 -0
- package/src/migrations/0022_attachments.sql +29 -0
- package/src/migrations/0023_sandboxes.sql +37 -0
- package/src/migrations/0024_skills.sql +46 -0
- package/src/migrations/0025_skills_catalog_idx.sql +6 -0
- package/src/migrations/0026_skill_changes.sql +34 -0
- package/src/migrations/0027_model_prices.sql +18 -0
- package/src/migrations/0028_evals.sql +105 -0
- package/src/migrations/0029_model_purposes.sql +18 -0
- package/src/migrations/0030_plugin_installs.sql +73 -0
- package/src/migrations/0031_plugin_snapshot_source.sql +6 -0
- package/src/migrations/0032_plugin_deployment_configs.sql +10 -0
- package/src/migrations/0033_rename_apps_to_connectors.sql +25 -0
- package/src/migrations/0034_directory.sql +49 -0
- package/src/migrations/0035_catalogs.sql +40 -0
- package/src/migrations/0036_app_import_staging.sql +17 -0
- package/src/migrations/0037_directory_installs.sql +92 -0
- package/src/migrations/0038_channel_inbound_mode.sql +6 -0
- package/src/migrations/0039_channel_card_pending.sql +8 -0
- package/src/migrations/0040_usage_report_sweep.sql +10 -0
- package/src/migrations/0041_rename_plugins_to_extensions.sql +38 -0
- package/src/migrations/0042_rename_directory_to_catalog.sql +80 -0
- package/src/migrations/0043_rename_app_installs_to_plugin_installs.sql +20 -0
- package/src/migrations/0044_catalog_one_kind.sql +90 -0
- package/src/migrations/0045_plugin_dependencies.sql +9 -0
- package/src/migrations/0046_git_sources.sql +25 -0
- package/src/migrations/0047_marketplace_entry_heads.sql +7 -0
- package/src/migrations/0048_marketplace_entry_trees.sql +8 -0
- package/src/migrations/0049_plugin_upgrades.sql +37 -0
- package/src/migrations/0050_bootstrap.sql +53 -0
- package/src/migrations/0051_claude_compat.sql +26 -0
- package/src/migrations/0052_conversations_account_agent_idx.sql +5 -0
- package/src/migrations/0053_subagents.sql +73 -0
- package/src/migrations/0054_subagent_wait_expiry.sql +7 -0
- package/src/migrations/0055_subagent_parent_indexes.sql +10 -0
- package/src/migrations/0056_approval_reason.sql +3 -0
- package/src/migrations/0057_conversation_titles.sql +11 -0
- package/src/migrations/0058_conversation_selection.sql +4 -0
- package/src/migrations/0059_conversation_queue.sql +22 -0
- package/src/migrations/0060_file_previewers.sql +10 -0
- package/src/migrations/0061_queue_selection.sql +5 -0
- package/src/migrations/0062_queued_skill.sql +8 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { sql } from "kysely";
|
|
3
|
+
import { normalizeStoredDefinition } from "../agents/definition.js";
|
|
4
|
+
import { ApiError } from "../errors.js";
|
|
5
|
+
import { notInvocable, recordedSkillBlocked, } from "../skills/invoke.js";
|
|
6
|
+
import { userMessageIdemKey, } from "./conversations.service.js";
|
|
7
|
+
import { payloadJson } from "./event-log.js";
|
|
8
|
+
import { planSelection, readSelection } from "./selection.js";
|
|
9
|
+
/**
|
|
10
|
+
* Queued messages (UI refresh B, spec §5.7): messages a person queued while a run was going. They
|
|
11
|
+
* are conversation state in PG, not events: the model has not seen them, so they enter the log only
|
|
12
|
+
* when sent. `RunQueue.ensureRun` sends the head item, one per run, when the conversation is idle
|
|
13
|
+
* (no unconsumed message, no active run, not paused), under the conversation row lock, so exactly
|
|
14
|
+
* one replica sends each item. A run that fails or is stopped pauses the queue (`finishRunIn`).
|
|
15
|
+
*/
|
|
16
|
+
/** The most messages a conversation can hold in its queue. */
|
|
17
|
+
export const QUEUE_MAX_ITEMS = 20;
|
|
18
|
+
const COLUMNS = [
|
|
19
|
+
"id",
|
|
20
|
+
"conversation_id",
|
|
21
|
+
"account_id",
|
|
22
|
+
"position",
|
|
23
|
+
"text",
|
|
24
|
+
"content",
|
|
25
|
+
"attachments",
|
|
26
|
+
"files",
|
|
27
|
+
"client_message_id",
|
|
28
|
+
"model",
|
|
29
|
+
"effort",
|
|
30
|
+
"skill",
|
|
31
|
+
"created_at",
|
|
32
|
+
];
|
|
33
|
+
/**
|
|
34
|
+
* Queued text as the event log will store it: NUL becomes U+FFFD (PG rejects NUL in text and
|
|
35
|
+
* jsonb), the mapping `payloadJson` applies to a direct send (final review m1).
|
|
36
|
+
*/
|
|
37
|
+
const noNul = (text) => text.replaceAll("\0", "\uFFFD");
|
|
38
|
+
const itemNotFound = () => new ApiError("conversation.queue_item_not_found", "Queued message not found");
|
|
39
|
+
function toItem(r) {
|
|
40
|
+
const skill = r.skill;
|
|
41
|
+
return {
|
|
42
|
+
id: r.id,
|
|
43
|
+
text: r.text,
|
|
44
|
+
files: r.files,
|
|
45
|
+
attachments: r.attachments.map((a) => ({
|
|
46
|
+
connectorId: a.appId,
|
|
47
|
+
name: a.name,
|
|
48
|
+
uri: a.uri,
|
|
49
|
+
})),
|
|
50
|
+
clientMessageId: r.client_message_id,
|
|
51
|
+
model: r.model ?? null,
|
|
52
|
+
effort: r.effort,
|
|
53
|
+
...(skill !== null && {
|
|
54
|
+
skill: { name: skill.invokedAs, arguments: skill.record.arguments, mode: skill.record.mode },
|
|
55
|
+
}),
|
|
56
|
+
createdAt: r.created_at,
|
|
57
|
+
position: Number(r.position),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The text rule of `POST …/messages`: text is required unless the message invokes a skill (its
|
|
62
|
+
* rendered text is `content[0]`) or carries files and no `@` resources (`content[0]` must be the
|
|
63
|
+
* text when resources follow it).
|
|
64
|
+
*/
|
|
65
|
+
function checkText(text, files, attachments, skill) {
|
|
66
|
+
if (text.length > 0 || skill || (files > 0 && attachments === 0))
|
|
67
|
+
return;
|
|
68
|
+
throw new ApiError("validation_failed", "Request validation failed", [
|
|
69
|
+
{
|
|
70
|
+
path: "text",
|
|
71
|
+
message: "Text is required unless the message invokes a skill or carries files (and no @ resources)",
|
|
72
|
+
},
|
|
73
|
+
]);
|
|
74
|
+
}
|
|
75
|
+
/** The stored form of a rendered invocation and its first content block. */
|
|
76
|
+
function storedSkill(invokedAs, invoked) {
|
|
77
|
+
const skill = { invokedAs, record: invoked.skill };
|
|
78
|
+
return { skill: payloadJson(skill), first: { type: "text", text: invoked.text } };
|
|
79
|
+
}
|
|
80
|
+
/** The `user_message` a queued item becomes, as `postUserMessage` would have written it. */
|
|
81
|
+
export function queuedUserMessage(r) {
|
|
82
|
+
const attachments = r.attachments;
|
|
83
|
+
const skill = r.skill;
|
|
84
|
+
return {
|
|
85
|
+
type: "user_message",
|
|
86
|
+
idemKey: userMessageIdemKey(r.client_message_id),
|
|
87
|
+
payload: {
|
|
88
|
+
// a skill invocation's `content` starts with the text rendered when queued
|
|
89
|
+
content: [
|
|
90
|
+
...(r.text === "" || skill !== null ? [] : [{ type: "text", text: r.text }]),
|
|
91
|
+
...r.content,
|
|
92
|
+
],
|
|
93
|
+
...(attachments.length > 0 && { attachments }),
|
|
94
|
+
authorAccountId: r.account_id,
|
|
95
|
+
clientMessageId: r.client_message_id,
|
|
96
|
+
...(skill !== null && { skill: skill.record }),
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Appends a queued item inside `t` (the caller holds the conversation row lock): its pick, re-planned
|
|
102
|
+
* against the selection in effect now, becomes a `model_switched` before the `user_message`, as a
|
|
103
|
+
* direct send writes it (final review I1), and the cached selection follows the log. A model that
|
|
104
|
+
* stopped resolving since the item was queued is still written: the run worker's fallback
|
|
105
|
+
* (`model_switched { reason: "unavailable" }` before `run_started`) handles it, as it does for a
|
|
106
|
+
* direct switch whose model disappears. Returns the `user_message` and whether it switched.
|
|
107
|
+
*/
|
|
108
|
+
export async function appendQueuedIn(t, eventLog, conversationId, r) {
|
|
109
|
+
const events = [];
|
|
110
|
+
const pick = {
|
|
111
|
+
...(r.model !== null && { model: r.model }),
|
|
112
|
+
...(r.effort !== null && { effort: r.effort }),
|
|
113
|
+
};
|
|
114
|
+
const next = pick.model === undefined && pick.effort === undefined
|
|
115
|
+
? null
|
|
116
|
+
: planSelection(await agentModel(t, conversationId), await readSelection(t, conversationId), pick);
|
|
117
|
+
if (next !== null) {
|
|
118
|
+
events.push({
|
|
119
|
+
type: "model_switched",
|
|
120
|
+
idemKey: `switch:${r.client_message_id}`,
|
|
121
|
+
payload: { ...next, byAccountId: r.account_id, reason: "user" },
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
events.push(queuedUserMessage(r));
|
|
125
|
+
const written = await eventLog.append(conversationId, events, t);
|
|
126
|
+
if (next !== null) {
|
|
127
|
+
await t
|
|
128
|
+
.updateTable("conversations")
|
|
129
|
+
.set({ selection: JSON.stringify(await readSelection(t, conversationId)) })
|
|
130
|
+
.where("id", "=", conversationId)
|
|
131
|
+
.execute();
|
|
132
|
+
}
|
|
133
|
+
return { event: written.at(-1), switched: next !== null };
|
|
134
|
+
}
|
|
135
|
+
/** The model of the conversation agent's current version (inside `t`). */
|
|
136
|
+
async function agentModel(t, conversationId) {
|
|
137
|
+
return (await currentAgent(t, conversationId)).definition.model;
|
|
138
|
+
}
|
|
139
|
+
/** The conversation's org, agent and the agent's current definition (inside `t`). */
|
|
140
|
+
async function currentAgent(t, conversationId) {
|
|
141
|
+
const row = await t
|
|
142
|
+
.selectFrom("conversations as c")
|
|
143
|
+
.innerJoin("agents as a", "a.id", "c.agent_id")
|
|
144
|
+
.innerJoin("agent_versions as v", (j) => j.onRef("v.agent_id", "=", "a.id").onRef("v.version", "=", "a.current_version"))
|
|
145
|
+
.select(["c.org_id", "c.agent_id", "v.definition"])
|
|
146
|
+
.where("c.id", "=", conversationId)
|
|
147
|
+
.executeTakeFirstOrThrow();
|
|
148
|
+
return {
|
|
149
|
+
orgId: row.org_id,
|
|
150
|
+
agentId: row.agent_id,
|
|
151
|
+
definition: normalizeStoredDefinition(row.definition),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Why a queued item's skill can no longer be invoked, or null (also null for a plain message).
|
|
156
|
+
* Checked at dispatch, inside `t` (phase D Task 9): the rendered text was frozen when queued, but
|
|
157
|
+
* the skill must still be one of the agent's skills a person can invoke.
|
|
158
|
+
*/
|
|
159
|
+
async function queuedSkillBlocked(t, conversationId, r) {
|
|
160
|
+
const skill = r.skill;
|
|
161
|
+
if (skill === null)
|
|
162
|
+
return null;
|
|
163
|
+
const a = await currentAgent(t, conversationId);
|
|
164
|
+
return recordedSkillBlocked(t, {
|
|
165
|
+
orgId: a.orgId,
|
|
166
|
+
agentId: a.agentId,
|
|
167
|
+
agent: a.definition,
|
|
168
|
+
conversationId,
|
|
169
|
+
skillId: skill.record.id,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/** Pauses the queue with `reason` (inside `t`, holding the conversation row lock). */
|
|
173
|
+
export async function pauseQueueWith(t, conversationId, reason) {
|
|
174
|
+
await t
|
|
175
|
+
.updateTable("conversations")
|
|
176
|
+
.set({ queue_paused: true, queue_pause_reason: reason })
|
|
177
|
+
.where("id", "=", conversationId)
|
|
178
|
+
.execute();
|
|
179
|
+
}
|
|
180
|
+
/** Whether a user_message with this client id is already in the log (inside `t`). */
|
|
181
|
+
async function alreadySent(t, conversationId, clientMessageId) {
|
|
182
|
+
const row = await t
|
|
183
|
+
.selectFrom("conversation_events")
|
|
184
|
+
.select("seq")
|
|
185
|
+
.where("conversation_id", "=", conversationId)
|
|
186
|
+
.where("idem_key", "=", userMessageIdemKey(clientMessageId))
|
|
187
|
+
.executeTakeFirst();
|
|
188
|
+
return row !== undefined;
|
|
189
|
+
}
|
|
190
|
+
/** Clears the pause once the queue is empty (inside `t`, holding the conversation row lock). */
|
|
191
|
+
async function unpauseIfEmpty(t, conversationId) {
|
|
192
|
+
await t
|
|
193
|
+
.updateTable("conversations")
|
|
194
|
+
.set({ queue_paused: false, queue_pause_reason: null })
|
|
195
|
+
.where("id", "=", conversationId)
|
|
196
|
+
.where("queue_paused", "=", true)
|
|
197
|
+
.where((eb) => eb.not(eb.exists(eb
|
|
198
|
+
.selectFrom("conversation_queue")
|
|
199
|
+
.select(sql `1`.as("one"))
|
|
200
|
+
.where("conversation_queue.conversation_id", "=", conversationId))))
|
|
201
|
+
.execute();
|
|
202
|
+
}
|
|
203
|
+
const queueFull = () => new ApiError("conversation.queue_full", `A conversation can hold at most ${QUEUE_MAX_ITEMS} queued messages`);
|
|
204
|
+
/**
|
|
205
|
+
* Sends the queue's head item as a `user_message` inside `t` (the caller holds the conversation
|
|
206
|
+
* row lock and has checked the conversation is idle and not paused); returns the event, or null
|
|
207
|
+
* when the queue is empty. An item whose message is already in the log (a retried enqueue after it
|
|
208
|
+
* was sent) is dropped and the next one is taken. A head item whose skill can no longer be invoked
|
|
209
|
+
* stays queued and the queue pauses (`skill_not_invocable`): `{ paused }`. The caller notifies
|
|
210
|
+
* after commit.
|
|
211
|
+
*/
|
|
212
|
+
export async function dispatchQueuedIn(t, eventLog, conversationId) {
|
|
213
|
+
for (;;) {
|
|
214
|
+
const head = await t
|
|
215
|
+
.selectFrom("conversation_queue")
|
|
216
|
+
.select(COLUMNS)
|
|
217
|
+
.where("conversation_id", "=", conversationId)
|
|
218
|
+
.orderBy("position")
|
|
219
|
+
.limit(1)
|
|
220
|
+
.executeTakeFirst();
|
|
221
|
+
if (!head)
|
|
222
|
+
return null;
|
|
223
|
+
const sent = await alreadySent(t, conversationId, head.client_message_id);
|
|
224
|
+
if (!sent && (await queuedSkillBlocked(t, conversationId, head)) !== null) {
|
|
225
|
+
await pauseQueueWith(t, conversationId, "skill_not_invocable");
|
|
226
|
+
return { paused: "skill_not_invocable" };
|
|
227
|
+
}
|
|
228
|
+
const row = await t
|
|
229
|
+
.deleteFrom("conversation_queue")
|
|
230
|
+
.where("id", "=", head.id)
|
|
231
|
+
.returning(COLUMNS)
|
|
232
|
+
.executeTakeFirst();
|
|
233
|
+
if (!row || sent)
|
|
234
|
+
continue;
|
|
235
|
+
return appendQueuedIn(t, eventLog, conversationId, row);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Pauses the queue of a conversation whose run just failed or was stopped, when it holds items
|
|
240
|
+
* (inside the terminal transaction, see `finishRunIn`).
|
|
241
|
+
*/
|
|
242
|
+
export async function pauseQueueIn(t, conversationId) {
|
|
243
|
+
await t
|
|
244
|
+
.updateTable("conversations")
|
|
245
|
+
.set({ queue_paused: true, queue_pause_reason: "run_ended" })
|
|
246
|
+
.where("id", "=", conversationId)
|
|
247
|
+
.where((eb) => eb.exists(eb
|
|
248
|
+
.selectFrom("conversation_queue")
|
|
249
|
+
.select(sql `1`.as("one"))
|
|
250
|
+
.where("conversation_queue.conversation_id", "=", conversationId)))
|
|
251
|
+
.execute();
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* The queue API (owner only, as the conversation): list, add, edit the text, delete, send now and
|
|
255
|
+
* resume. Every change publishes `changed: queue`.
|
|
256
|
+
*/
|
|
257
|
+
export class ConversationQueue {
|
|
258
|
+
d;
|
|
259
|
+
constructor(d) {
|
|
260
|
+
this.d = d;
|
|
261
|
+
}
|
|
262
|
+
async list(orgId, conversationId, accountId) {
|
|
263
|
+
await this.d.conversations.get(orgId, conversationId, accountId);
|
|
264
|
+
return this.d.db
|
|
265
|
+
.transaction()
|
|
266
|
+
.setIsolationLevel("repeatable read")
|
|
267
|
+
.execute(async (t) => {
|
|
268
|
+
const conv = await t
|
|
269
|
+
.selectFrom("conversations")
|
|
270
|
+
.select(["queue_paused", "queue_pause_reason"])
|
|
271
|
+
.where("id", "=", conversationId)
|
|
272
|
+
.executeTakeFirstOrThrow();
|
|
273
|
+
const rows = await t
|
|
274
|
+
.selectFrom("conversation_queue")
|
|
275
|
+
.select(COLUMNS)
|
|
276
|
+
.where("conversation_id", "=", conversationId)
|
|
277
|
+
.orderBy("position")
|
|
278
|
+
.execute();
|
|
279
|
+
const reason = conv.queue_paused ? conv.queue_pause_reason : null;
|
|
280
|
+
return {
|
|
281
|
+
items: rows.map(toItem),
|
|
282
|
+
paused: conv.queue_paused,
|
|
283
|
+
...(reason !== null && { pauseReason: reason }),
|
|
284
|
+
};
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Queues a message. `@` resources are read now with the caller's credentials and stored with the
|
|
289
|
+
* item, and uploaded files are bound to the conversation now, so sending later needs nobody's
|
|
290
|
+
* credentials. The same `clientMessageId` again returns the queued item (`created: false`), or,
|
|
291
|
+
* when it was already sent, the sent `user_message` with `item: null`. Then `ensureRun`: on an
|
|
292
|
+
* idle conversation the item goes out at once.
|
|
293
|
+
*/
|
|
294
|
+
async add(orgId, conversationId, accountId, input) {
|
|
295
|
+
const conv = await this.d.conversations.writable(orgId, conversationId, accountId);
|
|
296
|
+
this.d.conversations.checkFilesSupported(input);
|
|
297
|
+
const files = input.files ?? [];
|
|
298
|
+
checkText(input.text, files.length, input.attachments?.length ?? 0, input.skill !== undefined);
|
|
299
|
+
const prior = await this.prior(conversationId, input.clientMessageId);
|
|
300
|
+
if (prior)
|
|
301
|
+
return prior;
|
|
302
|
+
// a cheap unlocked check first, so a full queue never reads `@` resources (slow, remote,
|
|
303
|
+
// credentialed); the locked check below stays authoritative
|
|
304
|
+
const { n: queued } = await this.d.db
|
|
305
|
+
.selectFrom("conversation_queue")
|
|
306
|
+
.select((eb) => eb.fn.countAll().as("n"))
|
|
307
|
+
.where("conversation_id", "=", conversationId)
|
|
308
|
+
.executeTakeFirstOrThrow();
|
|
309
|
+
if (Number(queued) >= QUEUE_MAX_ITEMS)
|
|
310
|
+
throw queueFull();
|
|
311
|
+
await this.d.conversations.checkPick(orgId, conv, accountId, input);
|
|
312
|
+
// a skill invocation is rendered now, like the `@` resources (spec §4.5)
|
|
313
|
+
const invoked = await this.d.conversations.prepareQueuedSkill(orgId, conv, accountId, input);
|
|
314
|
+
const extra = await this.d.conversations.resolveExtra(orgId, accountId, input);
|
|
315
|
+
const skill = invoked === undefined || input.skill === undefined
|
|
316
|
+
? undefined
|
|
317
|
+
: storedSkill(input.skill.name, invoked);
|
|
318
|
+
const out = await this.d.db.transaction().execute(async (t) => {
|
|
319
|
+
await t
|
|
320
|
+
.selectFrom("conversations")
|
|
321
|
+
.select("id")
|
|
322
|
+
.where("id", "=", conversationId)
|
|
323
|
+
.forUpdate()
|
|
324
|
+
.executeTakeFirstOrThrow();
|
|
325
|
+
const existing = await t
|
|
326
|
+
.selectFrom("conversation_queue")
|
|
327
|
+
.select(COLUMNS)
|
|
328
|
+
.where("conversation_id", "=", conversationId)
|
|
329
|
+
.where("client_message_id", "=", input.clientMessageId)
|
|
330
|
+
.executeTakeFirst();
|
|
331
|
+
if (existing)
|
|
332
|
+
return { row: existing, created: false };
|
|
333
|
+
if (await alreadySent(t, conversationId, input.clientMessageId))
|
|
334
|
+
return null;
|
|
335
|
+
const { n, last } = await t
|
|
336
|
+
.selectFrom("conversation_queue")
|
|
337
|
+
.select((eb) => [
|
|
338
|
+
eb.fn.countAll().as("n"),
|
|
339
|
+
eb.fn.max("position").as("last"),
|
|
340
|
+
])
|
|
341
|
+
.where("conversation_id", "=", conversationId)
|
|
342
|
+
.executeTakeFirstOrThrow();
|
|
343
|
+
if (Number(n) >= QUEUE_MAX_ITEMS)
|
|
344
|
+
throw queueFull();
|
|
345
|
+
const blocks = await this.d.conversations.bindIn(t, orgId, conversationId, accountId, files);
|
|
346
|
+
const fileMeta = blocks.flatMap((b) => (b.type === "image" || b.type === "document") && b.source.kind === "ref"
|
|
347
|
+
? [{ attachmentId: b.source.attachmentId, name: b.name ?? "", mediaType: b.mediaType }]
|
|
348
|
+
: []);
|
|
349
|
+
const row = await t
|
|
350
|
+
.insertInto("conversation_queue")
|
|
351
|
+
.values({
|
|
352
|
+
id: randomUUID(),
|
|
353
|
+
conversation_id: conversationId,
|
|
354
|
+
account_id: accountId,
|
|
355
|
+
position: last === null ? 1 : Number(last) + 1,
|
|
356
|
+
text: noNul(input.text),
|
|
357
|
+
content: payloadJson([
|
|
358
|
+
...(skill === undefined ? [] : [skill.first]),
|
|
359
|
+
...extra.blocks,
|
|
360
|
+
...blocks,
|
|
361
|
+
]),
|
|
362
|
+
attachments: payloadJson(extra.attachments),
|
|
363
|
+
files: JSON.stringify(fileMeta),
|
|
364
|
+
client_message_id: input.clientMessageId,
|
|
365
|
+
model: input.model === undefined ? null : JSON.stringify(input.model),
|
|
366
|
+
effort: input.effort ?? null,
|
|
367
|
+
skill: skill?.skill ?? null,
|
|
368
|
+
})
|
|
369
|
+
.returning(COLUMNS)
|
|
370
|
+
.executeTakeFirstOrThrow();
|
|
371
|
+
return { row, created: true };
|
|
372
|
+
});
|
|
373
|
+
if (out === null) {
|
|
374
|
+
return ((await this.prior(conversationId, input.clientMessageId)) ?? { item: null, created: false });
|
|
375
|
+
}
|
|
376
|
+
if (out.created) {
|
|
377
|
+
await this.d.eventLog.publishChanged(conversationId, "queue");
|
|
378
|
+
await this.d.runs?.ensureRun(conversationId);
|
|
379
|
+
}
|
|
380
|
+
return { item: toItem(out.row), created: out.created };
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Changes a queued item's text (its resources and files stay as queued). A skill invocation's
|
|
384
|
+
* text is its arguments: the skill is rendered again with them now (phase D Task 9).
|
|
385
|
+
*/
|
|
386
|
+
async edit(orgId, conversationId, accountId, itemId, text) {
|
|
387
|
+
const conv = await this.d.conversations.writable(orgId, conversationId, accountId);
|
|
388
|
+
const before = await this.d.db
|
|
389
|
+
.selectFrom("conversation_queue")
|
|
390
|
+
.select("skill")
|
|
391
|
+
.where("id", "=", itemId)
|
|
392
|
+
.where("conversation_id", "=", conversationId)
|
|
393
|
+
.executeTakeFirst();
|
|
394
|
+
if (!before)
|
|
395
|
+
throw itemNotFound();
|
|
396
|
+
const was = before.skill;
|
|
397
|
+
const invoked = was === null
|
|
398
|
+
? undefined
|
|
399
|
+
: await this.d.conversations.prepareQueuedSkill(orgId, conv, accountId, {
|
|
400
|
+
skill: { name: was.invokedAs },
|
|
401
|
+
text,
|
|
402
|
+
});
|
|
403
|
+
const row = await this.d.db.transaction().execute(async (t) => {
|
|
404
|
+
const cur = await t
|
|
405
|
+
.selectFrom("conversation_queue")
|
|
406
|
+
.select(["attachments", "files", "content", "skill"])
|
|
407
|
+
.where("id", "=", itemId)
|
|
408
|
+
.where("conversation_id", "=", conversationId)
|
|
409
|
+
.forUpdate()
|
|
410
|
+
.executeTakeFirst();
|
|
411
|
+
if (!cur)
|
|
412
|
+
throw itemNotFound();
|
|
413
|
+
const skill = cur.skill;
|
|
414
|
+
checkText(text, cur.files.length, cur.attachments.length, skill !== null);
|
|
415
|
+
// an invocation's first block is its rendered text: replace it and the record
|
|
416
|
+
const stored = skill === null || invoked === undefined ? undefined : storedSkill(skill.invokedAs, invoked);
|
|
417
|
+
return t
|
|
418
|
+
.updateTable("conversation_queue")
|
|
419
|
+
.set({
|
|
420
|
+
text: noNul(text),
|
|
421
|
+
updated_at: sql `now()`,
|
|
422
|
+
...(stored !== undefined && {
|
|
423
|
+
skill: stored.skill,
|
|
424
|
+
content: payloadJson([stored.first, ...cur.content.slice(1)]),
|
|
425
|
+
}),
|
|
426
|
+
})
|
|
427
|
+
.where("id", "=", itemId)
|
|
428
|
+
.returning(COLUMNS)
|
|
429
|
+
.executeTakeFirstOrThrow();
|
|
430
|
+
});
|
|
431
|
+
await this.d.eventLog.publishChanged(conversationId, "queue");
|
|
432
|
+
return toItem(row);
|
|
433
|
+
}
|
|
434
|
+
async remove(orgId, conversationId, accountId, itemId) {
|
|
435
|
+
await this.d.conversations.writable(orgId, conversationId, accountId);
|
|
436
|
+
await this.d.db.transaction().execute(async (t) => {
|
|
437
|
+
await this.lockConversation(t, conversationId);
|
|
438
|
+
const gone = await t
|
|
439
|
+
.deleteFrom("conversation_queue")
|
|
440
|
+
.where("id", "=", itemId)
|
|
441
|
+
.where("conversation_id", "=", conversationId)
|
|
442
|
+
.returning("id")
|
|
443
|
+
.executeTakeFirst();
|
|
444
|
+
if (!gone)
|
|
445
|
+
throw itemNotFound();
|
|
446
|
+
await unpauseIfEmpty(t, conversationId);
|
|
447
|
+
});
|
|
448
|
+
await this.d.eventLog.publishChanged(conversationId, "queue");
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Sends a queued item now: it leaves the queue and is posted as a user message in the same
|
|
452
|
+
* transaction (an interjection when a run is active; the items before it keep their place).
|
|
453
|
+
* Racing the dispatcher, exactly one of them takes the item; the loser sees it gone (404).
|
|
454
|
+
*/
|
|
455
|
+
async sendNow(orgId, conversationId, accountId, itemId) {
|
|
456
|
+
await this.d.conversations.writable(orgId, conversationId, accountId);
|
|
457
|
+
const { event, fresh, switched } = await this.d.db.transaction().execute(async (t) => {
|
|
458
|
+
await this.lockConversation(t, conversationId);
|
|
459
|
+
const head = await t
|
|
460
|
+
.selectFrom("conversation_queue")
|
|
461
|
+
.select(["skill", "client_message_id"])
|
|
462
|
+
.where("id", "=", itemId)
|
|
463
|
+
.where("conversation_id", "=", conversationId)
|
|
464
|
+
.executeTakeFirst();
|
|
465
|
+
if (!head)
|
|
466
|
+
throw itemNotFound();
|
|
467
|
+
// the skill is checked again, as at dispatch; a refused item stays queued
|
|
468
|
+
if (!(await alreadySent(t, conversationId, head.client_message_id))) {
|
|
469
|
+
const blocked = await queuedSkillBlocked(t, conversationId, head);
|
|
470
|
+
if (blocked !== null) {
|
|
471
|
+
throw notInvocable(blocked, head.skill.invokedAs);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const row = await t
|
|
475
|
+
.deleteFrom("conversation_queue")
|
|
476
|
+
.where("id", "=", itemId)
|
|
477
|
+
.where("conversation_id", "=", conversationId)
|
|
478
|
+
.returning(COLUMNS)
|
|
479
|
+
.executeTakeFirst();
|
|
480
|
+
if (!row)
|
|
481
|
+
throw itemNotFound();
|
|
482
|
+
const sent = await alreadySent(t, conversationId, row.client_message_id);
|
|
483
|
+
const out = await appendQueuedIn(t, this.d.eventLog, conversationId, row);
|
|
484
|
+
await unpauseIfEmpty(t, conversationId);
|
|
485
|
+
return { ...out, fresh: !sent };
|
|
486
|
+
});
|
|
487
|
+
if (fresh)
|
|
488
|
+
await this.d.eventLog.notify(conversationId, event.seq);
|
|
489
|
+
if (switched)
|
|
490
|
+
await this.d.eventLog.publishChanged(conversationId, "selection");
|
|
491
|
+
await this.d.eventLog.publishChanged(conversationId, "queue");
|
|
492
|
+
await this.d.runs?.ensureRun(conversationId);
|
|
493
|
+
return event;
|
|
494
|
+
}
|
|
495
|
+
/** "Continue sending": clears the pause and lets `ensureRun` send the head item. */
|
|
496
|
+
async resume(orgId, conversationId, accountId) {
|
|
497
|
+
await this.d.conversations.writable(orgId, conversationId, accountId);
|
|
498
|
+
await this.d.db
|
|
499
|
+
.updateTable("conversations")
|
|
500
|
+
.set({ queue_paused: false, queue_pause_reason: null })
|
|
501
|
+
.where("id", "=", conversationId)
|
|
502
|
+
.execute();
|
|
503
|
+
await this.d.eventLog.publishChanged(conversationId, "queue");
|
|
504
|
+
await this.d.runs?.ensureRun(conversationId);
|
|
505
|
+
}
|
|
506
|
+
/** A queued item or a sent message for this client id (outside any transaction). */
|
|
507
|
+
async prior(conversationId, clientMessageId) {
|
|
508
|
+
const row = await this.d.db
|
|
509
|
+
.selectFrom("conversation_queue")
|
|
510
|
+
.select(COLUMNS)
|
|
511
|
+
.where("conversation_id", "=", conversationId)
|
|
512
|
+
.where("client_message_id", "=", clientMessageId)
|
|
513
|
+
.executeTakeFirst();
|
|
514
|
+
if (row)
|
|
515
|
+
return { item: toItem(row), created: false };
|
|
516
|
+
const event = await this.d.eventLog.findByIdem(conversationId, userMessageIdemKey(clientMessageId));
|
|
517
|
+
return event ? { item: null, event, created: false } : null;
|
|
518
|
+
}
|
|
519
|
+
async lockConversation(t, conversationId) {
|
|
520
|
+
await t
|
|
521
|
+
.selectFrom("conversations")
|
|
522
|
+
.select("id")
|
|
523
|
+
.where("id", "=", conversationId)
|
|
524
|
+
.forUpdate()
|
|
525
|
+
.executeTakeFirstOrThrow();
|
|
526
|
+
}
|
|
527
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { SandboxService } from "../sandbox/sandbox.service.js";
|
|
2
|
+
export interface SandboxStatusView {
|
|
3
|
+
status: "running" | "suspended";
|
|
4
|
+
lastUsedAt: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ConversationSandboxStatusDeps {
|
|
7
|
+
sandbox: Pick<SandboxService, "status">;
|
|
8
|
+
/** 会话可见性(与会话 SSE 流同一判定:`ConversationsService.isAccessible`)。 */
|
|
9
|
+
isAccessible(orgId: string, conversationId: string, viewerAccountId: string): Promise<boolean>;
|
|
10
|
+
/** The conversation whose sandbox it works in: a sub-agent's parent, else itself. */
|
|
11
|
+
sandboxConversationOf(orgId: string, conversationId: string): Promise<string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 对话沙箱的状态(网页上下文标签,M5 T11):会话不可见 → `conversation.not_found`;
|
|
15
|
+
* 没有可用的沙箱(未创建、已销毁、正在创建)→ `sandbox.not_found`(界面显示「未创建」)。
|
|
16
|
+
*/
|
|
17
|
+
export declare class ConversationSandboxStatus {
|
|
18
|
+
private readonly d;
|
|
19
|
+
constructor(d: ConversationSandboxStatusDeps);
|
|
20
|
+
get(orgId: string, conversationId: string, viewerAccountId: string): Promise<SandboxStatusView>;
|
|
21
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ApiError } from "../errors.js";
|
|
2
|
+
import { UUID_RE } from "../ui/registry.js";
|
|
3
|
+
/**
|
|
4
|
+
* 对话沙箱的状态(网页上下文标签,M5 T11):会话不可见 → `conversation.not_found`;
|
|
5
|
+
* 没有可用的沙箱(未创建、已销毁、正在创建)→ `sandbox.not_found`(界面显示「未创建」)。
|
|
6
|
+
*/
|
|
7
|
+
export class ConversationSandboxStatus {
|
|
8
|
+
d;
|
|
9
|
+
constructor(d) {
|
|
10
|
+
this.d = d;
|
|
11
|
+
}
|
|
12
|
+
async get(orgId, conversationId, viewerAccountId) {
|
|
13
|
+
if (!UUID_RE.test(conversationId) ||
|
|
14
|
+
!(await this.d.isAccessible(orgId, conversationId, viewerAccountId))) {
|
|
15
|
+
throw new ApiError("conversation.not_found", "Conversation not found");
|
|
16
|
+
}
|
|
17
|
+
// a sub-agent works in its parent conversation's sandbox (sub-agents spec §10.1)
|
|
18
|
+
const sandboxConv = await this.d.sandboxConversationOf(orgId, conversationId);
|
|
19
|
+
const s = await this.d.sandbox.status(orgId, sandboxConv);
|
|
20
|
+
if (!s)
|
|
21
|
+
throw new ApiError("sandbox.not_found", "This conversation has no sandbox");
|
|
22
|
+
return { status: s.status, lastUsedAt: s.lastUsedAt.toISOString() };
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Kysely } from "kysely";
|
|
2
|
+
import type { AgentDefinition, ModelRef } from "../agents/definition.js";
|
|
3
|
+
import type { KernelDatabase } from "../db/kernel-schema.js";
|
|
4
|
+
/**
|
|
5
|
+
* The model and effort a person chose for a conversation (UI refresh B, spec §5.2): `null` model =
|
|
6
|
+
* the agent's model, `null` effort = the agent's saved effort or the model's default. Recorded in
|
|
7
|
+
* the log as `model_switched` events (the source of truth) and cached in `conversations.selection`
|
|
8
|
+
* for the conversation view.
|
|
9
|
+
*/
|
|
10
|
+
export interface Selection {
|
|
11
|
+
model: ModelRef | null;
|
|
12
|
+
effort: string | null;
|
|
13
|
+
}
|
|
14
|
+
export declare const NO_SELECTION: Selection;
|
|
15
|
+
export declare const sameModel: (a: ModelRef, b: ModelRef) => boolean;
|
|
16
|
+
export declare const sameSelection: (a: Selection, b: Selection) => boolean;
|
|
17
|
+
/**
|
|
18
|
+
* The selection a message's pick switches to, or null when it changes nothing (pure; the direct
|
|
19
|
+
* send and queue dispatch share it). A model equal to the agent's means "back to the agent's
|
|
20
|
+
* model" (null); a model change without `effort` resets the effort.
|
|
21
|
+
*/
|
|
22
|
+
export declare function planSelection(agentModel: ModelRef, current: Selection, pick: {
|
|
23
|
+
model?: ModelRef | undefined;
|
|
24
|
+
effort?: string | undefined;
|
|
25
|
+
}): Selection | null;
|
|
26
|
+
/**
|
|
27
|
+
* The selection in effect for a run that started at `seq` (its `run_started`): the latest
|
|
28
|
+
* `model_switched` before it. Runtime and replays read it the same way, so a replay honors the
|
|
29
|
+
* switch the original run used.
|
|
30
|
+
*/
|
|
31
|
+
export declare function selectionAt(events: readonly {
|
|
32
|
+
seq: number;
|
|
33
|
+
type: string;
|
|
34
|
+
payload: unknown;
|
|
35
|
+
}[], seq: number): Selection;
|
|
36
|
+
/**
|
|
37
|
+
* The definition a run uses under a selection: `model` replaced by the selected one, `modelParams`
|
|
38
|
+
* = the agent's own (only while the model is the agent's) plus the selected effort. Fallback model
|
|
39
|
+
* and params are untouched. No selection returns the definition itself (old logs stay identical).
|
|
40
|
+
*/
|
|
41
|
+
export declare function effectiveDefinition(def: AgentDefinition, sel: Selection): AgentDefinition;
|
|
42
|
+
/**
|
|
43
|
+
* The selection from the log: the latest `model_switched` (before `beforeSeq` when given). Pass a
|
|
44
|
+
* transaction that holds the conversation row lock to read it consistently with an append.
|
|
45
|
+
*/
|
|
46
|
+
export declare function readSelection(db: Kysely<KernelDatabase>, conversationId: string, beforeSeq?: number): Promise<Selection>;
|