@capybara-hq/kernel 0.1.0-rc.0 → 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/bootstrap.json +10 -6
- 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 -193
- 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 +16 -1
- package/dist/config/schema.js +54 -7
- 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 -62
- 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/queue.js +3 -2
- 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 +2 -0
- package/dist/errors.js +2 -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 -120
- 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 +96 -42
- package/dist/extensions/bootstrap.js +303 -155
- 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 +52 -47
- 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 +19 -12
- package/dist/index.js +13 -8
- 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 -241
- 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-config.d.ts +9 -0
- package/dist/log-config.js +27 -0
- package/dist/log-context.d.ts +34 -0
- package/dist/log-context.js +44 -0
- package/dist/log-loki.d.ts +34 -0
- package/dist/log-loki.js +145 -0
- package/dist/log.d.ts +41 -10
- package/dist/log.js +91 -17
- 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/net/public-address.js +3 -2
- 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 -136
- 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 -225
- 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 -99
- 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 +7 -4
- package/dist/tools/builtins/sandbox/common.js +5 -3
- 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 +11 -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
|
@@ -1,11 +1,27 @@
|
|
|
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
|
+
};
|
|
1
10
|
import { randomUUID } from "node:crypto";
|
|
2
11
|
import { parseSkillMd, SKILL_ENTRY_FILE, ToolError } from "@capybara-hq/plugin-sdk";
|
|
12
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
3
13
|
import { sql } from "kysely";
|
|
4
|
-
import { visibleTo } from "../agents/
|
|
14
|
+
import { visibleTo } from "../agents/agent-lookup.js";
|
|
5
15
|
import { skillFilesPrefix } from "../conversations/attachments.service.js";
|
|
16
|
+
import { EventLog } from "../conversations/event-log.js";
|
|
6
17
|
import { ApiError } from "../errors.js";
|
|
7
18
|
import { audit } from "../identity/audit.js";
|
|
19
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
20
|
+
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
21
|
+
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
22
|
+
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
8
23
|
import { sameSnapshot, } from "../runtime/context/skills.js";
|
|
24
|
+
import { StorageService } from "../storage/storage.service.js";
|
|
9
25
|
import { fitPinned, invocationOf, lockLatestCatalog } from "./catalog.js";
|
|
10
26
|
/**
|
|
11
27
|
* 每个 agent 自己的技能(`scope = agent`)上限,含待批准的新技能。远低于目录快照的上限(`SKILLS_CATALOG_MAX`),
|
|
@@ -50,18 +66,25 @@ function writtenBody(pkg) {
|
|
|
50
66
|
* 别的对话再写被拒绝(英文说明)。
|
|
51
67
|
* 状态都在 PG(agent 行锁串行化同一 agent 的写与决定),文件在对象存储 `kernel/<orgId>/skills/<id>/`;无进程内状态。
|
|
52
68
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
let SkillChangesService = class SkillChangesService {
|
|
70
|
+
db;
|
|
71
|
+
storage;
|
|
72
|
+
eventLog;
|
|
73
|
+
log;
|
|
74
|
+
txHost;
|
|
75
|
+
constructor(db, storage, eventLog, log, txHost) {
|
|
76
|
+
this.db = db;
|
|
77
|
+
this.storage = storage;
|
|
78
|
+
this.eventLog = eventLog;
|
|
79
|
+
this.log = log;
|
|
80
|
+
this.txHost = txHost;
|
|
57
81
|
}
|
|
58
82
|
/** 写技能(见类注释)。模型可见的失败抛 `ToolError`。 */
|
|
59
83
|
async write(ctx, pkg) {
|
|
60
|
-
const { db, eventLog } = this.d;
|
|
61
84
|
let store;
|
|
62
85
|
try {
|
|
63
|
-
this.
|
|
64
|
-
store = this.
|
|
86
|
+
this.storage.assertAvailable();
|
|
87
|
+
store = this.storage.kernel(ctx.orgId);
|
|
65
88
|
}
|
|
66
89
|
catch (e) {
|
|
67
90
|
throw storageError(e);
|
|
@@ -77,175 +100,15 @@ export class SkillChangesService {
|
|
|
77
100
|
}
|
|
78
101
|
let committed;
|
|
79
102
|
try {
|
|
80
|
-
committed = await
|
|
81
|
-
await keyShareOrg(t, ctx.orgId);
|
|
82
|
-
// NO KEY UPDATE, not UPDATE (here, in decide and in deleteAgentSkill): it still serializes
|
|
83
|
-
// the writes and decisions of one agent, but not the foreign key check (FOR KEY SHARE) of a
|
|
84
|
-
// transaction that already holds the conversation row this one locks last, e.g. an event
|
|
85
|
-
// log append updating that row a second time (the title job): FOR UPDATE made that 40P01
|
|
86
|
-
const agent = await t
|
|
87
|
-
.selectFrom("agents")
|
|
88
|
-
.select(["visibility", "deleted_at"])
|
|
89
|
-
.where("id", "=", ctx.agentId)
|
|
90
|
-
.where("org_id", "=", ctx.orgId)
|
|
91
|
-
.forNoKeyUpdate()
|
|
92
|
-
.executeTakeFirst();
|
|
93
|
-
if (!agent || agent.deleted_at !== null)
|
|
94
|
-
throw new ToolError(AGENT_GONE_TEXT);
|
|
95
|
-
// Then the conversation row (appendCatalog's lock, still after the agent row like decide),
|
|
96
|
-
// before the change request insert: its foreign key check takes FOR KEY SHARE on that row,
|
|
97
|
-
// and upgrading to FOR UPDATE afterwards deadlocked with another writer doing the same
|
|
98
|
-
await t
|
|
99
|
-
.selectFrom("conversations")
|
|
100
|
-
.select("id")
|
|
101
|
-
.where("id", "=", ctx.conversationId)
|
|
102
|
-
.forUpdate()
|
|
103
|
-
.execute();
|
|
104
|
-
const existing = await t
|
|
105
|
-
.selectFrom("skills")
|
|
106
|
-
.select(["id", "current_version"])
|
|
107
|
-
.where("org_id", "=", ctx.orgId)
|
|
108
|
-
.where("scope", "=", "agent")
|
|
109
|
-
.where("agent_id", "=", ctx.agentId)
|
|
110
|
-
.where("name", "=", pkg.name)
|
|
111
|
-
.where("deleted_at", "is", null)
|
|
112
|
-
.forUpdate()
|
|
113
|
-
.executeTakeFirst();
|
|
114
|
-
const pend = await t
|
|
115
|
-
.selectFrom("skill_change_requests")
|
|
116
|
-
.selectAll()
|
|
117
|
-
.where("agent_id", "=", ctx.agentId)
|
|
118
|
-
.where("status", "=", "pending")
|
|
119
|
-
.where(sql `proposed_version -> 'manifest' ->> 'name'`, "=", pkg.name)
|
|
120
|
-
.forUpdate()
|
|
121
|
-
.executeTakeFirst();
|
|
122
|
-
const drop = [];
|
|
123
|
-
if (pend) {
|
|
124
|
-
if (pend.requested_in_conversation !== ctx.conversationId) {
|
|
125
|
-
throw new ToolError(pendingElsewhereText(pkg.name));
|
|
126
|
-
}
|
|
127
|
-
// 同一对话再写:取代旧申请
|
|
128
|
-
await t
|
|
129
|
-
.updateTable("skill_change_requests")
|
|
130
|
-
.set({ status: "cancelled", decided_at: sql `now()` })
|
|
131
|
-
.where("id", "=", pend.id)
|
|
132
|
-
.execute();
|
|
133
|
-
drop.push(pend.object_prefix);
|
|
134
|
-
await audit(t, {
|
|
135
|
-
actorAccountId: ctx.accountId,
|
|
136
|
-
orgId: ctx.orgId,
|
|
137
|
-
action: "skill.change_decided",
|
|
138
|
-
target: pend.id,
|
|
139
|
-
detail: {
|
|
140
|
-
decision: "cancelled",
|
|
141
|
-
reason: "superseded",
|
|
142
|
-
supersededBy: id,
|
|
143
|
-
agentId: ctx.agentId,
|
|
144
|
-
name: pkg.name,
|
|
145
|
-
},
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
if (!existing)
|
|
149
|
-
await this.assertBelowCap(t, ctx.agentId, pend?.id);
|
|
150
|
-
const version = (existing?.current_version ?? 0) + 1;
|
|
151
|
-
const skillId = existing?.id ?? pend?.proposed_version.skillId ?? randomUUID();
|
|
152
|
-
let outcome;
|
|
153
|
-
if (agent.visibility === "private") {
|
|
154
|
-
await this.createVersion(t, {
|
|
155
|
-
orgId: ctx.orgId,
|
|
156
|
-
agentId: ctx.agentId,
|
|
157
|
-
skillId,
|
|
158
|
-
exists: existing !== undefined,
|
|
159
|
-
version,
|
|
160
|
-
manifest: pkg.manifest,
|
|
161
|
-
prefix,
|
|
162
|
-
createdBy: ctx.accountId,
|
|
163
|
-
});
|
|
164
|
-
await audit(t, {
|
|
165
|
-
actorAccountId: ctx.accountId,
|
|
166
|
-
orgId: ctx.orgId,
|
|
167
|
-
action: existing ? "skill.version_created" : "skill.created",
|
|
168
|
-
target: skillId,
|
|
169
|
-
detail: {
|
|
170
|
-
name: pkg.name,
|
|
171
|
-
version,
|
|
172
|
-
files: pkg.manifest.files.length,
|
|
173
|
-
agentId: ctx.agentId,
|
|
174
|
-
conversationId: ctx.conversationId,
|
|
175
|
-
via: "skill_write",
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
outcome = { kind: "version", skillId, version, created: !existing };
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
const proposed = { skillId, version, manifest: pkg.manifest };
|
|
182
|
-
await t
|
|
183
|
-
.insertInto("skill_change_requests")
|
|
184
|
-
.values({
|
|
185
|
-
id,
|
|
186
|
-
org_id: ctx.orgId,
|
|
187
|
-
agent_id: ctx.agentId,
|
|
188
|
-
skill_id: existing?.id ?? null,
|
|
189
|
-
proposed_version: JSON.stringify(proposed),
|
|
190
|
-
object_prefix: prefix,
|
|
191
|
-
requested_by_account: ctx.accountId,
|
|
192
|
-
requested_in_conversation: ctx.conversationId,
|
|
193
|
-
decided_by: null,
|
|
194
|
-
})
|
|
195
|
-
.execute();
|
|
196
|
-
await audit(t, {
|
|
197
|
-
actorAccountId: ctx.accountId,
|
|
198
|
-
orgId: ctx.orgId,
|
|
199
|
-
action: "skill.change_requested",
|
|
200
|
-
target: id,
|
|
201
|
-
detail: {
|
|
202
|
-
agentId: ctx.agentId,
|
|
203
|
-
skillId: existing?.id ?? null,
|
|
204
|
-
name: pkg.name,
|
|
205
|
-
version,
|
|
206
|
-
files: pkg.manifest.files.length,
|
|
207
|
-
conversationId: ctx.conversationId,
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
outcome = { kind: "requested", requestId: id, skillId, version };
|
|
211
|
-
}
|
|
212
|
-
// 本对话立即看到新版本:在上一份快照上替换 / 加入这个技能(确定、来自日志;来源 = 本次的对象前缀)
|
|
213
|
-
// A pinned entry of this skill gets the version, source and body just written (phase B)
|
|
214
|
-
// A manual-only version (phase D) is never in the model's catalog: it removes the skill from
|
|
215
|
-
// the snapshot instead, and appendCatalog drops its pinned entry with it (no longer live)
|
|
216
|
-
const forModel = invocationOf(pkg.manifest).model;
|
|
217
|
-
const pinnedBody = writtenBody(pkg);
|
|
218
|
-
const toSeq = await this.appendCatalog(t, ctx.conversationId, (base) => ({
|
|
219
|
-
...base,
|
|
220
|
-
skills: [
|
|
221
|
-
...base.skills.filter((s) => s.name !== pkg.name),
|
|
222
|
-
...(forModel
|
|
223
|
-
? [
|
|
224
|
-
{
|
|
225
|
-
id: skillId,
|
|
226
|
-
name: pkg.name,
|
|
227
|
-
description: pkg.description,
|
|
228
|
-
version,
|
|
229
|
-
source: prefix,
|
|
230
|
-
},
|
|
231
|
-
]
|
|
232
|
-
: []),
|
|
233
|
-
],
|
|
234
|
-
...(base.pinned && {
|
|
235
|
-
pinned: base.pinned.map((p) => p.id === skillId && pinnedBody !== null
|
|
236
|
-
? { id: skillId, version, name: pkg.name, source: prefix, body: pinnedBody }
|
|
237
|
-
: p),
|
|
238
|
-
}),
|
|
239
|
-
}), `skills_catalog:write:${id}`, ctx.runId);
|
|
240
|
-
return { outcome, drop, toSeq };
|
|
241
|
-
});
|
|
103
|
+
committed = await this.writeIn(ctx, pkg, id, prefix);
|
|
242
104
|
}
|
|
243
105
|
catch (e) {
|
|
244
106
|
await this.deletePrefix(ctx.orgId, prefix);
|
|
245
107
|
throw e;
|
|
246
108
|
}
|
|
247
|
-
if (committed.toSeq !== null)
|
|
248
|
-
await eventLog.notify(ctx.conversationId, committed.toSeq);
|
|
109
|
+
if (committed.toSeq !== null) {
|
|
110
|
+
await this.eventLog.notify(ctx.conversationId, committed.toSeq);
|
|
111
|
+
}
|
|
249
112
|
for (const p of committed.drop)
|
|
250
113
|
await this.deletePrefix(ctx.orgId, p);
|
|
251
114
|
return committed.outcome;
|
|
@@ -257,8 +120,7 @@ export class SkillChangesService {
|
|
|
257
120
|
* 拒绝:提交后删除草稿对象。审计 `skill.change_decided`。
|
|
258
121
|
*/
|
|
259
122
|
async decide(orgId, id, accountId, body, actorTokenId) {
|
|
260
|
-
const
|
|
261
|
-
const head = await db
|
|
123
|
+
const head = await this.db
|
|
262
124
|
.selectFrom("skill_change_requests")
|
|
263
125
|
.select("agent_id")
|
|
264
126
|
.where("id", "=", id)
|
|
@@ -266,95 +128,10 @@ export class SkillChangesService {
|
|
|
266
128
|
.executeTakeFirst();
|
|
267
129
|
if (!head)
|
|
268
130
|
throw notFound();
|
|
269
|
-
const done = await
|
|
270
|
-
// 加锁顺序与 write 一致:组织行(KEY SHARE)→ agent 行 → 申请行 → 会话行
|
|
271
|
-
await keyShareOrg(t, orgId);
|
|
272
|
-
const agent = await t
|
|
273
|
-
.selectFrom("agents")
|
|
274
|
-
.select(["owner_account_id", "deleted_at"])
|
|
275
|
-
.where("id", "=", head.agent_id)
|
|
276
|
-
.forNoKeyUpdate()
|
|
277
|
-
.executeTakeFirst();
|
|
278
|
-
if (!agent || agent.deleted_at !== null)
|
|
279
|
-
throw notFound();
|
|
280
|
-
const req = await t
|
|
281
|
-
.selectFrom("skill_change_requests")
|
|
282
|
-
.selectAll()
|
|
283
|
-
.where("id", "=", id)
|
|
284
|
-
.forUpdate()
|
|
285
|
-
.executeTakeFirst();
|
|
286
|
-
// 首次读与加锁重读之间行被删了(agent / 组织被硬删除)→ 404,不是 500
|
|
287
|
-
if (!req)
|
|
288
|
-
throw notFound();
|
|
289
|
-
if (agent.owner_account_id !== accountId) {
|
|
290
|
-
throw new ApiError("skill_change.not_owner", "Only the agent's owner can decide on its skill changes");
|
|
291
|
-
}
|
|
292
|
-
if (req.status !== "pending") {
|
|
293
|
-
throw new ApiError("skill_change.already_decided", "This skill change has already been decided");
|
|
294
|
-
}
|
|
295
|
-
const p = req.proposed_version;
|
|
296
|
-
const approved = body.decision === "approve";
|
|
297
|
-
let skillId = req.skill_id;
|
|
298
|
-
let version = p.version;
|
|
299
|
-
if (approved) {
|
|
300
|
-
const existing = await t
|
|
301
|
-
.selectFrom("skills")
|
|
302
|
-
.select(["id", "current_version"])
|
|
303
|
-
.where("org_id", "=", orgId)
|
|
304
|
-
.where("scope", "=", "agent")
|
|
305
|
-
.where("agent_id", "=", req.agent_id)
|
|
306
|
-
.where("name", "=", p.manifest.name)
|
|
307
|
-
.where("deleted_at", "is", null)
|
|
308
|
-
.forUpdate()
|
|
309
|
-
.executeTakeFirst();
|
|
310
|
-
skillId = existing?.id ?? p.skillId;
|
|
311
|
-
version = (existing?.current_version ?? 0) + 1;
|
|
312
|
-
await this.createVersion(t, {
|
|
313
|
-
orgId,
|
|
314
|
-
agentId: req.agent_id,
|
|
315
|
-
skillId,
|
|
316
|
-
exists: existing !== undefined,
|
|
317
|
-
version,
|
|
318
|
-
manifest: p.manifest,
|
|
319
|
-
prefix: req.object_prefix,
|
|
320
|
-
createdBy: req.requested_by_account,
|
|
321
|
-
});
|
|
322
|
-
}
|
|
323
|
-
const updated = await t
|
|
324
|
-
.updateTable("skill_change_requests")
|
|
325
|
-
.set({
|
|
326
|
-
status: approved ? "approved" : "rejected",
|
|
327
|
-
decided_by: accountId,
|
|
328
|
-
decided_at: sql `now()`,
|
|
329
|
-
...(approved && { skill_id: skillId }),
|
|
330
|
-
})
|
|
331
|
-
.where("id", "=", id)
|
|
332
|
-
.returningAll()
|
|
333
|
-
.executeTakeFirstOrThrow();
|
|
334
|
-
await audit(t, {
|
|
335
|
-
actorAccountId: accountId,
|
|
336
|
-
...(actorTokenId !== undefined && { actorTokenId }),
|
|
337
|
-
orgId,
|
|
338
|
-
action: "skill.change_decided",
|
|
339
|
-
target: id,
|
|
340
|
-
detail: {
|
|
341
|
-
decision: approved ? "approved" : "rejected",
|
|
342
|
-
agentId: req.agent_id,
|
|
343
|
-
skillId,
|
|
344
|
-
name: p.manifest.name,
|
|
345
|
-
version: approved ? version : p.version,
|
|
346
|
-
requestedBy: req.requested_by_account,
|
|
347
|
-
conversationId: req.requested_in_conversation,
|
|
348
|
-
...(body.note !== undefined && { note: body.note }),
|
|
349
|
-
},
|
|
350
|
-
});
|
|
351
|
-
// 拒绝:发起对话立即回退到正式版本(或移除),模型在当前位置看到提醒
|
|
352
|
-
const revertSeq = approved ? null : await this.revertTrial(t, req);
|
|
353
|
-
return { updated, revertSeq };
|
|
354
|
-
});
|
|
131
|
+
const done = await this.decideIn(orgId, id, accountId, body, actorTokenId, head.agent_id);
|
|
355
132
|
const row = done.updated;
|
|
356
133
|
if (done.revertSeq !== null) {
|
|
357
|
-
await this.
|
|
134
|
+
await this.eventLog.notify(row.requested_in_conversation, done.revertSeq);
|
|
358
135
|
}
|
|
359
136
|
if (row.status === "rejected")
|
|
360
137
|
await this.deletePrefix(orgId, row.object_prefix);
|
|
@@ -369,85 +146,337 @@ export class SkillChangesService {
|
|
|
369
146
|
* 各对话下一次运行开始时目录里去掉它;之后同名可再写为新技能。
|
|
370
147
|
*/
|
|
371
148
|
async deleteAgentSkill(orgId, agentId, skillId, accountId, actorTokenId) {
|
|
372
|
-
const cancelled = await this.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
149
|
+
const cancelled = await this.deleteAgentSkillIn(orgId, agentId, skillId, accountId, actorTokenId);
|
|
150
|
+
await this.finishCancel(orgId, cancelled);
|
|
151
|
+
}
|
|
152
|
+
/** The transaction of {@link write}. */
|
|
153
|
+
async writeIn(ctx, pkg, id, prefix) {
|
|
154
|
+
await this.keyShareOrg(ctx.orgId);
|
|
155
|
+
// NO KEY UPDATE, not UPDATE (here, in decide and in deleteAgentSkill): it still serializes
|
|
156
|
+
// the writes and decisions of one agent, but not the foreign key check (FOR KEY SHARE) of a
|
|
157
|
+
// transaction that already holds the conversation row this one locks last, e.g. an event
|
|
158
|
+
// log append updating that row a second time (the title job): FOR UPDATE made that 40P01
|
|
159
|
+
const agent = await this.db
|
|
160
|
+
.selectFrom("agents")
|
|
161
|
+
.select(["visibility", "deleted_at"])
|
|
162
|
+
.where("id", "=", ctx.agentId)
|
|
163
|
+
.where("org_id", "=", ctx.orgId)
|
|
164
|
+
.forNoKeyUpdate()
|
|
165
|
+
.executeTakeFirst();
|
|
166
|
+
if (!agent || agent.deleted_at !== null)
|
|
167
|
+
throw new ToolError(AGENT_GONE_TEXT);
|
|
168
|
+
// Then the conversation row (appendCatalog's lock, still after the agent row like decide),
|
|
169
|
+
// before the change request insert: its foreign key check takes FOR KEY SHARE on that row,
|
|
170
|
+
// and upgrading to FOR UPDATE afterwards deadlocked with another writer doing the same
|
|
171
|
+
await this.db
|
|
172
|
+
.selectFrom("conversations")
|
|
173
|
+
.select("id")
|
|
174
|
+
.where("id", "=", ctx.conversationId)
|
|
175
|
+
.forUpdate()
|
|
176
|
+
.execute();
|
|
177
|
+
const existing = await this.db
|
|
178
|
+
.selectFrom("skills")
|
|
179
|
+
.select(["id", "current_version"])
|
|
180
|
+
.where("org_id", "=", ctx.orgId)
|
|
181
|
+
.where("scope", "=", "agent")
|
|
182
|
+
.where("agent_id", "=", ctx.agentId)
|
|
183
|
+
.where("name", "=", pkg.name)
|
|
184
|
+
.where("deleted_at", "is", null)
|
|
185
|
+
.forUpdate()
|
|
186
|
+
.executeTakeFirst();
|
|
187
|
+
const pend = await this.db
|
|
188
|
+
.selectFrom("skill_change_requests")
|
|
189
|
+
.selectAll()
|
|
190
|
+
.where("agent_id", "=", ctx.agentId)
|
|
191
|
+
.where("status", "=", "pending")
|
|
192
|
+
.where(sql `proposed_version -> 'manifest' ->> 'name'`, "=", pkg.name)
|
|
193
|
+
.forUpdate()
|
|
194
|
+
.executeTakeFirst();
|
|
195
|
+
const drop = [];
|
|
196
|
+
if (pend) {
|
|
197
|
+
if (pend.requested_in_conversation !== ctx.conversationId) {
|
|
198
|
+
throw new ToolError(pendingElsewhereText(pkg.name));
|
|
395
199
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
.
|
|
399
|
-
.
|
|
200
|
+
// 同一对话再写:取代旧申请
|
|
201
|
+
await this.db
|
|
202
|
+
.updateTable("skill_change_requests")
|
|
203
|
+
.set({ status: "cancelled", decided_at: sql `now()` })
|
|
204
|
+
.where("id", "=", pend.id)
|
|
205
|
+
.execute();
|
|
206
|
+
drop.push(pend.object_prefix);
|
|
207
|
+
await audit(this.db.db, {
|
|
208
|
+
actorAccountId: ctx.accountId,
|
|
209
|
+
orgId: ctx.orgId,
|
|
210
|
+
action: "skill.change_decided",
|
|
211
|
+
target: pend.id,
|
|
212
|
+
detail: {
|
|
213
|
+
decision: "cancelled",
|
|
214
|
+
reason: "superseded",
|
|
215
|
+
supersededBy: id,
|
|
216
|
+
agentId: ctx.agentId,
|
|
217
|
+
name: pkg.name,
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
if (!existing)
|
|
222
|
+
await this.assertBelowCap(ctx.agentId, pend?.id);
|
|
223
|
+
const version = (existing?.current_version ?? 0) + 1;
|
|
224
|
+
const skillId = existing?.id ?? pend?.proposed_version.skillId ?? randomUUID();
|
|
225
|
+
let outcome;
|
|
226
|
+
if (agent.visibility === "private") {
|
|
227
|
+
await this.createVersion({
|
|
228
|
+
orgId: ctx.orgId,
|
|
229
|
+
agentId: ctx.agentId,
|
|
230
|
+
skillId,
|
|
231
|
+
exists: existing !== undefined,
|
|
232
|
+
version,
|
|
233
|
+
manifest: pkg.manifest,
|
|
234
|
+
prefix,
|
|
235
|
+
createdBy: ctx.accountId,
|
|
236
|
+
});
|
|
237
|
+
await audit(this.db.db, {
|
|
238
|
+
actorAccountId: ctx.accountId,
|
|
239
|
+
orgId: ctx.orgId,
|
|
240
|
+
action: existing ? "skill.version_created" : "skill.created",
|
|
241
|
+
target: skillId,
|
|
242
|
+
detail: {
|
|
243
|
+
name: pkg.name,
|
|
244
|
+
version,
|
|
245
|
+
files: pkg.manifest.files.length,
|
|
246
|
+
agentId: ctx.agentId,
|
|
247
|
+
conversationId: ctx.conversationId,
|
|
248
|
+
via: "skill_write",
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
outcome = { kind: "version", skillId, version, created: !existing };
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
const proposed = { skillId, version, manifest: pkg.manifest };
|
|
255
|
+
await this.db
|
|
256
|
+
.insertInto("skill_change_requests")
|
|
257
|
+
.values({
|
|
258
|
+
id,
|
|
259
|
+
org_id: ctx.orgId,
|
|
260
|
+
agent_id: ctx.agentId,
|
|
261
|
+
skill_id: existing?.id ?? null,
|
|
262
|
+
proposed_version: JSON.stringify(proposed),
|
|
263
|
+
object_prefix: prefix,
|
|
264
|
+
requested_by_account: ctx.accountId,
|
|
265
|
+
requested_in_conversation: ctx.conversationId,
|
|
266
|
+
decided_by: null,
|
|
267
|
+
})
|
|
268
|
+
.execute();
|
|
269
|
+
await audit(this.db.db, {
|
|
270
|
+
actorAccountId: ctx.accountId,
|
|
271
|
+
orgId: ctx.orgId,
|
|
272
|
+
action: "skill.change_requested",
|
|
273
|
+
target: id,
|
|
274
|
+
detail: {
|
|
275
|
+
agentId: ctx.agentId,
|
|
276
|
+
skillId: existing?.id ?? null,
|
|
277
|
+
name: pkg.name,
|
|
278
|
+
version,
|
|
279
|
+
files: pkg.manifest.files.length,
|
|
280
|
+
conversationId: ctx.conversationId,
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
outcome = { kind: "requested", requestId: id, skillId, version };
|
|
284
|
+
}
|
|
285
|
+
// 本对话立即看到新版本:在上一份快照上替换 / 加入这个技能(确定、来自日志;来源 = 本次的对象前缀)
|
|
286
|
+
// A pinned entry of this skill gets the version, source and body just written (phase B)
|
|
287
|
+
// A manual-only version (phase D) is never in the model's catalog: it removes the skill from
|
|
288
|
+
// the snapshot instead, and appendCatalog drops its pinned entry with it (no longer live)
|
|
289
|
+
const forModel = invocationOf(pkg.manifest).model;
|
|
290
|
+
const pinnedBody = writtenBody(pkg);
|
|
291
|
+
const toSeq = await this.appendCatalog(ctx.conversationId, (base) => ({
|
|
292
|
+
...base,
|
|
293
|
+
skills: [
|
|
294
|
+
...base.skills.filter((s) => s.name !== pkg.name),
|
|
295
|
+
...(forModel
|
|
296
|
+
? [
|
|
297
|
+
{
|
|
298
|
+
id: skillId,
|
|
299
|
+
name: pkg.name,
|
|
300
|
+
description: pkg.description,
|
|
301
|
+
version,
|
|
302
|
+
source: prefix,
|
|
303
|
+
},
|
|
304
|
+
]
|
|
305
|
+
: []),
|
|
306
|
+
],
|
|
307
|
+
...(base.pinned && {
|
|
308
|
+
pinned: base.pinned.map((p) => p.id === skillId && pinnedBody !== null
|
|
309
|
+
? { id: skillId, version, name: pkg.name, source: prefix, body: pinnedBody }
|
|
310
|
+
: p),
|
|
311
|
+
}),
|
|
312
|
+
}), `skills_catalog:write:${id}`, ctx.runId);
|
|
313
|
+
return { outcome, drop, toSeq };
|
|
314
|
+
}
|
|
315
|
+
/** The transaction of {@link decide}. */
|
|
316
|
+
async decideIn(orgId, id, accountId, body, actorTokenId, agentId) {
|
|
317
|
+
// 加锁顺序与 write 一致:组织行(KEY SHARE)→ agent 行 → 申请行 → 会话行
|
|
318
|
+
await this.keyShareOrg(orgId);
|
|
319
|
+
const agent = await this.db
|
|
320
|
+
.selectFrom("agents")
|
|
321
|
+
.select(["owner_account_id", "deleted_at"])
|
|
322
|
+
.where("id", "=", agentId)
|
|
323
|
+
.forNoKeyUpdate()
|
|
324
|
+
.executeTakeFirst();
|
|
325
|
+
if (!agent || agent.deleted_at !== null)
|
|
326
|
+
throw notFound();
|
|
327
|
+
const req = await this.db
|
|
328
|
+
.selectFrom("skill_change_requests")
|
|
329
|
+
.selectAll()
|
|
330
|
+
.where("id", "=", id)
|
|
331
|
+
.forUpdate()
|
|
332
|
+
.executeTakeFirst();
|
|
333
|
+
// 首次读与加锁重读之间行被删了(agent / 组织被硬删除)→ 404,不是 500
|
|
334
|
+
if (!req)
|
|
335
|
+
throw notFound();
|
|
336
|
+
if (agent.owner_account_id !== accountId) {
|
|
337
|
+
throw new ApiError("skill_change.not_owner", "Only the agent's owner can decide on its skill changes");
|
|
338
|
+
}
|
|
339
|
+
if (req.status !== "pending") {
|
|
340
|
+
throw new ApiError("skill_change.already_decided", "This skill change has already been decided");
|
|
341
|
+
}
|
|
342
|
+
const p = req.proposed_version;
|
|
343
|
+
const approved = body.decision === "approve";
|
|
344
|
+
let skillId = req.skill_id;
|
|
345
|
+
let version = p.version;
|
|
346
|
+
if (approved) {
|
|
347
|
+
const existing = await this.db
|
|
348
|
+
.selectFrom("skills")
|
|
349
|
+
.select(["id", "current_version"])
|
|
400
350
|
.where("org_id", "=", orgId)
|
|
401
351
|
.where("scope", "=", "agent")
|
|
402
|
-
.where("agent_id", "=",
|
|
352
|
+
.where("agent_id", "=", req.agent_id)
|
|
353
|
+
.where("name", "=", p.manifest.name)
|
|
403
354
|
.where("deleted_at", "is", null)
|
|
404
|
-
.returning(["name"])
|
|
405
|
-
.executeTakeFirst();
|
|
406
|
-
if (!r)
|
|
407
|
-
throw new ApiError("skill.not_found", "Skill not found");
|
|
408
|
-
const out = { prefixes: [], seqs: [] };
|
|
409
|
-
const pend = await t
|
|
410
|
-
.selectFrom("skill_change_requests")
|
|
411
|
-
.selectAll()
|
|
412
|
-
.where("agent_id", "=", agentId)
|
|
413
|
-
.where("status", "=", "pending")
|
|
414
|
-
.where(sql `proposed_version -> 'manifest' ->> 'name'`, "=", r.name)
|
|
415
355
|
.forUpdate()
|
|
416
356
|
.executeTakeFirst();
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
357
|
+
skillId = existing?.id ?? p.skillId;
|
|
358
|
+
version = (existing?.current_version ?? 0) + 1;
|
|
359
|
+
await this.createVersion({
|
|
360
|
+
orgId,
|
|
361
|
+
agentId: req.agent_id,
|
|
362
|
+
skillId,
|
|
363
|
+
exists: existing !== undefined,
|
|
364
|
+
version,
|
|
365
|
+
manifest: p.manifest,
|
|
366
|
+
prefix: req.object_prefix,
|
|
367
|
+
createdBy: req.requested_by_account,
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
const updated = await this.db
|
|
371
|
+
.updateTable("skill_change_requests")
|
|
372
|
+
.set({
|
|
373
|
+
status: approved ? "approved" : "rejected",
|
|
374
|
+
decided_by: accountId,
|
|
375
|
+
decided_at: sql `now()`,
|
|
376
|
+
...(approved && { skill_id: skillId }),
|
|
377
|
+
})
|
|
378
|
+
.where("id", "=", id)
|
|
379
|
+
.returningAll()
|
|
380
|
+
.executeTakeFirstOrThrow();
|
|
381
|
+
await audit(this.db.db, {
|
|
382
|
+
actorAccountId: accountId,
|
|
383
|
+
...(actorTokenId !== undefined && { actorTokenId }),
|
|
384
|
+
orgId,
|
|
385
|
+
action: "skill.change_decided",
|
|
386
|
+
target: id,
|
|
387
|
+
detail: {
|
|
388
|
+
decision: approved ? "approved" : "rejected",
|
|
389
|
+
agentId: req.agent_id,
|
|
390
|
+
skillId,
|
|
391
|
+
name: p.manifest.name,
|
|
392
|
+
version: approved ? version : p.version,
|
|
393
|
+
requestedBy: req.requested_by_account,
|
|
394
|
+
conversationId: req.requested_in_conversation,
|
|
395
|
+
...(body.note !== undefined && { note: body.note }),
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
// 拒绝:发起对话立即回退到正式版本(或移除),模型在当前位置看到提醒
|
|
399
|
+
const revertSeq = approved ? null : await this.revertTrial(req);
|
|
400
|
+
return { updated, revertSeq };
|
|
401
|
+
}
|
|
402
|
+
/** The transaction of {@link deleteAgentSkill}. */
|
|
403
|
+
async deleteAgentSkillIn(orgId, agentId, skillId, accountId, actorTokenId) {
|
|
404
|
+
await this.keyShareOrg(orgId);
|
|
405
|
+
const agent = await this.db
|
|
406
|
+
.selectFrom("agents")
|
|
407
|
+
.select(["owner_account_id", "deleted_at"])
|
|
408
|
+
.where("id", "=", agentId)
|
|
409
|
+
.where("org_id", "=", orgId)
|
|
410
|
+
.forNoKeyUpdate()
|
|
411
|
+
.executeTakeFirst();
|
|
412
|
+
const agentNotFound = () => new ApiError("agent.not_found", "Agent not found");
|
|
413
|
+
if (!agent || agent.deleted_at !== null)
|
|
414
|
+
throw agentNotFound();
|
|
415
|
+
if (agent.owner_account_id !== accountId) {
|
|
416
|
+
// 与 AgentsService 一致:看不到的 agent → 404,看得到但不是负责人 → 403
|
|
417
|
+
const visible = await this.db
|
|
418
|
+
.selectFrom("agents")
|
|
419
|
+
.select("id")
|
|
420
|
+
.where("id", "=", agentId)
|
|
421
|
+
.where(visibleTo(accountId))
|
|
422
|
+
.executeTakeFirst();
|
|
423
|
+
if (!visible)
|
|
424
|
+
throw agentNotFound();
|
|
425
|
+
throw new ApiError("forbidden", "Only the agent's owner can delete its skills");
|
|
426
|
+
}
|
|
427
|
+
const r = await this.db
|
|
428
|
+
.updateTable("skills")
|
|
429
|
+
.set({ deleted_at: sql `now()`, updated_at: sql `now()` })
|
|
430
|
+
.where("id", "=", skillId)
|
|
431
|
+
.where("org_id", "=", orgId)
|
|
432
|
+
.where("scope", "=", "agent")
|
|
433
|
+
.where("agent_id", "=", agentId)
|
|
434
|
+
.where("deleted_at", "is", null)
|
|
435
|
+
.returning(["name"])
|
|
436
|
+
.executeTakeFirst();
|
|
437
|
+
if (!r)
|
|
438
|
+
throw new ApiError("skill.not_found", "Skill not found");
|
|
439
|
+
const out = { prefixes: [], seqs: [] };
|
|
440
|
+
const pend = await this.db
|
|
441
|
+
.selectFrom("skill_change_requests")
|
|
442
|
+
.selectAll()
|
|
443
|
+
.where("agent_id", "=", agentId)
|
|
444
|
+
.where("status", "=", "pending")
|
|
445
|
+
.where(sql `proposed_version -> 'manifest' ->> 'name'`, "=", r.name)
|
|
446
|
+
.forUpdate()
|
|
447
|
+
.executeTakeFirst();
|
|
448
|
+
if (pend) {
|
|
449
|
+
await this.db
|
|
450
|
+
.updateTable("skill_change_requests")
|
|
451
|
+
.set({ status: "cancelled", decided_at: sql `now()` })
|
|
452
|
+
.where("id", "=", pend.id)
|
|
453
|
+
.execute();
|
|
454
|
+
await audit(this.db.db, {
|
|
437
455
|
actorAccountId: accountId,
|
|
438
456
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
439
457
|
orgId,
|
|
440
|
-
action: "skill.
|
|
441
|
-
target:
|
|
442
|
-
detail: { name: r.name
|
|
458
|
+
action: "skill.change_decided",
|
|
459
|
+
target: pend.id,
|
|
460
|
+
detail: { decision: "cancelled", reason: "skill_deleted", agentId, name: r.name },
|
|
443
461
|
});
|
|
444
|
-
|
|
462
|
+
const seq = await this.revertTrial(pend);
|
|
463
|
+
if (seq !== null)
|
|
464
|
+
out.seqs.push([pend.requested_in_conversation, seq]);
|
|
465
|
+
out.prefixes.push(pend.object_prefix);
|
|
466
|
+
}
|
|
467
|
+
await audit(this.db.db, {
|
|
468
|
+
actorAccountId: accountId,
|
|
469
|
+
...(actorTokenId !== undefined && { actorTokenId }),
|
|
470
|
+
orgId,
|
|
471
|
+
action: "skill.deleted",
|
|
472
|
+
target: skillId,
|
|
473
|
+
detail: { name: r.name, agentId },
|
|
445
474
|
});
|
|
446
|
-
|
|
475
|
+
return out;
|
|
447
476
|
}
|
|
448
477
|
/** 当前用户(作为 agent 负责人)能决定的待处理申请,新的在前,最多 {@link SKILL_CHANGES_LIST_MAX} 条。 */
|
|
449
478
|
async listPending(orgId, accountId) {
|
|
450
|
-
const rows = await this.
|
|
479
|
+
const rows = await this.db
|
|
451
480
|
.selectFrom("skill_change_requests")
|
|
452
481
|
.innerJoin("agents", "agents.id", "skill_change_requests.agent_id")
|
|
453
482
|
.selectAll("skill_change_requests")
|
|
@@ -465,7 +494,7 @@ export class SkillChangesService {
|
|
|
465
494
|
* 草稿对象已删除(拒绝 / 取消)时文件内容为 null。
|
|
466
495
|
*/
|
|
467
496
|
async get(orgId, id, accountId) {
|
|
468
|
-
const row = await this.
|
|
497
|
+
const row = await this.db
|
|
469
498
|
.selectFrom("skill_change_requests")
|
|
470
499
|
.innerJoin("agents", "agents.id", "skill_change_requests.agent_id")
|
|
471
500
|
.selectAll("skill_change_requests")
|
|
@@ -483,13 +512,13 @@ export class SkillChangesService {
|
|
|
483
512
|
if (!view)
|
|
484
513
|
throw notFound();
|
|
485
514
|
const live = row.status === "pending" || row.status === "approved";
|
|
486
|
-
const store = this.
|
|
515
|
+
const store = this.storage.kernel(orgId);
|
|
487
516
|
const budget = { left: DETAIL_MAX_BYTES };
|
|
488
517
|
const files = await readTexts(live ? store : undefined, row.object_prefix, row.proposed_version.manifest.files, budget);
|
|
489
518
|
// 改动已有技能:附上当前生效版本的文件(批准后它就是上一版,差异仍按申请时的当前版本显示)
|
|
490
519
|
let current = null;
|
|
491
520
|
if (row.skill_id !== null) {
|
|
492
|
-
const cur = await this.
|
|
521
|
+
const cur = await this.db
|
|
493
522
|
.selectFrom("skills")
|
|
494
523
|
.innerJoin("skill_versions", (j) => j
|
|
495
524
|
.onRef("skill_versions.skill_id", "=", "skills.id")
|
|
@@ -520,14 +549,14 @@ export class SkillChangesService {
|
|
|
520
549
|
* skills), and the pinned bodies still fit the size limit. The tool map is only recomputed at run
|
|
521
550
|
* start.
|
|
522
551
|
*/
|
|
523
|
-
async appendCatalog(
|
|
524
|
-
const base = (await lockLatestCatalog(
|
|
552
|
+
async appendCatalog(conversationId, derive, idemKey, runId) {
|
|
553
|
+
const base = (await lockLatestCatalog(this.db.db, conversationId)) ?? { skills: [] };
|
|
525
554
|
const derived = derive(base);
|
|
526
555
|
if (derived === null)
|
|
527
556
|
return null;
|
|
528
557
|
const skills = [...derived.skills].sort(byName);
|
|
529
558
|
const live = (p) => skills.some((s) => s.id === p.id && s.version === p.version && s.source === p.source);
|
|
530
|
-
const pinned = fitPinned((derived.pinned ?? []).filter(live), this.
|
|
559
|
+
const pinned = fitPinned((derived.pinned ?? []).filter(live), this.log, {
|
|
531
560
|
conversationId,
|
|
532
561
|
});
|
|
533
562
|
const next = {
|
|
@@ -537,14 +566,14 @@ export class SkillChangesService {
|
|
|
537
566
|
};
|
|
538
567
|
if (sameSnapshot(base, next))
|
|
539
568
|
return null;
|
|
540
|
-
const written = await this.
|
|
569
|
+
const written = await this.eventLog.appendIn(conversationId, [
|
|
541
570
|
{
|
|
542
571
|
type: "skills_catalog",
|
|
543
572
|
...(runId !== undefined && { runId }),
|
|
544
573
|
idemKey,
|
|
545
574
|
payload: next,
|
|
546
575
|
},
|
|
547
|
-
]
|
|
576
|
+
]);
|
|
548
577
|
return Math.max(...written.map((e) => e.seq));
|
|
549
578
|
}
|
|
550
579
|
/**
|
|
@@ -553,9 +582,9 @@ export class SkillChangesService {
|
|
|
553
582
|
* 快照里已没有这份草稿 → 不写。对话正在运行时,提醒落在当前位置(构建时排在工具结果之后),下一步即生效。
|
|
554
583
|
* 移除时不推测同名的组织技能(快照里已被替换掉),下一次运行开始的解析会把它补回来。
|
|
555
584
|
*/
|
|
556
|
-
async revertTrial(
|
|
585
|
+
async revertTrial(req) {
|
|
557
586
|
const name = req.proposed_version.manifest.name;
|
|
558
|
-
const real = await
|
|
587
|
+
const real = await this.db
|
|
559
588
|
.selectFrom("skills")
|
|
560
589
|
.innerJoin("skill_versions", (j) => j
|
|
561
590
|
.onRef("skill_versions.skill_id", "=", "skills.id")
|
|
@@ -572,7 +601,7 @@ export class SkillChangesService {
|
|
|
572
601
|
.where("skills.name", "=", name)
|
|
573
602
|
.where("skills.deleted_at", "is", null)
|
|
574
603
|
.executeTakeFirst();
|
|
575
|
-
return this.appendCatalog(
|
|
604
|
+
return this.appendCatalog(req.requested_in_conversation, (base) => {
|
|
576
605
|
if (!base.skills.some((s) => s.source === req.object_prefix))
|
|
577
606
|
return null;
|
|
578
607
|
const rest = base.skills.filter((s) => s.source !== req.object_prefix);
|
|
@@ -599,11 +628,13 @@ export class SkillChangesService {
|
|
|
599
628
|
}, `skills_catalog:revert:${req.id}`);
|
|
600
629
|
}
|
|
601
630
|
/**
|
|
602
|
-
*
|
|
603
|
-
*
|
|
631
|
+
* In the caller's transaction (`mandatory`: `AgentsService.softDelete` holds the org and agent
|
|
632
|
+
* row locks), cancels every pending skill change of the agent: marks them cancelled, audits, and
|
|
633
|
+
* appends a reverting snapshot to each requesting conversation. After the commit the caller runs
|
|
634
|
+
* {@link finishCancel} to delete the drafts and publish the events.
|
|
604
635
|
*/
|
|
605
|
-
async cancelPendingForAgent(
|
|
606
|
-
const rows = await
|
|
636
|
+
async cancelPendingForAgent(orgId, agentId, actorAccountId, reason, actorTokenId) {
|
|
637
|
+
const rows = await this.db
|
|
607
638
|
.selectFrom("skill_change_requests")
|
|
608
639
|
.selectAll()
|
|
609
640
|
.where("org_id", "=", orgId)
|
|
@@ -614,12 +645,12 @@ export class SkillChangesService {
|
|
|
614
645
|
.execute();
|
|
615
646
|
const out = { prefixes: [], seqs: [] };
|
|
616
647
|
for (const r of rows) {
|
|
617
|
-
await
|
|
648
|
+
await this.db
|
|
618
649
|
.updateTable("skill_change_requests")
|
|
619
650
|
.set({ status: "cancelled", decided_at: sql `now()` })
|
|
620
651
|
.where("id", "=", r.id)
|
|
621
652
|
.execute();
|
|
622
|
-
await audit(
|
|
653
|
+
await audit(this.db.db, {
|
|
623
654
|
actorAccountId,
|
|
624
655
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
625
656
|
orgId,
|
|
@@ -627,7 +658,7 @@ export class SkillChangesService {
|
|
|
627
658
|
target: r.id,
|
|
628
659
|
detail: { decision: "cancelled", reason, agentId, name: r.proposed_version.manifest.name },
|
|
629
660
|
});
|
|
630
|
-
const seq = await this.revertTrial(
|
|
661
|
+
const seq = await this.revertTrial(r);
|
|
631
662
|
if (seq !== null)
|
|
632
663
|
out.seqs.push([r.requested_in_conversation, seq]);
|
|
633
664
|
out.prefixes.push(r.object_prefix);
|
|
@@ -637,20 +668,20 @@ export class SkillChangesService {
|
|
|
637
668
|
/** {@link cancelPendingForAgent} 提交之后:发布事件、尽力删除草稿对象。 */
|
|
638
669
|
async finishCancel(orgId, c) {
|
|
639
670
|
for (const [conv, seq] of c.seqs)
|
|
640
|
-
await this.
|
|
671
|
+
await this.eventLog.notify(conv, seq);
|
|
641
672
|
for (const p of c.prefixes)
|
|
642
673
|
await this.deletePrefix(orgId, p);
|
|
643
674
|
}
|
|
644
675
|
/** 新技能的数量上限(含待批准的新技能;`excluding` 是将被取代的申请)。 */
|
|
645
|
-
async assertBelowCap(
|
|
646
|
-
const skills = await
|
|
676
|
+
async assertBelowCap(agentId, excluding) {
|
|
677
|
+
const skills = await this.db
|
|
647
678
|
.selectFrom("skills")
|
|
648
679
|
.select((eb) => eb.fn.countAll().as("n"))
|
|
649
680
|
.where("scope", "=", "agent")
|
|
650
681
|
.where("agent_id", "=", agentId)
|
|
651
682
|
.where("deleted_at", "is", null)
|
|
652
683
|
.executeTakeFirstOrThrow();
|
|
653
|
-
let q =
|
|
684
|
+
let q = this.db
|
|
654
685
|
.selectFrom("skill_change_requests")
|
|
655
686
|
.select((eb) => eb.fn.countAll().as("n"))
|
|
656
687
|
.where("agent_id", "=", agentId)
|
|
@@ -663,9 +694,9 @@ export class SkillChangesService {
|
|
|
663
694
|
throw new ToolError(capText());
|
|
664
695
|
}
|
|
665
696
|
/** 写一个版本并让 `current_version` 指向它(技能不存在则新建)。 */
|
|
666
|
-
async createVersion(
|
|
697
|
+
async createVersion(v) {
|
|
667
698
|
if (v.exists) {
|
|
668
|
-
await
|
|
699
|
+
await this.db
|
|
669
700
|
.updateTable("skills")
|
|
670
701
|
.set({
|
|
671
702
|
current_version: v.version,
|
|
@@ -676,7 +707,7 @@ export class SkillChangesService {
|
|
|
676
707
|
.execute();
|
|
677
708
|
}
|
|
678
709
|
else {
|
|
679
|
-
await
|
|
710
|
+
await this.db
|
|
680
711
|
.insertInto("skills")
|
|
681
712
|
.values({
|
|
682
713
|
id: v.skillId,
|
|
@@ -690,7 +721,7 @@ export class SkillChangesService {
|
|
|
690
721
|
})
|
|
691
722
|
.execute();
|
|
692
723
|
}
|
|
693
|
-
await
|
|
724
|
+
await this.db
|
|
694
725
|
.insertInto("skill_versions")
|
|
695
726
|
.values({
|
|
696
727
|
skill_id: v.skillId,
|
|
@@ -701,13 +732,25 @@ export class SkillChangesService {
|
|
|
701
732
|
})
|
|
702
733
|
.execute();
|
|
703
734
|
}
|
|
735
|
+
/**
|
|
736
|
+
* 先给组织行加 KEY SHARE 锁,再锁 agent 行:与 `AgentsService`(组织行 FOR UPDATE → agent 行)同一顺序。
|
|
737
|
+
* 不先锁的话,本事务持有 agent 行后插入引用组织的行(外键取 KEY SHARE)会与之互相等待(40P01)。
|
|
738
|
+
*/
|
|
739
|
+
async keyShareOrg(orgId) {
|
|
740
|
+
await this.db
|
|
741
|
+
.selectFrom("orgs")
|
|
742
|
+
.select("id")
|
|
743
|
+
.where("id", "=", orgId)
|
|
744
|
+
.forKeyShare()
|
|
745
|
+
.executeTakeFirst();
|
|
746
|
+
}
|
|
704
747
|
/** 尽力删除草稿对象(失败只记日志:孤儿对象随组织数据清理删除)。 */
|
|
705
748
|
async deletePrefix(orgId, prefix) {
|
|
706
749
|
try {
|
|
707
|
-
await this.
|
|
750
|
+
await this.storage.kernel(orgId).deletePrefix(prefix);
|
|
708
751
|
}
|
|
709
752
|
catch (err) {
|
|
710
|
-
this.
|
|
753
|
+
this.log.warn("skill draft cleanup failed", { orgId, prefix, err });
|
|
711
754
|
}
|
|
712
755
|
}
|
|
713
756
|
/** 补齐 agent 名。 */
|
|
@@ -715,7 +758,7 @@ export class SkillChangesService {
|
|
|
715
758
|
if (rows.length === 0)
|
|
716
759
|
return [];
|
|
717
760
|
const agentIds = [...new Set(rows.map((r) => r.agent_id))];
|
|
718
|
-
const agents = await this.
|
|
761
|
+
const agents = await this.db
|
|
719
762
|
.selectFrom("agents")
|
|
720
763
|
.innerJoin("agent_versions", (j) => j
|
|
721
764
|
.onRef("agent_versions.agent_id", "=", "agents.id")
|
|
@@ -723,7 +766,7 @@ export class SkillChangesService {
|
|
|
723
766
|
.select(["agents.id", "agent_versions.definition"])
|
|
724
767
|
.where("agents.id", "in", agentIds)
|
|
725
768
|
.execute();
|
|
726
|
-
const requesters = await this.
|
|
769
|
+
const requesters = await this.db
|
|
727
770
|
.selectFrom("accounts")
|
|
728
771
|
.select(["id", "display_name"])
|
|
729
772
|
.where("id", "in", [...new Set(rows.map((r) => r.requested_by_account))])
|
|
@@ -752,14 +795,28 @@ export class SkillChangesService {
|
|
|
752
795
|
createdAt: iso(r.created_at),
|
|
753
796
|
}));
|
|
754
797
|
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
798
|
+
};
|
|
799
|
+
__decorate([
|
|
800
|
+
Transactional()
|
|
801
|
+
], SkillChangesService.prototype, "writeIn", null);
|
|
802
|
+
__decorate([
|
|
803
|
+
Transactional()
|
|
804
|
+
], SkillChangesService.prototype, "decideIn", null);
|
|
805
|
+
__decorate([
|
|
806
|
+
Transactional()
|
|
807
|
+
], SkillChangesService.prototype, "deleteAgentSkillIn", null);
|
|
808
|
+
__decorate([
|
|
809
|
+
Transactional({ propagation: "mandatory" })
|
|
810
|
+
], SkillChangesService.prototype, "cancelPendingForAgent", null);
|
|
811
|
+
SkillChangesService = __decorate([
|
|
812
|
+
Injectable(),
|
|
813
|
+
__param(0, Inject(KernelDb)),
|
|
814
|
+
__param(1, Inject(StorageService)),
|
|
815
|
+
__param(2, Inject(EventLog)),
|
|
816
|
+
__param(3, Inject(KERNEL_LOGGER)),
|
|
817
|
+
__param(4, Inject(TransactionHost))
|
|
818
|
+
], SkillChangesService);
|
|
819
|
+
export { SkillChangesService };
|
|
763
820
|
/**
|
|
764
821
|
* 按清单顺序读文件文本,共用读取额度 `budget`(超出、对象缺失、存储出错时该文件内容为 null)。
|
|
765
822
|
* `store` 为 undefined 表示不读(如草稿已删除)。
|