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