withruntime 0.33.3 → 0.35.0
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/E2B.md +7 -0
- package/dist/agents-cli.d.ts +1 -1
- package/dist/agents-cli.js +171 -7
- package/dist/agents-deploy.d.ts +13 -3
- package/dist/agents-deploy.js +68 -9
- package/dist/apps-cli.d.ts +1 -1
- package/dist/apps-cli.js +41 -9
- package/dist/browsers/index.d.ts +9 -0
- package/dist/browsers/index.js +10 -0
- package/dist/browsers-cli.d.ts +13 -0
- package/dist/browsers-cli.js +160 -0
- package/dist/ci-cli.d.ts +1 -1
- package/dist/ci-cli.js +16 -3
- package/dist/cli-words.js +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +103 -12
- package/dist/desktops/index.d.ts +9 -0
- package/dist/desktops/index.js +10 -0
- package/dist/e2b/code-interpreter.d.ts +3 -12
- package/dist/e2b/code-interpreter.js +3 -6
- package/dist/e2b/index.d.ts +7 -1
- package/dist/e2b/index.js +9 -2
- package/dist/functions/index.d.ts +10 -0
- package/dist/functions/index.js +11 -0
- package/dist/index.d.ts +5 -3
- package/dist/products/agents.d.ts +162 -8
- package/dist/products/agents.js +108 -3
- package/dist/products/apps.d.ts +46 -5
- package/dist/products/browsers.d.ts +26 -0
- package/dist/products/browsers.js +11 -0
- package/dist/products/ci.d.ts +10 -4
- package/dist/products/ci.js +8 -0
- package/dist/products/desktops.d.ts +71 -0
- package/dist/products/desktops.js +27 -0
- package/dist/products/functions.d.ts +2 -0
- package/dist/products/functions.js +5 -0
- package/dist/products/index.d.ts +6 -0
- package/dist/products/index.js +8 -0
- package/dist/products/network.d.ts +4 -2
- package/dist/products/secrets.d.ts +10 -2
- package/dist/products/secrets.js +27 -7
- package/dist/products/uptime.d.ts +97 -0
- package/dist/products/uptime.js +42 -0
- package/dist/products/volumes.d.ts +41 -9
- package/dist/products/volumes.js +5 -2
- package/dist/transport.d.ts +4 -1
- package/dist/transport.js +2 -2
- package/dist/types.d.ts +15 -3
- package/package.json +17 -1
|
@@ -51,6 +51,11 @@ export type AgentDefinition = {
|
|
|
51
51
|
* GEMINI_API_KEY, OPENROUTER_API_KEY, or an OpenAI-compatible endpoint's
|
|
52
52
|
* key with env.OPENAI_BASE_URL). */
|
|
53
53
|
secrets?: string[];
|
|
54
|
+
/** Claude accounts, 1 to 16 egress secrets' names: subscription tokens,
|
|
55
|
+
* or API keys for a name holding API_KEY. Each session takes the one with
|
|
56
|
+
* the most usage left; the review template moves to the next when one is
|
|
57
|
+
* out of usage, and waits for the soonest reset when all are. */
|
|
58
|
+
pool?: string[];
|
|
54
59
|
/** MCP servers the harness may reach. */
|
|
55
60
|
mcp?: {
|
|
56
61
|
name: string;
|
|
@@ -130,12 +135,90 @@ export type AgentEvent = {
|
|
|
130
135
|
} & Record<string, unknown>;
|
|
131
136
|
createdAt: string;
|
|
132
137
|
};
|
|
138
|
+
export type AgentAskState = "open" | "answered" | "expired" | "withdrawn" | "closed";
|
|
139
|
+
/** One row of the account's inbox: a question a session's harness needs
|
|
140
|
+
* answered to go on. Asks of one agent's sessions sharing a memory, with the same `step` are
|
|
141
|
+
* one row while it is open, and one answer reaches every session asking. */
|
|
142
|
+
export type AgentAsk = {
|
|
143
|
+
id: string;
|
|
144
|
+
/** The agent of the session that asked first. */
|
|
145
|
+
agentId: string;
|
|
146
|
+
/** What it waits on, in the asker's words. */
|
|
147
|
+
step: string | null;
|
|
148
|
+
question: string;
|
|
149
|
+
/** Why it matters. */
|
|
150
|
+
why: string | null;
|
|
151
|
+
options: {
|
|
152
|
+
label: string;
|
|
153
|
+
detail?: string;
|
|
154
|
+
}[];
|
|
155
|
+
/** The recommended option's label; taken as the answer when it expires. */
|
|
156
|
+
pick: string | null;
|
|
157
|
+
/** Who sees it: its agent's labels with the ask's own over them. */
|
|
158
|
+
labels: Record<string, string>;
|
|
159
|
+
state: AgentAskState;
|
|
160
|
+
/** An option's label and/or words; `expired` when the pick was taken at
|
|
161
|
+
* expiry. */
|
|
162
|
+
answer: {
|
|
163
|
+
option?: string;
|
|
164
|
+
text?: string;
|
|
165
|
+
expired?: boolean;
|
|
166
|
+
} | null;
|
|
167
|
+
/** A key's principal id, or `runtime` for a pick taken at expiry. */
|
|
168
|
+
answeredBy: string | null;
|
|
169
|
+
/** The sessions asking it, each with its ask event's seq and the answer
|
|
170
|
+
* event that woke it. */
|
|
171
|
+
sessions: {
|
|
172
|
+
sessionId: string;
|
|
173
|
+
state: "asking" | "answered" | "expired" | "withdrawn" | "ended";
|
|
174
|
+
seq: number;
|
|
175
|
+
answerSeq: number | null;
|
|
176
|
+
}[];
|
|
177
|
+
expiresAt: string | null;
|
|
178
|
+
createdAt: string;
|
|
179
|
+
updatedAt: string;
|
|
180
|
+
closedAt: string | null;
|
|
181
|
+
};
|
|
182
|
+
export type ListAgentAsks = {
|
|
183
|
+
/** Open by default. */
|
|
184
|
+
state?: AgentAskState[];
|
|
185
|
+
agent?: string;
|
|
186
|
+
/** Asks carrying every one of these labels: who sees an ask. */
|
|
187
|
+
labels?: Record<string, string>;
|
|
188
|
+
cursor?: string;
|
|
189
|
+
limit?: number;
|
|
190
|
+
};
|
|
191
|
+
/** An option's label, words, or both. */
|
|
192
|
+
export type AnswerAgentAsk = {
|
|
193
|
+
option?: string;
|
|
194
|
+
text?: string;
|
|
195
|
+
};
|
|
133
196
|
export type AgentTriggerKind = "slack" | "github" | "schedule" | "webhook";
|
|
197
|
+
/** A trigger's rules, each optional. */
|
|
198
|
+
export type AgentTriggerRules = {
|
|
199
|
+
/** Queue order of its sessions when the agent's maxConcurrent is full:
|
|
200
|
+
* -100 to 100, higher first, then oldest. Default 0. */
|
|
201
|
+
priority?: number;
|
|
202
|
+
/** Sessions it may start in an hour; a call past it is held for you.
|
|
203
|
+
* Joining an open session is never capped. Default none. */
|
|
204
|
+
maxStartsPerHour?: number;
|
|
205
|
+
/** A call whose key's last session has ended: "start" a new one (the
|
|
206
|
+
* default), "note" it in the ended session's log and run nothing, or
|
|
207
|
+
* "ask" you (the call is held until you start it). */
|
|
208
|
+
onEnded?: "start" | "note" | "ask";
|
|
209
|
+
/** Where a held call is told: "email" to who added the trigger (the
|
|
210
|
+
* default), or "webhook", the account's webhooks' agent.call.held alone. */
|
|
211
|
+
notify?: "email" | "webhook";
|
|
212
|
+
/** A webhook's only: the key of a call that sends none, from its JSON's
|
|
213
|
+
* fields: "{cause}", "{alert.host}:{check}". */
|
|
214
|
+
key?: string;
|
|
215
|
+
};
|
|
134
216
|
export type AgentTrigger = {
|
|
135
217
|
id: string;
|
|
136
218
|
agentId: string;
|
|
137
219
|
kind: AgentTriggerKind;
|
|
138
220
|
config: Record<string, unknown>;
|
|
221
|
+
rules: AgentTriggerRules;
|
|
139
222
|
pausedAt: string | null;
|
|
140
223
|
pausedWhy: string | null;
|
|
141
224
|
createdAt: string;
|
|
@@ -157,7 +240,7 @@ export type StartAgentSession = {
|
|
|
157
240
|
key?: string;
|
|
158
241
|
labels?: Record<string, string>;
|
|
159
242
|
};
|
|
160
|
-
export type CreateAgentTrigger = {
|
|
243
|
+
export type CreateAgentTrigger = ({
|
|
161
244
|
kind: "slack";
|
|
162
245
|
config: {
|
|
163
246
|
team: string;
|
|
@@ -180,9 +263,48 @@ export type CreateAgentTrigger = {
|
|
|
180
263
|
} | {
|
|
181
264
|
kind: "webhook";
|
|
182
265
|
config: Record<string, never>;
|
|
266
|
+
}) & {
|
|
267
|
+
rules?: AgentTriggerRules;
|
|
268
|
+
};
|
|
269
|
+
/** One call to a webhook trigger: its words, and the key and labels of the
|
|
270
|
+
* session it starts or joins. */
|
|
271
|
+
export type AgentTriggerCall = {
|
|
272
|
+
text: string;
|
|
273
|
+
key?: string;
|
|
274
|
+
labels?: Record<string, string>;
|
|
275
|
+
};
|
|
276
|
+
/** What a call did: started a session, joined its key's open one, was
|
|
277
|
+
* noted in its key's ended one, or was held for you (`why`). */
|
|
278
|
+
export type AgentTriggerCallOutcome = {
|
|
279
|
+
outcome: "started" | "joined" | "noted" | "held";
|
|
280
|
+
sessionId: string | null;
|
|
281
|
+
seq: number | null;
|
|
282
|
+
callId: string | null;
|
|
283
|
+
why: AgentHeldCall["why"] | null;
|
|
284
|
+
replayed: boolean;
|
|
285
|
+
};
|
|
286
|
+
/** A call a trigger held for you because no session could take it. None is
|
|
287
|
+
* ever dropped. */
|
|
288
|
+
export type AgentHeldCall = {
|
|
289
|
+
id: string;
|
|
290
|
+
triggerId: string;
|
|
291
|
+
agentId: string;
|
|
292
|
+
key: string | null;
|
|
293
|
+
text: string;
|
|
294
|
+
labels: Record<string, string>;
|
|
295
|
+
/** The trigger was paused; it had started maxStartsPerHour sessions this
|
|
296
|
+
* hour; its key's session had ended and onEnded is "ask"; the agent's day
|
|
297
|
+
* budget was spent; the account's sessions were at their limit; Agents
|
|
298
|
+
* was closed to the account. */
|
|
299
|
+
why: "paused" | "rate" | "ended" | "budget" | "quota" | "closed";
|
|
300
|
+
state: "held" | "started" | "dismissed";
|
|
301
|
+
sessionId: string | null;
|
|
302
|
+
notify: "email" | "webhook";
|
|
303
|
+
createdAt: string;
|
|
304
|
+
resolvedAt: string | null;
|
|
183
305
|
};
|
|
184
|
-
/** The
|
|
185
|
-
export type AgentTemplateKey = "claude-code" | "codex" | "gemini-cli" | "claude-agent-sdk" | "openai-agents-sdk";
|
|
306
|
+
/** The harnesses' names, so `templates["claude-code"]` is known to be there. */
|
|
307
|
+
export type AgentTemplateKey = "claude-code" | "codex" | "gemini-cli" | "claude-agent-sdk" | "openai-agents-sdk" | "review" | "judge";
|
|
186
308
|
/** A file of an agent's memory (`memory.list`). `scope` is whose: empty for
|
|
187
309
|
* the shared memory, which every session reads (one keeping memory per key
|
|
188
310
|
* reads what you wrote there, and never changes it), or a session key
|
|
@@ -240,9 +362,8 @@ export type AgentTemplate = {
|
|
|
240
362
|
/** How your own subscription logs it in, for your own team's agents, or
|
|
241
363
|
* null when it takes an API key alone. */
|
|
242
364
|
subscription: string | null;
|
|
243
|
-
definition: {
|
|
365
|
+
definition: Pick<AgentDefinition, "secrets" | "pool" | "vcpu" | "memoryMiB" | "maxSessionSeconds"> & {
|
|
244
366
|
command: string;
|
|
245
|
-
secrets: string[];
|
|
246
367
|
};
|
|
247
368
|
};
|
|
248
369
|
/** A use: what an agent is for, merged into a template's definition. */
|
|
@@ -257,7 +378,7 @@ export type AgentUse = {
|
|
|
257
378
|
template: "support" | "team";
|
|
258
379
|
};
|
|
259
380
|
};
|
|
260
|
-
/** The
|
|
381
|
+
/** The harnesses (agents-contract.md); tests/agents.test.ts holds them
|
|
261
382
|
* to packages/cloud-guide/agent-templates.json. */
|
|
262
383
|
export declare const AGENT_TEMPLATES: Readonly<Record<AgentTemplateKey, AgentTemplate>>;
|
|
263
384
|
/** A harness by a key read from a file or a flag, or undefined. */
|
|
@@ -321,13 +442,45 @@ export declare function agents(t: Transport): {
|
|
|
321
442
|
* (`session_open`): stop it first. */
|
|
322
443
|
delete: (id: string, options?: RequestOptions) => Promise<void>;
|
|
323
444
|
};
|
|
445
|
+
/** The account's inbox: the questions its agents' sessions need answered
|
|
446
|
+
* to go on, one row per step however many sessions ask it. */
|
|
447
|
+
asks: {
|
|
448
|
+
/** Newest first; open ones unless `state` says otherwise. */
|
|
449
|
+
list: (query?: ListAgentAsks, options?: RequestOptions) => Promise<Page<AgentAsk>>;
|
|
450
|
+
get: (id: string, options?: RequestOptions) => Promise<AgentAsk>;
|
|
451
|
+
/** Every session asking it reads the answer next, and wakes. An ask no
|
|
452
|
+
* longer open is refused with `ask_closed`. */
|
|
453
|
+
answer: (id: string, answer: AnswerAgentAsk, options?: RequestOptions) => Promise<AgentAsk>;
|
|
454
|
+
};
|
|
324
455
|
triggers: {
|
|
325
456
|
create: (agent: string, input: CreateAgentTrigger, options?: RequestOptions) => Promise<AgentTrigger>;
|
|
326
457
|
list: (agent: string, options?: RequestOptions) => Promise<AgentTrigger[]>;
|
|
327
|
-
/**
|
|
458
|
+
/** Held: a webhook's calls are kept for you (see `held`), saying
|
|
459
|
+
* `why`; nothing else is held. */
|
|
328
460
|
pause: (id: string, why: string, options?: RequestOptions) => Promise<AgentTrigger>;
|
|
329
461
|
resume: (id: string, options?: RequestOptions) => Promise<AgentTrigger>;
|
|
330
462
|
delete: (id: string, options?: RequestOptions) => Promise<void>;
|
|
463
|
+
/** Its rules, whole, in place: its secret stays. `{}` is every default. */
|
|
464
|
+
setRules: (id: string, rules: AgentTriggerRules, options?: RequestOptions) => Promise<AgentTrigger>;
|
|
465
|
+
/** A webhook trigger's call, as its sender makes it: by the trigger's
|
|
466
|
+
* secret, never your key. A call with the key of an open session joins
|
|
467
|
+
* it. Pass `idempotencyKey` to make a retry the same call. */
|
|
468
|
+
call: (id: string, secret: string, call: AgentTriggerCall, options?: RequestOptions) => Promise<AgentTriggerCallOutcome>;
|
|
469
|
+
/** Calls it held for you, newest first. */
|
|
470
|
+
held: (trigger: string, query?: {
|
|
471
|
+
state?: AgentHeldCall["state"][];
|
|
472
|
+
cursor?: string;
|
|
473
|
+
limit?: number;
|
|
474
|
+
}, options?: RequestOptions) => Promise<Page<AgentHeldCall>>;
|
|
475
|
+
/** Start a held call: one session with it and every call held for its
|
|
476
|
+
* key since, oldest first. */
|
|
477
|
+
startHeld: (id: string, call: string, options?: RequestOptions) => Promise<{
|
|
478
|
+
session: AgentSession;
|
|
479
|
+
joined: boolean;
|
|
480
|
+
calls: number;
|
|
481
|
+
}>;
|
|
482
|
+
/** Dismiss a held call: nothing runs. */
|
|
483
|
+
dismissHeld: (id: string, call: string, options?: RequestOptions) => Promise<AgentHeldCall>;
|
|
331
484
|
};
|
|
332
485
|
/** Its built-in memory: text files kept across sessions, which the
|
|
333
486
|
* agent reads, writes and searches from inside its sessions. A scope is
|
|
@@ -363,7 +516,8 @@ export declare function agents(t: Transport): {
|
|
|
363
516
|
}, options?: RequestOptions) => Promise<boolean>;
|
|
364
517
|
};
|
|
365
518
|
/** The harnesses, as data: claude-code, codex, gemini-cli,
|
|
366
|
-
* claude-agent-sdk, openai-agents-sdk
|
|
519
|
+
* claude-agent-sdk, openai-agents-sdk, review (a CI/CD agent step's
|
|
520
|
+
* reviewer) and judge (an agent step held to your instructions alone). */
|
|
367
521
|
templates: Readonly<Record<AgentTemplateKey, AgentTemplate>>;
|
|
368
522
|
/** The uses, as data: support (your customers) and team (your team). */
|
|
369
523
|
uses: Readonly<Record<"team" | "support", AgentUse>>;
|
package/dist/products/agents.js
CHANGED
|
@@ -22,7 +22,9 @@ import { Page } from "../page.js";
|
|
|
22
22
|
const START = 'npx -y @anthropic-ai/claude-code --dangerously-skip-permissions --mcp-config ~/.runtime-agent/mcp.json -p "$(cat ~/.runtime-agent/start.md)"';
|
|
23
23
|
const CODEX = 'npx -y @openai/codex exec --dangerously-bypass-approvals-and-sandbox "$(cat ~/.runtime-agent/start.md)"';
|
|
24
24
|
const GEMINI = 'npx -y @google/gemini-cli --yolo -p "$(cat ~/.runtime-agent/start.md)"';
|
|
25
|
-
|
|
25
|
+
const REVIEW = "python3 ~/.runtime-agent/runtime-agent review";
|
|
26
|
+
const JUDGE = "python3 ~/.runtime-agent/runtime-agent judge";
|
|
27
|
+
/** The harnesses (agents-contract.md); tests/agents.test.ts holds them
|
|
26
28
|
* to packages/cloud-guide/agent-templates.json. */
|
|
27
29
|
export const AGENT_TEMPLATES = {
|
|
28
30
|
"claude-code": {
|
|
@@ -70,6 +72,36 @@ export const AGENT_TEMPLATES = {
|
|
|
70
72
|
subscription: null,
|
|
71
73
|
definition: { command: "python3 ~/agent.py", secrets: ["OPENAI_API_KEY"] },
|
|
72
74
|
},
|
|
75
|
+
review: {
|
|
76
|
+
key: "review",
|
|
77
|
+
title: "Code review",
|
|
78
|
+
command: REVIEW,
|
|
79
|
+
apiKeySecret: "ANTHROPIC_API_KEY",
|
|
80
|
+
apiKeyHost: "api.anthropic.com",
|
|
81
|
+
subscription: "a token per account: run `claude setup-token` on your own computer (Pro/Max) for each, store each with `runtime secrets set CLAUDE_1` scoped to api.anthropic.com, then name them all in pool (--pool CLAUDE_1 --pool CLAUDE_2)",
|
|
82
|
+
definition: {
|
|
83
|
+
command: REVIEW,
|
|
84
|
+
pool: ["ANTHROPIC_API_KEY"],
|
|
85
|
+
vcpu: 2,
|
|
86
|
+
memoryMiB: 2048,
|
|
87
|
+
maxSessionSeconds: 1800,
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
judge: {
|
|
91
|
+
key: "judge",
|
|
92
|
+
title: "Your rules",
|
|
93
|
+
command: JUDGE,
|
|
94
|
+
apiKeySecret: "ANTHROPIC_API_KEY",
|
|
95
|
+
apiKeyHost: "api.anthropic.com",
|
|
96
|
+
subscription: "a token per account, as for review: `runtime secrets set CLAUDE_1` scoped to api.anthropic.com for each, then name them all in pool; its instructions are the rules that block",
|
|
97
|
+
definition: {
|
|
98
|
+
command: JUDGE,
|
|
99
|
+
pool: ["ANTHROPIC_API_KEY"],
|
|
100
|
+
vcpu: 2,
|
|
101
|
+
memoryMiB: 2048,
|
|
102
|
+
maxSessionSeconds: 1800,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
73
105
|
};
|
|
74
106
|
/** A harness by a key read from a file or a flag, or undefined. */
|
|
75
107
|
export function agentTemplate(key) {
|
|
@@ -166,6 +198,28 @@ export function agents(t) {
|
|
|
166
198
|
});
|
|
167
199
|
return new Page(page.data, page.nextCursor, (cursor) => listSessions({ ...query, cursor }, options));
|
|
168
200
|
};
|
|
201
|
+
const listAsks = async (query = {}, options) => {
|
|
202
|
+
const { labels, ...rest } = query;
|
|
203
|
+
const page = await t.json({
|
|
204
|
+
method: "GET",
|
|
205
|
+
path: "/v1/agents/asks",
|
|
206
|
+
query: {
|
|
207
|
+
...rest,
|
|
208
|
+
...(labels ? { label: Object.entries(labels).map(([k, v]) => `${k}:${v}`) } : {}),
|
|
209
|
+
},
|
|
210
|
+
...options,
|
|
211
|
+
});
|
|
212
|
+
return new Page(page.data, page.nextCursor, (cursor) => listAsks({ ...query, cursor }, options));
|
|
213
|
+
};
|
|
214
|
+
const listHeld = async (trigger, query = {}, options) => {
|
|
215
|
+
const page = await t.json({
|
|
216
|
+
method: "GET",
|
|
217
|
+
path: `/v1/agents/triggers/${enc(trigger)}/held`,
|
|
218
|
+
query,
|
|
219
|
+
...options,
|
|
220
|
+
});
|
|
221
|
+
return new Page(page.data, page.nextCursor, (cursor) => listHeld(trigger, { ...query, cursor }, options));
|
|
222
|
+
};
|
|
169
223
|
const listMemory = async (agent, query = {}, options) => {
|
|
170
224
|
const page = await t.json({
|
|
171
225
|
method: "GET",
|
|
@@ -227,6 +281,21 @@ export function agents(t) {
|
|
|
227
281
|
});
|
|
228
282
|
},
|
|
229
283
|
},
|
|
284
|
+
/** The account's inbox: the questions its agents' sessions need answered
|
|
285
|
+
* to go on, one row per step however many sessions ask it. */
|
|
286
|
+
asks: {
|
|
287
|
+
/** Newest first; open ones unless `state` says otherwise. */
|
|
288
|
+
list: listAsks,
|
|
289
|
+
get: (id, options) => t.json({ method: "GET", path: `/v1/agents/asks/${enc(id)}`, ...options }),
|
|
290
|
+
/** Every session asking it reads the answer next, and wakes. An ask no
|
|
291
|
+
* longer open is refused with `ask_closed`. */
|
|
292
|
+
answer: (id, answer, options) => t.json({
|
|
293
|
+
method: "POST",
|
|
294
|
+
path: `/v1/agents/asks/${enc(id)}/answer`,
|
|
295
|
+
body: answer,
|
|
296
|
+
...options,
|
|
297
|
+
}),
|
|
298
|
+
},
|
|
230
299
|
triggers: {
|
|
231
300
|
create: (agent, input, options) => t.json({
|
|
232
301
|
method: "POST",
|
|
@@ -239,7 +308,8 @@ export function agents(t) {
|
|
|
239
308
|
path: `/v1/agents/${enc(agent)}/triggers`,
|
|
240
309
|
...options,
|
|
241
310
|
})).data,
|
|
242
|
-
/**
|
|
311
|
+
/** Held: a webhook's calls are kept for you (see `held`), saying
|
|
312
|
+
* `why`; nothing else is held. */
|
|
243
313
|
pause: (id, why, options) => t.json({
|
|
244
314
|
method: "POST",
|
|
245
315
|
path: `/v1/agents/triggers/${enc(id)}/pause`,
|
|
@@ -259,6 +329,40 @@ export function agents(t) {
|
|
|
259
329
|
...options,
|
|
260
330
|
});
|
|
261
331
|
},
|
|
332
|
+
/** Its rules, whole, in place: its secret stays. `{}` is every default. */
|
|
333
|
+
setRules: (id, rules, options) => t.json({
|
|
334
|
+
method: "PATCH",
|
|
335
|
+
path: `/v1/agents/triggers/${enc(id)}`,
|
|
336
|
+
body: { rules },
|
|
337
|
+
...options,
|
|
338
|
+
}),
|
|
339
|
+
/** A webhook trigger's call, as its sender makes it: by the trigger's
|
|
340
|
+
* secret, never your key. A call with the key of an open session joins
|
|
341
|
+
* it. Pass `idempotencyKey` to make a retry the same call. */
|
|
342
|
+
call: (id, secret, call, options) => t.json({
|
|
343
|
+
method: "POST",
|
|
344
|
+
path: `/v1/agents/triggers/${enc(id)}/calls`,
|
|
345
|
+
body: call,
|
|
346
|
+
bearer: secret,
|
|
347
|
+
...options,
|
|
348
|
+
}),
|
|
349
|
+
/** Calls it held for you, newest first. */
|
|
350
|
+
held: listHeld,
|
|
351
|
+
/** Start a held call: one session with it and every call held for its
|
|
352
|
+
* key since, oldest first. */
|
|
353
|
+
startHeld: (id, call, options) => t.json({
|
|
354
|
+
method: "POST",
|
|
355
|
+
path: `/v1/agents/triggers/${enc(id)}/held/${enc(call)}/start`,
|
|
356
|
+
body: {},
|
|
357
|
+
...options,
|
|
358
|
+
}),
|
|
359
|
+
/** Dismiss a held call: nothing runs. */
|
|
360
|
+
dismissHeld: (id, call, options) => t.json({
|
|
361
|
+
method: "POST",
|
|
362
|
+
path: `/v1/agents/triggers/${enc(id)}/held/${enc(call)}/dismiss`,
|
|
363
|
+
body: {},
|
|
364
|
+
...options,
|
|
365
|
+
}),
|
|
262
366
|
},
|
|
263
367
|
/** Its built-in memory: text files kept across sessions, which the
|
|
264
368
|
* agent reads, writes and searches from inside its sessions. A scope is
|
|
@@ -292,7 +396,8 @@ export function agents(t) {
|
|
|
292
396
|
})).deleted,
|
|
293
397
|
},
|
|
294
398
|
/** The harnesses, as data: claude-code, codex, gemini-cli,
|
|
295
|
-
* claude-agent-sdk, openai-agents-sdk
|
|
399
|
+
* claude-agent-sdk, openai-agents-sdk, review (a CI/CD agent step's
|
|
400
|
+
* reviewer) and judge (an agent step held to your instructions alone). */
|
|
296
401
|
templates: AGENT_TEMPLATES,
|
|
297
402
|
/** The uses, as data: support (your customers) and team (your team). */
|
|
298
403
|
uses: AGENT_USES,
|
package/dist/products/apps.d.ts
CHANGED
|
@@ -39,7 +39,42 @@ export type StatefulSettings = {
|
|
|
39
39
|
/** Seconds a stopped copy has after SIGTERM to exit. */
|
|
40
40
|
stopGraceSeconds: number;
|
|
41
41
|
};
|
|
42
|
-
|
|
42
|
+
/** How an App's new version goes live: every copy together (at_once, the
|
|
43
|
+
* default), or staged: one copy of it beside the live version's, then about
|
|
44
|
+
* 10%, 50% and all of them, each stage judged on its visitors' errors and
|
|
45
|
+
* speed before the next. A stage that does worse goes back: its copies
|
|
46
|
+
* finish their requests and stop, then the deploy fails (deploy_stage_failed)
|
|
47
|
+
* and the live version never stops serving. */
|
|
48
|
+
export type ReleaseStages = "at_once" | "staged";
|
|
49
|
+
export type ReleaseSettings = {
|
|
50
|
+
releaseStages: ReleaseStages;
|
|
51
|
+
/** 60 to 3600 seconds; defaults to 300. How long each stage runs once its
|
|
52
|
+
* copies serve before it is judged. */
|
|
53
|
+
releaseSoakSeconds: number;
|
|
54
|
+
};
|
|
55
|
+
/** An App's staged release under way, or its last. */
|
|
56
|
+
export type StagedRelease = {
|
|
57
|
+
version: number;
|
|
58
|
+
/** The version live when it began, serving beside it. */
|
|
59
|
+
from: number;
|
|
60
|
+
/** rolling: its stages go live; back: a stage did worse and its copies
|
|
61
|
+
* leave; done: every copy runs it; failed: it went back (or its copies
|
|
62
|
+
* failed their health check) and the version failed; ended: another
|
|
63
|
+
* deploy or a rollback took its place. */
|
|
64
|
+
state: "rolling" | "back" | "done" | "failed" | "ended";
|
|
65
|
+
stage: number;
|
|
66
|
+
stages: number;
|
|
67
|
+
/** Copies of the new version the stage serves beside the old version's. */
|
|
68
|
+
copies: number;
|
|
69
|
+
/** Copies the release walks to. */
|
|
70
|
+
of: number;
|
|
71
|
+
soakSeconds: number;
|
|
72
|
+
/** Its last step, in words. */
|
|
73
|
+
detail: string;
|
|
74
|
+
startedAt: number;
|
|
75
|
+
updatedAt: number;
|
|
76
|
+
};
|
|
77
|
+
export type App = AppSettings & StatefulSettings & ReleaseSettings & {
|
|
43
78
|
id: string;
|
|
44
79
|
name: string | null;
|
|
45
80
|
/** Its address for life, its name then its account's:
|
|
@@ -58,6 +93,8 @@ export type App = AppSettings & StatefulSettings & {
|
|
|
58
93
|
} | null;
|
|
59
94
|
liveVersion: number | null;
|
|
60
95
|
previousVersion: number | null;
|
|
96
|
+
/** Its staged release under way, or its last; null before its first. */
|
|
97
|
+
stagedRelease: StagedRelease | null;
|
|
61
98
|
/** While a copy waits for room in its region: its account's lane, its
|
|
62
99
|
* place in line (1 is next), how many wait ahead by lane, and why.
|
|
63
100
|
* Higher lanes get room first. Absent while nothing of it waits. */
|
|
@@ -69,7 +106,7 @@ export type AppLine = {
|
|
|
69
106
|
ahead: Record<string, number>;
|
|
70
107
|
words: string;
|
|
71
108
|
};
|
|
72
|
-
export type RuntimeFunction = Omit<App, "minCopies" | keyof StatefulSettings> & {
|
|
109
|
+
export type RuntimeFunction = Omit<App, "minCopies" | keyof StatefulSettings | keyof ReleaseSettings | "stagedRelease"> & {
|
|
73
110
|
minCopies: 0;
|
|
74
111
|
/** 250 to 5000 ms: at most how long a copy stays awake after its last request ends. */
|
|
75
112
|
sleepAfterMs: number;
|
|
@@ -125,14 +162,18 @@ export type CreateApp = Omit<CreateFunction, "minCopies" | "sleepAfterMs"> & {
|
|
|
125
162
|
volume?: AppVolume;
|
|
126
163
|
/** 0 to 900; defaults to 30. */
|
|
127
164
|
stopGraceSeconds?: number;
|
|
165
|
+
/** Defaults to "at_once"; see ReleaseStages. */
|
|
166
|
+
releaseStages?: ReleaseStages;
|
|
167
|
+
/** 60 to 3600; defaults to 300. */
|
|
168
|
+
releaseSoakSeconds?: number;
|
|
128
169
|
};
|
|
129
|
-
export type UpdateApp = Partial<AppSettings & StatefulSettings> & {
|
|
170
|
+
export type UpdateApp = Partial<AppSettings & StatefulSettings & ReleaseSettings> & {
|
|
130
171
|
name?: string | null;
|
|
131
172
|
labels?: Record<string, string>;
|
|
132
173
|
/** Only Functions sleep on this rule; an App is refused it. */
|
|
133
174
|
sleepAfterMs?: never;
|
|
134
175
|
};
|
|
135
|
-
export type UpdateFunction = Omit<UpdateApp, "minCopies" | "sleepAfterMs" | keyof StatefulSettings> & {
|
|
176
|
+
export type UpdateFunction = Omit<UpdateApp, "minCopies" | "sleepAfterMs" | keyof StatefulSettings | keyof ReleaseSettings> & {
|
|
136
177
|
minCopies?: never;
|
|
137
178
|
/** 250 to 5000 ms; see CreateFunction.sleepAfterMs. */
|
|
138
179
|
sleepAfterMs?: number;
|
|
@@ -159,7 +200,7 @@ export type AppDeploy = {
|
|
|
159
200
|
} | {
|
|
160
201
|
state: "failed" | "superseded";
|
|
161
202
|
error: {
|
|
162
|
-
code: "deploy_build_failed" | "deploy_health_failed" | "deploy_stop_failed" | "deploy_switch_failed" | "deploy_superseded";
|
|
203
|
+
code: "deploy_build_failed" | "deploy_health_failed" | "deploy_stop_failed" | "deploy_stage_failed" | "deploy_switch_failed" | "deploy_superseded";
|
|
163
204
|
message: string;
|
|
164
205
|
hint: string;
|
|
165
206
|
lastOutput: string;
|
|
@@ -40,6 +40,28 @@ export type BrowserInfo = {
|
|
|
40
40
|
liveViewUrl?: string;
|
|
41
41
|
hint?: string;
|
|
42
42
|
};
|
|
43
|
+
export type BrowserScreenshot = {
|
|
44
|
+
/** An http(s) address, opened in a new tab that is closed after. */
|
|
45
|
+
url?: string;
|
|
46
|
+
/** The whole page, not only the window. */
|
|
47
|
+
fullPage?: boolean;
|
|
48
|
+
format?: "png" | "jpeg";
|
|
49
|
+
/** 0 to 10000 ms after the page loads, for late scripts. */
|
|
50
|
+
waitMs?: number;
|
|
51
|
+
};
|
|
52
|
+
export type BrowserScreenshotResult = {
|
|
53
|
+
/** Where the page ended, after redirects. */
|
|
54
|
+
url: string;
|
|
55
|
+
title: string;
|
|
56
|
+
/** The page's HTTP status; null for the page already shown. */
|
|
57
|
+
status: number | null;
|
|
58
|
+
mimeType: "image/png" | "image/jpeg";
|
|
59
|
+
bytes: number;
|
|
60
|
+
width: number | null;
|
|
61
|
+
height: number | null;
|
|
62
|
+
/** The image. */
|
|
63
|
+
base64: string;
|
|
64
|
+
};
|
|
43
65
|
export type BrowserConnectOptions = {
|
|
44
66
|
playwright: [endpointURL: string, options: {
|
|
45
67
|
headers: Record<string, string>;
|
|
@@ -66,6 +88,10 @@ export declare function browsers(t: Transport): {
|
|
|
66
88
|
list: (query?: ListBrowsers, options?: RequestOptions) => Promise<Page<Browser>>;
|
|
67
89
|
/** Change a browser's name or labels without changing its compute settings. */
|
|
68
90
|
update(id: string, input: UpdateBrowser, options?: RequestOptions): Promise<Browser>;
|
|
91
|
+
/** Open `url` in a new tab and shoot it once it loads (without `url`, what
|
|
92
|
+
* the browser shows now); the image is `base64`, its page's url, title
|
|
93
|
+
* and HTTP status beside it. Runs inside the browser's own sandbox. */
|
|
94
|
+
screenshot(id: string, input?: BrowserScreenshot, options?: RequestOptions): Promise<BrowserScreenshotResult>;
|
|
69
95
|
/** End a browser by id; pass RequestOptions to bound or deduplicate the request. */
|
|
70
96
|
delete: (id: string, options?: RequestOptions) => Promise<void>;
|
|
71
97
|
};
|
|
@@ -96,6 +96,17 @@ export function browsers(t) {
|
|
|
96
96
|
...options,
|
|
97
97
|
}));
|
|
98
98
|
},
|
|
99
|
+
/** Open `url` in a new tab and shoot it once it loads (without `url`, what
|
|
100
|
+
* the browser shows now); the image is `base64`, its page's url, title
|
|
101
|
+
* and HTTP status beside it. Runs inside the browser's own sandbox. */
|
|
102
|
+
screenshot(id, input = {}, options) {
|
|
103
|
+
return t.json({
|
|
104
|
+
method: "POST",
|
|
105
|
+
path: `${path(id)}:screenshot`,
|
|
106
|
+
body: input,
|
|
107
|
+
...options,
|
|
108
|
+
});
|
|
109
|
+
},
|
|
99
110
|
/** End a browser by id; pass RequestOptions to bound or deduplicate the request. */
|
|
100
111
|
delete: remove,
|
|
101
112
|
};
|
package/dist/products/ci.d.ts
CHANGED
|
@@ -144,7 +144,8 @@ export type CiReviewFinding = {
|
|
|
144
144
|
/** What would put it right. */
|
|
145
145
|
fix: string;
|
|
146
146
|
};
|
|
147
|
-
/**
|
|
147
|
+
/** An agent step's verdict on one commit (`review:` is its short form): it
|
|
148
|
+
* passes only with no findings. */
|
|
148
149
|
export type CiReview = {
|
|
149
150
|
verdict: "pass" | "block";
|
|
150
151
|
summary: string;
|
|
@@ -155,10 +156,11 @@ export type CiReview = {
|
|
|
155
156
|
line: number;
|
|
156
157
|
what: string;
|
|
157
158
|
}[];
|
|
158
|
-
/** The Runtime Agent that
|
|
159
|
+
/** The Runtime Agent that judged, and the model the step asked for. */
|
|
159
160
|
agent: string;
|
|
160
|
-
|
|
161
|
-
|
|
161
|
+
model: string | null;
|
|
162
|
+
/** The Claude account a verdict before agent steps ran on. */
|
|
163
|
+
account?: string;
|
|
162
164
|
/** The agent session that gave the verdict. */
|
|
163
165
|
session: string;
|
|
164
166
|
/** True when the diff was too long and its end was not read. */
|
|
@@ -353,6 +355,10 @@ export declare function ci(t: Transport): {
|
|
|
353
355
|
* are let go. A check that has ended is answered as it is; to a key
|
|
354
356
|
* that may cancel it but not read it, with its id and state alone. */
|
|
355
357
|
cancel: (id: string, options?: RequestOptions) => Promise<CiCheckDetail | CiCancelled>;
|
|
358
|
+
/** Run a check again, as GitHub's Re-run does: a new check of the
|
|
359
|
+
* same commit (a pull request's as it would land now), trusted only as
|
|
360
|
+
* the commit's last check was. A check still going is answered as it is. */
|
|
361
|
+
rerun: (id: string, options?: RequestOptions) => Promise<CiCheckDetail | CiCancelled>;
|
|
356
362
|
};
|
|
357
363
|
jobs: {
|
|
358
364
|
/** A job with the tail of its log and the sandboxes it ran in. */
|
package/dist/products/ci.js
CHANGED
|
@@ -92,6 +92,14 @@ export function ci(t) {
|
|
|
92
92
|
path: `${at("/v1/ci/checks", id)}:cancel`,
|
|
93
93
|
...options,
|
|
94
94
|
}),
|
|
95
|
+
/** Run a check again, as GitHub's Re-run does: a new check of the
|
|
96
|
+
* same commit (a pull request's as it would land now), trusted only as
|
|
97
|
+
* the commit's last check was. A check still going is answered as it is. */
|
|
98
|
+
rerun: (id, options) => t.json({
|
|
99
|
+
method: "POST",
|
|
100
|
+
path: `${at("/v1/ci/checks", id)}:rerun`,
|
|
101
|
+
...options,
|
|
102
|
+
}),
|
|
95
103
|
},
|
|
96
104
|
jobs: {
|
|
97
105
|
/** A job with the tail of its log and the sandboxes it ran in. */
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/** Desktops: a Linux desktop on its own sandbox, billed at the sandbox rates
|
|
2
|
+
* (packages/cloud/src/api/products/desktops.ts), at /v1/desktops, with a
|
|
3
|
+
* private live view and computer use: screenshot and act. In a private beta:
|
|
4
|
+
* an account outside it is refused with product_in_beta (403), and retrying
|
|
5
|
+
* does not change it. */
|
|
6
|
+
import type { RequestOptions, Transport } from "../transport.js";
|
|
7
|
+
import { type ResourceRecord } from "./resources.js";
|
|
8
|
+
export type DesktopState = "starting" | "running" | "paused" | "stopped" | "failed" | "deleted";
|
|
9
|
+
export type Desktop = ResourceRecord & {
|
|
10
|
+
name: string | null;
|
|
11
|
+
labels: Record<string, string>;
|
|
12
|
+
state: DesktopState;
|
|
13
|
+
sandboxId: string;
|
|
14
|
+
createdAt: number;
|
|
15
|
+
updatedAt: number;
|
|
16
|
+
deletedAt: number | null;
|
|
17
|
+
memoryMiB: number;
|
|
18
|
+
vcpu: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
timeoutSeconds: number;
|
|
22
|
+
idlePauseSeconds: number;
|
|
23
|
+
/** Opens the live desktop in a browser; carries a private preview token. */
|
|
24
|
+
liveViewUrl?: string;
|
|
25
|
+
/** When liveViewUrl's token ends; get the desktop again for a fresh one. */
|
|
26
|
+
expiresAt: string | null;
|
|
27
|
+
actions: {
|
|
28
|
+
screenshot: string;
|
|
29
|
+
act: string;
|
|
30
|
+
record: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export type CreateDesktop = {
|
|
34
|
+
/** 1024–16384 MiB; the server defaults to 2048. */
|
|
35
|
+
memoryMiB?: number;
|
|
36
|
+
/** The server defaults to 2 vCPU. */
|
|
37
|
+
vcpu?: number;
|
|
38
|
+
/** The screen, 640x480 to 3840x2160; 1280x800 by default. */
|
|
39
|
+
width?: number;
|
|
40
|
+
height?: number;
|
|
41
|
+
timeoutSeconds?: number;
|
|
42
|
+
idlePauseSeconds?: number;
|
|
43
|
+
name?: string;
|
|
44
|
+
labels?: Record<string, string>;
|
|
45
|
+
};
|
|
46
|
+
/** Only the name and labels change; a null name clears it. */
|
|
47
|
+
export type UpdateDesktop = {
|
|
48
|
+
name?: string | null;
|
|
49
|
+
labels?: Record<string, string>;
|
|
50
|
+
};
|
|
51
|
+
/** One computer-use step, as POST /v1/desktops/{id}:act takes it. */
|
|
52
|
+
export type DesktopAct = {
|
|
53
|
+
action: string;
|
|
54
|
+
} & Record<string, unknown>;
|
|
55
|
+
export declare function desktops(t: Transport): {
|
|
56
|
+
/** The screen as PNG (or JPEG) bytes. A write: it runs in the desktop's
|
|
57
|
+
* sandbox and wakes a paused one, so a read-only key is refused it. */
|
|
58
|
+
screenshot(id: string, shot?: {
|
|
59
|
+
format?: "png" | "jpeg";
|
|
60
|
+
quality?: number;
|
|
61
|
+
}, options?: RequestOptions): Promise<Uint8Array<ArrayBufferLike>>;
|
|
62
|
+
/** Move, click, drag, scroll, type, press keys, open a URL or launch a program. */
|
|
63
|
+
act(id: string, step: DesktopAct, options?: RequestOptions): Promise<Record<string, unknown>>;
|
|
64
|
+
base: string;
|
|
65
|
+
create: (input: CreateDesktop, options?: RequestOptions) => Promise<Desktop>;
|
|
66
|
+
get: (id: string, options?: import("./resources.js").ResourceGetOptions<"paused" | "stopped" | "starting" | "running" | "deleted" | "failed">) => Promise<Desktop>;
|
|
67
|
+
list: (query?: import("./resources.js").ResourceListQuery<"paused" | "stopped" | "starting" | "running" | "deleted" | "failed">, options?: RequestOptions) => Promise<import("../page.js").Page<Desktop>>;
|
|
68
|
+
update: (id: string, input: UpdateDesktop, options?: RequestOptions) => Promise<Desktop>;
|
|
69
|
+
wait: (id: string, target: "paused" | "stopped" | "starting" | "running" | "deleted" | "failed", options?: import("./resources.js").ResourceWaitOptions) => Promise<Desktop>;
|
|
70
|
+
delete: (id: string, options?: import("./resources.js").ResourceDeleteOptions) => Promise<Desktop>;
|
|
71
|
+
};
|