@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
|
@@ -11,10 +11,12 @@ import { EXTENSION_NAME_RE } from "@capybara-hq/plugin-sdk";
|
|
|
11
11
|
import { Inject, Injectable } from "@nestjs/common";
|
|
12
12
|
import { z } from "zod";
|
|
13
13
|
import { ApiError } from "../errors.js";
|
|
14
|
+
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
14
15
|
import { KernelDb } from "../infra/database/kernel-db.js";
|
|
15
16
|
import { TransactionHost } from "../infra/database/transaction-host.js";
|
|
16
17
|
import { Transactional } from "../infra/database/transactional.decorator.js";
|
|
17
18
|
import { KERNEL_LOGGER } from "../infra/tokens.js";
|
|
19
|
+
import { applyPlatformTiersPatch, chosenPlatformDefault, PLATFORM_TIER_FIELDS, PLATFORM_TIERS_PATCH, PLATFORM_TIERS_SETTING, platformTiersWiden, readStoredPlatformTiers, resolvePlatformTiers, } from "../sandbox/platform-tiers.js";
|
|
18
20
|
import { assertPlatformDefaultEligible, lockThemeShared } from "../themes/theme-state.js";
|
|
19
21
|
import { mergeArrangement, UiArrangementPatchSchema, UiArrangementSchema, } from "../ui/arrangement.js";
|
|
20
22
|
import { audit } from "./audit.js";
|
|
@@ -153,6 +155,7 @@ export const DEPLOYMENT_SETTINGS = z.object({
|
|
|
153
155
|
clientExtensions: ClientExtensionsSetting.default(clientExtensionsDefault),
|
|
154
156
|
});
|
|
155
157
|
const DEFAULTS = DEPLOYMENT_SETTINGS.parse({});
|
|
158
|
+
const tierWidenRefused = () => new ApiError("deployment.sandbox_tier_not_allowed", "Raising the platform's sandbox level (sandboxTiers) needs a super admin in the admin console; an API token or the Platform tool may only lower it.");
|
|
156
159
|
/**
|
|
157
160
|
* 设置的修改(PUT /api/v1/admin/settings 的 body):只改给出的键。
|
|
158
161
|
* `runConcurrencyOverrides` 按组织合并:值为正整数 → 设置该组织的上限;值为 null → 删除该组织的覆盖
|
|
@@ -198,6 +201,14 @@ export const DEPLOYMENT_SETTINGS_PATCH = z
|
|
|
198
201
|
message: "give enabled, disabled or both",
|
|
199
202
|
})
|
|
200
203
|
.optional(),
|
|
204
|
+
/**
|
|
205
|
+
* The platform's sandbox tiers (sandbox dev tiers spec §4.1): each given field replaces the
|
|
206
|
+
* stored one, null clears it (back to the default: max dev, default dev, unsandboxed allowed).
|
|
207
|
+
* A field set in the startup config is read-only (409 `deployment.setting_readonly`); the
|
|
208
|
+
* default may not be above the max; an API token or the Platform tool may only narrow (400
|
|
209
|
+
* `deployment.sandbox_tier_not_allowed`).
|
|
210
|
+
*/
|
|
211
|
+
sandboxTiers: PLATFORM_TIERS_PATCH.optional(),
|
|
201
212
|
})
|
|
202
213
|
.strict();
|
|
203
214
|
/**
|
|
@@ -350,11 +361,66 @@ let SettingsService = class SettingsService {
|
|
|
350
361
|
txHost;
|
|
351
362
|
adminLock;
|
|
352
363
|
log;
|
|
353
|
-
|
|
364
|
+
config;
|
|
365
|
+
constructor(db, txHost, adminLock, log,
|
|
366
|
+
/** The startup config's `sandbox.tiers`, which wins over the stored choice. */
|
|
367
|
+
config) {
|
|
354
368
|
this.db = db;
|
|
355
369
|
this.txHost = txHost;
|
|
356
370
|
this.adminLock = adminLock;
|
|
357
371
|
this.log = log;
|
|
372
|
+
this.config = config;
|
|
373
|
+
}
|
|
374
|
+
/** The settings with the platform's sandbox tiers in effect and their sources. */
|
|
375
|
+
async view() {
|
|
376
|
+
const [settings, stored] = await Promise.all([
|
|
377
|
+
this.get(),
|
|
378
|
+
readStoredPlatformTiers(this.db.db, this.log),
|
|
379
|
+
]);
|
|
380
|
+
return { ...settings, sandboxTiers: this.tiersView(stored) };
|
|
381
|
+
}
|
|
382
|
+
tiersView(stored) {
|
|
383
|
+
const config = this.config.get().sandbox.tiers;
|
|
384
|
+
const sources = Object.fromEntries(PLATFORM_TIER_FIELDS.map((f) => [
|
|
385
|
+
f,
|
|
386
|
+
this.config.fieldSource(`sandbox.tiers.${f}`) ??
|
|
387
|
+
(stored[f] !== undefined ? "db" : "default"),
|
|
388
|
+
]));
|
|
389
|
+
return { ...resolvePlatformTiers(config, stored), sources };
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* The refusals of a `sandboxTiers` change against the stored choice: a field set in the
|
|
393
|
+
* startup config (`deployment.setting_readonly`), a default above the max
|
|
394
|
+
* (`validation_failed`), and with `onlyNarrows` (an API token, the Platform tool) any widening:
|
|
395
|
+
* a higher max or default, unsandboxed allowed, in effect or in the stored choice (which
|
|
396
|
+
* applies once the startup config stops setting a field). Returns the next stored choice and
|
|
397
|
+
* the effective tiers before and after.
|
|
398
|
+
*/
|
|
399
|
+
async checkSandboxTiers(patch, opts = {}) {
|
|
400
|
+
const readonly = PLATFORM_TIER_FIELDS.filter((f) => patch[f] !== undefined && this.config.fieldSource(`sandbox.tiers.${f}`) !== undefined);
|
|
401
|
+
if (readonly.length > 0) {
|
|
402
|
+
throw new ApiError("deployment.setting_readonly", `These sandbox tier settings are set in the startup config (file, Nacos or environment) and are read-only here: ${readonly.map((f) => `sandbox.tiers.${f}`).join(", ")}`, readonly.map((f) => ({
|
|
403
|
+
path: `sandboxTiers.${f}`,
|
|
404
|
+
source: this.config.fieldSource(`sandbox.tiers.${f}`),
|
|
405
|
+
})));
|
|
406
|
+
}
|
|
407
|
+
const config = this.config.get().sandbox.tiers;
|
|
408
|
+
const stored = await readStoredPlatformTiers(this.db.db, this.log);
|
|
409
|
+
const next = applyPlatformTiersPatch(stored, patch);
|
|
410
|
+
const before = resolvePlatformTiers(config, stored);
|
|
411
|
+
const after = resolvePlatformTiers(config, next);
|
|
412
|
+
const chosen = chosenPlatformDefault(config, next);
|
|
413
|
+
if ((patch.max !== undefined || patch.default !== undefined) && chosen !== after.default) {
|
|
414
|
+
throw new ApiError("validation_failed", `The default sandbox tier (${chosen}) cannot be above the highest (${after.max}); lower sandboxTiers.default as well`, [{ path: "sandboxTiers.default", message: `must be at most ${after.max}` }]);
|
|
415
|
+
}
|
|
416
|
+
if (opts.onlyNarrows) {
|
|
417
|
+
const none = {};
|
|
418
|
+
if (platformTiersWiden(before, after) ||
|
|
419
|
+
platformTiersWiden(resolvePlatformTiers(none, stored), resolvePlatformTiers(none, next))) {
|
|
420
|
+
throw tierWidenRefused();
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return { next, before, after };
|
|
358
424
|
}
|
|
359
425
|
/**
|
|
360
426
|
* Reads every setting, in the context's transaction when there is one (a caller holding a
|
|
@@ -382,18 +448,21 @@ let SettingsService = class SettingsService {
|
|
|
382
448
|
}
|
|
383
449
|
return out;
|
|
384
450
|
}
|
|
385
|
-
/**
|
|
451
|
+
/**
|
|
452
|
+
* Updates settings under the super admin lock, re-checking the actor (else `forbidden`).
|
|
453
|
+
* `onlyNarrows` (an API token, the Platform tool): `sandboxTiers` may only narrow.
|
|
454
|
+
*/
|
|
386
455
|
async update(patch, actorAccountId, actorTokenId,
|
|
387
456
|
/** Merged into the audit detail (the Platform tool's `via: "agent"`). */
|
|
388
|
-
auditDetail) {
|
|
457
|
+
auditDetail, opts = {}) {
|
|
389
458
|
const check = DEPLOYMENT_SETTINGS_PATCH.safeParse(patch);
|
|
390
459
|
if (!check.success) {
|
|
391
460
|
throw new ApiError("validation_failed", "Invalid deployment settings", check.error.issues.map((i) => ({ path: i.path.join("."), message: i.message })));
|
|
392
461
|
}
|
|
393
|
-
await this.write(check.data, actorAccountId, actorTokenId, auditDetail);
|
|
394
|
-
return this.
|
|
462
|
+
await this.write(check.data, actorAccountId, actorTokenId, auditDetail, opts);
|
|
463
|
+
return this.view();
|
|
395
464
|
}
|
|
396
|
-
async write(patch, actorAccountId, actorTokenId, auditDetail) {
|
|
465
|
+
async write(patch, actorAccountId, actorTokenId, auditDetail, opts) {
|
|
397
466
|
await this.adminLock.lockAndAuthorize(actorAccountId);
|
|
398
467
|
// The super admin lock serializes every settings write: the current overrides are read
|
|
399
468
|
// and merged under it, so no concurrent change is lost
|
|
@@ -452,7 +521,16 @@ let SettingsService = class SettingsService {
|
|
|
452
521
|
next.subagentLimitOverrides = mergeByOrg(current.subagentLimitOverrides, subagentPatch);
|
|
453
522
|
}
|
|
454
523
|
}
|
|
455
|
-
|
|
524
|
+
// the platform's sandbox tiers: checked against the stored choice under the lock; lowering
|
|
525
|
+
// the max needs no org rewrite, the effective policy cuts every org's ceiling and default
|
|
526
|
+
let tiersChange;
|
|
527
|
+
const writes = Object.entries(next);
|
|
528
|
+
if (patch.sandboxTiers !== undefined) {
|
|
529
|
+
const r = await this.checkSandboxTiers(patch.sandboxTiers, opts);
|
|
530
|
+
tiersChange = { before: r.before, after: r.after };
|
|
531
|
+
writes.push([PLATFORM_TIERS_SETTING, r.next]);
|
|
532
|
+
}
|
|
533
|
+
for (const [key, value] of writes) {
|
|
456
534
|
if (value === undefined)
|
|
457
535
|
continue;
|
|
458
536
|
const json = JSON.stringify(value);
|
|
@@ -468,7 +546,11 @@ let SettingsService = class SettingsService {
|
|
|
468
546
|
actorAccountId,
|
|
469
547
|
...(actorTokenId !== undefined && { actorTokenId }),
|
|
470
548
|
action: "deployment.settings.updated",
|
|
471
|
-
detail: {
|
|
549
|
+
detail: {
|
|
550
|
+
...patch,
|
|
551
|
+
...(tiersChange !== undefined && { sandboxTiersEffective: tiersChange }),
|
|
552
|
+
...auditDetail,
|
|
553
|
+
},
|
|
472
554
|
});
|
|
473
555
|
}
|
|
474
556
|
};
|
|
@@ -480,6 +562,7 @@ SettingsService = __decorate([
|
|
|
480
562
|
__param(0, Inject(KernelDb)),
|
|
481
563
|
__param(1, Inject(TransactionHost)),
|
|
482
564
|
__param(2, Inject(SuperAdminLock)),
|
|
483
|
-
__param(3, Inject(KERNEL_LOGGER))
|
|
565
|
+
__param(3, Inject(KERNEL_LOGGER)),
|
|
566
|
+
__param(4, Inject(KernelConfigService))
|
|
484
567
|
], SettingsService);
|
|
485
568
|
export { SettingsService };
|
package/dist/index.d.ts
CHANGED
|
@@ -70,6 +70,7 @@ export { ROUTE_SCHEMAS, type RouteSchemas } from "./platform/route-schemas.js";
|
|
|
70
70
|
export { UNKNOWN_RESULT_TEXT } from "./runtime/context/pairing.js";
|
|
71
71
|
export type { AgentLoop, LoopContext, LoopOutcome } from "./runtime/loop.js";
|
|
72
72
|
export { MAINTENANCE_QUEUE_NAME } from "./runtime/maintenance-queue.js";
|
|
73
|
+
export { type OrphanCandidate, queuedRunsWithoutJob } from "./runtime/run-orphan-check.job.js";
|
|
73
74
|
export { runJobId } from "./runtime/run-queue.js";
|
|
74
75
|
export { SANDBOX_DESTROY_JOB, SANDBOX_SUSPEND_JOB, } from "./sandbox/jobs.js";
|
|
75
76
|
export { SANDBOX_LOCK_TTL_MS, SandboxService, type SandboxUseInfo, } from "./sandbox/sandbox.service.js";
|
package/dist/index.js
CHANGED
|
@@ -68,6 +68,7 @@ export { PlatformOperations } from "./platform/registry.js";
|
|
|
68
68
|
export { ROUTE_SCHEMAS } from "./platform/route-schemas.js";
|
|
69
69
|
export { UNKNOWN_RESULT_TEXT } from "./runtime/context/pairing.js";
|
|
70
70
|
export { MAINTENANCE_QUEUE_NAME } from "./runtime/maintenance-queue.js";
|
|
71
|
+
export { queuedRunsWithoutJob } from "./runtime/run-orphan-check.job.js";
|
|
71
72
|
export { runJobId } from "./runtime/run-queue.js";
|
|
72
73
|
export { SANDBOX_DESTROY_JOB, SANDBOX_SUSPEND_JOB, } from "./sandbox/jobs.js";
|
|
73
74
|
export { SANDBOX_LOCK_TTL_MS, SandboxService, } from "./sandbox/sandbox.service.js";
|
|
@@ -21,6 +21,7 @@ import { KernelEventsModule } from "../events/kernel-events.js";
|
|
|
21
21
|
import { GracefulShutdownModule } from "../lifecycle/graceful-shutdown.module.js";
|
|
22
22
|
import { LockModule } from "../lock/lock.module.js";
|
|
23
23
|
import { LoggingModule } from "../logging/logging.module.js";
|
|
24
|
+
import { OutboxModule } from "../outbox/outbox.module.js";
|
|
24
25
|
import { QueueModule } from "../queue/queue.module.js";
|
|
25
26
|
import { KERNEL_BUS, KERNEL_LOGGER, REDIS, REDIS_SUBSCRIBER } from "../tokens.js";
|
|
26
27
|
/** How long the CLI's Redis connection may take before a command fails (a publish only warns). */
|
|
@@ -110,6 +111,10 @@ let KernelCliModule = KernelCliModule_1 = class KernelCliModule {
|
|
|
110
111
|
ConfigModule.forRoot(config, opts.env !== undefined ? { env: opts.env } : {}),
|
|
111
112
|
GracefulShutdownModule,
|
|
112
113
|
DatabaseModule.forRoot(),
|
|
114
|
+
// owed jobs a command's domain writes carry (an extension's embed call owes its usage
|
|
115
|
+
// report); delivered by the fast path when the command's context has the queue, else by a
|
|
116
|
+
// worker's relay
|
|
117
|
+
OutboxModule,
|
|
113
118
|
// QueueModule's root gives the queues a command's modules register (the catalog's scope
|
|
114
119
|
// sync and maintenance queues) the configured Redis; without it BullMQ would connect to
|
|
115
120
|
// its default 127.0.0.1:6379
|
|
@@ -15,6 +15,13 @@ export declare class KernelConfigService {
|
|
|
15
15
|
private readonly listeners;
|
|
16
16
|
constructor(input: KernelConfigInput, log: KernelLogger);
|
|
17
17
|
get(): KernelConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Where the current value of a field without a schema default comes from: `env` when an
|
|
20
|
+
* environment variable sets it, else the config source (`file` / `nacos`) when it is set at all;
|
|
21
|
+
* undefined when nothing sets it (a layer below the startup config decides, e.g. the deployment
|
|
22
|
+
* settings for `sandbox.tiers.*`). Such fields are read-only in the admin console.
|
|
23
|
+
*/
|
|
24
|
+
fieldSource(path: string): "env" | "file" | "nacos" | undefined;
|
|
18
25
|
/** Subscribes to applied changes (hot fields only); returns the unsubscribe function. */
|
|
19
26
|
onChange(listener: ConfigChangeListener): () => void;
|
|
20
27
|
/**
|
|
@@ -8,9 +8,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
8
8
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
9
9
|
};
|
|
10
10
|
import { Inject, Injectable } from "@nestjs/common";
|
|
11
|
+
import { envOverrides } from "../../config/env.js";
|
|
11
12
|
import { changedPaths, configFields, getPath, secretValues, setPath } from "../../config/fields.js";
|
|
12
13
|
import { resolveConfig } from "../../config/load.js";
|
|
13
14
|
import { KernelConfigSchema } from "../../config/schema.js";
|
|
15
|
+
import { configSourceKind } from "../../config/sources.js";
|
|
14
16
|
import { KERNEL_CONFIG_INPUT, KERNEL_LOGGER } from "../tokens.js";
|
|
15
17
|
/**
|
|
16
18
|
* Appliers of the hot-reloadable fields: the key is a dotted path marked `hot` in the schema. A
|
|
@@ -101,6 +103,24 @@ let KernelConfigService = class KernelConfigService {
|
|
|
101
103
|
get() {
|
|
102
104
|
return this.current;
|
|
103
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Where the current value of a field without a schema default comes from: `env` when an
|
|
108
|
+
* environment variable sets it, else the config source (`file` / `nacos`) when it is set at all;
|
|
109
|
+
* undefined when nothing sets it (a layer below the startup config decides, e.g. the deployment
|
|
110
|
+
* settings for `sandbox.tiers.*`). Such fields are read-only in the admin console.
|
|
111
|
+
*/
|
|
112
|
+
fieldSource(path) {
|
|
113
|
+
if (getPath(this.current, path) === undefined)
|
|
114
|
+
return undefined;
|
|
115
|
+
let fromEnv = false;
|
|
116
|
+
try {
|
|
117
|
+
fromEnv = getPath(envOverrides(this.env), path) !== undefined;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
// conflicting variables fail the start; a later change here only loses the label
|
|
121
|
+
}
|
|
122
|
+
return fromEnv ? "env" : configSourceKind(this.env);
|
|
123
|
+
}
|
|
104
124
|
/** Subscribes to applied changes (hot fields only); returns the unsubscribe function. */
|
|
105
125
|
onChange(listener) {
|
|
106
126
|
this.listeners.add(listener);
|
|
@@ -23,8 +23,9 @@ export interface KernelEventMap {
|
|
|
23
23
|
};
|
|
24
24
|
/**
|
|
25
25
|
* A person decided a tool call approval (after the commit, exactly once: only the decision that
|
|
26
|
-
* changed it from pending). The
|
|
27
|
-
*
|
|
26
|
+
* changed it from pending). The decision's transaction resumed the run and, for a conversation
|
|
27
|
+
* with a channel target, owed the IM delivery that updates the card (with its `approval_decided`
|
|
28
|
+
* append); the event itself is only the decision's announcement.
|
|
28
29
|
*/
|
|
29
30
|
"approval.decided": {
|
|
30
31
|
id: string;
|
|
@@ -36,8 +37,7 @@ export interface KernelEventMap {
|
|
|
36
37
|
};
|
|
37
38
|
/**
|
|
38
39
|
* A person answered a tool call's input request, or skipped it with a message (after the commit,
|
|
39
|
-
* exactly once).
|
|
40
|
-
* consumers and the same re-derivation as `approval.decided`.
|
|
40
|
+
* exactly once). The same transaction contract as `approval.decided`.
|
|
41
41
|
*/
|
|
42
42
|
"question.answered": {
|
|
43
43
|
id: string;
|
|
@@ -47,38 +47,20 @@ export interface KernelEventMap {
|
|
|
47
47
|
/** `skipped`: the run's starter sent a message instead (reply-while-question spec §6.3). */
|
|
48
48
|
outcome: "answered" | "skipped";
|
|
49
49
|
};
|
|
50
|
-
/**
|
|
51
|
-
* EventAppended: a conversation's event log advanced to `toSeq` (after the commit, from
|
|
52
|
-
* `EventLog.notify`, right after the bus publish). The channel outbound delivery enqueues a job
|
|
53
|
-
* for a conversation with an IM target; a lost event is re-derived by the next append's (and the
|
|
54
|
-
* finished delivery job re-checks the log for content it has not delivered).
|
|
55
|
-
*/
|
|
56
|
-
"conversation.event-appended": {
|
|
57
|
-
conversationId: string;
|
|
58
|
-
toSeq: number;
|
|
59
|
-
};
|
|
60
50
|
/**
|
|
61
51
|
* A run started executing on this replica (its first start, a resume, or a takeover after a
|
|
62
52
|
* stall), after it took the conversation lock and an org quota slot. The channel outbound
|
|
63
|
-
* enqueues the conversation's IM delivery
|
|
53
|
+
* enqueues the conversation's IM delivery at once (a hint: the run's appends owe it, transactional
|
|
54
|
+
* outbox spec §8.1).
|
|
64
55
|
*/
|
|
65
56
|
"run.started": {
|
|
66
57
|
conversationId: string;
|
|
67
58
|
runId: string;
|
|
68
59
|
};
|
|
69
60
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*/
|
|
74
|
-
"run.wait-stopped": {
|
|
75
|
-
conversationId: string;
|
|
76
|
-
runId: string;
|
|
77
|
-
};
|
|
78
|
-
/**
|
|
79
|
-
* `ensureRun` marked an orphaned run failed (after the commit): the waits stop its active fork
|
|
80
|
-
* sub-agent at once (background sub-agents keep running, agent map spec §5.4). A lost event is
|
|
81
|
-
* repaired by the wait sweep (fork children of finished runs).
|
|
61
|
+
* The `run-orphan-check` failed an orphaned run (after the commit): the waits stop its active
|
|
62
|
+
* fork sub-agent at once (background sub-agents keep running, agent map spec §5.4). A lost event
|
|
63
|
+
* is repaired by the `stop-tree` job the run's terminal transaction owed.
|
|
82
64
|
*/
|
|
83
65
|
"run.orphaned": {
|
|
84
66
|
runId: string;
|
|
@@ -99,14 +81,6 @@ export interface KernelEventMap {
|
|
|
99
81
|
"background_task.finished": {
|
|
100
82
|
conversationId: string;
|
|
101
83
|
};
|
|
102
|
-
/**
|
|
103
|
-
* An extension's `ctx.models.embed` call wrote a `model_usage` row (after the commit, spec B
|
|
104
|
-
* §5.4). The usage reporter enqueues its `usage.report` delivery; a lost event is re-derived by
|
|
105
|
-
* the usage sweep (rows whose `reported_at` is still null).
|
|
106
|
-
*/
|
|
107
|
-
"model_usage.recorded": {
|
|
108
|
-
id: string;
|
|
109
|
-
};
|
|
110
84
|
}
|
|
111
85
|
type Handler<K extends keyof KernelEventMap> = (payload: KernelEventMap[K]) => Promise<void> | void;
|
|
112
86
|
/** Typed in-process event emitter; handlers run in order, a failing one is logged and skipped. */
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
import { Module } from "@nestjs/common";
|
|
8
|
+
import { OutboxRelay } from "./outbox.relay.js";
|
|
9
|
+
/**
|
|
10
|
+
* The outbox relay (`@LockedInterval`), imported only by `WorkerModule`. Its dispatcher comes from
|
|
11
|
+
* the global `OutboxModule`, which every role has (the fast path runs everywhere).
|
|
12
|
+
*/
|
|
13
|
+
let OutboxRelayModule = class OutboxRelayModule {
|
|
14
|
+
};
|
|
15
|
+
OutboxRelayModule = __decorate([
|
|
16
|
+
Module({ providers: [OutboxRelay] })
|
|
17
|
+
], OutboxRelayModule);
|
|
18
|
+
export { OutboxRelayModule };
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { ModuleRef } from "@nestjs/core";
|
|
2
|
+
import type { Queue } from "bullmq";
|
|
3
|
+
import type { KernelLogger } from "../../log.js";
|
|
4
|
+
import { KernelDb } from "../database/kernel-db.js";
|
|
5
|
+
import { TransactionHost } from "../database/transaction-host.js";
|
|
6
|
+
import { type KernelQueueName } from "../queue/queue-names.js";
|
|
7
|
+
/**
|
|
8
|
+
* Retry schedule of a row whose add failed (spec §3.4): the next attempt waits
|
|
9
|
+
* `min(capMs, baseMs * 2^attempts)`, and the row is dead (kept, never retried) at `maxAttempts`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const OUTBOX_BACKOFF: {
|
|
12
|
+
readonly baseMs: 1000;
|
|
13
|
+
readonly capMs: 300000;
|
|
14
|
+
readonly maxAttempts: 20;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* How long the queue adds of one claim pass may take in all: the claim transaction holds its rows'
|
|
18
|
+
* locks and a pool connection for at most about this long.
|
|
19
|
+
*/
|
|
20
|
+
export declare const OUTBOX_REDIS_TIMEOUT_MS = 2000;
|
|
21
|
+
/**
|
|
22
|
+
* Most fast-path passes running at once in one process; more are skipped and left to the relay,
|
|
23
|
+
* so a slow Redis cannot take the whole pool (a local resource bound, no shared state).
|
|
24
|
+
*/
|
|
25
|
+
export declare const OUTBOX_FAST_PATH_CONCURRENCY = 4;
|
|
26
|
+
/**
|
|
27
|
+
* Test seam (`KernelOverride`): returns true to make the adds to the given queue fail (a Redis
|
|
28
|
+
* outage) without calling Redis. The kernel never provides it; the dispatcher defaults to "never
|
|
29
|
+
* fails".
|
|
30
|
+
*/
|
|
31
|
+
export declare const OUTBOX_DISPATCH_FAILS: unique symbol;
|
|
32
|
+
/** What one pass did: rows delivered, rows whose add failed, and of those the rows now dead. */
|
|
33
|
+
export interface DispatchResult {
|
|
34
|
+
sent: number;
|
|
35
|
+
failed: number;
|
|
36
|
+
dead: number;
|
|
37
|
+
}
|
|
38
|
+
/** The queue handle the dispatcher uses: adds, and the connection's state. */
|
|
39
|
+
export type OutboxQueue = Pick<Queue, "addBulk" | "getBackend">;
|
|
40
|
+
/**
|
|
41
|
+
* Delivers outbox rows to BullMQ (transactional outbox spec §3.3, §3.4). A pass claims rows
|
|
42
|
+
* `FOR UPDATE SKIP LOCKED` (so concurrent passes never take the same row), adds their jobs per
|
|
43
|
+
* queue with `addBulk` (the queue defaults overlaid by the registry's options of the job name, the
|
|
44
|
+
* row's job id, a future `run_at` as the remaining `delay`), and deletes
|
|
45
|
+
* the delivered rows in the same short transaction. A crash after the add and before the commit
|
|
46
|
+
* leaves the rows; the next pass adds again and BullMQ ignores the existing job id. A queue whose
|
|
47
|
+
* add fails keeps its rows, and a second short update records the attempt with exponential
|
|
48
|
+
* backoff, setting `dead_at` at the last one.
|
|
49
|
+
*
|
|
50
|
+
* The fast path never queues behind an outage: it skips the pass (the relay delivers the rows) when
|
|
51
|
+
* a queue's Redis connection is not ready or {@link OUTBOX_FAST_PATH_CONCURRENCY} passes already
|
|
52
|
+
* run. Within a pass, the first failed queue fails the queues after it without trying them.
|
|
53
|
+
*
|
|
54
|
+
* The queue handles are the instances the queues' owner modules registered (one per queue, no
|
|
55
|
+
* connection of the outbox's own), resolved by token at use time. A queue whose owner this
|
|
56
|
+
* process's roles do not load is not reachable here: no pass claims its rows, which stay for a
|
|
57
|
+
* process that has it.
|
|
58
|
+
*/
|
|
59
|
+
export declare class OutboxDispatcher {
|
|
60
|
+
readonly txHost: TransactionHost;
|
|
61
|
+
private readonly db;
|
|
62
|
+
private readonly log;
|
|
63
|
+
private readonly moduleRef;
|
|
64
|
+
private readonly dispatchFails;
|
|
65
|
+
/** The owners' queue instances resolved so far (a per-process handle cache). */
|
|
66
|
+
private readonly queues;
|
|
67
|
+
/** Fast-path passes running in this process (bounded by OUTBOX_FAST_PATH_CONCURRENCY). */
|
|
68
|
+
private fastPaths;
|
|
69
|
+
constructor(txHost: TransactionHost, db: KernelDb, log: KernelLogger, moduleRef: Pick<ModuleRef, "get">, dispatchFails?: (queue: KernelQueueName) => boolean);
|
|
70
|
+
/** The queue instance its owner module registered, or undefined when no loaded module has it. */
|
|
71
|
+
private queue;
|
|
72
|
+
/** The kernel queues this process can add to, with their handles. */
|
|
73
|
+
private reachable;
|
|
74
|
+
/**
|
|
75
|
+
* The fast path: delivers the given rows (a committed transaction's own) right away. Never
|
|
76
|
+
* throws: whatever it does not deliver stays for the relay, and a failure is logged.
|
|
77
|
+
*/
|
|
78
|
+
dispatchOwn(ids: readonly string[]): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Every reachable queue's connection is ready (they reach the same Redis; the fast path does not
|
|
81
|
+
* read its rows' queues before claiming them).
|
|
82
|
+
*/
|
|
83
|
+
private redisReady;
|
|
84
|
+
/**
|
|
85
|
+
* The relay: delivers up to `limit` due rows (not dead, `next_attempt_at` reached), oldest
|
|
86
|
+
* first.
|
|
87
|
+
*/
|
|
88
|
+
dispatchDue(limit: number): Promise<DispatchResult>;
|
|
89
|
+
private dispatch;
|
|
90
|
+
/**
|
|
91
|
+
* One claim transaction: locks the rows (skipping rows another pass holds), adds their jobs and
|
|
92
|
+
* deletes the delivered rows. The only Redis calls made while a PG transaction is open in the
|
|
93
|
+
* kernel (spec §3.3): the locks held are outbox rows only, and the pass's adds together are
|
|
94
|
+
* bounded by {@link OUTBOX_REDIS_TIMEOUT_MS}.
|
|
95
|
+
*/
|
|
96
|
+
private claimAndSend;
|
|
97
|
+
/**
|
|
98
|
+
* Records a failed add on its rows (after the claim transaction, so the attempt is kept whatever
|
|
99
|
+
* that transaction did): one more attempt, the error, the next attempt by {@link OUTBOX_BACKOFF},
|
|
100
|
+
* and `dead_at` at the last attempt. Returns how many rows it made dead.
|
|
101
|
+
*/
|
|
102
|
+
private recordFailure;
|
|
103
|
+
}
|