@pi-oxide/pi-host-web 0.3.1 → 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/package.json CHANGED
@@ -5,33 +5,20 @@
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.1",
8
+ "version": "0.5.0",
9
9
  "license": "MIT",
10
10
  "repository": {
11
11
  "type": "git",
12
- "url": "https://github.com/pi-oxide/pi-oxide"
12
+ "url": "git+https://github.com/pi-oxide/pi-oxide.git"
13
13
  },
14
14
  "files": [
15
15
  "pi_host_web_bg.wasm",
16
16
  "pi_host_web.js",
17
- "pi_host_web.d.ts",
18
- "sdk/index.js",
19
- "sdk/index.d.ts"
17
+ "pi_host_web.d.ts"
20
18
  ],
21
19
  "main": "pi_host_web.js",
22
20
  "types": "pi_host_web.d.ts",
23
21
  "sideEffects": [
24
22
  "./snippets/*"
25
- ],
26
- "exports": {
27
- ".": {
28
- "import": "./sdk/index.js",
29
- "types": "./sdk/index.d.ts"
30
- },
31
- "./raw": {
32
- "import": "./pi_host_web.js",
33
- "types": "./pi_host_web.d.ts"
34
- },
35
- "./package.json": "./package.json"
36
- }
23
+ ]
37
24
  }
package/pi_host_web.d.ts CHANGED
@@ -10,30 +10,20 @@ export interface AgentOptions {
10
10
  system_prompt: string;
11
11
  model: Model;
12
12
  thinking_level?: ThinkingLevel;
13
- tools?: ToolDefinition[];
14
13
  steering_mode?: QueueMode;
15
14
  follow_up_mode?: QueueMode;
16
- tool_execution_mode?: ToolExecutionMode;
15
+ tool_execution_mode?: ExecutionMode;
17
16
  session_id?: SessionId;
18
- messages?: AgentMessage[];
19
- session_state?: SessionState | null;
20
17
  }
21
18
 
22
- export interface AgentState {
23
- system_prompt: string;
24
- model: Model;
25
- thinking_level: ThinkingLevel;
26
- tools: ToolDefinition[];
27
- messages: AgentMessage[];
28
- is_streaming: boolean;
29
- streaming_message?: AgentMessage;
30
- pending_tool_calls: string[];
31
- error_message?: string;
19
+ export interface ArtifactSearchResult {
20
+ id: string;
21
+ snippet: string;
22
+ match_count: number;
32
23
  }
33
24
 
34
- export interface ApiUsageSnapshot {
35
- estimated_tokens: number;
36
- actual_input_tokens: number;
25
+ export interface ArtifactSearchResults {
26
+ results: ArtifactSearchResult[];
37
27
  }
38
28
 
39
29
  export interface AssistantMessage {
@@ -47,49 +37,30 @@ export interface AssistantMessage {
47
37
  usage: TokenUsage;
48
38
  }
49
39
 
50
- export interface BranchSummary {
51
- summary: string;
52
- details?: JsonSchema;
53
- }
54
-
55
40
  export interface ContextProjectionBudget {
56
- max_tool_result_chars: number;
57
- max_context_tokens: number;
58
- default_preview_chars: number;
41
+ max_tool_result_chars?: number;
42
+ max_context_tokens?: number;
59
43
  microcompact_after_turns?: number;
60
44
  compaction_threshold?: number;
61
45
  }
62
46
 
63
- export interface ContextProjectionReport {
64
- estimated_tokens: number;
65
- replacements: ContextReplacement[];
66
- dropped_messages: number;
67
- needs_compaction?: boolean;
68
- cache_breakpoints?: number[];
69
- }
70
-
71
- export interface ContextProjectionState {
72
- replacements: Record<string, ContextReplacement>;
73
- last_api_usage?: ApiUsageSnapshot | null;
74
- turns_since_compaction?: number;
47
+ export interface CreateHostAgentOutput {
48
+ handle: number;
75
49
  }
76
50
 
77
- export interface ContextReplacement {
78
- tool_call_id: string;
79
- tool_name: string;
80
- artifact_id: string;
81
- original_chars: number;
82
- preview_chars: number;
83
- strategy: ContextStrategy;
51
+ export interface CreateHostAgentResult {
52
+ ok: boolean;
53
+ data?: CreateHostAgentOutput;
54
+ error?: ErrorDto;
84
55
  }
85
56
 
86
- export interface CreateAgentOutput {
57
+ export interface CreateHostStateOutput {
87
58
  handle: number;
88
59
  }
89
60
 
90
- export interface CreateAgentResult {
61
+ export interface CreateHostStateResult {
91
62
  ok: boolean;
92
- data?: CreateAgentOutput;
63
+ data?: CreateHostStateOutput;
93
64
  error?: ErrorDto;
94
65
  }
95
66
 
@@ -118,13 +89,13 @@ export interface EstimateTokensResult {
118
89
  error?: ErrorDto;
119
90
  }
120
91
 
121
- export interface EventsOutput {
122
- events: AgentEvent[];
92
+ export interface HostStatePersistDataOutput {
93
+ state: PersistData;
123
94
  }
124
95
 
125
- export interface EventsResult {
96
+ export interface HostStatePersistDataResult {
126
97
  ok: boolean;
127
- data?: EventsOutput;
98
+ data?: HostStatePersistDataOutput;
128
99
  error?: ErrorDto;
129
100
  }
130
101
 
@@ -172,87 +143,19 @@ export interface ModelCost {
172
143
  cache_write: number;
173
144
  }
174
145
 
175
- export interface MoveToOutput {
176
- summary_entry_id: string | null;
177
- }
178
-
179
- export interface MoveToResult {
180
- ok: boolean;
181
- data?: MoveToOutput;
182
- error?: ErrorDto;
183
- }
184
-
185
- export interface ProjectionInput {
186
- system_prompt: string;
187
- messages: AgentMessage[];
188
- budget: ContextProjectionBudget;
189
- state: ContextProjectionState;
190
- }
191
-
192
- export interface ProjectionOutput {
193
- projected_messages: AgentMessage[];
194
- updated_state: ContextProjectionState;
195
- report: ContextProjectionReport;
196
- }
197
-
198
- export interface ProjectionResult {
199
- ok: boolean;
200
- data?: ProjectionOutput;
201
- error?: ErrorDto;
202
- }
203
-
204
- export interface SessionBranchOutput {
205
- entries: SessionEntry[];
206
- }
207
-
208
- export interface SessionBranchResult {
209
- ok: boolean;
210
- data?: SessionBranchOutput;
211
- error?: ErrorDto;
212
- }
213
-
214
- export interface SessionEntry {
215
- id: string;
216
- parent_id?: string;
217
- kind: EntryKind;
218
- timestamp: number;
146
+ export interface PersistData {
147
+ T?: Value;
148
+ A?: Value;
149
+ turn_number?: number;
150
+ host_artifacts?: [string, string][];
151
+ budget?: ContextProjectionBudget;
152
+ system_prompt?: string;
153
+ compaction_prompt?: string;
219
154
  }
220
155
 
221
- export interface SessionState {
222
- entries: SessionEntry[];
223
- leaf_id: string;
224
- name?: string;
225
- }
226
-
227
- export interface SessionStateOutput {
228
- state: SessionState;
229
- }
230
-
231
- export interface SessionStateResult {
232
- ok: boolean;
233
- data?: SessionStateOutput;
234
- error?: ErrorDto;
235
- }
236
-
237
- export interface StateOutput {
238
- state: AgentState;
239
- }
240
-
241
- export interface StateResult {
242
- ok: boolean;
243
- data?: StateOutput;
244
- error?: ErrorDto;
245
- }
246
-
247
- export interface StepOutput {
248
- events: AgentEvent[];
249
- actions: AgentAction[];
250
- }
251
-
252
- export interface StepResult {
253
- ok: boolean;
254
- data?: StepOutput;
255
- error?: ErrorDto;
156
+ export interface StartTurnInput {
157
+ prompt: AgentMessage;
158
+ tools?: ToolDefinition[];
256
159
  }
257
160
 
258
161
  export interface TextContent {
@@ -273,12 +176,19 @@ export interface ToolCall {
273
176
  arguments: ToolArguments;
274
177
  }
275
178
 
179
+ export interface ToolCallPreparation {
180
+ tool_call_id: ToolCallId;
181
+ transform: ToolCallTransform;
182
+ permission: ToolCallPermission;
183
+ }
184
+
276
185
  export interface ToolDefinition {
277
186
  name: ToolName;
278
187
  label: string;
279
188
  description: string;
280
189
  parameters: JsonSchema;
281
190
  execution_mode?: ExecutionMode;
191
+ tool_run_mode?: ToolRunMode;
282
192
  }
283
193
 
284
194
  export interface ToolError {
@@ -301,15 +211,6 @@ export interface ToolResult {
301
211
  terminate?: boolean;
302
212
  }
303
213
 
304
- export interface ToolResultContext {
305
- content_kind: ContentKind;
306
- strategy: ContextStrategy;
307
- original_chars: number;
308
- truncated_by_tool: boolean;
309
- path?: string;
310
- exit_code?: number;
311
- }
312
-
313
214
  export interface ToolResultMessage {
314
215
  tool_call_id: ToolCallId;
315
216
  tool_name: ToolName;
@@ -319,14 +220,24 @@ export interface ToolResultMessage {
319
220
  timestamp: number;
320
221
  }
321
222
 
223
+ export interface TurnResultOutput {
224
+ events: AgentEvent[];
225
+ directives: HostDirective[];
226
+ markers?: ChangeMarkerDto[];
227
+ }
228
+
229
+ export interface TurnResultResult {
230
+ ok: boolean;
231
+ data?: TurnResultOutput;
232
+ error?: ErrorDto;
233
+ }
234
+
322
235
  export interface UserMessage {
323
236
  content: Content[];
324
237
  timestamp: number;
325
238
  }
326
239
 
327
- export type AgentAction = { type: "stream_llm"; context: LlmContext; session_id?: SessionId } | { type: "execute_tools"; calls: ToolCall[] } | { type: "cancel_tools"; tool_call_ids: ToolCallId[]; reason: CancelReason } | { type: "wait_for_input"; mode: WaitMode } | { type: "finished"; messages: AgentMessage[] };
328
-
329
- export type AgentEvent = { type: "agent_start" } | { type: "agent_end"; messages: AgentMessage[] } | { type: "turn_start" } | { type: "turn_end"; message: AgentMessage; tool_results: ToolResultMessage[] } | { type: "message_start"; message: AgentMessage } | { type: "message_update"; message: AgentMessage; delta: ContentDelta } | { type: "message_end"; message: AgentMessage } | { type: "tool_execution_start"; tool_call_id: ToolCallId; tool_name: ToolName; args?: ToolArguments } | { type: "tool_execution_update"; tool_call_id: ToolCallId; stream: ToolOutputStream; chunk: string; sequence: number; timestamp: number } | { type: "tool_execution_end"; tool_call_id: ToolCallId; result: ToolResult; is_error: boolean } | { type: "tool_execution_cancelled"; tool_call_id: ToolCallId; reason: CancelReason } | { type: "queue_update"; steer: AgentMessage[]; follow_up: AgentMessage[] } | { type: "save_point"; had_pending_writes: boolean } | { type: "settled" };
240
+ export type AgentEvent = { type: "agent_start" } | { type: "agent_end" } | { type: "turn_start" } | { type: "turn_end"; message: AgentMessage; tool_results: ToolResultMessage[] } | { type: "message_start"; message: AgentMessage } | { type: "message_update"; message: AgentMessage; delta: ContentDelta } | { type: "message_end"; message: AgentMessage } | { type: "tool_execution_start"; tool_call_id: ToolCallId; tool_name: ToolName; args?: ToolArguments } | { type: "tool_execution_update"; tool_call_id: ToolCallId; stream: ToolOutputStream; chunk: string; sequence: number; timestamp: number } | { type: "tool_execution_end"; tool_call_id: ToolCallId; tool_name: ToolName; result: ToolResult; args?: ToolArguments; is_error: boolean } | { type: "tool_execution_cancelled"; tool_call_id: ToolCallId; reason: CancelReason } | { type: "queue_update"; steer: AgentMessage[]; follow_up: AgentMessage[] } | { type: "save_point"; had_pending_writes: boolean } | { type: "settled" };
330
241
 
331
242
  export type AgentMessage = ({ role: "user" } & UserMessage) | ({ role: "assistant" } & AssistantMessage) | ({ role: "tool_result" } & ToolResultMessage);
332
243
 
@@ -334,18 +245,16 @@ export type ApiName = string;
334
245
 
335
246
  export type CancelReason = { type: "user_requested" } | { type: "timeout" } | { type: "agent_aborted" } | { type: "dependency_failed"; cause_tool_call_id: ToolCallId };
336
247
 
248
+ export type ChangeMarkerDto = { type: "compaction_applied" } | { type: "new_artifacts"; entry_ids: string[] };
249
+
337
250
  export type Content = ({ type: "text" } & TextContent) | ({ type: "image" } & ImageContent) | ({ type: "tool_call" } & ToolCall);
338
251
 
339
252
  export type ContentDelta = { kind: "text_start" } | { kind: "text_delta"; text: string } | { kind: "text_end" } | { kind: "thinking_start" } | { kind: "thinking_delta"; text: string } | { kind: "thinking_end" } | { kind: "tool_call_start"; tool_call: ToolCall } | { kind: "tool_call_delta"; tool_call_id: ToolCallId; delta: Value } | { kind: "tool_call_end"; tool_call_id: ToolCallId };
340
253
 
341
- export type ContentKind = "file_read" | "command_output" | "diff" | "search_results" | "directory_listing" | "generic_text";
342
-
343
- export type ContextStrategy = { type: "keep_full" } | { type: "head"; max_chars: number } | { type: "tail"; max_chars: number } | { type: "head_tail"; head_chars: number; tail_chars: number } | { type: "drop_if_old" } | { type: "microcompacted" };
344
-
345
- export type EntryKind = ({ type: "message" } & {} & AgentMessage) | { type: "compaction"; summary: string; first_kept_entry_id: string; tokens_before: number; details?: JsonSchema } | { type: "branch_summary"; summary: string; details?: JsonSchema } | { type: "model_change"; provider: string; model_id: string } | ({ type: "thinking_level_change" } & ThinkingLevel) | { type: "custom"; custom_type: string; data?: JsonSchema };
346
-
347
254
  export type ExecutionMode = "parallel" | "sequential";
348
255
 
256
+ export type HostDirective = { type: "stream_llm"; context: LlmContext } | { type: "prepare_tool_calls"; calls: ToolCall[] } | { type: "execute_tools"; calls: ToolCall[] } | { type: "cancel_tools"; tool_call_ids: ToolCallId[]; reason: CancelReason } | { type: "persist" } | { type: "summarize"; context: LlmContext } | { type: "finished" } | { type: "wait_for_input"; mode: WaitMode };
257
+
349
258
  export type JsonSchema = Value;
350
259
 
351
260
  export type LlmChunk = ({ kind: "start" } & {} & AssistantMessage) | { kind: "text_delta"; text: string } | { kind: "thinking_delta"; text: string } | { kind: "tool_call_delta"; tool_call_id: ToolCallId; delta: Value } | { kind: "done" } | { kind: "error"; message: string };
@@ -358,10 +267,6 @@ export type ModelName = string;
358
267
 
359
268
  export type ModelProvider = "open_ai" | "anthropic" | "google" | "ollama" | "custom";
360
269
 
361
- export type Phase = "idle" | "streaming" | "wait_for_input";
362
-
363
- export type PromptRequest = AgentMessage | { text: string };
364
-
365
270
  export type ProviderName = string;
366
271
 
367
272
  export type QueueMode = "one_at_a_time" | "all";
@@ -376,104 +281,110 @@ export type ToolArguments = Value;
376
281
 
377
282
  export type ToolCallId = string;
378
283
 
379
- export type ToolDetails = Value;
284
+ export type ToolCallPermission = { type: "allow" } | { type: "block"; reason: string };
380
285
 
381
- export type ToolDonePayload = { error: ToolError } | { result: ToolResult } | ToolResult;
286
+ export type ToolCallTransform = { type: "none" } | { type: "rewrite_args"; arguments: ToolArguments };
382
287
 
383
- export type ToolExecutionMode = "parallel" | "sequential";
288
+ export type ToolDetails = Value;
384
289
 
385
290
  export type ToolName = string;
386
291
 
387
292
  export type ToolOutputStream = "stdout" | "stderr" | "status";
388
293
 
389
- export type WaitMode = "steering" | "follow_up" | "any";
294
+ export type ToolRunMode = "immediate" | "deferred";
390
295
 
296
+ export type WaitMode = "steering" | "follow_up" | "any";
391
297
 
392
- export function abort(handle: number): StepResult;
393
298
 
394
- export function appendSessionEntry(handle: number, entry: SessionEntry): EmptyResult;
299
+ export function createHostAgent(options: AgentOptions, budget: ContextProjectionBudget): CreateHostAgentResult;
395
300
 
396
- export function continueTurn(handle: number): StepResult;
301
+ export function createHostState(_budget: ContextProjectionBudget): CreateHostStateResult;
397
302
 
398
- export function createAgent(options: AgentOptions): CreateAgentResult;
303
+ export function destroyHostAgent(handle: number): EmptyResult;
399
304
 
400
- export function destroyAgent(handle: number): EmptyResult;
305
+ export function destroyHostState(handle: number): EmptyResult;
401
306
 
402
307
  export function estimateTokens(input: EstimateTokensInput): EstimateTokensResult;
403
308
 
404
309
  export function estimateTokensForText(text: string): EstimateTokensResult;
405
310
 
406
- export function fallbackStrategy(tool_name: string): ContextStrategy;
311
+ export function getHostAgentPersistData(handle: number): HostStatePersistDataResult;
407
312
 
408
- export function feedLlmChunk(handle: number, chunk: LlmChunk): EventsResult;
313
+ export function getHostStatePersistData(handle: number): HostStatePersistDataResult;
409
314
 
410
- export function followUp(handle: number, message: AgentMessage): EmptyResult;
315
+ export function hostAbort(handle: number): TurnResultResult;
411
316
 
412
- export function getSessionBranch(handle: number): SessionBranchResult;
317
+ export function hostAcceptCompaction(handle: number, summary: string, _compacted_entry_ids: string[]): TurnResultResult;
413
318
 
414
- export function getSessionState(handle: number): SessionStateResult;
319
+ export function hostContinueTurn(handle: number): TurnResultResult;
415
320
 
416
- export function moveTo(handle: number, target_id: string, summary?: BranchSummary | null): MoveToResult;
321
+ export function hostFeedLlmChunk(handle: number, chunk: LlmChunk): TurnResultResult;
417
322
 
418
- export function onLlmDone(handle: number, result: LlmResult): StepResult;
323
+ export function hostLlmDone(handle: number, result: LlmResult): TurnResultResult;
419
324
 
420
- export function onToolCancelled(handle: number, tool_call_id: string, reason: CancelReason): StepResult;
325
+ export function hostPrepareToolCalls(handle: number, preparations_json: string): TurnResultResult;
421
326
 
422
- export function onToolDone(handle: number, tool_call_id: string, payload: ToolDonePayload): StepResult;
327
+ export function hostReadArtifact(handle: number, artifact_id: string): string;
423
328
 
424
- export function onToolStarted(handle: number, tool_call_id: string): EventsResult;
329
+ export function hostReset(handle: number): EmptyResult;
425
330
 
426
- export function onToolUpdate(handle: number, update: ToolExecutionUpdate): EventsResult;
331
+ export function hostSearchArtifacts(handle: number, query: string): ArtifactSearchResults;
427
332
 
428
- export function projectContext(input: ProjectionInput): ProjectionResult;
333
+ export function hostSteer(handle: number, message: AgentMessage): TurnResultResult;
429
334
 
430
- export function prompt(handle: number, prompt: PromptRequest): StepResult;
335
+ export function hostToolCancelled(handle: number, tool_call_id: string, reason: CancelReason): TurnResultResult;
431
336
 
432
- export function reset(handle: number): EmptyResult;
337
+ export function hostToolDone(handle: number, id: ToolCallId, result: ToolResult): TurnResultResult;
433
338
 
434
- export function setLogLevel(level: string): void;
339
+ export function hostToolFailed(handle: number, id: ToolCallId, error: ToolError): TurnResultResult;
340
+
341
+ export function restoreHostAgent(options: AgentOptions, data: PersistData): CreateHostAgentResult;
435
342
 
436
- export function setSessionState(handle: number, state: SessionState): EmptyResult;
343
+ export function restoreHostState(data: PersistData): CreateHostStateResult;
437
344
 
438
- export function state(handle: number): StateResult;
345
+ export function restoreHostStateFromJson(json: string): CreateHostStateResult;
346
+
347
+ export function setLogLevel(level: string): void;
439
348
 
440
- export function steer(handle: number, message: AgentMessage): EventsResult;
349
+ export function startTurn(handle: number, input: StartTurnInput): TurnResultResult;
441
350
 
442
351
  export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
443
352
 
444
353
  export interface InitOutput {
445
354
  readonly memory: WebAssembly.Memory;
446
- readonly abort: (a: number) => any;
447
- readonly appendSessionEntry: (a: number, b: any) => any;
448
- readonly continueTurn: (a: number) => any;
449
- readonly createAgent: (a: any) => any;
450
- readonly destroyAgent: (a: number) => any;
355
+ readonly createHostState: (a: any) => any;
356
+ readonly destroyHostState: (a: number) => any;
451
357
  readonly estimateTokens: (a: any) => any;
452
358
  readonly estimateTokensForText: (a: number, b: number) => any;
453
- readonly fallbackStrategy: (a: number, b: number) => any;
454
- readonly feedLlmChunk: (a: number, b: any) => any;
455
- readonly followUp: (a: number, b: any) => any;
456
- readonly getSessionBranch: (a: number) => any;
457
- readonly getSessionState: (a: number) => any;
458
- readonly moveTo: (a: number, b: number, c: number, d: number) => any;
459
- readonly onLlmDone: (a: number, b: any) => any;
460
- readonly onToolCancelled: (a: number, b: number, c: number, d: any) => any;
461
- readonly onToolDone: (a: number, b: number, c: number, d: any) => any;
462
- readonly onToolStarted: (a: number, b: number, c: number) => any;
463
- readonly onToolUpdate: (a: number, b: any) => any;
464
- readonly projectContext: (a: any) => any;
465
- readonly prompt: (a: number, b: any) => any;
466
- readonly reset: (a: number) => any;
359
+ readonly getHostStatePersistData: (a: number) => any;
360
+ readonly restoreHostState: (a: any) => any;
361
+ readonly restoreHostStateFromJson: (a: number, b: number) => any;
467
362
  readonly setLogLevel: (a: number, b: number) => void;
468
- readonly setSessionState: (a: number, b: any) => any;
469
- readonly state: (a: number) => any;
470
- readonly steer: (a: number, b: any) => any;
363
+ readonly hostReadArtifact: (a: number, b: number, c: number) => [number, number, number, number];
364
+ readonly hostSearchArtifacts: (a: number, b: number, c: number) => [number, number, number];
365
+ readonly createHostAgent: (a: any, b: any) => any;
366
+ readonly destroyHostAgent: (a: number) => any;
367
+ readonly getHostAgentPersistData: (a: number) => any;
368
+ readonly hostAbort: (a: number) => any;
369
+ readonly hostAcceptCompaction: (a: number, b: number, c: number, d: number, e: number) => any;
370
+ readonly hostContinueTurn: (a: number) => any;
371
+ readonly hostFeedLlmChunk: (a: number, b: any) => any;
372
+ readonly hostLlmDone: (a: number, b: any) => any;
373
+ readonly hostPrepareToolCalls: (a: number, b: number, c: number) => any;
374
+ readonly hostReset: (a: number) => any;
375
+ readonly hostSteer: (a: number, b: any) => any;
376
+ readonly hostToolCancelled: (a: number, b: number, c: number, d: any) => any;
377
+ readonly hostToolDone: (a: number, b: any, c: any) => any;
378
+ readonly hostToolFailed: (a: number, b: any, c: any) => any;
379
+ readonly restoreHostAgent: (a: any, b: any) => any;
380
+ readonly startTurn: (a: number, b: any) => any;
471
381
  readonly __wbindgen_malloc: (a: number, b: number) => number;
472
382
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
473
383
  readonly __wbindgen_free: (a: number, b: number, c: number) => void;
474
384
  readonly __wbindgen_exn_store: (a: number) => void;
475
385
  readonly __externref_table_alloc: () => number;
476
386
  readonly __wbindgen_externrefs: WebAssembly.Table;
387
+ readonly __externref_table_dealloc: (a: number) => void;
477
388
  readonly __wbindgen_start: () => void;
478
389
  }
479
390
 
package/pi_host_web.js CHANGED
@@ -1,39 +1,30 @@
1
1
  /* @ts-self-types="./pi_host_web.d.ts" */
2
2
 
3
3
  /**
4
- * @param {number} handle
5
- * @returns {StepResult}
4
+ * @param {AgentOptions} options
5
+ * @param {ContextProjectionBudget} budget
6
+ * @returns {CreateHostAgentResult}
6
7
  */
7
- export function abort(handle) {
8
- const ret = wasm.abort(handle);
8
+ export function createHostAgent(options, budget) {
9
+ const ret = wasm.createHostAgent(options, budget);
9
10
  return ret;
10
11
  }
11
12
 
12
13
  /**
13
- * @param {number} handle
14
- * @param {SessionEntry} entry
15
- * @returns {EmptyResult}
14
+ * @param {ContextProjectionBudget} _budget
15
+ * @returns {CreateHostStateResult}
16
16
  */
17
- export function appendSessionEntry(handle, entry) {
18
- const ret = wasm.appendSessionEntry(handle, entry);
17
+ export function createHostState(_budget) {
18
+ const ret = wasm.createHostState(_budget);
19
19
  return ret;
20
20
  }
21
21
 
22
22
  /**
23
23
  * @param {number} handle
24
- * @returns {StepResult}
25
- */
26
- export function continueTurn(handle) {
27
- const ret = wasm.continueTurn(handle);
28
- return ret;
29
- }
30
-
31
- /**
32
- * @param {AgentOptions} options
33
- * @returns {CreateAgentResult}
24
+ * @returns {EmptyResult}
34
25
  */
35
- export function createAgent(options) {
36
- const ret = wasm.createAgent(options);
26
+ export function destroyHostAgent(handle) {
27
+ const ret = wasm.destroyHostAgent(handle);
37
28
  return ret;
38
29
  }
39
30
 
@@ -41,8 +32,8 @@ export function createAgent(options) {
41
32
  * @param {number} handle
42
33
  * @returns {EmptyResult}
43
34
  */
44
- export function destroyAgent(handle) {
45
- const ret = wasm.destroyAgent(handle);
35
+ export function destroyHostState(handle) {
36
+ const ret = wasm.destroyHostState(handle);
46
37
  return ret;
47
38
  }
48
39
 
@@ -67,193 +58,241 @@ export function estimateTokensForText(text) {
67
58
  }
68
59
 
69
60
  /**
70
- * @param {string} tool_name
71
- * @returns {ContextStrategy}
61
+ * @param {number} handle
62
+ * @returns {HostStatePersistDataResult}
72
63
  */
73
- export function fallbackStrategy(tool_name) {
74
- const ptr0 = passStringToWasm0(tool_name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
75
- const len0 = WASM_VECTOR_LEN;
76
- const ret = wasm.fallbackStrategy(ptr0, len0);
64
+ export function getHostAgentPersistData(handle) {
65
+ const ret = wasm.getHostAgentPersistData(handle);
77
66
  return ret;
78
67
  }
79
68
 
80
69
  /**
81
70
  * @param {number} handle
82
- * @param {LlmChunk} chunk
83
- * @returns {EventsResult}
71
+ * @returns {HostStatePersistDataResult}
84
72
  */
85
- export function feedLlmChunk(handle, chunk) {
86
- const ret = wasm.feedLlmChunk(handle, chunk);
73
+ export function getHostStatePersistData(handle) {
74
+ const ret = wasm.getHostStatePersistData(handle);
87
75
  return ret;
88
76
  }
89
77
 
90
78
  /**
91
79
  * @param {number} handle
92
- * @param {AgentMessage} message
93
- * @returns {EmptyResult}
80
+ * @returns {TurnResultResult}
94
81
  */
95
- export function followUp(handle, message) {
96
- const ret = wasm.followUp(handle, message);
82
+ export function hostAbort(handle) {
83
+ const ret = wasm.hostAbort(handle);
97
84
  return ret;
98
85
  }
99
86
 
100
87
  /**
101
88
  * @param {number} handle
102
- * @returns {SessionBranchResult}
89
+ * @param {string} summary
90
+ * @param {string[]} _compacted_entry_ids
91
+ * @returns {TurnResultResult}
103
92
  */
104
- export function getSessionBranch(handle) {
105
- const ret = wasm.getSessionBranch(handle);
93
+ export function hostAcceptCompaction(handle, summary, _compacted_entry_ids) {
94
+ const ptr0 = passStringToWasm0(summary, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
95
+ const len0 = WASM_VECTOR_LEN;
96
+ const ptr1 = passArrayJsValueToWasm0(_compacted_entry_ids, wasm.__wbindgen_malloc);
97
+ const len1 = WASM_VECTOR_LEN;
98
+ const ret = wasm.hostAcceptCompaction(handle, ptr0, len0, ptr1, len1);
106
99
  return ret;
107
100
  }
108
101
 
109
102
  /**
110
103
  * @param {number} handle
111
- * @returns {SessionStateResult}
104
+ * @returns {TurnResultResult}
112
105
  */
113
- export function getSessionState(handle) {
114
- const ret = wasm.getSessionState(handle);
106
+ export function hostContinueTurn(handle) {
107
+ const ret = wasm.hostContinueTurn(handle);
115
108
  return ret;
116
109
  }
117
110
 
118
111
  /**
119
112
  * @param {number} handle
120
- * @param {string} target_id
121
- * @param {BranchSummary | null} [summary]
122
- * @returns {MoveToResult}
113
+ * @param {LlmChunk} chunk
114
+ * @returns {TurnResultResult}
123
115
  */
124
- export function moveTo(handle, target_id, summary) {
125
- const ptr0 = passStringToWasm0(target_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
126
- const len0 = WASM_VECTOR_LEN;
127
- const ret = wasm.moveTo(handle, ptr0, len0, isLikeNone(summary) ? 0 : addToExternrefTable0(summary));
116
+ export function hostFeedLlmChunk(handle, chunk) {
117
+ const ret = wasm.hostFeedLlmChunk(handle, chunk);
128
118
  return ret;
129
119
  }
130
120
 
131
121
  /**
132
122
  * @param {number} handle
133
123
  * @param {LlmResult} result
134
- * @returns {StepResult}
124
+ * @returns {TurnResultResult}
135
125
  */
136
- export function onLlmDone(handle, result) {
137
- const ret = wasm.onLlmDone(handle, result);
126
+ export function hostLlmDone(handle, result) {
127
+ const ret = wasm.hostLlmDone(handle, result);
138
128
  return ret;
139
129
  }
140
130
 
141
131
  /**
142
132
  * @param {number} handle
143
- * @param {string} tool_call_id
144
- * @param {CancelReason} reason
145
- * @returns {StepResult}
133
+ * @param {string} preparations_json
134
+ * @returns {TurnResultResult}
146
135
  */
147
- export function onToolCancelled(handle, tool_call_id, reason) {
148
- const ptr0 = passStringToWasm0(tool_call_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
136
+ export function hostPrepareToolCalls(handle, preparations_json) {
137
+ const ptr0 = passStringToWasm0(preparations_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
149
138
  const len0 = WASM_VECTOR_LEN;
150
- const ret = wasm.onToolCancelled(handle, ptr0, len0, reason);
139
+ const ret = wasm.hostPrepareToolCalls(handle, ptr0, len0);
151
140
  return ret;
152
141
  }
153
142
 
154
143
  /**
155
144
  * @param {number} handle
156
- * @param {string} tool_call_id
157
- * @param {ToolDonePayload} payload
158
- * @returns {StepResult}
145
+ * @param {string} artifact_id
146
+ * @returns {string}
159
147
  */
160
- export function onToolDone(handle, tool_call_id, payload) {
161
- const ptr0 = passStringToWasm0(tool_call_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
162
- const len0 = WASM_VECTOR_LEN;
163
- const ret = wasm.onToolDone(handle, ptr0, len0, payload);
148
+ export function hostReadArtifact(handle, artifact_id) {
149
+ let deferred3_0;
150
+ let deferred3_1;
151
+ try {
152
+ const ptr0 = passStringToWasm0(artifact_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
153
+ const len0 = WASM_VECTOR_LEN;
154
+ const ret = wasm.hostReadArtifact(handle, ptr0, len0);
155
+ var ptr2 = ret[0];
156
+ var len2 = ret[1];
157
+ if (ret[3]) {
158
+ ptr2 = 0; len2 = 0;
159
+ throw takeFromExternrefTable0(ret[2]);
160
+ }
161
+ deferred3_0 = ptr2;
162
+ deferred3_1 = len2;
163
+ return getStringFromWasm0(ptr2, len2);
164
+ } finally {
165
+ wasm.__wbindgen_free(deferred3_0, deferred3_1, 1);
166
+ }
167
+ }
168
+
169
+ /**
170
+ * @param {number} handle
171
+ * @returns {EmptyResult}
172
+ */
173
+ export function hostReset(handle) {
174
+ const ret = wasm.hostReset(handle);
164
175
  return ret;
165
176
  }
166
177
 
167
178
  /**
168
179
  * @param {number} handle
169
- * @param {string} tool_call_id
170
- * @returns {EventsResult}
180
+ * @param {string} query
181
+ * @returns {ArtifactSearchResults}
171
182
  */
172
- export function onToolStarted(handle, tool_call_id) {
173
- const ptr0 = passStringToWasm0(tool_call_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
183
+ export function hostSearchArtifacts(handle, query) {
184
+ const ptr0 = passStringToWasm0(query, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
174
185
  const len0 = WASM_VECTOR_LEN;
175
- const ret = wasm.onToolStarted(handle, ptr0, len0);
176
- return ret;
186
+ const ret = wasm.hostSearchArtifacts(handle, ptr0, len0);
187
+ if (ret[2]) {
188
+ throw takeFromExternrefTable0(ret[1]);
189
+ }
190
+ return takeFromExternrefTable0(ret[0]);
177
191
  }
178
192
 
179
193
  /**
180
194
  * @param {number} handle
181
- * @param {ToolExecutionUpdate} update
182
- * @returns {EventsResult}
195
+ * @param {AgentMessage} message
196
+ * @returns {TurnResultResult}
183
197
  */
184
- export function onToolUpdate(handle, update) {
185
- const ret = wasm.onToolUpdate(handle, update);
198
+ export function hostSteer(handle, message) {
199
+ const ret = wasm.hostSteer(handle, message);
186
200
  return ret;
187
201
  }
188
202
 
189
203
  /**
190
- * @param {ProjectionInput} input
191
- * @returns {ProjectionResult}
204
+ * @param {number} handle
205
+ * @param {string} tool_call_id
206
+ * @param {CancelReason} reason
207
+ * @returns {TurnResultResult}
192
208
  */
193
- export function projectContext(input) {
194
- const ret = wasm.projectContext(input);
209
+ export function hostToolCancelled(handle, tool_call_id, reason) {
210
+ const ptr0 = passStringToWasm0(tool_call_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
211
+ const len0 = WASM_VECTOR_LEN;
212
+ const ret = wasm.hostToolCancelled(handle, ptr0, len0, reason);
195
213
  return ret;
196
214
  }
197
215
 
198
216
  /**
199
217
  * @param {number} handle
200
- * @param {PromptRequest} prompt
201
- * @returns {StepResult}
218
+ * @param {ToolCallId} id
219
+ * @param {ToolResult} result
220
+ * @returns {TurnResultResult}
202
221
  */
203
- export function prompt(handle, prompt) {
204
- const ret = wasm.prompt(handle, prompt);
222
+ export function hostToolDone(handle, id, result) {
223
+ const ret = wasm.hostToolDone(handle, id, result);
205
224
  return ret;
206
225
  }
207
226
 
208
227
  /**
209
228
  * @param {number} handle
210
- * @returns {EmptyResult}
229
+ * @param {ToolCallId} id
230
+ * @param {ToolError} error
231
+ * @returns {TurnResultResult}
211
232
  */
212
- export function reset(handle) {
213
- const ret = wasm.reset(handle);
233
+ export function hostToolFailed(handle, id, error) {
234
+ const ret = wasm.hostToolFailed(handle, id, error);
214
235
  return ret;
215
236
  }
216
237
 
217
238
  /**
218
- * @param {string} level
239
+ * @param {AgentOptions} options
240
+ * @param {PersistData} data
241
+ * @returns {CreateHostAgentResult}
219
242
  */
220
- export function setLogLevel(level) {
221
- const ptr0 = passStringToWasm0(level, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
222
- const len0 = WASM_VECTOR_LEN;
223
- wasm.setLogLevel(ptr0, len0);
243
+ export function restoreHostAgent(options, data) {
244
+ const ret = wasm.restoreHostAgent(options, data);
245
+ return ret;
224
246
  }
225
247
 
226
248
  /**
227
- * @param {number} handle
228
- * @param {SessionState} state
229
- * @returns {EmptyResult}
249
+ * @param {PersistData} data
250
+ * @returns {CreateHostStateResult}
230
251
  */
231
- export function setSessionState(handle, state) {
232
- const ret = wasm.setSessionState(handle, state);
252
+ export function restoreHostState(data) {
253
+ const ret = wasm.restoreHostState(data);
233
254
  return ret;
234
255
  }
235
256
 
236
257
  /**
237
- * @param {number} handle
238
- * @returns {StateResult}
258
+ * @param {string} json
259
+ * @returns {CreateHostStateResult}
239
260
  */
240
- export function state(handle) {
241
- const ret = wasm.state(handle);
261
+ export function restoreHostStateFromJson(json) {
262
+ const ptr0 = passStringToWasm0(json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
263
+ const len0 = WASM_VECTOR_LEN;
264
+ const ret = wasm.restoreHostStateFromJson(ptr0, len0);
242
265
  return ret;
243
266
  }
244
267
 
268
+ /**
269
+ * @param {string} level
270
+ */
271
+ export function setLogLevel(level) {
272
+ const ptr0 = passStringToWasm0(level, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
273
+ const len0 = WASM_VECTOR_LEN;
274
+ wasm.setLogLevel(ptr0, len0);
275
+ }
276
+
245
277
  /**
246
278
  * @param {number} handle
247
- * @param {AgentMessage} message
248
- * @returns {EventsResult}
279
+ * @param {StartTurnInput} input
280
+ * @returns {TurnResultResult}
249
281
  */
250
- export function steer(handle, message) {
251
- const ret = wasm.steer(handle, message);
282
+ export function startTurn(handle, input) {
283
+ const ret = wasm.startTurn(handle, input);
252
284
  return ret;
253
285
  }
254
286
  function __wbg_get_imports() {
255
287
  const import0 = {
256
288
  __proto__: null,
289
+ __wbg___wbindgen_debug_string_0accd80f45e5faa2: function(arg0, arg1) {
290
+ const ret = debugString(arg1);
291
+ const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
292
+ const len1 = WASM_VECTOR_LEN;
293
+ getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);
294
+ getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);
295
+ },
257
296
  __wbg___wbindgen_is_undefined_67b456be8673d3d7: function(arg0) {
258
297
  const ret = arg0 === undefined;
259
298
  return ret;
@@ -325,10 +364,17 @@ function __wbg_get_imports() {
325
364
  const ret = new Error();
326
365
  return ret;
327
366
  },
367
+ __wbg_new_ce1ab61c1c2b300d: function() {
368
+ const ret = new Object();
369
+ return ret;
370
+ },
328
371
  __wbg_parse_03863847d06c4e89: function() { return handleError(function (arg0, arg1) {
329
372
  const ret = JSON.parse(getStringFromWasm0(arg0, arg1));
330
373
  return ret;
331
374
  }, arguments); },
375
+ __wbg_set_6be42768c690e380: function(arg0, arg1, arg2) {
376
+ arg0[arg1] = arg2;
377
+ },
332
378
  __wbg_stack_3b0d974bbf31e44f: function(arg0, arg1) {
333
379
  const ret = arg1.stack;
334
380
  const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@@ -340,6 +386,11 @@ function __wbg_get_imports() {
340
386
  const ret = JSON.stringify(arg0);
341
387
  return ret;
342
388
  }, arguments); },
389
+ __wbindgen_cast_0000000000000001: function(arg0, arg1) {
390
+ // Cast intrinsic for `Ref(String) -> Externref`.
391
+ const ret = getStringFromWasm0(arg0, arg1);
392
+ return ret;
393
+ },
343
394
  __wbindgen_init_externref_table: function() {
344
395
  const table = wasm.__wbindgen_externrefs;
345
396
  const offset = table.grow(4);
@@ -362,6 +413,71 @@ function addToExternrefTable0(obj) {
362
413
  return idx;
363
414
  }
364
415
 
416
+ function debugString(val) {
417
+ // primitive types
418
+ const type = typeof val;
419
+ if (type == 'number' || type == 'boolean' || val == null) {
420
+ return `${val}`;
421
+ }
422
+ if (type == 'string') {
423
+ return `"${val}"`;
424
+ }
425
+ if (type == 'symbol') {
426
+ const description = val.description;
427
+ if (description == null) {
428
+ return 'Symbol';
429
+ } else {
430
+ return `Symbol(${description})`;
431
+ }
432
+ }
433
+ if (type == 'function') {
434
+ const name = val.name;
435
+ if (typeof name == 'string' && name.length > 0) {
436
+ return `Function(${name})`;
437
+ } else {
438
+ return 'Function';
439
+ }
440
+ }
441
+ // objects
442
+ if (Array.isArray(val)) {
443
+ const length = val.length;
444
+ let debug = '[';
445
+ if (length > 0) {
446
+ debug += debugString(val[0]);
447
+ }
448
+ for(let i = 1; i < length; i++) {
449
+ debug += ', ' + debugString(val[i]);
450
+ }
451
+ debug += ']';
452
+ return debug;
453
+ }
454
+ // Test for built-in
455
+ const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
456
+ let className;
457
+ if (builtInMatches && builtInMatches.length > 1) {
458
+ className = builtInMatches[1];
459
+ } else {
460
+ // Failed to match the standard '[object ClassName]'
461
+ return toString.call(val);
462
+ }
463
+ if (className == 'Object') {
464
+ // we're a user defined class or Object
465
+ // JSON.stringify avoids problems with cycles, and is generally much
466
+ // easier than looping through ownProperties of `val`.
467
+ try {
468
+ return 'Object(' + JSON.stringify(val) + ')';
469
+ } catch (_) {
470
+ return 'Object';
471
+ }
472
+ }
473
+ // errors
474
+ if (val instanceof Error) {
475
+ return `${val.name}: ${val.message}\n${val.stack}`;
476
+ }
477
+ // TODO we could test for more things here, like `Set`s and `Map`s.
478
+ return className;
479
+ }
480
+
365
481
  let cachedDataViewMemory0 = null;
366
482
  function getDataViewMemory0() {
367
483
  if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
@@ -395,6 +511,16 @@ function isLikeNone(x) {
395
511
  return x === undefined || x === null;
396
512
  }
397
513
 
514
+ function passArrayJsValueToWasm0(array, malloc) {
515
+ const ptr = malloc(array.length * 4, 4) >>> 0;
516
+ for (let i = 0; i < array.length; i++) {
517
+ const add = addToExternrefTable0(array[i]);
518
+ getDataViewMemory0().setUint32(ptr + 4 * i, add, true);
519
+ }
520
+ WASM_VECTOR_LEN = array.length;
521
+ return ptr;
522
+ }
523
+
398
524
  function passStringToWasm0(arg, malloc, realloc) {
399
525
  if (realloc === undefined) {
400
526
  const buf = cachedTextEncoder.encode(arg);
@@ -432,6 +558,12 @@ function passStringToWasm0(arg, malloc, realloc) {
432
558
  return ptr;
433
559
  }
434
560
 
561
+ function takeFromExternrefTable0(idx) {
562
+ const value = wasm.__wbindgen_externrefs.get(idx);
563
+ wasm.__externref_table_dealloc(idx);
564
+ return value;
565
+ }
566
+
435
567
  let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
436
568
  cachedTextDecoder.decode();
437
569
  const MAX_SAFARI_DECODE_BYTES = 2146435072;
@@ -553,4 +685,4 @@ async function __wbg_init(module_or_path) {
553
685
  return __wbg_finalize_init(instance, module);
554
686
  }
555
687
 
556
- export { initSync, __wbg_init as default };
688
+ export { __wbg_init as default, initSync };
Binary file
package/sdk/index.d.ts DELETED
@@ -1,55 +0,0 @@
1
- /**
2
- * High-level JS SDK for @pi-oxide/pi-host-web.
3
- *
4
- * Re-exports all raw types so consumers never need to import from ./raw.
5
- */
6
-
7
- export * from "../pi_host_web.js";
8
-
9
- export declare function ensureInit(): Promise<void>;
10
-
11
- export declare function continueTurn(handle: number): StepResult;
12
-
13
- export declare function toolResult(
14
- text: string,
15
- opts?: { terminate?: boolean }
16
- ): { content: Array<{ type: "text"; text: string }>; terminate?: boolean };
17
-
18
- export declare function toolError(
19
- code: string,
20
- message: string
21
- ): { error: { code: string; message: string } };
22
-
23
- export interface LlmStream {
24
- chunks: AsyncIterable<LlmChunk>;
25
- result: Promise<LlmResult>;
26
- }
27
-
28
- export interface LlmProvider {
29
- call(context: LlmContext, signal?: AbortSignal): Promise<LlmStream> | LlmStream;
30
- }
31
-
32
- export type ToolMap = Record<
33
- string,
34
- (call: ToolCall) => Promise<ToolResult> | ToolResult
35
- >;
36
-
37
- export interface AgentRunConfig {
38
- llm: LlmProvider;
39
- tools: ToolMap;
40
- onEvent?: (event: AgentEvent) => void;
41
- signal?: AbortSignal;
42
- }
43
-
44
- export declare class Agent {
45
- static create(options: AgentOptions): Promise<Agent>;
46
- run(promptText: string, config: AgentRunConfig): Promise<AgentAction>;
47
- stop(): void;
48
- reset(): void;
49
- state(): AgentState;
50
- getSessionState(): SessionState;
51
- setSessionState(sessionState: SessionState): void;
52
- steer(message: AgentMessage): AgentEvent[];
53
- followUp(message: AgentMessage): void;
54
- destroy(): void;
55
- }
package/sdk/index.js DELETED
@@ -1,245 +0,0 @@
1
- /**
2
- * High-level JS SDK for @pi-oxide/pi-host-web.
3
- *
4
- * Hides WASM loading, numeric handles, and the agent drive-loop.
5
- * Supports streaming LLM responses and full agent lifecycle.
6
- *
7
- * Import from the package root:
8
- * import { Agent, toolResult } from "@pi-oxide/pi-host-web";
9
- */
10
-
11
- import {
12
- abort,
13
- createAgent,
14
- continueTurn,
15
- destroyAgent,
16
- feedLlmChunk,
17
- followUp,
18
- getSessionState,
19
- initSync,
20
- onLlmDone,
21
- onToolCancelled,
22
- onToolDone,
23
- onToolStarted,
24
- projectContext,
25
- prompt,
26
- reset,
27
- setSessionState,
28
- state,
29
- steer,
30
- default as init,
31
- } from "../pi_host_web.js";
32
-
33
- export { projectContext };
34
-
35
- let initialized = false;
36
-
37
- /** Ensure the WASM module is loaded. Safe to call multiple times. */
38
- export async function ensureInit() {
39
- if (initialized) return;
40
- if (typeof process !== "undefined" && process.versions?.node) {
41
- const { readFileSync } = await import("node:fs");
42
- const bytes = readFileSync(
43
- new URL("../pi_host_web_bg.wasm", import.meta.url)
44
- );
45
- initSync({ module: bytes });
46
- } else {
47
- await init();
48
- }
49
- initialized = true;
50
- }
51
-
52
- class HostError extends Error {
53
- constructor(code, message) {
54
- super(message);
55
- this.code = code;
56
- this.name = "HostError";
57
- }
58
- }
59
-
60
- function unwrap(result) {
61
- if (!result.ok) {
62
- throw new HostError(result.error.code, result.error.message);
63
- }
64
- return result.data;
65
- }
66
-
67
- /** Build a successful tool result payload. */
68
- export function toolResult(text, opts = {}) {
69
- const payload = {
70
- content: [{ type: "text", text }],
71
- };
72
- if (opts.terminate) {
73
- payload.terminate = true;
74
- }
75
- return payload;
76
- }
77
-
78
- /** Build an error tool result payload. */
79
- export function toolError(code, message) {
80
- return { error: { code, message } };
81
- }
82
-
83
- /**
84
- * High-level agent that manages the WASM handle and drive-loop.
85
- *
86
- * Usage:
87
- * const agent = await Agent.create(options);
88
- * const finalAction = await agent.run("hello", { llm, tools, onEvent });
89
- * agent.destroy();
90
- */
91
- export class Agent {
92
- /** @type {number} */
93
- #handle;
94
-
95
- constructor(handle) {
96
- this.#handle = handle;
97
- }
98
-
99
- /** Create a new agent. Loads WASM on first call automatically. */
100
- static async create(options) {
101
- await ensureInit();
102
- const result = unwrap(createAgent(options));
103
- return new Agent(result.handle);
104
- }
105
-
106
- /**
107
- * Run one user prompt through the full turn loop.
108
- *
109
- * @param {string} promptText
110
- * @param {object} config
111
- * @param {LlmProvider} config.llm
112
- * @param {Record<string, (call: ToolCall) => Promise<ToolResult> | ToolResult>} config.tools
113
- * @param {(event: AgentEvent) => void} [config.onEvent]
114
- * @param {AbortSignal} [config.signal] — abort to stop mid-stream or mid-tool
115
- * @returns {Promise<AgentAction>} terminal action (finished or wait_for_input)
116
- */
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
-
126
- let step = unwrap(prompt(this.#handle, { text: promptText }));
127
- for (const event of step.events) {
128
- config.onEvent?.(event);
129
- }
130
-
131
- while (true) {
132
- checkAbort();
133
- let actions = step.actions ?? [];
134
- if (actions.length === 0) {
135
- return { type: "finished", messages: [] };
136
- }
137
-
138
- for (const action of actions) {
139
- checkAbort();
140
- switch (action.type) {
141
- case "stream_llm": {
142
- const stream = await config.llm.call(action.context, signal);
143
- for await (const chunk of stream.chunks) {
144
- checkAbort();
145
- const ev = unwrap(feedLlmChunk(this.#handle, chunk));
146
- for (const e of ev.events) config.onEvent?.(e);
147
- }
148
- checkAbort();
149
- const result = await stream.result;
150
- step = unwrap(onLlmDone(this.#handle, result));
151
- for (const e of step.events) config.onEvent?.(e);
152
- break;
153
- }
154
-
155
- case "execute_tools": {
156
- for (const call of action.calls) {
157
- checkAbort();
158
- const started = unwrap(onToolStarted(this.#handle, call.id));
159
- for (const e of started.events) config.onEvent?.(e);
160
-
161
- const handler = config.tools[call.name];
162
- let result;
163
- if (handler) {
164
- result = await handler(call);
165
- } else {
166
- result = toolError("unknown_tool", `No handler for ${call.name}`);
167
- }
168
- step = unwrap(onToolDone(this.#handle, call.id, result));
169
- for (const e of step.events) config.onEvent?.(e);
170
- }
171
- if ((step.actions ?? []).length === 0) {
172
- step = unwrap(continueTurn(this.#handle));
173
- for (const e of step.events) config.onEvent?.(e);
174
- }
175
- break;
176
- }
177
-
178
- case "cancel_tools": {
179
- for (const id of action.tool_call_ids) {
180
- step = unwrap(
181
- onToolCancelled(this.#handle, id, action.reason)
182
- );
183
- for (const e of step.events) config.onEvent?.(e);
184
- }
185
- break;
186
- }
187
-
188
- case "finished":
189
- return action;
190
-
191
- case "wait_for_input":
192
- return action;
193
-
194
- default:
195
- return action;
196
- }
197
- }
198
- }
199
- }
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
-
210
- /** Reset agent state (clear messages, return to idle). */
211
- reset() {
212
- unwrap(reset(this.#handle));
213
- }
214
-
215
- /** Get public agent state. */
216
- state() {
217
- return unwrap(state(this.#handle));
218
- }
219
-
220
- /** Get session state for persistence. */
221
- getSessionState() {
222
- return unwrap(getSessionState(this.#handle));
223
- }
224
-
225
- /** Set session state (e.g. after restoring from storage). */
226
- setSessionState(sessionState) {
227
- unwrap(setSessionState(this.#handle, sessionState));
228
- }
229
-
230
- /** Send a steering message mid-turn. */
231
- steer(message) {
232
- const out = unwrap(steer(this.#handle, message));
233
- return out.events;
234
- }
235
-
236
- /** Queue a follow-up message. */
237
- followUp(message) {
238
- unwrap(followUp(this.#handle, message));
239
- }
240
-
241
- /** Destroy the underlying WASM handle. */
242
- destroy() {
243
- destroyAgent(this.#handle);
244
- }
245
- }