@capybara-hq/kernel 0.1.0-rc.22 → 0.1.0-rc.24
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 +25 -25
- package/dist/admin/admin.controller.d.ts +3 -3
- package/dist/admin/admin.controller.js +6 -2
- package/dist/admin/admin.module.d.ts +2 -1
- package/dist/admin/admin.module.js +7 -3
- package/dist/admin/admin.schemas.d.ts +13 -0
- package/dist/admin/outbox-dead.controller.d.ts +23 -0
- package/dist/admin/outbox-dead.controller.js +62 -0
- package/dist/admin/outbox-dead.schemas.d.ts +8 -0
- package/dist/admin/outbox-dead.schemas.js +18 -0
- package/dist/admin/outbox-dead.service.d.ts +66 -0
- package/dist/admin/outbox-dead.service.js +179 -0
- package/dist/admin/overview.service.d.ts +40 -5
- package/dist/admin/overview.service.js +41 -7
- package/dist/agents/from-template.js +1 -1
- package/dist/background/finish.d.ts +5 -2
- package/dist/background/finish.js +14 -3
- package/dist/background/launch.d.ts +44 -5
- package/dist/background/launch.js +92 -9
- package/dist/background/session.d.ts +14 -2
- package/dist/background/session.js +26 -4
- package/dist/background/status.d.ts +1 -1
- package/dist/background/status.js +3 -3
- package/dist/background/stop.d.ts +0 -2
- package/dist/background/stop.js +1 -21
- package/dist/background/store.d.ts +8 -0
- package/dist/background/store.js +24 -0
- package/dist/catalog/admin-catalog.controller.d.ts +21 -2
- package/dist/catalog/admin-catalog.controller.js +45 -6
- package/dist/catalog/admin-catalog.schemas.d.ts +5 -0
- package/dist/catalog/admin-catalog.schemas.js +8 -0
- package/dist/catalog/catalog-content.d.ts +5 -0
- package/dist/catalog/catalog-content.js +1 -0
- package/dist/catalog/catalog.module.d.ts +2 -1
- package/dist/catalog/catalog.module.js +5 -1
- package/dist/catalog/marketplaces.service.d.ts +1 -1
- package/dist/catalog/platform-import-update.d.ts +50 -0
- package/dist/catalog/platform-import-update.js +116 -0
- package/dist/catalog/plugin-import.d.ts +36 -1
- package/dist/catalog/plugin-import.js +23 -1
- package/dist/catalog/plugin-upgrade.d.ts +18 -0
- package/dist/catalog/plugin-upgrade.js +19 -0
- package/dist/catalog/requests.service.js +2 -2
- package/dist/channels/channels.module.d.ts +5 -2
- package/dist/channels/channels.module.js +9 -2
- package/dist/channels/deliver-job.d.ts +25 -0
- package/dist/channels/deliver-job.js +25 -0
- package/dist/channels/inbound.d.ts +1 -1
- package/dist/channels/inbound.js +2 -15
- package/dist/channels/jobs.d.ts +28 -18
- package/dist/channels/jobs.js +63 -26
- package/dist/config/schema.d.ts +3 -6
- package/dist/config/schema.js +20 -27
- package/dist/conversations/agent-tree.d.ts +16 -0
- package/dist/conversations/agent-tree.js +36 -0
- package/dist/conversations/conversations.service.d.ts +44 -14
- package/dist/conversations/conversations.service.js +52 -38
- package/dist/conversations/event-log.d.ts +7 -10
- package/dist/conversations/event-log.js +24 -15
- package/dist/conversations/events.js +2 -1
- package/dist/conversations/queue.service.d.ts +8 -3
- package/dist/conversations/queue.service.js +37 -13
- package/dist/conversations/titles.d.ts +21 -8
- package/dist/conversations/titles.js +42 -15
- package/dist/db/kernel-schema.d.ts +26 -8
- package/dist/devices/devices.service.d.ts +12 -3
- package/dist/devices/devices.service.js +30 -9
- package/dist/errors.d.ts +15 -0
- package/dist/errors.js +15 -0
- package/dist/evals/run-replay.js +14 -8
- package/dist/extensions/extensions.module.js +3 -0
- package/dist/extensions/lifecycle.d.ts +6 -1
- package/dist/extensions/lifecycle.js +9 -2
- package/dist/extensions/usage-subscribers.d.ts +43 -0
- package/dist/extensions/usage-subscribers.js +108 -0
- package/dist/http/api.module.js +2 -0
- package/dist/identity/settings.d.ts +53 -3
- package/dist/identity/settings.js +92 -9
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/infra/cli/kernel-cli.module.js +5 -0
- package/dist/infra/config/kernel-config.service.d.ts +7 -0
- package/dist/infra/config/kernel-config.service.js +20 -0
- package/dist/infra/events/kernel-events.d.ts +9 -35
- package/dist/infra/outbox/outbox-relay.module.d.ts +6 -0
- package/dist/infra/outbox/outbox-relay.module.js +18 -0
- package/dist/infra/outbox/outbox.dispatcher.d.ts +103 -0
- package/dist/infra/outbox/outbox.dispatcher.js +310 -0
- package/dist/infra/outbox/outbox.module.d.ts +24 -0
- package/dist/infra/outbox/outbox.module.js +50 -0
- package/dist/infra/outbox/outbox.relay.d.ts +31 -0
- package/dist/infra/outbox/outbox.relay.js +76 -0
- package/dist/infra/outbox/outbox.service.d.ts +51 -0
- package/dist/infra/outbox/outbox.service.js +131 -0
- package/dist/infra/outbox/registry.d.ts +120 -0
- package/dist/infra/outbox/registry.js +108 -0
- package/dist/infra/queue/queue-names.d.ts +8 -0
- package/dist/infra/queue/queue-names.js +16 -0
- package/dist/kernel.module.js +3 -0
- package/dist/local-devices/device-policy.service.d.ts +4 -0
- package/dist/local-devices/device-policy.service.js +61 -3
- package/dist/local-devices/local-device-gateway.d.ts +4 -2
- package/dist/local-devices/local-device-gateway.js +39 -14
- package/dist/local-devices/machines.d.ts +25 -1
- package/dist/local-devices/machines.js +91 -15
- package/dist/local-devices/policy-summary.d.ts +44 -1
- package/dist/local-devices/policy-summary.js +69 -0
- package/dist/models/embeddings.d.ts +9 -9
- package/dist/models/embeddings.js +11 -18
- package/dist/models/models.module.js +3 -0
- package/dist/orgs/orgs.service.js +7 -0
- package/dist/orgs/settings.controller.js +2 -2
- package/dist/orgs/settings.service.d.ts +11 -5
- package/dist/orgs/settings.service.js +28 -14
- package/dist/overrides.d.ts +20 -3
- package/dist/overrides.js +10 -2
- package/dist/platform/exclusions.js +5 -0
- package/dist/platform/ops/admin.ops.js +50 -9
- package/dist/platform/ops/catalog-admin.ops.d.ts +3 -1
- package/dist/platform/ops/catalog-admin.ops.js +32 -4
- package/dist/platform/ops/org-settings.ops.js +3 -3
- package/dist/platform/ops/orgs.ops.js +1 -0
- package/dist/platform/ops/outbox.ops.d.ts +21 -0
- package/dist/platform/ops/outbox.ops.js +125 -0
- package/dist/platform/ops/platform.ops.js +1 -1
- package/dist/platform/ops/schedules.ops.js +40 -1
- package/dist/platform/platform-ops.module.d.ts +2 -1
- package/dist/platform/platform-ops.module.js +3 -0
- package/dist/platform/route-schemas.js +3 -0
- package/dist/roles/worker.module.js +9 -4
- package/dist/runtime/langgraph-loop.js +13 -5
- package/dist/runtime/limits.d.ts +15 -0
- package/dist/runtime/limits.js +25 -0
- package/dist/runtime/loop.d.ts +8 -3
- package/dist/runtime/loop.js +2 -1
- package/dist/runtime/maintenance.d.ts +4 -2
- package/dist/runtime/maintenance.js +17 -2
- package/dist/runtime/model-call.d.ts +14 -16
- package/dist/runtime/model-call.js +14 -24
- package/dist/runtime/queue-lost-jobs.d.ts +24 -0
- package/dist/runtime/queue-lost-jobs.js +51 -0
- package/dist/runtime/run-control.d.ts +42 -5
- package/dist/runtime/run-control.js +66 -12
- package/dist/runtime/run-finish.d.ts +39 -12
- package/dist/runtime/run-finish.js +97 -14
- package/dist/runtime/run-jobs.d.ts +95 -13
- package/dist/runtime/run-jobs.js +199 -28
- package/dist/runtime/run-orphan-check.job.d.ts +142 -0
- package/dist/runtime/run-orphan-check.job.js +339 -0
- package/dist/runtime/run-processors.d.ts +16 -9
- package/dist/runtime/run-processors.js +1 -1
- package/dist/runtime/run-queue.d.ts +64 -55
- package/dist/runtime/run-queue.js +147 -284
- package/dist/runtime/run-steps.d.ts +1 -2
- package/dist/runtime/run-steps.js +8 -11
- package/dist/runtime/run-worker.d.ts +6 -17
- package/dist/runtime/run-worker.js +32 -34
- package/dist/runtime/runtime.module.d.ts +2 -3
- package/dist/runtime/runtime.module.js +5 -6
- package/dist/runtime/step-log.d.ts +16 -4
- package/dist/runtime/step-log.js +26 -6
- package/dist/runtime/stream.controller.d.ts +2 -4
- package/dist/runtime/stream.controller.js +5 -11
- package/dist/runtime/subagents/child.js +1 -1
- package/dist/runtime/subagents/definition.d.ts +2 -1
- package/dist/runtime/subagents/definition.js +4 -2
- package/dist/runtime/subagents/deliveries.d.ts +6 -3
- package/dist/runtime/subagents/deliveries.js +16 -7
- package/dist/runtime/subagents/dispatch.d.ts +12 -12
- package/dist/runtime/subagents/dispatch.js +13 -38
- package/dist/runtime/subagents/messages.d.ts +5 -1
- package/dist/runtime/subagents/messages.js +11 -3
- package/dist/runtime/subagents/skill-fork.d.ts +3 -3
- package/dist/runtime/subagents/skill-fork.js +5 -5
- package/dist/runtime/subagents/subagents.service.js +1 -1
- package/dist/runtime/subagents/tree-jobs.d.ts +61 -0
- package/dist/runtime/subagents/tree-jobs.js +86 -0
- package/dist/runtime/usage-report-jobs.d.ts +23 -48
- package/dist/runtime/usage-report-jobs.js +67 -119
- package/dist/runtime/usage-report.d.ts +28 -77
- package/dist/runtime/usage-report.js +35 -213
- package/dist/runtime/waits.d.ts +48 -198
- package/dist/runtime/waits.js +103 -805
- package/dist/sandbox/platform-tiers.d.ts +86 -0
- package/dist/sandbox/platform-tiers.js +97 -0
- package/dist/sandbox/sandbox.service.d.ts +18 -5
- package/dist/sandbox/sandbox.service.js +75 -20
- package/dist/sandbox/tiers.d.ts +14 -2
- package/dist/sandbox/tiers.js +8 -0
- package/dist/schedules/calendar.d.ts +134 -0
- package/dist/schedules/calendar.js +410 -0
- package/dist/schedules/fire.d.ts +1 -3
- package/dist/schedules/fire.js +5 -10
- package/dist/schedules/run-tracker.d.ts +0 -5
- package/dist/schedules/run-tracker.js +0 -13
- package/dist/schedules/scan.job.js +15 -20
- package/dist/schedules/schedule-math.d.ts +42 -0
- package/dist/schedules/schedule-math.js +52 -0
- package/dist/schedules/scheduled-tasks.service.d.ts +16 -0
- package/dist/schedules/scheduled-tasks.service.js +53 -0
- package/dist/schedules/schedules.controller.d.ts +5 -1
- package/dist/schedules/schedules.controller.js +15 -1
- package/dist/schedules/schedules.schemas.d.ts +35 -0
- package/dist/schedules/schedules.schemas.js +27 -0
- package/dist/schedules/store.d.ts +5 -0
- package/dist/schedules/store.js +20 -0
- package/dist/tools/approvals.service.d.ts +26 -7
- package/dist/tools/approvals.service.js +88 -10
- package/dist/tools/builtin-names.d.ts +5 -3
- package/dist/tools/builtin-names.js +12 -4
- package/dist/tools/builtins/builtin-tools.d.ts +1 -2
- package/dist/tools/builtins/builtin-tools.js +21 -17
- package/dist/tools/builtins/sandbox/bash.js +9 -3
- package/dist/tools/builtins/sandbox/common.d.ts +18 -1
- package/dist/tools/builtins/sandbox/common.js +14 -1
- package/dist/tools/builtins/sandbox/index.d.ts +2 -1
- package/dist/tools/builtins/sandbox/index.js +4 -1
- package/dist/tools/builtins/sandbox/task-list.d.ts +12 -0
- package/dist/tools/builtins/sandbox/task-list.js +130 -0
- package/dist/tools/builtins/sandbox/task-output.d.ts +8 -1
- package/dist/tools/builtins/sandbox/task-output.js +21 -3
- package/dist/tools/builtins/web/extract.d.ts +2 -4
- package/dist/tools/builtins/web/extract.js +2 -5
- package/dist/tools/pipeline.d.ts +1 -1
- package/dist/tools/pipeline.js +1 -1
- package/dist/tools/questions.service.d.ts +15 -6
- package/dist/tools/questions.service.js +20 -8
- package/dist/tools/registry.d.ts +4 -2
- package/dist/tools/registry.js +4 -3
- package/dist/tools/tools.module.js +4 -3
- package/package.json +3 -3
- package/src/migrations/0118_device_policy_ops.sql +6 -0
- package/src/migrations/0119_outbox.sql +22 -0
- package/src/migrations/0120_drop_usage_report_sweep.sql +7 -0
|
@@ -29,7 +29,7 @@ import { readOrgSettings } from "../orgs/settings.service.js";
|
|
|
29
29
|
import { SandboxJobs } from "../sandbox/jobs.js";
|
|
30
30
|
import { isInternalProvider, LOCAL_PROVIDER, SandboxProviders } from "../sandbox/providers.js";
|
|
31
31
|
import { deviceNotFound, SandboxService } from "../sandbox/sandbox.service.js";
|
|
32
|
-
import { effectiveSandboxPolicy } from "../sandbox/tiers.js";
|
|
32
|
+
import { effectiveSandboxPolicy, readDeploymentSandboxPolicy, } from "../sandbox/tiers.js";
|
|
33
33
|
import { unattendedTierOf } from "../schedules/unattended.js";
|
|
34
34
|
import { DeviceAccess, demotedProvider, deviceProvider, deviceUnavailable, inUseForDefault, } from "./access.js";
|
|
35
35
|
/** How many recent sandbox changes a device view lists. */
|
|
@@ -293,7 +293,11 @@ let DevicesService = class DevicesService {
|
|
|
293
293
|
}
|
|
294
294
|
/** The org's sandbox policy for a device choosing `tier` (null: the org's default). */
|
|
295
295
|
async policyFor(orgId, tier) {
|
|
296
|
-
|
|
296
|
+
const [deployment, settings] = await Promise.all([
|
|
297
|
+
readDeploymentSandboxPolicy(this.db.db, this.config),
|
|
298
|
+
readOrgSettings(this.db.db, orgId),
|
|
299
|
+
]);
|
|
300
|
+
return effectiveSandboxPolicy(deployment, settings, tier);
|
|
297
301
|
}
|
|
298
302
|
/**
|
|
299
303
|
* The sandbox level a sandbox call in the device runs at now, for the model (`device_paths`,
|
|
@@ -318,11 +322,12 @@ let DevicesService = class DevicesService {
|
|
|
318
322
|
.executeTakeFirst();
|
|
319
323
|
if (row === undefined)
|
|
320
324
|
return null;
|
|
321
|
-
const [settings, unattended] = await Promise.all([
|
|
325
|
+
const [deployment, settings, unattended] = await Promise.all([
|
|
326
|
+
readDeploymentSandboxPolicy(this.db.db, this.config),
|
|
322
327
|
readOrgSettings(this.db.db, orgId),
|
|
323
328
|
runId === undefined ? null : unattendedTierOf(this.db.db, runId, deviceId),
|
|
324
329
|
]);
|
|
325
|
-
const policyOf = (tier) => effectiveSandboxPolicy(
|
|
330
|
+
const policyOf = (tier) => effectiveSandboxPolicy(deployment, settings, tier);
|
|
326
331
|
const summary = localPolicyOf(row.local_policy);
|
|
327
332
|
const s = sandboxStateOf(policyOf, {
|
|
328
333
|
source: row.source,
|
|
@@ -807,12 +812,13 @@ let DevicesService = class DevicesService {
|
|
|
807
812
|
const demotedProviders = [
|
|
808
813
|
...new Set(rows.flatMap((r) => (demoted.get(r.id) ? [demoted.get(r.id)] : []))),
|
|
809
814
|
];
|
|
810
|
-
const [names, recent, settings] = await Promise.all([
|
|
815
|
+
const [names, recent, settings, deployment] = await Promise.all([
|
|
811
816
|
this.displayNames.many(demotedProviders),
|
|
812
817
|
this.recentSandboxChanges(orgId, rows.map((r) => r.id)),
|
|
813
818
|
readOrgSettings(this.db.db, orgId),
|
|
819
|
+
readDeploymentSandboxPolicy(this.db.db, this.config),
|
|
814
820
|
]);
|
|
815
|
-
const policyOf = (tier) => effectiveSandboxPolicy(
|
|
821
|
+
const policyOf = (tier) => effectiveSandboxPolicy(deployment, settings, tier);
|
|
816
822
|
// each device's limits (a cloud device's own tier) and its instance's pending change
|
|
817
823
|
const perDevice = new Map(await Promise.all(rows.map(async (r) => {
|
|
818
824
|
const policy = policyOf(r.source === "cloud" ? r.tier : null);
|
|
@@ -1049,7 +1055,16 @@ const tierOrNull = (v) => v === "strict" || v === "dev" || v === "open" ? v : nu
|
|
|
1049
1055
|
function sandboxChangeOf(action, at, d, by) {
|
|
1050
1056
|
const hosts = (v) => Array.isArray(v) ? v.filter((h) => typeof h === "string") : [];
|
|
1051
1057
|
const isolation = d.isolation === "sandbox" || d.isolation === "none" ? d.isolation : null;
|
|
1052
|
-
const base = {
|
|
1058
|
+
const base = {
|
|
1059
|
+
at: at.toISOString(),
|
|
1060
|
+
add: [],
|
|
1061
|
+
remove: [],
|
|
1062
|
+
tier: null,
|
|
1063
|
+
isolation: null,
|
|
1064
|
+
localhost: null,
|
|
1065
|
+
remoteGrants: null,
|
|
1066
|
+
by,
|
|
1067
|
+
};
|
|
1053
1068
|
if (action === "device.tier_changed") {
|
|
1054
1069
|
return { ...base, kind: "tier", tier: { to: tierOrNull(d.to) }, via: "web", confirmed: true };
|
|
1055
1070
|
}
|
|
@@ -1062,9 +1077,15 @@ function sandboxChangeOf(action, at, d, by) {
|
|
|
1062
1077
|
add: hosts(d.add),
|
|
1063
1078
|
remove: hosts(d.remove),
|
|
1064
1079
|
// the key is there only when the change set the tier (null: follow the org's default)
|
|
1065
|
-
tier: "tier" in d
|
|
1080
|
+
tier: "tier" in d
|
|
1081
|
+
? { ...("tierFrom" in d && { from: tierOrNull(d.tierFrom) }), to: tierOrNull(d.tier) }
|
|
1082
|
+
: null,
|
|
1066
1083
|
isolation,
|
|
1067
|
-
|
|
1084
|
+
localhost: d.localhost === "on" || d.localhost === "off-proxy-detected" || d.localhost === "off"
|
|
1085
|
+
? d.localhost
|
|
1086
|
+
: null,
|
|
1087
|
+
remoteGrants: d.remoteGrants === "owner" || d.remoteGrants === "off" ? d.remoteGrants : null,
|
|
1088
|
+
via: d.via === "im" ? "im" : d.via === "device" ? "device" : "web",
|
|
1068
1089
|
confirmed: d.confirmed === true,
|
|
1069
1090
|
};
|
|
1070
1091
|
}
|
package/dist/errors.d.ts
CHANGED
|
@@ -36,6 +36,10 @@ export declare const ERROR_CODES: {
|
|
|
36
36
|
readonly "org.owner_required": 403;
|
|
37
37
|
readonly "org.sandbox_egress_not_allowed": 400;
|
|
38
38
|
readonly "org.sandbox_tier_not_allowed": 400;
|
|
39
|
+
/** A deployment setting set in the startup config (file, Nacos or env): read-only in the admin console. */
|
|
40
|
+
readonly "deployment.setting_readonly": 409;
|
|
41
|
+
/** Raising the platform's sandbox tiers through an API token or the Platform tool (only narrowing). */
|
|
42
|
+
readonly "deployment.sandbox_tier_not_allowed": 400;
|
|
39
43
|
readonly "member.not_found": 404;
|
|
40
44
|
readonly "member.already_exists": 409;
|
|
41
45
|
readonly "member.anonymous_guest": 409;
|
|
@@ -221,10 +225,17 @@ export declare const ERROR_CODES: {
|
|
|
221
225
|
readonly "plugin.upgrade_stale": 409;
|
|
222
226
|
readonly "plugin.upgrade_target_invalid": 409;
|
|
223
227
|
readonly "plugin.upgrade_failed": 502;
|
|
228
|
+
/**
|
|
229
|
+
* The platform's import and update imported the version but the update failed: the platform
|
|
230
|
+
* stays on its version, the imported version is in the catalog (retry with the plain update).
|
|
231
|
+
*/
|
|
232
|
+
readonly "plugin.imported_not_updated": 409;
|
|
224
233
|
readonly "setup.already_completed": 409;
|
|
225
234
|
readonly "setup.token_invalid": 403;
|
|
226
235
|
/** The admin overview's seven-day usage aggregate ran past its statement timeout (spec §5.5). */
|
|
227
236
|
readonly "admin.usage_unavailable": 503;
|
|
237
|
+
/** No dead outbox row has this id (delivered, discarded, retried, or never dead). */
|
|
238
|
+
readonly "outbox.not_found": 404;
|
|
228
239
|
readonly "agent.not_found": 404;
|
|
229
240
|
readonly "agent.version_conflict": 409;
|
|
230
241
|
/** The profile was changed since the client read it (`expectedUpdatedAt` is stale). */
|
|
@@ -315,6 +326,10 @@ export declare const ERROR_CODES: {
|
|
|
315
326
|
readonly "attachment.too_many_pending": 429;
|
|
316
327
|
readonly "sandbox.unavailable": 503;
|
|
317
328
|
readonly "sandbox.busy": 409;
|
|
329
|
+
/** A cloud sandbox provider refused the device's tier (its config refuses open egress). */
|
|
330
|
+
readonly "sandbox.tier_refused": 409;
|
|
331
|
+
/** A cloud sandbox provider failed to create a device's sandbox for another reason. */
|
|
332
|
+
readonly "sandbox.create_failed": 502;
|
|
318
333
|
/** A sandbox file path the kernel reads is not absolute or not under the sandbox roots. */
|
|
319
334
|
readonly "sandbox.file_invalid_path": 422;
|
|
320
335
|
/** No file at the sandbox path the kernel reads. */
|
package/dist/errors.js
CHANGED
|
@@ -36,6 +36,10 @@ export const ERROR_CODES = {
|
|
|
36
36
|
"org.owner_required": 403,
|
|
37
37
|
"org.sandbox_egress_not_allowed": 400,
|
|
38
38
|
"org.sandbox_tier_not_allowed": 400,
|
|
39
|
+
/** A deployment setting set in the startup config (file, Nacos or env): read-only in the admin console. */
|
|
40
|
+
"deployment.setting_readonly": 409,
|
|
41
|
+
/** Raising the platform's sandbox tiers through an API token or the Platform tool (only narrowing). */
|
|
42
|
+
"deployment.sandbox_tier_not_allowed": 400,
|
|
39
43
|
"member.not_found": 404,
|
|
40
44
|
"member.already_exists": 409,
|
|
41
45
|
"member.anonymous_guest": 409,
|
|
@@ -221,10 +225,17 @@ export const ERROR_CODES = {
|
|
|
221
225
|
"plugin.upgrade_stale": 409,
|
|
222
226
|
"plugin.upgrade_target_invalid": 409,
|
|
223
227
|
"plugin.upgrade_failed": 502,
|
|
228
|
+
/**
|
|
229
|
+
* The platform's import and update imported the version but the update failed: the platform
|
|
230
|
+
* stays on its version, the imported version is in the catalog (retry with the plain update).
|
|
231
|
+
*/
|
|
232
|
+
"plugin.imported_not_updated": 409,
|
|
224
233
|
"setup.already_completed": 409,
|
|
225
234
|
"setup.token_invalid": 403,
|
|
226
235
|
/** The admin overview's seven-day usage aggregate ran past its statement timeout (spec §5.5). */
|
|
227
236
|
"admin.usage_unavailable": 503,
|
|
237
|
+
/** No dead outbox row has this id (delivered, discarded, retried, or never dead). */
|
|
238
|
+
"outbox.not_found": 404,
|
|
228
239
|
"agent.not_found": 404,
|
|
229
240
|
"agent.version_conflict": 409,
|
|
230
241
|
/** The profile was changed since the client read it (`expectedUpdatedAt` is stale). */
|
|
@@ -315,6 +326,10 @@ export const ERROR_CODES = {
|
|
|
315
326
|
"attachment.too_many_pending": 429,
|
|
316
327
|
"sandbox.unavailable": 503,
|
|
317
328
|
"sandbox.busy": 409,
|
|
329
|
+
/** A cloud sandbox provider refused the device's tier (its config refuses open egress). */
|
|
330
|
+
"sandbox.tier_refused": 409,
|
|
331
|
+
/** A cloud sandbox provider failed to create a device's sandbox for another reason. */
|
|
332
|
+
"sandbox.create_failed": 502,
|
|
318
333
|
/** A sandbox file path the kernel reads is not absolute or not under the sandbox roots. */
|
|
319
334
|
"sandbox.file_invalid_path": 422,
|
|
320
335
|
/** No file at the sandbox path the kernel reads. */
|
package/dist/evals/run-replay.js
CHANGED
|
@@ -19,6 +19,7 @@ import { KernelDb } from "../infra/database/kernel-db.js";
|
|
|
19
19
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
20
20
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
21
21
|
import { estimateTokens } from "../runtime/context/tokens.js";
|
|
22
|
+
import { runDeadline, tightestLimit } from "../runtime/limits.js";
|
|
22
23
|
import { RunError } from "../runtime/model-call.js";
|
|
23
24
|
import { runContextIdemKey } from "../runtime/run-context.service.js";
|
|
24
25
|
import { recordedSkillForks } from "../runtime/subagents/skill-fork.js";
|
|
@@ -526,13 +527,18 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
526
527
|
return out;
|
|
527
528
|
};
|
|
528
529
|
const runtime = d.config.get().runtime;
|
|
529
|
-
|
|
530
|
+
// 0 in the config or the logged child limit = no limit there
|
|
531
|
+
const maxSteps = tightestLimit(subagent?.maxSteps, runtime.maxSteps);
|
|
532
|
+
// `runtime.maxRunSeconds` 0: no deadline and no timer
|
|
533
|
+
const deadline = runDeadline(Date.now(), runtime.maxRunSeconds);
|
|
530
534
|
let deadlineHit = false;
|
|
531
|
-
const timer =
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
535
|
+
const timer = deadline === undefined
|
|
536
|
+
? undefined
|
|
537
|
+
: setTimeout(() => {
|
|
538
|
+
deadlineHit = true;
|
|
539
|
+
stopper.abort();
|
|
540
|
+
}, Math.max(0, deadline - Date.now()));
|
|
541
|
+
timer?.unref();
|
|
536
542
|
// a fork invocation's report is the recorded one: a replay never dispatches a sub-agent (A5)
|
|
537
543
|
const skillForks = recordedSkillForks(eventLog, s.events.filter((e) => e.runId === s.runId));
|
|
538
544
|
const loop = d.loop({ toolPipeline: pipeline, registry, skillForks, ...(media && { media }) });
|
|
@@ -551,8 +557,8 @@ export async function replayRun(d, s, candidate, evalRunId, signal) {
|
|
|
551
557
|
sink: () => { },
|
|
552
558
|
pendingAbsorbable,
|
|
553
559
|
limits: {
|
|
554
|
-
maxSteps
|
|
555
|
-
deadline,
|
|
560
|
+
...(maxSteps !== undefined && { maxSteps }),
|
|
561
|
+
...(deadline !== undefined && { deadline }),
|
|
556
562
|
},
|
|
557
563
|
// replays never fire plugin hooks (the loop deps omit them too, P-18)
|
|
558
564
|
conversationKind: "eval",
|
|
@@ -28,6 +28,7 @@ import { SingleProviderGuard } from "./single-provider.js";
|
|
|
28
28
|
import { ReplicaStatusStore } from "./sources.js";
|
|
29
29
|
import { ExtensionStateModule } from "./state.module.js";
|
|
30
30
|
import { ExtensionAvailability } from "./unavailable.js";
|
|
31
|
+
import { UsageSubscribersModule } from "./usage-subscribers.js";
|
|
31
32
|
/**
|
|
32
33
|
* The extensions domain: the extension host (it builds each `ctx` from the injected kernel
|
|
33
34
|
* services), the package store and install records (the desired state the host converges to, one
|
|
@@ -48,6 +49,8 @@ ExtensionsModule = __decorate([
|
|
|
48
49
|
ExtensionStateModule,
|
|
49
50
|
// ctx.models: the embeddings broker (models domain, below the host through ExtensionStateModule)
|
|
50
51
|
ModelsModule,
|
|
52
|
+
// the lifecycle clears the `usage.report` subscriber cache on PLUGINS_CHANGED
|
|
53
|
+
UsageSubscribersModule,
|
|
51
54
|
],
|
|
52
55
|
providers: [
|
|
53
56
|
PluginInstallLock,
|
|
@@ -7,6 +7,7 @@ import { ExtensionInstalls } from "./installs.js";
|
|
|
7
7
|
import { PLUGINS_CHANGED_TOPIC, PLUGINS_RECONCILE_JOB, PLUGINS_RECONCILE_TOPIC, STALE_RECONCILE_PERIODS } from "./lifecycle-topics.js";
|
|
8
8
|
import { PLUGINS_MIGRATED_TOPIC } from "./migrate-lock.js";
|
|
9
9
|
import { ReplicaStatusStore } from "./sources.js";
|
|
10
|
+
import { UsageSubscribers } from "./usage-subscribers.js";
|
|
10
11
|
export { PLUGINS_CHANGED_TOPIC, PLUGINS_MIGRATED_TOPIC, PLUGINS_RECONCILE_JOB, PLUGINS_RECONCILE_TOPIC, STALE_RECONCILE_PERIODS, };
|
|
11
12
|
/**
|
|
12
13
|
* 每副本一个:把本副本的插件加载状态收敛到 PG 期望状态(C16)。
|
|
@@ -24,6 +25,8 @@ export declare class ExtensionLifecycle {
|
|
|
24
25
|
private readonly installs;
|
|
25
26
|
private readonly config;
|
|
26
27
|
private readonly log;
|
|
28
|
+
/** "Does any plugin subscribe to usage.report": its cached answer is cleared on PLUGINS_CHANGED. */
|
|
29
|
+
private readonly usageSubscribers;
|
|
27
30
|
private running;
|
|
28
31
|
private queued;
|
|
29
32
|
private unsubs;
|
|
@@ -32,7 +35,9 @@ export declare class ExtensionLifecycle {
|
|
|
32
35
|
private stopped;
|
|
33
36
|
constructor(host: ExtensionHost, bus: Pick<ExtensionContext["bus"], "publish" | "subscribe">, status: ReplicaStatusStore,
|
|
34
37
|
/** Every install record's name (any desired state): prunes status rows this replica no longer knows. */
|
|
35
|
-
installs: ExtensionInstalls, config: KernelConfigService, log: KernelLogger
|
|
38
|
+
installs: ExtensionInstalls, config: KernelConfigService, log: KernelLogger,
|
|
39
|
+
/** "Does any plugin subscribe to usage.report": its cached answer is cleared on PLUGINS_CHANGED. */
|
|
40
|
+
usageSubscribers: Pick<UsageSubscribers, "invalidate">);
|
|
36
41
|
/** 订阅三个主题(订阅失败只记 error:周期任务的消息同样收不到时,下次启动再来)。 */
|
|
37
42
|
start(): Promise<void>;
|
|
38
43
|
/**
|
|
@@ -17,6 +17,7 @@ import { ExtensionInstalls } from "./installs.js";
|
|
|
17
17
|
import { PLUGIN_DEPLOYMENT_CONFIG_TOPIC, PLUGINS_CHANGED_TOPIC, PLUGINS_RECONCILE_JOB, PLUGINS_RECONCILE_TOPIC, STALE_RECONCILE_PERIODS, } from "./lifecycle-topics.js";
|
|
18
18
|
import { PLUGINS_MIGRATED_TOPIC } from "./migrate-lock.js";
|
|
19
19
|
import { ReplicaStatusStore } from "./sources.js";
|
|
20
|
+
import { UsageSubscribers } from "./usage-subscribers.js";
|
|
20
21
|
export { PLUGINS_CHANGED_TOPIC, PLUGINS_MIGRATED_TOPIC, PLUGINS_RECONCILE_JOB, PLUGINS_RECONCILE_TOPIC, STALE_RECONCILE_PERIODS, };
|
|
21
22
|
/** 心跳超过这么多个周期的行直接删除(副本早已退出;读的一方本来就不计入)。 */
|
|
22
23
|
const PRUNE_RECONCILE_PERIODS = 10;
|
|
@@ -35,6 +36,7 @@ let ExtensionLifecycle = class ExtensionLifecycle {
|
|
|
35
36
|
installs;
|
|
36
37
|
config;
|
|
37
38
|
log;
|
|
39
|
+
usageSubscribers;
|
|
38
40
|
running;
|
|
39
41
|
queued;
|
|
40
42
|
unsubs = [];
|
|
@@ -43,13 +45,16 @@ let ExtensionLifecycle = class ExtensionLifecycle {
|
|
|
43
45
|
stopped = false;
|
|
44
46
|
constructor(host, bus, status,
|
|
45
47
|
/** Every install record's name (any desired state): prunes status rows this replica no longer knows. */
|
|
46
|
-
installs, config, log
|
|
48
|
+
installs, config, log,
|
|
49
|
+
/** "Does any plugin subscribe to usage.report": its cached answer is cleared on PLUGINS_CHANGED. */
|
|
50
|
+
usageSubscribers) {
|
|
47
51
|
this.host = host;
|
|
48
52
|
this.bus = bus;
|
|
49
53
|
this.status = status;
|
|
50
54
|
this.installs = installs;
|
|
51
55
|
this.config = config;
|
|
52
56
|
this.log = log;
|
|
57
|
+
this.usageSubscribers = usageSubscribers;
|
|
53
58
|
}
|
|
54
59
|
/** 订阅三个主题(订阅失败只记 error:周期任务的消息同样收不到时,下次启动再来)。 */
|
|
55
60
|
async start() {
|
|
@@ -65,6 +70,7 @@ let ExtensionLifecycle = class ExtensionLifecycle {
|
|
|
65
70
|
await on(PLUGINS_CHANGED_TOPIC, (p) => {
|
|
66
71
|
// 安装 / 卸载改变了「部署已知」的插件名:路由闸门不等 TTL
|
|
67
72
|
this.host.invalidateKnownNames();
|
|
73
|
+
this.usageSubscribers.invalidate();
|
|
68
74
|
this.trigger(`changed:${pluginOf(p)}`);
|
|
69
75
|
});
|
|
70
76
|
await on(PLUGINS_RECONCILE_TOPIC, () => this.trigger("periodic"));
|
|
@@ -176,7 +182,8 @@ ExtensionLifecycle = __decorate([
|
|
|
176
182
|
__param(2, Inject(ReplicaStatusStore)),
|
|
177
183
|
__param(3, Inject(ExtensionInstalls)),
|
|
178
184
|
__param(4, Inject(KernelConfigService)),
|
|
179
|
-
__param(5, Inject(KERNEL_LOGGER))
|
|
185
|
+
__param(5, Inject(KERNEL_LOGGER)),
|
|
186
|
+
__param(6, Inject(UsageSubscribers))
|
|
180
187
|
], ExtensionLifecycle);
|
|
181
188
|
export { ExtensionLifecycle };
|
|
182
189
|
const pluginOf = (p) => typeof p === "object" && p !== null && typeof p.plugin === "string"
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
2
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
3
|
+
/**
|
|
4
|
+
* Plugins that subscribe to `usage.report` according to deployment state: an approved permission
|
|
5
|
+
* snapshot that declares the `usage.report` hook, for a plugin the deployment still knows: an enabled
|
|
6
|
+
* install, or a config-declared plugin with a replica status row that is not `unloaded`. With `orgId`, only plugins
|
|
7
|
+
* the organization enabled (org config rows and required bootstrap plugins).
|
|
8
|
+
*/
|
|
9
|
+
export declare function queryUsageSubscribers(db: KernelSchemaDb, orgId?: string): Promise<Set<string>>;
|
|
10
|
+
/** How long one replica trusts its answer to "does any plugin subscribe" (spec §8.1). */
|
|
11
|
+
export declare const USAGE_SUBSCRIBERS_TTL_MS = 30000;
|
|
12
|
+
/**
|
|
13
|
+
* Test seam (`KernelOverride`): the clock {@link UsageSubscribers} ages its cached answer with
|
|
14
|
+
* (default `Date.now`); the kernel never provides it.
|
|
15
|
+
*/
|
|
16
|
+
export declare const USAGE_SUBSCRIBERS_CLOCK: unique symbol;
|
|
17
|
+
/**
|
|
18
|
+
* Whether the deployment has at least one `usage.report` subscriber ({@link queryUsageSubscribers}
|
|
19
|
+
* without an org), which decides whether a usage write owes a delivery (transactional outbox spec
|
|
20
|
+
* §8.1): a usage event written while no plugin subscribes is never reported, later subscribers
|
|
21
|
+
* included. The answer comes from PG, not from this replica's loaded handlers, so a replica that
|
|
22
|
+
* has no handler still owes the delivery another replica makes.
|
|
23
|
+
*
|
|
24
|
+
* Per-process memoisation of that PG read: kept {@link USAGE_SUBSCRIBERS_TTL_MS} and cleared on
|
|
25
|
+
* `PLUGINS_CHANGED` (`ExtensionLifecycle` calls {@link invalidate}), so an enabled subscriber is
|
|
26
|
+
* seen at once, or within 30 s when the bus message is lost. It holds no state another request or
|
|
27
|
+
* replica relies on.
|
|
28
|
+
*/
|
|
29
|
+
export declare class UsageSubscribers {
|
|
30
|
+
private readonly kdb;
|
|
31
|
+
private readonly now;
|
|
32
|
+
private cached;
|
|
33
|
+
/** Bumped by {@link invalidate}: a read that started before it does not refill the cache. */
|
|
34
|
+
private generation;
|
|
35
|
+
constructor(kdb: KernelDb, now?: () => number);
|
|
36
|
+
/** Whether any plugin subscribes (cached; the read joins the caller's transaction, if any). */
|
|
37
|
+
any(): Promise<boolean>;
|
|
38
|
+
/** Forgets the cached answer (a plugin was installed, enabled, upgraded or removed). */
|
|
39
|
+
invalidate(): void;
|
|
40
|
+
}
|
|
41
|
+
/** {@link UsageSubscribers}: below the extension host, so the model broker and the runtime use it. */
|
|
42
|
+
export declare class UsageSubscribersModule {
|
|
43
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
8
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
|
+
};
|
|
10
|
+
import { Inject, Injectable, Module, Optional } from "@nestjs/common";
|
|
11
|
+
import { sql } from "kysely";
|
|
12
|
+
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
13
|
+
import { enabledExtensionsQuery } from "./enabled.js";
|
|
14
|
+
/**
|
|
15
|
+
* Plugins that subscribe to `usage.report` according to deployment state: an approved permission
|
|
16
|
+
* snapshot that declares the `usage.report` hook, for a plugin the deployment still knows: an enabled
|
|
17
|
+
* install, or a config-declared plugin with a replica status row that is not `unloaded`. With `orgId`, only plugins
|
|
18
|
+
* the organization enabled (org config rows and required bootstrap plugins).
|
|
19
|
+
*/
|
|
20
|
+
export async function queryUsageSubscribers(db, orgId) {
|
|
21
|
+
let q = db
|
|
22
|
+
.selectFrom("extension_permission_snapshots as s")
|
|
23
|
+
.select("s.plugin")
|
|
24
|
+
.where(sql `s.permissions -> 'permissions' -> 'hooks' ? 'usage.report'`)
|
|
25
|
+
.where((eb) => eb.or([
|
|
26
|
+
eb.exists(eb
|
|
27
|
+
.selectFrom("extension_installs as i")
|
|
28
|
+
.select(sql `1`.as("one"))
|
|
29
|
+
.whereRef("i.name", "=", "s.plugin")
|
|
30
|
+
.where("i.desired_state", "=", "enabled")),
|
|
31
|
+
// config-declared plugins still declared (and not unloaded) on some replica; installs are
|
|
32
|
+
// covered by desired_state above (their replica rows linger as `unloaded` when disabled)
|
|
33
|
+
eb.exists(eb
|
|
34
|
+
.selectFrom("extension_replica_status as r")
|
|
35
|
+
.select(sql `1`.as("one"))
|
|
36
|
+
.whereRef("r.plugin", "=", "s.plugin")
|
|
37
|
+
.where("r.source", "=", "config")
|
|
38
|
+
.where("r.state", "<>", "unloaded")),
|
|
39
|
+
]));
|
|
40
|
+
if (orgId !== undefined) {
|
|
41
|
+
q = q.where("s.plugin", "in", enabledExtensionsQuery(db, orgId));
|
|
42
|
+
}
|
|
43
|
+
return new Set((await q.execute()).map((r) => r.plugin));
|
|
44
|
+
}
|
|
45
|
+
/** How long one replica trusts its answer to "does any plugin subscribe" (spec §8.1). */
|
|
46
|
+
export const USAGE_SUBSCRIBERS_TTL_MS = 30_000;
|
|
47
|
+
/**
|
|
48
|
+
* Test seam (`KernelOverride`): the clock {@link UsageSubscribers} ages its cached answer with
|
|
49
|
+
* (default `Date.now`); the kernel never provides it.
|
|
50
|
+
*/
|
|
51
|
+
export const USAGE_SUBSCRIBERS_CLOCK = Symbol("USAGE_SUBSCRIBERS_CLOCK");
|
|
52
|
+
/**
|
|
53
|
+
* Whether the deployment has at least one `usage.report` subscriber ({@link queryUsageSubscribers}
|
|
54
|
+
* without an org), which decides whether a usage write owes a delivery (transactional outbox spec
|
|
55
|
+
* §8.1): a usage event written while no plugin subscribes is never reported, later subscribers
|
|
56
|
+
* included. The answer comes from PG, not from this replica's loaded handlers, so a replica that
|
|
57
|
+
* has no handler still owes the delivery another replica makes.
|
|
58
|
+
*
|
|
59
|
+
* Per-process memoisation of that PG read: kept {@link USAGE_SUBSCRIBERS_TTL_MS} and cleared on
|
|
60
|
+
* `PLUGINS_CHANGED` (`ExtensionLifecycle` calls {@link invalidate}), so an enabled subscriber is
|
|
61
|
+
* seen at once, or within 30 s when the bus message is lost. It holds no state another request or
|
|
62
|
+
* replica relies on.
|
|
63
|
+
*/
|
|
64
|
+
let UsageSubscribers = class UsageSubscribers {
|
|
65
|
+
kdb;
|
|
66
|
+
now;
|
|
67
|
+
cached;
|
|
68
|
+
/** Bumped by {@link invalidate}: a read that started before it does not refill the cache. */
|
|
69
|
+
generation = 0;
|
|
70
|
+
constructor(kdb, now = Date.now) {
|
|
71
|
+
this.kdb = kdb;
|
|
72
|
+
this.now = now;
|
|
73
|
+
}
|
|
74
|
+
/** Whether any plugin subscribes (cached; the read joins the caller's transaction, if any). */
|
|
75
|
+
async any() {
|
|
76
|
+
const at = this.now();
|
|
77
|
+
const c = this.cached;
|
|
78
|
+
if (c !== undefined && at - c.at < USAGE_SUBSCRIBERS_TTL_MS)
|
|
79
|
+
return c.any;
|
|
80
|
+
const generation = this.generation;
|
|
81
|
+
const any = (await queryUsageSubscribers(this.kdb.db)).size > 0;
|
|
82
|
+
if (generation === this.generation)
|
|
83
|
+
this.cached = { any, at };
|
|
84
|
+
return any;
|
|
85
|
+
}
|
|
86
|
+
/** Forgets the cached answer (a plugin was installed, enabled, upgraded or removed). */
|
|
87
|
+
invalidate() {
|
|
88
|
+
this.generation++;
|
|
89
|
+
this.cached = undefined;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
UsageSubscribers = __decorate([
|
|
93
|
+
Injectable(),
|
|
94
|
+
__param(0, Inject(KernelDb)),
|
|
95
|
+
__param(1, Optional()),
|
|
96
|
+
__param(1, Inject(USAGE_SUBSCRIBERS_CLOCK))
|
|
97
|
+
], UsageSubscribers);
|
|
98
|
+
export { UsageSubscribers };
|
|
99
|
+
/** {@link UsageSubscribers}: below the extension host, so the model broker and the runtime use it. */
|
|
100
|
+
let UsageSubscribersModule = class UsageSubscribersModule {
|
|
101
|
+
};
|
|
102
|
+
UsageSubscribersModule = __decorate([
|
|
103
|
+
Module({
|
|
104
|
+
providers: [UsageSubscribers],
|
|
105
|
+
exports: [UsageSubscribers],
|
|
106
|
+
})
|
|
107
|
+
], UsageSubscribersModule);
|
|
108
|
+
export { UsageSubscribersModule };
|
package/dist/http/api.module.js
CHANGED
|
@@ -12,6 +12,7 @@ import { AdminAgentsController } from "../admin/admin-agents.controller.js";
|
|
|
12
12
|
import { AdminConnectorsController } from "../admin/admin-connectors.controller.js";
|
|
13
13
|
import { AdminAuditController } from "../admin/audit.controller.js";
|
|
14
14
|
import { AdminExtensionsController } from "../admin/extensions.controller.js";
|
|
15
|
+
import { OutboxDeadController } from "../admin/outbox-dead.controller.js";
|
|
15
16
|
import { AdminOverviewController } from "../admin/overview.controller.js";
|
|
16
17
|
import { SetupController } from "../admin/setup.controller.js";
|
|
17
18
|
import { AgentsController } from "../agents/agents.controller.js";
|
|
@@ -107,6 +108,7 @@ const CONTROLLERS = [
|
|
|
107
108
|
AdminConnectorsController,
|
|
108
109
|
AdminAuditController,
|
|
109
110
|
AdminOverviewController,
|
|
111
|
+
OutboxDeadController,
|
|
110
112
|
AdminExtensionsController,
|
|
111
113
|
AdminCatalogController,
|
|
112
114
|
AdminComponentsController,
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { KernelSchemaDb } from "../db/kernel-schema.js";
|
|
3
|
+
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
3
4
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
4
5
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
5
6
|
import type { KernelLogger } from "../log.js";
|
|
7
|
+
import { type PlatformTiers, type PlatformTiersPatch, type PlatformTiersStored, type PlatformTiersView } from "../sandbox/platform-tiers.js";
|
|
6
8
|
import { type UiArrangement } from "../ui/arrangement.js";
|
|
7
9
|
import { SuperAdminLock } from "./super-admin.js";
|
|
8
10
|
/** 沙箱 cpu(核)与内存(MB)覆盖的范围(C19)。 */
|
|
@@ -105,6 +107,14 @@ export declare const DEPLOYMENT_SETTINGS: z.ZodObject<{
|
|
|
105
107
|
}, z.core.$strip>>;
|
|
106
108
|
}, z.core.$strip>;
|
|
107
109
|
export type DeploymentSettings = z.infer<typeof DEPLOYMENT_SETTINGS>;
|
|
110
|
+
/**
|
|
111
|
+
* What `GET /api/v1/admin/settings` answers: the stored settings, and the platform's sandbox tiers
|
|
112
|
+
* as they are in effect with where each field comes from (`env` / `file` / `nacos`: the startup
|
|
113
|
+
* config, read-only here; `db`: chosen in the admin console; `default`).
|
|
114
|
+
*/
|
|
115
|
+
export type DeploymentSettingsView = DeploymentSettings & {
|
|
116
|
+
sandboxTiers: PlatformTiersView;
|
|
117
|
+
};
|
|
108
118
|
/**
|
|
109
119
|
* 设置的修改(PUT /api/v1/admin/settings 的 body):只改给出的键。
|
|
110
120
|
* `runConcurrencyOverrides` 按组织合并:值为正整数 → 设置该组织的上限;值为 null → 删除该组织的覆盖
|
|
@@ -147,6 +157,19 @@ export declare const DEPLOYMENT_SETTINGS_PATCH: z.ZodObject<{
|
|
|
147
157
|
enabled: z.ZodOptional<z.ZodBoolean>;
|
|
148
158
|
disabled: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
149
159
|
}, z.core.$strict>>;
|
|
160
|
+
sandboxTiers: z.ZodOptional<z.ZodObject<{
|
|
161
|
+
max: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
162
|
+
dev: "dev";
|
|
163
|
+
open: "open";
|
|
164
|
+
strict: "strict";
|
|
165
|
+
}>>>;
|
|
166
|
+
default: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
167
|
+
dev: "dev";
|
|
168
|
+
open: "open";
|
|
169
|
+
strict: "strict";
|
|
170
|
+
}>>>;
|
|
171
|
+
allowUnsandboxed: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
172
|
+
}, z.core.$strict>>;
|
|
150
173
|
}, z.core.$strict>;
|
|
151
174
|
export type DeploymentSettingsPatch = z.infer<typeof DEPLOYMENT_SETTINGS_PATCH>;
|
|
152
175
|
/**
|
|
@@ -198,7 +221,29 @@ export declare class SettingsService {
|
|
|
198
221
|
readonly txHost: TransactionHost;
|
|
199
222
|
private readonly adminLock;
|
|
200
223
|
private readonly log;
|
|
201
|
-
|
|
224
|
+
/** The startup config's `sandbox.tiers`, which wins over the stored choice. */
|
|
225
|
+
private readonly config;
|
|
226
|
+
constructor(db: KernelDb, txHost: TransactionHost, adminLock: SuperAdminLock, log: Pick<KernelLogger, "warn">,
|
|
227
|
+
/** The startup config's `sandbox.tiers`, which wins over the stored choice. */
|
|
228
|
+
config: Pick<KernelConfigService, "get" | "fieldSource">);
|
|
229
|
+
/** The settings with the platform's sandbox tiers in effect and their sources. */
|
|
230
|
+
view(): Promise<DeploymentSettingsView>;
|
|
231
|
+
private tiersView;
|
|
232
|
+
/**
|
|
233
|
+
* The refusals of a `sandboxTiers` change against the stored choice: a field set in the
|
|
234
|
+
* startup config (`deployment.setting_readonly`), a default above the max
|
|
235
|
+
* (`validation_failed`), and with `onlyNarrows` (an API token, the Platform tool) any widening:
|
|
236
|
+
* a higher max or default, unsandboxed allowed, in effect or in the stored choice (which
|
|
237
|
+
* applies once the startup config stops setting a field). Returns the next stored choice and
|
|
238
|
+
* the effective tiers before and after.
|
|
239
|
+
*/
|
|
240
|
+
checkSandboxTiers(patch: PlatformTiersPatch, opts?: {
|
|
241
|
+
onlyNarrows?: boolean;
|
|
242
|
+
}): Promise<{
|
|
243
|
+
next: PlatformTiersStored;
|
|
244
|
+
before: PlatformTiers;
|
|
245
|
+
after: PlatformTiers;
|
|
246
|
+
}>;
|
|
202
247
|
/**
|
|
203
248
|
* Reads every setting, in the context's transaction when there is one (a caller holding a
|
|
204
249
|
* transaction connection does not take a second one from the pool). Each key is validated on
|
|
@@ -206,9 +251,14 @@ export declare class SettingsService {
|
|
|
206
251
|
* valid keys apply; unknown keys (written by a newer version) are ignored.
|
|
207
252
|
*/
|
|
208
253
|
get(): Promise<DeploymentSettings>;
|
|
209
|
-
/**
|
|
254
|
+
/**
|
|
255
|
+
* Updates settings under the super admin lock, re-checking the actor (else `forbidden`).
|
|
256
|
+
* `onlyNarrows` (an API token, the Platform tool): `sandboxTiers` may only narrow.
|
|
257
|
+
*/
|
|
210
258
|
update(patch: DeploymentSettingsPatch, actorAccountId: string, actorTokenId?: string,
|
|
211
259
|
/** Merged into the audit detail (the Platform tool's `via: "agent"`). */
|
|
212
|
-
auditDetail?: Record<string, unknown
|
|
260
|
+
auditDetail?: Record<string, unknown>, opts?: {
|
|
261
|
+
onlyNarrows?: boolean;
|
|
262
|
+
}): Promise<DeploymentSettingsView>;
|
|
213
263
|
private write;
|
|
214
264
|
}
|