@bunny-agent/sdk 0.9.30 → 0.9.32

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/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import { BunnyAgentOptions, SandboxAdapter, RunnerSpec } from '@bunny-agent/manager';
2
- export { DEFAULT_BUNNY_AGENT_DAEMON_URL, IsBunnyAgentDaemonHealthyOptions, LocalSandbox, LocalSandboxOptions, Message, RunnerEnvParams, RunnerType, SandboxAdapter, SandboxHandle, TranscriptEntry, buildRunnerEnv, isBunnyAgentDaemonHealthy } from '@bunny-agent/manager';
1
+ import { BunnyAgentOptions, SandboxAdapter, ToolRef, RunnerSpec } from '@bunny-agent/manager';
2
+ export { DEFAULT_BUNNY_AGENT_DAEMON_URL, IsBunnyAgentDaemonHealthyOptions, LocalSandbox, LocalSandboxOptions, Message, RunnerEnvParams, RunnerType, SandboxAdapter, SandboxHandle, ToolRuntime, TranscriptEntry, buildRunnerEnv, isBunnyAgentDaemonHealthy } from '@bunny-agent/manager';
3
3
  import { LanguageModelV3StreamPart, LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateResult, LanguageModelV3StreamResult, ProviderV3, EmbeddingModelV3, ImageModelV3, JSONValue, LanguageModelV3Usage } from '@ai-sdk/provider';
4
4
  export { LanguageModelV3StreamPart } from '@ai-sdk/provider';
5
+ import { Tool } from 'ai';
5
6
 
6
7
  /**
7
8
  * Artifact Processor result
@@ -111,6 +112,8 @@ interface BunnyAgentProviderSettings extends Omit<BunnyAgentOptions, "runner" |
111
112
  allowedTools?: string[];
112
113
  /** Skip tool approval checks (bypass permissions). */
113
114
  yolo?: boolean;
115
+ /** Advanced static tool refs to expose directly to the runner. */
116
+ toolRefs?: ToolRef[];
114
117
  }
115
118
  /**
116
119
  * Model identifier: user passes whatever the runner expects (e.g. Claude model id, Pi model id).
@@ -134,6 +137,9 @@ declare class BunnyAgentLanguageModel implements LanguageModelV3 {
134
137
  readonly provider: string;
135
138
  readonly modelId: string;
136
139
  readonly supportedUrls: Record<string, RegExp[]>;
140
+ readonly settings: BunnyAgentProviderSettings & {
141
+ runner: RunnerSpec;
142
+ };
137
143
  private readonly options;
138
144
  private readonly logger;
139
145
  private sessionId;
@@ -215,6 +221,30 @@ interface SubmitAnswerOptions {
215
221
  */
216
222
  declare function submitAnswer(sandbox: SandboxAdapter, params: SubmitAnswerParams, options?: SubmitAnswerOptions): Promise<void>;
217
223
 
224
+ type BunnyDynamicTool<INPUT> = Tool<INPUT, unknown> & {
225
+ type: "dynamic";
226
+ };
227
+ /**
228
+ * AI SDK helper for tools that the sandbox runner should call by HTTP.
229
+ *
230
+ * This is still used with the standard AI SDK `streamText`:
231
+ * `import { streamText } from "ai"`.
232
+ */
233
+ declare function bunnyHttpTool<INPUT, OUTPUT>(input: Omit<Tool<INPUT, OUTPUT>, "execute" | "outputSchema"> & {
234
+ endpoint: {
235
+ url: string;
236
+ headers?: Record<string, string>;
237
+ };
238
+ }): BunnyDynamicTool<INPUT>;
239
+ /**
240
+ * AI SDK helper for tools implemented by a module already present in the
241
+ * sandbox filesystem.
242
+ */
243
+ declare function bunnySandboxTool<INPUT, OUTPUT>(input: Omit<Tool<INPUT, OUTPUT>, "execute" | "outputSchema"> & {
244
+ module: string;
245
+ exportName?: string;
246
+ }): BunnyDynamicTool<INPUT>;
247
+
218
248
  type JsonRecord = Record<string, JSONValue | undefined>;
219
249
  /**
220
250
  * Extract `providerMetadata["bunny-agent"]` from an AI SDK providerMetadata object.
@@ -251,4 +281,4 @@ declare function getBunnyAgentUsage(providerMetadata: unknown): LanguageModelV3U
251
281
 
252
282
  declare const VERSION = "0.1.0";
253
283
 
254
- export { type ArtifactProcessor, type ArtifactResult, BunnyAgentLanguageModel, type BunnyAgentLanguageModelOptions, type BunnyAgentModelId, type BunnyAgentProvider, type BunnyAgentProviderSettings, type Logger, type Question, type StreamWriter, type SubmitAnswerOptions, type SubmitAnswerParams, VERSION, createBunnyAgent, getBunnyAgentMetadata, getBunnyAgentUsage, submitAnswer };
284
+ export { type ArtifactProcessor, type ArtifactResult, BunnyAgentLanguageModel, type BunnyAgentLanguageModelOptions, type BunnyAgentModelId, type BunnyAgentProvider, type BunnyAgentProviderSettings, type Logger, type Question, type StreamWriter, type SubmitAnswerOptions, type SubmitAnswerParams, VERSION, bunnyHttpTool, bunnySandboxTool, createBunnyAgent, getBunnyAgentMetadata, getBunnyAgentUsage, submitAnswer };
package/dist/index.js CHANGED
@@ -38,6 +38,121 @@ function getProviderLogger(settings) {
38
38
  };
39
39
  }
40
40
 
41
+ // src/provider/tool-refs.ts
42
+ var BUNNY_PROVIDER_OPTIONS_KEY = "bunny-agent";
43
+ function bunnyHttpTool(input) {
44
+ return {
45
+ type: "dynamic",
46
+ description: input.description,
47
+ title: input.title,
48
+ providerOptions: withBunnyProviderOptions(input.providerOptions, {
49
+ runtime: {
50
+ type: "http",
51
+ url: input.endpoint.url,
52
+ ...input.endpoint.headers ? { headers: input.endpoint.headers } : {}
53
+ }
54
+ }),
55
+ inputSchema: input.inputSchema,
56
+ inputExamples: input.inputExamples,
57
+ needsApproval: input.needsApproval,
58
+ strict: input.strict,
59
+ onInputStart: input.onInputStart,
60
+ onInputDelta: input.onInputDelta,
61
+ onInputAvailable: input.onInputAvailable,
62
+ async execute() {
63
+ throw new Error(
64
+ "bunnyHttpTool is provider-executed by the sandbox runner."
65
+ );
66
+ }
67
+ };
68
+ }
69
+ function bunnySandboxTool(input) {
70
+ return {
71
+ type: "dynamic",
72
+ description: input.description,
73
+ title: input.title,
74
+ providerOptions: withBunnyProviderOptions(input.providerOptions, {
75
+ runtime: {
76
+ type: "module",
77
+ module: input.module,
78
+ ...input.exportName ? { exportName: input.exportName } : {}
79
+ }
80
+ }),
81
+ inputSchema: input.inputSchema,
82
+ inputExamples: input.inputExamples,
83
+ needsApproval: input.needsApproval,
84
+ strict: input.strict,
85
+ onInputStart: input.onInputStart,
86
+ onInputDelta: input.onInputDelta,
87
+ onInputAvailable: input.onInputAvailable,
88
+ async execute() {
89
+ throw new Error(
90
+ "bunnySandboxTool is provider-executed by the sandbox runner."
91
+ );
92
+ }
93
+ };
94
+ }
95
+ function compileToolRefsFromLanguageModelTools(tools) {
96
+ if (!tools || tools.length === 0) return void 0;
97
+ const toolRefs = [];
98
+ for (const tool of tools) {
99
+ if (tool.type !== "function") {
100
+ continue;
101
+ }
102
+ const runtime = getBunnyRuntime(tool);
103
+ if (!runtime) {
104
+ throw new Error(
105
+ `[bunny-agent] Tool "${tool.name}" was passed through AI SDK streamText, but Bunny cannot access host-side tool({ execute }) callbacks at the provider boundary. Use bunnyHttpTool(...) for an endpoint tool or bunnySandboxTool(...) for a sandbox-local module.`
106
+ );
107
+ }
108
+ toolRefs.push({
109
+ name: tool.name,
110
+ description: tool.description ?? "",
111
+ inputSchema: tool.inputSchema,
112
+ runtime
113
+ });
114
+ }
115
+ return toolRefs.length > 0 ? toolRefs : void 0;
116
+ }
117
+ function getBunnyRuntime(tool) {
118
+ const options = tool.providerOptions?.[BUNNY_PROVIDER_OPTIONS_KEY];
119
+ const runtime = options?.runtime;
120
+ if (!isRecord(runtime) || typeof runtime.type !== "string") {
121
+ return void 0;
122
+ }
123
+ if (runtime.type === "http" && typeof runtime.url === "string") {
124
+ return {
125
+ type: "http",
126
+ url: runtime.url,
127
+ ...isStringRecord(runtime.headers) ? { headers: runtime.headers } : {}
128
+ };
129
+ }
130
+ if (runtime.type === "module" && typeof runtime.module === "string") {
131
+ return {
132
+ type: "module",
133
+ module: runtime.module,
134
+ ...typeof runtime.exportName === "string" ? { exportName: runtime.exportName } : {}
135
+ };
136
+ }
137
+ return void 0;
138
+ }
139
+ function withBunnyProviderOptions(providerOptions, bunnyOptions) {
140
+ return {
141
+ ...providerOptions ?? {},
142
+ [BUNNY_PROVIDER_OPTIONS_KEY]: {
143
+ ...providerOptions?.[BUNNY_PROVIDER_OPTIONS_KEY] ?? {},
144
+ ...bunnyOptions
145
+ }
146
+ };
147
+ }
148
+ function isRecord(value) {
149
+ return value !== null && typeof value === "object" && !Array.isArray(value);
150
+ }
151
+ function isStringRecord(value) {
152
+ if (!isRecord(value)) return false;
153
+ return Object.values(value).every((entry) => typeof entry === "string");
154
+ }
155
+
41
156
  // src/provider/usage.ts
42
157
  function asRecord(value) {
43
158
  if (value == null || typeof value !== "object" || Array.isArray(value)) {
@@ -131,6 +246,10 @@ function asyncIterableToReadableStream(iterable) {
131
246
  }
132
247
  });
133
248
  }
249
+ function mergeToolRefs(staticToolRefs, callToolRefs) {
250
+ const merged = [...staticToolRefs ?? [], ...callToolRefs ?? []];
251
+ return merged.length > 0 ? merged : void 0;
252
+ }
134
253
  function getLastUserTextFromMessages(messages) {
135
254
  const lastUser = [...messages].reverse().find((m) => m.role === "user");
136
255
  if (!lastUser) return "";
@@ -154,6 +273,12 @@ function createEmptyUsage() {
154
273
  raw: void 0
155
274
  };
156
275
  }
276
+ function readToolDynamicFlag(parsed) {
277
+ if (typeof parsed.dynamic === "boolean") {
278
+ return parsed.dynamic;
279
+ }
280
+ return parsed.providerExecuted === true;
281
+ }
157
282
  var BunnyAgentLanguageModel = class {
158
283
  specificationVersion = "v3";
159
284
  provider;
@@ -161,6 +286,7 @@ var BunnyAgentLanguageModel = class {
161
286
  supportedUrls = {
162
287
  "image/*": [/.*/]
163
288
  };
289
+ settings;
164
290
  options;
165
291
  logger;
166
292
  sessionId;
@@ -182,6 +308,7 @@ var BunnyAgentLanguageModel = class {
182
308
  }
183
309
  constructor(modelOptions) {
184
310
  this.modelId = modelOptions.id;
311
+ this.settings = modelOptions.options;
185
312
  this.options = modelOptions.options;
186
313
  this.logger = getProviderLogger(modelOptions.options);
187
314
  this.provider = "bunny-agent";
@@ -292,13 +419,17 @@ var BunnyAgentLanguageModel = class {
292
419
  "BunnyAgent language model requires a sandbox adapter (set `sandbox` on the provider)."
293
420
  );
294
421
  }
422
+ const toolRefs = mergeToolRefs(
423
+ this.options.toolRefs,
424
+ compileToolRefsFromLanguageModelTools(options.tools)
425
+ );
295
426
  const daemonUrl = this.options.daemonUrl;
296
427
  if (daemonUrl) {
297
428
  const handle = await sandbox.attach();
298
429
  const sandboxEnv2 = sandbox.getEnv?.() ?? {};
299
430
  const runnerEnv = { ...sandboxEnv2, ...this.options.env };
300
431
  const body = {
301
- ...this.buildCodingRunBody(messages, handle.getWorkdir()),
432
+ ...this.buildCodingRunBody(messages, handle.getWorkdir(), toolRefs),
302
433
  ...Object.keys(runnerEnv).length > 0 ? { env: runnerEnv } : {}
303
434
  };
304
435
  const execOpts = {
@@ -328,7 +459,8 @@ var BunnyAgentLanguageModel = class {
328
459
  path: sandboxWorkdir
329
460
  },
330
461
  resume: this.options.resume,
331
- signal: abortSignal
462
+ signal: abortSignal,
463
+ ...toolRefs && toolRefs.length > 0 ? { toolRefs } : {}
332
464
  });
333
465
  return this.buildStreamResult(bytesStream, messages);
334
466
  } catch (error) {
@@ -342,7 +474,7 @@ var BunnyAgentLanguageModel = class {
342
474
  this.toolNameMap = /* @__PURE__ */ new Map();
343
475
  this.legacyTextPartCounter = 0;
344
476
  }
345
- buildCodingRunBody(messages, cwdFallback) {
477
+ buildCodingRunBody(messages, cwdFallback, toolRefs) {
346
478
  const runner = this.options.runner;
347
479
  const cwd = this.options.cwd ?? cwdFallback;
348
480
  return {
@@ -355,7 +487,8 @@ var BunnyAgentLanguageModel = class {
355
487
  maxTurns: this.options.maxTurns ?? runner.maxTurns,
356
488
  allowedTools: runner.allowedTools ?? this.options.allowedTools,
357
489
  skillPaths: runner.skillPaths ?? this.options.skillPaths,
358
- yolo: this.options.yolo
490
+ yolo: this.options.yolo,
491
+ ...toolRefs && toolRefs.length > 0 ? { toolRefs } : {}
359
492
  };
360
493
  }
361
494
  buildStreamResult(bytesStream, messages) {
@@ -539,7 +672,7 @@ var BunnyAgentLanguageModel = class {
539
672
  type: "tool-input-start",
540
673
  id: parsed.toolCallId,
541
674
  toolName: parsed.toolName,
542
- dynamic: parsed.dynamic,
675
+ dynamic: readToolDynamicFlag(parsed),
543
676
  providerExecuted: parsed.providerExecuted
544
677
  });
545
678
  break;
@@ -562,7 +695,7 @@ var BunnyAgentLanguageModel = class {
562
695
  toolCallId,
563
696
  toolName,
564
697
  input: JSON.stringify(input),
565
- dynamic: parsed.dynamic,
698
+ dynamic: readToolDynamicFlag(parsed),
566
699
  providerExecuted: parsed.providerExecuted
567
700
  });
568
701
  break;
@@ -575,7 +708,7 @@ var BunnyAgentLanguageModel = class {
575
708
  toolName: toolName ?? "",
576
709
  result: parsed.output,
577
710
  isError: parsed.isError,
578
- dynamic: parsed.dynamic
711
+ dynamic: readToolDynamicFlag(parsed)
579
712
  });
580
713
  break;
581
714
  }
@@ -730,7 +863,8 @@ function createBunnyAgent(defaultOptions) {
730
863
  artifactProcessors: [
731
864
  ...defaultOptions.artifactProcessors ?? [],
732
865
  ...options.artifactProcessors ?? []
733
- ]
866
+ ],
867
+ toolRefs: options.toolRefs !== void 0 ? options.toolRefs : defaultOptions.toolRefs
734
868
  };
735
869
  logger.debug(
736
870
  `[bunny-agent] Creating model: ${modelId}${runner.runnerType ? ` (runnerType: ${runner.runnerType})` : ""}${runner.skillPaths?.length ? ` skillPaths=${runner.skillPaths.length}` : ""}`
@@ -806,6 +940,8 @@ export {
806
940
  LocalSandbox,
807
941
  VERSION,
808
942
  buildRunnerEnv,
943
+ bunnyHttpTool,
944
+ bunnySandboxTool,
809
945
  createBunnyAgent,
810
946
  getBunnyAgentMetadata,
811
947
  getBunnyAgentUsage,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/provider/bunny-agent-language-model.ts","../src/provider/logging.ts","../src/provider/usage.ts","../src/provider/bunny-agent-provider.ts","../src/provider/question-processor.ts"],"sourcesContent":["/**\n * @bunny-agent/sdk\n *\n * BunnyAgent SDK - AI Provider and React hooks for building AI chat interfaces.\n *\n * Main entry point exports the AI provider (backend).\n * React hooks are available via \"@bunny-agent/sdk/react\".\n *\n * @example\n * ```typescript\n * // Backend - Provider\n * import { createBunnyAgent } from \"@bunny-agent/sdk\";\n * const bunnyAgent = createBunnyAgent({ sandbox, env });\n * const model = bunnyAgent(\"sonnet\");\n *\n * // Frontend - React hooks\n * import { useBunnyAgentChat } from \"@bunny-agent/sdk/react\";\n * const { messages, sendMessage } = useBunnyAgentChat({ apiEndpoint: \"/api/ai\" });\n * ```\n */\n\nexport type {\n IsBunnyAgentDaemonHealthyOptions,\n LocalSandboxOptions,\n RunnerEnvParams,\n RunnerType,\n} from \"@bunny-agent/manager\";\n// Re-export LocalSandbox for convenience\n// Re-export env helpers\nexport {\n buildRunnerEnv,\n DEFAULT_BUNNY_AGENT_DAEMON_URL,\n isBunnyAgentDaemonHealthy,\n LocalSandbox,\n} from \"@bunny-agent/manager\";\nexport type {\n ArtifactProcessor,\n ArtifactResult,\n BunnyAgentLanguageModelOptions,\n BunnyAgentModelId,\n BunnyAgentProvider,\n BunnyAgentProviderSettings,\n // Re-exports from @ai-sdk/provider\n LanguageModelV3StreamPart,\n Logger,\n Message,\n Question,\n // Re-exports from @bunny-agent/manager\n SandboxAdapter,\n SandboxHandle,\n StreamWriter,\n SubmitAnswerOptions,\n SubmitAnswerParams,\n TranscriptEntry,\n} from \"./provider\";\n// Provider exports\nexport {\n BunnyAgentLanguageModel,\n createBunnyAgent,\n getBunnyAgentMetadata,\n getBunnyAgentUsage,\n submitAnswer,\n} from \"./provider\";\n\nexport const VERSION = \"0.1.0\";\n","import type {\n JSONValue,\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3Content,\n LanguageModelV3FinishReason,\n LanguageModelV3GenerateResult,\n LanguageModelV3Prompt,\n LanguageModelV3StreamPart,\n LanguageModelV3StreamResult,\n LanguageModelV3Usage,\n SharedV3ProviderMetadata,\n SharedV3Warning,\n} from \"@ai-sdk/provider\";\nimport {\n BunnyAgent,\n type BunnyAgentCodingRunBody,\n type Message,\n type RunnerSpec,\n streamCodingRunFromSandbox,\n} from \"@bunny-agent/manager\";\nimport { getProviderLogger } from \"./logging\";\nimport type {\n BunnyAgentModelId,\n BunnyAgentProviderSettings,\n Logger,\n} from \"./types\";\nimport { normalizeBunnyAgentUsage } from \"./usage\";\n\n/**\n * Options for creating a BunnyAgent language model instance.\n */\nexport interface BunnyAgentLanguageModelOptions {\n id: BunnyAgentModelId;\n options: BunnyAgentProviderSettings & { runner: RunnerSpec };\n}\n\n/** Format error so message and cause chain are visible (e.g. includes \"Fatal error: ...\" from runner). */\nfunction formatErrorForLog(error: unknown): string {\n if (error instanceof Error) {\n const parts = [error.message];\n let cause: unknown = error.cause;\n while (cause instanceof Error) {\n parts.push(cause.message);\n cause = cause.cause;\n }\n return parts.join(\" | cause: \");\n }\n return String(error);\n}\n\n/** Bridge async iterable (sandbox exec / curl) to Web ReadableStream for SSE parsing. */\nfunction asyncIterableToReadableStream(\n iterable: AsyncIterable<Uint8Array>,\n): ReadableStream<Uint8Array> {\n const iterator = iterable[Symbol.asyncIterator]();\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n while (true) {\n const { done, value } = await iterator.next();\n if (done) {\n controller.close();\n return;\n }\n if (value.byteLength > 0) {\n controller.enqueue(value);\n return;\n }\n }\n } catch (error) {\n const isAbort =\n (error instanceof Error && error.name === \"AbortError\") ||\n (typeof DOMException !== \"undefined\" &&\n error instanceof DOMException &&\n error.name === \"AbortError\") ||\n (error instanceof Error && /abort/i.test(error.message));\n if (isAbort) {\n controller.close();\n } else {\n controller.error(error);\n }\n }\n },\n async cancel(reason) {\n await iterator.return?.(reason);\n },\n });\n}\n\nfunction getLastUserTextFromMessages(messages: Message[]): string {\n const lastUser = [...messages].reverse().find((m) => m.role === \"user\");\n if (!lastUser) return \"\";\n const c = lastUser.content;\n if (typeof c === \"string\") return c;\n return c\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n\nfunction createEmptyUsage(): LanguageModelV3Usage {\n return {\n inputTokens: {\n total: 0,\n noCache: 0,\n cacheRead: 0,\n cacheWrite: 0,\n },\n outputTokens: {\n total: 0,\n text: undefined,\n reasoning: undefined,\n },\n raw: undefined,\n };\n}\n\n/**\n * BunnyAgent Language Model implementation for AI SDK.\n */\nexport class BunnyAgentLanguageModel implements LanguageModelV3 {\n readonly specificationVersion = \"v3\" as const;\n readonly provider: string;\n readonly modelId: string;\n readonly supportedUrls: Record<string, RegExp[]> = {\n \"image/*\": [/.*/],\n };\n\n private readonly options: BunnyAgentProviderSettings & { runner: RunnerSpec };\n private readonly logger: Logger;\n private sessionId: string | undefined;\n private toolNameMap: Map<string, string> = new Map();\n private legacyTextPartCounter = 0;\n\n private logUnparsedStreamLine(candidate: string, error: unknown): void {\n const trimmed = candidate.trim();\n if (!trimmed) return;\n const looksLikeError = /\\b(error|failed|exception|traceback|fatal)\\b/i.test(\n trimmed,\n );\n if (looksLikeError) {\n const snippet = trimmed.slice(0, 500);\n const msg = error instanceof Error ? error.message : String(error);\n this.logger.error(\n `[bunny-agent] Unparsed stream line (likely runner error): ${snippet} | parser: ${msg}`,\n );\n }\n }\n\n constructor(modelOptions: BunnyAgentLanguageModelOptions) {\n this.modelId = modelOptions.id;\n this.options = modelOptions.options;\n this.logger = getProviderLogger(modelOptions.options);\n this.provider = \"bunny-agent\";\n }\n\n async doGenerate(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3GenerateResult> {\n const { stream, request } = await this.doStream(options);\n const reader = stream.getReader();\n\n const content: LanguageModelV3Content[] = [];\n const warnings: SharedV3Warning[] = [];\n let finishReason: LanguageModelV3FinishReason = {\n unified: \"other\",\n raw: undefined,\n };\n let usage: LanguageModelV3Usage = createEmptyUsage();\n let providerMetadata: SharedV3ProviderMetadata | undefined;\n\n const textParts: Map<string, { text: string }> = new Map();\n const toolInputs: Map<string, { toolName: string; input: string }> =\n new Map();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n switch (value.type) {\n case \"text-start\": {\n textParts.set(value.id, { text: \"\" });\n break;\n }\n case \"text-delta\": {\n const part = textParts.get(value.id);\n if (part) {\n part.text += value.delta;\n }\n break;\n }\n case \"text-end\": {\n const part = textParts.get(value.id);\n if (part) {\n content.push({\n type: \"text\",\n text: part.text,\n });\n }\n break;\n }\n case \"tool-input-start\": {\n toolInputs.set(value.id, { toolName: value.toolName, input: \"\" });\n break;\n }\n case \"tool-input-delta\": {\n const tool = toolInputs.get(value.id);\n if (tool) {\n tool.input += value.delta;\n }\n break;\n }\n case \"tool-input-end\": {\n break;\n }\n case \"tool-call\": {\n content.push({\n type: \"tool-call\",\n toolCallId: value.toolCallId,\n toolName: value.toolName,\n input: value.input,\n providerExecuted: value.providerExecuted,\n });\n break;\n }\n case \"stream-start\": {\n warnings.push(...value.warnings);\n break;\n }\n case \"error\": {\n // `value.error` type comes from AI SDK and can be `{}`-shaped.\n // Convert it to a readable string safely.\n const message =\n value.error instanceof Error\n ? value.error.message\n : typeof value.error === \"string\"\n ? value.error\n : value.error\n ? String(value.error)\n : \"Unknown error\";\n\n // Surface errors as assistant text + mark finishReason=error.\n content.push({ type: \"text\", text: message });\n finishReason = { unified: \"error\", raw: \"error\" };\n break;\n }\n case \"finish\": {\n finishReason = value.finishReason;\n usage = value.usage;\n providerMetadata = value.providerMetadata;\n break;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return {\n content,\n finishReason,\n usage,\n providerMetadata,\n request,\n warnings,\n };\n }\n\n async doStream(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3StreamResult> {\n const { prompt, abortSignal } = options;\n const messages = this.convertPromptToMessages(prompt);\n\n this.resetStreamState();\n\n this.logger.debug(\n `[bunny-agent] Starting stream with ${messages.length} messages`,\n );\n\n const sandbox = this.options.sandbox;\n if (!sandbox) {\n throw new Error(\n \"BunnyAgent language model requires a sandbox adapter (set `sandbox` on the provider).\",\n );\n }\n\n const daemonUrl = this.options.daemonUrl;\n\n if (daemonUrl) {\n const handle = await sandbox.attach();\n const sandboxEnv = sandbox.getEnv?.() ?? {};\n const runnerEnv = { ...sandboxEnv, ...this.options.env };\n const body: BunnyAgentCodingRunBody = {\n ...this.buildCodingRunBody(messages, handle.getWorkdir()),\n ...(Object.keys(runnerEnv).length > 0 ? { env: runnerEnv } : {}),\n };\n const execOpts = {\n cwd: this.options.cwd ?? handle.getWorkdir(),\n signal: abortSignal,\n };\n const iterable = streamCodingRunFromSandbox(\n handle,\n daemonUrl,\n body,\n execOpts,\n );\n const bytesStream = asyncIterableToReadableStream(iterable);\n return this.buildStreamResult(bytesStream, messages);\n }\n\n const sandboxEnv = sandbox.getEnv?.() ?? {};\n const sandboxWorkdir =\n this.options.cwd ?? sandbox.getWorkdir?.() ?? \"/workspace\";\n\n const agent = new BunnyAgent({\n sandbox,\n runner: this.options.runner,\n env: { ...sandboxEnv, ...this.options.env },\n });\n\n try {\n const bytesStream = await agent.stream({\n messages,\n workspace: {\n path: sandboxWorkdir,\n },\n resume: this.options.resume,\n signal: abortSignal,\n });\n return this.buildStreamResult(bytesStream, messages);\n } catch (error) {\n await agent.destroy().catch(() => {});\n throw error;\n }\n }\n\n private resetStreamState(): void {\n this.sessionId = undefined;\n this.toolNameMap = new Map();\n this.legacyTextPartCounter = 0;\n }\n\n private buildCodingRunBody(\n messages: Message[],\n cwdFallback: string,\n ): BunnyAgentCodingRunBody {\n const runner = this.options.runner;\n const cwd = this.options.cwd ?? cwdFallback;\n return {\n runner: runner.runnerType ?? \"claude\",\n model: this.modelId,\n userInput: getLastUserTextFromMessages(messages),\n cwd,\n resume: this.options.resume,\n systemPrompt: this.options.systemPrompt ?? runner.systemPrompt,\n maxTurns: this.options.maxTurns ?? runner.maxTurns,\n allowedTools: runner.allowedTools ?? this.options.allowedTools,\n skillPaths: runner.skillPaths ?? this.options.skillPaths,\n yolo: this.options.yolo,\n };\n }\n\n private buildStreamResult(\n bytesStream: ReadableStream<Uint8Array>,\n messages: Message[],\n ): LanguageModelV3StreamResult {\n const reader = bytesStream.getReader();\n\n return {\n stream: this.createLanguageModelStreamFromSseReader(reader),\n request: {\n body: JSON.stringify({ messages }),\n },\n };\n }\n\n private createLanguageModelStreamFromSseReader(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n ): ReadableStream<LanguageModelV3StreamPart> {\n const self = this;\n\n return new ReadableStream<LanguageModelV3StreamPart>({\n async start(controller) {\n try {\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n if (buffer.trim()) {\n const parts = self.parseSSEBuffer(buffer);\n for (const part of parts) {\n controller.enqueue(part);\n }\n }\n controller.close();\n break;\n }\n\n const text = new TextDecoder().decode(value);\n buffer += text;\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n let foundDone = false;\n for (const line of lines) {\n const candidate = line.startsWith(\"data: \")\n ? line.slice(6)\n : line.trim();\n if (!candidate) continue;\n if (candidate === \"[DONE]\") {\n foundDone = true;\n continue;\n }\n\n try {\n const parts = self.parseSSEData(candidate);\n for (const part of parts) {\n controller.enqueue(part);\n\n if (self.sessionId) {\n const sessionId: string = self.sessionId;\n\n if (self.options.artifactProcessors?.length) {\n for (const processor of self.options.artifactProcessors) {\n Promise.resolve()\n .then(() => processor.onChange(part, sessionId))\n .catch((e) => {\n self.logger.error(\n `[bunny-agent] Artifact processor error: ${e}`,\n );\n });\n }\n }\n }\n }\n } catch (e) {\n // daemon /api/coding/run or CLI runner may emit plain text lines.\n self.logUnparsedStreamLine(candidate, e);\n }\n }\n\n if (foundDone) {\n controller.close();\n return;\n }\n }\n } catch (error) {\n const isAbort =\n (error instanceof Error && error.name === \"AbortError\") ||\n (typeof DOMException !== \"undefined\" &&\n error instanceof DOMException &&\n error.name === \"AbortError\") ||\n (error instanceof Error && /abort/i.test(error.message));\n if (isAbort) {\n self.logger.info(\"[bunny-agent] Stream aborted by user\");\n controller.close();\n } else {\n self.logger.error(\n `[bunny-agent] Stream error: ${formatErrorForLog(error)}`,\n );\n controller.error(error);\n }\n }\n },\n\n cancel() {\n reader.cancel();\n },\n });\n }\n\n private parseSSEBuffer(buffer: string): LanguageModelV3StreamPart[] {\n const parts: LanguageModelV3StreamPart[] = [];\n const lines = buffer.split(\"\\n\");\n\n for (const line of lines) {\n const candidate = line.startsWith(\"data: \") ? line.slice(6) : line.trim();\n if (!candidate || candidate === \"[DONE]\") continue;\n try {\n const parsedParts = this.parseSSEData(candidate);\n parts.push(...parsedParts);\n } catch (e) {\n this.logUnparsedStreamLine(candidate, e);\n }\n }\n\n return parts;\n }\n\n private parseSSEData(data: string): LanguageModelV3StreamPart[] {\n const parts: LanguageModelV3StreamPart[] = [];\n const parsed = JSON.parse(data) as Record<string, unknown>;\n const parsedType =\n typeof parsed.type === \"string\" ? parsed.type : undefined;\n\n // daemon NDJSON errors may arrive as: {\"error\":\"...\"} (without type)\n if (!parsedType && typeof parsed.error === \"string\") {\n return [\n {\n type: \"error\",\n error: new Error(parsed.error),\n },\n ];\n }\n\n switch (parsedType) {\n case \"start\": {\n break;\n }\n\n // Backward-compatible NDJSON chunk from daemon tests/mock runners.\n case \"text\": {\n const text = typeof parsed.text === \"string\" ? parsed.text : \"\";\n if (text.length > 0) {\n const id = `legacy-text-${++this.legacyTextPartCounter}`;\n parts.push(\n {\n type: \"text-start\",\n id,\n providerMetadata: {\n \"bunny-agent\": {\n sessionId: this.sessionId,\n } as unknown as SharedV3ProviderMetadata,\n },\n },\n { type: \"text-delta\", id, delta: text },\n { type: \"text-end\", id },\n );\n }\n break;\n }\n\n case \"message-metadata\": {\n const metadata = parsed.messageMetadata as Record<string, unknown>;\n if (metadata?.sessionId && typeof metadata.sessionId === \"string\") {\n this.sessionId = metadata.sessionId;\n this.logger.debug(\n `[bunny-agent] Session ID extracted: ${this.sessionId}`,\n );\n parts.push({\n type: \"raw\",\n rawValue: this.sessionId,\n });\n }\n break;\n }\n\n case \"text-start\": {\n parts.push({\n type: \"text-start\",\n id: parsed.id as string,\n providerMetadata: {\n \"bunny-agent\": {\n sessionId: this.sessionId,\n } as unknown as SharedV3ProviderMetadata,\n },\n });\n break;\n }\n\n case \"text-delta\": {\n parts.push({\n type: \"text-delta\",\n id: parsed.id as string,\n delta: parsed.delta as string,\n });\n break;\n }\n\n case \"text-end\": {\n parts.push({\n type: \"text-end\",\n id: parsed.id as string,\n });\n break;\n }\n\n case \"tool-input-start\": {\n parts.push({\n type: \"tool-input-start\",\n id: parsed.toolCallId as string,\n toolName: parsed.toolName as string,\n dynamic: parsed.dynamic as boolean,\n providerExecuted: parsed.providerExecuted as boolean,\n });\n break;\n }\n\n case \"tool-input-delta\": {\n parts.push({\n type: \"tool-input-delta\",\n id: parsed.toolCallId as string,\n delta: parsed.inputTextDelta as string,\n });\n break;\n }\n case \"tool-input-available\": {\n const toolCallId = parsed.toolCallId as string;\n const toolName = parsed.toolName as string;\n const input = parsed.input as Record<string, unknown>;\n this.toolNameMap.set(toolCallId, toolName);\n parts.push({\n type: \"tool-call\",\n toolCallId,\n toolName,\n input: JSON.stringify(input),\n dynamic: parsed.dynamic as boolean,\n providerExecuted: parsed.providerExecuted as boolean,\n });\n break;\n }\n\n case \"tool-output-available\": {\n const toolName = this.toolNameMap.get(parsed.toolCallId as string);\n parts.push({\n type: \"tool-result\",\n toolCallId: parsed.toolCallId as string,\n toolName: toolName ?? \"\",\n result: parsed.output as NonNullable<JSONValue>,\n isError: parsed.isError as boolean,\n dynamic: parsed.dynamic as boolean,\n });\n break;\n }\n case \"error\": {\n parts.push({\n type: \"error\",\n error: new Error(\n (parsed.errorText as string) ||\n (parsed.error as string) ||\n \"Unknown stream error\",\n ),\n });\n break;\n }\n\n case \"finish\": {\n const rawFinishReason = parsed.finishReason;\n let finishReason: LanguageModelV3FinishReason;\n\n if (\n typeof rawFinishReason === \"object\" &&\n rawFinishReason !== null &&\n \"unified\" in rawFinishReason\n ) {\n finishReason = rawFinishReason as LanguageModelV3FinishReason;\n } else {\n finishReason = this.mapFinishReason(rawFinishReason as string);\n }\n\n const usage =\n normalizeBunnyAgentUsage(\n (parsed.messageMetadata as Record<string, unknown>) ?? undefined,\n ) ?? createEmptyUsage();\n\n parts.push({\n type: \"finish\",\n finishReason,\n usage,\n providerMetadata: {\n \"bunny-agent\": {\n ...((parsed.messageMetadata as Record<string, unknown>) ?? {}),\n sessionId: this.sessionId,\n } as unknown as SharedV3ProviderMetadata,\n },\n });\n break;\n }\n }\n\n return parts;\n }\n\n private convertPromptToMessages(prompt: LanguageModelV3Prompt): Message[] {\n const messages: Message[] = [];\n\n for (const message of prompt) {\n switch (message.role) {\n case \"system\": {\n messages.push({\n role: \"system\",\n content: message.content,\n });\n break;\n }\n\n case \"user\": {\n const parts = message.content\n .map((part) => {\n if (part.type === \"text\") {\n return { type: \"text\" as const, text: part.text };\n }\n if (part.type === \"file\") {\n // LanguageModelV3FilePart: data is Uint8Array | string | URL, mediaType is IANA type\n let dataStr = \"\";\n if (part.data instanceof Uint8Array) {\n dataStr = `data:${part.mediaType};base64,${Buffer.from(part.data).toString(\"base64\")}`;\n } else if (part.data instanceof URL) {\n dataStr = part.data.toString();\n } else if (typeof part.data === \"string\") {\n // Already a data URL or base64 string\n dataStr = part.data;\n }\n return {\n type: \"image\" as const,\n mimeType: part.mediaType || \"image/png\",\n data: dataStr,\n };\n }\n return null;\n })\n .filter(\n (\n p,\n ): p is\n | { type: \"text\"; text: string }\n | { type: \"image\"; mimeType: string; data: string } =>\n p !== null,\n );\n\n if (parts.length > 0) {\n // If only text parts, combine them into a string for cleaner payload, else pass array\n const isAllText = parts.every((p) => p.type === \"text\");\n messages.push({\n role: \"user\",\n content: isAllText\n ? parts\n .map((p) => (p as { type: \"text\"; text: string }).text)\n .join(\"\\n\")\n : parts,\n });\n }\n break;\n }\n\n case \"assistant\": {\n const textParts = message.content\n .filter(\n (part): part is { type: \"text\"; text: string } =>\n part.type === \"text\",\n )\n .map((part) => part.text);\n\n if (textParts.length > 0) {\n messages.push({\n role: \"assistant\",\n content: textParts.join(\"\\n\"),\n });\n }\n break;\n }\n\n case \"tool\": {\n break;\n }\n }\n }\n\n return messages;\n }\n\n private mapFinishReason(\n reason: string | undefined,\n ): LanguageModelV3FinishReason {\n switch (reason) {\n case \"stop\":\n return { unified: \"stop\", raw: reason };\n case \"length\":\n return { unified: \"length\", raw: reason };\n case \"tool_calls\":\n case \"tool-calls\":\n return { unified: \"tool-calls\", raw: reason };\n case \"content_filter\":\n case \"content-filter\":\n return { unified: \"content-filter\", raw: reason };\n case \"error\":\n return { unified: \"error\", raw: reason };\n default:\n return { unified: \"other\", raw: reason ?? \"unknown\" };\n }\n }\n}\n","import type { BunnyAgentProviderSettings, Logger } from \"./types\";\n\n/** Shared logger factory for provider and language model. */\nexport function getProviderLogger(\n settings: Partial<BunnyAgentProviderSettings>,\n): Logger {\n if (settings.logger === false) {\n return {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n };\n }\n\n if (settings.logger) {\n return settings.logger;\n }\n\n const isVerbose = settings.verbose ?? false;\n return {\n debug: (msg) => isVerbose && console.debug(msg),\n info: (msg) => isVerbose && console.info(msg),\n warn: (msg) => console.warn(msg),\n error: (msg) => console.error(msg),\n };\n}\n","import type { JSONValue, LanguageModelV3Usage } from \"@ai-sdk/provider\";\n\ntype JsonRecord = Record<string, JSONValue | undefined>;\n\nfunction asRecord(value: unknown): JsonRecord | undefined {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as JsonRecord;\n}\n\n/**\n * Extract `providerMetadata[\"bunny-agent\"]` from an AI SDK providerMetadata object.\n */\nexport function getBunnyAgentMetadata(\n providerMetadata: unknown,\n): JsonRecord | undefined {\n const providerMeta = asRecord(providerMetadata);\n if (providerMeta == null) return undefined;\n return asRecord(providerMeta[\"bunny-agent\"]);\n}\n\n/**\n * Extract Bunny Agent usage payload from an AI SDK providerMetadata object.\n *\n * This returns the raw usage object emitted by Bunny Agent stream metadata,\n * e.g. `{ input_tokens, output_tokens, cache_read_input_tokens, ... }`.\n */\nexport function getBunnyAgentUsage(\n providerMetadata: unknown,\n): LanguageModelV3Usage | undefined {\n const bunnyMeta = getBunnyAgentMetadata(providerMetadata);\n if (bunnyMeta == null) return undefined;\n return normalizeBunnyAgentUsage(bunnyMeta);\n}\n\n/**\n * Convert Bunny Agent usage metadata to AI SDK standard usage shape.\n *\n * Accepts either:\n * - a metadata object that contains `usage` plus extra fields (model/cost/image/search)\n * - or a direct usage payload in snake_case token fields.\n *\n * `raw` preserves usage fields and includes extra metadata fields when available.\n */\nexport function normalizeBunnyAgentUsage(\n data: unknown,\n): LanguageModelV3Usage | undefined {\n const dataRecord = asRecord(data);\n if (dataRecord == null) return undefined;\n\n const usageSource = asRecord(dataRecord.usage ?? dataRecord);\n if (usageSource == null) return undefined;\n const hasTokenFields =\n \"input_tokens\" in usageSource ||\n \"output_tokens\" in usageSource ||\n \"cache_read_input_tokens\" in usageSource ||\n \"cache_creation_input_tokens\" in usageSource;\n if (!hasTokenFields) return undefined;\n\n const inputTokens =\n typeof usageSource.input_tokens === \"number\" ? usageSource.input_tokens : 0;\n const outputTokens =\n typeof usageSource.output_tokens === \"number\"\n ? usageSource.output_tokens\n : 0;\n const cacheRead =\n typeof usageSource.cache_read_input_tokens === \"number\"\n ? usageSource.cache_read_input_tokens\n : 0;\n const cacheWrite =\n typeof usageSource.cache_creation_input_tokens === \"number\"\n ? usageSource.cache_creation_input_tokens\n : 0;\n const textTokens =\n typeof usageSource.text_tokens === \"number\"\n ? usageSource.text_tokens\n : undefined;\n const reasoningTokens =\n typeof usageSource.reasoning_tokens === \"number\"\n ? usageSource.reasoning_tokens\n : undefined;\n const extraMetadata = Object.fromEntries(\n Object.entries(dataRecord).filter(([key]) => key !== \"usage\"),\n ) as JsonRecord;\n const raw =\n Object.keys(extraMetadata).length > 0\n ? { ...usageSource, ...extraMetadata }\n : usageSource;\n\n return {\n inputTokens: {\n total: inputTokens + cacheRead + cacheWrite,\n noCache: inputTokens,\n cacheRead,\n cacheWrite,\n },\n outputTokens: {\n total: outputTokens,\n text: textTokens,\n reasoning: reasoningTokens,\n },\n raw,\n };\n}\n","import type {\n EmbeddingModelV3,\n ImageModelV3,\n LanguageModelV3,\n ProviderV3,\n} from \"@ai-sdk/provider\";\nimport { NoSuchModelError } from \"@ai-sdk/provider\";\nimport type { RunnerSpec } from \"@bunny-agent/manager\";\nimport { BunnyAgentLanguageModel } from \"./bunny-agent-language-model\";\nimport { getProviderLogger } from \"./logging\";\nimport type { BunnyAgentModelId, BunnyAgentProviderSettings } from \"./types\";\n\nexport type { BunnyAgentProviderSettings } from \"./types\";\n\n/**\n * BunnyAgent provider interface that extends the AI SDK's ProviderV3.\n */\nexport interface BunnyAgentProvider extends ProviderV3 {\n (\n modelId: BunnyAgentModelId,\n options?: Partial<BunnyAgentProviderSettings>,\n ): LanguageModelV3;\n\n languageModel(\n modelId: BunnyAgentModelId,\n options?: Partial<BunnyAgentProviderSettings>,\n ): LanguageModelV3;\n\n chat(\n modelId: BunnyAgentModelId,\n options?: Partial<BunnyAgentProviderSettings>,\n ): LanguageModelV3;\n\n embeddingModel(modelId: string): EmbeddingModelV3;\n textEmbeddingModel(modelId: string): EmbeddingModelV3;\n imageModel(modelId: string): ImageModelV3;\n}\n\n/**\n * Creates a BunnyAgent provider instance with the specified configuration.\n *\n * @example\n * ```typescript\n * import { createBunnyAgent } from '@bunny-agent/sdk';\n * import { E2BSandbox } from '@bunny-agent/sandbox-e2b';\n * import { generateText } from 'ai';\n *\n * const bunnyAgent = createBunnyAgent({\n * sandbox: new E2BSandbox({ apiKey: process.env.E2B_API_KEY! }),\n * env: {\n * ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,\n * },\n * });\n *\n * const { text } = await generateText({\n * model: bunnyAgent('sonnet'),\n * prompt: 'Create a hello world program',\n * });\n * ```\n */\nexport function createBunnyAgent(\n defaultOptions: BunnyAgentProviderSettings,\n): BunnyAgentProvider {\n const logger = getProviderLogger(defaultOptions);\n\n if (!defaultOptions.sandbox) {\n throw new Error(\n \"Provide a `sandbox` adapter (e.g. E2BSandbox, LocalSandbox). \" +\n \"Optional `daemonUrl` uses in-sandbox HTTP to bunny-agent-daemon (no automatic `/healthz` probe). Use `isBunnyAgentDaemonHealthy` from `@bunny-agent/sdk` if you want to probe and omit `daemonUrl` for CLI fallback. Omit `daemonUrl` to always use CLI.\",\n );\n }\n\n const createModel = (\n modelId: BunnyAgentModelId,\n options: Partial<BunnyAgentProviderSettings> = {},\n ): LanguageModelV3 => {\n const mergedSkillPaths =\n options.skillPaths !== undefined\n ? options.skillPaths\n : defaultOptions.skillPaths;\n\n const mergedAllowedTools =\n options.allowedTools !== undefined\n ? options.allowedTools\n : defaultOptions.allowedTools;\n\n const runner: RunnerSpec = {\n model: modelId,\n runnerType: options.runnerType ?? defaultOptions.runnerType,\n outputFormat: \"stream\",\n maxTurns: options.maxTurns ?? defaultOptions.maxTurns,\n ...((options.systemPrompt ?? defaultOptions.systemPrompt)\n ? { systemPrompt: options.systemPrompt ?? defaultOptions.systemPrompt }\n : {}),\n ...(mergedSkillPaths && mergedSkillPaths.length > 0\n ? { skillPaths: mergedSkillPaths }\n : {}),\n ...(mergedAllowedTools !== undefined\n ? { allowedTools: mergedAllowedTools }\n : {}),\n };\n\n const mergedOptions = {\n ...defaultOptions,\n ...options,\n runner,\n env: {\n ...defaultOptions.env,\n ...options.env,\n },\n artifactProcessors: [\n ...(defaultOptions.artifactProcessors ?? []),\n ...(options.artifactProcessors ?? []),\n ],\n } as BunnyAgentProviderSettings & { runner: RunnerSpec };\n\n logger.debug(\n `[bunny-agent] Creating model: ${modelId}${runner.runnerType ? ` (runnerType: ${runner.runnerType})` : \"\"}${runner.skillPaths?.length ? ` skillPaths=${runner.skillPaths.length}` : \"\"}`,\n );\n\n return new BunnyAgentLanguageModel({\n id: modelId,\n options: mergedOptions,\n });\n };\n\n const provider = function (\n modelId: BunnyAgentModelId,\n options?: Partial<BunnyAgentProviderSettings>,\n ) {\n if (new.target) {\n throw new Error(\n \"The BunnyAgent model function cannot be called with the new keyword.\",\n );\n }\n\n return createModel(modelId, options);\n };\n\n provider.languageModel = createModel;\n provider.chat = createModel;\n provider.specificationVersion = \"v3\" as const;\n\n provider.embeddingModel = (modelId: string): EmbeddingModelV3 => {\n throw new NoSuchModelError({\n modelId,\n modelType: \"embeddingModel\",\n });\n };\n\n provider.textEmbeddingModel = (modelId: string): EmbeddingModelV3 => {\n throw new NoSuchModelError({\n modelId,\n modelType: \"embeddingModel\",\n });\n };\n\n provider.imageModel = (modelId: string): ImageModelV3 => {\n throw new NoSuchModelError({\n modelId,\n modelType: \"imageModel\",\n });\n };\n\n return provider as BunnyAgentProvider;\n}\n","import type { SandboxAdapter } from \"@bunny-agent/manager\";\nimport type { SubmitAnswerParams } from \"./types\";\n\n/**\n * Options for submitAnswer\n */\nexport interface SubmitAnswerOptions {\n /**\n * Optional base path prefix for approval files\n * @default \".bunny-agent/approvals\"\n */\n basePath?: string;\n}\n\n/**\n * Submit user's answer for an AskUserQuestion tool call.\n * Writes the answer file to `.bunny-agent/approvals/{toolCallId}.json` in the sandbox workdir.\n *\n * @example\n * ```typescript\n * import { submitAnswer } from \"@bunny-agent/sdk\";\n *\n * await submitAnswer(sandbox, {\n * toolCallId: \"tool-456\",\n * questions: [...],\n * answers: { \"Question 1\": \"Answer 1\" },\n * });\n * ```\n */\nexport async function submitAnswer(\n sandbox: SandboxAdapter,\n params: SubmitAnswerParams,\n options?: SubmitAnswerOptions,\n): Promise<void> {\n const { toolCallId, questions, answers } = params;\n const basePath = options?.basePath ?? \".bunny-agent/approvals\";\n\n const allAnswered = questions.every(\n (q) => answers[q.question] !== undefined && answers[q.question] !== \"\",\n );\n\n const answerData = {\n questions,\n answers,\n status: allAnswered ? \"completed\" : \"pending\",\n timestamp: new Date().toISOString(),\n };\n\n const filename = `${toolCallId}.json`;\n const handle = sandbox.getHandle() ?? (await sandbox.attach());\n // Absolute path so remote sandboxes (Sandock) write to the same path the runner reads (/workspace/.bunny-agent/approvals).\n const workdir = handle.getWorkdir();\n const targetDir = workdir\n ? `${workdir.replace(/\\/$/, \"\")}/${basePath}`\n : basePath;\n\n await handle.upload(\n [{ path: filename, content: JSON.stringify(answerData, null, 2) }],\n targetDir,\n );\n\n console.log(\n `[submitAnswer] Answer submitted: ${targetDir}/${filename} (status: ${answerData.status}, workdir: ${workdir ?? \"(none)\"})`,\n );\n}\n"],"mappings":"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","names":["sandboxEnv"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/provider/bunny-agent-language-model.ts","../src/provider/logging.ts","../src/provider/tool-refs.ts","../src/provider/usage.ts","../src/provider/bunny-agent-provider.ts","../src/provider/question-processor.ts"],"sourcesContent":["/**\n * @bunny-agent/sdk\n *\n * BunnyAgent SDK - AI Provider and React hooks for building AI chat interfaces.\n *\n * Main entry point exports the AI provider (backend).\n * React hooks are available via \"@bunny-agent/sdk/react\".\n *\n * @example\n * ```typescript\n * // Backend - Provider\n * import { createBunnyAgent } from \"@bunny-agent/sdk\";\n * const bunnyAgent = createBunnyAgent({ sandbox, env });\n * const model = bunnyAgent(\"sonnet\");\n *\n * // Frontend - React hooks\n * import { useBunnyAgentChat } from \"@bunny-agent/sdk/react\";\n * const { messages, sendMessage } = useBunnyAgentChat({ apiEndpoint: \"/api/ai\" });\n * ```\n */\n\nexport type {\n IsBunnyAgentDaemonHealthyOptions,\n LocalSandboxOptions,\n RunnerEnvParams,\n RunnerType,\n} from \"@bunny-agent/manager\";\n// Re-export LocalSandbox for convenience\n// Re-export env helpers\nexport {\n buildRunnerEnv,\n DEFAULT_BUNNY_AGENT_DAEMON_URL,\n isBunnyAgentDaemonHealthy,\n LocalSandbox,\n} from \"@bunny-agent/manager\";\nexport type {\n ArtifactProcessor,\n ArtifactResult,\n BunnyAgentLanguageModelOptions,\n BunnyAgentModelId,\n BunnyAgentProvider,\n BunnyAgentProviderSettings,\n // Re-exports from @ai-sdk/provider\n LanguageModelV3StreamPart,\n Logger,\n Message,\n Question,\n // Re-exports from @bunny-agent/manager\n SandboxAdapter,\n SandboxHandle,\n StreamWriter,\n SubmitAnswerOptions,\n SubmitAnswerParams,\n ToolRuntime,\n TranscriptEntry,\n} from \"./provider\";\n// Provider exports\nexport {\n BunnyAgentLanguageModel,\n bunnyHttpTool,\n bunnySandboxTool,\n createBunnyAgent,\n getBunnyAgentMetadata,\n getBunnyAgentUsage,\n submitAnswer,\n} from \"./provider\";\n\nexport const VERSION = \"0.1.0\";\n","import type {\n JSONValue,\n LanguageModelV3,\n LanguageModelV3CallOptions,\n LanguageModelV3Content,\n LanguageModelV3FinishReason,\n LanguageModelV3GenerateResult,\n LanguageModelV3Prompt,\n LanguageModelV3StreamPart,\n LanguageModelV3StreamResult,\n LanguageModelV3Usage,\n SharedV3ProviderMetadata,\n SharedV3Warning,\n} from \"@ai-sdk/provider\";\nimport {\n BunnyAgent,\n type BunnyAgentCodingRunBody,\n type Message,\n type RunnerSpec,\n streamCodingRunFromSandbox,\n type ToolRef,\n} from \"@bunny-agent/manager\";\nimport { getProviderLogger } from \"./logging\";\nimport { compileToolRefsFromLanguageModelTools } from \"./tool-refs\";\nimport type {\n BunnyAgentModelId,\n BunnyAgentProviderSettings,\n Logger,\n} from \"./types\";\nimport { normalizeBunnyAgentUsage } from \"./usage\";\n\n/**\n * Options for creating a BunnyAgent language model instance.\n */\nexport interface BunnyAgentLanguageModelOptions {\n id: BunnyAgentModelId;\n options: BunnyAgentProviderSettings & { runner: RunnerSpec };\n}\n\n/** Format error so message and cause chain are visible (e.g. includes \"Fatal error: ...\" from runner). */\nfunction formatErrorForLog(error: unknown): string {\n if (error instanceof Error) {\n const parts = [error.message];\n let cause: unknown = error.cause;\n while (cause instanceof Error) {\n parts.push(cause.message);\n cause = cause.cause;\n }\n return parts.join(\" | cause: \");\n }\n return String(error);\n}\n\n/** Bridge async iterable (sandbox exec / curl) to Web ReadableStream for SSE parsing. */\nfunction asyncIterableToReadableStream(\n iterable: AsyncIterable<Uint8Array>,\n): ReadableStream<Uint8Array> {\n const iterator = iterable[Symbol.asyncIterator]();\n return new ReadableStream<Uint8Array>({\n async pull(controller) {\n try {\n while (true) {\n const { done, value } = await iterator.next();\n if (done) {\n controller.close();\n return;\n }\n if (value.byteLength > 0) {\n controller.enqueue(value);\n return;\n }\n }\n } catch (error) {\n const isAbort =\n (error instanceof Error && error.name === \"AbortError\") ||\n (typeof DOMException !== \"undefined\" &&\n error instanceof DOMException &&\n error.name === \"AbortError\") ||\n (error instanceof Error && /abort/i.test(error.message));\n if (isAbort) {\n controller.close();\n } else {\n controller.error(error);\n }\n }\n },\n async cancel(reason) {\n await iterator.return?.(reason);\n },\n });\n}\n\nfunction mergeToolRefs(\n staticToolRefs: ToolRef[] | undefined,\n callToolRefs: ToolRef[] | undefined,\n): ToolRef[] | undefined {\n const merged = [...(staticToolRefs ?? []), ...(callToolRefs ?? [])];\n return merged.length > 0 ? merged : undefined;\n}\n\nfunction getLastUserTextFromMessages(messages: Message[]): string {\n const lastUser = [...messages].reverse().find((m) => m.role === \"user\");\n if (!lastUser) return \"\";\n const c = lastUser.content;\n if (typeof c === \"string\") return c;\n return c\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\\n\");\n}\n\nfunction createEmptyUsage(): LanguageModelV3Usage {\n return {\n inputTokens: {\n total: 0,\n noCache: 0,\n cacheRead: 0,\n cacheWrite: 0,\n },\n outputTokens: {\n total: 0,\n text: undefined,\n reasoning: undefined,\n },\n raw: undefined,\n };\n}\n\nfunction readToolDynamicFlag(parsed: Record<string, unknown>): boolean {\n if (typeof parsed.dynamic === \"boolean\") {\n return parsed.dynamic;\n }\n return parsed.providerExecuted === true;\n}\n\n/**\n * BunnyAgent Language Model implementation for AI SDK.\n */\nexport class BunnyAgentLanguageModel implements LanguageModelV3 {\n readonly specificationVersion = \"v3\" as const;\n readonly provider: string;\n readonly modelId: string;\n readonly supportedUrls: Record<string, RegExp[]> = {\n \"image/*\": [/.*/],\n };\n\n readonly settings: BunnyAgentProviderSettings & { runner: RunnerSpec };\n private readonly options: BunnyAgentProviderSettings & { runner: RunnerSpec };\n private readonly logger: Logger;\n private sessionId: string | undefined;\n private toolNameMap: Map<string, string> = new Map();\n private legacyTextPartCounter = 0;\n\n private logUnparsedStreamLine(candidate: string, error: unknown): void {\n const trimmed = candidate.trim();\n if (!trimmed) return;\n const looksLikeError = /\\b(error|failed|exception|traceback|fatal)\\b/i.test(\n trimmed,\n );\n if (looksLikeError) {\n const snippet = trimmed.slice(0, 500);\n const msg = error instanceof Error ? error.message : String(error);\n this.logger.error(\n `[bunny-agent] Unparsed stream line (likely runner error): ${snippet} | parser: ${msg}`,\n );\n }\n }\n\n constructor(modelOptions: BunnyAgentLanguageModelOptions) {\n this.modelId = modelOptions.id;\n this.settings = modelOptions.options;\n this.options = modelOptions.options;\n this.logger = getProviderLogger(modelOptions.options);\n this.provider = \"bunny-agent\";\n }\n\n async doGenerate(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3GenerateResult> {\n const { stream, request } = await this.doStream(options);\n const reader = stream.getReader();\n\n const content: LanguageModelV3Content[] = [];\n const warnings: SharedV3Warning[] = [];\n let finishReason: LanguageModelV3FinishReason = {\n unified: \"other\",\n raw: undefined,\n };\n let usage: LanguageModelV3Usage = createEmptyUsage();\n let providerMetadata: SharedV3ProviderMetadata | undefined;\n\n const textParts: Map<string, { text: string }> = new Map();\n const toolInputs: Map<string, { toolName: string; input: string }> =\n new Map();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n switch (value.type) {\n case \"text-start\": {\n textParts.set(value.id, { text: \"\" });\n break;\n }\n case \"text-delta\": {\n const part = textParts.get(value.id);\n if (part) {\n part.text += value.delta;\n }\n break;\n }\n case \"text-end\": {\n const part = textParts.get(value.id);\n if (part) {\n content.push({\n type: \"text\",\n text: part.text,\n });\n }\n break;\n }\n case \"tool-input-start\": {\n toolInputs.set(value.id, { toolName: value.toolName, input: \"\" });\n break;\n }\n case \"tool-input-delta\": {\n const tool = toolInputs.get(value.id);\n if (tool) {\n tool.input += value.delta;\n }\n break;\n }\n case \"tool-input-end\": {\n break;\n }\n case \"tool-call\": {\n content.push({\n type: \"tool-call\",\n toolCallId: value.toolCallId,\n toolName: value.toolName,\n input: value.input,\n providerExecuted: value.providerExecuted,\n });\n break;\n }\n case \"stream-start\": {\n warnings.push(...value.warnings);\n break;\n }\n case \"error\": {\n // `value.error` type comes from AI SDK and can be `{}`-shaped.\n // Convert it to a readable string safely.\n const message =\n value.error instanceof Error\n ? value.error.message\n : typeof value.error === \"string\"\n ? value.error\n : value.error\n ? String(value.error)\n : \"Unknown error\";\n\n // Surface errors as assistant text + mark finishReason=error.\n content.push({ type: \"text\", text: message });\n finishReason = { unified: \"error\", raw: \"error\" };\n break;\n }\n case \"finish\": {\n finishReason = value.finishReason;\n usage = value.usage;\n providerMetadata = value.providerMetadata;\n break;\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n return {\n content,\n finishReason,\n usage,\n providerMetadata,\n request,\n warnings,\n };\n }\n\n async doStream(\n options: LanguageModelV3CallOptions,\n ): Promise<LanguageModelV3StreamResult> {\n const { prompt, abortSignal } = options;\n const messages = this.convertPromptToMessages(prompt);\n\n this.resetStreamState();\n\n this.logger.debug(\n `[bunny-agent] Starting stream with ${messages.length} messages`,\n );\n\n const sandbox = this.options.sandbox;\n if (!sandbox) {\n throw new Error(\n \"BunnyAgent language model requires a sandbox adapter (set `sandbox` on the provider).\",\n );\n }\n\n const toolRefs = mergeToolRefs(\n this.options.toolRefs,\n compileToolRefsFromLanguageModelTools(options.tools),\n );\n\n const daemonUrl = this.options.daemonUrl;\n\n if (daemonUrl) {\n const handle = await sandbox.attach();\n const sandboxEnv = sandbox.getEnv?.() ?? {};\n const runnerEnv = { ...sandboxEnv, ...this.options.env };\n const body: BunnyAgentCodingRunBody = {\n ...this.buildCodingRunBody(messages, handle.getWorkdir(), toolRefs),\n ...(Object.keys(runnerEnv).length > 0 ? { env: runnerEnv } : {}),\n };\n const execOpts = {\n cwd: this.options.cwd ?? handle.getWorkdir(),\n signal: abortSignal,\n };\n const iterable = streamCodingRunFromSandbox(\n handle,\n daemonUrl,\n body,\n execOpts,\n );\n const bytesStream = asyncIterableToReadableStream(iterable);\n return this.buildStreamResult(bytesStream, messages);\n }\n\n const sandboxEnv = sandbox.getEnv?.() ?? {};\n const sandboxWorkdir =\n this.options.cwd ?? sandbox.getWorkdir?.() ?? \"/workspace\";\n\n const agent = new BunnyAgent({\n sandbox,\n runner: this.options.runner,\n env: { ...sandboxEnv, ...this.options.env },\n });\n\n try {\n const bytesStream = await agent.stream({\n messages,\n workspace: {\n path: sandboxWorkdir,\n },\n resume: this.options.resume,\n signal: abortSignal,\n ...(toolRefs && toolRefs.length > 0 ? { toolRefs } : {}),\n });\n return this.buildStreamResult(bytesStream, messages);\n } catch (error) {\n await agent.destroy().catch(() => {});\n throw error;\n }\n }\n\n private resetStreamState(): void {\n this.sessionId = undefined;\n this.toolNameMap = new Map();\n this.legacyTextPartCounter = 0;\n }\n\n private buildCodingRunBody(\n messages: Message[],\n cwdFallback: string,\n toolRefs: ToolRef[] | undefined,\n ): BunnyAgentCodingRunBody {\n const runner = this.options.runner;\n const cwd = this.options.cwd ?? cwdFallback;\n\n return {\n runner: runner.runnerType ?? \"claude\",\n model: this.modelId,\n userInput: getLastUserTextFromMessages(messages),\n cwd,\n resume: this.options.resume,\n systemPrompt: this.options.systemPrompt ?? runner.systemPrompt,\n maxTurns: this.options.maxTurns ?? runner.maxTurns,\n allowedTools: runner.allowedTools ?? this.options.allowedTools,\n skillPaths: runner.skillPaths ?? this.options.skillPaths,\n yolo: this.options.yolo,\n ...(toolRefs && toolRefs.length > 0 ? { toolRefs } : {}),\n };\n }\n\n private buildStreamResult(\n bytesStream: ReadableStream<Uint8Array>,\n messages: Message[],\n ): LanguageModelV3StreamResult {\n const reader = bytesStream.getReader();\n\n return {\n stream: this.createLanguageModelStreamFromSseReader(reader),\n request: {\n body: JSON.stringify({ messages }),\n },\n };\n }\n\n private createLanguageModelStreamFromSseReader(\n reader: ReadableStreamDefaultReader<Uint8Array>,\n ): ReadableStream<LanguageModelV3StreamPart> {\n const self = this;\n\n return new ReadableStream<LanguageModelV3StreamPart>({\n async start(controller) {\n try {\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n if (buffer.trim()) {\n const parts = self.parseSSEBuffer(buffer);\n for (const part of parts) {\n controller.enqueue(part);\n }\n }\n controller.close();\n break;\n }\n\n const text = new TextDecoder().decode(value);\n buffer += text;\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n let foundDone = false;\n for (const line of lines) {\n const candidate = line.startsWith(\"data: \")\n ? line.slice(6)\n : line.trim();\n if (!candidate) continue;\n if (candidate === \"[DONE]\") {\n foundDone = true;\n continue;\n }\n\n try {\n const parts = self.parseSSEData(candidate);\n for (const part of parts) {\n controller.enqueue(part);\n\n if (self.sessionId) {\n const sessionId: string = self.sessionId;\n\n if (self.options.artifactProcessors?.length) {\n for (const processor of self.options.artifactProcessors) {\n Promise.resolve()\n .then(() => processor.onChange(part, sessionId))\n .catch((e) => {\n self.logger.error(\n `[bunny-agent] Artifact processor error: ${e}`,\n );\n });\n }\n }\n }\n }\n } catch (e) {\n // daemon /api/coding/run or CLI runner may emit plain text lines.\n self.logUnparsedStreamLine(candidate, e);\n }\n }\n\n if (foundDone) {\n controller.close();\n return;\n }\n }\n } catch (error) {\n const isAbort =\n (error instanceof Error && error.name === \"AbortError\") ||\n (typeof DOMException !== \"undefined\" &&\n error instanceof DOMException &&\n error.name === \"AbortError\") ||\n (error instanceof Error && /abort/i.test(error.message));\n if (isAbort) {\n self.logger.info(\"[bunny-agent] Stream aborted by user\");\n controller.close();\n } else {\n self.logger.error(\n `[bunny-agent] Stream error: ${formatErrorForLog(error)}`,\n );\n controller.error(error);\n }\n }\n },\n\n cancel() {\n reader.cancel();\n },\n });\n }\n\n private parseSSEBuffer(buffer: string): LanguageModelV3StreamPart[] {\n const parts: LanguageModelV3StreamPart[] = [];\n const lines = buffer.split(\"\\n\");\n\n for (const line of lines) {\n const candidate = line.startsWith(\"data: \") ? line.slice(6) : line.trim();\n if (!candidate || candidate === \"[DONE]\") continue;\n try {\n const parsedParts = this.parseSSEData(candidate);\n parts.push(...parsedParts);\n } catch (e) {\n this.logUnparsedStreamLine(candidate, e);\n }\n }\n\n return parts;\n }\n\n private parseSSEData(data: string): LanguageModelV3StreamPart[] {\n const parts: LanguageModelV3StreamPart[] = [];\n const parsed = JSON.parse(data) as Record<string, unknown>;\n const parsedType =\n typeof parsed.type === \"string\" ? parsed.type : undefined;\n\n // daemon NDJSON errors may arrive as: {\"error\":\"...\"} (without type)\n if (!parsedType && typeof parsed.error === \"string\") {\n return [\n {\n type: \"error\",\n error: new Error(parsed.error),\n },\n ];\n }\n\n switch (parsedType) {\n case \"start\": {\n break;\n }\n\n // Backward-compatible NDJSON chunk from daemon tests/mock runners.\n case \"text\": {\n const text = typeof parsed.text === \"string\" ? parsed.text : \"\";\n if (text.length > 0) {\n const id = `legacy-text-${++this.legacyTextPartCounter}`;\n parts.push(\n {\n type: \"text-start\",\n id,\n providerMetadata: {\n \"bunny-agent\": {\n sessionId: this.sessionId,\n } as unknown as SharedV3ProviderMetadata,\n },\n },\n { type: \"text-delta\", id, delta: text },\n { type: \"text-end\", id },\n );\n }\n break;\n }\n\n case \"message-metadata\": {\n const metadata = parsed.messageMetadata as Record<string, unknown>;\n if (metadata?.sessionId && typeof metadata.sessionId === \"string\") {\n this.sessionId = metadata.sessionId;\n this.logger.debug(\n `[bunny-agent] Session ID extracted: ${this.sessionId}`,\n );\n parts.push({\n type: \"raw\",\n rawValue: this.sessionId,\n });\n }\n break;\n }\n\n case \"text-start\": {\n parts.push({\n type: \"text-start\",\n id: parsed.id as string,\n providerMetadata: {\n \"bunny-agent\": {\n sessionId: this.sessionId,\n } as unknown as SharedV3ProviderMetadata,\n },\n });\n break;\n }\n\n case \"text-delta\": {\n parts.push({\n type: \"text-delta\",\n id: parsed.id as string,\n delta: parsed.delta as string,\n });\n break;\n }\n\n case \"text-end\": {\n parts.push({\n type: \"text-end\",\n id: parsed.id as string,\n });\n break;\n }\n\n case \"tool-input-start\": {\n parts.push({\n type: \"tool-input-start\",\n id: parsed.toolCallId as string,\n toolName: parsed.toolName as string,\n dynamic: readToolDynamicFlag(parsed),\n providerExecuted: parsed.providerExecuted as boolean,\n });\n break;\n }\n\n case \"tool-input-delta\": {\n parts.push({\n type: \"tool-input-delta\",\n id: parsed.toolCallId as string,\n delta: parsed.inputTextDelta as string,\n });\n break;\n }\n case \"tool-input-available\": {\n const toolCallId = parsed.toolCallId as string;\n const toolName = parsed.toolName as string;\n const input = parsed.input as Record<string, unknown>;\n this.toolNameMap.set(toolCallId, toolName);\n parts.push({\n type: \"tool-call\",\n toolCallId,\n toolName,\n input: JSON.stringify(input),\n dynamic: readToolDynamicFlag(parsed),\n providerExecuted: parsed.providerExecuted as boolean,\n });\n break;\n }\n\n case \"tool-output-available\": {\n const toolName = this.toolNameMap.get(parsed.toolCallId as string);\n parts.push({\n type: \"tool-result\",\n toolCallId: parsed.toolCallId as string,\n toolName: toolName ?? \"\",\n result: parsed.output as NonNullable<JSONValue>,\n isError: parsed.isError as boolean,\n dynamic: readToolDynamicFlag(parsed),\n });\n break;\n }\n case \"error\": {\n parts.push({\n type: \"error\",\n error: new Error(\n (parsed.errorText as string) ||\n (parsed.error as string) ||\n \"Unknown stream error\",\n ),\n });\n break;\n }\n\n case \"finish\": {\n const rawFinishReason = parsed.finishReason;\n let finishReason: LanguageModelV3FinishReason;\n\n if (\n typeof rawFinishReason === \"object\" &&\n rawFinishReason !== null &&\n \"unified\" in rawFinishReason\n ) {\n finishReason = rawFinishReason as LanguageModelV3FinishReason;\n } else {\n finishReason = this.mapFinishReason(rawFinishReason as string);\n }\n\n const usage =\n normalizeBunnyAgentUsage(\n (parsed.messageMetadata as Record<string, unknown>) ?? undefined,\n ) ?? createEmptyUsage();\n\n parts.push({\n type: \"finish\",\n finishReason,\n usage,\n providerMetadata: {\n \"bunny-agent\": {\n ...((parsed.messageMetadata as Record<string, unknown>) ?? {}),\n sessionId: this.sessionId,\n } as unknown as SharedV3ProviderMetadata,\n },\n });\n break;\n }\n }\n\n return parts;\n }\n\n private convertPromptToMessages(prompt: LanguageModelV3Prompt): Message[] {\n const messages: Message[] = [];\n\n for (const message of prompt) {\n switch (message.role) {\n case \"system\": {\n messages.push({\n role: \"system\",\n content: message.content,\n });\n break;\n }\n\n case \"user\": {\n const parts = message.content\n .map((part) => {\n if (part.type === \"text\") {\n return { type: \"text\" as const, text: part.text };\n }\n if (part.type === \"file\") {\n // LanguageModelV3FilePart: data is Uint8Array | string | URL, mediaType is IANA type\n let dataStr = \"\";\n if (part.data instanceof Uint8Array) {\n dataStr = `data:${part.mediaType};base64,${Buffer.from(part.data).toString(\"base64\")}`;\n } else if (part.data instanceof URL) {\n dataStr = part.data.toString();\n } else if (typeof part.data === \"string\") {\n // Already a data URL or base64 string\n dataStr = part.data;\n }\n return {\n type: \"image\" as const,\n mimeType: part.mediaType || \"image/png\",\n data: dataStr,\n };\n }\n return null;\n })\n .filter(\n (\n p,\n ): p is\n | { type: \"text\"; text: string }\n | { type: \"image\"; mimeType: string; data: string } =>\n p !== null,\n );\n\n if (parts.length > 0) {\n // If only text parts, combine them into a string for cleaner payload, else pass array\n const isAllText = parts.every((p) => p.type === \"text\");\n messages.push({\n role: \"user\",\n content: isAllText\n ? parts\n .map((p) => (p as { type: \"text\"; text: string }).text)\n .join(\"\\n\")\n : parts,\n });\n }\n break;\n }\n\n case \"assistant\": {\n const textParts = message.content\n .filter(\n (part): part is { type: \"text\"; text: string } =>\n part.type === \"text\",\n )\n .map((part) => part.text);\n\n if (textParts.length > 0) {\n messages.push({\n role: \"assistant\",\n content: textParts.join(\"\\n\"),\n });\n }\n break;\n }\n\n case \"tool\": {\n break;\n }\n }\n }\n\n return messages;\n }\n\n private mapFinishReason(\n reason: string | undefined,\n ): LanguageModelV3FinishReason {\n switch (reason) {\n case \"stop\":\n return { unified: \"stop\", raw: reason };\n case \"length\":\n return { unified: \"length\", raw: reason };\n case \"tool_calls\":\n case \"tool-calls\":\n return { unified: \"tool-calls\", raw: reason };\n case \"content_filter\":\n case \"content-filter\":\n return { unified: \"content-filter\", raw: reason };\n case \"error\":\n return { unified: \"error\", raw: reason };\n default:\n return { unified: \"other\", raw: reason ?? \"unknown\" };\n }\n }\n}\n","import type { BunnyAgentProviderSettings, Logger } from \"./types\";\n\n/** Shared logger factory for provider and language model. */\nexport function getProviderLogger(\n settings: Partial<BunnyAgentProviderSettings>,\n): Logger {\n if (settings.logger === false) {\n return {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n };\n }\n\n if (settings.logger) {\n return settings.logger;\n }\n\n const isVerbose = settings.verbose ?? false;\n return {\n debug: (msg) => isVerbose && console.debug(msg),\n info: (msg) => isVerbose && console.info(msg),\n warn: (msg) => console.warn(msg),\n error: (msg) => console.error(msg),\n };\n}\n","import type {\n JSONObject,\n LanguageModelV3FunctionTool,\n LanguageModelV3ProviderTool,\n SharedV3ProviderOptions,\n} from \"@ai-sdk/provider\";\nimport type { ToolRef } from \"@bunny-agent/manager\";\nimport type { Tool } from \"ai\";\n\nconst BUNNY_PROVIDER_OPTIONS_KEY = \"bunny-agent\";\n\ntype BunnyProviderOptions = {\n runtime?: JSONObject;\n};\n\ntype BunnyToolRuntime = Extract<\n ToolRef[\"runtime\"],\n { type: \"http\" | \"module\" }\n>;\n\ntype BunnyDynamicTool<INPUT> = Tool<INPUT, unknown> & { type: \"dynamic\" };\n\n/**\n * AI SDK helper for tools that the sandbox runner should call by HTTP.\n *\n * This is still used with the standard AI SDK `streamText`:\n * `import { streamText } from \"ai\"`.\n */\nexport function bunnyHttpTool<INPUT, OUTPUT>(\n input: Omit<Tool<INPUT, OUTPUT>, \"execute\" | \"outputSchema\"> & {\n endpoint: {\n url: string;\n headers?: Record<string, string>;\n };\n },\n): BunnyDynamicTool<INPUT> {\n return {\n type: \"dynamic\" as const,\n description: input.description,\n title: input.title,\n providerOptions: withBunnyProviderOptions(input.providerOptions, {\n runtime: {\n type: \"http\",\n url: input.endpoint.url,\n ...(input.endpoint.headers ? { headers: input.endpoint.headers } : {}),\n },\n }),\n inputSchema: input.inputSchema,\n inputExamples: input.inputExamples,\n needsApproval: input.needsApproval,\n strict: input.strict,\n onInputStart: input.onInputStart,\n onInputDelta: input.onInputDelta,\n onInputAvailable: input.onInputAvailable,\n async execute() {\n throw new Error(\n \"bunnyHttpTool is provider-executed by the sandbox runner.\",\n );\n },\n } satisfies BunnyDynamicTool<INPUT>;\n}\n\n/**\n * AI SDK helper for tools implemented by a module already present in the\n * sandbox filesystem.\n */\nexport function bunnySandboxTool<INPUT, OUTPUT>(\n input: Omit<Tool<INPUT, OUTPUT>, \"execute\" | \"outputSchema\"> & {\n module: string;\n exportName?: string;\n },\n): BunnyDynamicTool<INPUT> {\n return {\n type: \"dynamic\" as const,\n description: input.description,\n title: input.title,\n providerOptions: withBunnyProviderOptions(input.providerOptions, {\n runtime: {\n type: \"module\",\n module: input.module,\n ...(input.exportName ? { exportName: input.exportName } : {}),\n },\n }),\n inputSchema: input.inputSchema,\n inputExamples: input.inputExamples,\n needsApproval: input.needsApproval,\n strict: input.strict,\n onInputStart: input.onInputStart,\n onInputDelta: input.onInputDelta,\n onInputAvailable: input.onInputAvailable,\n async execute() {\n throw new Error(\n \"bunnySandboxTool is provider-executed by the sandbox runner.\",\n );\n },\n } satisfies BunnyDynamicTool<INPUT>;\n}\n\nexport function compileToolRefsFromLanguageModelTools(\n tools:\n | Array<LanguageModelV3FunctionTool | LanguageModelV3ProviderTool>\n | undefined,\n): ToolRef[] | undefined {\n if (!tools || tools.length === 0) return undefined;\n\n const toolRefs: ToolRef[] = [];\n\n for (const tool of tools) {\n if (tool.type !== \"function\") {\n continue;\n }\n\n const runtime = getBunnyRuntime(tool);\n if (!runtime) {\n throw new Error(\n `[bunny-agent] Tool \"${tool.name}\" was passed through AI SDK streamText, ` +\n \"but Bunny cannot access host-side tool({ execute }) callbacks at the provider boundary. \" +\n \"Use bunnyHttpTool(...) for an endpoint tool or bunnySandboxTool(...) for a sandbox-local module.\",\n );\n }\n\n toolRefs.push({\n name: tool.name,\n description: tool.description ?? \"\",\n inputSchema: tool.inputSchema as Record<string, unknown>,\n runtime,\n });\n }\n\n return toolRefs.length > 0 ? toolRefs : undefined;\n}\n\nfunction getBunnyRuntime(\n tool: LanguageModelV3FunctionTool,\n): BunnyToolRuntime | undefined {\n const options = tool.providerOptions?.[BUNNY_PROVIDER_OPTIONS_KEY] as\n | BunnyProviderOptions\n | undefined;\n const runtime = options?.runtime;\n if (!isRecord(runtime) || typeof runtime.type !== \"string\") {\n return undefined;\n }\n if (runtime.type === \"http\" && typeof runtime.url === \"string\") {\n return {\n type: \"http\",\n url: runtime.url,\n ...(isStringRecord(runtime.headers) ? { headers: runtime.headers } : {}),\n };\n }\n if (runtime.type === \"module\" && typeof runtime.module === \"string\") {\n return {\n type: \"module\",\n module: runtime.module,\n ...(typeof runtime.exportName === \"string\"\n ? { exportName: runtime.exportName }\n : {}),\n };\n }\n return undefined;\n}\n\nfunction withBunnyProviderOptions(\n providerOptions: SharedV3ProviderOptions | undefined,\n bunnyOptions: BunnyProviderOptions,\n): SharedV3ProviderOptions {\n return {\n ...(providerOptions ?? {}),\n [BUNNY_PROVIDER_OPTIONS_KEY]: {\n ...((providerOptions?.[BUNNY_PROVIDER_OPTIONS_KEY] as\n | object\n | undefined) ?? {}),\n ...bunnyOptions,\n },\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction isStringRecord(value: unknown): value is Record<string, string> {\n if (!isRecord(value)) return false;\n return Object.values(value).every((entry) => typeof entry === \"string\");\n}\n","import type { JSONValue, LanguageModelV3Usage } from \"@ai-sdk/provider\";\n\ntype JsonRecord = Record<string, JSONValue | undefined>;\n\nfunction asRecord(value: unknown): JsonRecord | undefined {\n if (value == null || typeof value !== \"object\" || Array.isArray(value)) {\n return undefined;\n }\n return value as JsonRecord;\n}\n\n/**\n * Extract `providerMetadata[\"bunny-agent\"]` from an AI SDK providerMetadata object.\n */\nexport function getBunnyAgentMetadata(\n providerMetadata: unknown,\n): JsonRecord | undefined {\n const providerMeta = asRecord(providerMetadata);\n if (providerMeta == null) return undefined;\n return asRecord(providerMeta[\"bunny-agent\"]);\n}\n\n/**\n * Extract Bunny Agent usage payload from an AI SDK providerMetadata object.\n *\n * This returns the raw usage object emitted by Bunny Agent stream metadata,\n * e.g. `{ input_tokens, output_tokens, cache_read_input_tokens, ... }`.\n */\nexport function getBunnyAgentUsage(\n providerMetadata: unknown,\n): LanguageModelV3Usage | undefined {\n const bunnyMeta = getBunnyAgentMetadata(providerMetadata);\n if (bunnyMeta == null) return undefined;\n return normalizeBunnyAgentUsage(bunnyMeta);\n}\n\n/**\n * Convert Bunny Agent usage metadata to AI SDK standard usage shape.\n *\n * Accepts either:\n * - a metadata object that contains `usage` plus extra fields (model/cost/image/search)\n * - or a direct usage payload in snake_case token fields.\n *\n * `raw` preserves usage fields and includes extra metadata fields when available.\n */\nexport function normalizeBunnyAgentUsage(\n data: unknown,\n): LanguageModelV3Usage | undefined {\n const dataRecord = asRecord(data);\n if (dataRecord == null) return undefined;\n\n const usageSource = asRecord(dataRecord.usage ?? dataRecord);\n if (usageSource == null) return undefined;\n const hasTokenFields =\n \"input_tokens\" in usageSource ||\n \"output_tokens\" in usageSource ||\n \"cache_read_input_tokens\" in usageSource ||\n \"cache_creation_input_tokens\" in usageSource;\n if (!hasTokenFields) return undefined;\n\n const inputTokens =\n typeof usageSource.input_tokens === \"number\" ? usageSource.input_tokens : 0;\n const outputTokens =\n typeof usageSource.output_tokens === \"number\"\n ? usageSource.output_tokens\n : 0;\n const cacheRead =\n typeof usageSource.cache_read_input_tokens === \"number\"\n ? usageSource.cache_read_input_tokens\n : 0;\n const cacheWrite =\n typeof usageSource.cache_creation_input_tokens === \"number\"\n ? usageSource.cache_creation_input_tokens\n : 0;\n const textTokens =\n typeof usageSource.text_tokens === \"number\"\n ? usageSource.text_tokens\n : undefined;\n const reasoningTokens =\n typeof usageSource.reasoning_tokens === \"number\"\n ? usageSource.reasoning_tokens\n : undefined;\n const extraMetadata = Object.fromEntries(\n Object.entries(dataRecord).filter(([key]) => key !== \"usage\"),\n ) as JsonRecord;\n const raw =\n Object.keys(extraMetadata).length > 0\n ? { ...usageSource, ...extraMetadata }\n : usageSource;\n\n return {\n inputTokens: {\n total: inputTokens + cacheRead + cacheWrite,\n noCache: inputTokens,\n cacheRead,\n cacheWrite,\n },\n outputTokens: {\n total: outputTokens,\n text: textTokens,\n reasoning: reasoningTokens,\n },\n raw,\n };\n}\n","import type {\n EmbeddingModelV3,\n ImageModelV3,\n LanguageModelV3,\n ProviderV3,\n} from \"@ai-sdk/provider\";\nimport { NoSuchModelError } from \"@ai-sdk/provider\";\nimport type { RunnerSpec } from \"@bunny-agent/manager\";\nimport { BunnyAgentLanguageModel } from \"./bunny-agent-language-model\";\nimport { getProviderLogger } from \"./logging\";\nimport type { BunnyAgentModelId, BunnyAgentProviderSettings } from \"./types\";\n\nexport type { BunnyAgentProviderSettings } from \"./types\";\n\n/**\n * BunnyAgent provider interface that extends the AI SDK's ProviderV3.\n */\nexport interface BunnyAgentProvider extends ProviderV3 {\n (\n modelId: BunnyAgentModelId,\n options?: Partial<BunnyAgentProviderSettings>,\n ): LanguageModelV3;\n\n languageModel(\n modelId: BunnyAgentModelId,\n options?: Partial<BunnyAgentProviderSettings>,\n ): LanguageModelV3;\n\n chat(\n modelId: BunnyAgentModelId,\n options?: Partial<BunnyAgentProviderSettings>,\n ): LanguageModelV3;\n\n embeddingModel(modelId: string): EmbeddingModelV3;\n textEmbeddingModel(modelId: string): EmbeddingModelV3;\n imageModel(modelId: string): ImageModelV3;\n}\n\n/**\n * Creates a BunnyAgent provider instance with the specified configuration.\n *\n * @example\n * ```typescript\n * import { createBunnyAgent } from '@bunny-agent/sdk';\n * import { E2BSandbox } from '@bunny-agent/sandbox-e2b';\n * import { generateText } from 'ai';\n *\n * const bunnyAgent = createBunnyAgent({\n * sandbox: new E2BSandbox({ apiKey: process.env.E2B_API_KEY! }),\n * env: {\n * ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,\n * },\n * });\n *\n * const { text } = await generateText({\n * model: bunnyAgent('sonnet'),\n * prompt: 'Create a hello world program',\n * });\n * ```\n */\nexport function createBunnyAgent(\n defaultOptions: BunnyAgentProviderSettings,\n): BunnyAgentProvider {\n const logger = getProviderLogger(defaultOptions);\n\n if (!defaultOptions.sandbox) {\n throw new Error(\n \"Provide a `sandbox` adapter (e.g. E2BSandbox, LocalSandbox). \" +\n \"Optional `daemonUrl` uses in-sandbox HTTP to bunny-agent-daemon (no automatic `/healthz` probe). Use `isBunnyAgentDaemonHealthy` from `@bunny-agent/sdk` if you want to probe and omit `daemonUrl` for CLI fallback. Omit `daemonUrl` to always use CLI.\",\n );\n }\n\n const createModel = (\n modelId: BunnyAgentModelId,\n options: Partial<BunnyAgentProviderSettings> = {},\n ): LanguageModelV3 => {\n const mergedSkillPaths =\n options.skillPaths !== undefined\n ? options.skillPaths\n : defaultOptions.skillPaths;\n\n const mergedAllowedTools =\n options.allowedTools !== undefined\n ? options.allowedTools\n : defaultOptions.allowedTools;\n\n const runner: RunnerSpec = {\n model: modelId,\n runnerType: options.runnerType ?? defaultOptions.runnerType,\n outputFormat: \"stream\",\n maxTurns: options.maxTurns ?? defaultOptions.maxTurns,\n ...((options.systemPrompt ?? defaultOptions.systemPrompt)\n ? { systemPrompt: options.systemPrompt ?? defaultOptions.systemPrompt }\n : {}),\n ...(mergedSkillPaths && mergedSkillPaths.length > 0\n ? { skillPaths: mergedSkillPaths }\n : {}),\n ...(mergedAllowedTools !== undefined\n ? { allowedTools: mergedAllowedTools }\n : {}),\n };\n\n const mergedOptions = {\n ...defaultOptions,\n ...options,\n runner,\n env: {\n ...defaultOptions.env,\n ...options.env,\n },\n artifactProcessors: [\n ...(defaultOptions.artifactProcessors ?? []),\n ...(options.artifactProcessors ?? []),\n ],\n toolRefs:\n options.toolRefs !== undefined\n ? options.toolRefs\n : defaultOptions.toolRefs,\n } as BunnyAgentProviderSettings & { runner: RunnerSpec };\n\n logger.debug(\n `[bunny-agent] Creating model: ${modelId}${runner.runnerType ? ` (runnerType: ${runner.runnerType})` : \"\"}${runner.skillPaths?.length ? ` skillPaths=${runner.skillPaths.length}` : \"\"}`,\n );\n\n return new BunnyAgentLanguageModel({\n id: modelId,\n options: mergedOptions,\n });\n };\n\n const provider = function (\n modelId: BunnyAgentModelId,\n options?: Partial<BunnyAgentProviderSettings>,\n ) {\n if (new.target) {\n throw new Error(\n \"The BunnyAgent model function cannot be called with the new keyword.\",\n );\n }\n\n return createModel(modelId, options);\n };\n\n provider.languageModel = createModel;\n provider.chat = createModel;\n provider.specificationVersion = \"v3\" as const;\n\n provider.embeddingModel = (modelId: string): EmbeddingModelV3 => {\n throw new NoSuchModelError({\n modelId,\n modelType: \"embeddingModel\",\n });\n };\n\n provider.textEmbeddingModel = (modelId: string): EmbeddingModelV3 => {\n throw new NoSuchModelError({\n modelId,\n modelType: \"embeddingModel\",\n });\n };\n\n provider.imageModel = (modelId: string): ImageModelV3 => {\n throw new NoSuchModelError({\n modelId,\n modelType: \"imageModel\",\n });\n };\n\n return provider as BunnyAgentProvider;\n}\n","import type { SandboxAdapter } from \"@bunny-agent/manager\";\nimport type { SubmitAnswerParams } from \"./types\";\n\n/**\n * Options for submitAnswer\n */\nexport interface SubmitAnswerOptions {\n /**\n * Optional base path prefix for approval files\n * @default \".bunny-agent/approvals\"\n */\n basePath?: string;\n}\n\n/**\n * Submit user's answer for an AskUserQuestion tool call.\n * Writes the answer file to `.bunny-agent/approvals/{toolCallId}.json` in the sandbox workdir.\n *\n * @example\n * ```typescript\n * import { submitAnswer } from \"@bunny-agent/sdk\";\n *\n * await submitAnswer(sandbox, {\n * toolCallId: \"tool-456\",\n * questions: [...],\n * answers: { \"Question 1\": \"Answer 1\" },\n * });\n * ```\n */\nexport async function submitAnswer(\n sandbox: SandboxAdapter,\n params: SubmitAnswerParams,\n options?: SubmitAnswerOptions,\n): Promise<void> {\n const { toolCallId, questions, answers } = params;\n const basePath = options?.basePath ?? \".bunny-agent/approvals\";\n\n const allAnswered = questions.every(\n (q) => answers[q.question] !== undefined && answers[q.question] !== \"\",\n );\n\n const answerData = {\n questions,\n answers,\n status: allAnswered ? \"completed\" : \"pending\",\n timestamp: new Date().toISOString(),\n };\n\n const filename = `${toolCallId}.json`;\n const handle = sandbox.getHandle() ?? (await sandbox.attach());\n // Absolute path so remote sandboxes (Sandock) write to the same path the runner reads (/workspace/.bunny-agent/approvals).\n const workdir = handle.getWorkdir();\n const targetDir = workdir\n ? `${workdir.replace(/\\/$/, \"\")}/${basePath}`\n : basePath;\n\n await handle.upload(\n [{ path: filename, content: JSON.stringify(answerData, null, 2) }],\n targetDir,\n );\n\n console.log(\n `[submitAnswer] Answer submitted: ${targetDir}/${filename} (status: ${answerData.status}, workdir: ${workdir ?? \"(none)\"})`,\n );\n}\n"],"mappings":";AA6BA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACpBP;AAAA,EACE;AAAA,EAIA;AAAA,OAEK;;;AClBA,SAAS,kBACd,UACQ;AACR,MAAI,SAAS,WAAW,OAAO;AAC7B,WAAO;AAAA,MACL,OAAO,MAAM;AAAA,MAAC;AAAA,MACd,MAAM,MAAM;AAAA,MAAC;AAAA,MACb,MAAM,MAAM;AAAA,MAAC;AAAA,MACb,OAAO,MAAM;AAAA,MAAC;AAAA,IAChB;AAAA,EACF;AAEA,MAAI,SAAS,QAAQ;AACnB,WAAO,SAAS;AAAA,EAClB;AAEA,QAAM,YAAY,SAAS,WAAW;AACtC,SAAO;AAAA,IACL,OAAO,CAAC,QAAQ,aAAa,QAAQ,MAAM,GAAG;AAAA,IAC9C,MAAM,CAAC,QAAQ,aAAa,QAAQ,KAAK,GAAG;AAAA,IAC5C,MAAM,CAAC,QAAQ,QAAQ,KAAK,GAAG;AAAA,IAC/B,OAAO,CAAC,QAAQ,QAAQ,MAAM,GAAG;AAAA,EACnC;AACF;;;ACjBA,IAAM,6BAA6B;AAmB5B,SAAS,cACd,OAMyB;AACzB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa,MAAM;AAAA,IACnB,OAAO,MAAM;AAAA,IACb,iBAAiB,yBAAyB,MAAM,iBAAiB;AAAA,MAC/D,SAAS;AAAA,QACP,MAAM;AAAA,QACN,KAAK,MAAM,SAAS;AAAA,QACpB,GAAI,MAAM,SAAS,UAAU,EAAE,SAAS,MAAM,SAAS,QAAQ,IAAI,CAAC;AAAA,MACtE;AAAA,IACF,CAAC;AAAA,IACD,aAAa,MAAM;AAAA,IACnB,eAAe,MAAM;AAAA,IACrB,eAAe,MAAM;AAAA,IACrB,QAAQ,MAAM;AAAA,IACd,cAAc,MAAM;AAAA,IACpB,cAAc,MAAM;AAAA,IACpB,kBAAkB,MAAM;AAAA,IACxB,MAAM,UAAU;AACd,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAMO,SAAS,iBACd,OAIyB;AACzB,SAAO;AAAA,IACL,MAAM;AAAA,IACN,aAAa,MAAM;AAAA,IACnB,OAAO,MAAM;AAAA,IACb,iBAAiB,yBAAyB,MAAM,iBAAiB;AAAA,MAC/D,SAAS;AAAA,QACP,MAAM;AAAA,QACN,QAAQ,MAAM;AAAA,QACd,GAAI,MAAM,aAAa,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,MAC7D;AAAA,IACF,CAAC;AAAA,IACD,aAAa,MAAM;AAAA,IACnB,eAAe,MAAM;AAAA,IACrB,eAAe,MAAM;AAAA,IACrB,QAAQ,MAAM;AAAA,IACd,cAAc,MAAM;AAAA,IACpB,cAAc,MAAM;AAAA,IACpB,kBAAkB,MAAM;AAAA,IACxB,MAAM,UAAU;AACd,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,SAAS,sCACd,OAGuB;AACvB,MAAI,CAAC,SAAS,MAAM,WAAW,EAAG,QAAO;AAEzC,QAAM,WAAsB,CAAC;AAE7B,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,SAAS,YAAY;AAC5B;AAAA,IACF;AAEA,UAAM,UAAU,gBAAgB,IAAI;AACpC,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR,uBAAuB,KAAK,IAAI;AAAA,MAGlC;AAAA,IACF;AAEA,aAAS,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,aAAa,KAAK,eAAe;AAAA,MACjC,aAAa,KAAK;AAAA,MAClB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO,SAAS,SAAS,IAAI,WAAW;AAC1C;AAEA,SAAS,gBACP,MAC8B;AAC9B,QAAM,UAAU,KAAK,kBAAkB,0BAA0B;AAGjE,QAAM,UAAU,SAAS;AACzB,MAAI,CAAC,SAAS,OAAO,KAAK,OAAO,QAAQ,SAAS,UAAU;AAC1D,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,SAAS,UAAU,OAAO,QAAQ,QAAQ,UAAU;AAC9D,WAAO;AAAA,MACL,MAAM;AAAA,MACN,KAAK,QAAQ;AAAA,MACb,GAAI,eAAe,QAAQ,OAAO,IAAI,EAAE,SAAS,QAAQ,QAAQ,IAAI,CAAC;AAAA,IACxE;AAAA,EACF;AACA,MAAI,QAAQ,SAAS,YAAY,OAAO,QAAQ,WAAW,UAAU;AACnE,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,QAAQ;AAAA,MAChB,GAAI,OAAO,QAAQ,eAAe,WAC9B,EAAE,YAAY,QAAQ,WAAW,IACjC,CAAC;AAAA,IACP;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,yBACP,iBACA,cACyB;AACzB,SAAO;AAAA,IACL,GAAI,mBAAmB,CAAC;AAAA,IACxB,CAAC,0BAA0B,GAAG;AAAA,MAC5B,GAAK,kBAAkB,0BAA0B,KAE/B,CAAC;AAAA,MACnB,GAAG;AAAA,IACL;AAAA,EACF;AACF;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,eAAe,OAAiD;AACvE,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,SAAO,OAAO,OAAO,KAAK,EAAE,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ;AACxE;;;ACnLA,SAAS,SAAS,OAAwC;AACxD,MAAI,SAAS,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AACtE,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKO,SAAS,sBACd,kBACwB;AACxB,QAAM,eAAe,SAAS,gBAAgB;AAC9C,MAAI,gBAAgB,KAAM,QAAO;AACjC,SAAO,SAAS,aAAa,aAAa,CAAC;AAC7C;AAQO,SAAS,mBACd,kBACkC;AAClC,QAAM,YAAY,sBAAsB,gBAAgB;AACxD,MAAI,aAAa,KAAM,QAAO;AAC9B,SAAO,yBAAyB,SAAS;AAC3C;AAWO,SAAS,yBACd,MACkC;AAClC,QAAM,aAAa,SAAS,IAAI;AAChC,MAAI,cAAc,KAAM,QAAO;AAE/B,QAAM,cAAc,SAAS,WAAW,SAAS,UAAU;AAC3D,MAAI,eAAe,KAAM,QAAO;AAChC,QAAM,iBACJ,kBAAkB,eAClB,mBAAmB,eACnB,6BAA6B,eAC7B,iCAAiC;AACnC,MAAI,CAAC,eAAgB,QAAO;AAE5B,QAAM,cACJ,OAAO,YAAY,iBAAiB,WAAW,YAAY,eAAe;AAC5E,QAAM,eACJ,OAAO,YAAY,kBAAkB,WACjC,YAAY,gBACZ;AACN,QAAM,YACJ,OAAO,YAAY,4BAA4B,WAC3C,YAAY,0BACZ;AACN,QAAM,aACJ,OAAO,YAAY,gCAAgC,WAC/C,YAAY,8BACZ;AACN,QAAM,aACJ,OAAO,YAAY,gBAAgB,WAC/B,YAAY,cACZ;AACN,QAAM,kBACJ,OAAO,YAAY,qBAAqB,WACpC,YAAY,mBACZ;AACN,QAAM,gBAAgB,OAAO;AAAA,IAC3B,OAAO,QAAQ,UAAU,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,QAAQ,OAAO;AAAA,EAC9D;AACA,QAAM,MACJ,OAAO,KAAK,aAAa,EAAE,SAAS,IAChC,EAAE,GAAG,aAAa,GAAG,cAAc,IACnC;AAEN,SAAO;AAAA,IACL,aAAa;AAAA,MACX,OAAO,cAAc,YAAY;AAAA,MACjC,SAAS;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACA,cAAc;AAAA,MACZ,OAAO;AAAA,MACP,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,IACA;AAAA,EACF;AACF;;;AHhEA,SAAS,kBAAkB,OAAwB;AACjD,MAAI,iBAAiB,OAAO;AAC1B,UAAM,QAAQ,CAAC,MAAM,OAAO;AAC5B,QAAI,QAAiB,MAAM;AAC3B,WAAO,iBAAiB,OAAO;AAC7B,YAAM,KAAK,MAAM,OAAO;AACxB,cAAQ,MAAM;AAAA,IAChB;AACA,WAAO,MAAM,KAAK,YAAY;AAAA,EAChC;AACA,SAAO,OAAO,KAAK;AACrB;AAGA,SAAS,8BACP,UAC4B;AAC5B,QAAM,WAAW,SAAS,OAAO,aAAa,EAAE;AAChD,SAAO,IAAI,eAA2B;AAAA,IACpC,MAAM,KAAK,YAAY;AACrB,UAAI;AACF,eAAO,MAAM;AACX,gBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,SAAS,KAAK;AAC5C,cAAI,MAAM;AACR,uBAAW,MAAM;AACjB;AAAA,UACF;AACA,cAAI,MAAM,aAAa,GAAG;AACxB,uBAAW,QAAQ,KAAK;AACxB;AAAA,UACF;AAAA,QACF;AAAA,MACF,SAAS,OAAO;AACd,cAAM,UACH,iBAAiB,SAAS,MAAM,SAAS,gBACzC,OAAO,iBAAiB,eACvB,iBAAiB,gBACjB,MAAM,SAAS,gBAChB,iBAAiB,SAAS,SAAS,KAAK,MAAM,OAAO;AACxD,YAAI,SAAS;AACX,qBAAW,MAAM;AAAA,QACnB,OAAO;AACL,qBAAW,MAAM,KAAK;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,OAAO,QAAQ;AACnB,YAAM,SAAS,SAAS,MAAM;AAAA,IAChC;AAAA,EACF,CAAC;AACH;AAEA,SAAS,cACP,gBACA,cACuB;AACvB,QAAM,SAAS,CAAC,GAAI,kBAAkB,CAAC,GAAI,GAAI,gBAAgB,CAAC,CAAE;AAClE,SAAO,OAAO,SAAS,IAAI,SAAS;AACtC;AAEA,SAAS,4BAA4B,UAA6B;AAChE,QAAM,WAAW,CAAC,GAAG,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AACtE,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,IAAI,SAAS;AACnB,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,SAAO,EACJ,OAAO,CAAC,MAA2C,EAAE,SAAS,MAAM,EACpE,IAAI,CAAC,MAAM,EAAE,IAAI,EACjB,KAAK,IAAI;AACd;AAEA,SAAS,mBAAyC;AAChD,SAAO;AAAA,IACL,aAAa;AAAA,MACX,OAAO;AAAA,MACP,SAAS;AAAA,MACT,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,IACA,cAAc;AAAA,MACZ,OAAO;AAAA,MACP,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AAAA,IACA,KAAK;AAAA,EACP;AACF;AAEA,SAAS,oBAAoB,QAA0C;AACrE,MAAI,OAAO,OAAO,YAAY,WAAW;AACvC,WAAO,OAAO;AAAA,EAChB;AACA,SAAO,OAAO,qBAAqB;AACrC;AAKO,IAAM,0BAAN,MAAyD;AAAA,EACrD,uBAAuB;AAAA,EACvB;AAAA,EACA;AAAA,EACA,gBAA0C;AAAA,IACjD,WAAW,CAAC,IAAI;AAAA,EAClB;AAAA,EAES;AAAA,EACQ;AAAA,EACA;AAAA,EACT;AAAA,EACA,cAAmC,oBAAI,IAAI;AAAA,EAC3C,wBAAwB;AAAA,EAExB,sBAAsB,WAAmB,OAAsB;AACrE,UAAM,UAAU,UAAU,KAAK;AAC/B,QAAI,CAAC,QAAS;AACd,UAAM,iBAAiB,gDAAgD;AAAA,MACrE;AAAA,IACF;AACA,QAAI,gBAAgB;AAClB,YAAM,UAAU,QAAQ,MAAM,GAAG,GAAG;AACpC,YAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,WAAK,OAAO;AAAA,QACV,6DAA6D,OAAO,cAAc,GAAG;AAAA,MACvF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY,cAA8C;AACxD,SAAK,UAAU,aAAa;AAC5B,SAAK,WAAW,aAAa;AAC7B,SAAK,UAAU,aAAa;AAC5B,SAAK,SAAS,kBAAkB,aAAa,OAAO;AACpD,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,MAAM,WACJ,SACwC;AACxC,UAAM,EAAE,QAAQ,QAAQ,IAAI,MAAM,KAAK,SAAS,OAAO;AACvD,UAAM,SAAS,OAAO,UAAU;AAEhC,UAAM,UAAoC,CAAC;AAC3C,UAAM,WAA8B,CAAC;AACrC,QAAI,eAA4C;AAAA,MAC9C,SAAS;AAAA,MACT,KAAK;AAAA,IACP;AACA,QAAI,QAA8B,iBAAiB;AACnD,QAAI;AAEJ,UAAM,YAA2C,oBAAI,IAAI;AACzD,UAAM,aACJ,oBAAI,IAAI;AAEV,QAAI;AACF,aAAO,MAAM;AACX,cAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,YAAI,KAAM;AAEV,gBAAQ,MAAM,MAAM;AAAA,UAClB,KAAK,cAAc;AACjB,sBAAU,IAAI,MAAM,IAAI,EAAE,MAAM,GAAG,CAAC;AACpC;AAAA,UACF;AAAA,UACA,KAAK,cAAc;AACjB,kBAAM,OAAO,UAAU,IAAI,MAAM,EAAE;AACnC,gBAAI,MAAM;AACR,mBAAK,QAAQ,MAAM;AAAA,YACrB;AACA;AAAA,UACF;AAAA,UACA,KAAK,YAAY;AACf,kBAAM,OAAO,UAAU,IAAI,MAAM,EAAE;AACnC,gBAAI,MAAM;AACR,sBAAQ,KAAK;AAAA,gBACX,MAAM;AAAA,gBACN,MAAM,KAAK;AAAA,cACb,CAAC;AAAA,YACH;AACA;AAAA,UACF;AAAA,UACA,KAAK,oBAAoB;AACvB,uBAAW,IAAI,MAAM,IAAI,EAAE,UAAU,MAAM,UAAU,OAAO,GAAG,CAAC;AAChE;AAAA,UACF;AAAA,UACA,KAAK,oBAAoB;AACvB,kBAAM,OAAO,WAAW,IAAI,MAAM,EAAE;AACpC,gBAAI,MAAM;AACR,mBAAK,SAAS,MAAM;AAAA,YACtB;AACA;AAAA,UACF;AAAA,UACA,KAAK,kBAAkB;AACrB;AAAA,UACF;AAAA,UACA,KAAK,aAAa;AAChB,oBAAQ,KAAK;AAAA,cACX,MAAM;AAAA,cACN,YAAY,MAAM;AAAA,cAClB,UAAU,MAAM;AAAA,cAChB,OAAO,MAAM;AAAA,cACb,kBAAkB,MAAM;AAAA,YAC1B,CAAC;AACD;AAAA,UACF;AAAA,UACA,KAAK,gBAAgB;AACnB,qBAAS,KAAK,GAAG,MAAM,QAAQ;AAC/B;AAAA,UACF;AAAA,UACA,KAAK,SAAS;AAGZ,kBAAM,UACJ,MAAM,iBAAiB,QACnB,MAAM,MAAM,UACZ,OAAO,MAAM,UAAU,WACrB,MAAM,QACN,MAAM,QACJ,OAAO,MAAM,KAAK,IAClB;AAGV,oBAAQ,KAAK,EAAE,MAAM,QAAQ,MAAM,QAAQ,CAAC;AAC5C,2BAAe,EAAE,SAAS,SAAS,KAAK,QAAQ;AAChD;AAAA,UACF;AAAA,UACA,KAAK,UAAU;AACb,2BAAe,MAAM;AACrB,oBAAQ,MAAM;AACd,+BAAmB,MAAM;AACzB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,UAAE;AACA,aAAO,YAAY;AAAA,IACrB;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,SACJ,SACsC;AACtC,UAAM,EAAE,QAAQ,YAAY,IAAI;AAChC,UAAM,WAAW,KAAK,wBAAwB,MAAM;AAEpD,SAAK,iBAAiB;AAEtB,SAAK,OAAO;AAAA,MACV,sCAAsC,SAAS,MAAM;AAAA,IACvD;AAEA,UAAM,UAAU,KAAK,QAAQ;AAC7B,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW;AAAA,MACf,KAAK,QAAQ;AAAA,MACb,sCAAsC,QAAQ,KAAK;AAAA,IACrD;AAEA,UAAM,YAAY,KAAK,QAAQ;AAE/B,QAAI,WAAW;AACb,YAAM,SAAS,MAAM,QAAQ,OAAO;AACpC,YAAMA,cAAa,QAAQ,SAAS,KAAK,CAAC;AAC1C,YAAM,YAAY,EAAE,GAAGA,aAAY,GAAG,KAAK,QAAQ,IAAI;AACvD,YAAM,OAAgC;AAAA,QACpC,GAAG,KAAK,mBAAmB,UAAU,OAAO,WAAW,GAAG,QAAQ;AAAA,QAClE,GAAI,OAAO,KAAK,SAAS,EAAE,SAAS,IAAI,EAAE,KAAK,UAAU,IAAI,CAAC;AAAA,MAChE;AACA,YAAM,WAAW;AAAA,QACf,KAAK,KAAK,QAAQ,OAAO,OAAO,WAAW;AAAA,QAC3C,QAAQ;AAAA,MACV;AACA,YAAM,WAAW;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,cAAc,8BAA8B,QAAQ;AAC1D,aAAO,KAAK,kBAAkB,aAAa,QAAQ;AAAA,IACrD;AAEA,UAAM,aAAa,QAAQ,SAAS,KAAK,CAAC;AAC1C,UAAM,iBACJ,KAAK,QAAQ,OAAO,QAAQ,aAAa,KAAK;AAEhD,UAAM,QAAQ,IAAI,WAAW;AAAA,MAC3B;AAAA,MACA,QAAQ,KAAK,QAAQ;AAAA,MACrB,KAAK,EAAE,GAAG,YAAY,GAAG,KAAK,QAAQ,IAAI;AAAA,IAC5C,CAAC;AAED,QAAI;AACF,YAAM,cAAc,MAAM,MAAM,OAAO;AAAA,QACrC;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,QACR;AAAA,QACA,QAAQ,KAAK,QAAQ;AAAA,QACrB,QAAQ;AAAA,QACR,GAAI,YAAY,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,MACxD,CAAC;AACD,aAAO,KAAK,kBAAkB,aAAa,QAAQ;AAAA,IACrD,SAAS,OAAO;AACd,YAAM,MAAM,QAAQ,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AACpC,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEQ,mBAAyB;AAC/B,SAAK,YAAY;AACjB,SAAK,cAAc,oBAAI,IAAI;AAC3B,SAAK,wBAAwB;AAAA,EAC/B;AAAA,EAEQ,mBACN,UACA,aACA,UACyB;AACzB,UAAM,SAAS,KAAK,QAAQ;AAC5B,UAAM,MAAM,KAAK,QAAQ,OAAO;AAEhC,WAAO;AAAA,MACL,QAAQ,OAAO,cAAc;AAAA,MAC7B,OAAO,KAAK;AAAA,MACZ,WAAW,4BAA4B,QAAQ;AAAA,MAC/C;AAAA,MACA,QAAQ,KAAK,QAAQ;AAAA,MACrB,cAAc,KAAK,QAAQ,gBAAgB,OAAO;AAAA,MAClD,UAAU,KAAK,QAAQ,YAAY,OAAO;AAAA,MAC1C,cAAc,OAAO,gBAAgB,KAAK,QAAQ;AAAA,MAClD,YAAY,OAAO,cAAc,KAAK,QAAQ;AAAA,MAC9C,MAAM,KAAK,QAAQ;AAAA,MACnB,GAAI,YAAY,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;AAAA,IACxD;AAAA,EACF;AAAA,EAEQ,kBACN,aACA,UAC6B;AAC7B,UAAM,SAAS,YAAY,UAAU;AAErC,WAAO;AAAA,MACL,QAAQ,KAAK,uCAAuC,MAAM;AAAA,MAC1D,SAAS;AAAA,QACP,MAAM,KAAK,UAAU,EAAE,SAAS,CAAC;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,uCACN,QAC2C;AAC3C,UAAM,OAAO;AAEb,WAAO,IAAI,eAA0C;AAAA,MACnD,MAAM,MAAM,YAAY;AACtB,YAAI;AACF,cAAI,SAAS;AAEb,iBAAO,MAAM;AACX,kBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAE1C,gBAAI,MAAM;AACR,kBAAI,OAAO,KAAK,GAAG;AACjB,sBAAM,QAAQ,KAAK,eAAe,MAAM;AACxC,2BAAW,QAAQ,OAAO;AACxB,6BAAW,QAAQ,IAAI;AAAA,gBACzB;AAAA,cACF;AACA,yBAAW,MAAM;AACjB;AAAA,YACF;AAEA,kBAAM,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAC3C,sBAAU;AAEV,kBAAM,QAAQ,OAAO,MAAM,IAAI;AAC/B,qBAAS,MAAM,IAAI,KAAK;AAExB,gBAAI,YAAY;AAChB,uBAAW,QAAQ,OAAO;AACxB,oBAAM,YAAY,KAAK,WAAW,QAAQ,IACtC,KAAK,MAAM,CAAC,IACZ,KAAK,KAAK;AACd,kBAAI,CAAC,UAAW;AAChB,kBAAI,cAAc,UAAU;AAC1B,4BAAY;AACZ;AAAA,cACF;AAEA,kBAAI;AACF,sBAAM,QAAQ,KAAK,aAAa,SAAS;AACzC,2BAAW,QAAQ,OAAO;AACxB,6BAAW,QAAQ,IAAI;AAEvB,sBAAI,KAAK,WAAW;AAClB,0BAAM,YAAoB,KAAK;AAE/B,wBAAI,KAAK,QAAQ,oBAAoB,QAAQ;AAC3C,iCAAW,aAAa,KAAK,QAAQ,oBAAoB;AACvD,gCAAQ,QAAQ,EACb,KAAK,MAAM,UAAU,SAAS,MAAM,SAAS,CAAC,EAC9C,MAAM,CAAC,MAAM;AACZ,+BAAK,OAAO;AAAA,4BACV,2CAA2C,CAAC;AAAA,0BAC9C;AAAA,wBACF,CAAC;AAAA,sBACL;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF;AAAA,cACF,SAAS,GAAG;AAEV,qBAAK,sBAAsB,WAAW,CAAC;AAAA,cACzC;AAAA,YACF;AAEA,gBAAI,WAAW;AACb,yBAAW,MAAM;AACjB;AAAA,YACF;AAAA,UACF;AAAA,QACF,SAAS,OAAO;AACd,gBAAM,UACH,iBAAiB,SAAS,MAAM,SAAS,gBACzC,OAAO,iBAAiB,eACvB,iBAAiB,gBACjB,MAAM,SAAS,gBAChB,iBAAiB,SAAS,SAAS,KAAK,MAAM,OAAO;AACxD,cAAI,SAAS;AACX,iBAAK,OAAO,KAAK,sCAAsC;AACvD,uBAAW,MAAM;AAAA,UACnB,OAAO;AACL,iBAAK,OAAO;AAAA,cACV,+BAA+B,kBAAkB,KAAK,CAAC;AAAA,YACzD;AACA,uBAAW,MAAM,KAAK;AAAA,UACxB;AAAA,QACF;AAAA,MACF;AAAA,MAEA,SAAS;AACP,eAAO,OAAO;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,eAAe,QAA6C;AAClE,UAAM,QAAqC,CAAC;AAC5C,UAAM,QAAQ,OAAO,MAAM,IAAI;AAE/B,eAAW,QAAQ,OAAO;AACxB,YAAM,YAAY,KAAK,WAAW,QAAQ,IAAI,KAAK,MAAM,CAAC,IAAI,KAAK,KAAK;AACxE,UAAI,CAAC,aAAa,cAAc,SAAU;AAC1C,UAAI;AACF,cAAM,cAAc,KAAK,aAAa,SAAS;AAC/C,cAAM,KAAK,GAAG,WAAW;AAAA,MAC3B,SAAS,GAAG;AACV,aAAK,sBAAsB,WAAW,CAAC;AAAA,MACzC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,aAAa,MAA2C;AAC9D,UAAM,QAAqC,CAAC;AAC5C,UAAM,SAAS,KAAK,MAAM,IAAI;AAC9B,UAAM,aACJ,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;AAGlD,QAAI,CAAC,cAAc,OAAO,OAAO,UAAU,UAAU;AACnD,aAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,OAAO,IAAI,MAAM,OAAO,KAAK;AAAA,QAC/B;AAAA,MACF;AAAA,IACF;AAEA,YAAQ,YAAY;AAAA,MAClB,KAAK,SAAS;AACZ;AAAA,MACF;AAAA;AAAA,MAGA,KAAK,QAAQ;AACX,cAAM,OAAO,OAAO,OAAO,SAAS,WAAW,OAAO,OAAO;AAC7D,YAAI,KAAK,SAAS,GAAG;AACnB,gBAAM,KAAK,eAAe,EAAE,KAAK,qBAAqB;AACtD,gBAAM;AAAA,YACJ;AAAA,cACE,MAAM;AAAA,cACN;AAAA,cACA,kBAAkB;AAAA,gBAChB,eAAe;AAAA,kBACb,WAAW,KAAK;AAAA,gBAClB;AAAA,cACF;AAAA,YACF;AAAA,YACA,EAAE,MAAM,cAAc,IAAI,OAAO,KAAK;AAAA,YACtC,EAAE,MAAM,YAAY,GAAG;AAAA,UACzB;AAAA,QACF;AACA;AAAA,MACF;AAAA,MAEA,KAAK,oBAAoB;AACvB,cAAM,WAAW,OAAO;AACxB,YAAI,UAAU,aAAa,OAAO,SAAS,cAAc,UAAU;AACjE,eAAK,YAAY,SAAS;AAC1B,eAAK,OAAO;AAAA,YACV,uCAAuC,KAAK,SAAS;AAAA,UACvD;AACA,gBAAM,KAAK;AAAA,YACT,MAAM;AAAA,YACN,UAAU,KAAK;AAAA,UACjB,CAAC;AAAA,QACH;AACA;AAAA,MACF;AAAA,MAEA,KAAK,cAAc;AACjB,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,OAAO;AAAA,UACX,kBAAkB;AAAA,YAChB,eAAe;AAAA,cACb,WAAW,KAAK;AAAA,YAClB;AAAA,UACF;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,cAAc;AACjB,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,OAAO;AAAA,UACX,OAAO,OAAO;AAAA,QAChB,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,YAAY;AACf,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,OAAO;AAAA,QACb,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,oBAAoB;AACvB,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,OAAO;AAAA,UACX,UAAU,OAAO;AAAA,UACjB,SAAS,oBAAoB,MAAM;AAAA,UACnC,kBAAkB,OAAO;AAAA,QAC3B,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,oBAAoB;AACvB,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,IAAI,OAAO;AAAA,UACX,OAAO,OAAO;AAAA,QAChB,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,wBAAwB;AAC3B,cAAM,aAAa,OAAO;AAC1B,cAAM,WAAW,OAAO;AACxB,cAAM,QAAQ,OAAO;AACrB,aAAK,YAAY,IAAI,YAAY,QAAQ;AACzC,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,OAAO,KAAK,UAAU,KAAK;AAAA,UAC3B,SAAS,oBAAoB,MAAM;AAAA,UACnC,kBAAkB,OAAO;AAAA,QAC3B,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,yBAAyB;AAC5B,cAAM,WAAW,KAAK,YAAY,IAAI,OAAO,UAAoB;AACjE,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,YAAY,OAAO;AAAA,UACnB,UAAU,YAAY;AAAA,UACtB,QAAQ,OAAO;AAAA,UACf,SAAS,OAAO;AAAA,UAChB,SAAS,oBAAoB,MAAM;AAAA,QACrC,CAAC;AACD;AAAA,MACF;AAAA,MACA,KAAK,SAAS;AACZ,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN,OAAO,IAAI;AAAA,YACR,OAAO,aACL,OAAO,SACR;AAAA,UACJ;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAAA,MAEA,KAAK,UAAU;AACb,cAAM,kBAAkB,OAAO;AAC/B,YAAI;AAEJ,YACE,OAAO,oBAAoB,YAC3B,oBAAoB,QACpB,aAAa,iBACb;AACA,yBAAe;AAAA,QACjB,OAAO;AACL,yBAAe,KAAK,gBAAgB,eAAyB;AAAA,QAC/D;AAEA,cAAM,QACJ;AAAA,UACG,OAAO,mBAA+C;AAAA,QACzD,KAAK,iBAAiB;AAExB,cAAM,KAAK;AAAA,UACT,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,kBAAkB;AAAA,YAChB,eAAe;AAAA,cACb,GAAK,OAAO,mBAA+C,CAAC;AAAA,cAC5D,WAAW,KAAK;AAAA,YAClB;AAAA,UACF;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,wBAAwB,QAA0C;AACxE,UAAM,WAAsB,CAAC;AAE7B,eAAW,WAAW,QAAQ;AAC5B,cAAQ,QAAQ,MAAM;AAAA,QACpB,KAAK,UAAU;AACb,mBAAS,KAAK;AAAA,YACZ,MAAM;AAAA,YACN,SAAS,QAAQ;AAAA,UACnB,CAAC;AACD;AAAA,QACF;AAAA,QAEA,KAAK,QAAQ;AACX,gBAAM,QAAQ,QAAQ,QACnB,IAAI,CAAC,SAAS;AACb,gBAAI,KAAK,SAAS,QAAQ;AACxB,qBAAO,EAAE,MAAM,QAAiB,MAAM,KAAK,KAAK;AAAA,YAClD;AACA,gBAAI,KAAK,SAAS,QAAQ;AAExB,kBAAI,UAAU;AACd,kBAAI,KAAK,gBAAgB,YAAY;AACnC,0BAAU,QAAQ,KAAK,SAAS,WAAW,OAAO,KAAK,KAAK,IAAI,EAAE,SAAS,QAAQ,CAAC;AAAA,cACtF,WAAW,KAAK,gBAAgB,KAAK;AACnC,0BAAU,KAAK,KAAK,SAAS;AAAA,cAC/B,WAAW,OAAO,KAAK,SAAS,UAAU;AAExC,0BAAU,KAAK;AAAA,cACjB;AACA,qBAAO;AAAA,gBACL,MAAM;AAAA,gBACN,UAAU,KAAK,aAAa;AAAA,gBAC5B,MAAM;AAAA,cACR;AAAA,YACF;AACA,mBAAO;AAAA,UACT,CAAC,EACA;AAAA,YACC,CACE,MAIA,MAAM;AAAA,UACV;AAEF,cAAI,MAAM,SAAS,GAAG;AAEpB,kBAAM,YAAY,MAAM,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM;AACtD,qBAAS,KAAK;AAAA,cACZ,MAAM;AAAA,cACN,SAAS,YACL,MACG,IAAI,CAAC,MAAO,EAAqC,IAAI,EACrD,KAAK,IAAI,IACZ;AAAA,YACN,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAAA,QAEA,KAAK,aAAa;AAChB,gBAAM,YAAY,QAAQ,QACvB;AAAA,YACC,CAAC,SACC,KAAK,SAAS;AAAA,UAClB,EACC,IAAI,CAAC,SAAS,KAAK,IAAI;AAE1B,cAAI,UAAU,SAAS,GAAG;AACxB,qBAAS,KAAK;AAAA,cACZ,MAAM;AAAA,cACN,SAAS,UAAU,KAAK,IAAI;AAAA,YAC9B,CAAC;AAAA,UACH;AACA;AAAA,QACF;AAAA,QAEA,KAAK,QAAQ;AACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,gBACN,QAC6B;AAC7B,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO,EAAE,SAAS,QAAQ,KAAK,OAAO;AAAA,MACxC,KAAK;AACH,eAAO,EAAE,SAAS,UAAU,KAAK,OAAO;AAAA,MAC1C,KAAK;AAAA,MACL,KAAK;AACH,eAAO,EAAE,SAAS,cAAc,KAAK,OAAO;AAAA,MAC9C,KAAK;AAAA,MACL,KAAK;AACH,eAAO,EAAE,SAAS,kBAAkB,KAAK,OAAO;AAAA,MAClD,KAAK;AACH,eAAO,EAAE,SAAS,SAAS,KAAK,OAAO;AAAA,MACzC;AACE,eAAO,EAAE,SAAS,SAAS,KAAK,UAAU,UAAU;AAAA,IACxD;AAAA,EACF;AACF;;;AIzyBA,SAAS,wBAAwB;AAsD1B,SAAS,iBACd,gBACoB;AACpB,QAAM,SAAS,kBAAkB,cAAc;AAE/C,MAAI,CAAC,eAAe,SAAS;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IAEF;AAAA,EACF;AAEA,QAAM,cAAc,CAClB,SACA,UAA+C,CAAC,MAC5B;AACpB,UAAM,mBACJ,QAAQ,eAAe,SACnB,QAAQ,aACR,eAAe;AAErB,UAAM,qBACJ,QAAQ,iBAAiB,SACrB,QAAQ,eACR,eAAe;AAErB,UAAM,SAAqB;AAAA,MACzB,OAAO;AAAA,MACP,YAAY,QAAQ,cAAc,eAAe;AAAA,MACjD,cAAc;AAAA,MACd,UAAU,QAAQ,YAAY,eAAe;AAAA,MAC7C,GAAK,QAAQ,gBAAgB,eAAe,eACxC,EAAE,cAAc,QAAQ,gBAAgB,eAAe,aAAa,IACpE,CAAC;AAAA,MACL,GAAI,oBAAoB,iBAAiB,SAAS,IAC9C,EAAE,YAAY,iBAAiB,IAC/B,CAAC;AAAA,MACL,GAAI,uBAAuB,SACvB,EAAE,cAAc,mBAAmB,IACnC,CAAC;AAAA,IACP;AAEA,UAAM,gBAAgB;AAAA,MACpB,GAAG;AAAA,MACH,GAAG;AAAA,MACH;AAAA,MACA,KAAK;AAAA,QACH,GAAG,eAAe;AAAA,QAClB,GAAG,QAAQ;AAAA,MACb;AAAA,MACA,oBAAoB;AAAA,QAClB,GAAI,eAAe,sBAAsB,CAAC;AAAA,QAC1C,GAAI,QAAQ,sBAAsB,CAAC;AAAA,MACrC;AAAA,MACA,UACE,QAAQ,aAAa,SACjB,QAAQ,WACR,eAAe;AAAA,IACvB;AAEA,WAAO;AAAA,MACL,iCAAiC,OAAO,GAAG,OAAO,aAAa,iBAAiB,OAAO,UAAU,MAAM,EAAE,GAAG,OAAO,YAAY,SAAS,eAAe,OAAO,WAAW,MAAM,KAAK,EAAE;AAAA,IACxL;AAEA,WAAO,IAAI,wBAAwB;AAAA,MACjC,IAAI;AAAA,MACJ,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,QAAM,WAAW,SACf,SACA,SACA;AACA,QAAI,YAAY;AACd,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,WAAO,YAAY,SAAS,OAAO;AAAA,EACrC;AAEA,WAAS,gBAAgB;AACzB,WAAS,OAAO;AAChB,WAAS,uBAAuB;AAEhC,WAAS,iBAAiB,CAAC,YAAsC;AAC/D,UAAM,IAAI,iBAAiB;AAAA,MACzB;AAAA,MACA,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,WAAS,qBAAqB,CAAC,YAAsC;AACnE,UAAM,IAAI,iBAAiB;AAAA,MACzB;AAAA,MACA,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,WAAS,aAAa,CAAC,YAAkC;AACvD,UAAM,IAAI,iBAAiB;AAAA,MACzB;AAAA,MACA,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC5IA,eAAsB,aACpB,SACA,QACA,SACe;AACf,QAAM,EAAE,YAAY,WAAW,QAAQ,IAAI;AAC3C,QAAM,WAAW,SAAS,YAAY;AAEtC,QAAM,cAAc,UAAU;AAAA,IAC5B,CAAC,MAAM,QAAQ,EAAE,QAAQ,MAAM,UAAa,QAAQ,EAAE,QAAQ,MAAM;AAAA,EACtE;AAEA,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA,QAAQ,cAAc,cAAc;AAAA,IACpC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,EACpC;AAEA,QAAM,WAAW,GAAG,UAAU;AAC9B,QAAM,SAAS,QAAQ,UAAU,KAAM,MAAM,QAAQ,OAAO;AAE5D,QAAM,UAAU,OAAO,WAAW;AAClC,QAAM,YAAY,UACd,GAAG,QAAQ,QAAQ,OAAO,EAAE,CAAC,IAAI,QAAQ,KACzC;AAEJ,QAAM,OAAO;AAAA,IACX,CAAC,EAAE,MAAM,UAAU,SAAS,KAAK,UAAU,YAAY,MAAM,CAAC,EAAE,CAAC;AAAA,IACjE;AAAA,EACF;AAEA,UAAQ;AAAA,IACN,oCAAoC,SAAS,IAAI,QAAQ,aAAa,WAAW,MAAM,cAAc,WAAW,QAAQ;AAAA,EAC1H;AACF;;;ANGO,IAAM,UAAU;","names":["sandboxEnv"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bunny-agent/sdk",
3
- "version": "0.9.30",
3
+ "version": "0.9.32",
4
4
  "description": "BunnyAgent SDK - AI Provider and React hooks for building AI agents",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -52,7 +52,7 @@
52
52
  "dependencies": {
53
53
  "@ai-sdk/provider": "^3.0.8",
54
54
  "@ai-sdk/react": "^3.0.105",
55
- "@bunny-agent/manager": "0.9.30"
55
+ "@bunny-agent/manager": "0.9.32"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/node": "^20.10.0",