@capybara-hq/kernel 0.1.0-rc.23 → 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.module.d.ts +2 -1
- package/dist/admin/admin.module.js +7 -3
- 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 +2 -1
- package/dist/background/launch.js +5 -2
- 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.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/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 +0 -3
- package/dist/config/schema.js +11 -20
- 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 +18 -3
- package/dist/errors.d.ts +11 -0
- package/dist/errors.js +11 -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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/infra/cli/kernel-cli.module.js +5 -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/machines.d.ts +13 -5
- package/dist/local-devices/machines.js +45 -7
- 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/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 +18 -2
- 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/outbox.ops.d.ts +21 -0
- package/dist/platform/ops/outbox.ops.js +125 -0
- 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/sandbox.service.d.ts +17 -4
- package/dist/sandbox/sandbox.service.js +55 -14
- 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
|
@@ -2,7 +2,7 @@ import { type ExecResult, type SandboxActor, type SandboxHandle, type SandboxLim
|
|
|
2
2
|
import type { Redis } from "ioredis";
|
|
3
3
|
import { type Selectable } from "kysely";
|
|
4
4
|
import { BackgroundTaskStore } from "../background/store.js";
|
|
5
|
-
import {
|
|
5
|
+
import type { KernelConfig } from "../config/schema.js";
|
|
6
6
|
import type { DeviceInstancesTable } from "../db/kernel-schema.js";
|
|
7
7
|
import { ApiError } from "../errors.js";
|
|
8
8
|
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
@@ -106,6 +106,19 @@ export declare const deviceNotFound: () => ApiError;
|
|
|
106
106
|
* owner's: `capybara-device logout`, then `login` into the device, recreates it (ruling R24).
|
|
107
107
|
*/
|
|
108
108
|
export declare const deviceFilesLost: (local?: boolean) => ApiError;
|
|
109
|
+
/**
|
|
110
|
+
* A cloud sandbox provider refused to make (or move) an instance with open egress, the open tier
|
|
111
|
+
* (409; sandbox dev tiers spec §5.3): above all a provider set to refuse it (sandbox-docker /
|
|
112
|
+
* sandbox-e2b `openEgress: "off"`). Details `[{ tier }]`. The provider's own error goes only to
|
|
113
|
+
* the log: it may name the provider's settings.
|
|
114
|
+
*/
|
|
115
|
+
export declare const sandboxTierRefused: (tier: SandboxTier) => ApiError;
|
|
116
|
+
/**
|
|
117
|
+
* A cloud sandbox provider failed to make a device's file system or instance for another reason
|
|
118
|
+
* (502): often its deployment config (image, runtime, network), sometimes a passing fault. The
|
|
119
|
+
* provider's own error goes only to the log.
|
|
120
|
+
*/
|
|
121
|
+
export declare const sandboxCreateFailed: () => ApiError;
|
|
109
122
|
/**
|
|
110
123
|
* The row still records the instance `gone` (same handle and same `created_at`). Handles compare
|
|
111
124
|
* canonically: a jsonb round trip reorders a multi-key handle's keys (final review m9).
|
|
@@ -117,11 +130,11 @@ export declare const isInstance: (row: Pick<Row, "handle" | "created_at">, gone:
|
|
|
117
130
|
* run time limit (Ruling M20);
|
|
118
131
|
* - `sandbox.tiers.max` is open but the current provider plugin sets `openEgress: "off"`: every
|
|
119
132
|
* creation of an open-tier instance is refused.
|
|
120
|
-
*
|
|
121
|
-
*
|
|
133
|
+
* No run duration limit (`runtime.maxRunSeconds` 0, the default) cuts no command, so there is
|
|
134
|
+
* nothing to tell.
|
|
122
135
|
*/
|
|
123
136
|
export declare function sandboxConfigWarnings(cfg: Pick<KernelConfig, "runtime" | "sandbox" | "extensionConfig">, providerPlugin?: string): {
|
|
124
|
-
level: "
|
|
137
|
+
level: "warn";
|
|
125
138
|
message: string;
|
|
126
139
|
}[];
|
|
127
140
|
/** No sandbox provider (503). */
|
|
@@ -13,7 +13,6 @@ import { Inject, Injectable } from "@nestjs/common";
|
|
|
13
13
|
import { sql, } from "kysely";
|
|
14
14
|
import { SESSION_MODE_SCRIPT } from "../background/launch.js";
|
|
15
15
|
import { BackgroundTaskStore } from "../background/store.js";
|
|
16
|
-
import { DEFAULT_MAX_COMMAND_SECONDS, DEFAULT_MAX_RUN_SECONDS, } from "../config/schema.js";
|
|
17
16
|
import { ApiError } from "../errors.js";
|
|
18
17
|
import { readSandboxLimitOverride } from "../identity/settings.js";
|
|
19
18
|
import { KernelConfigService } from "../infra/config/kernel-config.service.js";
|
|
@@ -23,8 +22,9 @@ import { effectiveSandboxLimits, readOrgSettings } from "../orgs/settings.servic
|
|
|
23
22
|
import { appendMissingGrant, TIER_OPEN_GRANT_KEY, UNATTENDED_OPEN_TIER_ERROR, unattendedTierOf, } from "../schedules/unattended.js";
|
|
24
23
|
import { canonicalJson } from "../tools/canonical-json.js";
|
|
25
24
|
import { SandboxLeases, SandboxLockLostError, sandboxBusy, } from "./leases.js";
|
|
26
|
-
import { LOCAL_PROVIDER, providerForDevice, SandboxProviders, } from "./providers.js";
|
|
25
|
+
import { isInternalProvider, LOCAL_PROVIDER, providerForDevice, SandboxProviders, } from "./providers.js";
|
|
27
26
|
import { appliedOf, effectiveSandboxPolicy, instanceLimitsJson, limitsForTier, readDeploymentSandboxPolicy, readInstanceLimits, sameApplied, } from "./tiers.js";
|
|
27
|
+
import { SandboxProviderUnreachableError } from "./unreachable.js";
|
|
28
28
|
// Moved to leases.ts (phase C); re-exported for existing importers
|
|
29
29
|
export { SANDBOX_LOCK_PREFIX, SANDBOX_LOCK_TTL_MS, SandboxLockLostError, sandboxBusy, } from "./leases.js";
|
|
30
30
|
/** Margin (ms) of a holder record's TTL beyond the longest command: by then the in-sandbox limit has ended its commands. */
|
|
@@ -58,6 +58,46 @@ export const deviceNotFound = () => new ApiError("device.not_found", "This devic
|
|
|
58
58
|
export const deviceFilesLost = (local = false) => local
|
|
59
59
|
? new ApiError("device.files_lost", "The local device's directory is gone from its machine; run capybara-device logout, then capybara-device login into this device, on that machine to recreate it.", [{ source: "local" }])
|
|
60
60
|
: new ApiError("device.files_lost", "The device's files are gone; reset its files from the devices page to start with an empty workspace.");
|
|
61
|
+
/**
|
|
62
|
+
* A cloud sandbox provider refused to make (or move) an instance with open egress, the open tier
|
|
63
|
+
* (409; sandbox dev tiers spec §5.3): above all a provider set to refuse it (sandbox-docker /
|
|
64
|
+
* sandbox-e2b `openEgress: "off"`). Details `[{ tier }]`. The provider's own error goes only to
|
|
65
|
+
* the log: it may name the provider's settings.
|
|
66
|
+
*/
|
|
67
|
+
export const sandboxTierRefused = (tier) => new ApiError("sandbox.tier_refused", `The cloud sandbox can't run this device at the ${tier} tier: the sandbox provider refused to create it there. An org admin can lower the tier on the device page or in the org's sandbox settings, or a super admin can allow it in the sandbox extension's settings.`, [{ tier }]);
|
|
68
|
+
/**
|
|
69
|
+
* A cloud sandbox provider failed to make a device's file system or instance for another reason
|
|
70
|
+
* (502): often its deployment config (image, runtime, network), sometimes a passing fault. The
|
|
71
|
+
* provider's own error goes only to the log.
|
|
72
|
+
*/
|
|
73
|
+
export const sandboxCreateFailed = () => new ApiError("sandbox.create_failed", "The cloud sandbox provider could not create this device's sandbox. Retry; if it keeps failing, a super admin should check the sandbox extension's settings.");
|
|
74
|
+
/**
|
|
75
|
+
* What a failed `createFileSystem` / `create` / `update` of a cloud provider becomes: an abort,
|
|
76
|
+
* a gone error, an unreachable provider and a kernel error stay as they are (their callers and the
|
|
77
|
+
* tools handle them); any other error is logged (warn, redacted) and replaced by
|
|
78
|
+
* {@link sandboxTierRefused} when `limits` ask for open egress (the only egress a provider's
|
|
79
|
+
* config refuses), else (a create) by {@link sandboxCreateFailed}; a failed `update` below open
|
|
80
|
+
* stays as it is. A kernel-internal provider (`@local`) keeps its own errors.
|
|
81
|
+
*/
|
|
82
|
+
function providerRefusal(log, err, facts, limits, signal) {
|
|
83
|
+
if (signal.aborted ||
|
|
84
|
+
isInternalProvider(facts.provider) ||
|
|
85
|
+
isSandboxGoneError(err) ||
|
|
86
|
+
isFileSystemGoneError(err) ||
|
|
87
|
+
err instanceof SandboxProviderUnreachableError ||
|
|
88
|
+
err instanceof ApiError) {
|
|
89
|
+
return err;
|
|
90
|
+
}
|
|
91
|
+
if (limits.egress === "open") {
|
|
92
|
+
// spec §5.3: a provider set to refuse open egress (`openEgress: "off"`) fails here
|
|
93
|
+
log.warn("the sandbox provider refused an instance in the open tier; check its openEgress setting or lower sandbox.tiers.max", { ...facts, tier: limits.tier, err });
|
|
94
|
+
return sandboxTierRefused(limits.tier);
|
|
95
|
+
}
|
|
96
|
+
if (facts.op === "update")
|
|
97
|
+
return err;
|
|
98
|
+
log.warn("the sandbox provider failed to create a device's sandbox", { ...facts, err });
|
|
99
|
+
return sandboxCreateFailed();
|
|
100
|
+
}
|
|
61
101
|
/**
|
|
62
102
|
* The row still records the instance `gone` (same handle and same `created_at`). Handles compare
|
|
63
103
|
* canonically: a jsonb round trip reorders a multi-key handle's keys (final review m9).
|
|
@@ -87,8 +127,8 @@ function tagged(impl, tag, actor, before) {
|
|
|
87
127
|
* run time limit (Ruling M20);
|
|
88
128
|
* - `sandbox.tiers.max` is open but the current provider plugin sets `openEgress: "off"`: every
|
|
89
129
|
* creation of an open-tier instance is refused.
|
|
90
|
-
*
|
|
91
|
-
*
|
|
130
|
+
* No run duration limit (`runtime.maxRunSeconds` 0, the default) cuts no command, so there is
|
|
131
|
+
* nothing to tell.
|
|
92
132
|
*/
|
|
93
133
|
export function sandboxConfigWarnings(cfg, providerPlugin) {
|
|
94
134
|
const out = [];
|
|
@@ -104,10 +144,9 @@ export function sandboxConfigWarnings(cfg, providerPlugin) {
|
|
|
104
144
|
}
|
|
105
145
|
const run = cfg.runtime.maxRunSeconds;
|
|
106
146
|
const cmd = cfg.sandbox.limits.maxCommandSeconds;
|
|
107
|
-
if (run < cmd) {
|
|
108
|
-
const defaults = run === DEFAULT_MAX_RUN_SECONDS && cmd === DEFAULT_MAX_COMMAND_SECONDS;
|
|
147
|
+
if (run > 0 && run < cmd) {
|
|
109
148
|
out.push({
|
|
110
|
-
level:
|
|
149
|
+
level: "warn",
|
|
111
150
|
message: `runtime.maxRunSeconds (${run}) is less than sandbox.limits.maxCommandSeconds (${cmd}): sandbox commands are limited to the time left in the run, so commands longer than about ${run} seconds cannot finish; raise runtime.maxRunSeconds to at least ${cmd} if agents need long commands`,
|
|
112
151
|
});
|
|
113
152
|
}
|
|
@@ -1380,7 +1419,12 @@ let SandboxService = class SandboxService {
|
|
|
1380
1419
|
? row.fs_handle
|
|
1381
1420
|
: null;
|
|
1382
1421
|
if (fs === null) {
|
|
1383
|
-
|
|
1422
|
+
try {
|
|
1423
|
+
fs = await p.impl.createFileSystem({ name, limits, signal });
|
|
1424
|
+
}
|
|
1425
|
+
catch (err) {
|
|
1426
|
+
throw providerRefusal(this.log, err, { deviceId: id, provider: p.plugin, op: "createFileSystem" }, limits, signal);
|
|
1427
|
+
}
|
|
1384
1428
|
// A lost lease fails this write and leaves the file system alone: createFileSystem returns
|
|
1385
1429
|
// the existing one for a name, so the new holder may already use it, files and all.
|
|
1386
1430
|
await this.fenced(held, id, fence, {
|
|
@@ -1403,11 +1447,7 @@ let SandboxService = class SandboxService {
|
|
|
1403
1447
|
}
|
|
1404
1448
|
catch (err) {
|
|
1405
1449
|
if (!isFileSystemGoneError(err)) {
|
|
1406
|
-
|
|
1407
|
-
// spec §5.3: a provider set to refuse open egress (`openEgress: "off"`) fails here
|
|
1408
|
-
this.log.warn("the sandbox provider did not create an instance in the open tier; check its openEgress setting or lower sandbox.tiers.max", { deviceId: id, provider: p.plugin, err });
|
|
1409
|
-
}
|
|
1410
|
-
throw err;
|
|
1450
|
+
throw providerRefusal(this.log, err, { deviceId: id, provider: p.plugin, op: "create" }, limits, signal);
|
|
1411
1451
|
}
|
|
1412
1452
|
this.log.warn("device file system is gone at the provider; its files are lost", {
|
|
1413
1453
|
deviceId: id,
|
|
@@ -1479,7 +1519,8 @@ let SandboxService = class SandboxService {
|
|
|
1479
1519
|
// the instance may run with half-applied limits and cannot be recreated here: stop it,
|
|
1480
1520
|
// so the next use resumes it and applies them again
|
|
1481
1521
|
await this.quarantine(held, id, handle, p, fence);
|
|
1482
|
-
|
|
1522
|
+
// a provider bound to its file system that refuses the new tier (E2B, `openEgress: "off"`)
|
|
1523
|
+
throw providerRefusal(this.log, err, { deviceId: id, provider: p.plugin, op: "update" }, want, signal);
|
|
1483
1524
|
}
|
|
1484
1525
|
else {
|
|
1485
1526
|
// a new instance gets the limits at create: recreate rather than trust a failed update
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { ScheduledTask, ScheduleMode, SchedulePauseReason, ScheduleStatus, ScheduleTrigger, TaskRun, TaskRunSkipReason, TaskRunStatus } from "./types.js";
|
|
2
|
+
/** Planned occurrences reach this far ahead of now (spec §5.2, "about six weeks"). */
|
|
3
|
+
export declare const CALENDAR_HORIZON_DAYS = 42;
|
|
4
|
+
/** The longest range one request may ask for: a 6-week month grid plus a DST hour (§5.1). */
|
|
5
|
+
export declare const CALENDAR_RANGE_DAYS = 43;
|
|
6
|
+
/** The longest range with `taskId` (the panel's one-day list, §5.4). */
|
|
7
|
+
export declare const CALENDAR_TASK_RANGE_DAYS = 2;
|
|
8
|
+
/** A task-day with more items than this is collapsed into one summary (§5.4). */
|
|
9
|
+
export declare const CALENDAR_COLLAPSE_OVER = 6;
|
|
10
|
+
/**
|
|
11
|
+
* Ticks taken per request after the first local day, across all tasks (§5.5). One tick costs
|
|
12
|
+
* about 150-340 µs (cron's `getNextDateFrom`, measured 2026-11-12 with a ticker built once per
|
|
13
|
+
* task), so 3,000 keeps a worst-case request near one second.
|
|
14
|
+
*/
|
|
15
|
+
export declare const CALENDAR_TICK_BUDGET = 3000;
|
|
16
|
+
/** Entries (`items` + `collapsed`) per request after the first local day (§5.5). */
|
|
17
|
+
export declare const CALENDAR_ITEM_CAP = 3000;
|
|
18
|
+
/** Run rows read per request after the first local day (§5.5). */
|
|
19
|
+
export declare const CALENDAR_RUN_ROW_CAP = 20000;
|
|
20
|
+
/**
|
|
21
|
+
* The first requested local day is always returned whole, outside the limits above; only these
|
|
22
|
+
* safety caps stop it (then nothing is returned, `truncated`, `horizon` = `from`).
|
|
23
|
+
*/
|
|
24
|
+
export declare const CALENDAR_FIRST_DAY_TICK_CAP = 10000;
|
|
25
|
+
export declare const CALENDAR_FIRST_DAY_RUN_CAP = 20000;
|
|
26
|
+
/** The limits of one assembly; tests lower them. */
|
|
27
|
+
export interface CalendarLimits {
|
|
28
|
+
horizonDays: number;
|
|
29
|
+
collapseOver: number;
|
|
30
|
+
/**
|
|
31
|
+
* Ticks taken (planned ticks in the range, the due tick included), after the first day. Not
|
|
32
|
+
* counted: each stream's one lookahead evaluation past its `until` and the doubling search of
|
|
33
|
+
* `scanStep` for a task already due, at most about 2 × tasks evaluations more.
|
|
34
|
+
*/
|
|
35
|
+
tickBudget: number;
|
|
36
|
+
itemCap: number;
|
|
37
|
+
runRowCap: number;
|
|
38
|
+
firstDayTickCap: number;
|
|
39
|
+
firstDayRunCap: number;
|
|
40
|
+
}
|
|
41
|
+
export declare const CALENDAR_LIMITS: CalendarLimits;
|
|
42
|
+
/** How many run rows the service reads: enough to tell where either run cap cuts. */
|
|
43
|
+
export declare const calendarRunReadLimit: (limits: CalendarLimits) => number;
|
|
44
|
+
/** A task an entry of the answer names. */
|
|
45
|
+
export interface CalendarTask {
|
|
46
|
+
id: string;
|
|
47
|
+
name: string;
|
|
48
|
+
agentId: string;
|
|
49
|
+
accountId: string;
|
|
50
|
+
status: ScheduleStatus;
|
|
51
|
+
pauseReason: SchedulePauseReason | null;
|
|
52
|
+
trigger: ScheduleTrigger;
|
|
53
|
+
mode: ScheduleMode;
|
|
54
|
+
jitterSeconds: number;
|
|
55
|
+
nextRunAt: string | null;
|
|
56
|
+
}
|
|
57
|
+
export type CalendarItem = {
|
|
58
|
+
kind: "run";
|
|
59
|
+
taskId: string;
|
|
60
|
+
/** The task run's id. */
|
|
61
|
+
id: string;
|
|
62
|
+
scheduledFor: string;
|
|
63
|
+
firedAt: string | null;
|
|
64
|
+
status: TaskRunStatus;
|
|
65
|
+
skipReason: TaskRunSkipReason | null;
|
|
66
|
+
trial: boolean;
|
|
67
|
+
manual: boolean;
|
|
68
|
+
/** Null for another member's run (admin `all`, spec §15 Q3), as `error` and `missingGrants`. */
|
|
69
|
+
conversationId: string | null;
|
|
70
|
+
error: string | null;
|
|
71
|
+
missingGrants: number | null;
|
|
72
|
+
} | {
|
|
73
|
+
kind: "occurrence";
|
|
74
|
+
taskId: string;
|
|
75
|
+
/** The tick, before jitter. */
|
|
76
|
+
scheduledFor: string;
|
|
77
|
+
/** When it fires: the tick plus the task's jitter. */
|
|
78
|
+
at: string;
|
|
79
|
+
};
|
|
80
|
+
/** A task's items of one local day, summarized (§5.4). */
|
|
81
|
+
export interface CalendarCollapsed {
|
|
82
|
+
taskId: string;
|
|
83
|
+
/** YYYY-MM-DD in the request's `timeZone`. */
|
|
84
|
+
day: string;
|
|
85
|
+
count: number;
|
|
86
|
+
upcoming: number;
|
|
87
|
+
running: number;
|
|
88
|
+
completed: number;
|
|
89
|
+
failed: number;
|
|
90
|
+
skipped: number;
|
|
91
|
+
/** The earliest and latest `scheduledFor` of the day's items. */
|
|
92
|
+
first: string;
|
|
93
|
+
last: string;
|
|
94
|
+
}
|
|
95
|
+
export interface CalendarAnswer {
|
|
96
|
+
tasks: CalendarTask[];
|
|
97
|
+
items: CalendarItem[];
|
|
98
|
+
collapsed: CalendarCollapsed[];
|
|
99
|
+
/** Nothing is returned after it: 42 days ahead, or the cut. */
|
|
100
|
+
horizon: string;
|
|
101
|
+
/** A limit cut the range at a whole local day. */
|
|
102
|
+
truncated: boolean;
|
|
103
|
+
}
|
|
104
|
+
export interface CalendarInput {
|
|
105
|
+
/** The live tasks the viewer may see in this request. */
|
|
106
|
+
tasks: readonly ScheduledTask[];
|
|
107
|
+
/**
|
|
108
|
+
* Their runs with `scheduledFor` in `[from, to)`, trial included, ordered by `scheduledFor`, at
|
|
109
|
+
* most {@link calendarRunReadLimit} (rows past it are not read; the range is cut before them).
|
|
110
|
+
*/
|
|
111
|
+
runs: readonly TaskRun[];
|
|
112
|
+
/** The viewer: another creator's runs lose `conversationId`, `error` and `missingGrants`. */
|
|
113
|
+
viewerAccountId: string;
|
|
114
|
+
from: Date;
|
|
115
|
+
to: Date;
|
|
116
|
+
/** The viewer's zone: local days for the collapse and the cut. */
|
|
117
|
+
timeZone: string;
|
|
118
|
+
now: Date;
|
|
119
|
+
/** False when the org turned scheduled tasks off: nothing would fire, so nothing is planned. */
|
|
120
|
+
plan: boolean;
|
|
121
|
+
/** The org's catch-up window, as the scanner reads it. */
|
|
122
|
+
catchUpWindowMinutes: number;
|
|
123
|
+
/** False for a `taskId` read: every item, never collapsed. */
|
|
124
|
+
collapse: boolean;
|
|
125
|
+
}
|
|
126
|
+
/** The calendar answer from the rows (spec §5.2–§5.5). */
|
|
127
|
+
export declare function assembleCalendar(input: CalendarInput, limits?: CalendarLimits): CalendarAnswer;
|
|
128
|
+
/** YYYY-MM-DD of the instant (epoch ms) in `timeZone`. */
|
|
129
|
+
export declare function dayKey(ms: number, timeZone: string): string;
|
|
130
|
+
/**
|
|
131
|
+
* The first instant (epoch ms) of the local day of `ms` in `timeZone`: midnight, or the end of a
|
|
132
|
+
* DST gap that swallows it. A day is at most 25 hours long, so 27 hours back is an earlier day.
|
|
133
|
+
*/
|
|
134
|
+
export declare function startOfLocalDay(ms: number, timeZone: string): number;
|