@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
|
@@ -152,8 +152,8 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
152
152
|
throw setNotFound();
|
|
153
153
|
return EvalSetsService_1.toView(r);
|
|
154
154
|
}
|
|
155
|
-
async create(orgId, actor, input, actorTokenId) {
|
|
156
|
-
const id = await this.createIn(orgId, actor, input, actorTokenId);
|
|
155
|
+
async create(orgId, actor, input, actorTokenId, auditDetail) {
|
|
156
|
+
const id = await this.createIn(orgId, actor, input, actorTokenId, auditDetail);
|
|
157
157
|
return this.view(orgId, id);
|
|
158
158
|
}
|
|
159
159
|
async list(orgId) {
|
|
@@ -175,22 +175,22 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
175
175
|
.execute();
|
|
176
176
|
return { ...set, cases: cases.map(toCaseView) };
|
|
177
177
|
}
|
|
178
|
-
async update(orgId, actor, setId, patch, actorTokenId) {
|
|
178
|
+
async update(orgId, actor, setId, patch, actorTokenId, auditDetail) {
|
|
179
179
|
if (!UUID.test(setId))
|
|
180
180
|
throw setNotFound();
|
|
181
|
-
await this.updateIn(orgId, actor, setId, patch, actorTokenId);
|
|
181
|
+
await this.updateIn(orgId, actor, setId, patch, actorTokenId, auditDetail);
|
|
182
182
|
return this.view(orgId, setId);
|
|
183
183
|
}
|
|
184
184
|
/**
|
|
185
185
|
* 删除评测集(Ruling S1-a):集合行软删除,留作审计存根;用例(含快照)硬删,结果随之级联删除,不留复制来的对话内容;
|
|
186
186
|
* 在执行的运行取消,运行行保留(无入口)。
|
|
187
187
|
*/
|
|
188
|
-
async remove(orgId, actor, setId, actorTokenId) {
|
|
188
|
+
async remove(orgId, actor, setId, actorTokenId, auditDetail) {
|
|
189
189
|
if (!UUID.test(setId))
|
|
190
190
|
throw setNotFound();
|
|
191
|
-
await this.removeIn(orgId, actor, setId, actorTokenId);
|
|
191
|
+
await this.removeIn(orgId, actor, setId, actorTokenId, auditDetail);
|
|
192
192
|
}
|
|
193
|
-
async createIn(orgId, actor, input, actorTokenId) {
|
|
193
|
+
async createIn(orgId, actor, input, actorTokenId, auditDetail) {
|
|
194
194
|
await this.orgLock.lockAndAuthorize(orgId, actor, "evals.manage");
|
|
195
195
|
const agent = await this.db
|
|
196
196
|
.selectFrom("agents")
|
|
@@ -219,11 +219,11 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
219
219
|
orgId,
|
|
220
220
|
action: "eval.set_created",
|
|
221
221
|
target: row.id,
|
|
222
|
-
detail: { agentId: input.agentId, name: input.name },
|
|
222
|
+
detail: { agentId: input.agentId, name: input.name, ...auditDetail },
|
|
223
223
|
});
|
|
224
224
|
return row.id;
|
|
225
225
|
}
|
|
226
|
-
async updateIn(orgId, actor, setId, patch, actorTokenId) {
|
|
226
|
+
async updateIn(orgId, actor, setId, patch, actorTokenId, auditDetail) {
|
|
227
227
|
await this.orgLock.lockAndAuthorize(orgId, actor, "evals.manage");
|
|
228
228
|
const r = await this.db
|
|
229
229
|
.updateTable("eval_sets")
|
|
@@ -248,10 +248,11 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
248
248
|
// 只记改了哪些字段(评分标准可能很长,不进审计)
|
|
249
249
|
detail: {
|
|
250
250
|
fields: ["name", "description", "rubric"].filter((f) => patch[f] !== undefined),
|
|
251
|
+
...auditDetail,
|
|
251
252
|
},
|
|
252
253
|
});
|
|
253
254
|
}
|
|
254
|
-
async removeIn(orgId, actor, setId, actorTokenId) {
|
|
255
|
+
async removeIn(orgId, actor, setId, actorTokenId, auditDetail) {
|
|
255
256
|
await this.orgLock.lockAndAuthorize(orgId, actor, "evals.manage");
|
|
256
257
|
const r = await this.db
|
|
257
258
|
.updateTable("eval_sets")
|
|
@@ -269,6 +270,7 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
269
270
|
orgId,
|
|
270
271
|
action: "eval.set_deleted",
|
|
271
272
|
target: setId,
|
|
273
|
+
...(auditDetail !== undefined && { detail: auditDetail }),
|
|
272
274
|
});
|
|
273
275
|
}
|
|
274
276
|
async insertCaseIn(orgId, actor, setId, snapshot, extra, prepared) {
|
|
@@ -319,11 +321,12 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
319
321
|
conversationId: snapshot.conversationId,
|
|
320
322
|
runId: snapshot.runId,
|
|
321
323
|
...(extra.sampled && { sampled: true }),
|
|
324
|
+
...extra.auditDetail,
|
|
322
325
|
},
|
|
323
326
|
});
|
|
324
327
|
return toCaseView(row);
|
|
325
328
|
}
|
|
326
|
-
async removeCaseIn(orgId, actor, setId, caseId, actorTokenId) {
|
|
329
|
+
async removeCaseIn(orgId, actor, setId, caseId, actorTokenId, auditDetail) {
|
|
327
330
|
await this.orgLock.lockAndAuthorize(orgId, actor, "evals.manage");
|
|
328
331
|
const set = await this.db
|
|
329
332
|
.selectFrom("eval_sets")
|
|
@@ -354,6 +357,7 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
354
357
|
caseId,
|
|
355
358
|
conversationId: r.source_conversation_id,
|
|
356
359
|
runId: r.source_run_id,
|
|
360
|
+
...auditDetail,
|
|
357
361
|
},
|
|
358
362
|
});
|
|
359
363
|
}
|
|
@@ -402,7 +406,7 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
402
406
|
* `eval.agent_mismatch`;已在集合里 → `eval.case_exists`;集合满了 → `eval.too_many_cases`;
|
|
403
407
|
* 运行未终态 / 快照超大 → `eval.run_not_finished` / `eval.case_too_large`(`takeSnapshot`)。
|
|
404
408
|
*/
|
|
405
|
-
async addCase(orgId, actor, setId, input, actorTokenId) {
|
|
409
|
+
async addCase(orgId, actor, setId, input, actorTokenId, auditDetail) {
|
|
406
410
|
const set = await this.liveSet(orgId, setId);
|
|
407
411
|
const conv = await this.db
|
|
408
412
|
.selectFrom("conversations")
|
|
@@ -434,6 +438,7 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
434
438
|
const r = await this.insertCase(orgId, actor, setId, snapshot, {
|
|
435
439
|
sampled: false,
|
|
436
440
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
441
|
+
...(auditDetail !== undefined && { auditDetail }),
|
|
437
442
|
});
|
|
438
443
|
if (r === "exists")
|
|
439
444
|
throw caseExists();
|
|
@@ -446,7 +451,7 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
446
451
|
* `min(count, 剩余容量)` 个,逐个取快照写入。快照超大(或其间被删除 / 写入时已满 / 并发加入)的计入 `skipped`。
|
|
447
452
|
* 集合已满 → `eval.too_many_cases`。逐个写入,内存里一次只有一份快照。
|
|
448
453
|
*/
|
|
449
|
-
async sample(orgId, actor, setId, input, actorTokenId) {
|
|
454
|
+
async sample(orgId, actor, setId, input, actorTokenId, auditDetail) {
|
|
450
455
|
const set = await this.liveSet(orgId, setId);
|
|
451
456
|
const { maxCasesPerSet, maxCaseBytes } = this.config.get().evals;
|
|
452
457
|
const room = maxCasesPerSet - (await this.caseCount(this.db, setId));
|
|
@@ -497,6 +502,7 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
497
502
|
const r = await this.insertCase(orgId, actor, setId, snapshot, {
|
|
498
503
|
sampled: true,
|
|
499
504
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
505
|
+
...(auditDetail !== undefined && { auditDetail }),
|
|
500
506
|
});
|
|
501
507
|
if (typeof r === "string")
|
|
502
508
|
skipped++;
|
|
@@ -505,18 +511,18 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
505
511
|
}
|
|
506
512
|
return { added, skipped };
|
|
507
513
|
}
|
|
508
|
-
async removeCase(orgId, actor, setId, caseId, actorTokenId) {
|
|
514
|
+
async removeCase(orgId, actor, setId, caseId, actorTokenId, auditDetail) {
|
|
509
515
|
if (!UUID.test(setId))
|
|
510
516
|
throw setNotFound();
|
|
511
517
|
if (!UUID.test(caseId))
|
|
512
518
|
throw caseNotFound();
|
|
513
|
-
await this.removeCaseIn(orgId, actor, setId, caseId, actorTokenId);
|
|
519
|
+
await this.removeCaseIn(orgId, actor, setId, caseId, actorTokenId, auditDetail);
|
|
514
520
|
}
|
|
515
521
|
/**
|
|
516
522
|
* 用例详情:由快照还原轨迹(原对话删除后照常可读)。快照即对话内容,每次查看写审计 `trajectory.viewed`
|
|
517
523
|
* (target = 原对话 id,detail 带 `caseId` / `setId`)。
|
|
518
524
|
*/
|
|
519
|
-
async getCase(orgId, actor, setId, caseId, actorTokenId) {
|
|
525
|
+
async getCase(orgId, actor, setId, caseId, actorTokenId, auditDetail) {
|
|
520
526
|
await this.liveSet(orgId, setId);
|
|
521
527
|
if (!UUID.test(caseId))
|
|
522
528
|
throw caseNotFound();
|
|
@@ -537,7 +543,7 @@ let EvalSetsService = EvalSetsService_1 = class EvalSetsService {
|
|
|
537
543
|
orgId,
|
|
538
544
|
action: "trajectory.viewed",
|
|
539
545
|
target: row.source_conversation_id,
|
|
540
|
-
detail: { agentId: snapshot.agentId, caseId, setId },
|
|
546
|
+
detail: { agentId: snapshot.agentId, caseId, setId, ...auditDetail },
|
|
541
547
|
});
|
|
542
548
|
return {
|
|
543
549
|
case: toCaseView(row),
|
package/dist/evals/snapshot.d.ts
CHANGED
|
@@ -59,8 +59,9 @@ export interface CaseSnapshot {
|
|
|
59
59
|
*/
|
|
60
60
|
export declare function takeSnapshot(db: KernelSchemaDb, orgId: string, conversationId: string, runId: string, maxBytes: number): Promise<CaseSnapshot>;
|
|
61
61
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
62
|
+
* Reads a stored snapshot (`eval_cases.snapshot`): each version's definition goes through
|
|
63
|
+
* `normalizeStoredDefinition` (rc tool keys, and an enabled tool list read as nothing turned off).
|
|
64
|
+
* Other fields as they are.
|
|
64
65
|
*/
|
|
65
66
|
export declare function readSnapshot(raw: unknown): CaseSnapshot;
|
|
66
67
|
/** 快照事件还原为日志事件(`createdAt` 转回 Date)。 */
|
package/dist/evals/snapshot.js
CHANGED
|
@@ -97,7 +97,7 @@ export async function takeSnapshot(db, orgId, conversationId, runId, maxBytes) {
|
|
|
97
97
|
.orderBy("version")
|
|
98
98
|
.execute();
|
|
99
99
|
for (const r of defRows) {
|
|
100
|
-
definitions[String(r.version)] =
|
|
100
|
+
definitions[String(r.version)] = snapshotDefinition(r.definition);
|
|
101
101
|
}
|
|
102
102
|
const toolSpecs = {};
|
|
103
103
|
if (hashes.size > 0) {
|
|
@@ -151,14 +151,27 @@ export async function takeSnapshot(db, orgId, conversationId, runId, maxBytes) {
|
|
|
151
151
|
return snapshot;
|
|
152
152
|
}
|
|
153
153
|
/**
|
|
154
|
-
*
|
|
155
|
-
*
|
|
154
|
+
* A definition as a snapshot holds it: normalized (`normalizeStoredDefinition`), and one from
|
|
155
|
+
* before tools were on by default keeps its enabled list next to it: rc tool keys are read by its
|
|
156
|
+
* extension refs (`legacyScopeOf`); the runtime ignores it (tools default-on spec §2).
|
|
157
|
+
*/
|
|
158
|
+
function snapshotDefinition(d) {
|
|
159
|
+
const enabled = d?.tools;
|
|
160
|
+
return {
|
|
161
|
+
...normalizeStoredDefinition(d),
|
|
162
|
+
...(Array.isArray(enabled) && { tools: enabled }),
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Reads a stored snapshot (`eval_cases.snapshot`): each version's definition goes through
|
|
167
|
+
* `normalizeStoredDefinition` (rc tool keys, and an enabled tool list read as nothing turned off).
|
|
168
|
+
* Other fields as they are.
|
|
156
169
|
*/
|
|
157
170
|
export function readSnapshot(raw) {
|
|
158
171
|
const s = raw;
|
|
159
172
|
const definitions = {};
|
|
160
173
|
for (const [v, d] of Object.entries(s.definitions ?? {})) {
|
|
161
|
-
definitions[v] =
|
|
174
|
+
definitions[v] = snapshotDefinition(d);
|
|
162
175
|
}
|
|
163
176
|
return {
|
|
164
177
|
...s,
|
|
@@ -92,7 +92,8 @@ export declare class ReplayAttemptError extends Error {
|
|
|
92
92
|
* 否则带候选的定义、版本与参数——参数按候选模型的声明宽松处理,与运行时一致),用 `consumeModelStream` 收完。
|
|
93
93
|
* 请求发出之前的错误原样抛出(`agent.model_unavailable`、取附件暂时失败为 `MediaUnavailableError`);请求发出之后的
|
|
94
94
|
* 错误包成 {@link ReplayAttemptError}(带估算用量,调用方计入预算后按 `cause` 分类重试)。
|
|
95
|
-
*
|
|
95
|
+
* The candidate model resolves in the snapshot's org like the runtime (its effective provider
|
|
96
|
+
* config and disabled lists: a model disabled there is `agent.model_unavailable`, spec B §5.3).
|
|
96
97
|
* 不另设单次请求的墙钟时限:与运行时一样只有流空闲看门狗(`streamIdleTimeoutMs` / `runtime.streamIdleMs`)。
|
|
97
98
|
*/
|
|
98
99
|
export declare function replayStep(d: StepReplayDeps, s: CaseSnapshot, call: {
|
|
@@ -126,12 +126,13 @@ function baselineOf(s, call) {
|
|
|
126
126
|
* 否则带候选的定义、版本与参数——参数按候选模型的声明宽松处理,与运行时一致),用 `consumeModelStream` 收完。
|
|
127
127
|
* 请求发出之前的错误原样抛出(`agent.model_unavailable`、取附件暂时失败为 `MediaUnavailableError`);请求发出之后的
|
|
128
128
|
* 错误包成 {@link ReplayAttemptError}(带估算用量,调用方计入预算后按 `cause` 分类重试)。
|
|
129
|
-
*
|
|
129
|
+
* The candidate model resolves in the snapshot's org like the runtime (its effective provider
|
|
130
|
+
* config and disabled lists: a model disabled there is `agent.model_unavailable`, spec B §5.3).
|
|
130
131
|
* 不另设单次请求的墙钟时限:与运行时一样只有流空闲看门狗(`streamIdleTimeoutMs` / `runtime.streamIdleMs`)。
|
|
131
132
|
*/
|
|
132
133
|
export async function replayStep(d, s, call, candidate, signal) {
|
|
133
134
|
const baseline = baselineOf(s, call);
|
|
134
|
-
const { provider, info } = await d.registry.resolve(candidate.model);
|
|
135
|
+
const { provider, info } = await d.registry.resolve(s.orgId, candidate.model);
|
|
135
136
|
let media;
|
|
136
137
|
if (d.media) {
|
|
137
138
|
try {
|
|
@@ -120,14 +120,16 @@ export declare class ExtensionAdminOps {
|
|
|
120
120
|
}): Promise<AdminExtensionView>;
|
|
121
121
|
private writeInstall;
|
|
122
122
|
/** Enable on the deployment (audit `extension.enabled`); no change when already enabled. Org enablement is unchanged. */
|
|
123
|
-
enable(name: string, actor: string | null, actorTokenId?: string, owner?: ExtensionOpsOwner
|
|
123
|
+
enable(name: string, actor: string | null, actorTokenId?: string, owner?: ExtensionOpsOwner,
|
|
124
|
+
/** Merged into the audit detail (a write made through the Platform tool). */
|
|
125
|
+
auditDetail?: Record<string, unknown>): Promise<AdminExtensionView>;
|
|
124
126
|
/**
|
|
125
127
|
* Disables on the deployment (audit `extension.disabled`); no change when already disabled. Every
|
|
126
128
|
* replica unloads it (draining in-flight calls), and the extensions that `requires` it unload with
|
|
127
129
|
* it; the org enablement switch is unchanged and the org page shows it as unavailable. A required
|
|
128
130
|
* bootstrap plugin -> `extension.required`.
|
|
129
131
|
*/
|
|
130
|
-
disable(name: string, actor: string | null, actorTokenId?: string, owner?: ExtensionOpsOwner): Promise<AdminExtensionView>;
|
|
132
|
+
disable(name: string, actor: string | null, actorTokenId?: string, owner?: ExtensionOpsOwner, auditDetail?: Record<string, unknown>): Promise<AdminExtensionView>;
|
|
131
133
|
/**
|
|
132
134
|
* Uninstall: a required bootstrap plugin -> `extension.required`; must be disabled first
|
|
133
135
|
* (otherwise `extension.not_disabled`); deletes the install record
|
|
@@ -136,7 +138,7 @@ export declare class ExtensionAdminOps {
|
|
|
136
138
|
* permission snapshot and the package in the package store are untouched (a reinstall picks them
|
|
137
139
|
* up).
|
|
138
140
|
*/
|
|
139
|
-
uninstall(name: string, actor: string | null, actorTokenId?: string, owner?: ExtensionOpsOwner): Promise<void>;
|
|
141
|
+
uninstall(name: string, actor: string | null, actorTokenId?: string, owner?: ExtensionOpsOwner, auditDetail?: Record<string, unknown>): Promise<void>;
|
|
140
142
|
private writeUninstall;
|
|
141
143
|
private setState;
|
|
142
144
|
private writeState;
|
|
@@ -222,8 +222,10 @@ let ExtensionAdminOps = class ExtensionAdminOps {
|
|
|
222
222
|
return { changed: true, state: row?.desired_state ?? "disabled" };
|
|
223
223
|
}
|
|
224
224
|
/** Enable on the deployment (audit `extension.enabled`); no change when already enabled. Org enablement is unchanged. */
|
|
225
|
-
enable(name, actor, actorTokenId, owner
|
|
226
|
-
|
|
225
|
+
enable(name, actor, actorTokenId, owner,
|
|
226
|
+
/** Merged into the audit detail (a write made through the Platform tool). */
|
|
227
|
+
auditDetail) {
|
|
228
|
+
return this.setState(name, "enabled", actor, actorTokenId, owner, auditDetail);
|
|
227
229
|
}
|
|
228
230
|
/**
|
|
229
231
|
* Disables on the deployment (audit `extension.disabled`); no change when already disabled. Every
|
|
@@ -231,8 +233,8 @@ let ExtensionAdminOps = class ExtensionAdminOps {
|
|
|
231
233
|
* it; the org enablement switch is unchanged and the org page shows it as unavailable. A required
|
|
232
234
|
* bootstrap plugin -> `extension.required`.
|
|
233
235
|
*/
|
|
234
|
-
disable(name, actor, actorTokenId, owner) {
|
|
235
|
-
return this.setState(name, "disabled", actor, actorTokenId, owner);
|
|
236
|
+
disable(name, actor, actorTokenId, owner, auditDetail) {
|
|
237
|
+
return this.setState(name, "disabled", actor, actorTokenId, owner, auditDetail);
|
|
236
238
|
}
|
|
237
239
|
/**
|
|
238
240
|
* Uninstall: a required bootstrap plugin -> `extension.required`; must be disabled first
|
|
@@ -242,11 +244,11 @@ let ExtensionAdminOps = class ExtensionAdminOps {
|
|
|
242
244
|
* permission snapshot and the package in the package store are untouched (a reinstall picks them
|
|
243
245
|
* up).
|
|
244
246
|
*/
|
|
245
|
-
async uninstall(name, actor, actorTokenId, owner) {
|
|
247
|
+
async uninstall(name, actor, actorTokenId, owner, auditDetail) {
|
|
246
248
|
this.assertInstallable(name);
|
|
247
|
-
await this.writeUninstall(name, actor, actorTokenId, owner);
|
|
249
|
+
await this.writeUninstall(name, actor, actorTokenId, owner, auditDetail);
|
|
248
250
|
}
|
|
249
|
-
async writeUninstall(name, actor, actorTokenId, owner) {
|
|
251
|
+
async writeUninstall(name, actor, actorTokenId, owner, auditDetail) {
|
|
250
252
|
const db = this.db;
|
|
251
253
|
await this.authorize(actor, owner);
|
|
252
254
|
const row = await this.lockRow(name);
|
|
@@ -260,19 +262,22 @@ let ExtensionAdminOps = class ExtensionAdminOps {
|
|
|
260
262
|
await db.deleteFrom("extension_installs").where("name", "=", name).execute();
|
|
261
263
|
// 来源条目随安装记录一起删:之后不经目录重新安装时不再受旧条目的策略约束(T26 裁决)
|
|
262
264
|
await db.deleteFrom("extension_catalog_sources").where("plugin", "=", name).execute();
|
|
263
|
-
await this.audit(actor, actorTokenId, "extension.uninstalled", name, row.version, row.sha256,
|
|
265
|
+
await this.audit(actor, actorTokenId, "extension.uninstalled", name, row.version, row.sha256, {
|
|
266
|
+
...ownerDetail(owner),
|
|
267
|
+
...auditDetail,
|
|
268
|
+
});
|
|
264
269
|
afterCommit(() => this.notify(name));
|
|
265
270
|
}
|
|
266
|
-
async setState(name, state, actor, actorTokenId, owner) {
|
|
271
|
+
async setState(name, state, actor, actorTokenId, owner, auditDetail) {
|
|
267
272
|
this.assertInstallable(name);
|
|
268
|
-
const result = await this.writeState(name, state, actor, actorTokenId, owner);
|
|
273
|
+
const result = await this.writeState(name, state, actor, actorTokenId, owner, auditDetail);
|
|
269
274
|
return this.viewAfterCommit(name, {
|
|
270
275
|
version: result.row.version,
|
|
271
276
|
sha256: result.row.sha256,
|
|
272
277
|
state,
|
|
273
278
|
});
|
|
274
279
|
}
|
|
275
|
-
async writeState(name, state, actor, actorTokenId, owner) {
|
|
280
|
+
async writeState(name, state, actor, actorTokenId, owner, auditDetail) {
|
|
276
281
|
const db = this.db;
|
|
277
282
|
await this.authorize(actor, owner);
|
|
278
283
|
const row = await this.lockRow(name);
|
|
@@ -291,7 +296,7 @@ let ExtensionAdminOps = class ExtensionAdminOps {
|
|
|
291
296
|
})
|
|
292
297
|
.where("name", "=", name)
|
|
293
298
|
.execute();
|
|
294
|
-
await this.audit(actor, actorTokenId, state === "enabled" ? "extension.enabled" : "extension.disabled", name, row.version, row.sha256, ownerDetail(owner));
|
|
299
|
+
await this.audit(actor, actorTokenId, state === "enabled" ? "extension.enabled" : "extension.disabled", name, row.version, row.sha256, { ...ownerDetail(owner), ...auditDetail });
|
|
295
300
|
afterCommit(() => this.notify(name));
|
|
296
301
|
return { row, changed: true };
|
|
297
302
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { core } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* 插件部署配置(校验后)中非密钥部分的摘要:先把 schema 里所有 secret 叶子(`configFields` 可达路径,
|
|
4
|
+
* 加载时 `assertSecretsReachable` 已保证密钥都在这些路径上)换成固定占位值,再取 sha256(键排序 JSON) 前 16 位十六进制。
|
|
5
|
+
* 给需要「配置变了就失效」的缓存键用(如模型列表)。密钥不参与摘要:不加盐的短摘要写进 Redis 键名后,
|
|
6
|
+
* 低熵密钥可被离线猜测、泄露的密钥可被确认;代价是轮换密钥不会让缓存失效(缓存内容本来就不该依赖密钥)。
|
|
7
|
+
* 没有部署配置 schema 时无从得知哪些是密钥,摘要不按配置区分。同一份配置在各副本上得到同一摘要。
|
|
8
|
+
* 函数自己按 schema 遮蔽,调用方不必(也不能忘记)先打码。
|
|
9
|
+
*/
|
|
10
|
+
export declare function deploymentConfigHash(schema: core.$ZodType | undefined, config: unknown): string;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { configFields, getPath, setPath } from "../config/fields.js";
|
|
3
|
+
/** 键排序后的 JSON(对象键顺序不影响结果);undefined 字段与 JSON.stringify 一样省略。 */
|
|
4
|
+
const canonicalJson = (v) => {
|
|
5
|
+
if (Array.isArray(v))
|
|
6
|
+
return `[${v.map((x) => (x === undefined ? "null" : canonicalJson(x))).join(",")}]`;
|
|
7
|
+
if (v !== null && typeof v === "object") {
|
|
8
|
+
const entries = Object.entries(v)
|
|
9
|
+
.filter(([, x]) => x !== undefined)
|
|
10
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
11
|
+
return `{${entries.map(([k, x]) => `${JSON.stringify(k)}:${canonicalJson(x)}`).join(",")}}`;
|
|
12
|
+
}
|
|
13
|
+
return JSON.stringify(v) ?? "null";
|
|
14
|
+
};
|
|
15
|
+
/** 遮蔽 secret 字段后参与摘要的固定占位值。 */
|
|
16
|
+
const SECRET_PLACEHOLDER = "<secret>";
|
|
17
|
+
/**
|
|
18
|
+
* 插件部署配置(校验后)中非密钥部分的摘要:先把 schema 里所有 secret 叶子(`configFields` 可达路径,
|
|
19
|
+
* 加载时 `assertSecretsReachable` 已保证密钥都在这些路径上)换成固定占位值,再取 sha256(键排序 JSON) 前 16 位十六进制。
|
|
20
|
+
* 给需要「配置变了就失效」的缓存键用(如模型列表)。密钥不参与摘要:不加盐的短摘要写进 Redis 键名后,
|
|
21
|
+
* 低熵密钥可被离线猜测、泄露的密钥可被确认;代价是轮换密钥不会让缓存失效(缓存内容本来就不该依赖密钥)。
|
|
22
|
+
* 没有部署配置 schema 时无从得知哪些是密钥,摘要不按配置区分。同一份配置在各副本上得到同一摘要。
|
|
23
|
+
* 函数自己按 schema 遮蔽,调用方不必(也不能忘记)先打码。
|
|
24
|
+
*/
|
|
25
|
+
export function deploymentConfigHash(schema, config) {
|
|
26
|
+
let redacted = null;
|
|
27
|
+
if (schema) {
|
|
28
|
+
redacted = structuredClone(config);
|
|
29
|
+
if (redacted !== null && typeof redacted === "object") {
|
|
30
|
+
for (const f of configFields(schema)) {
|
|
31
|
+
if (f.meta?.secret && getPath(redacted, f.path) !== undefined) {
|
|
32
|
+
setPath(redacted, f.path, SECRET_PLACEHOLDER);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return createHash("sha256").update(canonicalJson(redacted)).digest("hex").slice(0, 16);
|
|
38
|
+
}
|
|
@@ -59,7 +59,7 @@ export interface SecretEntry {
|
|
|
59
59
|
value?: string | null | undefined;
|
|
60
60
|
renameFrom?: string | undefined;
|
|
61
61
|
}
|
|
62
|
-
/** The response of `GET / PUT /api/v1/admin/extensions/:name/config`. */
|
|
62
|
+
/** The response of `GET / PUT / DELETE /api/v1/admin/extensions/:name/config`. */
|
|
63
63
|
export interface DeploymentConfigView {
|
|
64
64
|
plugin: string;
|
|
65
65
|
/** The plugin's display name (`ExtensionDisplayNames`); null when it has none. */
|
|
@@ -159,6 +159,21 @@ export declare class ExtensionDeploymentConfigService {
|
|
|
159
159
|
* applies it on this replica right away.
|
|
160
160
|
*/
|
|
161
161
|
put(plugin: string, values: Record<string, unknown>, actor: string, actorTokenId?: string, secretEntries?: readonly SecretEntry[]): Promise<DeploymentConfigView>;
|
|
162
|
+
/**
|
|
163
|
+
* Clears the deployment config stored in PG: the `extension_deployment_configs` row and every
|
|
164
|
+
* secret stored for the extension (any path, also ones an older version declared). Fields from
|
|
165
|
+
* the startup config (file / Nacos / env) are untouched and stay in effect (they stay
|
|
166
|
+
* `readonly` in the view; only the startup config changes them). Unknown to the deployment ->
|
|
167
|
+
* `extension.not_found`.
|
|
168
|
+
* In a transaction: `lockAndAuthorize` (re-checks the super admin under the lock), the advisory
|
|
169
|
+
* lock per extension, audit `extension.config_cleared` (detail `clearedPaths`: the stored field
|
|
170
|
+
* paths, never values; nothing stored -> no audit, no publish). After the commit publishes
|
|
171
|
+
* {@link PLUGIN_DEPLOYMENT_CONFIG_TOPIC} and applies it on this replica: every replica re-reads,
|
|
172
|
+
* and the extension loads from what remains, or is unloaded and becomes pending configuration
|
|
173
|
+
* when that is missing or invalid (`ExtensionHost.applyDeploymentConfig`), without a restart.
|
|
174
|
+
*/
|
|
175
|
+
clear(plugin: string, actor: string, actorTokenId?: string): Promise<DeploymentConfigView>;
|
|
176
|
+
private clearStored;
|
|
162
177
|
/**
|
|
163
178
|
* Secret entries name a secret record field some hint names (else 400 `validation_failed`, also
|
|
164
179
|
* for a path given in `values` too, an entry with neither `value` nor `renameFrom`, or a key
|
|
@@ -16,6 +16,7 @@ import { ApiError } from "../errors.js";
|
|
|
16
16
|
import { audit } from "../identity/audit.js";
|
|
17
17
|
import { SuperAdminLock } from "../identity/super-admin.js";
|
|
18
18
|
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
19
|
+
import { afterCommit } from "../infra/database/after-commit.js";
|
|
19
20
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
20
21
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
21
22
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
@@ -193,6 +194,85 @@ let ExtensionDeploymentConfigService = class ExtensionDeploymentConfigService {
|
|
|
193
194
|
}
|
|
194
195
|
return this.render(plugin, info, stored, await this.displayNames.get(plugin));
|
|
195
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Clears the deployment config stored in PG: the `extension_deployment_configs` row and every
|
|
199
|
+
* secret stored for the extension (any path, also ones an older version declared). Fields from
|
|
200
|
+
* the startup config (file / Nacos / env) are untouched and stay in effect (they stay
|
|
201
|
+
* `readonly` in the view; only the startup config changes them). Unknown to the deployment ->
|
|
202
|
+
* `extension.not_found`.
|
|
203
|
+
* In a transaction: `lockAndAuthorize` (re-checks the super admin under the lock), the advisory
|
|
204
|
+
* lock per extension, audit `extension.config_cleared` (detail `clearedPaths`: the stored field
|
|
205
|
+
* paths, never values; nothing stored -> no audit, no publish). After the commit publishes
|
|
206
|
+
* {@link PLUGIN_DEPLOYMENT_CONFIG_TOPIC} and applies it on this replica: every replica re-reads,
|
|
207
|
+
* and the extension loads from what remains, or is unloaded and becomes pending configuration
|
|
208
|
+
* when that is missing or invalid (`ExtensionHost.applyDeploymentConfig`), without a restart.
|
|
209
|
+
*/
|
|
210
|
+
async clear(plugin, actor, actorTokenId) {
|
|
211
|
+
const info = await this.info(plugin);
|
|
212
|
+
await this.clearStored(plugin, info.fields.map((f) => f.path), actor, actorTokenId);
|
|
213
|
+
return this.render(plugin, info, {}, await this.displayNames.get(plugin));
|
|
214
|
+
}
|
|
215
|
+
async clearStored(plugin, fieldPaths, actor, actorTokenId) {
|
|
216
|
+
const t = this.db;
|
|
217
|
+
await this.adminLock.lockAndAuthorize(actor);
|
|
218
|
+
await this.configLock.lock(plugin);
|
|
219
|
+
const row = await t
|
|
220
|
+
.selectFrom("extension_deployment_configs")
|
|
221
|
+
.select("config")
|
|
222
|
+
.where("plugin", "=", plugin)
|
|
223
|
+
.forUpdate()
|
|
224
|
+
.executeTakeFirst();
|
|
225
|
+
const prefix = secretKey(plugin, "");
|
|
226
|
+
const secretKeys = (await t
|
|
227
|
+
.selectFrom("secrets")
|
|
228
|
+
.select("key")
|
|
229
|
+
.where("namespace", "=", SECRETS_NAMESPACE)
|
|
230
|
+
.where("org_id", "=", DEPLOYMENT_SECRETS_ORG)
|
|
231
|
+
.execute())
|
|
232
|
+
.map((r) => r.key)
|
|
233
|
+
.filter((k) => k.startsWith(prefix));
|
|
234
|
+
if (row === undefined && secretKeys.length === 0)
|
|
235
|
+
return;
|
|
236
|
+
if (secretKeys.length > 0) {
|
|
237
|
+
await t
|
|
238
|
+
.deleteFrom("secrets")
|
|
239
|
+
.where("namespace", "=", SECRETS_NAMESPACE)
|
|
240
|
+
.where("org_id", "=", DEPLOYMENT_SECRETS_ORG)
|
|
241
|
+
.where("key", "in", secretKeys)
|
|
242
|
+
.execute();
|
|
243
|
+
}
|
|
244
|
+
await t.deleteFrom("extension_deployment_configs").where("plugin", "=", plugin).execute();
|
|
245
|
+
const clearedPaths = [
|
|
246
|
+
...new Set([
|
|
247
|
+
...fieldPaths.filter((p) => getPath(row?.config ?? {}, p) !== undefined),
|
|
248
|
+
...secretKeys.map((k) => k.slice(prefix.length)),
|
|
249
|
+
]),
|
|
250
|
+
].sort();
|
|
251
|
+
await audit(t, {
|
|
252
|
+
actorAccountId: actor,
|
|
253
|
+
...(actorTokenId !== undefined && { actorTokenId }),
|
|
254
|
+
action: "extension.config_cleared",
|
|
255
|
+
target: plugin,
|
|
256
|
+
detail: { clearedPaths },
|
|
257
|
+
});
|
|
258
|
+
afterCommit(async () => {
|
|
259
|
+
try {
|
|
260
|
+
await this.bus.publish(PLUGIN_DEPLOYMENT_CONFIG_TOPIC, { plugin });
|
|
261
|
+
}
|
|
262
|
+
catch (err) {
|
|
263
|
+
this.log.warn("cannot publish plugin-deployment-config after clearing", { plugin, err });
|
|
264
|
+
}
|
|
265
|
+
try {
|
|
266
|
+
await this.lifecycle.applyConfig(plugin);
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
this.log.error("applying the cleared plugin deployment config on this replica failed", {
|
|
270
|
+
plugin,
|
|
271
|
+
err,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
}
|
|
196
276
|
/**
|
|
197
277
|
* Secret entries name a secret record field some hint names (else 400 `validation_failed`, also
|
|
198
278
|
* for a path given in `values` too, an entry with neither `value` nor `renameFrom`, or a key
|
|
@@ -405,6 +485,9 @@ __decorate([
|
|
|
405
485
|
accessMode: "read only",
|
|
406
486
|
})
|
|
407
487
|
], ExtensionDeploymentConfigService.prototype, "readStored", null);
|
|
488
|
+
__decorate([
|
|
489
|
+
Transactional()
|
|
490
|
+
], ExtensionDeploymentConfigService.prototype, "clearStored", null);
|
|
408
491
|
__decorate([
|
|
409
492
|
Transactional()
|
|
410
493
|
], ExtensionDeploymentConfigService.prototype, "write", null);
|
|
@@ -6,19 +6,16 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { Module } from "@nestjs/common";
|
|
8
8
|
import { SuperAdminLockModule } from "../identity/super-admin.js";
|
|
9
|
+
import { ModelsModule } from "../models/models.module.js";
|
|
9
10
|
import { OrgLockModule } from "../orgs/org-lock.js";
|
|
10
11
|
import { StorageModule } from "../storage/storage.module.js";
|
|
11
12
|
import { EmbedTokensModule } from "../ui/embed-token.js";
|
|
12
13
|
import { ExtensionAdminOps } from "./admin-ops.js";
|
|
13
14
|
import { ExtensionAdmin } from "./admin-view.js";
|
|
14
|
-
import { ExtensionApprovals } from "./approvals.js";
|
|
15
|
-
import { ExtensionBlobs } from "./blobs.js";
|
|
16
15
|
import { BootstrapService } from "./bootstrap.js";
|
|
17
16
|
import { ExtensionDeploymentConfigService } from "./deployment-config.js";
|
|
18
17
|
import { ExtensionDisplayNames } from "./display-name.js";
|
|
19
|
-
import { EffectiveConfigs } from "./effective-config.js";
|
|
20
18
|
import { ExtensionHost } from "./host.js";
|
|
21
|
-
import { ExtensionInstalls } from "./installs.js";
|
|
22
19
|
import { ExtensionLifecycle } from "./lifecycle.js";
|
|
23
20
|
import { PluginApproveLock, PluginDeploymentConfigLock, PluginInstallLock } from "./locks.js";
|
|
24
21
|
import { OrgExtensionConfigs } from "./org-config.js";
|
|
@@ -26,6 +23,8 @@ import { OrgOverrides } from "./org-overrides.js";
|
|
|
26
23
|
import { ExtensionPointDefaults } from "./point-defaults.js";
|
|
27
24
|
import { ExtensionRegistryModule } from "./registry.js";
|
|
28
25
|
import { ReplicaStatusStore } from "./sources.js";
|
|
26
|
+
import { ExtensionStateModule } from "./state.module.js";
|
|
27
|
+
import { ExtensionAvailability } from "./unavailable.js";
|
|
29
28
|
/**
|
|
30
29
|
* The extensions domain: the extension host (it builds each `ctx` from the injected kernel
|
|
31
30
|
* services), the package store and install records (the desired state the host converges to, one
|
|
@@ -43,14 +42,14 @@ ExtensionsModule = __decorate([
|
|
|
43
42
|
StorageModule,
|
|
44
43
|
// ctx.ui verifies embed tokens with the one provider the UI routes issue them with
|
|
45
44
|
EmbedTokensModule,
|
|
45
|
+
ExtensionStateModule,
|
|
46
|
+
// ctx.models: the embeddings broker (models domain, below the host through ExtensionStateModule)
|
|
47
|
+
ModelsModule,
|
|
46
48
|
],
|
|
47
49
|
providers: [
|
|
48
50
|
PluginInstallLock,
|
|
49
51
|
PluginApproveLock,
|
|
50
52
|
PluginDeploymentConfigLock,
|
|
51
|
-
ExtensionApprovals,
|
|
52
|
-
ExtensionBlobs,
|
|
53
|
-
ExtensionInstalls,
|
|
54
53
|
ReplicaStatusStore,
|
|
55
54
|
ExtensionHost,
|
|
56
55
|
ExtensionLifecycle,
|
|
@@ -58,19 +57,17 @@ ExtensionsModule = __decorate([
|
|
|
58
57
|
ExtensionAdminOps,
|
|
59
58
|
ExtensionDisplayNames,
|
|
60
59
|
ExtensionDeploymentConfigService,
|
|
61
|
-
EffectiveConfigs,
|
|
62
60
|
OrgExtensionConfigs,
|
|
63
61
|
OrgOverrides,
|
|
64
62
|
ExtensionPointDefaults,
|
|
65
63
|
BootstrapService,
|
|
64
|
+
ExtensionAvailability,
|
|
66
65
|
],
|
|
67
66
|
exports: [
|
|
68
67
|
ExtensionRegistryModule,
|
|
68
|
+
ExtensionStateModule,
|
|
69
69
|
PluginInstallLock,
|
|
70
70
|
PluginApproveLock,
|
|
71
|
-
ExtensionApprovals,
|
|
72
|
-
ExtensionBlobs,
|
|
73
|
-
ExtensionInstalls,
|
|
74
71
|
ReplicaStatusStore,
|
|
75
72
|
ExtensionHost,
|
|
76
73
|
ExtensionLifecycle,
|
|
@@ -78,11 +75,11 @@ ExtensionsModule = __decorate([
|
|
|
78
75
|
ExtensionAdminOps,
|
|
79
76
|
ExtensionDisplayNames,
|
|
80
77
|
ExtensionDeploymentConfigService,
|
|
81
|
-
EffectiveConfigs,
|
|
82
78
|
OrgExtensionConfigs,
|
|
83
79
|
OrgOverrides,
|
|
84
80
|
ExtensionPointDefaults,
|
|
85
81
|
BootstrapService,
|
|
82
|
+
ExtensionAvailability,
|
|
86
83
|
],
|
|
87
84
|
})
|
|
88
85
|
], ExtensionsModule);
|