@capybara-hq/kernel 0.1.0-rc.5 → 0.1.0-rc.7
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 +27 -3
- package/dist/admin/admin.controller.d.ts +21 -74
- package/dist/admin/admin.controller.js +50 -50
- package/dist/admin/admin.schemas.d.ts +57 -0
- package/dist/admin/admin.schemas.js +50 -0
- package/dist/admin/extensions.controller.d.ts +10 -0
- package/dist/admin/extensions.controller.js +18 -0
- package/dist/admin/extensions.schemas.d.ts +7 -0
- package/dist/admin/extensions.schemas.js +10 -0
- package/dist/admin/limit-defaults.d.ts +20 -0
- package/dist/admin/limit-defaults.js +10 -0
- package/dist/agents/agent-profile.service.d.ts +7 -5
- package/dist/agents/agent-profile.service.js +14 -9
- package/dist/agents/agents.controller.d.ts +7 -287
- package/dist/agents/agents.controller.js +7 -67
- package/dist/agents/agents.schemas.d.ts +389 -0
- package/dist/agents/agents.schemas.js +126 -0
- package/dist/agents/agents.service.d.ts +16 -6
- package/dist/agents/agents.service.js +75 -19
- package/dist/agents/definition.d.ts +47 -19
- package/dist/agents/definition.js +119 -38
- package/dist/agents/from-template.d.ts +2 -2
- package/dist/agents/from-template.js +76 -45
- package/dist/agents/from-template.service.d.ts +12 -0
- package/dist/agents/from-template.service.js +23 -6
- package/dist/agents/models.controller.d.ts +33 -5
- package/dist/agents/models.controller.js +50 -6
- package/dist/agents/org-templates.d.ts +13 -3
- package/dist/agents/org-templates.js +69 -28
- package/dist/agents/pending-connector-requests.d.ts +2 -0
- package/dist/agents/pending-connector-requests.js +1 -1
- package/dist/agents/pending-connectors.controller.d.ts +1 -1
- package/dist/agents/pending-connectors.controller.js +2 -2
- package/dist/agents/pending-connectors.service.d.ts +2 -2
- package/dist/agents/pending-connectors.service.js +19 -19
- package/dist/agents/profile.d.ts +18 -0
- package/dist/agents/profile.js +5 -1
- package/dist/agents/readiness.controller.d.ts +5 -5
- package/dist/agents/readiness.controller.js +6 -6
- package/dist/agents/templates.controller.d.ts +8 -17
- package/dist/agents/templates.controller.js +13 -31
- package/dist/agents/templates.schemas.d.ts +20 -0
- package/dist/agents/templates.schemas.js +45 -0
- package/dist/background/background.controller.js +3 -2
- package/dist/background/background.schemas.d.ts +10 -0
- package/dist/background/background.schemas.js +16 -0
- package/dist/background/tasks.service.d.ts +1 -1
- package/dist/background/tasks.service.js +7 -2
- package/dist/catalog/admin-catalog.controller.d.ts +4 -57
- package/dist/catalog/admin-catalog.controller.js +8 -45
- package/dist/catalog/admin-catalog.schemas.d.ts +72 -0
- package/dist/catalog/admin-catalog.schemas.js +92 -0
- package/dist/catalog/catalog-content.d.ts +12 -2
- package/dist/catalog/catalog-scope.service.js +8 -2
- package/dist/catalog/catalog.service.d.ts +2 -0
- package/dist/catalog/catalog.service.js +3 -0
- package/dist/catalog/component-scope.controller.d.ts +3 -65
- package/dist/catalog/component-scope.controller.js +3 -56
- package/dist/catalog/component-scope.schemas.d.ts +114 -0
- package/dist/catalog/component-scope.schemas.js +97 -0
- package/dist/catalog/component-scope.service.d.ts +28 -4
- package/dist/catalog/component-scope.service.js +55 -3
- package/dist/catalog/component-state.d.ts +9 -2
- package/dist/catalog/component-state.js +22 -13
- package/dist/catalog/marketplaces.controller.d.ts +5 -35
- package/dist/catalog/marketplaces.controller.js +6 -34
- package/dist/catalog/marketplaces.schemas.d.ts +48 -0
- package/dist/catalog/marketplaces.schemas.js +53 -0
- package/dist/catalog/marketplaces.service.d.ts +15 -1
- package/dist/catalog/marketplaces.service.js +22 -1
- package/dist/catalog/org-catalog.controller.d.ts +6 -62
- package/dist/catalog/org-catalog.controller.js +12 -66
- package/dist/catalog/org-catalog.schemas.d.ts +79 -0
- package/dist/catalog/org-catalog.schemas.js +82 -0
- package/dist/catalog/org-catalog.service.d.ts +9 -2
- package/dist/catalog/org-catalog.service.js +38 -5
- package/dist/catalog/org-extension.controller.d.ts +1 -12
- package/dist/catalog/org-extension.controller.js +1 -10
- package/dist/catalog/org-extension.schemas.d.ts +15 -0
- package/dist/catalog/org-extension.schemas.js +22 -0
- package/dist/catalog/org-plugin-uploads.controller.d.ts +2 -19
- package/dist/catalog/org-plugin-uploads.controller.js +15 -28
- package/dist/catalog/org-plugin-uploads.schemas.d.ts +20 -0
- package/dist/catalog/org-plugin-uploads.schemas.js +32 -0
- package/dist/catalog/owned-items.d.ts +6 -2
- package/dist/catalog/owned-items.js +16 -4
- package/dist/catalog/platform-components.d.ts +2 -0
- package/dist/catalog/platform-components.js +2 -0
- package/dist/catalog/plugin-import.js +1 -0
- package/dist/catalog/plugin-install.js +1 -1
- package/dist/catalog/requests.service.d.ts +2 -1
- package/dist/catalog/requests.service.js +6 -2
- package/dist/channels/channels.schemas.d.ts +33 -0
- package/dist/channels/channels.schemas.js +34 -0
- package/dist/channels/connections.controller.d.ts +2 -29
- package/dist/channels/connections.controller.js +1 -23
- package/dist/channels/connections.service.d.ts +8 -2
- package/dist/channels/connections.service.js +23 -5
- package/dist/channels/inbound.js +4 -0
- package/dist/config/schema.d.ts +4 -0
- package/dist/config/schema.js +24 -0
- package/dist/conversations/conversations.controller.d.ts +16 -37
- package/dist/conversations/conversations.controller.js +16 -56
- package/dist/conversations/conversations.schemas.d.ts +52 -0
- package/dist/conversations/conversations.schemas.js +79 -0
- package/dist/conversations/conversations.service.d.ts +13 -4
- package/dist/conversations/conversations.service.js +32 -26
- package/dist/conversations/events.d.ts +80 -6
- package/dist/conversations/events.js +60 -5
- package/dist/conversations/message-context.d.ts +28 -0
- package/dist/conversations/message-context.js +56 -0
- package/dist/conversations/queue.d.ts +2 -1
- package/dist/conversations/queue.js +11 -2
- package/dist/ctx/create-ctx.d.ts +15 -1
- package/dist/ctx/create-ctx.js +23 -2
- package/dist/db/kernel-schema.d.ts +44 -0
- package/dist/environments/environments.schemas.d.ts +3 -0
- package/dist/environments/environments.schemas.js +14 -0
- package/dist/environments/environments.service.d.ts +16 -4
- package/dist/environments/environments.service.js +58 -13
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +6 -0
- package/dist/evals/evals.schemas.d.ts +110 -0
- package/dist/evals/evals.schemas.js +107 -0
- package/dist/evals/reconstruct.js +18 -11
- package/dist/evals/recorded-tools.d.ts +2 -1
- package/dist/evals/recorded-tools.js +11 -3
- package/dist/evals/run-replay.d.ts +8 -1
- package/dist/evals/run-replay.js +17 -2
- package/dist/evals/runs.controller.d.ts +2 -57
- package/dist/evals/runs.controller.js +1 -42
- package/dist/evals/runs.service.d.ts +8 -7
- package/dist/evals/runs.service.js +45 -30
- package/dist/evals/sets.controller.d.ts +2 -28
- package/dist/evals/sets.controller.js +1 -31
- package/dist/evals/sets.service.d.ts +7 -7
- package/dist/evals/sets.service.js +23 -17
- package/dist/evals/snapshot.d.ts +3 -2
- package/dist/evals/snapshot.js +17 -4
- package/dist/evals/step-replay.d.ts +2 -1
- package/dist/evals/step-replay.js +3 -2
- package/dist/extensions/admin-ops.d.ts +5 -3
- package/dist/extensions/admin-ops.js +17 -12
- package/dist/extensions/config-hash.d.ts +10 -0
- package/dist/extensions/config-hash.js +38 -0
- package/dist/extensions/deployment-config.d.ts +16 -1
- package/dist/extensions/deployment-config.js +83 -0
- package/dist/extensions/extensions.module.js +9 -12
- package/dist/extensions/host.d.ts +39 -12
- package/dist/extensions/host.js +129 -51
- package/dist/extensions/installs.d.ts +5 -0
- package/dist/extensions/installs.js +12 -0
- package/dist/extensions/org-config.d.ts +17 -2
- package/dist/extensions/org-config.js +23 -4
- package/dist/extensions/point-defaults.controller.d.ts +2 -8
- package/dist/extensions/point-defaults.controller.js +1 -3
- package/dist/extensions/point-defaults.d.ts +3 -1
- package/dist/extensions/point-defaults.js +4 -2
- package/dist/extensions/point-defaults.schemas.d.ts +9 -0
- package/dist/extensions/point-defaults.schemas.js +14 -0
- package/dist/extensions/state.module.d.ts +9 -0
- package/dist/extensions/state.module.js +38 -0
- package/dist/extensions/unavailable.d.ts +49 -0
- package/dist/extensions/unavailable.js +113 -0
- package/dist/files/previewers.controller.js +2 -3
- package/dist/files/previewers.d.ts +1 -1
- package/dist/files/previewers.js +4 -4
- package/dist/files/previewers.schemas.d.ts +10 -0
- package/dist/files/previewers.schemas.js +9 -0
- package/dist/http/api.module.js +4 -0
- package/dist/http/plugin-dispatch.d.ts +4 -1
- package/dist/http/plugin-dispatch.js +14 -2
- package/dist/identity/accounts.d.ts +43 -4
- package/dist/identity/accounts.js +74 -6
- package/dist/identity/auth.guard.js +10 -1
- package/dist/identity/cookies.d.ts +6 -0
- package/dist/identity/cookies.js +14 -0
- package/dist/identity/identity.module.js +3 -0
- package/dist/identity/initial-passwords.controller.d.ts +22 -0
- package/dist/identity/initial-passwords.controller.js +49 -0
- package/dist/identity/initial-passwords.d.ts +61 -0
- package/dist/identity/initial-passwords.job.d.ts +16 -0
- package/dist/identity/initial-passwords.job.js +46 -0
- package/dist/identity/initial-passwords.js +159 -0
- package/dist/identity/me.controller.d.ts +14 -0
- package/dist/identity/me.controller.js +39 -1
- package/dist/identity/principal.d.ts +8 -0
- package/dist/identity/principal.js +8 -0
- package/dist/identity/settings.d.ts +3 -1
- package/dist/identity/settings.js +6 -4
- package/dist/inbox/inbox.schemas.d.ts +8 -0
- package/dist/inbox/inbox.schemas.js +11 -0
- package/dist/inbox/platform-inbox.controller.d.ts +1 -1
- package/dist/inbox/platform-inbox.controller.js +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +6 -0
- package/dist/infra/config/kernel-config.service.js +3 -0
- package/dist/infra/events/kernel-events.d.ts +8 -0
- package/dist/lifecycle/kernel-lifecycle.js +4 -0
- package/dist/models/embeddings.d.ts +82 -0
- package/dist/models/embeddings.js +326 -0
- package/dist/models/enablement.controller.d.ts +40 -0
- package/dist/models/enablement.controller.js +74 -0
- package/dist/models/enablement.d.ts +101 -0
- package/dist/models/enablement.js +264 -0
- package/dist/models/models.module.d.ts +5 -1
- package/dist/models/models.module.js +16 -4
- package/dist/models/org-models.schemas.d.ts +8 -0
- package/dist/models/org-models.schemas.js +22 -0
- package/dist/models/prices.d.ts +3 -1
- package/dist/models/prices.js +7 -5
- package/dist/models/purposes.d.ts +30 -6
- package/dist/models/purposes.js +68 -17
- package/dist/orgs/orgs.controller.d.ts +2 -5
- package/dist/orgs/orgs.controller.js +3 -6
- package/dist/orgs/orgs.schemas.d.ts +8 -0
- package/dist/orgs/orgs.schemas.js +16 -0
- package/dist/orgs/orgs.service.d.ts +3 -1
- package/dist/orgs/orgs.service.js +6 -4
- package/dist/orgs/settings.service.d.ts +9 -1
- package/dist/orgs/settings.service.js +20 -5
- package/dist/overrides.d.ts +4 -0
- package/dist/overrides.js +2 -0
- package/dist/platform/errors.d.ts +21 -4
- package/dist/platform/errors.js +45 -6
- package/dist/platform/exclusions.d.ts +2 -3
- package/dist/platform/exclusions.js +68 -831
- package/dist/platform/method.js +1 -1
- package/dist/platform/operation.d.ts +82 -5
- package/dist/platform/operation.js +62 -7
- package/dist/platform/ops/accounts.ops.d.ts +32 -0
- package/dist/platform/ops/accounts.ops.js +291 -0
- package/dist/platform/ops/admin.ops.d.ts +36 -0
- package/dist/platform/ops/admin.ops.js +389 -0
- package/dist/platform/ops/agent-skills.ops.d.ts +24 -0
- package/dist/platform/ops/agent-skills.ops.js +226 -0
- package/dist/platform/ops/agent-templates.ops.d.ts +4 -1
- package/dist/platform/ops/agent-templates.ops.js +194 -14
- package/dist/platform/ops/agents.ops.d.ts +19 -1
- package/dist/platform/ops/agents.ops.js +481 -58
- package/dist/platform/ops/approvals.ops.d.ts +30 -0
- package/dist/platform/ops/approvals.ops.js +116 -0
- package/dist/platform/ops/background.ops.d.ts +14 -0
- package/dist/platform/ops/background.ops.js +134 -0
- package/dist/platform/ops/catalog-admin.ops.d.ts +74 -0
- package/dist/platform/ops/catalog-admin.ops.js +587 -0
- package/dist/platform/ops/channels.ops.d.ts +16 -0
- package/dist/platform/ops/channels.ops.js +195 -0
- package/dist/platform/ops/components.ops.d.ts +46 -0
- package/dist/platform/ops/components.ops.js +853 -0
- package/dist/platform/ops/connectors.ops.d.ts +4 -2
- package/dist/platform/ops/connectors.ops.js +68 -6
- package/dist/platform/ops/conversations.ops.d.ts +30 -0
- package/dist/platform/ops/conversations.ops.js +470 -0
- package/dist/platform/ops/environments.ops.d.ts +26 -0
- package/dist/platform/ops/environments.ops.js +289 -0
- package/dist/platform/ops/errors.d.ts +10 -5
- package/dist/platform/ops/errors.js +19 -11
- package/dist/platform/ops/evals.ops.d.ts +28 -0
- package/dist/platform/ops/evals.ops.js +783 -0
- package/dist/platform/ops/extensions-admin.ops.d.ts +25 -0
- package/dist/platform/ops/extensions-admin.ops.js +344 -0
- package/dist/platform/ops/extensions.ops.d.ts +7 -1
- package/dist/platform/ops/extensions.ops.js +248 -17
- package/dist/platform/ops/inbox.ops.d.ts +25 -0
- package/dist/platform/ops/inbox.ops.js +378 -0
- package/dist/platform/ops/marketplaces.ops.d.ts +7 -1
- package/dist/platform/ops/marketplaces.ops.js +326 -17
- package/dist/platform/ops/models.ops.d.ts +25 -0
- package/dist/platform/ops/models.ops.js +232 -0
- package/dist/platform/ops/org-plugins.ops.d.ts +29 -0
- package/dist/platform/ops/org-plugins.ops.js +329 -0
- package/dist/platform/ops/org-settings.ops.d.ts +16 -0
- package/dist/platform/ops/org-settings.ops.js +102 -0
- package/dist/platform/ops/orgs.ops.d.ts +28 -0
- package/dist/platform/ops/orgs.ops.js +295 -0
- package/dist/platform/ops/other-orgs.d.ts +20 -0
- package/dist/platform/ops/other-orgs.js +72 -0
- package/dist/platform/ops/platform.ops.d.ts +4 -4
- package/dist/platform/ops/platform.ops.js +23 -24
- package/dist/platform/ops/plugins.ops.d.ts +10 -8
- package/dist/platform/ops/plugins.ops.js +176 -77
- package/dist/platform/ops/previewers.ops.d.ts +14 -0
- package/dist/platform/ops/previewers.ops.js +109 -0
- package/dist/platform/ops/requests.ops.js +57 -19
- package/dist/platform/ops/skills.ops.d.ts +5 -1
- package/dist/platform/ops/skills.ops.js +129 -11
- package/dist/platform/ops/unavailable.d.ts +23 -0
- package/dist/platform/ops/unavailable.js +111 -0
- package/dist/platform/parity.d.ts +33 -0
- package/dist/platform/parity.js +272 -0
- package/dist/platform/platform-ops.module.d.ts +32 -0
- package/dist/platform/platform-ops.module.js +78 -11
- package/dist/platform/route-schemas.d.ts +18 -0
- package/dist/platform/route-schemas.js +60 -0
- package/dist/roles/worker.module.js +2 -0
- package/dist/runtime/context/build.d.ts +2 -0
- package/dist/runtime/context/build.js +28 -2
- package/dist/runtime/context/compaction.js +10 -1
- package/dist/runtime/context/run-context.d.ts +65 -0
- package/dist/runtime/context/run-context.js +215 -0
- package/dist/runtime/hook-calls.d.ts +8 -1
- package/dist/runtime/hook-calls.js +40 -9
- package/dist/runtime/model-call.d.ts +8 -3
- package/dist/runtime/model-call.js +30 -6
- package/dist/runtime/providers.d.ts +146 -32
- package/dist/runtime/providers.js +328 -67
- package/dist/runtime/run-context.service.d.ts +65 -0
- package/dist/runtime/run-context.service.js +220 -0
- package/dist/runtime/run-worker.d.ts +6 -1
- package/dist/runtime/run-worker.js +35 -10
- package/dist/runtime/runtime.module.js +2 -0
- package/dist/runtime/subagents/definition.d.ts +15 -15
- package/dist/runtime/subagents/definition.js +49 -118
- package/dist/runtime/usage-report-jobs.d.ts +88 -0
- package/dist/runtime/usage-report-jobs.js +158 -0
- package/dist/runtime/usage-report.d.ts +33 -38
- package/dist/runtime/usage-report.js +152 -84
- package/dist/skills/changes.controller.js +2 -1
- package/dist/skills/changes.service.d.ts +1 -1
- package/dist/skills/changes.service.js +4 -4
- package/dist/skills/invocable.controller.d.ts +1 -1
- package/dist/skills/invocable.controller.js +2 -2
- package/dist/skills/invoke.d.ts +2 -2
- package/dist/skills/invoke.js +8 -1
- package/dist/skills/skills.controller.d.ts +4 -13
- package/dist/skills/skills.controller.js +8 -24
- package/dist/skills/skills.schemas.d.ts +48 -0
- package/dist/skills/skills.schemas.js +61 -0
- package/dist/skills/skills.service.d.ts +11 -1
- package/dist/skills/skills.service.js +37 -14
- package/dist/time-zone.d.ts +5 -0
- package/dist/time-zone.js +19 -0
- package/dist/tools/approvals.controller.js +2 -3
- package/dist/tools/approvals.schemas.d.ts +21 -0
- package/dist/tools/approvals.schemas.js +15 -0
- package/dist/tools/builtin-names.d.ts +10 -8
- package/dist/tools/builtin-names.js +16 -11
- package/dist/tools/builtins/builtin-tools.d.ts +3 -1
- package/dist/tools/builtins/builtin-tools.js +15 -3
- package/dist/tools/builtins/current-time.d.ts +26 -0
- package/dist/tools/builtins/current-time.js +99 -0
- package/dist/tools/builtins/platform.d.ts +19 -2
- package/dist/tools/builtins/platform.js +105 -16
- package/dist/tools/connectors.controller.d.ts +1 -2
- package/dist/tools/connectors.controller.js +1 -4
- package/dist/tools/connectors.schemas.d.ts +12 -0
- package/dist/tools/connectors.schemas.js +19 -0
- package/dist/tools/connectors.service.d.ts +5 -2
- package/dist/tools/connectors.service.js +7 -5
- package/dist/tools/org-tool-switches.d.ts +16 -2
- package/dist/tools/org-tool-switches.js +26 -9
- package/dist/tools/pipeline.js +9 -1
- package/dist/tools/registry.d.ts +48 -51
- package/dist/tools/registry.js +222 -233
- package/package.json +3 -3
- package/src/migrations/0089_model_kinds_usage.sql +38 -0
- package/src/migrations/0090_initial_passwords.sql +27 -0
- package/src/migrations/0091_account_time_zone.sql +4 -0
- package/src/migrations/0092_tools_default_on.sql +27 -0
- package/dist/platform/redact-orgs.d.ts +0 -7
- package/dist/platform/redact-orgs.js +0 -52
|
@@ -9,9 +9,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
9
9
|
};
|
|
10
10
|
import { getQueueToken } from "@nestjs/bullmq";
|
|
11
11
|
import { Inject, Injectable, Module, Optional } from "@nestjs/common";
|
|
12
|
-
import { DelayedError, Job, UnrecoverableError
|
|
12
|
+
import { DelayedError, Job, UnrecoverableError } from "bullmq";
|
|
13
13
|
import { sql } from "kysely";
|
|
14
|
-
import { enabledExtensionsQuery } from "../extensions/enabled.js";
|
|
15
14
|
import { ExtensionsModule } from "../extensions/extensions.module.js";
|
|
16
15
|
import { deepFreeze, errMsg, HookNeedsConfigError, } from "../extensions/hooks.js";
|
|
17
16
|
import { ExtensionHost } from "../extensions/host.js";
|
|
@@ -19,31 +18,13 @@ import { STALE_RECONCILE_PERIODS } from "../extensions/lifecycle-topics.js";
|
|
|
19
18
|
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
20
19
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
21
20
|
import { LockService } from "../infra/lock/lock.service.js";
|
|
22
|
-
import { QueueModule } from "../infra/queue/queue.module.js";
|
|
23
21
|
import { LockedCron } from "../infra/schedule/locked-cron.decorator.js";
|
|
24
22
|
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
25
23
|
import { deliveryRowOfChildRun } from "./subagents/child.js";
|
|
26
|
-
|
|
27
|
-
export
|
|
28
|
-
/** One job per `usage` event (no `:`: conversation ids are UUIDs, seq is a number). */
|
|
29
|
-
export const usageReportJobId = (conversationId, seq) => `usage-${conversationId}-${seq}`;
|
|
30
|
-
/** First attempt plus 5 retries (F11). */
|
|
31
|
-
export const USAGE_REPORT_ATTEMPTS = 6;
|
|
32
|
-
/** Retry backoff: 2 s, doubling (2, 4, 8, 16, 32 s). */
|
|
33
|
-
export const USAGE_REPORT_BACKOFF_MS = 2000;
|
|
34
|
-
/** Optional provider: the {@link UsageReportRetry} instead of the defaults above (tests). */
|
|
35
|
-
export const USAGE_REPORT_RETRY = Symbol("USAGE_REPORT_RETRY");
|
|
36
|
-
/** Failed jobs (given up) are kept for inspection, at most {@link KEEP_FAILED_MAX} of them. */
|
|
37
|
-
const KEEP_FAILED_S = 7 * 86_400;
|
|
38
|
-
/** Upper bound on kept failed jobs (I-2): a long outage of a billing endpoint cannot grow Redis. */
|
|
39
|
-
const KEEP_FAILED_MAX = 100_000;
|
|
24
|
+
import { modelUsageJobId, queryUsageSubscribers, USAGE_REPORT_ATTEMPTS, USAGE_REPORT_BACKOFF_MS, USAGE_REPORT_JOB, USAGE_REPORT_QUEUE, USAGE_REPORT_RETRY, UsageReportJobsModule, usageReportJobId, usageReportJobOpts, } from "./usage-report-jobs.js";
|
|
25
|
+
export { ModelUsageJobs, modelUsageJobId, queryUsageSubscribers, USAGE_REPORT_ATTEMPTS, USAGE_REPORT_BACKOFF_MS, USAGE_REPORT_QUEUE, USAGE_REPORT_RETRY, UsageReportJobsModule, usageReportJobId, } from "./usage-report-jobs.js";
|
|
40
26
|
/** Warnings about a plugin that cannot take deliveries are logged at most once per this window. */
|
|
41
27
|
const WARN_WINDOW_MS = 60_000;
|
|
42
|
-
/**
|
|
43
|
-
* Upper bound on kept finished jobs (Redis memory). At the default retention it only bites above
|
|
44
|
-
* ~1.1 usage events per second sustained for a day; dedupe needs the jobs only for the sweeper overlap.
|
|
45
|
-
*/
|
|
46
|
-
const KEEP_COMPLETED_MAX = 100_000;
|
|
47
28
|
/** The sweeper's cron job name (no `:`; every minute, once across replicas). */
|
|
48
29
|
export const USAGE_SWEEP_JOB = "usage-report-sweep";
|
|
49
30
|
/** The maintenance scheduler the sweep ran on before it became a `@LockedCron` (retired). */
|
|
@@ -57,38 +38,6 @@ export const USAGE_SWEEP_LAG_MS = 30_000;
|
|
|
57
38
|
*/
|
|
58
39
|
export const USAGE_SWEEP_OVERLAP_MS = 10 * 60_000;
|
|
59
40
|
const SWEEP_PAGE = 500;
|
|
60
|
-
const JOB = "usage-report";
|
|
61
|
-
/**
|
|
62
|
-
* Plugins that subscribe to `usage.report` according to deployment state: an approved permission
|
|
63
|
-
* snapshot that declares the `usage.report` hook, for a plugin the deployment still knows: an enabled
|
|
64
|
-
* install, or a config-declared plugin with a replica status row that is not `unloaded`. With `orgId`, only plugins
|
|
65
|
-
* the organization enabled (org config rows and required bootstrap plugins).
|
|
66
|
-
*/
|
|
67
|
-
export async function queryUsageSubscribers(db, orgId) {
|
|
68
|
-
let q = db
|
|
69
|
-
.selectFrom("extension_permission_snapshots as s")
|
|
70
|
-
.select("s.plugin")
|
|
71
|
-
.where(sql `s.permissions -> 'permissions' -> 'hooks' ? 'usage.report'`)
|
|
72
|
-
.where((eb) => eb.or([
|
|
73
|
-
eb.exists(eb
|
|
74
|
-
.selectFrom("extension_installs as i")
|
|
75
|
-
.select(sql `1`.as("one"))
|
|
76
|
-
.whereRef("i.name", "=", "s.plugin")
|
|
77
|
-
.where("i.desired_state", "=", "enabled")),
|
|
78
|
-
// config-declared plugins still declared (and not unloaded) on some replica; installs are
|
|
79
|
-
// covered by desired_state above (their replica rows linger as `unloaded` when disabled)
|
|
80
|
-
eb.exists(eb
|
|
81
|
-
.selectFrom("extension_replica_status as r")
|
|
82
|
-
.select(sql `1`.as("one"))
|
|
83
|
-
.whereRef("r.plugin", "=", "s.plugin")
|
|
84
|
-
.where("r.source", "=", "config")
|
|
85
|
-
.where("r.state", "<>", "unloaded")),
|
|
86
|
-
]));
|
|
87
|
-
if (orgId !== undefined) {
|
|
88
|
-
q = q.where("s.plugin", "in", enabledExtensionsQuery(db, orgId));
|
|
89
|
-
}
|
|
90
|
-
return new Set((await q.execute()).map((r) => r.plugin));
|
|
91
|
-
}
|
|
92
41
|
/**
|
|
93
42
|
* Of `plugins`, those that are **definitely** unservable right now (I-2, N-3): live replicas report
|
|
94
43
|
* them (a `extension_replica_status` row with a heartbeat newer than `staleSeconds`), no live row is
|
|
@@ -128,6 +77,10 @@ class Undeliverable extends Error {
|
|
|
128
77
|
this.name = "Undeliverable";
|
|
129
78
|
}
|
|
130
79
|
}
|
|
80
|
+
/** A job's identity: its `usage` event or its `model_usage` row. */
|
|
81
|
+
const keyOf = (d) => d.usageId !== undefined
|
|
82
|
+
? { usageId: d.usageId }
|
|
83
|
+
: { conversationId: d.conversationId, seq: d.seq };
|
|
131
84
|
/**
|
|
132
85
|
* The next `pending` set (m-2 fence): plugins that failed now, narrowed to what the stored job data
|
|
133
86
|
* still lists. A plugin another (stalled-over) execution already delivered never comes back.
|
|
@@ -159,11 +112,18 @@ export function narrowPending(stored, failed) {
|
|
|
159
112
|
* most 100 000. Each call runs through the instance's `inflight.run`, limited by `hooks.timeoutMs`;
|
|
160
113
|
* when this replica stops, in-flight calls are aborted and the job goes back to the queue without
|
|
161
114
|
* using up an attempt.
|
|
162
|
-
* Handlers must be idempotent by `eventId` (`<conversationId>/<seq
|
|
163
|
-
* log (never model-visible). Compaction calls log usage too (`purpose: "compaction"`) and are reported,
|
|
115
|
+
* Handlers must be idempotent by `eventId` (`<conversationId>/<seq>`, or a `model_usage` row id).
|
|
116
|
+
* Nothing is written to the event log (never model-visible). Compaction calls log usage too (`purpose: "compaction"`) and are reported,
|
|
164
117
|
* as are conversation title calls (`purpose: "title"`, no run: `runId` is "") and `WebFetch`
|
|
165
118
|
* extraction calls (`purpose: "web_fetch"`).
|
|
166
119
|
* Single-step eval replays and judge requests log no usage: not reported (M7).
|
|
120
|
+
* - **Model usage outside conversations** (spec B §5.4): each `ctx.models.embed` call writes a
|
|
121
|
+
* `model_usage` row; on its `model_usage.recorded` event `ModelUsageJobs` (`usage-report-jobs.ts`)
|
|
122
|
+
* enqueues job `usage-model-<rowId>` (only while some plugin subscribes); the payload
|
|
123
|
+
* (`purpose: "embedding"`, `eventId` = the row id, the calling `extension`, no conversation fields)
|
|
124
|
+
* is read from the row when the job runs, and the row's `reported_at` is set once nothing is left
|
|
125
|
+
* to deliver; a job that gives up after its last attempt sets `report_failed_at`. The sweep
|
|
126
|
+
* re-enqueues recent rows that are neither (see {@link sweep}).
|
|
167
127
|
*/
|
|
168
128
|
let UsageReporter = class UsageReporter {
|
|
169
129
|
kdb;
|
|
@@ -226,17 +186,8 @@ let UsageReporter = class UsageReporter {
|
|
|
226
186
|
subscribers(orgId) {
|
|
227
187
|
return queryUsageSubscribers(this.db, orgId);
|
|
228
188
|
}
|
|
229
|
-
jobOpts(
|
|
230
|
-
return
|
|
231
|
-
jobId: usageReportJobId(conversationId, seq),
|
|
232
|
-
attempts: this.retry.attempts,
|
|
233
|
-
backoff: { type: "exponential", delay: this.retry.backoffMs },
|
|
234
|
-
removeOnComplete: {
|
|
235
|
-
age: this.config.get().hooks.usageReportKeepHours * 3600,
|
|
236
|
-
count: KEEP_COMPLETED_MAX,
|
|
237
|
-
},
|
|
238
|
-
removeOnFail: { age: KEEP_FAILED_S, count: KEEP_FAILED_MAX },
|
|
239
|
-
};
|
|
189
|
+
jobOpts(jobId) {
|
|
190
|
+
return usageReportJobOpts(jobId, this.retry, this.config.get().hooks.usageReportKeepHours);
|
|
240
191
|
}
|
|
241
192
|
/**
|
|
242
193
|
* Enqueues the delivery of one `usage` event. Returns without a job when no plugin subscribes.
|
|
@@ -252,7 +203,7 @@ let UsageReporter = class UsageReporter {
|
|
|
252
203
|
try {
|
|
253
204
|
if ((await this.subscribers()).size === 0)
|
|
254
205
|
return;
|
|
255
|
-
await this.queue.add(
|
|
206
|
+
await this.queue.add(USAGE_REPORT_JOB, { conversationId, seq }, this.jobOpts(usageReportJobId(conversationId, seq)));
|
|
256
207
|
}
|
|
257
208
|
catch (err) {
|
|
258
209
|
this.log.warn("cannot enqueue usage report", { conversationId, seq, err });
|
|
@@ -261,7 +212,10 @@ let UsageReporter = class UsageReporter {
|
|
|
261
212
|
/**
|
|
262
213
|
* One sweep (R13): re-enqueues the `usage` events created in `[watermark - overlap, now - lag]` in
|
|
263
214
|
* pages, then advances the watermark to `now - lag`. With no subscriber it only advances. The first
|
|
264
|
-
* sweep starts at `now - lag - overlap`.
|
|
215
|
+
* sweep starts at `now - lag - overlap`. Also re-enqueues the `model_usage` rows of the same
|
|
216
|
+
* window that are neither reported nor given up (spec B §5.4),
|
|
217
|
+
* or, with no subscriber, marks those rows reported (nobody to deliver to). Returns the number of
|
|
218
|
+
* events and rows offered to the queue.
|
|
265
219
|
*/
|
|
266
220
|
async sweep(opts = {}) {
|
|
267
221
|
// bounds and keyset as full-precision timestamp text (microseconds), computed with the DB clock
|
|
@@ -278,7 +232,8 @@ let UsageReporter = class UsageReporter {
|
|
|
278
232
|
.executeTakeFirst();
|
|
279
233
|
const watermark = row?.watermark ?? to;
|
|
280
234
|
let offered = 0;
|
|
281
|
-
|
|
235
|
+
const subscribed = (await this.subscribers()).size > 0;
|
|
236
|
+
if (subscribed) {
|
|
282
237
|
let after;
|
|
283
238
|
for (;;) {
|
|
284
239
|
let q = this.db
|
|
@@ -298,9 +253,9 @@ let UsageReporter = class UsageReporter {
|
|
|
298
253
|
.execute();
|
|
299
254
|
if (page.length > 0) {
|
|
300
255
|
await this.queue.addBulk(page.map((r) => ({
|
|
301
|
-
name:
|
|
256
|
+
name: USAGE_REPORT_JOB,
|
|
302
257
|
data: { conversationId: r.conversation_id, seq: Number(r.seq) },
|
|
303
|
-
opts: this.jobOpts(r.conversation_id, Number(r.seq)),
|
|
258
|
+
opts: this.jobOpts(usageReportJobId(r.conversation_id, Number(r.seq))),
|
|
304
259
|
})));
|
|
305
260
|
offered += page.length;
|
|
306
261
|
}
|
|
@@ -310,6 +265,7 @@ let UsageReporter = class UsageReporter {
|
|
|
310
265
|
after = { at: last.at, conv: last.conversation_id, seq: String(last.seq) };
|
|
311
266
|
}
|
|
312
267
|
}
|
|
268
|
+
offered += await this.sweepModelUsage(watermark, to, subscribed);
|
|
313
269
|
await this.db
|
|
314
270
|
.insertInto("usage_report_sweep")
|
|
315
271
|
.values({ id: 1, watermark: sql `${to}::timestamptz` })
|
|
@@ -320,6 +276,51 @@ let UsageReporter = class UsageReporter {
|
|
|
320
276
|
.execute();
|
|
321
277
|
return offered;
|
|
322
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* The `model_usage` half of {@link sweep}: rows neither reported nor given up that occurred in
|
|
281
|
+
* the same window as the events (`[watermark - overlap, to]`), oldest first. Bounded like the
|
|
282
|
+
* event sweep, so a row whose job failed for good is never offered again, even after its failed
|
|
283
|
+
* job left Redis (no repeated backlog, no second delivery to plugins already served).
|
|
284
|
+
*/
|
|
285
|
+
async sweepModelUsage(watermark, to, subscribed) {
|
|
286
|
+
if (!subscribed) {
|
|
287
|
+
await this.db
|
|
288
|
+
.updateTable("model_usage")
|
|
289
|
+
.set({ reported_at: sql `now()` })
|
|
290
|
+
.where("reported_at", "is", null)
|
|
291
|
+
.where(sql `occurred_at <= ${to}::timestamptz`)
|
|
292
|
+
.execute();
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
295
|
+
let offered = 0;
|
|
296
|
+
let after;
|
|
297
|
+
for (;;) {
|
|
298
|
+
let q = this.db
|
|
299
|
+
.selectFrom("model_usage")
|
|
300
|
+
.select(["id", sql `occurred_at::text`.as("at")])
|
|
301
|
+
.where("reported_at", "is", null)
|
|
302
|
+
.where("report_failed_at", "is", null)
|
|
303
|
+
.where(sql `occurred_at >= ${watermark}::timestamptz - make_interval(secs => ${USAGE_SWEEP_OVERLAP_MS / 1000})`)
|
|
304
|
+
.where(sql `occurred_at <= ${to}::timestamptz`);
|
|
305
|
+
if (after) {
|
|
306
|
+
q = q.where(sql `(occurred_at, id) > (${after.at}::timestamptz, ${after.id}::uuid)`);
|
|
307
|
+
}
|
|
308
|
+
const page = await q.orderBy("occurred_at").orderBy("id").limit(SWEEP_PAGE).execute();
|
|
309
|
+
if (page.length > 0) {
|
|
310
|
+
await this.queue.addBulk(page.map((r) => ({
|
|
311
|
+
name: USAGE_REPORT_JOB,
|
|
312
|
+
data: { usageId: r.id },
|
|
313
|
+
opts: this.jobOpts(modelUsageJobId(r.id)),
|
|
314
|
+
})));
|
|
315
|
+
offered += page.length;
|
|
316
|
+
}
|
|
317
|
+
const last = page.at(-1);
|
|
318
|
+
if (!last || page.length < SWEEP_PAGE)
|
|
319
|
+
break;
|
|
320
|
+
after = { at: last.at, id: last.id };
|
|
321
|
+
}
|
|
322
|
+
return offered;
|
|
323
|
+
}
|
|
323
324
|
/**
|
|
324
325
|
* Starts consuming (worker role only): `worker` is the `@Processor` worker of
|
|
325
326
|
* {@link USAGE_REPORT_QUEUE} (built with the run queue's job lock and stalled detection).
|
|
@@ -344,14 +345,17 @@ let UsageReporter = class UsageReporter {
|
|
|
344
345
|
const final = j.attemptsMade >= (j.opts.attempts ?? 1);
|
|
345
346
|
const fields = {
|
|
346
347
|
jobId: j.id,
|
|
347
|
-
|
|
348
|
-
|
|
348
|
+
...(j.data.usageId !== undefined
|
|
349
|
+
? { usageId: j.data.usageId }
|
|
350
|
+
: { conversationId: j.data.conversationId, seq: j.data.seq }),
|
|
349
351
|
pending: j.data.pending,
|
|
350
352
|
attempt: j.attemptsMade,
|
|
351
353
|
error: err.message,
|
|
352
354
|
};
|
|
353
|
-
if (final)
|
|
355
|
+
if (final) {
|
|
354
356
|
this.log.error("usage report given up after retries", fields);
|
|
357
|
+
void this.markFailed(j.data);
|
|
358
|
+
}
|
|
355
359
|
else
|
|
356
360
|
this.log.warn("usage report attempt failed; retrying", fields);
|
|
357
361
|
}
|
|
@@ -366,6 +370,67 @@ let UsageReporter = class UsageReporter {
|
|
|
366
370
|
this.worker = undefined;
|
|
367
371
|
await w?.close().catch(() => { });
|
|
368
372
|
}
|
|
373
|
+
/** The payload of a job: a `usage` event's or a `model_usage` row's; null when it is gone. */
|
|
374
|
+
payloadOfJob(data) {
|
|
375
|
+
return data.usageId !== undefined
|
|
376
|
+
? this.payloadOfUsage(data.usageId)
|
|
377
|
+
: this.payloadOf(data.conversationId, data.seq);
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* The payload of one `model_usage` row (spec B §5.4): purpose `embedding`, the calling extension,
|
|
381
|
+
* no conversation fields; `eventId` is the row id. Null when the row no longer exists.
|
|
382
|
+
*/
|
|
383
|
+
async payloadOfUsage(id) {
|
|
384
|
+
const row = await this.db
|
|
385
|
+
.selectFrom("model_usage")
|
|
386
|
+
.select(["id", "org_id", "extension", "provider", "model", "input_tokens", "occurred_at"])
|
|
387
|
+
.where("id", "=", id)
|
|
388
|
+
.executeTakeFirst();
|
|
389
|
+
if (!row)
|
|
390
|
+
return null;
|
|
391
|
+
return {
|
|
392
|
+
eventId: row.id,
|
|
393
|
+
purpose: "embedding",
|
|
394
|
+
orgId: row.org_id,
|
|
395
|
+
extension: row.extension,
|
|
396
|
+
provider: row.provider,
|
|
397
|
+
model: row.model,
|
|
398
|
+
usage: {
|
|
399
|
+
inputTokens: row.input_tokens,
|
|
400
|
+
outputTokens: 0,
|
|
401
|
+
cacheReadTokens: 0,
|
|
402
|
+
cacheWriteTokens: 0,
|
|
403
|
+
},
|
|
404
|
+
occurredAt: new Date(row.occurred_at).toISOString(),
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
/** A `model_usage` job is done (delivered, or nothing left to deliver to): marks the row. */
|
|
408
|
+
async markReported(data) {
|
|
409
|
+
if (data.usageId === undefined)
|
|
410
|
+
return;
|
|
411
|
+
await this.db
|
|
412
|
+
.updateTable("model_usage")
|
|
413
|
+
.set({ reported_at: sql `now()` })
|
|
414
|
+
.where("id", "=", data.usageId)
|
|
415
|
+
.where("reported_at", "is", null)
|
|
416
|
+
.execute();
|
|
417
|
+
}
|
|
418
|
+
/** A `model_usage` job gave up after its last attempt: the sweep never offers the row again. */
|
|
419
|
+
async markFailed(data) {
|
|
420
|
+
if (data.usageId === undefined)
|
|
421
|
+
return;
|
|
422
|
+
try {
|
|
423
|
+
await this.db
|
|
424
|
+
.updateTable("model_usage")
|
|
425
|
+
.set({ report_failed_at: sql `now()` })
|
|
426
|
+
.where("id", "=", data.usageId)
|
|
427
|
+
.where("reported_at", "is", null)
|
|
428
|
+
.execute();
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
this.log.warn("cannot mark a model usage report as given up", { usageId: data.usageId, err });
|
|
432
|
+
}
|
|
433
|
+
}
|
|
369
434
|
/** The payload of one usage event, read from the log; null when the event no longer exists. */
|
|
370
435
|
async payloadOf(conversationId, seq) {
|
|
371
436
|
const row = await this.db
|
|
@@ -435,8 +500,7 @@ let UsageReporter = class UsageReporter {
|
|
|
435
500
|
const allowed = stored === undefined ? undefined : [...stored, ...Object.keys(storedDropped)];
|
|
436
501
|
const keep = [...dropped].filter(([p]) => allowed === undefined || allowed.includes(p));
|
|
437
502
|
const out = {
|
|
438
|
-
|
|
439
|
-
seq: j.data.seq,
|
|
503
|
+
...keyOf(j.data),
|
|
440
504
|
pending: narrowPending(allowed, next),
|
|
441
505
|
...(keep.length > 0 && { dropped: Object.fromEntries(keep) }),
|
|
442
506
|
};
|
|
@@ -445,22 +509,24 @@ let UsageReporter = class UsageReporter {
|
|
|
445
509
|
}
|
|
446
510
|
/** One delivery job (the `@Processor` of {@link USAGE_REPORT_QUEUE} calls it). */
|
|
447
511
|
async process(j, token) {
|
|
448
|
-
const
|
|
449
|
-
|
|
512
|
+
const payload = await this.payloadOfJob(j.data);
|
|
513
|
+
// conversation (or org) deleted meanwhile: nothing to report
|
|
450
514
|
if (payload === null)
|
|
451
|
-
return;
|
|
515
|
+
return;
|
|
452
516
|
const subscribers = await this.subscribers(payload.orgId);
|
|
453
517
|
if (j.data.pending === undefined) {
|
|
454
518
|
// first attempt: the targets come from deployment state, recorded so later attempts (on any
|
|
455
519
|
// replica) deliver exactly the plugins that have not succeeded yet
|
|
456
520
|
const targets = [...subscribers];
|
|
457
|
-
await j.updateData({
|
|
521
|
+
await j.updateData({ ...keyOf(j.data), pending: targets });
|
|
458
522
|
j.data.pending = targets;
|
|
459
523
|
}
|
|
460
524
|
// plugins the organization disabled meanwhile are dropped (not a failure)
|
|
461
525
|
const targets = (j.data.pending ?? []).filter((p) => subscribers.has(p));
|
|
462
|
-
if (targets.length === 0)
|
|
526
|
+
if (targets.length === 0) {
|
|
527
|
+
await this.markReported(j.data);
|
|
463
528
|
return;
|
|
529
|
+
}
|
|
464
530
|
const byPlugin = new Map();
|
|
465
531
|
for (const h of this.hooks.handlers("usage.report")) {
|
|
466
532
|
byPlugin.set(h.plugin, [...(byPlugin.get(h.plugin) ?? []), h.handler]);
|
|
@@ -539,6 +605,8 @@ let UsageReporter = class UsageReporter {
|
|
|
539
605
|
// m-1: pending = the dropped plugins only, so a manual retry reaches them and never the
|
|
540
606
|
// plugins already served
|
|
541
607
|
await this.writePending(j, [...allDropped.keys()], allDropped);
|
|
608
|
+
// delivered to every target still servable (a definite drop is final too): the row is done
|
|
609
|
+
await this.markReported(j.data);
|
|
542
610
|
const traced = new Map([...allDropped].filter(([p]) => j.data.dropped?.[p] !== undefined));
|
|
543
611
|
if (traced.size === 0)
|
|
544
612
|
return;
|
|
@@ -649,9 +717,9 @@ let UsageReportModule = class UsageReportModule {
|
|
|
649
717
|
};
|
|
650
718
|
UsageReportModule = __decorate([
|
|
651
719
|
Module({
|
|
652
|
-
imports: [ExtensionsModule,
|
|
720
|
+
imports: [ExtensionsModule, UsageReportJobsModule],
|
|
653
721
|
providers: [UsageReporter],
|
|
654
|
-
exports: [UsageReporter],
|
|
722
|
+
exports: [UsageReporter, UsageReportJobsModule],
|
|
655
723
|
})
|
|
656
724
|
], UsageReportModule);
|
|
657
725
|
export { UsageReportModule };
|
|
@@ -11,6 +11,7 @@ import { Controller, Delete, Get, HttpCode, Inject, Param, Post } from "@nestjs/
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { AgentsService } from "../agents/agents.service.js";
|
|
13
13
|
import { CurrentPrincipal, patTokenId, requireUser, } from "../identity/principal.js";
|
|
14
|
+
import { InboxNoticeParams } from "../inbox/inbox.schemas.js";
|
|
14
15
|
import { InboxService } from "../inbox/inbox.service.js";
|
|
15
16
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
16
17
|
import { ZBody, ZParam } from "../infra/validation/zod-params.js";
|
|
@@ -25,7 +26,7 @@ const DecideBody = z
|
|
|
25
26
|
.strict();
|
|
26
27
|
class SkillChangeDecideBody extends createZodDto(DecideBody, "SkillChangeDecideBody") {
|
|
27
28
|
}
|
|
28
|
-
const NoticeParamsSchema =
|
|
29
|
+
const NoticeParamsSchema = InboxNoticeParams;
|
|
29
30
|
class NoticeParams extends createZodDto(NoticeParamsSchema, "InboxNoticeParams") {
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
@@ -130,7 +130,7 @@ export declare class SkillChangesService {
|
|
|
130
130
|
* agent → `skill.not_found`。同名的待处理改动一并取消(发起对话追加回退快照,提交后删草稿)。审计 `skill.deleted`。
|
|
131
131
|
* 各对话下一次运行开始时目录里去掉它;之后同名可再写为新技能。
|
|
132
132
|
*/
|
|
133
|
-
deleteAgentSkill(orgId: string, agentId: string, skillId: string, accountId: string, actorTokenId?: string): Promise<void>;
|
|
133
|
+
deleteAgentSkill(orgId: string, agentId: string, skillId: string, accountId: string, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<void>;
|
|
134
134
|
/** The transaction of {@link write}. */
|
|
135
135
|
private writeIn;
|
|
136
136
|
/** The transaction of {@link decide}. */
|
|
@@ -146,8 +146,8 @@ let SkillChangesService = class SkillChangesService {
|
|
|
146
146
|
* agent → `skill.not_found`。同名的待处理改动一并取消(发起对话追加回退快照,提交后删草稿)。审计 `skill.deleted`。
|
|
147
147
|
* 各对话下一次运行开始时目录里去掉它;之后同名可再写为新技能。
|
|
148
148
|
*/
|
|
149
|
-
async deleteAgentSkill(orgId, agentId, skillId, accountId, actorTokenId) {
|
|
150
|
-
const cancelled = await this.deleteAgentSkillIn(orgId, agentId, skillId, accountId, actorTokenId);
|
|
149
|
+
async deleteAgentSkill(orgId, agentId, skillId, accountId, actorTokenId, auditDetail) {
|
|
150
|
+
const cancelled = await this.deleteAgentSkillIn(orgId, agentId, skillId, accountId, actorTokenId, auditDetail);
|
|
151
151
|
await this.finishCancel(orgId, cancelled);
|
|
152
152
|
}
|
|
153
153
|
/** The transaction of {@link write}. */
|
|
@@ -401,7 +401,7 @@ let SkillChangesService = class SkillChangesService {
|
|
|
401
401
|
return { updated, revertSeq };
|
|
402
402
|
}
|
|
403
403
|
/** The transaction of {@link deleteAgentSkill}. */
|
|
404
|
-
async deleteAgentSkillIn(orgId, agentId, skillId, accountId, actorTokenId) {
|
|
404
|
+
async deleteAgentSkillIn(orgId, agentId, skillId, accountId, actorTokenId, auditDetail) {
|
|
405
405
|
await this.keyShareOrg(orgId);
|
|
406
406
|
const agent = await this.db
|
|
407
407
|
.selectFrom("agents")
|
|
@@ -471,7 +471,7 @@ let SkillChangesService = class SkillChangesService {
|
|
|
471
471
|
orgId,
|
|
472
472
|
action: "skill.deleted",
|
|
473
473
|
target: skillId,
|
|
474
|
-
detail: { name: r.name, agentId },
|
|
474
|
+
detail: { name: r.name, agentId, ...auditDetail },
|
|
475
475
|
});
|
|
476
476
|
return out;
|
|
477
477
|
}
|
|
@@ -8,13 +8,13 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
10
|
import { Controller, Get, Header, Inject, Param } from "@nestjs/common";
|
|
11
|
-
import { z } from "zod";
|
|
12
11
|
import { CurrentPrincipal, requireUser } from "../identity/principal.js";
|
|
13
12
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
14
13
|
import { ZQuery } from "../infra/validation/zod-params.js";
|
|
15
14
|
import { CurrentOrg, OrgAction } from "../orgs/org.guard.js";
|
|
16
15
|
import { SkillInvoker } from "./invoke.js";
|
|
17
|
-
|
|
16
|
+
import { InvocableSkillsQuerySchema } from "./skills.schemas.js";
|
|
17
|
+
const ListQuery = InvocableSkillsQuerySchema;
|
|
18
18
|
class InvocableSkillsQuery extends createZodDto(ListQuery, "InvocableSkillsQuery") {
|
|
19
19
|
}
|
|
20
20
|
/**
|
package/dist/skills/invoke.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AgentLookup } from "../agents/agent-lookup.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type AgentDefinition } from "../agents/definition.js";
|
|
3
3
|
import type { EventPayload } from "../conversations/events.js";
|
|
4
4
|
import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
5
5
|
import { ApiError } from "../errors.js";
|
|
@@ -128,7 +128,7 @@ export declare class SkillInvoker {
|
|
|
128
128
|
conversationId: string;
|
|
129
129
|
skill: InvocationRecord;
|
|
130
130
|
}): Promise<{
|
|
131
|
-
task: (child: Pick<AgentDefinition, "
|
|
131
|
+
task: (child: Pick<AgentDefinition, "disabledTools" | "subagentTools">) => string;
|
|
132
132
|
warning?: string;
|
|
133
133
|
}>;
|
|
134
134
|
/** Reads and parses the version's SKILL.md (checked against the manifest), returns the body. */
|
package/dist/skills/invoke.js
CHANGED
|
@@ -10,6 +10,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
10
10
|
import { escapeSkillInvocationTags, hasShellInjection, parseSkillMd, renderSkillBody, renderSkillInvocation, SKILL_ENTRY_FILE, SKILL_INVOCATION_LIMITS, skillDigest, } from "@capybara-hq/plugin-sdk";
|
|
11
11
|
import { Inject, Injectable } from "@nestjs/common";
|
|
12
12
|
import { AgentLookup } from "../agents/agent-lookup.js";
|
|
13
|
+
import { builtinDisabled } from "../agents/definition.js";
|
|
13
14
|
import { ApiError } from "../errors.js";
|
|
14
15
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
15
16
|
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
@@ -289,7 +290,13 @@ SkillInvoker = __decorate([
|
|
|
289
290
|
__param(3, Inject(KERNEL_LOGGER))
|
|
290
291
|
], SkillInvoker);
|
|
291
292
|
export { SkillInvoker };
|
|
292
|
-
|
|
293
|
+
/**
|
|
294
|
+
* Does the definition leave builtin `name` on (tools default-on spec §4): not turned off and not
|
|
295
|
+
* removed by a sub-agent's key filter. Whether it can run now (a sandbox) is not checked.
|
|
296
|
+
*/
|
|
297
|
+
const hasBuiltin = (agent, name) => !builtinDisabled(agent.disabledTools, name) &&
|
|
298
|
+
!(agent.subagentTools?.deny ?? []).includes(name) &&
|
|
299
|
+
(agent.subagentTools?.allow === undefined || agent.subagentTools.allow.includes(name));
|
|
293
300
|
/** The skill's own body over the rendered limit: a 400 on `skill` naming the skill. */
|
|
294
301
|
function tooLarge(name, render) {
|
|
295
302
|
try {
|
|
@@ -3,21 +3,12 @@ import { OwnedItems, type OwnedSkillDeletePreview } from "../catalog/owned-items
|
|
|
3
3
|
import { type CreatedAttachment } from "../conversations/attachments.service.js";
|
|
4
4
|
import { type Principal } from "../identity/principal.js";
|
|
5
5
|
import { type OrgContext } from "../orgs/org.guard.js";
|
|
6
|
+
import { SkillCreateBody, SkillIdParams } from "./skills.schemas.js";
|
|
6
7
|
import { type SkillDetail, type SkillSummary, SkillsService, type UploadedSkill } from "./skills.service.js";
|
|
7
8
|
declare const UploadBody: z.ZodObject<{
|
|
8
9
|
name: z.ZodString;
|
|
9
10
|
size: z.ZodNumber;
|
|
10
11
|
}, z.core.$strict>;
|
|
11
|
-
declare const CreateBody: z.ZodObject<{
|
|
12
|
-
uploadId: z.ZodOptional<z.ZodString>;
|
|
13
|
-
name: z.ZodOptional<z.ZodString & z.ZodType<string, string, z.core.$ZodTypeInternals<string, string>>>;
|
|
14
|
-
description: z.ZodOptional<z.ZodString>;
|
|
15
|
-
body: z.ZodOptional<z.ZodString>;
|
|
16
|
-
shareable: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
-
}, z.core.$strict>;
|
|
18
|
-
declare const IdParams: z.ZodObject<{
|
|
19
|
-
id: z.ZodString;
|
|
20
|
-
}, z.core.$strip>;
|
|
21
12
|
declare const ShareableBody: z.ZodObject<{
|
|
22
13
|
shareable: z.ZodBoolean;
|
|
23
14
|
}, z.core.$strict>;
|
|
@@ -46,7 +37,7 @@ export declare class SkillsController {
|
|
|
46
37
|
/** The org's own items: 可共享 and the delete of a promoted skill (rulings P3-3, P3-19). */
|
|
47
38
|
owned: OwnedItems);
|
|
48
39
|
createUpload(principal: Principal, org: OrgContext, body: z.infer<typeof UploadBody>): Promise<CreatedAttachment>;
|
|
49
|
-
create(principal: Principal, org: OrgContext, body: z.infer<typeof
|
|
40
|
+
create(principal: Principal, org: OrgContext, body: z.infer<typeof SkillCreateBody>): Promise<UploadedSkill>;
|
|
50
41
|
list(principal: Principal, org: OrgContext): Promise<{
|
|
51
42
|
skills: SkillSummary[];
|
|
52
43
|
}>;
|
|
@@ -56,7 +47,7 @@ export declare class SkillsController {
|
|
|
56
47
|
* skill of the org's own (P3-6: an agent's skill or a copy of another owner's platform skill ->
|
|
57
48
|
* 409 `catalog.not_owned`); one it promoted writes its platform row too (ruling P3-2).
|
|
58
49
|
*/
|
|
59
|
-
setShareable(principal: Principal, org: OrgContext, params: z.infer<typeof
|
|
50
|
+
setShareable(principal: Principal, org: OrgContext, params: z.infer<typeof SkillIdParams>, body: z.infer<typeof ShareableBody>): Promise<{
|
|
60
51
|
id: string;
|
|
61
52
|
shareable: boolean;
|
|
62
53
|
}>;
|
|
@@ -65,7 +56,7 @@ export declare class SkillsController {
|
|
|
65
56
|
* `transferred` when it was shared and another org uses it (`orgs`), else `removed`; `agents`
|
|
66
57
|
* the org's agents that lose it.
|
|
67
58
|
*/
|
|
68
|
-
deletePreview(principal: Principal, org: OrgContext, params: z.infer<typeof
|
|
59
|
+
deletePreview(principal: Principal, org: OrgContext, params: z.infer<typeof SkillIdParams>): Promise<OwnedSkillDeletePreview>;
|
|
69
60
|
/**
|
|
70
61
|
* Soft-deletes the skill; one the org shared that another org uses is transferred to the
|
|
71
62
|
* platform first (P3-19, platform notice `ownership_transferred`). 204.
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
|
-
import { hasControlChars,
|
|
10
|
+
import { hasControlChars, MEDIA_NAME_MAX_CHARS } from "@capybara-hq/plugin-sdk";
|
|
11
11
|
import { Controller, Delete, Get, HttpCode, Inject, Param, Post, Put } from "@nestjs/common";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
import { OwnedItems } from "../catalog/owned-items.js";
|
|
@@ -16,7 +16,7 @@ import { CurrentPrincipal, patTokenId, requireUser, } from "../identity/principa
|
|
|
16
16
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
17
17
|
import { ZBody, ZParam } from "../infra/validation/zod-params.js";
|
|
18
18
|
import { CurrentOrg, OrgAction } from "../orgs/org.guard.js";
|
|
19
|
-
import {
|
|
19
|
+
import { SkillCreateBody, SkillIdParams, SkillShareableSchema } from "./skills.schemas.js";
|
|
20
20
|
import { SkillsService, } from "./skills.service.js";
|
|
21
21
|
const UploadBody = z
|
|
22
22
|
.object({
|
|
@@ -28,28 +28,12 @@ const UploadBody = z
|
|
|
28
28
|
size: z.number().int().min(1).max(SKILL_PACKAGE_UPLOAD_MAX_BYTES),
|
|
29
29
|
})
|
|
30
30
|
.strict();
|
|
31
|
-
const CreateBody = z
|
|
32
|
-
.object({
|
|
33
|
-
uploadId: z.string().min(1).max(100).optional(),
|
|
34
|
-
name: z
|
|
35
|
-
.string()
|
|
36
|
-
.refine(isSkillName, "name must be 1-64 lowercase letters, digits and single hyphens")
|
|
37
|
-
.optional(),
|
|
38
|
-
description: z.string().min(1).max(SKILL_LIMITS.descriptionMaxChars).optional(),
|
|
39
|
-
body: z.string().max(SKILL_WRITE_MAX_BYTES).optional(),
|
|
40
|
-
shareable: z.boolean().optional(),
|
|
41
|
-
})
|
|
42
|
-
.strict()
|
|
43
|
-
.refine((v) => v.uploadId !== undefined
|
|
44
|
-
? v.name === undefined && v.description === undefined && v.body === undefined
|
|
45
|
-
: v.name !== undefined && v.description !== undefined && v.body !== undefined, "send either { uploadId } or { name, description, body }");
|
|
46
31
|
class SkillUploadBody extends createZodDto(UploadBody, "SkillUploadBody") {
|
|
47
32
|
}
|
|
48
|
-
class
|
|
33
|
+
class SkillCreateBodyDto extends createZodDto(SkillCreateBody, "SkillCreateBody") {
|
|
49
34
|
}
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
class SkillIdParams extends createZodDto(IdParams, "SkillIdParams") {
|
|
35
|
+
const ShareableBody = SkillShareableSchema;
|
|
36
|
+
class SkillIdParamsDto extends createZodDto(SkillIdParams, "SkillIdParams") {
|
|
53
37
|
}
|
|
54
38
|
class SkillShareableBody extends createZodDto(ShareableBody, "SkillShareableBody") {
|
|
55
39
|
}
|
|
@@ -147,7 +131,7 @@ __decorate([
|
|
|
147
131
|
OrgAction("skills.manage"),
|
|
148
132
|
__param(0, CurrentPrincipal()),
|
|
149
133
|
__param(1, CurrentOrg()),
|
|
150
|
-
__param(2, ZBody(
|
|
134
|
+
__param(2, ZBody(SkillCreateBodyDto))
|
|
151
135
|
], SkillsController.prototype, "create", null);
|
|
152
136
|
__decorate([
|
|
153
137
|
Get(),
|
|
@@ -167,7 +151,7 @@ __decorate([
|
|
|
167
151
|
OrgAction("skills.manage"),
|
|
168
152
|
__param(0, CurrentPrincipal()),
|
|
169
153
|
__param(1, CurrentOrg()),
|
|
170
|
-
__param(2, ZParam(
|
|
154
|
+
__param(2, ZParam(SkillIdParamsDto)),
|
|
171
155
|
__param(3, ZBody(SkillShareableBody))
|
|
172
156
|
], SkillsController.prototype, "setShareable", null);
|
|
173
157
|
__decorate([
|
|
@@ -175,7 +159,7 @@ __decorate([
|
|
|
175
159
|
OrgAction("skills.manage"),
|
|
176
160
|
__param(0, CurrentPrincipal()),
|
|
177
161
|
__param(1, CurrentOrg()),
|
|
178
|
-
__param(2, ZParam(
|
|
162
|
+
__param(2, ZParam(SkillIdParamsDto))
|
|
179
163
|
], SkillsController.prototype, "deletePreview", null);
|
|
180
164
|
__decorate([
|
|
181
165
|
Delete(":id"),
|