@rivet-dev/agentos-core 0.2.8-rc.1 → 0.2.8-rc.3
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/README.md +41 -38
- package/dist/agent-os.d.ts +189 -231
- package/dist/agent-os.js +756 -1162
- package/dist/agentos-package.d.ts +5 -3
- package/dist/agentos-package.js +5 -2
- package/dist/{host-tools-zod.d.ts → bindings-zod.d.ts} +1 -1
- package/dist/{host-tools-zod.js → bindings-zod.js} +27 -20
- package/dist/bindings.d.ts +43 -0
- package/dist/bindings.js +34 -0
- package/dist/cron/cron-manager.js +43 -10
- package/dist/cron/index.d.ts +1 -1
- package/dist/cron/types.d.ts +25 -9
- package/dist/filesystem-snapshot.d.ts +1 -2
- package/dist/filesystem-snapshot.js +0 -43
- package/dist/generated/AcpLimitsConfig.d.ts +16 -0
- package/dist/generated/BindingLimitsConfig.d.ts +10 -0
- package/dist/generated/CreateVmConfig.d.ts +2 -0
- package/dist/generated/ProcessLimitsConfig.d.ts +7 -0
- package/dist/generated/ProcessLimitsConfig.js +2 -0
- package/dist/generated/VmGroupConfig.d.ts +5 -0
- package/dist/generated/VmGroupConfig.js +2 -0
- package/dist/generated/VmLimitsConfig.d.ts +4 -2
- package/dist/generated/VmUserAccountConfig.d.ts +9 -0
- package/dist/generated/VmUserAccountConfig.js +2 -0
- package/dist/generated/VmUserConfig.d.ts +19 -0
- package/dist/generated/WasmLimitsConfig.d.ts +1 -0
- package/dist/index.d.ts +4 -5
- package/dist/index.js +4 -5
- package/dist/layers.d.ts +5 -2
- package/dist/layers.js +0 -185
- package/dist/options-schema.d.ts +133 -31
- package/dist/options-schema.js +143 -26
- package/dist/runtime-compat.d.ts +6 -35
- package/dist/runtime-compat.js +84 -372
- package/dist/runtime.d.ts +5 -1
- package/dist/sandbox.d.ts +4 -4
- package/dist/sandbox.js +4 -4
- package/dist/session-api.d.ts +180 -0
- package/dist/session-api.js +1 -0
- package/dist/sidecar/agentos-protocol.d.ts +429 -29
- package/dist/sidecar/agentos-protocol.js +691 -93
- package/dist/sidecar/rpc-client.d.ts +18 -6
- package/dist/sidecar/rpc-client.js +78 -31
- package/dist/test/runtime.d.ts +2 -1
- package/dist/test/runtime.js +2 -1
- package/dist/test/terminal-harness.js +0 -3
- package/dist/types.d.ts +4 -5
- package/package.json +21 -20
- package/dist/agent-session-types.d.ts +0 -67
- package/dist/generated/ToolLimitsConfig.d.ts +0 -10
- package/dist/host-tools.d.ts +0 -45
- package/dist/host-tools.js +0 -35
- package/dist/overlay-filesystem.d.ts +0 -19
- package/dist/overlay-filesystem.js +0 -645
- /package/dist/generated/{ToolLimitsConfig.js → BindingLimitsConfig.js} +0 -0
- /package/dist/{agent-session-types.js → generated/VmUserConfig.js} +0 -0
|
@@ -21,9 +21,11 @@ export type PackageRef = ManifestPackageRef;
|
|
|
21
21
|
export type SoftwarePackageRef = {
|
|
22
22
|
packagePath: string;
|
|
23
23
|
};
|
|
24
|
-
/**
|
|
25
|
-
export
|
|
26
|
-
|
|
24
|
+
/** Portable descriptor used to link a package into a running VM. */
|
|
25
|
+
export interface PackageDescriptor {
|
|
26
|
+
path: string;
|
|
27
|
+
}
|
|
28
|
+
/** Discriminate the path-only package reference. */
|
|
27
29
|
export declare function isPackageDescriptor(value: unknown): value is PackageDescriptor;
|
|
28
30
|
export declare function readAgentosPackageManifest(dir: string): AgentosPackageManifest;
|
|
29
31
|
export declare function tryReadAgentosPackageManifest(dir: string): AgentosPackageManifest | undefined;
|
package/dist/agentos-package.js
CHANGED
|
@@ -17,9 +17,12 @@ import { join } from "node:path";
|
|
|
17
17
|
export const OPT_AGENTOS_ROOT = "/opt/agentos";
|
|
18
18
|
/** The symlink farm on `$PATH` (commands link here). */
|
|
19
19
|
export const OPT_AGENTOS_BIN = "/opt/agentos/bin";
|
|
20
|
-
/** Discriminate the
|
|
20
|
+
/** Discriminate the path-only package reference. */
|
|
21
21
|
export function isPackageDescriptor(value) {
|
|
22
|
-
return typeof value === "
|
|
22
|
+
return (typeof value === "object" &&
|
|
23
|
+
value !== null &&
|
|
24
|
+
!Array.isArray(value) &&
|
|
25
|
+
typeof value.path === "string");
|
|
23
26
|
}
|
|
24
27
|
export function readAgentosPackageManifest(dir) {
|
|
25
28
|
const manifestPath = join(dir, "agentos-package.json");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ZodType } from "zod";
|
|
2
|
-
export declare class
|
|
2
|
+
export declare class BindingSchemaConversionError extends Error {
|
|
3
3
|
readonly path: string;
|
|
4
4
|
readonly zodType: string;
|
|
5
5
|
constructor(path: string, zodType: string, details?: string);
|
|
@@ -15,7 +15,7 @@ const UNSUPPORTED_TYPES = new Set([
|
|
|
15
15
|
"pipe",
|
|
16
16
|
"tuple",
|
|
17
17
|
]);
|
|
18
|
-
export class
|
|
18
|
+
export class BindingSchemaConversionError extends Error {
|
|
19
19
|
path;
|
|
20
20
|
zodType;
|
|
21
21
|
constructor(path, zodType, details) {
|
|
@@ -25,7 +25,7 @@ export class HostToolSchemaConversionError extends Error {
|
|
|
25
25
|
]
|
|
26
26
|
.filter(Boolean)
|
|
27
27
|
.join(" "));
|
|
28
|
-
this.name = "
|
|
28
|
+
this.name = "BindingSchemaConversionError";
|
|
29
29
|
this.path = path;
|
|
30
30
|
this.zodType = zodType;
|
|
31
31
|
}
|
|
@@ -50,7 +50,10 @@ function normalizeTypeName(schema) {
|
|
|
50
50
|
if (constructorName === "discriminatedunion" || "discriminator" in def) {
|
|
51
51
|
return "discriminatedunion";
|
|
52
52
|
}
|
|
53
|
-
const rawTypeName = String(def.typeName ??
|
|
53
|
+
const rawTypeName = String(def.typeName ??
|
|
54
|
+
def.type ??
|
|
55
|
+
schema.type ??
|
|
56
|
+
constructorName);
|
|
54
57
|
return rawTypeName.replace(/^Zod/, "").toLowerCase();
|
|
55
58
|
}
|
|
56
59
|
function displayTypeName(typeName) {
|
|
@@ -93,24 +96,24 @@ function isCustomRefinement(check) {
|
|
|
93
96
|
}
|
|
94
97
|
function validateChecks(schema, path, typeName) {
|
|
95
98
|
if (getChecks(schema).some(isCustomRefinement)) {
|
|
96
|
-
throw new
|
|
99
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "custom refinements cannot be represented faithfully in JSON Schema");
|
|
97
100
|
}
|
|
98
101
|
}
|
|
99
102
|
function validateSchema(schema, path) {
|
|
100
103
|
const typeName = normalizeTypeName(schema);
|
|
101
104
|
if (metadataProducesRefs(schema)) {
|
|
102
|
-
throw new
|
|
105
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "metadata that emits $ref/$defs is not supported");
|
|
103
106
|
}
|
|
104
107
|
if (UNSUPPORTED_TYPES.has(typeName)) {
|
|
105
|
-
throw new
|
|
108
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName));
|
|
106
109
|
}
|
|
107
110
|
if (typeName === "discriminatedunion") {
|
|
108
|
-
throw new
|
|
111
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName));
|
|
109
112
|
}
|
|
110
113
|
if (TRANSPARENT_WRAPPER_TYPES.has(typeName)) {
|
|
111
114
|
const inner = getInnerSchema(schema);
|
|
112
115
|
if (!inner) {
|
|
113
|
-
throw new
|
|
116
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "wrapper schema is missing its inner schema");
|
|
114
117
|
}
|
|
115
118
|
validateSchema(inner, path);
|
|
116
119
|
return;
|
|
@@ -118,7 +121,7 @@ function validateSchema(schema, path) {
|
|
|
118
121
|
if (typeName === "nullable") {
|
|
119
122
|
const inner = getInnerSchema(schema);
|
|
120
123
|
if (!inner) {
|
|
121
|
-
throw new
|
|
124
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "nullable schema is missing its inner schema");
|
|
122
125
|
}
|
|
123
126
|
validateSchema(inner, path);
|
|
124
127
|
return;
|
|
@@ -138,7 +141,7 @@ function validateSchema(schema, path) {
|
|
|
138
141
|
const def = getSchemaDef(schema);
|
|
139
142
|
const itemSchema = (def.element ?? def.type);
|
|
140
143
|
if (!itemSchema) {
|
|
141
|
-
throw new
|
|
144
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "array schema is missing its item schema");
|
|
142
145
|
}
|
|
143
146
|
validateSchema(itemSchema, `${path}[]`);
|
|
144
147
|
return;
|
|
@@ -148,11 +151,11 @@ function validateSchema(schema, path) {
|
|
|
148
151
|
const keySchema = def.keyType;
|
|
149
152
|
const valueSchema = def.valueType;
|
|
150
153
|
if (!keySchema || !valueSchema) {
|
|
151
|
-
throw new
|
|
154
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "record schema is missing its key or value schema");
|
|
152
155
|
}
|
|
153
156
|
const keyTypeName = normalizeTypeName(keySchema);
|
|
154
157
|
if (keyTypeName !== "string" || getChecks(keySchema).length > 0) {
|
|
155
|
-
throw new
|
|
158
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "record keys must be unconstrained strings");
|
|
156
159
|
}
|
|
157
160
|
validateSchema(valueSchema, `${path}<record-value>`);
|
|
158
161
|
return;
|
|
@@ -160,7 +163,7 @@ function validateSchema(schema, path) {
|
|
|
160
163
|
if (typeName === "union") {
|
|
161
164
|
const options = getSchemaDef(schema).options;
|
|
162
165
|
if (!Array.isArray(options) || options.length === 0) {
|
|
163
|
-
throw new
|
|
166
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "union schema is missing its options");
|
|
164
167
|
}
|
|
165
168
|
for (let index = 0; index < options.length; index += 1) {
|
|
166
169
|
validateSchema(options[index], `${path}<union:${index}>`);
|
|
@@ -176,8 +179,9 @@ function validateSchema(schema, path) {
|
|
|
176
179
|
: [];
|
|
177
180
|
const [literalValue] = literalValues;
|
|
178
181
|
if (literalValues.length !== 1 ||
|
|
179
|
-
!("string number boolean".split(" ").includes(typeof literalValue) ||
|
|
180
|
-
|
|
182
|
+
!("string number boolean".split(" ").includes(typeof literalValue) ||
|
|
183
|
+
literalValue === null)) {
|
|
184
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName), "literal values must be JSON primitives");
|
|
181
185
|
}
|
|
182
186
|
return;
|
|
183
187
|
}
|
|
@@ -188,7 +192,7 @@ function validateSchema(schema, path) {
|
|
|
188
192
|
typeName === "nativeenum") {
|
|
189
193
|
return;
|
|
190
194
|
}
|
|
191
|
-
throw new
|
|
195
|
+
throw new BindingSchemaConversionError(path, displayTypeName(typeName));
|
|
192
196
|
}
|
|
193
197
|
function sanitizeJsonSchema(value) {
|
|
194
198
|
if (Array.isArray(value)) {
|
|
@@ -203,7 +207,9 @@ function sanitizeJsonSchema(value) {
|
|
|
203
207
|
if (key === "$schema") {
|
|
204
208
|
continue;
|
|
205
209
|
}
|
|
206
|
-
if (key === "additionalProperties" &&
|
|
210
|
+
if (key === "additionalProperties" &&
|
|
211
|
+
entry === false &&
|
|
212
|
+
record.type === "object") {
|
|
207
213
|
continue;
|
|
208
214
|
}
|
|
209
215
|
sanitized[key] = sanitizeJsonSchema(entry);
|
|
@@ -243,8 +249,9 @@ function generateJsonSchema(schema) {
|
|
|
243
249
|
$refStrategy: "none",
|
|
244
250
|
target: "jsonSchema7",
|
|
245
251
|
});
|
|
246
|
-
if (!generated ||
|
|
247
|
-
|
|
252
|
+
if (!generated ||
|
|
253
|
+
(typeof generated === "object" && Object.keys(generated).length === 0)) {
|
|
254
|
+
throw new BindingSchemaConversionError("$", displayTypeName(normalizeTypeName(schema)), "schema cannot be converted to JSON Schema");
|
|
248
255
|
}
|
|
249
256
|
return generated;
|
|
250
257
|
}
|
|
@@ -253,7 +260,7 @@ export function zodToJsonSchema(schema) {
|
|
|
253
260
|
const jsonSchema = generateJsonSchema(schema);
|
|
254
261
|
const unsupportedKeyword = findUnsupportedGeneratedKeyword(jsonSchema, "$");
|
|
255
262
|
if (unsupportedKeyword) {
|
|
256
|
-
throw new
|
|
263
|
+
throw new BindingSchemaConversionError("$", displayTypeName(normalizeTypeName(schema)), `${unsupportedKeyword.keyword} emitted at ${unsupportedKeyword.path} is not supported`);
|
|
257
264
|
}
|
|
258
265
|
const sanitized = sanitizeJsonSchema(jsonSchema);
|
|
259
266
|
const description = getDescription(schema);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ZodType } from "zod";
|
|
2
|
+
/** Maximum length for binding descriptions (characters). */
|
|
3
|
+
export declare const MAX_BINDING_DESCRIPTION_LENGTH = 200;
|
|
4
|
+
/**
|
|
5
|
+
* A single binding that executes on the host.
|
|
6
|
+
*/
|
|
7
|
+
export interface Binding<INPUT = any, OUTPUT = any> {
|
|
8
|
+
/** Description shown to the agent in --help and prompt docs. Max 200 characters. */
|
|
9
|
+
description: string;
|
|
10
|
+
/** Zod schema for the input. Drives CLI flag generation and validation. */
|
|
11
|
+
inputSchema: ZodType<INPUT>;
|
|
12
|
+
/** Runs on the host when the agent invokes the binding. */
|
|
13
|
+
execute: (input: INPUT) => Promise<OUTPUT> | OUTPUT;
|
|
14
|
+
/** Examples included in auto-generated prompt docs. */
|
|
15
|
+
examples?: BindingExample<INPUT>[];
|
|
16
|
+
/** Timeout in ms. Default: 30000. */
|
|
17
|
+
timeout?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface BindingExample<INPUT = any> {
|
|
20
|
+
/** Human description of what this example does. */
|
|
21
|
+
description: string;
|
|
22
|
+
/** The input args for the example. */
|
|
23
|
+
input: INPUT;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A named collection of bindings. Becomes a CLI binary: agentos-{name}.
|
|
27
|
+
*/
|
|
28
|
+
export interface Bindings {
|
|
29
|
+
/** Collection name. Must be lowercase alphanumeric + hyphens. Becomes the CLI suffix: agentos-{name}. */
|
|
30
|
+
name: string;
|
|
31
|
+
/** Description shown in `agentos list-bindings` and prompt docs. */
|
|
32
|
+
description: string;
|
|
33
|
+
/** The bindings in this collection. Keys become subcommands. */
|
|
34
|
+
bindings: Record<string, Binding>;
|
|
35
|
+
}
|
|
36
|
+
/** Helper to create a binding with type inference. */
|
|
37
|
+
export declare function binding<INPUT, OUTPUT>(def: Binding<INPUT, OUTPUT>): Binding<INPUT, OUTPUT>;
|
|
38
|
+
/** Helper to create a named binding collection. */
|
|
39
|
+
export declare function bindings(def: Bindings): Bindings;
|
|
40
|
+
/**
|
|
41
|
+
* Validate every binding collection and binding.
|
|
42
|
+
*/
|
|
43
|
+
export declare function validateBindings(collections: Bindings[]): void;
|
package/dist/bindings.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Maximum length for binding descriptions (characters). */
|
|
2
|
+
export const MAX_BINDING_DESCRIPTION_LENGTH = 200;
|
|
3
|
+
/** Helper to create a binding with type inference. */
|
|
4
|
+
export function binding(def) {
|
|
5
|
+
return def;
|
|
6
|
+
}
|
|
7
|
+
/** Helper to create a named binding collection. */
|
|
8
|
+
export function bindings(def) {
|
|
9
|
+
return def;
|
|
10
|
+
}
|
|
11
|
+
const BINDING_COMMAND_NAME_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
12
|
+
function validateBindingCommandName(kind, name) {
|
|
13
|
+
if (BINDING_COMMAND_NAME_RE.test(name)) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
throw new Error(`${kind} name "${name}" must be lowercase alphanumeric with optional single hyphen separators`);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Validate every binding collection and binding.
|
|
20
|
+
*/
|
|
21
|
+
export function validateBindings(collections) {
|
|
22
|
+
for (const collection of collections) {
|
|
23
|
+
validateBindingCommandName("Binding collection", collection.name);
|
|
24
|
+
if (collection.description.length > MAX_BINDING_DESCRIPTION_LENGTH) {
|
|
25
|
+
throw new Error(`Binding collection "${collection.name}" description is ${collection.description.length} characters, max is ${MAX_BINDING_DESCRIPTION_LENGTH}`);
|
|
26
|
+
}
|
|
27
|
+
for (const [bindingName, definition] of Object.entries(collection.bindings)) {
|
|
28
|
+
validateBindingCommandName("Binding", bindingName);
|
|
29
|
+
if (definition.description.length > MAX_BINDING_DESCRIPTION_LENGTH) {
|
|
30
|
+
throw new Error(`Binding "${collection.name}/${bindingName}" description is ${definition.description.length} characters, max is ${MAX_BINDING_DESCRIPTION_LENGTH}`);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { resolveSchedule, validateScheduleForRegistration, } from "./parse-schedule.js";
|
|
3
|
+
function describeAction(action) {
|
|
4
|
+
switch (action.type) {
|
|
5
|
+
case "session":
|
|
6
|
+
return {
|
|
7
|
+
type: "session",
|
|
8
|
+
agentType: action.agentType,
|
|
9
|
+
prompt: action.prompt,
|
|
10
|
+
...(action.options === undefined
|
|
11
|
+
? {}
|
|
12
|
+
: { options: structuredClone(action.options) }),
|
|
13
|
+
};
|
|
14
|
+
case "exec":
|
|
15
|
+
return {
|
|
16
|
+
type: "exec",
|
|
17
|
+
command: action.command,
|
|
18
|
+
...(action.args === undefined ? {} : { args: [...action.args] }),
|
|
19
|
+
};
|
|
20
|
+
case "callback":
|
|
21
|
+
return { type: "callback" };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
3
24
|
/**
|
|
4
25
|
* Compute the next fire time for a schedule string. Returns undefined if
|
|
5
26
|
* the schedule is a one-shot ISO timestamp in the past or if croner
|
|
@@ -58,10 +79,10 @@ export class CronManager {
|
|
|
58
79
|
result.push({
|
|
59
80
|
id: state.id,
|
|
60
81
|
schedule: state.schedule,
|
|
61
|
-
action: state.action,
|
|
82
|
+
action: describeAction(state.action),
|
|
62
83
|
overlap: state.overlap,
|
|
63
|
-
lastRun: state.lastRun,
|
|
64
|
-
nextRun: state.nextRun,
|
|
84
|
+
lastRun: state.lastRun?.toISOString(),
|
|
85
|
+
nextRun: state.nextRun?.toISOString(),
|
|
65
86
|
runCount: state.runCount,
|
|
66
87
|
running: state.running,
|
|
67
88
|
});
|
|
@@ -103,14 +124,18 @@ export class CronManager {
|
|
|
103
124
|
state.running = true;
|
|
104
125
|
state.lastRun = new Date();
|
|
105
126
|
state.runCount++;
|
|
106
|
-
this.emit({
|
|
127
|
+
this.emit({
|
|
128
|
+
type: "cron:fire",
|
|
129
|
+
jobId: state.id,
|
|
130
|
+
time: new Date().toISOString(),
|
|
131
|
+
});
|
|
107
132
|
const startTime = Date.now();
|
|
108
133
|
try {
|
|
109
134
|
await this.runAction(state.action);
|
|
110
135
|
this.emit({
|
|
111
136
|
type: "cron:complete",
|
|
112
137
|
jobId: state.id,
|
|
113
|
-
time: new Date(),
|
|
138
|
+
time: new Date().toISOString(),
|
|
114
139
|
durationMs: Date.now() - startTime,
|
|
115
140
|
});
|
|
116
141
|
}
|
|
@@ -118,8 +143,8 @@ export class CronManager {
|
|
|
118
143
|
this.emit({
|
|
119
144
|
type: "cron:error",
|
|
120
145
|
jobId: state.id,
|
|
121
|
-
time: new Date(),
|
|
122
|
-
error: error,
|
|
146
|
+
time: new Date().toISOString(),
|
|
147
|
+
error: error instanceof Error ? error.message : String(error),
|
|
123
148
|
});
|
|
124
149
|
}
|
|
125
150
|
finally {
|
|
@@ -135,12 +160,20 @@ export class CronManager {
|
|
|
135
160
|
async runAction(action) {
|
|
136
161
|
switch (action.type) {
|
|
137
162
|
case "session": {
|
|
138
|
-
const
|
|
163
|
+
const sessionId = `cron-${randomUUID()}`;
|
|
164
|
+
await this.vm.openSession({
|
|
165
|
+
...action.options,
|
|
166
|
+
sessionId,
|
|
167
|
+
agent: action.agentType,
|
|
168
|
+
});
|
|
139
169
|
try {
|
|
140
|
-
await this.vm.prompt(
|
|
170
|
+
await this.vm.prompt({
|
|
171
|
+
sessionId,
|
|
172
|
+
content: [{ type: "text", text: action.prompt }],
|
|
173
|
+
});
|
|
141
174
|
}
|
|
142
175
|
finally {
|
|
143
|
-
this.vm.
|
|
176
|
+
await this.vm.deleteSession({ sessionId });
|
|
144
177
|
}
|
|
145
178
|
break;
|
|
146
179
|
}
|
package/dist/cron/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { CronManager } from "./cron-manager.js";
|
|
|
2
2
|
export { InvalidScheduleError, PastScheduleError, } from "./parse-schedule.js";
|
|
3
3
|
export type { ScheduleDriver, ScheduleEntry, ScheduleHandle, } from "./schedule-driver.js";
|
|
4
4
|
export { TimerScheduleDriver } from "./timer-driver.js";
|
|
5
|
-
export type { CronAction, CronEvent, CronEventHandler, CronJob, CronJobInfo, CronJobOptions, } from "./types.js";
|
|
5
|
+
export type { CronAction, CronActionInfo, CronEvent, CronEventHandler, CronJob, CronJobInfo, CronJobOptions, } from "./types.js";
|
package/dist/cron/types.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { OpenSessionInput } from "../session-api.js";
|
|
2
2
|
import type { AgentType } from "../types.js";
|
|
3
3
|
export type CronAction = {
|
|
4
4
|
type: "session";
|
|
5
5
|
agentType: AgentType;
|
|
6
6
|
prompt: string;
|
|
7
|
-
options?:
|
|
7
|
+
options?: Omit<OpenSessionInput, "agent" | "sessionId">;
|
|
8
8
|
} | {
|
|
9
9
|
type: "exec";
|
|
10
10
|
command: string;
|
|
@@ -13,6 +13,22 @@ export type CronAction = {
|
|
|
13
13
|
type: "callback";
|
|
14
14
|
fn: () => void | Promise<void>;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Serializable description of a scheduled action. Callback jobs deliberately
|
|
18
|
+
* expose only their kind: the host closure is execution state, not job data.
|
|
19
|
+
*/
|
|
20
|
+
export type CronActionInfo = {
|
|
21
|
+
type: "session";
|
|
22
|
+
agentType: AgentType;
|
|
23
|
+
prompt: string;
|
|
24
|
+
options?: Omit<OpenSessionInput, "agent" | "sessionId">;
|
|
25
|
+
} | {
|
|
26
|
+
type: "exec";
|
|
27
|
+
command: string;
|
|
28
|
+
args?: string[];
|
|
29
|
+
} | {
|
|
30
|
+
type: "callback";
|
|
31
|
+
};
|
|
16
32
|
export interface CronJobOptions {
|
|
17
33
|
/** Optional ID. Auto-generated UUID if omitted. */
|
|
18
34
|
id?: string;
|
|
@@ -30,26 +46,26 @@ export interface CronJob {
|
|
|
30
46
|
export interface CronJobInfo {
|
|
31
47
|
id: string;
|
|
32
48
|
schedule: string;
|
|
33
|
-
action:
|
|
49
|
+
action: CronActionInfo;
|
|
34
50
|
overlap: "allow" | "skip" | "queue";
|
|
35
|
-
lastRun?:
|
|
36
|
-
nextRun?:
|
|
51
|
+
lastRun?: string;
|
|
52
|
+
nextRun?: string;
|
|
37
53
|
runCount: number;
|
|
38
54
|
running: boolean;
|
|
39
55
|
}
|
|
40
56
|
export type CronEvent = {
|
|
41
57
|
type: "cron:fire";
|
|
42
58
|
jobId: string;
|
|
43
|
-
time:
|
|
59
|
+
time: string;
|
|
44
60
|
} | {
|
|
45
61
|
type: "cron:complete";
|
|
46
62
|
jobId: string;
|
|
47
|
-
time:
|
|
63
|
+
time: string;
|
|
48
64
|
durationMs: number;
|
|
49
65
|
} | {
|
|
50
66
|
type: "cron:error";
|
|
51
67
|
jobId: string;
|
|
52
|
-
time:
|
|
53
|
-
error:
|
|
68
|
+
time: string;
|
|
69
|
+
error: string;
|
|
54
70
|
};
|
|
55
71
|
export type CronEventHandler = (event: CronEvent) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { VirtualFileSystem } from "./runtime-compat.js";
|
|
2
2
|
export interface FilesystemEntry {
|
|
3
3
|
path: string;
|
|
4
4
|
type: "directory" | "file" | "symlink";
|
|
@@ -10,5 +10,4 @@ export interface FilesystemEntry {
|
|
|
10
10
|
target?: string;
|
|
11
11
|
}
|
|
12
12
|
export declare function sortFilesystemEntries(entries: FilesystemEntry[]): FilesystemEntry[];
|
|
13
|
-
export declare function createFilesystemFromEntries(entries: FilesystemEntry[]): Promise<VirtualFileSystem>;
|
|
14
13
|
export declare function snapshotVirtualFilesystem(filesystem: VirtualFileSystem, rootPath?: string): Promise<FilesystemEntry[]>;
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import * as posixPath from "node:path/posix";
|
|
2
|
-
import { createInMemoryFileSystem, } from "./runtime-compat.js";
|
|
3
|
-
function parseMode(mode) {
|
|
4
|
-
return Number.parseInt(mode, 8);
|
|
5
|
-
}
|
|
6
2
|
export function sortFilesystemEntries(entries) {
|
|
7
3
|
return [...entries].sort((a, b) => {
|
|
8
4
|
const depthA = a.path === "/" ? 0 : a.path.split("/").filter(Boolean).length;
|
|
@@ -13,45 +9,6 @@ export function sortFilesystemEntries(entries) {
|
|
|
13
9
|
return a.path.localeCompare(b.path);
|
|
14
10
|
});
|
|
15
11
|
}
|
|
16
|
-
async function applyDirectory(filesystem, entry) {
|
|
17
|
-
if (entry.path !== "/") {
|
|
18
|
-
await filesystem.mkdir(entry.path, { recursive: true });
|
|
19
|
-
}
|
|
20
|
-
await filesystem.chmod(entry.path, parseMode(entry.mode));
|
|
21
|
-
await filesystem.chown(entry.path, entry.uid, entry.gid);
|
|
22
|
-
}
|
|
23
|
-
async function applyFile(filesystem, entry) {
|
|
24
|
-
const content = entry.content ?? "";
|
|
25
|
-
await filesystem.writeFile(entry.path, entry.encoding === "base64" ? Buffer.from(content, "base64") : content);
|
|
26
|
-
await filesystem.chmod(entry.path, parseMode(entry.mode));
|
|
27
|
-
await filesystem.chown(entry.path, entry.uid, entry.gid);
|
|
28
|
-
}
|
|
29
|
-
async function applySymlink(filesystem, entry) {
|
|
30
|
-
if (!entry.target) {
|
|
31
|
-
throw new Error(`Missing symlink target for ${entry.path}`);
|
|
32
|
-
}
|
|
33
|
-
await filesystem.symlink(entry.target, entry.path);
|
|
34
|
-
}
|
|
35
|
-
export async function createFilesystemFromEntries(entries) {
|
|
36
|
-
const filesystem = createInMemoryFileSystem();
|
|
37
|
-
const sortedEntries = sortFilesystemEntries(entries);
|
|
38
|
-
for (const entry of sortedEntries) {
|
|
39
|
-
if (entry.type === "directory") {
|
|
40
|
-
await applyDirectory(filesystem, entry);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
for (const entry of sortedEntries) {
|
|
44
|
-
if (entry.type === "file") {
|
|
45
|
-
await applyFile(filesystem, entry);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
for (const entry of sortedEntries) {
|
|
49
|
-
if (entry.type === "symlink") {
|
|
50
|
-
await applySymlink(filesystem, entry);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
return filesystem;
|
|
54
|
-
}
|
|
55
12
|
function toModeString(mode) {
|
|
56
13
|
return `0${(mode & 0o7777).toString(8)}`;
|
|
57
14
|
}
|
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
export type AcpLimitsConfig = {
|
|
2
2
|
maxReadLineBytes?: number;
|
|
3
3
|
stdoutBufferByteLimit?: number;
|
|
4
|
+
maxCompletedMessageBytes?: number;
|
|
5
|
+
maxTurnOutputBytes?: number;
|
|
6
|
+
maxPromptBytes?: number;
|
|
7
|
+
maxPromptBlocks?: number;
|
|
8
|
+
maxFallbackContinuationBytes?: number;
|
|
9
|
+
maxSessionHistoryBytes?: number;
|
|
10
|
+
maxSessionHistoryEvents?: number;
|
|
11
|
+
maxHistoryPageEntries?: number;
|
|
12
|
+
maxSessionListEntries?: number;
|
|
13
|
+
maxSessionsPerVm?: number;
|
|
14
|
+
maxPromptsPerSession?: number;
|
|
15
|
+
maxPromptsPerVm?: number;
|
|
16
|
+
maxPendingPermissionsPerSession?: number;
|
|
17
|
+
maxPendingPermissionsPerVm?: number;
|
|
18
|
+
maxPermissionOutcomesPerSession?: number;
|
|
19
|
+
maxPermissionOutcomesPerVm?: number;
|
|
4
20
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type BindingLimitsConfig = {
|
|
2
|
+
defaultBindingTimeoutMs?: number;
|
|
3
|
+
maxBindingTimeoutMs?: number;
|
|
4
|
+
maxRegisteredCollections?: number;
|
|
5
|
+
maxRegisteredBindingsPerVm?: number;
|
|
6
|
+
maxBindingsPerCollection?: number;
|
|
7
|
+
maxBindingSchemaBytes?: number;
|
|
8
|
+
maxExamplesPerBinding?: number;
|
|
9
|
+
maxBindingExampleInputBytes?: number;
|
|
10
|
+
};
|
|
@@ -5,6 +5,7 @@ import type { RootFilesystemConfig } from "./RootFilesystemConfig.js";
|
|
|
5
5
|
import type { VmDnsConfig } from "./VmDnsConfig.js";
|
|
6
6
|
import type { VmLimitsConfig } from "./VmLimitsConfig.js";
|
|
7
7
|
import type { VmListenPolicyConfig } from "./VmListenPolicyConfig.js";
|
|
8
|
+
import type { VmUserConfig } from "./VmUserConfig.js";
|
|
8
9
|
/**
|
|
9
10
|
* Canonical Rust-side VM config. Unknown fields must stay rejected here and in
|
|
10
11
|
* the TS preflight schema at
|
|
@@ -14,6 +15,7 @@ import type { VmListenPolicyConfig } from "./VmListenPolicyConfig.js";
|
|
|
14
15
|
export type CreateVmConfig = {
|
|
15
16
|
cwd?: string;
|
|
16
17
|
env: Record<string, string>;
|
|
18
|
+
user?: VmUserConfig;
|
|
17
19
|
rootFilesystem: RootFilesystemConfig;
|
|
18
20
|
permissions?: PermissionsPolicy;
|
|
19
21
|
limits?: VmLimitsConfig;
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import type { AcpLimitsConfig } from "./AcpLimitsConfig.js";
|
|
2
|
+
import type { BindingLimitsConfig } from "./BindingLimitsConfig.js";
|
|
2
3
|
import type { HttpLimitsConfig } from "./HttpLimitsConfig.js";
|
|
3
4
|
import type { JsRuntimeLimitsConfig } from "./JsRuntimeLimitsConfig.js";
|
|
4
5
|
import type { PluginLimitsConfig } from "./PluginLimitsConfig.js";
|
|
6
|
+
import type { ProcessLimitsConfig } from "./ProcessLimitsConfig.js";
|
|
5
7
|
import type { PythonLimitsConfig } from "./PythonLimitsConfig.js";
|
|
6
8
|
import type { ResourceLimitsConfig } from "./ResourceLimitsConfig.js";
|
|
7
|
-
import type { ToolLimitsConfig } from "./ToolLimitsConfig.js";
|
|
8
9
|
import type { WasmLimitsConfig } from "./WasmLimitsConfig.js";
|
|
9
10
|
export type VmLimitsConfig = {
|
|
10
11
|
resources?: ResourceLimitsConfig;
|
|
11
12
|
http?: HttpLimitsConfig;
|
|
12
|
-
|
|
13
|
+
bindings?: BindingLimitsConfig;
|
|
13
14
|
plugins?: PluginLimitsConfig;
|
|
14
15
|
acp?: AcpLimitsConfig;
|
|
15
16
|
jsRuntime?: JsRuntimeLimitsConfig;
|
|
16
17
|
python?: PythonLimitsConfig;
|
|
17
18
|
wasm?: WasmLimitsConfig;
|
|
19
|
+
process?: ProcessLimitsConfig;
|
|
18
20
|
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { VmGroupConfig } from "./VmGroupConfig.js";
|
|
2
|
+
import type { VmUserAccountConfig } from "./VmUserAccountConfig.js";
|
|
3
|
+
/**
|
|
4
|
+
* Initial Linux-style credentials and account record for processes in a VM.
|
|
5
|
+
*/
|
|
6
|
+
export type VmUserConfig = {
|
|
7
|
+
uid?: number;
|
|
8
|
+
gid?: number;
|
|
9
|
+
euid?: number;
|
|
10
|
+
egid?: number;
|
|
11
|
+
username?: string;
|
|
12
|
+
homedir?: string;
|
|
13
|
+
shell?: string;
|
|
14
|
+
gecos?: string;
|
|
15
|
+
groupName?: string;
|
|
16
|
+
supplementaryGids?: Array<number>;
|
|
17
|
+
accounts?: Array<VmUserAccountConfig>;
|
|
18
|
+
groups?: Array<VmGroupConfig>;
|
|
19
|
+
};
|