@capybara-hq/kernel 0.1.0-rc.6 → 0.1.0-rc.8
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 +8 -72
- package/dist/admin/admin.controller.js +21 -46
- 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 +13 -5
- package/dist/agents/agents.service.js +67 -13
- 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 +20 -3
- package/dist/agents/models.controller.d.ts +1 -2
- package/dist/agents/models.controller.js +1 -1
- 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/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/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 +9 -1
- package/dist/conversations/conversations.service.js +23 -18
- 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/db/kernel-schema.d.ts +20 -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 +3 -0
- package/dist/errors.js +3 -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 +13 -0
- package/dist/evals/runs.controller.d.ts +2 -57
- package/dist/evals/runs.controller.js +1 -42
- package/dist/evals/runs.service.d.ts +6 -6
- package/dist/evals/runs.service.js +32 -18
- 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/extensions/admin-ops.d.ts +5 -3
- package/dist/extensions/admin-ops.js +17 -12
- package/dist/extensions/deployment-config.d.ts +16 -1
- package/dist/extensions/deployment-config.js +83 -0
- package/dist/extensions/extensions.module.js +3 -0
- package/dist/extensions/host.d.ts +33 -2
- package/dist/extensions/host.js +107 -1
- 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/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 +2 -0
- 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 +12 -0
- package/dist/identity/me.controller.js +31 -1
- package/dist/identity/me.schemas.d.ts +14 -0
- package/dist/identity/me.schemas.js +17 -0
- 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/lifecycle/kernel-lifecycle.js +4 -0
- package/dist/models/enablement.d.ts +2 -0
- package/dist/models/enablement.js +1 -0
- 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 +12 -2
- package/dist/models/purposes.js +22 -8
- 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 +58 -849
- package/dist/platform/method.js +1 -1
- package/dist/platform/operation.d.ts +82 -5
- package/dist/platform/operation.js +63 -8
- 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 +11 -6
- package/dist/platform/ops/platform.ops.js +73 -27
- 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 +63 -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/model-call.js +2 -1
- package/dist/runtime/providers.js +8 -1
- 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 +5 -0
- package/dist/runtime/run-worker.js +31 -6
- package/dist/runtime/runtime.module.js +2 -0
- package/dist/runtime/subagents/definition.d.ts +15 -15
- package/dist/runtime/subagents/definition.js +46 -115
- 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 +3 -1
- package/dist/tools/registry.d.ts +48 -51
- package/dist/tools/registry.js +222 -233
- package/package.json +3 -3
- 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
|
@@ -8,42 +8,12 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
10
|
import { Controller, Delete, Get, HttpCode, Inject, Param, Patch, Post } from "@nestjs/common";
|
|
11
|
-
import { z } from "zod";
|
|
12
11
|
import { CurrentPrincipal, patTokenId, requireUser, } from "../identity/principal.js";
|
|
13
12
|
import { createZodDto } from "../infra/validation/create-zod-dto.js";
|
|
14
13
|
import { ZBody } from "../infra/validation/zod-params.js";
|
|
15
14
|
import { CurrentOrg, OrgAction } from "../orgs/org.guard.js";
|
|
15
|
+
import { EvalAddCaseBody as AddCaseBody, EvalSetCreateBody as CreateBody, EvalSetPatchBody as PatchBody, EvalSampleBody as SampleBody, } from "./evals.schemas.js";
|
|
16
16
|
import { EvalSetsService, } from "./sets.service.js";
|
|
17
|
-
const NAME = z.string().trim().min(1).max(200);
|
|
18
|
-
const DESCRIPTION = z.string().max(2000);
|
|
19
|
-
const RUBRIC = z.string().min(1).max(20_000);
|
|
20
|
-
const CreateBody = z
|
|
21
|
-
.object({
|
|
22
|
-
agentId: z.string().min(1).max(100),
|
|
23
|
-
name: NAME,
|
|
24
|
-
description: DESCRIPTION.optional(),
|
|
25
|
-
rubric: RUBRIC.optional(),
|
|
26
|
-
})
|
|
27
|
-
.strict();
|
|
28
|
-
const PatchBody = z
|
|
29
|
-
.object({
|
|
30
|
-
name: NAME.optional(),
|
|
31
|
-
description: DESCRIPTION.optional(),
|
|
32
|
-
rubric: RUBRIC.nullable().optional(),
|
|
33
|
-
})
|
|
34
|
-
.strict();
|
|
35
|
-
const AddCaseBody = z
|
|
36
|
-
.object({ conversationId: z.string().min(1).max(100), runId: z.string().min(1).max(100) })
|
|
37
|
-
.strict();
|
|
38
|
-
const SampleBody = z
|
|
39
|
-
.object({
|
|
40
|
-
from: z.iso.datetime({ offset: true }).optional(),
|
|
41
|
-
to: z.iso.datetime({ offset: true }).optional(),
|
|
42
|
-
count: z.number().int().min(1).max(50),
|
|
43
|
-
status: z.enum(["completed", "failed", "any"]).optional(),
|
|
44
|
-
minToolCalls: z.number().int().min(0).max(1000).optional(),
|
|
45
|
-
})
|
|
46
|
-
.strict();
|
|
47
17
|
class CreateBodyDto extends createZodDto(CreateBody, "EvalSetCreateBody") {
|
|
48
18
|
}
|
|
49
19
|
class PatchBodyDto extends createZodDto(PatchBody, "EvalSetPatchBody") {
|
|
@@ -91,19 +91,19 @@ export declare class EvalSetsService {
|
|
|
91
91
|
name: string;
|
|
92
92
|
description?: string;
|
|
93
93
|
rubric?: string;
|
|
94
|
-
}, actorTokenId?: string): Promise<EvalSetView>;
|
|
94
|
+
}, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<EvalSetView>;
|
|
95
95
|
list(orgId: string): Promise<EvalSetView[]>;
|
|
96
96
|
get(orgId: string, setId: string): Promise<EvalSetDetail>;
|
|
97
97
|
update(orgId: string, actor: string, setId: string, patch: {
|
|
98
98
|
name?: string;
|
|
99
99
|
description?: string;
|
|
100
100
|
rubric?: string | null;
|
|
101
|
-
}, actorTokenId?: string): Promise<EvalSetView>;
|
|
101
|
+
}, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<EvalSetView>;
|
|
102
102
|
/**
|
|
103
103
|
* 删除评测集(Ruling S1-a):集合行软删除,留作审计存根;用例(含快照)硬删,结果随之级联删除,不留复制来的对话内容;
|
|
104
104
|
* 在执行的运行取消,运行行保留(无入口)。
|
|
105
105
|
*/
|
|
106
|
-
remove(orgId: string, actor: string, setId: string, actorTokenId?: string): Promise<void>;
|
|
106
|
+
remove(orgId: string, actor: string, setId: string, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<void>;
|
|
107
107
|
private createIn;
|
|
108
108
|
private updateIn;
|
|
109
109
|
private removeIn;
|
|
@@ -125,20 +125,20 @@ export declare class EvalSetsService {
|
|
|
125
125
|
addCase(orgId: string, actor: string, setId: string, input: {
|
|
126
126
|
conversationId: string;
|
|
127
127
|
runId: string;
|
|
128
|
-
}, actorTokenId?: string): Promise<EvalCaseView>;
|
|
128
|
+
}, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<EvalCaseView>;
|
|
129
129
|
/**
|
|
130
130
|
* 抽样:从该 agent 的 chat 对话里随机取(`ORDER BY random()`)已终态、尚不在集合里的运行,至多
|
|
131
131
|
* `min(count, 剩余容量)` 个,逐个取快照写入。快照超大(或其间被删除 / 写入时已满 / 并发加入)的计入 `skipped`。
|
|
132
132
|
* 集合已满 → `eval.too_many_cases`。逐个写入,内存里一次只有一份快照。
|
|
133
133
|
*/
|
|
134
|
-
sample(orgId: string, actor: string, setId: string, input: SampleInput, actorTokenId?: string): Promise<{
|
|
134
|
+
sample(orgId: string, actor: string, setId: string, input: SampleInput, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<{
|
|
135
135
|
added: number;
|
|
136
136
|
skipped: number;
|
|
137
137
|
}>;
|
|
138
|
-
removeCase(orgId: string, actor: string, setId: string, caseId: string, actorTokenId?: string): Promise<void>;
|
|
138
|
+
removeCase(orgId: string, actor: string, setId: string, caseId: string, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<void>;
|
|
139
139
|
/**
|
|
140
140
|
* 用例详情:由快照还原轨迹(原对话删除后照常可读)。快照即对话内容,每次查看写审计 `trajectory.viewed`
|
|
141
141
|
* (target = 原对话 id,detail 带 `caseId` / `setId`)。
|
|
142
142
|
*/
|
|
143
|
-
getCase(orgId: string, actor: string, setId: string, caseId: string, actorTokenId?: string): Promise<EvalCaseDetail>;
|
|
143
|
+
getCase(orgId: string, actor: string, setId: string, caseId: string, actorTokenId?: string, auditDetail?: Record<string, unknown>): Promise<EvalCaseDetail>;
|
|
144
144
|
}
|
|
@@ -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,
|
|
@@ -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
|
}
|
|
@@ -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);
|
|
@@ -24,6 +24,7 @@ import { ExtensionPointDefaults } from "./point-defaults.js";
|
|
|
24
24
|
import { ExtensionRegistryModule } from "./registry.js";
|
|
25
25
|
import { ReplicaStatusStore } from "./sources.js";
|
|
26
26
|
import { ExtensionStateModule } from "./state.module.js";
|
|
27
|
+
import { ExtensionAvailability } from "./unavailable.js";
|
|
27
28
|
/**
|
|
28
29
|
* The extensions domain: the extension host (it builds each `ctx` from the injected kernel
|
|
29
30
|
* services), the package store and install records (the desired state the host converges to, one
|
|
@@ -60,6 +61,7 @@ ExtensionsModule = __decorate([
|
|
|
60
61
|
OrgOverrides,
|
|
61
62
|
ExtensionPointDefaults,
|
|
62
63
|
BootstrapService,
|
|
64
|
+
ExtensionAvailability,
|
|
63
65
|
],
|
|
64
66
|
exports: [
|
|
65
67
|
ExtensionRegistryModule,
|
|
@@ -77,6 +79,7 @@ ExtensionsModule = __decorate([
|
|
|
77
79
|
OrgOverrides,
|
|
78
80
|
ExtensionPointDefaults,
|
|
79
81
|
BootstrapService,
|
|
82
|
+
ExtensionAvailability,
|
|
80
83
|
],
|
|
81
84
|
})
|
|
82
85
|
], ExtensionsModule);
|
|
@@ -179,6 +179,11 @@ export declare class ExtensionHost {
|
|
|
179
179
|
* 安装记录不在这里:每次 converge 都按 PG 期望状态重新判定。
|
|
180
180
|
*/
|
|
181
181
|
private readonly pendingActivations;
|
|
182
|
+
/**
|
|
183
|
+
* The load parameters of each config-declared extension that loaded: when its deployment config
|
|
184
|
+
* is cleared and the rest is invalid it goes back to {@link pendingActivations} (pending config).
|
|
185
|
+
*/
|
|
186
|
+
private readonly declaredActivations;
|
|
182
187
|
/** 安装记录准备好的候选(按插件名;sha 变了就作废)。 */
|
|
183
188
|
private readonly prepared;
|
|
184
189
|
/** 闸门放行后导入过的安装记录真实清单(按插件名;部署配置 schema 用,含待配置而未加载的)。 */
|
|
@@ -516,12 +521,38 @@ export declare class ExtensionHost {
|
|
|
516
521
|
/**
|
|
517
522
|
* 部署配置保存后(`kernel.plugin-deployment-config`)本副本重读并校验(C10;与 unload / reload 串行):
|
|
518
523
|
* - 插件没在本副本生效 → `not_loaded`(配置声明的刷新后台的合法性判定;待配置的由 reconcile 加载);
|
|
519
|
-
* - 不合法 → `invalid
|
|
524
|
+
* - 不合法 → `invalid`:保持当前值,告警;但 PG 里已没有保存的配置(超级管理员清空了,`DELETE
|
|
525
|
+
* /api/v1/admin/extensions/:name/config`)、剩下的来源(启动配置、默认值)又不够时 → `unloaded`:卸下实例、
|
|
526
|
+
* 记为待配置(pending / config),依赖方连锁;重新配好后由 reconcile 加载;
|
|
520
527
|
* - 没变 → `unchanged`;只改了 hot 字段 → `hot`:就地替换,插件经 `ctx.config` 读到新值,不重新 setup;
|
|
521
528
|
* - 改了非 hot 字段 → `reload`:用新配置重新加载实例(先新后旧,排空在途调用),依赖方连锁;
|
|
522
529
|
* 重新加载失败旧实例保留(`reload_failed`,记 error)。
|
|
523
530
|
*/
|
|
524
|
-
applyDeploymentConfig(plugin: string): Promise<"not_loaded" | "invalid" | "unchanged" | "hot" | "reload" | "reload_failed">;
|
|
531
|
+
applyDeploymentConfig(plugin: string): Promise<"not_loaded" | "invalid" | "unloaded" | "unchanged" | "hot" | "reload" | "reload_failed">;
|
|
532
|
+
/** PG holds no deployment config for the plugin (it was cleared); a read error counts as no. */
|
|
533
|
+
private clearedInPg;
|
|
534
|
+
/**
|
|
535
|
+
* Unloads an extension whose deployment config was cleared and is now missing or invalid (in
|
|
536
|
+
* the host's serial queue): drains it, records pending / config (a config-declared one goes back
|
|
537
|
+
* to {@link pendingActivations}; an install record is decided again on every converge) and
|
|
538
|
+
* cascades to its dependents. It loads again without a restart once it is configured.
|
|
539
|
+
*/
|
|
540
|
+
private unloadForMissingConfig;
|
|
541
|
+
/**
|
|
542
|
+
* Records an extension that is not loaded as pending configuration: a config-declared one goes
|
|
543
|
+
* back to {@link pendingActivations} (a later save loads it); an install record is decided again
|
|
544
|
+
* on every converge.
|
|
545
|
+
*/
|
|
546
|
+
private markPendingConfig;
|
|
547
|
+
/**
|
|
548
|
+
* Before an extension unloaded for a dependency comes back ({@link cascade}): re-reads its
|
|
549
|
+
* deployment config, which may have been saved or cleared while it was down (applyDeploymentConfig
|
|
550
|
+
* only records validity then), and refreshes its load parameters, so it never returns on a stale
|
|
551
|
+
* config or revoked secrets. Returns false when the config is now missing or invalid and PG holds
|
|
552
|
+
* none: the extension is left pending configuration instead. A read error, or an invalid config
|
|
553
|
+
* that is still stored, keeps the previous config (as for a loaded extension).
|
|
554
|
+
*/
|
|
555
|
+
private refreshConfigForRestore;
|
|
525
556
|
/** 本次未加载、等待批准权限的插件(含因 `requires` 只能由它们满足而未加载的插件),按依赖拓扑序。 */
|
|
526
557
|
pending(): PendingExtension[];
|
|
527
558
|
/** 已加载插件的清单(按加载顺序,即依赖拓扑序)。 */
|