@capybara-hq/kernel 0.1.0-rc.1 → 0.1.0-rc.2
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/dist/admin/admin.controller.d.ts +17 -17
- package/dist/admin/admin.controller.js +43 -26
- package/dist/admin/admin.module.d.ts +3 -0
- package/dist/admin/admin.module.js +22 -0
- package/dist/admin/extensions.controller.d.ts +14 -14
- package/dist/admin/extensions.controller.js +30 -17
- package/dist/admin/setup-lock.d.ts +16 -0
- package/dist/admin/setup-lock.js +47 -0
- package/dist/admin/setup.controller.d.ts +8 -8
- package/dist/admin/setup.controller.js +27 -25
- package/dist/admin/setup.service.d.ts +19 -27
- package/dist/admin/setup.service.js +61 -61
- package/dist/agents/agent-lookup.d.ts +53 -0
- package/dist/agents/agent-lookup.js +179 -0
- package/dist/agents/agents.controller.d.ts +1 -1
- package/dist/agents/agents.controller.js +14 -8
- package/dist/agents/agents.module.d.ts +7 -0
- package/dist/agents/agents.module.js +41 -0
- package/dist/agents/agents.service.d.ts +39 -58
- package/dist/agents/agents.service.js +261 -329
- package/dist/agents/definition.d.ts +8 -0
- package/dist/agents/definition.js +8 -0
- package/dist/agents/models.controller.d.ts +1 -1
- package/dist/agents/models.controller.js +2 -2
- package/dist/agents/templates.controller.d.ts +1 -1
- package/dist/agents/templates.controller.js +2 -2
- package/dist/agents/templates.d.ts +6 -8
- package/dist/agents/templates.js +20 -4
- package/dist/app.d.ts +93 -0
- package/dist/app.js +150 -0
- package/dist/catalog/admin-catalog.controller.d.ts +3 -3
- package/dist/catalog/admin-catalog.controller.js +27 -13
- package/dist/catalog/catalog-content.d.ts +185 -0
- package/dist/catalog/catalog-content.js +323 -0
- package/dist/catalog/catalog-items.d.ts +186 -0
- package/dist/catalog/catalog-items.js +410 -0
- package/dist/catalog/catalog.module.d.ts +14 -0
- package/dist/catalog/catalog.module.js +71 -0
- package/dist/catalog/catalog.service.d.ts +34 -188
- package/dist/catalog/catalog.service.js +155 -489
- package/dist/catalog/cli.d.ts +3 -2
- package/dist/catalog/cli.js +13 -31
- package/dist/catalog/job-ids.d.ts +15 -0
- package/dist/catalog/job-ids.js +15 -0
- package/dist/catalog/jobs.d.ts +27 -0
- package/dist/catalog/jobs.js +70 -0
- package/dist/catalog/locks.d.ts +24 -0
- package/dist/catalog/locks.js +63 -0
- package/dist/catalog/marketplaces.controller.d.ts +4 -4
- package/dist/catalog/marketplaces.controller.js +22 -11
- package/dist/catalog/marketplaces.service.d.ts +30 -13
- package/dist/catalog/marketplaces.service.js +330 -256
- package/dist/catalog/org-catalog.controller.d.ts +4 -3
- package/dist/catalog/org-catalog.controller.js +29 -14
- package/dist/catalog/org-catalog.service.d.ts +32 -198
- package/dist/catalog/org-catalog.service.js +159 -400
- package/dist/catalog/plugin-import.d.ts +73 -34
- package/dist/catalog/plugin-import.js +356 -217
- package/dist/catalog/plugin-install.d.ts +83 -41
- package/dist/catalog/plugin-install.js +421 -269
- package/dist/catalog/plugin-upgrade.d.ts +59 -4
- package/dist/catalog/plugin-upgrade.js +407 -282
- package/dist/catalog/requests.service.d.ts +27 -15
- package/dist/catalog/requests.service.js +201 -145
- package/dist/catalog/upgrade-targets.d.ts +4 -7
- package/dist/channels/actions.d.ts +6 -4
- package/dist/channels/actions.js +1 -1
- package/dist/channels/cards.d.ts +2 -2
- package/dist/channels/channels.module.d.ts +40 -0
- package/dist/channels/channels.module.js +128 -0
- package/dist/channels/connections.controller.d.ts +1 -1
- package/dist/channels/connections.controller.js +11 -6
- package/dist/channels/connections.service.d.ts +43 -21
- package/dist/channels/connections.service.js +236 -131
- package/dist/channels/inbound.d.ts +34 -38
- package/dist/channels/inbound.js +107 -41
- package/dist/channels/job-ids.d.ts +10 -0
- package/dist/channels/job-ids.js +10 -0
- package/dist/channels/jobs.d.ts +85 -0
- package/dist/channels/jobs.js +157 -0
- package/dist/channels/outbound.d.ts +60 -82
- package/dist/channels/outbound.js +165 -194
- package/dist/channels/supervisor.d.ts +88 -46
- package/dist/channels/supervisor.js +230 -132
- package/dist/channels/threads.d.ts +29 -8
- package/dist/channels/threads.js +71 -13
- package/dist/channels/webhook.d.ts +20 -14
- package/dist/channels/webhook.js +51 -20
- package/dist/config/load.d.ts +3 -2
- package/dist/config/load.js +3 -2
- package/dist/config/nacos-source.js +11 -2
- package/dist/config/schema.d.ts +1 -0
- package/dist/config/schema.js +10 -4
- package/dist/conversations/access.d.ts +29 -0
- package/dist/conversations/access.js +86 -0
- package/dist/conversations/artifacts.d.ts +10 -10
- package/dist/conversations/artifacts.js +35 -9
- package/dist/conversations/attachments.controller.d.ts +1 -1
- package/dist/conversations/attachments.controller.js +8 -6
- package/dist/conversations/attachments.module.d.ts +7 -0
- package/dist/conversations/attachments.module.js +25 -0
- package/dist/conversations/attachments.service.d.ts +30 -22
- package/dist/conversations/attachments.service.js +119 -46
- package/dist/conversations/conversations.controller.d.ts +8 -7
- package/dist/conversations/conversations.controller.js +59 -29
- package/dist/conversations/conversations.module.d.ts +8 -0
- package/dist/conversations/conversations.module.js +69 -0
- package/dist/conversations/conversations.service.d.ts +40 -38
- package/dist/conversations/conversations.service.js +130 -140
- package/dist/conversations/event-log.d.ts +28 -18
- package/dist/conversations/event-log.js +74 -27
- package/dist/conversations/files.d.ts +10 -10
- package/dist/conversations/files.js +37 -11
- package/dist/conversations/idem-keys.d.ts +5 -0
- package/dist/conversations/idem-keys.js +5 -0
- package/dist/conversations/job-ids.d.ts +6 -0
- package/dist/conversations/job-ids.js +6 -0
- package/dist/conversations/outputs-read.d.ts +11 -11
- package/dist/conversations/outputs-read.js +31 -7
- package/dist/conversations/queue.d.ts +48 -56
- package/dist/conversations/queue.js +13 -289
- package/dist/conversations/queue.service.d.ts +60 -0
- package/dist/conversations/queue.service.js +343 -0
- package/dist/conversations/sandbox-status.d.ts +13 -10
- package/dist/conversations/sandbox-status.js +36 -8
- package/dist/conversations/titles.d.ts +71 -24
- package/dist/conversations/titles.js +159 -63
- package/dist/ctx/bus.js +9 -3
- package/dist/ctx/create-ctx.d.ts +6 -0
- package/dist/ctx/create-ctx.js +7 -9
- package/dist/ctx/lock.d.ts +7 -3
- package/dist/ctx/lock.js +9 -20
- package/dist/ctx/secrets.d.ts +10 -2
- package/dist/ctx/secrets.js +7 -3
- package/dist/db/kernel-schema.d.ts +2 -2
- package/dist/db/pool.d.ts +5 -0
- package/dist/db/pool.js +1 -0
- package/dist/errors.d.ts +1 -0
- package/dist/errors.js +1 -0
- package/dist/evals/budget.d.ts +42 -21
- package/dist/evals/budget.js +114 -62
- package/dist/evals/evals.module.d.ts +31 -0
- package/dist/evals/evals.module.js +114 -0
- package/dist/evals/jobs.d.ts +20 -0
- package/dist/evals/jobs.js +45 -0
- package/dist/evals/run-replay.d.ts +56 -8
- package/dist/evals/run-replay.js +140 -80
- package/dist/evals/runs.controller.d.ts +1 -1
- package/dist/evals/runs.controller.js +17 -8
- package/dist/evals/runs.service.d.ts +23 -45
- package/dist/evals/runs.service.js +245 -234
- package/dist/evals/sets.controller.d.ts +1 -1
- package/dist/evals/sets.controller.js +17 -8
- package/dist/evals/sets.service.d.ts +22 -6
- package/dist/evals/sets.service.js +248 -194
- package/dist/evals/snapshot.d.ts +2 -2
- package/dist/evals/step-replay.d.ts +2 -2
- package/dist/evals/step-replay.js +1 -1
- package/dist/evals/trajectory.controller.d.ts +1 -1
- package/dist/evals/trajectory.controller.js +11 -7
- package/dist/evals/trajectory.service.d.ts +5 -4
- package/dist/evals/trajectory.service.js +30 -7
- package/dist/evals/worker.d.ts +44 -27
- package/dist/evals/worker.js +220 -121
- package/dist/extensions/admin-ops.d.ts +61 -33
- package/dist/extensions/admin-ops.js +248 -154
- package/dist/extensions/admin-view.d.ts +38 -27
- package/dist/extensions/admin-view.js +126 -55
- package/dist/extensions/approvals.d.ts +12 -8
- package/dist/extensions/approvals.js +73 -46
- package/dist/extensions/blobs.d.ts +27 -10
- package/dist/extensions/blobs.js +111 -45
- package/dist/extensions/bootstrap.d.ts +58 -31
- package/dist/extensions/bootstrap.js +175 -121
- package/dist/extensions/cli.d.ts +20 -10
- package/dist/extensions/cli.js +41 -96
- package/dist/extensions/config-issues.d.ts +7 -0
- package/dist/extensions/config-issues.js +31 -0
- package/dist/extensions/deployment-config-store.d.ts +49 -0
- package/dist/extensions/deployment-config-store.js +133 -0
- package/dist/extensions/deployment-config.d.ts +58 -67
- package/dist/extensions/deployment-config.js +202 -230
- package/dist/extensions/enabled.d.ts +5 -5
- package/dist/extensions/extensions.module.d.ts +8 -0
- package/dist/extensions/extensions.module.js +77 -0
- package/dist/extensions/hooks.d.ts +3 -2
- package/dist/extensions/hooks.js +1 -1
- package/dist/extensions/host.d.ts +72 -68
- package/dist/extensions/host.js +191 -152
- package/dist/extensions/installs.d.ts +49 -16
- package/dist/extensions/installs.js +128 -32
- package/dist/extensions/job-ids.d.ts +6 -0
- package/dist/extensions/job-ids.js +6 -0
- package/dist/extensions/lifecycle-topics.d.ts +18 -0
- package/dist/extensions/lifecycle-topics.js +18 -0
- package/dist/extensions/lifecycle.d.ts +35 -47
- package/dist/extensions/lifecycle.js +103 -39
- package/dist/extensions/locks.d.ts +33 -0
- package/dist/extensions/locks.js +86 -0
- package/dist/extensions/migrate-lock.d.ts +3 -4
- package/dist/extensions/org-config.controller.d.ts +1 -1
- package/dist/extensions/org-config.controller.js +8 -5
- package/dist/extensions/org-config.d.ts +48 -46
- package/dist/extensions/org-config.js +284 -226
- package/dist/extensions/registry.d.ts +50 -2
- package/dist/extensions/registry.js +89 -4
- package/dist/extensions/sources.d.ts +12 -8
- package/dist/extensions/sources.js +34 -13
- package/dist/files/files.module.d.ts +3 -0
- package/dist/files/files.module.js +22 -0
- package/dist/files/previewers.controller.d.ts +7 -2
- package/dist/files/previewers.controller.js +17 -9
- package/dist/files/previewers.d.ts +13 -18
- package/dist/files/previewers.js +83 -36
- package/dist/http/adapter.d.ts +3 -0
- package/dist/http/adapter.js +25 -0
- package/dist/http/api.module.d.ts +3 -110
- package/dist/http/api.module.js +47 -355
- package/dist/http/app.d.ts +11 -15
- package/dist/http/app.js +17 -62
- package/dist/http/error-filter.module.d.ts +5 -0
- package/dist/http/error-filter.module.js +18 -0
- package/dist/http/error.filter.js +2 -2
- package/dist/identity/accounts.d.ts +82 -29
- package/dist/identity/accounts.js +294 -175
- package/dist/identity/api-tokens.d.ts +11 -7
- package/dist/identity/api-tokens.js +71 -44
- package/dist/identity/audit.d.ts +7 -4
- package/dist/identity/audit.js +5 -1
- package/dist/identity/auth.controller.d.ts +11 -10
- package/dist/identity/auth.controller.js +31 -25
- package/dist/identity/auth.guard.d.ts +3 -3
- package/dist/identity/auth.guard.js +6 -4
- package/dist/identity/binding.d.ts +9 -11
- package/dist/identity/binding.js +41 -13
- package/dist/identity/enterprise-admin.d.ts +18 -12
- package/dist/identity/enterprise-admin.js +67 -13
- package/dist/identity/external-identity-lock.d.ts +17 -0
- package/dist/identity/external-identity-lock.js +39 -0
- package/dist/identity/external.d.ts +19 -15
- package/dist/identity/external.js +163 -125
- package/dist/identity/identity.module.d.ts +6 -0
- package/dist/identity/identity.module.js +56 -0
- package/dist/identity/me.controller.d.ts +16 -15
- package/dist/identity/me.controller.js +37 -31
- package/dist/identity/sessions.d.ts +12 -10
- package/dist/identity/sessions.js +74 -42
- package/dist/identity/settings.d.ts +20 -14
- package/dist/identity/settings.js +85 -57
- package/dist/identity/sso.controller.d.ts +7 -7
- package/dist/identity/sso.controller.js +13 -9
- package/dist/identity/sso.d.ts +9 -12
- package/dist/identity/sso.js +54 -24
- package/dist/inbox/inbox.module.d.ts +3 -0
- package/dist/inbox/inbox.module.js +22 -0
- package/dist/inbox/inbox.service.d.ts +7 -9
- package/dist/inbox/inbox.service.js +32 -11
- package/dist/index.d.ts +16 -11
- package/dist/index.js +9 -6
- package/dist/infra/cache/cache.module.d.ts +3 -0
- package/dist/infra/cache/cache.module.js +16 -0
- package/dist/infra/cache/cache.service.d.ts +21 -0
- package/dist/infra/cache/cache.service.js +80 -0
- package/dist/infra/cache/cacheable.decorator.d.ts +32 -0
- package/dist/infra/cache/cacheable.decorator.js +83 -0
- package/dist/infra/cli/kernel-cli.module.d.ts +66 -0
- package/dist/infra/cli/kernel-cli.module.js +165 -0
- package/dist/infra/close-within.d.ts +15 -0
- package/dist/infra/close-within.js +36 -0
- package/dist/infra/config/config.module.d.ts +13 -0
- package/dist/infra/config/config.module.js +39 -0
- package/dist/infra/config/kernel-config.service.d.ts +25 -0
- package/dist/infra/config/kernel-config.service.js +126 -0
- package/dist/infra/database/after-commit.d.ts +6 -0
- package/dist/infra/database/after-commit.js +9 -0
- package/dist/infra/database/database.module.d.ts +25 -0
- package/dist/infra/database/database.module.js +90 -0
- package/dist/infra/database/kernel-db.d.ts +22 -0
- package/dist/infra/database/kernel-db.js +65 -0
- package/dist/infra/database/transaction-host.d.ts +50 -0
- package/dist/infra/database/transaction-host.js +125 -0
- package/dist/infra/database/transactional.decorator.d.ts +15 -0
- package/dist/infra/database/transactional.decorator.js +27 -0
- package/dist/infra/database/xact-lock.d.ts +17 -0
- package/dist/infra/database/xact-lock.js +43 -0
- package/dist/infra/events/kernel-events.d.ts +96 -0
- package/dist/infra/events/kernel-events.js +65 -0
- package/dist/infra/health/health.controller.d.ts +26 -0
- package/dist/infra/health/health.controller.js +104 -0
- package/dist/infra/health/health.module.d.ts +9 -0
- package/dist/infra/health/health.module.js +24 -0
- package/dist/infra/health/health.options.d.ts +10 -0
- package/dist/infra/health/health.options.js +15 -0
- package/dist/infra/health/shutdown-state.d.ts +6 -0
- package/dist/infra/health/shutdown-state.js +2 -0
- package/dist/infra/lifecycle/graceful-shutdown.module.d.ts +6 -0
- package/dist/infra/lifecycle/graceful-shutdown.module.js +23 -0
- package/dist/infra/lifecycle/graceful-shutdown.service.d.ts +70 -0
- package/dist/infra/lifecycle/graceful-shutdown.service.js +135 -0
- package/dist/infra/lifecycle/process-guards.d.ts +52 -0
- package/dist/infra/lifecycle/process-guards.js +86 -0
- package/dist/infra/lifecycle/shutdown-signals.d.ts +30 -0
- package/dist/infra/lifecycle/shutdown-signals.js +48 -0
- package/dist/infra/lock/key-template.d.ts +13 -0
- package/dist/infra/lock/key-template.js +46 -0
- package/dist/infra/lock/lock.module.d.ts +3 -0
- package/dist/infra/lock/lock.module.js +16 -0
- package/dist/infra/lock/lock.service.d.ts +120 -0
- package/dist/infra/lock/lock.service.js +343 -0
- package/dist/infra/lock/shared-lease.d.ts +44 -0
- package/dist/infra/lock/shared-lease.js +121 -0
- package/dist/infra/lock/with-lock.decorator.d.ts +28 -0
- package/dist/infra/lock/with-lock.decorator.js +49 -0
- package/dist/infra/logging/logging.module.d.ts +16 -0
- package/dist/infra/logging/logging.module.js +34 -0
- package/dist/infra/queue/configured-processor.d.ts +18 -0
- package/dist/infra/queue/configured-processor.js +23 -0
- package/dist/infra/queue/job-failure.d.ts +18 -0
- package/dist/infra/queue/job-failure.js +26 -0
- package/dist/infra/queue/queue-shutdown.d.ts +27 -0
- package/dist/infra/queue/queue-shutdown.js +81 -0
- package/dist/infra/queue/queue.module.d.ts +16 -0
- package/dist/infra/queue/queue.module.js +61 -0
- package/dist/infra/queue/redis-connection.d.ts +7 -0
- package/dist/infra/queue/redis-connection.js +18 -0
- package/dist/infra/queue/retired-schedulers.d.ts +7 -0
- package/dist/infra/queue/retired-schedulers.js +9 -0
- package/dist/infra/queue/run-job.d.ts +16 -0
- package/dist/infra/queue/run-job.js +19 -0
- package/dist/infra/redis/redis.module.d.ts +24 -0
- package/dist/infra/redis/redis.module.js +87 -0
- package/dist/infra/schedule/cron-tick.d.ts +12 -0
- package/dist/infra/schedule/cron-tick.js +25 -0
- package/dist/infra/schedule/locked-cron.decorator.d.ts +27 -0
- package/dist/infra/schedule/locked-cron.decorator.js +53 -0
- package/dist/infra/schedule/locked-interval.d.ts +69 -0
- package/dist/infra/schedule/locked-interval.js +190 -0
- package/dist/infra/schedule/locked-tick.d.ts +90 -0
- package/dist/infra/schedule/locked-tick.js +137 -0
- package/dist/infra/schedule/schedule.module.d.ts +8 -0
- package/dist/infra/schedule/schedule.module.js +27 -0
- package/dist/infra/schedule/scheduled-runs.d.ts +69 -0
- package/dist/infra/schedule/scheduled-runs.js +163 -0
- package/dist/infra/swagger/swagger.d.ts +16 -0
- package/dist/infra/swagger/swagger.js +31 -0
- package/dist/infra/throttler/credential-throttler.d.ts +35 -0
- package/dist/infra/throttler/credential-throttler.js +77 -0
- package/dist/infra/throttler/named-throttlers.d.ts +31 -0
- package/dist/infra/throttler/named-throttlers.js +119 -0
- package/dist/infra/throttler/redis-throttler-storage.d.ts +38 -0
- package/dist/infra/throttler/redis-throttler-storage.js +130 -0
- package/dist/infra/throttler/throttler.guard.d.ts +23 -0
- package/dist/infra/throttler/throttler.guard.js +68 -0
- package/dist/infra/throttler/throttler.module.d.ts +15 -0
- package/dist/infra/throttler/throttler.module.js +53 -0
- package/dist/infra/tokens.d.ts +15 -0
- package/dist/infra/tokens.js +15 -0
- package/dist/infra/validation/create-zod-dto.d.ts +23 -0
- package/dist/infra/validation/create-zod-dto.js +35 -0
- package/dist/infra/validation/parse-with-zod.d.ts +7 -0
- package/dist/infra/validation/parse-with-zod.js +12 -0
- package/dist/infra/validation/validation.module.d.ts +3 -0
- package/dist/infra/validation/validation.module.js +16 -0
- package/dist/infra/validation/zod-params.d.ts +7 -0
- package/dist/infra/validation/zod-params.js +42 -0
- package/dist/infra/validation/zod-validation.pipe.d.ts +11 -0
- package/dist/infra/validation/zod-validation.pipe.js +31 -0
- package/dist/kernel.d.ts +9 -244
- package/dist/kernel.js +8 -1305
- package/dist/kernel.module.d.ts +17 -0
- package/dist/kernel.module.js +136 -0
- package/dist/lifecycle/kernel-lifecycle.d.ts +140 -0
- package/dist/lifecycle/kernel-lifecycle.js +451 -0
- package/dist/lifecycle/tokens.d.ts +3 -0
- package/dist/lifecycle/tokens.js +3 -0
- package/dist/log-context.d.ts +2 -0
- package/dist/log-context.js +4 -0
- package/dist/models/models.module.d.ts +3 -0
- package/dist/models/models.module.js +24 -0
- package/dist/models/prices.d.ts +8 -2
- package/dist/models/prices.js +65 -37
- package/dist/models/purposes.controller.d.ts +1 -1
- package/dist/models/purposes.controller.js +5 -6
- package/dist/models/purposes.d.ts +35 -13
- package/dist/models/purposes.js +101 -51
- package/dist/orgs/directory-sync.controller.d.ts +1 -1
- package/dist/orgs/directory-sync.controller.js +2 -2
- package/dist/orgs/directory-sync.d.ts +61 -31
- package/dist/orgs/directory-sync.js +212 -125
- package/dist/orgs/invitations.controller.d.ts +8 -8
- package/dist/orgs/invitations.controller.js +27 -26
- package/dist/orgs/invitations.service.d.ts +12 -9
- package/dist/orgs/invitations.service.js +130 -92
- package/dist/orgs/job-ids.d.ts +8 -0
- package/dist/orgs/job-ids.js +8 -0
- package/dist/orgs/members.service.d.ts +19 -12
- package/dist/orgs/members.service.js +161 -117
- package/dist/orgs/offboarding.d.ts +54 -57
- package/dist/orgs/offboarding.js +161 -71
- package/dist/orgs/org-lock.d.ts +28 -19
- package/dist/orgs/org-lock.js +81 -35
- package/dist/orgs/org.guard.d.ts +1 -1
- package/dist/orgs/org.guard.js +2 -2
- package/dist/orgs/orgs.controller.d.ts +13 -13
- package/dist/orgs/orgs.controller.js +29 -17
- package/dist/orgs/orgs.module.d.ts +6 -0
- package/dist/orgs/orgs.module.js +68 -0
- package/dist/orgs/orgs.service.d.ts +30 -19
- package/dist/orgs/orgs.service.js +139 -86
- package/dist/orgs/settings.controller.d.ts +1 -1
- package/dist/orgs/settings.controller.js +8 -6
- package/dist/orgs/settings.service.d.ts +14 -8
- package/dist/orgs/settings.service.js +75 -46
- package/dist/overrides.d.ts +56 -0
- package/dist/overrides.js +30 -0
- package/dist/roles/gateway-role.d.ts +43 -0
- package/dist/roles/gateway-role.js +98 -0
- package/dist/roles/gateway.module.d.ts +8 -0
- package/dist/roles/gateway.module.js +28 -0
- package/dist/roles/worker-role.d.ts +63 -0
- package/dist/roles/worker-role.js +144 -0
- package/dist/roles/worker.module.d.ts +14 -0
- package/dist/roles/worker.module.js +90 -0
- package/dist/runtime/abort.js +19 -2
- package/dist/runtime/checkpointer.d.ts +8 -3
- package/dist/runtime/checkpointer.js +87 -55
- package/dist/runtime/conversation-lock.d.ts +20 -11
- package/dist/runtime/conversation-lock.js +62 -72
- package/dist/runtime/hook-calls.d.ts +3 -3
- package/dist/runtime/hook-calls.js +1 -6
- package/dist/runtime/job-ids.d.ts +10 -0
- package/dist/runtime/job-ids.js +10 -0
- package/dist/runtime/langgraph-loop.js +1 -1
- package/dist/runtime/loop.d.ts +7 -0
- package/dist/runtime/loop.js +14 -0
- package/dist/runtime/maintenance-queue.d.ts +10 -0
- package/dist/runtime/maintenance-queue.js +10 -0
- package/dist/runtime/maintenance.d.ts +45 -74
- package/dist/runtime/maintenance.js +139 -137
- package/dist/runtime/model-call.d.ts +7 -4
- package/dist/runtime/model-call.js +24 -57
- package/dist/runtime/providers.d.ts +17 -6
- package/dist/runtime/providers.js +66 -25
- package/dist/runtime/quota.d.ts +17 -3
- package/dist/runtime/quota.js +27 -2
- package/dist/runtime/retired-schedulers.d.ts +7 -0
- package/dist/runtime/retired-schedulers.js +31 -0
- package/dist/runtime/run-control.d.ts +33 -0
- package/dist/runtime/run-control.js +77 -0
- package/dist/runtime/run-finish.d.ts +26 -17
- package/dist/runtime/run-finish.js +98 -51
- package/dist/runtime/run-jobs.d.ts +48 -0
- package/dist/runtime/run-jobs.js +95 -0
- package/dist/runtime/run-processors.d.ts +60 -0
- package/dist/runtime/run-processors.js +185 -0
- package/dist/runtime/run-queue.d.ts +32 -57
- package/dist/runtime/run-queue.js +291 -295
- package/dist/runtime/run-steps.d.ts +39 -0
- package/dist/runtime/run-steps.js +96 -0
- package/dist/runtime/run-worker.d.ts +121 -75
- package/dist/runtime/run-worker.js +340 -226
- package/dist/runtime/runtime.module.d.ts +10 -0
- package/dist/runtime/runtime.module.js +112 -0
- package/dist/runtime/step-log.d.ts +40 -0
- package/dist/runtime/step-log.js +94 -0
- package/dist/runtime/stream.controller.d.ts +5 -8
- package/dist/runtime/stream.controller.js +14 -12
- package/dist/runtime/stream.d.ts +24 -6
- package/dist/runtime/stream.js +78 -7
- package/dist/runtime/subagents/child.d.ts +3 -44
- package/dist/runtime/subagents/child.js +0 -79
- package/dist/runtime/subagents/definition.d.ts +4 -4
- package/dist/runtime/subagents/definition.js +2 -2
- package/dist/runtime/subagents/dispatch.d.ts +87 -6
- package/dist/runtime/subagents/dispatch.js +135 -140
- package/dist/runtime/subagents/limits.d.ts +9 -4
- package/dist/runtime/subagents/limits.js +4 -2
- package/dist/runtime/subagents/org-agents.d.ts +4 -4
- package/dist/runtime/subagents/org-agents.js +1 -1
- package/dist/runtime/subagents/progress.d.ts +2 -2
- package/dist/runtime/subagents/roster.d.ts +3 -3
- package/dist/runtime/subagents/roster.js +1 -1
- package/dist/runtime/subagents/skill-fork.d.ts +6 -7
- package/dist/runtime/subagents/skill-fork.js +16 -5
- package/dist/runtime/subagents/subagents.service.d.ts +40 -0
- package/dist/runtime/subagents/subagents.service.js +101 -0
- package/dist/runtime/usage-report.d.ts +94 -52
- package/dist/runtime/usage-report.js +200 -100
- package/dist/runtime/waits.d.ts +125 -57
- package/dist/runtime/waits.js +431 -208
- package/dist/sandbox/job-ids.d.ts +10 -0
- package/dist/sandbox/job-ids.js +10 -0
- package/dist/sandbox/jobs.d.ts +41 -0
- package/dist/sandbox/jobs.js +113 -0
- package/dist/sandbox/leases.d.ts +39 -31
- package/dist/sandbox/leases.js +117 -257
- package/dist/sandbox/providers.d.ts +19 -0
- package/dist/sandbox/providers.js +38 -0
- package/dist/sandbox/sandbox.module.d.ts +8 -0
- package/dist/sandbox/sandbox.module.js +30 -0
- package/dist/sandbox/sandbox.service.d.ts +24 -29
- package/dist/sandbox/sandbox.service.js +106 -75
- package/dist/skills/catalog.d.ts +33 -20
- package/dist/skills/catalog.js +96 -53
- package/dist/skills/changes.controller.d.ts +4 -4
- package/dist/skills/changes.controller.js +15 -9
- package/dist/skills/changes.service.d.ts +28 -18
- package/dist/skills/changes.service.js +421 -364
- package/dist/skills/invocable.controller.d.ts +1 -1
- package/dist/skills/invocable.controller.js +8 -5
- package/dist/skills/invoke.d.ts +16 -15
- package/dist/skills/invoke.js +48 -17
- package/dist/skills/skills.controller.d.ts +1 -1
- package/dist/skills/skills.controller.js +11 -6
- package/dist/skills/skills.module.d.ts +6 -0
- package/dist/skills/skills.module.js +30 -0
- package/dist/skills/skills.service.d.ts +47 -30
- package/dist/skills/skills.service.js +221 -158
- package/dist/storage/job-ids.d.ts +6 -0
- package/dist/storage/job-ids.js +6 -0
- package/dist/storage/purge.d.ts +22 -7
- package/dist/storage/purge.js +55 -3
- package/dist/storage/storage.module.d.ts +6 -0
- package/dist/storage/storage.module.js +23 -0
- package/dist/storage/storage.service.d.ts +18 -4
- package/dist/storage/storage.service.js +44 -3
- package/dist/tools/approvals.controller.d.ts +1 -1
- package/dist/tools/approvals.controller.js +12 -8
- package/dist/tools/approvals.service.d.ts +27 -25
- package/dist/tools/approvals.service.js +324 -258
- package/dist/tools/breaker.d.ts +2 -2
- package/dist/tools/breaker.js +21 -3
- package/dist/tools/builtins/ask-user.d.ts +2 -2
- package/dist/tools/builtins/ask-user.js +1 -1
- package/dist/tools/builtins/builtin-tools.d.ts +21 -0
- package/dist/tools/builtins/builtin-tools.js +80 -0
- package/dist/tools/builtins/read-tool-output.d.ts +2 -2
- package/dist/tools/builtins/read-tool-output.js +1 -1
- package/dist/tools/builtins/sandbox/bash.js +2 -2
- package/dist/tools/builtins/sandbox/common.d.ts +2 -1
- package/dist/tools/builtins/sandbox/deliver.js +2 -2
- package/dist/tools/builtins/sandbox/edit.js +1 -1
- package/dist/tools/builtins/sandbox/glob.js +2 -2
- package/dist/tools/builtins/sandbox/grep.js +2 -2
- package/dist/tools/builtins/sandbox/read.js +1 -1
- package/dist/tools/builtins/sandbox/write.js +1 -1
- package/dist/tools/builtins/skill-load.d.ts +3 -3
- package/dist/tools/builtins/skill-load.js +1 -1
- package/dist/tools/canonical-json.d.ts +6 -0
- package/dist/tools/canonical-json.js +16 -0
- package/dist/tools/connector-content.controller.d.ts +1 -1
- package/dist/tools/connector-content.controller.js +11 -6
- package/dist/tools/connector-content.d.ts +12 -15
- package/dist/tools/connector-content.js +53 -18
- package/dist/tools/connectors.controller.d.ts +1 -1
- package/dist/tools/connectors.controller.js +21 -10
- package/dist/tools/connectors.service.d.ts +31 -13
- package/dist/tools/connectors.service.js +434 -344
- package/dist/tools/credentials.d.ts +17 -20
- package/dist/tools/credentials.js +55 -34
- package/dist/tools/drift.d.ts +29 -41
- package/dist/tools/drift.js +111 -79
- package/dist/tools/info.d.ts +12 -9
- package/dist/tools/info.js +33 -7
- package/dist/tools/job-ids.d.ts +13 -0
- package/dist/tools/job-ids.js +15 -0
- package/dist/tools/jobs.d.ts +24 -0
- package/dist/tools/jobs.js +69 -0
- package/dist/tools/oauth/flow-paths.d.ts +16 -0
- package/dist/tools/oauth/flow-paths.js +38 -0
- package/dist/tools/oauth/flow.d.ts +30 -30
- package/dist/tools/oauth/flow.js +109 -81
- package/dist/tools/oauth/oauth.controller.d.ts +3 -3
- package/dist/tools/oauth/oauth.controller.js +12 -9
- package/dist/tools/oauth/tokens.d.ts +11 -3
- package/dist/tools/oauth/tokens.js +15 -14
- package/dist/tools/outputs.d.ts +13 -4
- package/dist/tools/outputs.js +47 -3
- package/dist/tools/pipeline.d.ts +62 -46
- package/dist/tools/pipeline.js +145 -64
- package/dist/tools/policy.d.ts +2 -2
- package/dist/tools/questions.controller.d.ts +1 -1
- package/dist/tools/questions.controller.js +8 -5
- package/dist/tools/questions.service.d.ts +25 -24
- package/dist/tools/questions.service.js +201 -142
- package/dist/tools/registry.d.ts +30 -20
- package/dist/tools/registry.js +73 -37
- package/dist/tools/specs.d.ts +5 -4
- package/dist/tools/specs.js +3 -1
- package/dist/tools/tools.module.d.ts +10 -0
- package/dist/tools/tools.module.js +91 -0
- package/dist/ui/call-extension.d.ts +16 -0
- package/dist/ui/call-extension.js +38 -0
- package/dist/ui/embed-token.d.ts +9 -5
- package/dist/ui/embed-token.js +34 -6
- package/dist/ui/ui-stream.d.ts +22 -17
- package/dist/ui/ui-stream.js +72 -12
- package/dist/ui/ui.module.d.ts +7 -0
- package/dist/ui/ui.module.js +28 -0
- package/dist/ui/views.controller.d.ts +14 -12
- package/dist/ui/views.controller.js +32 -25
- package/dist/ui/views.d.ts +9 -57
- package/dist/ui/views.js +43 -45
- package/package.json +9 -2
- package/dist/http/health.controller.d.ts +0 -26
- package/dist/http/health.controller.js +0 -79
- package/dist/http/tokens.d.ts +0 -131
- package/dist/http/tokens.js +0 -131
- package/dist/http/zod.pipe.d.ts +0 -8
- package/dist/http/zod.pipe.js +0 -14
- package/dist/identity/rate-limit.d.ts +0 -55
- package/dist/identity/rate-limit.js +0 -121
- package/dist/sandbox/lifecycle.d.ts +0 -21
- package/dist/sandbox/lifecycle.js +0 -68
- /package/dist/http/{gateway.module.d.ts → gateway-routes.d.ts} +0 -0
- /package/dist/http/{gateway.module.js → gateway-routes.js} +0 -0
package/dist/runtime/waits.js
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
10
|
+
import { getQueueToken } from "@nestjs/bullmq";
|
|
11
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
1
12
|
import { DelayedError } from "bullmq";
|
|
2
13
|
import { sql } from "kysely";
|
|
3
|
-
import {
|
|
14
|
+
import { EventLog } from "../conversations/event-log.js";
|
|
15
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
16
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
17
|
+
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
18
|
+
import { KernelEvents } from "../infra/events/kernel-events.js";
|
|
19
|
+
import { LockService } from "../infra/lock/lock.service.js";
|
|
20
|
+
import { LockedCron } from "../infra/schedule/locked-cron.decorator.js";
|
|
21
|
+
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
22
|
+
import { ApprovalsService } from "../tools/approvals.service.js";
|
|
23
|
+
import { APPROVAL_CANCELLED_TEXT, INPUT_CANCELLED_TEXT, RUN_STOPPED_TEXT, ToolPipeline, } from "../tools/pipeline.js";
|
|
24
|
+
import { QuestionsService } from "../tools/questions.service.js";
|
|
25
|
+
import { RunAbort } from "./abort.js";
|
|
26
|
+
import { KyselyCheckpointSaver } from "./checkpointer.js";
|
|
4
27
|
import { subagentsWaitId, subagentWaitingIdemKey } from "./loop.js";
|
|
5
|
-
import { MAINTENANCE_QUEUE_NAME } from "./maintenance.js";
|
|
28
|
+
import { MAINTENANCE_QUEUE_NAME } from "./maintenance-queue.js";
|
|
6
29
|
import { assistantIdemKey } from "./model-call.js";
|
|
7
|
-
import {
|
|
8
|
-
import { ACTIVE_RUN_STATUSES } from "./run-queue.js";
|
|
30
|
+
import { notifyFinished, RunFinish, TERMINAL_STATUSES } from "./run-finish.js";
|
|
31
|
+
import { ACTIVE_RUN_STATUSES, RunQueue } from "./run-queue.js";
|
|
32
|
+
import { childResult, dispatchOfChildRun, finishedEvent } from "./subagents/child.js";
|
|
9
33
|
/** 等待超时任务所在的内核维护队列(见 maintenance.ts)。 */
|
|
10
34
|
export { MAINTENANCE_QUEUE_NAME };
|
|
11
35
|
/** 等待超时任务的名字与 jobId(每个审批 / 输入请求一个,重复投递被 BullMQ 忽略)。 */
|
|
@@ -18,8 +42,8 @@ export const resumeJobId = (conversationId, waitId) => `run-${conversationId}-re
|
|
|
18
42
|
* 宽限期:waiting 超过它、等待却已全部处理的运行才视为「续跑丢失」,避免与正常续跑(暂停后的复查等)竞争。
|
|
19
43
|
*/
|
|
20
44
|
export const WAIT_SWEEP_JOB = "wait-sweep";
|
|
21
|
-
|
|
22
|
-
export
|
|
45
|
+
/** The maintenance scheduler the sweep ran on before it became a `@LockedCron` (retired). */
|
|
46
|
+
export { WAIT_SWEEP_SCHEDULER_ID } from "./job-ids.js";
|
|
23
47
|
export const WAIT_SWEEP_GRACE_MS = 60_000;
|
|
24
48
|
export const WAIT_SWEEP_BATCH = 500;
|
|
25
49
|
const TERMINAL_RUN_STATUSES = ["completed", "failed", "aborted"];
|
|
@@ -34,19 +58,62 @@ const TIMEOUT_JOB_BACKOFF_MS = 5_000;
|
|
|
34
58
|
* 成功者投递 jobId 为 `run-<conversationId>-resume-<waitId>` 的运行任务。人工决定、超时任务、
|
|
35
59
|
* 暂停后的复查都可能调用它,谁先谁后都只有一次续跑。
|
|
36
60
|
*/
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
61
|
+
let Waits = class Waits {
|
|
62
|
+
kdb;
|
|
63
|
+
eventLog;
|
|
64
|
+
approvals;
|
|
65
|
+
questions;
|
|
66
|
+
runQueue;
|
|
67
|
+
pipeline;
|
|
68
|
+
finisher;
|
|
69
|
+
checkpoints;
|
|
70
|
+
abort;
|
|
71
|
+
timeouts;
|
|
72
|
+
log;
|
|
73
|
+
txHost;
|
|
74
|
+
/** Drops the `run.orphaned` subscription (the events may outlive this instance). */
|
|
75
|
+
unsubscribe;
|
|
76
|
+
constructor(kdb, eventLog, approvals, questions, runQueue,
|
|
77
|
+
/**
|
|
78
|
+
* Writes, in the caller's transaction, the results of a stopped run's open `agent` calls;
|
|
79
|
+
* `fire` runs their observe hooks after the commit.
|
|
80
|
+
*/
|
|
81
|
+
pipeline, finisher,
|
|
82
|
+
/** 等待中被中止的运行删除其 checkpoint thread。 */
|
|
83
|
+
checkpoints,
|
|
84
|
+
/**
|
|
85
|
+
* The run's stop marker (`RunAbort.requested`): between suspending and becoming `waiting` the
|
|
86
|
+
* run has no subscriber, so a stop arriving then only sits in the marker; checked once after
|
|
87
|
+
* `waiting` is set. Children are stopped through `request`.
|
|
88
|
+
*/
|
|
89
|
+
abort,
|
|
90
|
+
/** The maintenance queue: wait timeout jobs (`MaintenanceProcessor` consumes them). */
|
|
91
|
+
timeouts, events, log, txHost) {
|
|
92
|
+
this.kdb = kdb;
|
|
93
|
+
this.eventLog = eventLog;
|
|
94
|
+
this.approvals = approvals;
|
|
95
|
+
this.questions = questions;
|
|
96
|
+
this.runQueue = runQueue;
|
|
97
|
+
this.pipeline = pipeline;
|
|
98
|
+
this.finisher = finisher;
|
|
99
|
+
this.checkpoints = checkpoints;
|
|
100
|
+
this.abort = abort;
|
|
101
|
+
this.timeouts = timeouts;
|
|
102
|
+
this.log = log;
|
|
103
|
+
this.txHost = txHost;
|
|
104
|
+
// an orphaned parent run (marked failed by `ensureRun`) stops its children at once; the
|
|
105
|
+
// sweep's `sweepChildrenOfFinished` is the backstop
|
|
106
|
+
this.unsubscribe = events.on("run.orphaned", ({ runId }) => this.stopChildren(runId, null)
|
|
107
|
+
.then(() => { })
|
|
108
|
+
.catch((err) => this.log.error("cannot stop the sub-agents of an orphaned run", { runId, err })));
|
|
109
|
+
}
|
|
110
|
+
/** Unsubscribes after the stop phases: events emitted while they drain are still handled. */
|
|
111
|
+
onApplicationShutdown() {
|
|
112
|
+
this.unsubscribe();
|
|
113
|
+
}
|
|
114
|
+
/** The context's handle (the transaction of a `@Transactional` method, else the pool). */
|
|
115
|
+
get db() {
|
|
116
|
+
return this.kdb.db;
|
|
50
117
|
}
|
|
51
118
|
/**
|
|
52
119
|
* 兜底扫描(维护队列每 10 分钟一次,防延迟任务 / 续跑丢失)。每项修复都复用常规路径,与并发的超时任务、
|
|
@@ -81,7 +148,7 @@ export class Waits {
|
|
|
81
148
|
* 运行(置 waiting 之后到达的中止由 `POST .../abort` 看到 waiting 直接处理,两边不会都漏掉)。
|
|
82
149
|
*/
|
|
83
150
|
async suspend(runId, conversationId, waitingFor, abort) {
|
|
84
|
-
const r = await this.
|
|
151
|
+
const r = await this.db
|
|
85
152
|
.updateTable("runs")
|
|
86
153
|
.set({
|
|
87
154
|
status: "waiting",
|
|
@@ -93,10 +160,10 @@ export class Waits {
|
|
|
93
160
|
.where("status", "=", "running")
|
|
94
161
|
.executeTakeFirst();
|
|
95
162
|
if (Number(r.numUpdatedRows) === 0) {
|
|
96
|
-
this.
|
|
163
|
+
this.log.warn("run is no longer running; not suspending", { runId });
|
|
97
164
|
return;
|
|
98
165
|
}
|
|
99
|
-
const stop = abort ?? (await this.
|
|
166
|
+
const stop = abort ?? (await this.abort.requested(runId)) ?? null;
|
|
100
167
|
if (stop && (await this.abortWaiting(conversationId, runId, stop.byAccountId, stop.detail))) {
|
|
101
168
|
return;
|
|
102
169
|
}
|
|
@@ -116,7 +183,7 @@ export class Waits {
|
|
|
116
183
|
if (waitingFor.kind === "subagents")
|
|
117
184
|
return;
|
|
118
185
|
try {
|
|
119
|
-
const d = await this.
|
|
186
|
+
const d = await this.db
|
|
120
187
|
.selectFrom("subagent_dispatches")
|
|
121
188
|
.select(["parent_conversation_id", "parent_run_id", "child_conversation_id"])
|
|
122
189
|
.where("child_run_id", "=", runId)
|
|
@@ -124,19 +191,19 @@ export class Waits {
|
|
|
124
191
|
if (!d)
|
|
125
192
|
return;
|
|
126
193
|
const row = waitingFor.kind === "approval"
|
|
127
|
-
? await this.
|
|
194
|
+
? await this.db
|
|
128
195
|
.selectFrom("approvals")
|
|
129
196
|
.select(["tool_key", "expires_at"])
|
|
130
197
|
.where("id", "=", waitingFor.id)
|
|
131
198
|
.executeTakeFirst()
|
|
132
|
-
: await this.
|
|
199
|
+
: await this.db
|
|
133
200
|
.selectFrom("questions")
|
|
134
201
|
.select([sql `spec->>'toolKey'`.as("tool_key"), "expires_at"])
|
|
135
202
|
.where("id", "=", waitingFor.id)
|
|
136
203
|
.executeTakeFirst();
|
|
137
204
|
if (!row)
|
|
138
205
|
return;
|
|
139
|
-
await this.
|
|
206
|
+
await this.eventLog.append(d.parent_conversation_id, [
|
|
140
207
|
{
|
|
141
208
|
type: "subagent_waiting",
|
|
142
209
|
runId: d.parent_run_id,
|
|
@@ -155,7 +222,7 @@ export class Waits {
|
|
|
155
222
|
]);
|
|
156
223
|
}
|
|
157
224
|
catch (err) {
|
|
158
|
-
this.
|
|
225
|
+
this.log.error("cannot surface a sub-agent's wait in its parent", { runId, err });
|
|
159
226
|
}
|
|
160
227
|
}
|
|
161
228
|
/**
|
|
@@ -164,7 +231,7 @@ export class Waits {
|
|
|
164
231
|
* 投递失败 → 撤回为 waiting(等待时长已计入,重新从现在起计),之后超时任务到点会再次续跑,并抛出。
|
|
165
232
|
*/
|
|
166
233
|
async resume(runId, waitId) {
|
|
167
|
-
const row = await this.
|
|
234
|
+
const row = await this.db
|
|
168
235
|
.updateTable("runs")
|
|
169
236
|
.set({
|
|
170
237
|
status: "queued",
|
|
@@ -197,11 +264,11 @@ export class Waits {
|
|
|
197
264
|
return false;
|
|
198
265
|
const jobId = resumeJobId(row.conversation_id, waitId);
|
|
199
266
|
try {
|
|
200
|
-
await this.
|
|
267
|
+
await this.runQueue.enqueue({ runId, conversationId: row.conversation_id }, jobId);
|
|
201
268
|
}
|
|
202
269
|
catch (err) {
|
|
203
|
-
this.
|
|
204
|
-
await this.
|
|
270
|
+
this.log.error("cannot enqueue resumed run; back to waiting", { runId, jobId, err });
|
|
271
|
+
await this.db
|
|
205
272
|
.updateTable("runs")
|
|
206
273
|
.set({ status: "waiting", waiting_since: sql `now()`, job_id: null, queued_at: null })
|
|
207
274
|
.where("id", "=", runId)
|
|
@@ -223,13 +290,13 @@ export class Waits {
|
|
|
223
290
|
// stopped child reports to the parent, and the last one resumes it. The resume tried here
|
|
224
291
|
// covers a step whose children were all done already.
|
|
225
292
|
if (!at) {
|
|
226
|
-
this.
|
|
293
|
+
this.log.warn("sub-agent wait timeout without its run; ignored", { id });
|
|
227
294
|
return {};
|
|
228
295
|
}
|
|
229
296
|
const { runId, step } = at;
|
|
230
|
-
const stopped =
|
|
297
|
+
const stopped = await this.stopChildren(runId, null, { step, detail: "wait_timeout" });
|
|
231
298
|
if (stopped > 0) {
|
|
232
|
-
this.
|
|
299
|
+
this.log.warn("sub-agent wait timed out; stopping its sub-agents", {
|
|
233
300
|
runId,
|
|
234
301
|
id,
|
|
235
302
|
stopped,
|
|
@@ -238,7 +305,7 @@ export class Waits {
|
|
|
238
305
|
const resumed = await this.resume(runId, id);
|
|
239
306
|
return { acted: stopped > 0 || resumed };
|
|
240
307
|
}
|
|
241
|
-
const r = kind === "approval" ? await this.
|
|
308
|
+
const r = kind === "approval" ? await this.approvals.expire(id) : await this.questions.expire(id);
|
|
242
309
|
if (r.outcome === "not_due" && r.record) {
|
|
243
310
|
return { notDueUntil: new Date(r.record.expiresAt).getTime() };
|
|
244
311
|
}
|
|
@@ -253,94 +320,93 @@ export class Waits {
|
|
|
253
320
|
* 运行已不是 waiting(例如刚被续跑)→ 返回 false,由调用方走常规中止。
|
|
254
321
|
*/
|
|
255
322
|
async abortWaiting(conversationId, runId, byAccountId, detail) {
|
|
256
|
-
|
|
257
|
-
const toSeq = await this.
|
|
258
|
-
|
|
259
|
-
await t
|
|
260
|
-
.selectFrom("conversations")
|
|
261
|
-
.select("id")
|
|
262
|
-
.where("id", "=", conversationId)
|
|
263
|
-
.forUpdate()
|
|
264
|
-
.executeTakeFirst();
|
|
265
|
-
const run = await t
|
|
266
|
-
.selectFrom("runs")
|
|
267
|
-
.select("status")
|
|
268
|
-
.where("id", "=", runId)
|
|
269
|
-
.where("conversation_id", "=", conversationId)
|
|
270
|
-
.forUpdate()
|
|
271
|
-
.executeTakeFirst();
|
|
272
|
-
if (run?.status !== "waiting")
|
|
273
|
-
return null;
|
|
274
|
-
await this.d.approvals.cancelPendingIn(t, runId);
|
|
275
|
-
await this.d.questions.cancelPendingIn(t, runId);
|
|
276
|
-
// 本运行全部审批 / 输入请求涉及的调用(不只刚取消的):决定已提交、续跑尚未发生时被中止的调用同样没有结果,
|
|
277
|
-
// 一并写取消说明(已有结果的按幂等键命中、不重复)。同一调用先审批后输入,后者覆盖前者。
|
|
278
|
-
const cancelled = new Map();
|
|
279
|
-
const steps = new Set();
|
|
280
|
-
const approvals = await t
|
|
281
|
-
.selectFrom("approvals")
|
|
282
|
-
.select(["id", "call_id", "tool_key"])
|
|
283
|
-
.where("run_id", "=", runId)
|
|
284
|
-
.orderBy("created_at")
|
|
285
|
-
.execute();
|
|
286
|
-
for (const a of approvals) {
|
|
287
|
-
cancelled.set(a.call_id, { toolKey: a.tool_key, text: APPROVAL_CANCELLED_TEXT });
|
|
288
|
-
const step = await this.approvalStep(t, conversationId, a.id);
|
|
289
|
-
if (step !== null)
|
|
290
|
-
steps.add(step);
|
|
291
|
-
}
|
|
292
|
-
const questions = await t
|
|
293
|
-
.selectFrom("questions")
|
|
294
|
-
.select(["call_id", "spec"])
|
|
295
|
-
.where("run_id", "=", runId)
|
|
296
|
-
.orderBy("created_at")
|
|
297
|
-
.execute();
|
|
298
|
-
for (const q of questions) {
|
|
299
|
-
const spec = q.spec;
|
|
300
|
-
cancelled.set(q.call_id, { toolKey: spec.toolKey ?? "", text: INPUT_CANCELLED_TEXT });
|
|
301
|
-
if (typeof spec.step === "number")
|
|
302
|
-
steps.add(spec.step);
|
|
303
|
-
}
|
|
304
|
-
// a parent waiting on sub-agents (spec §12): its open `agent` calls get their results
|
|
305
|
-
const agents = await this.d.subagents?.stopOpenCalls?.(t, runId);
|
|
306
|
-
for (const step of agents?.steps ?? [])
|
|
307
|
-
steps.add(step);
|
|
308
|
-
const results = await this.stoppedResults(t, conversationId, runId, [...steps], cancelled, agents?.callIds);
|
|
309
|
-
if (results.length > 0)
|
|
310
|
-
await this.d.eventLog.append(conversationId, results, t);
|
|
311
|
-
stopped = agents;
|
|
312
|
-
return finishRunIn(t, this.d.eventLog, {
|
|
313
|
-
conversationId,
|
|
314
|
-
runId,
|
|
315
|
-
status: "aborted",
|
|
316
|
-
consumed: null,
|
|
317
|
-
event: {
|
|
318
|
-
type: "run_aborted",
|
|
319
|
-
payload: { byAccountId, reason: "user", ...(detail !== undefined && { detail }) },
|
|
320
|
-
},
|
|
321
|
-
});
|
|
322
|
-
});
|
|
323
|
+
const st = {};
|
|
324
|
+
const toSeq = await this.abortWaitingIn(conversationId, runId, byAccountId, detail, st);
|
|
325
|
+
const stopped = st.stopped;
|
|
323
326
|
if (toSeq === null)
|
|
324
327
|
return false;
|
|
325
|
-
await notifyFinished(this.
|
|
326
|
-
await this.
|
|
327
|
-
|
|
328
|
-
.catch((err) => this.
|
|
328
|
+
await notifyFinished(this.eventLog, conversationId, toSeq, "aborted");
|
|
329
|
+
await this.checkpoints
|
|
330
|
+
.deleteThread(runId)
|
|
331
|
+
.catch((err) => this.log.warn("checkpoint delete failed", { runId, err }));
|
|
329
332
|
stopped?.fire();
|
|
330
333
|
// a stopped sub-agent reports to its parent now, not at the next sweep (a no-op for other runs)
|
|
331
|
-
await this.
|
|
332
|
-
?.finished(runId)
|
|
333
|
-
.catch((err) => this.d.log.error("cannot report stopped sub-agent run", { runId, err }));
|
|
334
|
+
await this.childFinished(runId).catch((err) => this.log.error("cannot report stopped sub-agent run", { runId, err }));
|
|
334
335
|
// a stopped parent stops its children (spec §12), on the parent's behalf (no account: they
|
|
335
336
|
// report "stopped with this run"); the wait sweep is the backstop
|
|
336
|
-
await this.
|
|
337
|
-
?.stop(runId, null)
|
|
338
|
-
.catch((err) => this.d.log.error("cannot stop the sub-agents of a run", { runId, err }));
|
|
337
|
+
await this.stopChildren(runId, null).catch((err) => this.log.error("cannot stop the sub-agents of a run", { runId, err }));
|
|
339
338
|
return true;
|
|
340
339
|
}
|
|
340
|
+
/** {@link abortWaiting}'s transaction; the open `agent` calls it wrote go back through `st`. */
|
|
341
|
+
async abortWaitingIn(conversationId, runId, byAccountId, detail, st) {
|
|
342
|
+
const t = this.db;
|
|
343
|
+
await t
|
|
344
|
+
.selectFrom("conversations")
|
|
345
|
+
.select("id")
|
|
346
|
+
.where("id", "=", conversationId)
|
|
347
|
+
.forUpdate()
|
|
348
|
+
.executeTakeFirst();
|
|
349
|
+
const run = await t
|
|
350
|
+
.selectFrom("runs")
|
|
351
|
+
.select("status")
|
|
352
|
+
.where("id", "=", runId)
|
|
353
|
+
.where("conversation_id", "=", conversationId)
|
|
354
|
+
.forUpdate()
|
|
355
|
+
.executeTakeFirst();
|
|
356
|
+
if (run?.status !== "waiting")
|
|
357
|
+
return null;
|
|
358
|
+
await this.approvals.cancelPendingIn(runId);
|
|
359
|
+
await this.questions.cancelPendingIn(runId);
|
|
360
|
+
// 本运行全部审批 / 输入请求涉及的调用(不只刚取消的):决定已提交、续跑尚未发生时被中止的调用同样没有结果,
|
|
361
|
+
// 一并写取消说明(已有结果的按幂等键命中、不重复)。同一调用先审批后输入,后者覆盖前者。
|
|
362
|
+
const cancelled = new Map();
|
|
363
|
+
const steps = new Set();
|
|
364
|
+
const approvals = await t
|
|
365
|
+
.selectFrom("approvals")
|
|
366
|
+
.select(["id", "call_id", "tool_key"])
|
|
367
|
+
.where("run_id", "=", runId)
|
|
368
|
+
.orderBy("created_at")
|
|
369
|
+
.execute();
|
|
370
|
+
for (const a of approvals) {
|
|
371
|
+
cancelled.set(a.call_id, { toolKey: a.tool_key, text: APPROVAL_CANCELLED_TEXT });
|
|
372
|
+
const step = await this.approvalStep(t, conversationId, a.id);
|
|
373
|
+
if (step !== null)
|
|
374
|
+
steps.add(step);
|
|
375
|
+
}
|
|
376
|
+
const questions = await t
|
|
377
|
+
.selectFrom("questions")
|
|
378
|
+
.select(["call_id", "spec"])
|
|
379
|
+
.where("run_id", "=", runId)
|
|
380
|
+
.orderBy("created_at")
|
|
381
|
+
.execute();
|
|
382
|
+
for (const q of questions) {
|
|
383
|
+
const spec = q.spec;
|
|
384
|
+
cancelled.set(q.call_id, { toolKey: spec.toolKey ?? "", text: INPUT_CANCELLED_TEXT });
|
|
385
|
+
if (typeof spec.step === "number")
|
|
386
|
+
steps.add(spec.step);
|
|
387
|
+
}
|
|
388
|
+
// a parent waiting on sub-agents (spec §12): its open `agent` calls get their results
|
|
389
|
+
const agents = await this.pipeline.stopOpenAgentCalls(runId);
|
|
390
|
+
for (const step of agents.steps)
|
|
391
|
+
steps.add(step);
|
|
392
|
+
const results = await this.stoppedResults(t, conversationId, runId, [...steps], cancelled, agents?.callIds);
|
|
393
|
+
if (results.length > 0)
|
|
394
|
+
await this.eventLog.appendIn(conversationId, results);
|
|
395
|
+
st.stopped = agents;
|
|
396
|
+
return this.finisher.finishIn({
|
|
397
|
+
conversationId,
|
|
398
|
+
runId,
|
|
399
|
+
status: "aborted",
|
|
400
|
+
consumed: null,
|
|
401
|
+
event: {
|
|
402
|
+
type: "run_aborted",
|
|
403
|
+
payload: { byAccountId, reason: "user", ...(detail !== undefined && { detail }) },
|
|
404
|
+
},
|
|
405
|
+
});
|
|
406
|
+
}
|
|
341
407
|
/** 扫描 3:运行已终态(如暂停途中失败)仍 pending 的审批 / 输入请求 → 取消(写决定 / 回答事件)。 */
|
|
342
408
|
async sweepFinishedRuns() {
|
|
343
|
-
const
|
|
409
|
+
const db = this.db;
|
|
344
410
|
const runs = await db
|
|
345
411
|
.selectFrom("runs")
|
|
346
412
|
.select(["id", "conversation_id"])
|
|
@@ -363,7 +429,7 @@ export class Waits {
|
|
|
363
429
|
const n = await this.cancelWaitsOfFinished(run.conversation_id, run.id);
|
|
364
430
|
if (n > 0) {
|
|
365
431
|
total += n;
|
|
366
|
-
this.
|
|
432
|
+
this.log.warn("wait sweep: cancelled waits of finished run", {
|
|
367
433
|
runId: run.id,
|
|
368
434
|
conversationId: run.conversation_id,
|
|
369
435
|
count: n,
|
|
@@ -371,7 +437,7 @@ export class Waits {
|
|
|
371
437
|
}
|
|
372
438
|
}
|
|
373
439
|
catch (err) {
|
|
374
|
-
this.
|
|
440
|
+
this.log.error("wait sweep: cannot cancel waits of finished run", { runId: run.id, err });
|
|
375
441
|
}
|
|
376
442
|
}
|
|
377
443
|
return total;
|
|
@@ -381,39 +447,41 @@ export class Waits {
|
|
|
381
447
|
* 提交后发布事件。返回取消的条数(并发的另一副本拿到锁时已无 pending → 0)。
|
|
382
448
|
*/
|
|
383
449
|
async cancelWaitsOfFinished(conversationId, runId) {
|
|
384
|
-
const r = await this.
|
|
385
|
-
await t
|
|
386
|
-
.selectFrom("conversations")
|
|
387
|
-
.select("id")
|
|
388
|
-
.where("id", "=", conversationId)
|
|
389
|
-
.forUpdate()
|
|
390
|
-
.executeTakeFirst();
|
|
391
|
-
const run = await t
|
|
392
|
-
.selectFrom("runs")
|
|
393
|
-
.select("status")
|
|
394
|
-
.where("id", "=", runId)
|
|
395
|
-
.forUpdate()
|
|
396
|
-
.executeTakeFirst();
|
|
397
|
-
if (!run || !TERMINAL_RUN_STATUSES.includes(run.status))
|
|
398
|
-
return 0;
|
|
399
|
-
const a = await this.d.approvals.cancelPendingIn(t, runId);
|
|
400
|
-
const q = await this.d.questions.cancelPendingIn(t, runId);
|
|
401
|
-
return a.length + q.length;
|
|
402
|
-
});
|
|
450
|
+
const r = await this.cancelWaitsOfFinishedIn(conversationId, runId);
|
|
403
451
|
if (r > 0) {
|
|
404
|
-
const last = await this.
|
|
452
|
+
const last = await this.db
|
|
405
453
|
.selectFrom("conversation_events")
|
|
406
454
|
.select(sql `max(seq)`.as("seq"))
|
|
407
455
|
.where("conversation_id", "=", conversationId)
|
|
408
456
|
.executeTakeFirst();
|
|
409
457
|
if (last?.seq != null)
|
|
410
|
-
await this.
|
|
458
|
+
await this.eventLog.notify(conversationId, Number(last.seq));
|
|
411
459
|
}
|
|
412
460
|
return r;
|
|
413
461
|
}
|
|
462
|
+
async cancelWaitsOfFinishedIn(conversationId, runId) {
|
|
463
|
+
const t = this.db;
|
|
464
|
+
await t
|
|
465
|
+
.selectFrom("conversations")
|
|
466
|
+
.select("id")
|
|
467
|
+
.where("id", "=", conversationId)
|
|
468
|
+
.forUpdate()
|
|
469
|
+
.executeTakeFirst();
|
|
470
|
+
const run = await t
|
|
471
|
+
.selectFrom("runs")
|
|
472
|
+
.select("status")
|
|
473
|
+
.where("id", "=", runId)
|
|
474
|
+
.forUpdate()
|
|
475
|
+
.executeTakeFirst();
|
|
476
|
+
if (!run || !TERMINAL_RUN_STATUSES.includes(run.status))
|
|
477
|
+
return 0;
|
|
478
|
+
const a = await this.approvals.cancelPendingIn(runId);
|
|
479
|
+
const q = await this.questions.cancelPendingIn(runId);
|
|
480
|
+
return a.length + q.length;
|
|
481
|
+
}
|
|
414
482
|
/** 扫描 1:`expires_at < now()` 仍 pending 的审批 / 输入请求 → 与超时任务同一路径(置 expired、写事件、续跑)。 */
|
|
415
483
|
async sweepOverdue() {
|
|
416
|
-
const
|
|
484
|
+
const db = this.db;
|
|
417
485
|
const approvals = await db
|
|
418
486
|
.selectFrom("approvals")
|
|
419
487
|
.select(["id", "run_id"])
|
|
@@ -438,12 +506,12 @@ export class Waits {
|
|
|
438
506
|
for (const w of due) {
|
|
439
507
|
try {
|
|
440
508
|
const r = w.kind === "approval"
|
|
441
|
-
? await this.
|
|
442
|
-
: await this.
|
|
509
|
+
? await this.approvals.expire(w.id)
|
|
510
|
+
: await this.questions.expire(w.id);
|
|
443
511
|
if (r.outcome !== "expired")
|
|
444
512
|
continue;
|
|
445
513
|
total++;
|
|
446
|
-
this.
|
|
514
|
+
this.log.warn("wait sweep: expired overdue wait", {
|
|
447
515
|
kind: w.kind,
|
|
448
516
|
id: w.id,
|
|
449
517
|
runId: w.runId,
|
|
@@ -452,7 +520,7 @@ export class Waits {
|
|
|
452
520
|
await this.resume(r.record.runId, w.id);
|
|
453
521
|
}
|
|
454
522
|
catch (err) {
|
|
455
|
-
this.
|
|
523
|
+
this.log.error("wait sweep: cannot expire overdue wait", { kind: w.kind, id: w.id, err });
|
|
456
524
|
}
|
|
457
525
|
}
|
|
458
526
|
return total + (await this.sweepOverdueSubagents());
|
|
@@ -465,9 +533,7 @@ export class Waits {
|
|
|
465
533
|
* stopped; a pass that neither stopped a child nor resumed the run is not counted.
|
|
466
534
|
*/
|
|
467
535
|
async sweepOverdueSubagents() {
|
|
468
|
-
|
|
469
|
-
return 0;
|
|
470
|
-
const runs = await this.d.db
|
|
536
|
+
const runs = await this.db
|
|
471
537
|
.selectFrom("runs")
|
|
472
538
|
.select(["id"])
|
|
473
539
|
.where("status", "=", "waiting")
|
|
@@ -478,7 +544,7 @@ export class Waits {
|
|
|
478
544
|
let total = 0;
|
|
479
545
|
for (const r of runs) {
|
|
480
546
|
try {
|
|
481
|
-
const last = await this.
|
|
547
|
+
const last = await this.db
|
|
482
548
|
.selectFrom("subagent_dispatches")
|
|
483
549
|
.select(sql `max(step)`.as("step"))
|
|
484
550
|
.where("parent_run_id", "=", r.id)
|
|
@@ -492,11 +558,11 @@ export class Waits {
|
|
|
492
558
|
const { acted } = await this.expire("subagents", id, { runId: r.id, step });
|
|
493
559
|
if (!acted)
|
|
494
560
|
continue;
|
|
495
|
-
this.
|
|
561
|
+
this.log.warn("wait sweep: expired overdue wait", { kind: "subagents", id, runId: r.id });
|
|
496
562
|
total++;
|
|
497
563
|
}
|
|
498
564
|
catch (err) {
|
|
499
|
-
this.
|
|
565
|
+
this.log.error("wait sweep: cannot expire overdue wait", {
|
|
500
566
|
kind: "subagents",
|
|
501
567
|
runId: r.id,
|
|
502
568
|
err,
|
|
@@ -515,10 +581,7 @@ export class Waits {
|
|
|
515
581
|
*/
|
|
516
582
|
async sweepSubagentOrphans() {
|
|
517
583
|
const out = { requeued: 0, orphaned: 0 };
|
|
518
|
-
const
|
|
519
|
-
if (!sub)
|
|
520
|
-
return out;
|
|
521
|
-
const runs = await this.d.db
|
|
584
|
+
const runs = await this.db
|
|
522
585
|
.selectFrom("runs")
|
|
523
586
|
.innerJoin("conversations as c", "c.id", "runs.conversation_id")
|
|
524
587
|
.select(["runs.id", "runs.conversation_id"])
|
|
@@ -538,23 +601,23 @@ export class Waits {
|
|
|
538
601
|
.execute();
|
|
539
602
|
for (const run of runs) {
|
|
540
603
|
try {
|
|
541
|
-
const r = await this.
|
|
604
|
+
const r = await this.runQueue.repairOrphan(run.conversation_id, run.id);
|
|
542
605
|
if (r === null)
|
|
543
606
|
continue;
|
|
544
607
|
if (r === "failed") {
|
|
545
608
|
out.orphaned++;
|
|
546
|
-
await
|
|
609
|
+
await this.childFinished(run.id);
|
|
547
610
|
}
|
|
548
611
|
else
|
|
549
612
|
out.requeued++;
|
|
550
|
-
this.
|
|
613
|
+
this.log.warn("wait sweep: repaired orphaned sub-agent run", {
|
|
551
614
|
runId: run.id,
|
|
552
615
|
conversationId: run.conversation_id,
|
|
553
616
|
outcome: r,
|
|
554
617
|
});
|
|
555
618
|
}
|
|
556
619
|
catch (err) {
|
|
557
|
-
this.
|
|
620
|
+
this.log.error("wait sweep: cannot repair orphaned sub-agent run", {
|
|
558
621
|
runId: run.id,
|
|
559
622
|
err,
|
|
560
623
|
});
|
|
@@ -572,10 +635,7 @@ export class Waits {
|
|
|
572
635
|
* are then stopped by {@link sweepChildrenOfFinished}.
|
|
573
636
|
*/
|
|
574
637
|
async sweepOpenAgentCalls() {
|
|
575
|
-
const
|
|
576
|
-
if (!stopOpenCalls)
|
|
577
|
-
return 0;
|
|
578
|
-
const agentCalls = await this.d.db
|
|
638
|
+
const agentCalls = await this.db
|
|
579
639
|
.selectFrom("subagent_dispatches as sd")
|
|
580
640
|
.innerJoin("runs as pr", "pr.id", "sd.parent_run_id")
|
|
581
641
|
.select(["sd.parent_run_id", "sd.parent_conversation_id"])
|
|
@@ -591,48 +651,27 @@ export class Waits {
|
|
|
591
651
|
.where(sql `NOT (sd.step = 0 AND sd.parent_call_id LIKE 'skill-%')`)
|
|
592
652
|
.limit(WAIT_SWEEP_BATCH)
|
|
593
653
|
.execute();
|
|
594
|
-
const forkRuns = await unreportedForkRuns(this.
|
|
654
|
+
const forkRuns = await unreportedForkRuns(this.db);
|
|
595
655
|
const runs = [...agentCalls, ...forkRuns].filter((r, i, all) => all.findIndex((x) => x.parent_run_id === r.parent_run_id) === i);
|
|
596
656
|
let total = 0;
|
|
597
657
|
for (const r of runs) {
|
|
598
658
|
try {
|
|
599
|
-
|
|
600
|
-
const toSeq = await this.
|
|
601
|
-
|
|
602
|
-
await t
|
|
603
|
-
.selectFrom("conversations")
|
|
604
|
-
.select("id")
|
|
605
|
-
.where("id", "=", r.parent_conversation_id)
|
|
606
|
-
.forUpdate()
|
|
607
|
-
.executeTakeFirst();
|
|
608
|
-
const run = await t
|
|
609
|
-
.selectFrom("runs")
|
|
610
|
-
.select("status")
|
|
611
|
-
.where("id", "=", r.parent_run_id)
|
|
612
|
-
.executeTakeFirst();
|
|
613
|
-
if (run === undefined ||
|
|
614
|
-
!TERMINAL_RUN_STATUSES.includes(run.status)) {
|
|
615
|
-
return null;
|
|
616
|
-
}
|
|
617
|
-
const stopped = await stopOpenCalls(t, r.parent_run_id);
|
|
618
|
-
if (stopped.callIds.size === 0)
|
|
619
|
-
return null;
|
|
620
|
-
fire = stopped.fire;
|
|
621
|
-
return stopped.toSeq ?? null;
|
|
622
|
-
});
|
|
659
|
+
const st = {};
|
|
660
|
+
const toSeq = await this.repairOpenAgentCallsIn(r.parent_conversation_id, r.parent_run_id, st);
|
|
661
|
+
const fire = st.fire;
|
|
623
662
|
if (fire === undefined)
|
|
624
663
|
continue;
|
|
625
664
|
if (toSeq !== null)
|
|
626
|
-
await this.
|
|
665
|
+
await this.eventLog.notify(r.parent_conversation_id, toSeq);
|
|
627
666
|
fire();
|
|
628
667
|
total++;
|
|
629
|
-
this.
|
|
668
|
+
this.log.warn("wait sweep: wrote missing agent results of a finished run", {
|
|
630
669
|
runId: r.parent_run_id,
|
|
631
670
|
conversationId: r.parent_conversation_id,
|
|
632
671
|
});
|
|
633
672
|
}
|
|
634
673
|
catch (err) {
|
|
635
|
-
this.
|
|
674
|
+
this.log.error("wait sweep: cannot write missing agent results of a finished run", {
|
|
636
675
|
runId: r.parent_run_id,
|
|
637
676
|
err,
|
|
638
677
|
});
|
|
@@ -640,15 +679,35 @@ export class Waits {
|
|
|
640
679
|
}
|
|
641
680
|
return total;
|
|
642
681
|
}
|
|
682
|
+
/** One run's repair of {@link sweepOpenAgentCalls}; its observe hooks go back through `st`. */
|
|
683
|
+
async repairOpenAgentCallsIn(conversationId, runId, st) {
|
|
684
|
+
const t = this.db;
|
|
685
|
+
await t
|
|
686
|
+
.selectFrom("conversations")
|
|
687
|
+
.select("id")
|
|
688
|
+
.where("id", "=", conversationId)
|
|
689
|
+
.forUpdate()
|
|
690
|
+
.executeTakeFirst();
|
|
691
|
+
const run = await t
|
|
692
|
+
.selectFrom("runs")
|
|
693
|
+
.select("status")
|
|
694
|
+
.where("id", "=", runId)
|
|
695
|
+
.executeTakeFirst();
|
|
696
|
+
if (run === undefined || !TERMINAL_RUN_STATUSES.includes(run.status)) {
|
|
697
|
+
return null;
|
|
698
|
+
}
|
|
699
|
+
const stopped = await this.pipeline.stopOpenAgentCalls(runId);
|
|
700
|
+
if (stopped.callIds.size === 0)
|
|
701
|
+
return null;
|
|
702
|
+
st.fire = stopped.fire;
|
|
703
|
+
return stopped.toSeq ?? null;
|
|
704
|
+
}
|
|
643
705
|
/**
|
|
644
706
|
* Active sub-agent runs of a parent run that finished more than the grace period ago (spec §7.5,
|
|
645
707
|
* §12: a parent's terminal state stops its children; this is the backstop) → stopped.
|
|
646
708
|
*/
|
|
647
709
|
async sweepChildrenOfFinished() {
|
|
648
|
-
const
|
|
649
|
-
if (!sub)
|
|
650
|
-
return 0;
|
|
651
|
-
const parents = await this.d.db
|
|
710
|
+
const parents = await this.db
|
|
652
711
|
.selectFrom("subagent_dispatches as sd")
|
|
653
712
|
.innerJoin("runs as cr", "cr.id", "sd.child_run_id")
|
|
654
713
|
.innerJoin("runs as pr", "pr.id", "sd.parent_run_id")
|
|
@@ -662,17 +721,17 @@ export class Waits {
|
|
|
662
721
|
let total = 0;
|
|
663
722
|
for (const p of parents) {
|
|
664
723
|
try {
|
|
665
|
-
const n = await
|
|
724
|
+
const n = await this.stopChildren(p.parent_run_id, null);
|
|
666
725
|
if (n === 0)
|
|
667
726
|
continue;
|
|
668
727
|
total += n;
|
|
669
|
-
this.
|
|
728
|
+
this.log.warn("wait sweep: stopped sub-agents of a finished run", {
|
|
670
729
|
runId: p.parent_run_id,
|
|
671
730
|
count: n,
|
|
672
731
|
});
|
|
673
732
|
}
|
|
674
733
|
catch (err) {
|
|
675
|
-
this.
|
|
734
|
+
this.log.error("wait sweep: cannot stop sub-agents of a finished run", {
|
|
676
735
|
runId: p.parent_run_id,
|
|
677
736
|
err,
|
|
678
737
|
});
|
|
@@ -686,7 +745,7 @@ export class Waits {
|
|
|
686
745
|
* (与人工决定 / 超时任务一致,已投递过的同一续跑被 BullMQ 去重)。
|
|
687
746
|
*/
|
|
688
747
|
async sweepStuckRuns() {
|
|
689
|
-
const runs = await this.
|
|
748
|
+
const runs = await this.db
|
|
690
749
|
.selectFrom("runs")
|
|
691
750
|
.select(["id", "conversation_id"])
|
|
692
751
|
.where("status", "=", "waiting")
|
|
@@ -714,14 +773,14 @@ export class Waits {
|
|
|
714
773
|
if (!(await this.resume(run.id, waitId)))
|
|
715
774
|
continue;
|
|
716
775
|
total++;
|
|
717
|
-
this.
|
|
776
|
+
this.log.warn("wait sweep: resumed stuck waiting run", {
|
|
718
777
|
runId: run.id,
|
|
719
778
|
conversationId: run.conversation_id,
|
|
720
779
|
waitId,
|
|
721
780
|
});
|
|
722
781
|
}
|
|
723
782
|
catch (err) {
|
|
724
|
-
this.
|
|
783
|
+
this.log.error("wait sweep: cannot resume stuck waiting run", { runId: run.id, err });
|
|
725
784
|
}
|
|
726
785
|
}
|
|
727
786
|
return total;
|
|
@@ -732,16 +791,16 @@ export class Waits {
|
|
|
732
791
|
* with, so a sweep resume and a late finisher resume share one job id).
|
|
733
792
|
*/
|
|
734
793
|
async lastWaitId(runId) {
|
|
735
|
-
const row = await this.
|
|
736
|
-
.selectFrom(this.
|
|
794
|
+
const row = await this.db
|
|
795
|
+
.selectFrom(this.db
|
|
737
796
|
.selectFrom("approvals")
|
|
738
797
|
.select(["id", "created_at"])
|
|
739
798
|
.where("run_id", "=", runId)
|
|
740
|
-
.unionAll(this.
|
|
799
|
+
.unionAll(this.db
|
|
741
800
|
.selectFrom("questions")
|
|
742
801
|
.select(["id", "created_at"])
|
|
743
802
|
.where("run_id", "=", runId))
|
|
744
|
-
.unionAll(this.
|
|
803
|
+
.unionAll(this.db
|
|
745
804
|
.selectFrom("subagent_dispatches")
|
|
746
805
|
.select(["child_run_id as id", "created_at"])
|
|
747
806
|
.where("parent_run_id", "=", runId))
|
|
@@ -752,7 +811,11 @@ export class Waits {
|
|
|
752
811
|
.executeTakeFirst();
|
|
753
812
|
return row?.id ?? null;
|
|
754
813
|
}
|
|
755
|
-
|
|
814
|
+
/**
|
|
815
|
+
* A `wait-timeout` job (dispatched by `MaintenanceProcessor`): expires the wait,
|
|
816
|
+
* or delays the job again until the wait's expiry when it ran early.
|
|
817
|
+
*/
|
|
818
|
+
async processTimeout(job, token) {
|
|
756
819
|
const { kind, id, runId, step } = job.data;
|
|
757
820
|
const at = runId !== undefined && step !== undefined ? { runId, step } : undefined;
|
|
758
821
|
const r = await this.expire(kind, id, at);
|
|
@@ -767,7 +830,7 @@ export class Waits {
|
|
|
767
830
|
? { kind: w.kind, id: w.id, runId, step: w.step }
|
|
768
831
|
: { kind: w.kind, id: w.id };
|
|
769
832
|
try {
|
|
770
|
-
await this.
|
|
833
|
+
await this.timeouts.add(WAIT_TIMEOUT_JOB, data, {
|
|
771
834
|
jobId: waitTimeoutJobId(w.id),
|
|
772
835
|
delay: Math.max(0, new Date(w.expiresAt).getTime() - Date.now()),
|
|
773
836
|
attempts: TIMEOUT_JOB_ATTEMPTS,
|
|
@@ -777,7 +840,7 @@ export class Waits {
|
|
|
777
840
|
});
|
|
778
841
|
}
|
|
779
842
|
catch (err) {
|
|
780
|
-
this.
|
|
843
|
+
this.log.error("cannot schedule wait timeout", { waitId: w.id, err });
|
|
781
844
|
}
|
|
782
845
|
}
|
|
783
846
|
/**
|
|
@@ -786,7 +849,7 @@ export class Waits {
|
|
|
786
849
|
*/
|
|
787
850
|
async isSettled(w, runId) {
|
|
788
851
|
if (w.kind === "subagents") {
|
|
789
|
-
const active = await this.
|
|
852
|
+
const active = await this.db
|
|
790
853
|
.selectFrom("subagent_dispatches as sd")
|
|
791
854
|
.innerJoin("runs as cr", "cr.id", "sd.child_run_id")
|
|
792
855
|
.select("cr.id")
|
|
@@ -796,12 +859,12 @@ export class Waits {
|
|
|
796
859
|
return active === undefined;
|
|
797
860
|
}
|
|
798
861
|
const row = w.kind === "approval"
|
|
799
|
-
? await this.
|
|
862
|
+
? await this.db
|
|
800
863
|
.selectFrom("approvals")
|
|
801
864
|
.select("status")
|
|
802
865
|
.where("id", "=", w.id)
|
|
803
866
|
.executeTakeFirst()
|
|
804
|
-
: await this.
|
|
867
|
+
: await this.db
|
|
805
868
|
.selectFrom("questions")
|
|
806
869
|
.select("status")
|
|
807
870
|
.where("id", "=", w.id)
|
|
@@ -855,7 +918,111 @@ export class Waits {
|
|
|
855
918
|
}
|
|
856
919
|
return out;
|
|
857
920
|
}
|
|
858
|
-
|
|
921
|
+
/**
|
|
922
|
+
* After a child run's terminal state committed (sub-agents spec §7.3): appends
|
|
923
|
+
* `subagent_finished` to the parent log (idempotent; allowed while the parent waits, it is not
|
|
924
|
+
* model-visible) and tries {@link resume}`(parentRunId, childRunId)`. Every finishing child tries;
|
|
925
|
+
* the conditional resume lets exactly one succeed, the last to see all its siblings terminal. A
|
|
926
|
+
* run that is not a dispatched child, or not terminal yet, is left alone. A crash in between is
|
|
927
|
+
* repaired by the wait sweep and by the parent's tools node, which writes a missing
|
|
928
|
+
* `subagent_finished` itself.
|
|
929
|
+
*/
|
|
930
|
+
async childFinished(childRunId) {
|
|
931
|
+
const row = await dispatchOfChildRun(this.db, childRunId);
|
|
932
|
+
if (!row)
|
|
933
|
+
return;
|
|
934
|
+
const run = await this.db
|
|
935
|
+
.selectFrom("runs")
|
|
936
|
+
.select("status")
|
|
937
|
+
.where("id", "=", childRunId)
|
|
938
|
+
.executeTakeFirst();
|
|
939
|
+
if (!run || !TERMINAL_STATUSES.has(run.status))
|
|
940
|
+
return;
|
|
941
|
+
const r = await childResult(this.eventLog, row);
|
|
942
|
+
if (!r) {
|
|
943
|
+
this.log.warn("sub-agent run is terminal without a terminal event", { childRunId });
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
await this.eventLog.append(row.parentConversationId, [finishedEvent(row, r.finished)]);
|
|
947
|
+
await this.resume(row.parentRunId, childRunId);
|
|
948
|
+
}
|
|
949
|
+
/**
|
|
950
|
+
* Stops the active children of a parent run (sub-agents spec §12), or only those dispatched in
|
|
951
|
+
* `opts.step`: a `waiting` child through its own {@link abortWaiting}, a `queued` / `running` one
|
|
952
|
+
* that no worker holds directly (`RunQueue.abortIfOrphaned`), any other through
|
|
953
|
+
* `RunAbort.request` (the cross-replica broadcast plus the marker key, so a child that starts
|
|
954
|
+
* later still sees it), after which a child found `waiting` is stopped through `abortWaiting`
|
|
955
|
+
* too. A child stopped here is reported to the parent at once (by `abortWaiting` itself, or
|
|
956
|
+
* {@link childFinished} after `abortIfOrphaned`); one stopped by its worker is reported by that
|
|
957
|
+
* worker. Returns the number of children asked to stop.
|
|
958
|
+
*
|
|
959
|
+
* `byAccountId` is the person whose action stops them, or null when the kernel stops them on the
|
|
960
|
+
* parent's behalf; a child stopped with null reports the §4.4 "parent's stop" text.
|
|
961
|
+
*/
|
|
962
|
+
async stopChildren(parentRunId, byAccountId, opts = {}) {
|
|
963
|
+
let q = this.db
|
|
964
|
+
.selectFrom("subagent_dispatches as sd")
|
|
965
|
+
.innerJoin("runs as cr", "cr.id", "sd.child_run_id")
|
|
966
|
+
.select(["sd.child_conversation_id", "sd.child_run_id", "cr.status"])
|
|
967
|
+
.where("sd.parent_run_id", "=", parentRunId)
|
|
968
|
+
.where("cr.status", "in", ACTIVE_RUN_STATUSES);
|
|
969
|
+
if (opts.step !== undefined)
|
|
970
|
+
q = q.where("sd.step", "=", opts.step);
|
|
971
|
+
const children = await q.execute();
|
|
972
|
+
for (const c of children) {
|
|
973
|
+
const conv = c.child_conversation_id;
|
|
974
|
+
const runId = c.child_run_id;
|
|
975
|
+
// abortWaiting reports the stopped child to the parent itself (childFinished)
|
|
976
|
+
if (c.status === "waiting" &&
|
|
977
|
+
(await this.abortWaiting(conv, runId, byAccountId, opts.detail))) {
|
|
978
|
+
continue;
|
|
979
|
+
}
|
|
980
|
+
if (await this.runQueue.abortIfOrphaned(conv, runId, byAccountId, opts.detail)) {
|
|
981
|
+
await this.childFinished(runId);
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
await this.abort.request(runId, byAccountId, opts.detail);
|
|
985
|
+
// the suspend handshake (see suspend): a child that became `waiting` after the read above
|
|
986
|
+
// may have checked the marker before it was set, so check `waiting` again after setting it
|
|
987
|
+
// (review M1)
|
|
988
|
+
const now = await this.db
|
|
989
|
+
.selectFrom("runs")
|
|
990
|
+
.select("status")
|
|
991
|
+
.where("id", "=", runId)
|
|
992
|
+
.executeTakeFirst();
|
|
993
|
+
if (now?.status === "waiting") {
|
|
994
|
+
await this.abortWaiting(conv, runId, byAccountId, opts.detail);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
return children.length;
|
|
998
|
+
}
|
|
999
|
+
};
|
|
1000
|
+
__decorate([
|
|
1001
|
+
Transactional({ propagation: "requires_new" })
|
|
1002
|
+
], Waits.prototype, "abortWaitingIn", null);
|
|
1003
|
+
__decorate([
|
|
1004
|
+
Transactional({ propagation: "requires_new" })
|
|
1005
|
+
], Waits.prototype, "cancelWaitsOfFinishedIn", null);
|
|
1006
|
+
__decorate([
|
|
1007
|
+
Transactional({ propagation: "requires_new" })
|
|
1008
|
+
], Waits.prototype, "repairOpenAgentCallsIn", null);
|
|
1009
|
+
Waits = __decorate([
|
|
1010
|
+
Injectable(),
|
|
1011
|
+
__param(0, Inject(KernelDb)),
|
|
1012
|
+
__param(1, Inject(EventLog)),
|
|
1013
|
+
__param(2, Inject(ApprovalsService)),
|
|
1014
|
+
__param(3, Inject(QuestionsService)),
|
|
1015
|
+
__param(4, Inject(RunQueue)),
|
|
1016
|
+
__param(5, Inject(ToolPipeline)),
|
|
1017
|
+
__param(6, Inject(RunFinish)),
|
|
1018
|
+
__param(7, Inject(KyselyCheckpointSaver)),
|
|
1019
|
+
__param(8, Inject(RunAbort)),
|
|
1020
|
+
__param(9, Inject(getQueueToken(MAINTENANCE_QUEUE_NAME))),
|
|
1021
|
+
__param(10, Inject(KernelEvents)),
|
|
1022
|
+
__param(11, Inject(KERNEL_LOGGER)),
|
|
1023
|
+
__param(12, Inject(TransactionHost))
|
|
1024
|
+
], Waits);
|
|
1025
|
+
export { Waits };
|
|
859
1026
|
/**
|
|
860
1027
|
* Phase D: finished chat runs (past the grace period, within the last day) triggered by a fork
|
|
861
1028
|
* invocation that has no report (dispatched or not); the wait sweep writes it
|
|
@@ -881,3 +1048,59 @@ export function unreportedForkRuns(db) {
|
|
|
881
1048
|
.limit(WAIT_SWEEP_BATCH)
|
|
882
1049
|
.execute());
|
|
883
1050
|
}
|
|
1051
|
+
/**
|
|
1052
|
+
* A decided approval / answered question resumes the waiting run on this replica (domain events,
|
|
1053
|
+
* spec §3b; the wait sweep resumes a run whose resume was lost). Its IM delivery follows the same
|
|
1054
|
+
* events (`ChannelJobs`).
|
|
1055
|
+
*/
|
|
1056
|
+
let DecisionResumer = class DecisionResumer {
|
|
1057
|
+
unsubscribe;
|
|
1058
|
+
constructor(waits, events) {
|
|
1059
|
+
this.unsubscribe = [
|
|
1060
|
+
events.on("approval.decided", async (a) => {
|
|
1061
|
+
await waits.resume(a.runId, a.id);
|
|
1062
|
+
}),
|
|
1063
|
+
events.on("question.answered", async (q) => {
|
|
1064
|
+
await waits.resume(q.runId, q.id);
|
|
1065
|
+
}),
|
|
1066
|
+
];
|
|
1067
|
+
}
|
|
1068
|
+
/** Unsubscribes after the stop phases: events emitted while they drain are still handled. */
|
|
1069
|
+
onApplicationShutdown() {
|
|
1070
|
+
for (const off of this.unsubscribe)
|
|
1071
|
+
off();
|
|
1072
|
+
}
|
|
1073
|
+
};
|
|
1074
|
+
DecisionResumer = __decorate([
|
|
1075
|
+
Injectable(),
|
|
1076
|
+
__param(0, Inject(Waits)),
|
|
1077
|
+
__param(1, Inject(KernelEvents))
|
|
1078
|
+
], DecisionResumer);
|
|
1079
|
+
export { DecisionResumer };
|
|
1080
|
+
/**
|
|
1081
|
+
* The wait sweep, every 10 minutes, once across replicas: {@link Waits.sweep}. Replaces
|
|
1082
|
+
* the maintenance scheduler `wait-sweep-every-10m` (retired at worker start).
|
|
1083
|
+
*/
|
|
1084
|
+
let WaitSweepJob = class WaitSweepJob {
|
|
1085
|
+
waits;
|
|
1086
|
+
lockService;
|
|
1087
|
+
log;
|
|
1088
|
+
constructor(waits, lockService, log) {
|
|
1089
|
+
this.waits = waits;
|
|
1090
|
+
this.lockService = lockService;
|
|
1091
|
+
this.log = log;
|
|
1092
|
+
}
|
|
1093
|
+
async run() {
|
|
1094
|
+
await this.waits.sweep();
|
|
1095
|
+
}
|
|
1096
|
+
};
|
|
1097
|
+
__decorate([
|
|
1098
|
+
LockedCron("*/10 * * * *", { name: WAIT_SWEEP_JOB })
|
|
1099
|
+
], WaitSweepJob.prototype, "run", null);
|
|
1100
|
+
WaitSweepJob = __decorate([
|
|
1101
|
+
Injectable(),
|
|
1102
|
+
__param(0, Inject(Waits)),
|
|
1103
|
+
__param(1, Inject(LockService)),
|
|
1104
|
+
__param(2, Inject(KERNEL_LOGGER))
|
|
1105
|
+
], WaitSweepJob);
|
|
1106
|
+
export { WaitSweepJob };
|