@pi-oxide/pi-host-web 0.4.0 → 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,64 +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.4.0",
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",
20
- "sdk/agent.ts",
21
- "sdk/artifacts.ts",
22
- "sdk/context.ts",
23
- "sdk/errors.ts",
24
- "sdk/events.ts",
25
- "sdk/index.ts",
26
- "sdk/init.ts",
27
- "sdk/internal/engine.ts",
28
- "sdk/internal/events.ts",
29
- "sdk/internal/providers/anthropic.ts",
30
- "sdk/internal/providers/openai.ts",
31
- "sdk/internal/providers/types.ts",
32
- "sdk/internal/stores/indexedDb.ts",
33
- "sdk/internal/stores/persistence.ts",
34
- "sdk/internal/tools/artifact.ts",
35
- "sdk/internal/tools/browser.ts",
36
- "sdk/internal/tools/browserRuntime.ts",
37
- "sdk/internal/tools/liveRuntime.ts",
38
- "sdk/internal/tools/registry.ts",
39
- "sdk/internal/tools/service.ts",
40
- "sdk/model.ts",
41
- "sdk/react/index.ts",
42
- "sdk/react/useAgent.ts",
43
- "sdk/snapshot.ts",
44
- "sdk/stores.ts",
45
- "sdk/tools.ts",
46
- "sdk/types.ts"
17
+ "pi_host_web.d.ts"
47
18
  ],
48
19
  "main": "pi_host_web.js",
49
20
  "types": "pi_host_web.d.ts",
50
21
  "sideEffects": [
51
22
  "./snippets/*"
52
- ],
53
- "exports": {
54
- ".": {
55
- "import": "./sdk/index.ts",
56
- "types": "./sdk/index.ts"
57
- },
58
- "./raw": {
59
- "import": "./pi_host_web.js",
60
- "types": "./pi_host_web.d.ts"
61
- },
62
- "./react": {
63
- "import": "./sdk/react/index.ts",
64
- "types": "./sdk/react/index.ts"
65
- },
66
- "./package.json": "./package.json"
67
- }
23
+ ]
68
24
  }
package/pi_host_web.d.ts CHANGED
@@ -176,6 +176,12 @@ export interface ToolCall {
176
176
  arguments: ToolArguments;
177
177
  }
178
178
 
179
+ export interface ToolCallPreparation {
180
+ tool_call_id: ToolCallId;
181
+ transform: ToolCallTransform;
182
+ permission: ToolCallPermission;
183
+ }
184
+
179
185
  export interface ToolDefinition {
180
186
  name: ToolName;
181
187
  label: string;
@@ -231,7 +237,7 @@ export interface UserMessage {
231
237
  timestamp: number;
232
238
  }
233
239
 
234
- 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; 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" };
235
241
 
236
242
  export type AgentMessage = ({ role: "user" } & UserMessage) | ({ role: "assistant" } & AssistantMessage) | ({ role: "tool_result" } & ToolResultMessage);
237
243
 
@@ -247,7 +253,7 @@ export type ContentDelta = { kind: "text_start" } | { kind: "text_delta"; text:
247
253
 
248
254
  export type ExecutionMode = "parallel" | "sequential";
249
255
 
250
- export type HostDirective = { type: "stream_llm"; context: LlmContext } | { 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 };
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 };
251
257
 
252
258
  export type JsonSchema = Value;
253
259
 
@@ -275,6 +281,10 @@ export type ToolArguments = Value;
275
281
 
276
282
  export type ToolCallId = string;
277
283
 
284
+ export type ToolCallPermission = { type: "allow" } | { type: "block"; reason: string };
285
+
286
+ export type ToolCallTransform = { type: "none" } | { type: "rewrite_args"; arguments: ToolArguments };
287
+
278
288
  export type ToolDetails = Value;
279
289
 
280
290
  export type ToolName = string;
@@ -312,6 +322,8 @@ export function hostFeedLlmChunk(handle: number, chunk: LlmChunk): TurnResultRes
312
322
 
313
323
  export function hostLlmDone(handle: number, result: LlmResult): TurnResultResult;
314
324
 
325
+ export function hostPrepareToolCalls(handle: number, preparations_json: string): TurnResultResult;
326
+
315
327
  export function hostReadArtifact(handle: number, artifact_id: string): string;
316
328
 
317
329
  export function hostReset(handle: number): EmptyResult;
@@ -324,6 +336,8 @@ export function hostToolCancelled(handle: number, tool_call_id: string, reason:
324
336
 
325
337
  export function hostToolDone(handle: number, id: ToolCallId, result: ToolResult): TurnResultResult;
326
338
 
339
+ export function hostToolFailed(handle: number, id: ToolCallId, error: ToolError): TurnResultResult;
340
+
327
341
  export function restoreHostAgent(options: AgentOptions, data: PersistData): CreateHostAgentResult;
328
342
 
329
343
  export function restoreHostState(data: PersistData): CreateHostStateResult;
@@ -343,10 +357,11 @@ export interface InitOutput {
343
357
  readonly estimateTokens: (a: any) => any;
344
358
  readonly estimateTokensForText: (a: number, b: number) => any;
345
359
  readonly getHostStatePersistData: (a: number) => any;
346
- readonly hostReadArtifact: (a: number, b: number, c: number) => [number, number, number, number];
347
- readonly hostSearchArtifacts: (a: number, b: number, c: number) => [number, number, number];
348
360
  readonly restoreHostState: (a: any) => any;
349
361
  readonly restoreHostStateFromJson: (a: number, b: number) => any;
362
+ readonly setLogLevel: (a: number, b: number) => void;
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];
350
365
  readonly createHostAgent: (a: any, b: any) => any;
351
366
  readonly destroyHostAgent: (a: number) => any;
352
367
  readonly getHostAgentPersistData: (a: number) => any;
@@ -355,13 +370,14 @@ export interface InitOutput {
355
370
  readonly hostContinueTurn: (a: number) => any;
356
371
  readonly hostFeedLlmChunk: (a: number, b: any) => any;
357
372
  readonly hostLlmDone: (a: number, b: any) => any;
373
+ readonly hostPrepareToolCalls: (a: number, b: number, c: number) => any;
358
374
  readonly hostReset: (a: number) => any;
359
375
  readonly hostSteer: (a: number, b: any) => any;
360
376
  readonly hostToolCancelled: (a: number, b: number, c: number, d: any) => any;
361
377
  readonly hostToolDone: (a: number, b: any, c: any) => any;
378
+ readonly hostToolFailed: (a: number, b: any, c: any) => any;
362
379
  readonly restoreHostAgent: (a: any, b: any) => any;
363
380
  readonly startTurn: (a: number, b: any) => any;
364
- readonly setLogLevel: (a: number, b: number) => void;
365
381
  readonly __wbindgen_malloc: (a: number, b: number) => number;
366
382
  readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
367
383
  readonly __wbindgen_free: (a: number, b: number, c: number) => void;
package/pi_host_web.js CHANGED
@@ -128,6 +128,18 @@ export function hostLlmDone(handle, result) {
128
128
  return ret;
129
129
  }
130
130
 
131
+ /**
132
+ * @param {number} handle
133
+ * @param {string} preparations_json
134
+ * @returns {TurnResultResult}
135
+ */
136
+ export function hostPrepareToolCalls(handle, preparations_json) {
137
+ const ptr0 = passStringToWasm0(preparations_json, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
138
+ const len0 = WASM_VECTOR_LEN;
139
+ const ret = wasm.hostPrepareToolCalls(handle, ptr0, len0);
140
+ return ret;
141
+ }
142
+
131
143
  /**
132
144
  * @param {number} handle
133
145
  * @param {string} artifact_id
@@ -212,6 +224,17 @@ export function hostToolDone(handle, id, result) {
212
224
  return ret;
213
225
  }
214
226
 
227
+ /**
228
+ * @param {number} handle
229
+ * @param {ToolCallId} id
230
+ * @param {ToolError} error
231
+ * @returns {TurnResultResult}
232
+ */
233
+ export function hostToolFailed(handle, id, error) {
234
+ const ret = wasm.hostToolFailed(handle, id, error);
235
+ return ret;
236
+ }
237
+
215
238
  /**
216
239
  * @param {AgentOptions} options
217
240
  * @param {PersistData} data
@@ -662,4 +685,4 @@ async function __wbg_init(module_or_path) {
662
685
  return __wbg_finalize_init(instance, module);
663
686
  }
664
687
 
665
- export { initSync, __wbg_init as default };
688
+ export { __wbg_init as default, initSync };
Binary file
package/sdk/agent.ts DELETED
@@ -1,274 +0,0 @@
1
- // Public Agent class — the primary SDK surface.
2
- // Thin facade over the internal engine. No WASM imports here.
3
-
4
- import { EventEmitter } from "./events.ts";
5
- import type {
6
- AgentConfig,
7
- AgentInput,
8
- AgentRunOptions,
9
- AgentRunResult,
10
- AgentEventName,
11
- AgentEventHandler,
12
- AgentStatus,
13
- Unsubscribe,
14
- AgentError,
15
- } from "./types.ts";
16
- import { createAgentError } from "./errors.ts";
17
- import type { HostAgent } from "./internal/engine.ts";
18
- import {
19
- runAgentTurn,
20
- resetAgentState,
21
- steerAgent,
22
- createEngineAgent,
23
- destroyEngineAgent,
24
- } from "./internal/engine.ts";
25
-
26
- export class Agent {
27
- private config: AgentConfig;
28
- private emitter: EventEmitter;
29
- private status: AgentStatus = { state: "idle" };
30
- private currentRun: Promise<AgentRunResult> | null = null;
31
- private currentAbortController: AbortController | null = null;
32
- private disposed = false;
33
- private engineAgent: HostAgent | null = null;
34
-
35
- constructor(config: AgentConfig) {
36
- this.config = config;
37
- this.emitter = new EventEmitter();
38
- }
39
-
40
- on<E extends AgentEventName>(
41
- event: E,
42
- handler: AgentEventHandler<E>,
43
- ): Unsubscribe {
44
- if (this.disposed) {
45
- return () => {};
46
- }
47
- return this.emitter.on(event, handler);
48
- }
49
-
50
- async run(
51
- input: string | AgentInput,
52
- options?: AgentRunOptions,
53
- ): Promise<AgentRunResult> {
54
- if (this.disposed) {
55
- const error = createAgentError(
56
- "agent_disposed",
57
- "Agent has been disposed",
58
- { recoverable: false },
59
- );
60
- const result: AgentRunResult = {
61
- status: "failed",
62
- text: "",
63
- toolCalls: [],
64
- artifacts: [],
65
- error,
66
- };
67
- this.emitter.emit("error", error);
68
- this.emitter.emit("status", { state: "failed", message: error.message });
69
- this.emitter.emit("done", result);
70
- return result;
71
- }
72
-
73
- if (this.currentRun) {
74
- const error = createAgentError(
75
- "agent_busy",
76
- "Agent is already running a turn",
77
- { recoverable: true },
78
- );
79
- const result: AgentRunResult = {
80
- status: "failed",
81
- text: "",
82
- toolCalls: [],
83
- artifacts: [],
84
- error,
85
- };
86
- this.emitter.emit("error", error);
87
- this.emitter.emit("status", { state: "failed", message: error.message });
88
- this.emitter.emit("done", result);
89
- return result;
90
- }
91
-
92
- const abortController = new AbortController();
93
- this.currentAbortController = abortController;
94
-
95
- // Merge external signal if provided
96
- if (options?.signal) {
97
- if (options.signal.aborted) {
98
- abortController.abort(options.signal.reason);
99
- } else {
100
- options.signal.addEventListener(
101
- "abort",
102
- () => {
103
- abortController.abort(options.signal!.reason);
104
- },
105
- { once: true },
106
- );
107
- }
108
- }
109
-
110
- const runPromise = this._doRun(input, options, abortController.signal);
111
- this.currentRun = runPromise;
112
-
113
- try {
114
- const result = await runPromise;
115
- this.emitter.emit("done", result);
116
- return result;
117
- } catch (e) {
118
- // Safety net: convert any unexpected throw to a failed result
119
- const error = createAgentError(
120
- "internal_error",
121
- e instanceof Error ? e.message : String(e),
122
- { cause: e, recoverable: false },
123
- );
124
- const failedResult: AgentRunResult = {
125
- status: "failed",
126
- text: "",
127
- toolCalls: [],
128
- artifacts: [],
129
- error,
130
- };
131
- this.emitter.emit("error", error);
132
- this.emitter.emit("status", { state: "failed", message: error.message });
133
- this.emitter.emit("done", failedResult);
134
- return failedResult;
135
- } finally {
136
- this.currentRun = null;
137
- this.currentAbortController = null;
138
- }
139
- }
140
-
141
- private async _doRun(
142
- input: string | AgentInput,
143
- options: AgentRunOptions | undefined,
144
- signal: AbortSignal,
145
- ): Promise<AgentRunResult> {
146
- // Lazy initialization on first run
147
- if (!this.engineAgent) {
148
- this.engineAgent = await createEngineAgent(this.config, {
149
- onEvent: (event) => this.emitter.emit(event.type as AgentEventName, event.payload),
150
- onStatus: (status) => {
151
- this.status = status;
152
- this.emitter.emit("status", status);
153
- },
154
- });
155
- }
156
-
157
- try {
158
- return await runAgentTurn(
159
- this.engineAgent,
160
- this.config,
161
- input,
162
- options,
163
- signal,
164
- {
165
- onEvent: (event) =>
166
- this.emitter.emit(event.type as AgentEventName, event.payload),
167
- onStatus: (status) => {
168
- this.status = status;
169
- this.emitter.emit("status", status);
170
- },
171
- },
172
- );
173
- } catch (e) {
174
- const isAbort =
175
- signal.aborted ||
176
- (e instanceof Error && e.name === "AbortError") ||
177
- (e instanceof Error && e.message.includes("user_aborted"));
178
-
179
- if (isAbort) {
180
- const abortedResult: AgentRunResult = {
181
- status: "aborted",
182
- text: "",
183
- toolCalls: [],
184
- artifacts: [],
185
- };
186
- this.emitter.emit("status", {
187
- state: "aborted",
188
- message: "Stopped by user",
189
- });
190
- return abortedResult;
191
- }
192
-
193
- const code =
194
- e instanceof Error && "code" in e && typeof (e as { code: unknown }).code === "string"
195
- ? ((e as { code: string }).code as AgentError["code"])
196
- : "internal_error";
197
- const error = createAgentError(
198
- code,
199
- e instanceof Error ? e.message : String(e),
200
- { cause: e, recoverable: false },
201
- );
202
- const failedResult: AgentRunResult = {
203
- status: "failed",
204
- text: "",
205
- toolCalls: [],
206
- artifacts: [],
207
- error,
208
- };
209
- this.emitter.emit("error", error);
210
- this.emitter.emit("status", { state: "failed", message: error.message });
211
- return failedResult;
212
- }
213
- }
214
-
215
- stop(reason?: string): void {
216
- if (this.disposed || !this.currentAbortController) return;
217
- this.currentAbortController.abort(reason ?? "user-requested");
218
- }
219
-
220
- async steer(input: string | AgentInput): Promise<void> {
221
- if (this.disposed) {
222
- throw createAgentError(
223
- "agent_disposed",
224
- "Agent has been disposed",
225
- { recoverable: false },
226
- );
227
- }
228
- if (!this.engineAgent) {
229
- throw createAgentError(
230
- "agent_not_initialized",
231
- "Agent has not been run yet",
232
- { recoverable: true },
233
- );
234
- }
235
- return steerAgent(this.engineAgent, input);
236
- }
237
-
238
- async reset(): Promise<void> {
239
- if (this.disposed) {
240
- throw createAgentError(
241
- "agent_disposed",
242
- "Agent has been disposed",
243
- { recoverable: false },
244
- );
245
- }
246
- if (this.engineAgent) {
247
- await resetAgentState(this.engineAgent);
248
- this.engineAgent = null;
249
- }
250
- this.currentRun = null;
251
- this.currentAbortController = null;
252
- this.status = { state: "idle" };
253
- this.emitter.emit("status", this.status);
254
- }
255
-
256
- dispose(): void {
257
- if (this.disposed) return;
258
- this.disposed = true;
259
- if (this.currentAbortController) {
260
- this.currentAbortController.abort("disposed");
261
- this.currentAbortController = null;
262
- }
263
- if (this.engineAgent) {
264
- destroyEngineAgent(this.engineAgent);
265
- this.engineAgent = null;
266
- }
267
- this.emitter.clear();
268
- this.currentRun = null;
269
- }
270
-
271
- getStatus(): AgentStatus {
272
- return this.status;
273
- }
274
- }
package/sdk/artifacts.ts DELETED
@@ -1,35 +0,0 @@
1
- // Artifact types for the pi-oxide SDK.
2
- // These are public objects, not leaked host internals.
3
-
4
- export interface AgentArtifact {
5
- id: string;
6
- kind: "text" | "json" | "binary";
7
- content: string | Uint8Array | unknown;
8
- mimeType?: string;
9
- title?: string;
10
- metadata?: Record<string, unknown>;
11
- createdAt: number;
12
- }
13
-
14
- export interface AgentArtifactRef {
15
- id: string;
16
- kind: AgentArtifact["kind"];
17
- title?: string;
18
- mimeType?: string;
19
- }
20
-
21
- export interface ArtifactPolicy {
22
- mode: "inline" | "external";
23
- }
24
-
25
- export interface ArtifactSearchQuery {
26
- text: string;
27
- limit?: number;
28
- }
29
-
30
- export interface ArtifactSearchResult {
31
- artifact: AgentArtifactRef;
32
- snippet?: string;
33
- score?: number;
34
- matchCount?: number;
35
- }
package/sdk/context.ts DELETED
@@ -1,4 +0,0 @@
1
- // Context policy types for the pi-oxide SDK.
2
- // Re-exported from types.ts for a cleaner public API surface.
3
-
4
- export type { AgentContextPolicy, AgentSummarizer } from "./types.ts";
package/sdk/errors.ts DELETED
@@ -1,24 +0,0 @@
1
- // AgentError interface and factory.
2
- // AgentError is an interface, NOT a class — it is a plain object.
3
-
4
- import type { AgentError } from "./types.ts";
5
-
6
- export type { AgentError } from "./types.ts";
7
-
8
- export function createAgentError(
9
- code: AgentError["code"],
10
- message: string,
11
- options?: {
12
- cause?: unknown;
13
- recoverable?: boolean;
14
- metadata?: Record<string, unknown>;
15
- },
16
- ): AgentError {
17
- return {
18
- code,
19
- message,
20
- cause: options?.cause,
21
- recoverable: options?.recoverable ?? false,
22
- metadata: options?.metadata,
23
- };
24
- }
package/sdk/events.ts DELETED
@@ -1,52 +0,0 @@
1
- // Lightweight, type-safe EventEmitter (not Node's).
2
- // Maps event names to typed handlers using the SDK's AgentEventName union.
3
-
4
- import type { AgentEventName, AgentEventHandler } from "./types.ts";
5
-
6
- type AnyHandler = (payload: unknown) => void;
7
-
8
- export class EventEmitter {
9
- private handlers: Partial<Record<AgentEventName, Set<AnyHandler>>> = {};
10
-
11
- on<E extends AgentEventName>(
12
- event: E,
13
- handler: AgentEventHandler<E>,
14
- ): () => void {
15
- const set = (this.handlers[event] ??= new Set()) as Set<AnyHandler>;
16
- set.add(handler as AnyHandler);
17
-
18
- return () => {
19
- set.delete(handler as AnyHandler);
20
- if (set.size === 0) {
21
- delete this.handlers[event];
22
- }
23
- };
24
- }
25
-
26
- off<E extends AgentEventName>(
27
- event: E,
28
- handler: AgentEventHandler<E>,
29
- ): void {
30
- const set = this.handlers[event];
31
- if (!set) return;
32
- set.delete(handler as AnyHandler);
33
- if (set.size === 0) {
34
- delete this.handlers[event];
35
- }
36
- }
37
-
38
- emit<E extends AgentEventName>(
39
- event: E,
40
- payload: Parameters<AgentEventHandler<E>>[0],
41
- ): void {
42
- const set = this.handlers[event];
43
- if (!set) return;
44
- for (const handler of set) {
45
- handler(payload);
46
- }
47
- }
48
-
49
- clear(): void {
50
- this.handlers = {};
51
- }
52
- }
package/sdk/index.d.ts DELETED
@@ -1,29 +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";
8
-
9
- export declare function ensureInit(): Promise<void>;
10
-
11
- export declare function toolResult(
12
- text: string,
13
- opts?: { terminate?: boolean; details?: object },
14
- ): {
15
- content: Array<{ type: "text"; text: string }>;
16
- terminate?: boolean;
17
- details?: object;
18
- };
19
-
20
- export declare class HostError extends Error {
21
- code: string;
22
- constructor(code: string, message: string);
23
- }
24
-
25
- export declare function unwrap<T>(result: {
26
- ok: boolean;
27
- data?: T;
28
- error?: { code: string; message: string };
29
- }): T;