@coltonkirsten/a12s 0.4.2 → 0.5.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/dist/src/client.d.ts +13 -8
- package/dist/src/client.js +13 -6
- package/dist/src/fleet.d.ts +33 -9
- package/dist/src/fleet.js +39 -12
- package/dist/src/types.d.ts +11 -1
- package/package.json +5 -7
- package/dist/a12s.js +0 -1036
package/dist/src/client.d.ts
CHANGED
|
@@ -49,13 +49,13 @@ export interface EventsOptions {
|
|
|
49
49
|
onGap?: "yield" | "throw";
|
|
50
50
|
}
|
|
51
51
|
export type SharedEventsOptions = Omit<EventsOptions, "turn" | "after">;
|
|
52
|
-
export interface
|
|
52
|
+
export interface WaitOptions {
|
|
53
53
|
signal?: AbortSignal;
|
|
54
54
|
/** Every event of the Turn, as it streams. */
|
|
55
55
|
onEvent?: (ev: A12sEvent) => void;
|
|
56
56
|
}
|
|
57
|
-
/** What `
|
|
58
|
-
export interface
|
|
57
|
+
/** What `send(...).wait()` resolves with: the finished Turn that delivered the Message, and the Message. */
|
|
58
|
+
export interface Reply extends Turn {
|
|
59
59
|
message: EnqueueResponse;
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
@@ -82,8 +82,13 @@ export declare class A12sClient {
|
|
|
82
82
|
* batched with anything else pending. Works while the Computer is busy or asleep.
|
|
83
83
|
*/
|
|
84
84
|
send(computer: string, msg: EnqueueRequest | string): Promise<EnqueueResponse>;
|
|
85
|
-
/** Sends a Message, waits for the Turn that delivers it and resolves when that Turn ends
|
|
86
|
-
prompt(computer: string, body: string, opts?:
|
|
85
|
+
/** Sends a Message, waits for the Turn that delivers it and resolves when that Turn ends. */
|
|
86
|
+
prompt(computer: string, body: string, opts?: Omit<EnqueueRequest, "body"> & WaitOptions): Promise<Reply>;
|
|
87
|
+
/**
|
|
88
|
+
* @internal Waits for the Turn that delivers the Message and resolves when it ends. Delivery is read from the
|
|
89
|
+
* Message's own snapshot and the Turn is replayed from its start, so it works however late it is called.
|
|
90
|
+
*/
|
|
91
|
+
reply(computer: string, message: EnqueueResponse, opts?: WaitOptions): Promise<Reply>;
|
|
87
92
|
/**
|
|
88
93
|
* Live events of one Computer, several, or (no argument) every Computer in the Fleet, merged. Each event carries
|
|
89
94
|
* its `computer`. Reconnects after a network drop without losing or repeating events. Call `await stream.ready()`
|
|
@@ -107,11 +112,11 @@ export declare class A12sClient {
|
|
|
107
112
|
/** Interrupts a Turn (default: the active one). The Turn ends `interrupted`; nothing is replayed. */
|
|
108
113
|
stop(computer: string, turn?: string): Promise<void>;
|
|
109
114
|
/**
|
|
110
|
-
* Stops the agent computer's processes and keeps its disks, session and inbox.
|
|
111
|
-
*
|
|
115
|
+
* Stops the agent computer's processes and keeps its disks, session and inbox. A Message from a sender its power
|
|
116
|
+
* policy lists (wakeOnMessage) wakes it; with `hold` it stays asleep until wake().
|
|
112
117
|
*/
|
|
113
118
|
sleep(computer: string, opts?: {
|
|
114
|
-
|
|
119
|
+
hold?: boolean;
|
|
115
120
|
}): Promise<void>;
|
|
116
121
|
/** Starts a sleeping agent computer; its session resumes on the next Turn. `clearInbox` discards pending Messages. */
|
|
117
122
|
wake(computer: string, opts?: {
|
package/dist/src/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Runs in Node, Deno, Bun and browsers: no node: imports here (`npm run
|
|
1
|
+
// Runs in Node, Deno, Bun and browsers: no node: imports here (`npm run dashboard` bundles it for the browser).
|
|
2
2
|
import { readSSE } from "./sse.js";
|
|
3
3
|
/** A refused call: the HTTP status and the Controller's error, including its fix line. */
|
|
4
4
|
export class A12sError extends Error {
|
|
@@ -94,10 +94,17 @@ export class A12sClient {
|
|
|
94
94
|
m.idempotencyKey ??= globalThis.crypto.randomUUID();
|
|
95
95
|
return this.request("POST", `/v1/agent-computers/${enc(computer)}/inbox`, m);
|
|
96
96
|
}
|
|
97
|
-
/** Sends a Message, waits for the Turn that delivers it and resolves when that Turn ends
|
|
97
|
+
/** Sends a Message, waits for the Turn that delivers it and resolves when that Turn ends. */
|
|
98
98
|
async prompt(computer, body, opts = {}) {
|
|
99
99
|
const { signal, onEvent, ...msg } = opts;
|
|
100
|
-
|
|
100
|
+
return this.reply(computer, await this.send(computer, { ...msg, body }), { signal, onEvent });
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* @internal Waits for the Turn that delivers the Message and resolves when it ends. Delivery is read from the
|
|
104
|
+
* Message's own snapshot and the Turn is replayed from its start, so it works however late it is called.
|
|
105
|
+
*/
|
|
106
|
+
async reply(computer, message, opts = {}) {
|
|
107
|
+
const { signal, onEvent } = opts;
|
|
101
108
|
const turn = await this.deliveredIn(computer, message.id, signal);
|
|
102
109
|
const builder = new TurnBuilder();
|
|
103
110
|
// A gap mid-Turn would silently drop text: fail loudly instead.
|
|
@@ -170,13 +177,13 @@ export class A12sClient {
|
|
|
170
177
|
await this.request("POST", `/v1/agent-computers/${enc(computer)}/turns/${enc(id)}/stop`, {});
|
|
171
178
|
}
|
|
172
179
|
/**
|
|
173
|
-
* Stops the agent computer's processes and keeps its disks, session and inbox.
|
|
174
|
-
*
|
|
180
|
+
* Stops the agent computer's processes and keeps its disks, session and inbox. A Message from a sender its power
|
|
181
|
+
* policy lists (wakeOnMessage) wakes it; with `hold` it stays asleep until wake().
|
|
175
182
|
*/
|
|
176
183
|
async sleep(computer, opts = {}) {
|
|
177
184
|
await this.request("POST", `/v1/agent-computers/${enc(computer)}/power`, {
|
|
178
185
|
state: "asleep",
|
|
179
|
-
...(opts.
|
|
186
|
+
...(opts.hold ? { hold: true } : {}),
|
|
180
187
|
});
|
|
181
188
|
}
|
|
182
189
|
/** Starts a sleeping agent computer; its session resumes on the next Turn. `clearInbox` discards pending Messages. */
|
package/dist/src/fleet.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A12sClient, type A12sClientOptions, type EventsOptions, TurnStream, type EventStream, type
|
|
1
|
+
import { A12sClient, type A12sClientOptions, type EventsOptions, TurnStream, type EventStream, type Reply, type SharedEventsOptions, type WaitOptions } from "./client.js";
|
|
2
2
|
import type { AgentComputerData, AgentComputerSpec, Change, ComputerStatus, CredentialInfo, EnqueueRequest, EnqueueResponse, FleetSpec, InboxListOptions, InboxListResponse, MergePatch, Message, ServiceStatus, StatusResponse, Token, TokenAction, Turn } from "./types.js";
|
|
3
3
|
/** The Fleet as written, and its version for a conditional write. */
|
|
4
4
|
export interface FleetState {
|
|
@@ -18,7 +18,7 @@ export interface CreateOptions {
|
|
|
18
18
|
* ```ts
|
|
19
19
|
* const fleet = await Fleet.connect();
|
|
20
20
|
* const hello = await fleet.agentComputers.create("hello", { instructions: "Be helpful" });
|
|
21
|
-
* await hello.
|
|
21
|
+
* const reply = await hello.send("hi").wait();
|
|
22
22
|
* await hello.remove();
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
@@ -58,7 +58,11 @@ export declare class Fleet {
|
|
|
58
58
|
export declare class AgentComputers {
|
|
59
59
|
private readonly client;
|
|
60
60
|
constructor(client: A12sClient);
|
|
61
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* Adds an agent computer to the Fleet and starts it. One that names a credential with no value yet resolves at once,
|
|
63
|
+
* waiting in Provisioning (`status.waiting`, and a console warning); it starts when the value is set. Fails with
|
|
64
|
+
* code `exists` if the name is taken.
|
|
65
|
+
*/
|
|
62
66
|
create(name: string, spec?: AgentComputerSpec & CreateOptions): Promise<AgentComputer>;
|
|
63
67
|
/** Throws {@link NotFound} if there is none. */
|
|
64
68
|
get(name: string): Promise<AgentComputer>;
|
|
@@ -80,10 +84,11 @@ export declare class AgentComputer {
|
|
|
80
84
|
update(changes: MergePatch<AgentComputerSpec>): Promise<this>;
|
|
81
85
|
/** Removes it from the Fleet and stops it; its drives are kept. */
|
|
82
86
|
remove(): Promise<void>;
|
|
83
|
-
/**
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Puts a Message in the inbox; it is delivered at the next idle moment. Await it for the queued Message, or call
|
|
89
|
+
* `wait()` on it (or on the awaited Message, at any time later) for the Turn that delivers it.
|
|
90
|
+
*/
|
|
91
|
+
send(text: string, opts?: Omit<EnqueueRequest, "body">): Sending;
|
|
87
92
|
/** Its events, live, from the Fleet's shared connection; `turn` replays one Turn from its start instead. */
|
|
88
93
|
events(opts?: EventsOptions): EventStream;
|
|
89
94
|
/** Its last `limit` finished Turns, newest first. */
|
|
@@ -95,9 +100,9 @@ export declare class AgentComputer {
|
|
|
95
100
|
limit?: undefined;
|
|
96
101
|
}): TurnStream;
|
|
97
102
|
private pastTurns;
|
|
98
|
-
/** Stops its processes and keeps its disks, session and inbox
|
|
103
|
+
/** Stops its processes and keeps its disks, session and inbox; a sender in wakeOnMessage wakes it, unless `hold`. */
|
|
99
104
|
sleep(opts?: {
|
|
100
|
-
|
|
105
|
+
hold?: boolean;
|
|
101
106
|
}): Promise<void>;
|
|
102
107
|
/** Wakes it; `clearInbox` discards the pending Messages first. */
|
|
103
108
|
wake(opts?: {
|
|
@@ -116,6 +121,25 @@ export declare class AgentComputer {
|
|
|
116
121
|
/** Withdraws a pending Message; a 409 A12sError names its state if it is too late. */
|
|
117
122
|
withdraw(id: string): Promise<Message>;
|
|
118
123
|
}
|
|
124
|
+
/** A queued Message. */
|
|
125
|
+
export interface SentMessage extends EnqueueResponse {
|
|
126
|
+
/**
|
|
127
|
+
* Waits for the Turn that delivers this Message and resolves with it once it ends, also if it already has. A failed
|
|
128
|
+
* Turn resolves with status "failed"; a Message that is withdrawn, expired, replaced or held throws A12sError.
|
|
129
|
+
*/
|
|
130
|
+
wait(opts?: WaitOptions): Promise<Reply>;
|
|
131
|
+
}
|
|
132
|
+
/** What `send()` returns: a promise of the {@link SentMessage}, with its `wait()` one call away. */
|
|
133
|
+
export declare class Sending implements Promise<SentMessage> {
|
|
134
|
+
private readonly sent;
|
|
135
|
+
readonly [Symbol.toStringTag] = "Sending";
|
|
136
|
+
constructor(sent: Promise<SentMessage>);
|
|
137
|
+
then<A = SentMessage, B = never>(onfulfilled?: ((m: SentMessage) => A | PromiseLike<A>) | null, onrejected?: ((reason: unknown) => B | PromiseLike<B>) | null): Promise<A | B>;
|
|
138
|
+
catch<B = never>(onrejected?: ((reason: unknown) => B | PromiseLike<B>) | null): Promise<SentMessage | B>;
|
|
139
|
+
finally(onfinally?: (() => void) | null): Promise<SentMessage>;
|
|
140
|
+
/** See {@link SentMessage.wait}. */
|
|
141
|
+
wait(opts?: WaitOptions): Promise<Reply>;
|
|
142
|
+
}
|
|
119
143
|
export declare class Services {
|
|
120
144
|
private readonly client;
|
|
121
145
|
constructor(client: A12sClient);
|
package/dist/src/fleet.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Runs in Node, Deno, Bun and browsers: no node: imports here (`npm run
|
|
1
|
+
// Runs in Node, Deno, Bun and browsers: no node: imports here (`npm run dashboard` bundles it for the browser).
|
|
2
2
|
import { A12sClient, A12sError, TurnStream, } from "./client.js";
|
|
3
3
|
const enc = encodeURIComponent;
|
|
4
4
|
const maxReplaceTries = 5;
|
|
@@ -9,7 +9,7 @@ const maxReplaceTries = 5;
|
|
|
9
9
|
* ```ts
|
|
10
10
|
* const fleet = await Fleet.connect();
|
|
11
11
|
* const hello = await fleet.agentComputers.create("hello", { instructions: "Be helpful" });
|
|
12
|
-
* await hello.
|
|
12
|
+
* const reply = await hello.send("hi").wait();
|
|
13
13
|
* await hello.remove();
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
@@ -98,7 +98,11 @@ export class AgentComputers {
|
|
|
98
98
|
constructor(client) {
|
|
99
99
|
this.client = client;
|
|
100
100
|
}
|
|
101
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Adds an agent computer to the Fleet and starts it. One that names a credential with no value yet resolves at once,
|
|
103
|
+
* waiting in Provisioning (`status.waiting`, and a console warning); it starts when the value is set. Fails with
|
|
104
|
+
* code `exists` if the name is taken.
|
|
105
|
+
*/
|
|
102
106
|
async create(name, spec = {}) {
|
|
103
107
|
const { replace, ...body } = spec;
|
|
104
108
|
const r = await this.client.request("PUT", `/v1/agent-computers/${enc(name)}`, body, {
|
|
@@ -151,13 +155,15 @@ export class AgentComputer {
|
|
|
151
155
|
async remove() {
|
|
152
156
|
await this.client.request("DELETE", this.path);
|
|
153
157
|
}
|
|
154
|
-
/**
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
/** Puts a Message in the inbox and returns at once; it is delivered at the next idle moment. */
|
|
158
|
+
/**
|
|
159
|
+
* Puts a Message in the inbox; it is delivered at the next idle moment. Await it for the queued Message, or call
|
|
160
|
+
* `wait()` on it (or on the awaited Message, at any time later) for the Turn that delivers it.
|
|
161
|
+
*/
|
|
159
162
|
send(text, opts = {}) {
|
|
160
|
-
return this.client.send(this.name, { ...opts, body: text })
|
|
163
|
+
return new Sending(this.client.send(this.name, { ...opts, body: text }).then((message) => ({
|
|
164
|
+
...message,
|
|
165
|
+
wait: (w) => this.client.reply(this.name, message, w),
|
|
166
|
+
})));
|
|
161
167
|
}
|
|
162
168
|
/** Its events, live, from the Fleet's shared connection; `turn` replays one Turn from its start instead. */
|
|
163
169
|
events(opts = {}) {
|
|
@@ -179,7 +185,7 @@ export class AgentComputer {
|
|
|
179
185
|
tools: t.tools.map((tc) => ({ ...tc, isError: tc.isError ?? false })),
|
|
180
186
|
}));
|
|
181
187
|
}
|
|
182
|
-
/** Stops its processes and keeps its disks, session and inbox
|
|
188
|
+
/** Stops its processes and keeps its disks, session and inbox; a sender in wakeOnMessage wakes it, unless `hold`. */
|
|
183
189
|
sleep(opts = {}) {
|
|
184
190
|
return this.client.sleep(this.name, opts);
|
|
185
191
|
}
|
|
@@ -210,6 +216,27 @@ export class AgentComputer {
|
|
|
210
216
|
return this.client.withdraw(this.name, id);
|
|
211
217
|
}
|
|
212
218
|
}
|
|
219
|
+
/** What `send()` returns: a promise of the {@link SentMessage}, with its `wait()` one call away. */
|
|
220
|
+
export class Sending {
|
|
221
|
+
sent;
|
|
222
|
+
[Symbol.toStringTag] = "Sending";
|
|
223
|
+
constructor(sent) {
|
|
224
|
+
this.sent = sent;
|
|
225
|
+
}
|
|
226
|
+
then(onfulfilled, onrejected) {
|
|
227
|
+
return this.sent.then(onfulfilled, onrejected);
|
|
228
|
+
}
|
|
229
|
+
catch(onrejected) {
|
|
230
|
+
return this.sent.catch(onrejected);
|
|
231
|
+
}
|
|
232
|
+
finally(onfinally) {
|
|
233
|
+
return this.sent.finally(onfinally);
|
|
234
|
+
}
|
|
235
|
+
/** See {@link SentMessage.wait}. */
|
|
236
|
+
async wait(opts) {
|
|
237
|
+
return (await this.sent).wait(opts);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
213
240
|
export class Services {
|
|
214
241
|
client;
|
|
215
242
|
constructor(client) {
|
|
@@ -317,8 +344,8 @@ export class Credentials {
|
|
|
317
344
|
await this.client.request("DELETE", `/v1/credentials/${enc(name)}`);
|
|
318
345
|
}
|
|
319
346
|
}
|
|
320
|
-
/** A write's warnings (a grant to an agent computer that doesn't exist yet, a missing harness credential
|
|
321
|
-
* console instead of being dropped. */
|
|
347
|
+
/** A write's warnings (a grant to an agent computer that doesn't exist yet, a missing harness credential, a credential
|
|
348
|
+
* with no value yet) go to the console instead of being dropped. */
|
|
322
349
|
function warnWrites(r) {
|
|
323
350
|
for (const w of r?.warnings ?? [])
|
|
324
351
|
console.warn(`a12s: ${w}`);
|
package/dist/src/types.d.ts
CHANGED
|
@@ -3,6 +3,12 @@ export interface Failure {
|
|
|
3
3
|
reason: string;
|
|
4
4
|
retryable: boolean;
|
|
5
5
|
}
|
|
6
|
+
/** Credentials an agent computer or Service waits for, in Provisioning; it starts by itself once they are set. */
|
|
7
|
+
export interface Waiting {
|
|
8
|
+
credentials: string[];
|
|
9
|
+
/** The commands that set them, e.g. "a12s creds set dbname". */
|
|
10
|
+
fix: string;
|
|
11
|
+
}
|
|
6
12
|
export interface Harness {
|
|
7
13
|
kind: string;
|
|
8
14
|
version: string;
|
|
@@ -204,6 +210,7 @@ export interface ComputerStatus {
|
|
|
204
210
|
name: string;
|
|
205
211
|
phase: Phase;
|
|
206
212
|
error?: Failure;
|
|
213
|
+
waiting?: Waiting;
|
|
207
214
|
resumePending?: boolean;
|
|
208
215
|
session?: string;
|
|
209
216
|
activeTurn?: string;
|
|
@@ -240,6 +247,7 @@ export interface ServiceStatus {
|
|
|
240
247
|
name: string;
|
|
241
248
|
phase: Phase;
|
|
242
249
|
error?: Failure;
|
|
250
|
+
waiting?: Waiting;
|
|
243
251
|
image: string;
|
|
244
252
|
pin?: string;
|
|
245
253
|
generation: number;
|
|
@@ -405,6 +413,7 @@ export interface FleetChangedData {
|
|
|
405
413
|
export interface PhaseData {
|
|
406
414
|
phase: Phase;
|
|
407
415
|
error?: Failure;
|
|
416
|
+
waiting?: Waiting;
|
|
408
417
|
}
|
|
409
418
|
/** A Service's phase, health or restart count changed. */
|
|
410
419
|
export interface ServicePhaseData {
|
|
@@ -414,6 +423,7 @@ export interface ServicePhaseData {
|
|
|
414
423
|
health?: string;
|
|
415
424
|
restarts: number;
|
|
416
425
|
error?: Failure;
|
|
426
|
+
waiting?: Waiting;
|
|
417
427
|
}
|
|
418
428
|
export interface ToolStartedData {
|
|
419
429
|
id: string;
|
|
@@ -502,7 +512,7 @@ export interface ToolCall {
|
|
|
502
512
|
output?: unknown;
|
|
503
513
|
isError: boolean;
|
|
504
514
|
}
|
|
505
|
-
/** A finished Turn: what `turns()` yields and `
|
|
515
|
+
/** A finished Turn: what `turns()` yields and `wait()` returns. */
|
|
506
516
|
export interface Turn {
|
|
507
517
|
agentComputer: string;
|
|
508
518
|
/** `agentComputer` under its old name, for one release. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coltonkirsten/a12s",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "TypeScript client for a12s: send work to agent Computers, stream their events and Turns, in Node or the browser",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -16,12 +16,10 @@
|
|
|
16
16
|
"types": "./dist/src/index.d.ts",
|
|
17
17
|
"default": "./dist/src/index.js"
|
|
18
18
|
}
|
|
19
|
-
}
|
|
20
|
-
"./browser.js": "./dist/a12s.js"
|
|
19
|
+
}
|
|
21
20
|
},
|
|
22
21
|
"files": [
|
|
23
|
-
"dist/src"
|
|
24
|
-
"dist/a12s.js"
|
|
22
|
+
"dist/src"
|
|
25
23
|
],
|
|
26
24
|
"engines": {
|
|
27
25
|
"node": ">=20"
|
|
@@ -37,10 +35,10 @@
|
|
|
37
35
|
"provenance": true
|
|
38
36
|
},
|
|
39
37
|
"scripts": {
|
|
40
|
-
"build": "rm -rf dist && tsc -p tsconfig.json && npm run
|
|
38
|
+
"build": "rm -rf dist && tsc -p tsconfig.json && npm run dashboard",
|
|
41
39
|
"lint": "tsc -p tsconfig.json --noEmit",
|
|
42
40
|
"test": "npm run build && node --test 'dist/test/*.test.js'",
|
|
43
|
-
"
|
|
41
|
+
"dashboard": "esbuild ../../internal/gateway/dashboard/main.js --bundle --platform=browser --format=esm --alias:@coltonkirsten/a12s=./src/index.ts --log-level=warning --outfile=dist/dashboard.js"
|
|
44
42
|
},
|
|
45
43
|
"devDependencies": {
|
|
46
44
|
"@types/node": "^24.19.1",
|