@pi-oxide/pi-host-web 0.3.0 → 0.3.1
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/package.json +2 -2
- package/pi_host_web.d.ts +6 -0
- package/pi_host_web.js +18 -0
- package/pi_host_web_bg.wasm +0 -0
- package/sdk/index.d.ts +5 -1
- package/sdk/index.js +30 -1
package/package.json
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
"Irving Ou <irving@pi-oxide.dev>"
|
|
6
6
|
],
|
|
7
7
|
"description": "WASM host for pi-core. Browser FileSystem Access API, fetch(), JS event loop.",
|
|
8
|
-
"version": "0.3.
|
|
8
|
+
"version": "0.3.1",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "
|
|
12
|
+
"url": "https://github.com/pi-oxide/pi-oxide"
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
15
|
"pi_host_web_bg.wasm",
|
package/pi_host_web.d.ts
CHANGED
|
@@ -389,8 +389,12 @@ export type ToolOutputStream = "stdout" | "stderr" | "status";
|
|
|
389
389
|
export type WaitMode = "steering" | "follow_up" | "any";
|
|
390
390
|
|
|
391
391
|
|
|
392
|
+
export function abort(handle: number): StepResult;
|
|
393
|
+
|
|
392
394
|
export function appendSessionEntry(handle: number, entry: SessionEntry): EmptyResult;
|
|
393
395
|
|
|
396
|
+
export function continueTurn(handle: number): StepResult;
|
|
397
|
+
|
|
394
398
|
export function createAgent(options: AgentOptions): CreateAgentResult;
|
|
395
399
|
|
|
396
400
|
export function destroyAgent(handle: number): EmptyResult;
|
|
@@ -439,7 +443,9 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
|
|
439
443
|
|
|
440
444
|
export interface InitOutput {
|
|
441
445
|
readonly memory: WebAssembly.Memory;
|
|
446
|
+
readonly abort: (a: number) => any;
|
|
442
447
|
readonly appendSessionEntry: (a: number, b: any) => any;
|
|
448
|
+
readonly continueTurn: (a: number) => any;
|
|
443
449
|
readonly createAgent: (a: any) => any;
|
|
444
450
|
readonly destroyAgent: (a: number) => any;
|
|
445
451
|
readonly estimateTokens: (a: any) => any;
|
package/pi_host_web.js
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
/* @ts-self-types="./pi_host_web.d.ts" */
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* @param {number} handle
|
|
5
|
+
* @returns {StepResult}
|
|
6
|
+
*/
|
|
7
|
+
export function abort(handle) {
|
|
8
|
+
const ret = wasm.abort(handle);
|
|
9
|
+
return ret;
|
|
10
|
+
}
|
|
11
|
+
|
|
3
12
|
/**
|
|
4
13
|
* @param {number} handle
|
|
5
14
|
* @param {SessionEntry} entry
|
|
@@ -10,6 +19,15 @@ export function appendSessionEntry(handle, entry) {
|
|
|
10
19
|
return ret;
|
|
11
20
|
}
|
|
12
21
|
|
|
22
|
+
/**
|
|
23
|
+
* @param {number} handle
|
|
24
|
+
* @returns {StepResult}
|
|
25
|
+
*/
|
|
26
|
+
export function continueTurn(handle) {
|
|
27
|
+
const ret = wasm.continueTurn(handle);
|
|
28
|
+
return ret;
|
|
29
|
+
}
|
|
30
|
+
|
|
13
31
|
/**
|
|
14
32
|
* @param {AgentOptions} options
|
|
15
33
|
* @returns {CreateAgentResult}
|
package/pi_host_web_bg.wasm
CHANGED
|
Binary file
|
package/sdk/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export * from "../pi_host_web.js";
|
|
|
8
8
|
|
|
9
9
|
export declare function ensureInit(): Promise<void>;
|
|
10
10
|
|
|
11
|
+
export declare function continueTurn(handle: number): StepResult;
|
|
12
|
+
|
|
11
13
|
export declare function toolResult(
|
|
12
14
|
text: string,
|
|
13
15
|
opts?: { terminate?: boolean }
|
|
@@ -24,7 +26,7 @@ export interface LlmStream {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export interface LlmProvider {
|
|
27
|
-
call(context: LlmContext): Promise<LlmStream> | LlmStream;
|
|
29
|
+
call(context: LlmContext, signal?: AbortSignal): Promise<LlmStream> | LlmStream;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
32
|
export type ToolMap = Record<
|
|
@@ -36,11 +38,13 @@ export interface AgentRunConfig {
|
|
|
36
38
|
llm: LlmProvider;
|
|
37
39
|
tools: ToolMap;
|
|
38
40
|
onEvent?: (event: AgentEvent) => void;
|
|
41
|
+
signal?: AbortSignal;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
export declare class Agent {
|
|
42
45
|
static create(options: AgentOptions): Promise<Agent>;
|
|
43
46
|
run(promptText: string, config: AgentRunConfig): Promise<AgentAction>;
|
|
47
|
+
stop(): void;
|
|
44
48
|
reset(): void;
|
|
45
49
|
state(): AgentState;
|
|
46
50
|
getSessionState(): SessionState;
|
package/sdk/index.js
CHANGED
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
|
+
abort,
|
|
12
13
|
createAgent,
|
|
14
|
+
continueTurn,
|
|
13
15
|
destroyAgent,
|
|
14
16
|
feedLlmChunk,
|
|
15
17
|
followUp,
|
|
@@ -109,28 +111,41 @@ export class Agent {
|
|
|
109
111
|
* @param {LlmProvider} config.llm
|
|
110
112
|
* @param {Record<string, (call: ToolCall) => Promise<ToolResult> | ToolResult>} config.tools
|
|
111
113
|
* @param {(event: AgentEvent) => void} [config.onEvent]
|
|
114
|
+
* @param {AbortSignal} [config.signal] — abort to stop mid-stream or mid-tool
|
|
112
115
|
* @returns {Promise<AgentAction>} terminal action (finished or wait_for_input)
|
|
113
116
|
*/
|
|
114
117
|
async run(promptText, config) {
|
|
118
|
+
const signal = config.signal;
|
|
119
|
+
const checkAbort = () => {
|
|
120
|
+
if (signal?.aborted) {
|
|
121
|
+
this.stop();
|
|
122
|
+
throw new HostError("user_aborted", "Turn stopped by user");
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
115
126
|
let step = unwrap(prompt(this.#handle, { text: promptText }));
|
|
116
127
|
for (const event of step.events) {
|
|
117
128
|
config.onEvent?.(event);
|
|
118
129
|
}
|
|
119
130
|
|
|
120
131
|
while (true) {
|
|
132
|
+
checkAbort();
|
|
121
133
|
let actions = step.actions ?? [];
|
|
122
134
|
if (actions.length === 0) {
|
|
123
135
|
return { type: "finished", messages: [] };
|
|
124
136
|
}
|
|
125
137
|
|
|
126
138
|
for (const action of actions) {
|
|
139
|
+
checkAbort();
|
|
127
140
|
switch (action.type) {
|
|
128
141
|
case "stream_llm": {
|
|
129
|
-
const stream = await config.llm.call(action.context);
|
|
142
|
+
const stream = await config.llm.call(action.context, signal);
|
|
130
143
|
for await (const chunk of stream.chunks) {
|
|
144
|
+
checkAbort();
|
|
131
145
|
const ev = unwrap(feedLlmChunk(this.#handle, chunk));
|
|
132
146
|
for (const e of ev.events) config.onEvent?.(e);
|
|
133
147
|
}
|
|
148
|
+
checkAbort();
|
|
134
149
|
const result = await stream.result;
|
|
135
150
|
step = unwrap(onLlmDone(this.#handle, result));
|
|
136
151
|
for (const e of step.events) config.onEvent?.(e);
|
|
@@ -139,6 +154,7 @@ export class Agent {
|
|
|
139
154
|
|
|
140
155
|
case "execute_tools": {
|
|
141
156
|
for (const call of action.calls) {
|
|
157
|
+
checkAbort();
|
|
142
158
|
const started = unwrap(onToolStarted(this.#handle, call.id));
|
|
143
159
|
for (const e of started.events) config.onEvent?.(e);
|
|
144
160
|
|
|
@@ -152,6 +168,10 @@ export class Agent {
|
|
|
152
168
|
step = unwrap(onToolDone(this.#handle, call.id, result));
|
|
153
169
|
for (const e of step.events) config.onEvent?.(e);
|
|
154
170
|
}
|
|
171
|
+
if ((step.actions ?? []).length === 0) {
|
|
172
|
+
step = unwrap(continueTurn(this.#handle));
|
|
173
|
+
for (const e of step.events) config.onEvent?.(e);
|
|
174
|
+
}
|
|
155
175
|
break;
|
|
156
176
|
}
|
|
157
177
|
|
|
@@ -178,6 +198,15 @@ export class Agent {
|
|
|
178
198
|
}
|
|
179
199
|
}
|
|
180
200
|
|
|
201
|
+
/** Abort a running turn mid-stream or mid-tool. */
|
|
202
|
+
stop() {
|
|
203
|
+
try {
|
|
204
|
+
unwrap(abort(this.#handle));
|
|
205
|
+
} catch (e) {
|
|
206
|
+
if (e.code !== "wrong_phase") throw e;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
181
210
|
/** Reset agent state (clear messages, return to idle). */
|
|
182
211
|
reset() {
|
|
183
212
|
unwrap(reset(this.#handle));
|