@sandagent/sdk 0.9.9-beta.1 → 0.9.9-beta.3

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/README.md CHANGED
@@ -272,7 +272,7 @@ const model = sandagent("claude-sonnet-4-20250514");
272
272
 
273
273
  #### Daemon HTTP transport (same provider)
274
274
 
275
- **With any sandbox adapter** (E2B, Sandock, `LocalSandbox`, etc.): pass **`sandbox` + `daemonUrl`**. The URL is resolved **inside** the sandbox (the `vikadata/sandagent` image starts `sandagent-daemon` on port 3080). The SDK always streams via `streamCodingRunFromSandbox` (`curl -N` in the sandbox, including `LocalSandbox`), not `fetch` from your server.
275
+ **With any sandbox adapter** (E2B, Sandock, `LocalSandbox`, etc.): pass **`sandbox` + `daemonUrl`**. The URL is resolved **inside** the sandbox (the `vikadata/sandagent` image starts `sandagent-daemon` on port 3080). The SDK streams via `streamCodingRunFromSandbox` (`curl -N` in the sandbox, including `LocalSandbox`), not `fetch` from your server. It does **not** call `/healthz` for you — use `isSandagentDaemonHealthy` from `@sandagent/sdk` when you want a probe before setting `daemonUrl` (e.g. to fall back to the CLI runner).
276
276
 
277
277
  ```typescript
278
278
  import { createSandAgent, DEFAULT_SANDAGENT_DAEMON_URL } from "@sandagent/sdk";
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { SandAgentOptions, SandboxAdapter, RunnerSpec } from '@sandagent/manager';
2
- export { LocalSandbox, LocalSandboxOptions, Message, RunnerEnvParams, RunnerType, SandboxAdapter, SandboxHandle, TranscriptEntry, buildRunnerEnv } from '@sandagent/manager';
2
+ export { IsSandagentDaemonHealthyOptions, LocalSandbox, LocalSandboxOptions, Message, RunnerEnvParams, RunnerType, SandboxAdapter, SandboxHandle, TranscriptEntry, buildRunnerEnv, isSandagentDaemonHealthy } from '@sandagent/manager';
3
3
  import { LanguageModelV3StreamPart, LanguageModelV3, LanguageModelV3CallOptions, LanguageModelV3GenerateResult, LanguageModelV3StreamResult, ProviderV3, EmbeddingModelV3, ImageModelV3 } from '@ai-sdk/provider';
4
4
  export { LanguageModelV3StreamPart } from '@ai-sdk/provider';
5
5
 
@@ -71,16 +71,19 @@ interface Logger {
71
71
  type SandAgentRunnerType = "claude" | "pi" | "codex" | "gemini" | "opencode";
72
72
  /**
73
73
  * AI Provider specific settings that extend SandAgentOptions.
74
- * Requires a `sandbox`. Optional `daemonUrl` streams via sandagent-daemon
75
- * **inside** that sandbox; without it, the CLI runner is used in the sandbox.
74
+ * Requires a `sandbox`. Optional `daemonUrl` streams via sandagent-daemon HTTP
75
+ * (`POST /api/coding/run`) inside the sandbox. The SDK does **not** probe `/healthz`
76
+ * on each request — call `isSandagentDaemonHealthy` (re-exported from
77
+ * `@sandagent/sdk`) when you want to check readiness and omit `daemonUrl` to fall
78
+ * back to the CLI runner, or set `daemonUrl` and handle HTTP errors yourself.
76
79
  */
77
80
  interface SandAgentProviderSettings extends Omit<SandAgentOptions, "runner" | "sandboxId" | "sandbox"> {
78
81
  /** Required. All transports run relative to this adapter. */
79
82
  sandbox: SandboxAdapter;
80
83
  /**
81
84
  * sandagent-daemon base URL **inside** the sandbox (e.g. SandAgent image:
82
- * `http://127.0.0.1:3080`). When set, the SDK uses `streamCodingRunFromSandbox`
83
- * instead of the CLI runner.
85
+ * `http://127.0.0.1:3080`). When set, the SDK uses HTTP streaming only (no
86
+ * automatic health probe or CLI fallback).
84
87
  */
85
88
  daemonUrl?: string;
86
89
  /**
package/dist/index.js CHANGED
@@ -1,5 +1,9 @@
1
1
  // src/index.ts
2
- import { buildRunnerEnv, LocalSandbox } from "@sandagent/manager";
2
+ import {
3
+ buildRunnerEnv,
4
+ isSandagentDaemonHealthy,
5
+ LocalSandbox
6
+ } from "@sandagent/manager";
3
7
 
4
8
  // src/provider/question-processor.ts
5
9
  async function submitAnswer(sandbox, params, options) {
@@ -364,7 +368,9 @@ var SandAgentLanguageModel = class {
364
368
  } catch (e) {
365
369
  const msg = e instanceof Error ? e.message : String(e);
366
370
  if (!msg.includes("Unexpected token")) {
367
- self.logger.error(`[sandagent] Failed to parse stream data: ${e}`);
371
+ self.logger.error(
372
+ `[sandagent] Failed to parse stream data: ${e}`
373
+ );
368
374
  }
369
375
  }
370
376
  }
@@ -695,27 +701,17 @@ var SandAgentLanguageModel = class {
695
701
 
696
702
  // src/provider/sandagent-provider.ts
697
703
  import { NoSuchModelError } from "@ai-sdk/provider";
698
-
699
- // src/provider/types.ts
700
- function getRunnerKindForModel(_modelId) {
701
- return "claude-agent-sdk";
702
- }
703
- var DEFAULT_SANDAGENT_DAEMON_URL = "http://127.0.0.1:3080";
704
-
705
- // src/provider/sandagent-provider.ts
706
704
  function createSandAgent(defaultOptions) {
707
705
  const logger = getProviderLogger(defaultOptions);
708
706
  if (!defaultOptions.sandbox) {
709
707
  throw new Error(
710
- "Provide a `sandbox` adapter (e.g. E2BSandbox, LocalSandbox). Optional `daemonUrl` selects in-sandbox HTTP to sandagent-daemon (e.g. `http://127.0.0.1:3080`); omit it to use the CLI runner in the sandbox."
708
+ "Provide a `sandbox` adapter (e.g. E2BSandbox, LocalSandbox). Optional `daemonUrl` uses in-sandbox HTTP to sandagent-daemon (no automatic `/healthz` probe). Use `isSandagentDaemonHealthy` from `@sandagent/sdk` if you want to probe and omit `daemonUrl` for CLI fallback. Omit `daemonUrl` to always use CLI."
711
709
  );
712
710
  }
713
711
  const createModel = (modelId, options = {}) => {
714
- const runnerKind = getRunnerKindForModel(modelId);
715
712
  const mergedSkillPaths = options.skillPaths !== void 0 ? options.skillPaths : defaultOptions.skillPaths;
716
713
  const mergedAllowedTools = options.allowedTools !== void 0 ? options.allowedTools : defaultOptions.allowedTools;
717
714
  const runner = {
718
- kind: runnerKind,
719
715
  model: modelId,
720
716
  runnerType: options.runnerType ?? defaultOptions.runnerType,
721
717
  outputFormat: "stream",
@@ -738,7 +734,7 @@ function createSandAgent(defaultOptions) {
738
734
  ]
739
735
  };
740
736
  logger.debug(
741
- `[sandagent] Creating model: ${modelId} with runner: ${runner.kind}${runner.runnerType ? ` (runnerType: ${runner.runnerType})` : ""}${runner.skillPaths?.length ? ` skillPaths=${runner.skillPaths.length}` : ""}`
737
+ `[sandagent] Creating model: ${modelId}${runner.runnerType ? ` (runnerType: ${runner.runnerType})` : ""}${runner.skillPaths?.length ? ` skillPaths=${runner.skillPaths.length}` : ""}`
742
738
  );
743
739
  return new SandAgentLanguageModel({
744
740
  id: modelId,
@@ -777,6 +773,9 @@ function createSandAgent(defaultOptions) {
777
773
  return provider;
778
774
  }
779
775
 
776
+ // src/provider/types.ts
777
+ var DEFAULT_SANDAGENT_DAEMON_URL = "http://127.0.0.1:3080";
778
+
780
779
  // src/index.ts
781
780
  var VERSION = "0.1.0";
782
781
  export {
@@ -786,6 +785,7 @@ export {
786
785
  VERSION,
787
786
  buildRunnerEnv,
788
787
  createSandAgent,
788
+ isSandagentDaemonHealthy,
789
789
  submitAnswer
790
790
  };
791
791
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/provider/question-processor.ts","../src/provider/sandagent-language-model.ts","../src/provider/logging.ts","../src/provider/sandagent-provider.ts","../src/provider/types.ts"],"sourcesContent":["/**\n * @sandagent/sdk\n *\n * SandAgent 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 \"@sandagent/sdk/react\".\n *\n * @example\n * ```typescript\n * // Backend - Provider\n * import { createSandAgent } from \"@sandagent/sdk\";\n * const sandagent = createSandAgent({ sandbox, env });\n * const model = sandagent(\"sonnet\");\n *\n * // Frontend - React hooks\n * import { useSandAgentChat } from \"@sandagent/sdk/react\";\n * const { messages, sendMessage } = useSandAgentChat({ apiEndpoint: \"/api/ai\" });\n * ```\n */\n\nexport type {\n LocalSandboxOptions,\n RunnerEnvParams,\n RunnerType,\n} from \"@sandagent/manager\";\n// Re-export LocalSandbox for convenience\n// Re-export env helpers\nexport { buildRunnerEnv, LocalSandbox } from \"@sandagent/manager\";\nexport type {\n ArtifactProcessor,\n ArtifactResult,\n // Re-exports from @ai-sdk/provider\n LanguageModelV3StreamPart,\n Logger,\n Message,\n Question,\n SandAgentLanguageModelOptions,\n SandAgentModelId,\n SandAgentProvider,\n SandAgentProviderSettings,\n // Re-exports from @sandagent/manager\n SandboxAdapter,\n SandboxHandle,\n StreamWriter,\n SubmitAnswerOptions,\n SubmitAnswerParams,\n TranscriptEntry,\n} from \"./provider\";\n// Provider exports\nexport {\n createSandAgent,\n DEFAULT_SANDAGENT_DAEMON_URL,\n SandAgentLanguageModel,\n submitAnswer,\n} from \"./provider\";\n\nexport const VERSION = \"0.1.0\";\n","import type { SandboxAdapter } from \"@sandagent/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 \".sandagent/approvals\"\n */\n basePath?: string;\n}\n\n/**\n * Submit user's answer for an AskUserQuestion tool call.\n * Writes the answer file to `.sandagent/approvals/{toolCallId}.json` in the sandbox workdir.\n *\n * @example\n * ```typescript\n * import { submitAnswer } from \"@sandagent/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 ?? \".sandagent/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/.sandagent/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","import type {\n JSONObject,\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 type Message,\n type RunnerSpec,\n SandAgent,\n type SandAgentCodingRunBody,\n streamCodingRunFromSandbox,\n} from \"@sandagent/manager\";\nimport { getProviderLogger } from \"./logging\";\nimport type { Logger, SandAgentModelId, SandAgentProviderSettings } from \"./types\";\n\n/**\n * Options for creating a SandAgent language model instance.\n */\nexport interface SandAgentLanguageModelOptions {\n id: SandAgentModelId;\n options: SandAgentProviderSettings & { 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 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 },\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 * SandAgent Language Model implementation for AI SDK.\n */\nexport class SandAgentLanguageModel 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: SandAgentProviderSettings & { 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 constructor(modelOptions: SandAgentLanguageModelOptions) {\n this.modelId = modelOptions.id;\n this.options = modelOptions.options;\n this.logger = getProviderLogger(modelOptions.options);\n this.provider = modelOptions.options.daemonUrl\n ? \"sandagent-daemon\"\n : \"sandagent\";\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 `[sandagent] Starting stream with ${messages.length} messages`,\n );\n\n const sandbox = this.options.sandbox;\n if (!sandbox) {\n throw new Error(\n \"SandAgent 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: SandAgentCodingRunBody = {\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 SandAgent({\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 ): SandAgentCodingRunBody {\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 };\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\n .artifactProcessors) {\n Promise.resolve()\n .then(() => processor.onChange(part, sessionId))\n .catch((e) => {\n self.logger.error(\n `[sandagent] Artifact processor error: ${e}`,\n );\n });\n }\n }\n }\n }\n } catch (e) {\n // daemon /api/coding/run may emit plain text lines; ignore non-JSON fragments.\n const msg = e instanceof Error ? e.message : String(e);\n if (!msg.includes(\"Unexpected token\")) {\n self.logger.error(`[sandagent] Failed to parse stream data: ${e}`);\n }\n }\n }\n\n if (foundDone) {\n controller.close();\n return;\n }\n }\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n self.logger.info(\"[sandagent] Stream aborted by user\");\n } else {\n self.logger.error(\n `[sandagent] Stream error: ${formatErrorForLog(error)}`,\n );\n }\n controller.error(error);\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: \")\n ? line.slice(6)\n : line.trim();\n if (!candidate || candidate === \"[DONE]\") continue;\n try {\n const parsedParts = this.parseSSEData(candidate);\n parts.push(...parsedParts);\n } catch {\n // ignore trailing non-JSON lines on stream close\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 sandagent: {\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 `[sandagent] 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 sandagent: {\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 messageMetadata = parsed.messageMetadata as\n | { usage?: Record<string, unknown> }\n | undefined;\n const rawUsage = messageMetadata?.usage;\n const usage = this.convertUsage(rawUsage);\n\n parts.push({\n type: \"finish\",\n finishReason,\n usage,\n providerMetadata: {\n sandagent: {\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 private convertUsage(\n data: Record<string, unknown> | undefined,\n ): LanguageModelV3Usage {\n if (!data) {\n return createEmptyUsage();\n }\n\n if (\"inputTokens\" in data && \"outputTokens\" in data) {\n const inputTokens = data.inputTokens as Record<string, number>;\n const outputTokens = data.outputTokens as Record<string, number>;\n // Check if there's a raw field in the data\n const rawData =\n \"raw\" in data ? (data.raw as Record<string, unknown>) : data;\n\n return {\n inputTokens: {\n total: inputTokens.total ?? 0,\n noCache: inputTokens.noCache ?? 0,\n cacheRead: inputTokens.cacheRead ?? 0,\n cacheWrite: inputTokens.cacheWrite ?? 0,\n },\n outputTokens: {\n total: outputTokens.total ?? 0,\n text: outputTokens.text ?? outputTokens.textTokens ?? undefined,\n reasoning:\n outputTokens.reasoning ?? outputTokens.reasoningTokens ?? undefined,\n },\n raw: rawData as JSONObject,\n };\n }\n\n const usage = (data.usage ?? data) as Record<string, number | undefined>;\n\n if (\"input_tokens\" in usage || \"output_tokens\" in usage) {\n const inputTokens = (usage.input_tokens as number) ?? 0;\n const outputTokens = (usage.output_tokens as number) ?? 0;\n const cacheWrite = (usage.cache_creation_input_tokens as number) ?? 0;\n const cacheRead = (usage.cache_read_input_tokens as number) ?? 0;\n // Check for text/reasoning tokens if available\n const textTokens = (usage.text_tokens as number) ?? undefined;\n const reasoningTokens = (usage.reasoning_tokens as number) ?? undefined;\n\n return {\n inputTokens: {\n total: inputTokens + cacheWrite + cacheRead,\n noCache: inputTokens,\n cacheRead,\n cacheWrite,\n },\n outputTokens: {\n total: outputTokens,\n text: textTokens,\n reasoning: reasoningTokens,\n },\n raw: usage as JSONObject,\n };\n }\n\n return createEmptyUsage();\n }\n}\n","import type { Logger, SandAgentProviderSettings } from \"./types\";\n\n/** Shared logger factory for provider and language model. */\nexport function getProviderLogger(\n settings: Partial<SandAgentProviderSettings>,\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 EmbeddingModelV3,\n ImageModelV3,\n LanguageModelV3,\n ProviderV3,\n} from \"@ai-sdk/provider\";\nimport { NoSuchModelError } from \"@ai-sdk/provider\";\nimport type { RunnerSpec } from \"@sandagent/manager\";\nimport { getProviderLogger } from \"./logging\";\nimport { SandAgentLanguageModel } from \"./sandagent-language-model\";\nimport type { SandAgentModelId } from \"./types\";\nimport { getRunnerKindForModel, type SandAgentProviderSettings } from \"./types\";\n\nexport type { SandAgentProviderSettings } from \"./types\";\n\n/**\n * SandAgent provider interface that extends the AI SDK's ProviderV3.\n */\nexport interface SandAgentProvider extends ProviderV3 {\n (\n modelId: SandAgentModelId,\n options?: Partial<SandAgentProviderSettings>,\n ): LanguageModelV3;\n\n languageModel(\n modelId: SandAgentModelId,\n options?: Partial<SandAgentProviderSettings>,\n ): LanguageModelV3;\n\n chat(\n modelId: SandAgentModelId,\n options?: Partial<SandAgentProviderSettings>,\n ): LanguageModelV3;\n\n embeddingModel(modelId: string): EmbeddingModelV3;\n textEmbeddingModel(modelId: string): EmbeddingModelV3;\n imageModel(modelId: string): ImageModelV3;\n}\n\n/**\n * Creates a SandAgent provider instance with the specified configuration.\n *\n * @example\n * ```typescript\n * import { createSandAgent } from '@sandagent/sdk';\n * import { E2BSandbox } from '@sandagent/sandbox-e2b';\n * import { generateText } from 'ai';\n *\n * const sandagent = createSandAgent({\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: sandagent('sonnet'),\n * prompt: 'Create a hello world program',\n * });\n * ```\n */\nexport function createSandAgent(\n defaultOptions: SandAgentProviderSettings,\n): SandAgentProvider {\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` selects in-sandbox HTTP to sandagent-daemon (e.g. `http://127.0.0.1:3080`); omit it to use the CLI runner in the sandbox.\",\n );\n }\n\n const createModel = (\n modelId: SandAgentModelId,\n options: Partial<SandAgentProviderSettings> = {},\n ): LanguageModelV3 => {\n const runnerKind = getRunnerKindForModel(modelId);\n\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 kind: runnerKind,\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 SandAgentProviderSettings & { runner: RunnerSpec };\n\n logger.debug(\n `[sandagent] Creating model: ${modelId} with runner: ${runner.kind}${runner.runnerType ? ` (runnerType: ${runner.runnerType})` : \"\"}${runner.skillPaths?.length ? ` skillPaths=${runner.skillPaths.length}` : \"\"}`,\n );\n\n return new SandAgentLanguageModel({\n id: modelId,\n options: mergedOptions,\n });\n };\n\n const provider = function (\n modelId: SandAgentModelId,\n options?: Partial<SandAgentProviderSettings>,\n ) {\n if (new.target) {\n throw new Error(\n \"The SandAgent 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 SandAgentProvider;\n}\n","import type { LanguageModelV3StreamPart } from \"@ai-sdk/provider\";\nimport type { SandAgentOptions, SandboxAdapter } from \"@sandagent/manager\";\n\n/**\n * Artifact Processor result\n */\nexport interface ArtifactResult {\n artifactId: string;\n content: string;\n mimeType?: string;\n}\n\n/**\n * Stream writer interface for writing data parts\n */\nexport interface StreamWriter {\n write(chunk: {\n type: string;\n id?: string;\n data?: unknown;\n transient?: boolean;\n }): void;\n}\n\n/**\n * Artifact Processor interface\n */\nexport interface ArtifactProcessor {\n /**\n * Invoked when a stream part is received\n * @param event - Stream part event\n * @param sessionId - Current session ID (taskId)\n */\n onChange(event: LanguageModelV3StreamPart, sessionId: string): Promise<void>;\n}\n\n/**\n * Question structure for AskUserQuestion tool\n */\nexport interface Question {\n question: string;\n header?: string;\n options?: Array<{ label: string; description?: string }>;\n multiSelect?: boolean;\n}\n\n/**\n * Parameters for submitting an answer\n */\nexport interface SubmitAnswerParams {\n /** Tool call ID from the AskUserQuestion tool */\n toolCallId: string;\n /** Original questions from the tool */\n questions: Question[];\n /** User's answers keyed by question text */\n answers: Record<string, string>;\n}\n\n/**\n * Logger interface for custom logging.\n */\nexport interface Logger {\n debug: (message: string) => void;\n info: (message: string) => void;\n warn: (message: string) => void;\n error: (message: string) => void;\n}\n\n/**\n * CLI runner type passed to `sandagent run --runner <runnerType>`.\n */\nexport type SandAgentRunnerType =\n | \"claude\"\n | \"pi\"\n | \"codex\"\n | \"gemini\"\n | \"opencode\";\n\n/**\n * AI Provider specific settings that extend SandAgentOptions.\n * Requires a `sandbox`. Optional `daemonUrl` streams via sandagent-daemon\n * **inside** that sandbox; without it, the CLI runner is used in the sandbox.\n */\nexport interface SandAgentProviderSettings\n extends Omit<SandAgentOptions, \"runner\" | \"sandboxId\" | \"sandbox\"> {\n /** Required. All transports run relative to this adapter. */\n sandbox: SandboxAdapter;\n /**\n * sandagent-daemon base URL **inside** the sandbox (e.g. SandAgent image:\n * `http://127.0.0.1:3080`). When set, the SDK uses `streamCodingRunFromSandbox`\n * instead of the CLI runner.\n */\n daemonUrl?: string;\n /**\n * Which runner implementation to use: claude (default), pi, codex, gemini, opencode.\n * Maps to `sandagent run --runner <runnerType>`.\n */\n runnerType?: SandAgentRunnerType;\n /** Working directory for CLI operations inside the sandbox. */\n cwd?: string;\n /** Resume session ID for multi-turn conversation. */\n resume?: string;\n /** Enable verbose logging for debugging. */\n verbose?: boolean;\n /** Custom logger for handling warnings and errors. */\n logger?: Logger | false;\n /** Artifact processors for handling artifact events. */\n artifactProcessors?: ArtifactProcessor[];\n /** Limit the number of back-and-forth iterations */\n maxTurns?: number;\n /** Optional system prompt override (overrides template's default) */\n systemPrompt?: string;\n /** Additional skill paths (files or directories) for pi runner */\n skillPaths?: string[];\n /** Allowed tools for the runner (undefined = template defaults). */\n allowedTools?: string[];\n}\n\n/**\n * Model identifier: user passes whatever the runner expects (e.g. Claude model id, Pi model id).\n */\nexport type SandAgentModelId = string;\n\n/**\n * Determine the runner kind based on model ID (for future multi-runner support).\n */\nexport function getRunnerKindForModel(\n _modelId: SandAgentModelId,\n): \"claude-agent-sdk\" {\n return \"claude-agent-sdk\";\n}\n\n/**\n * Default sandagent-daemon base URL inside the SandAgent Docker image / local\n * daemon (`http://127.0.0.1:3080`). Pass as `daemonUrl` with a `sandbox`.\n */\nexport const DEFAULT_SANDAGENT_DAEMON_URL = \"http://127.0.0.1:3080\";\n"],"mappings":"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","names":["sandboxEnv"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/provider/question-processor.ts","../src/provider/sandagent-language-model.ts","../src/provider/logging.ts","../src/provider/sandagent-provider.ts","../src/provider/types.ts"],"sourcesContent":["/**\n * @sandagent/sdk\n *\n * SandAgent 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 \"@sandagent/sdk/react\".\n *\n * @example\n * ```typescript\n * // Backend - Provider\n * import { createSandAgent } from \"@sandagent/sdk\";\n * const sandagent = createSandAgent({ sandbox, env });\n * const model = sandagent(\"sonnet\");\n *\n * // Frontend - React hooks\n * import { useSandAgentChat } from \"@sandagent/sdk/react\";\n * const { messages, sendMessage } = useSandAgentChat({ apiEndpoint: \"/api/ai\" });\n * ```\n */\n\nexport type {\n IsSandagentDaemonHealthyOptions,\n LocalSandboxOptions,\n RunnerEnvParams,\n RunnerType,\n} from \"@sandagent/manager\";\n// Re-export LocalSandbox for convenience\n// Re-export env helpers\nexport {\n buildRunnerEnv,\n isSandagentDaemonHealthy,\n LocalSandbox,\n} from \"@sandagent/manager\";\nexport type {\n ArtifactProcessor,\n ArtifactResult,\n // Re-exports from @ai-sdk/provider\n LanguageModelV3StreamPart,\n Logger,\n Message,\n Question,\n SandAgentLanguageModelOptions,\n SandAgentModelId,\n SandAgentProvider,\n SandAgentProviderSettings,\n // Re-exports from @sandagent/manager\n SandboxAdapter,\n SandboxHandle,\n StreamWriter,\n SubmitAnswerOptions,\n SubmitAnswerParams,\n TranscriptEntry,\n} from \"./provider\";\n// Provider exports\nexport {\n createSandAgent,\n DEFAULT_SANDAGENT_DAEMON_URL,\n SandAgentLanguageModel,\n submitAnswer,\n} from \"./provider\";\n\nexport const VERSION = \"0.1.0\";\n","import type { SandboxAdapter } from \"@sandagent/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 \".sandagent/approvals\"\n */\n basePath?: string;\n}\n\n/**\n * Submit user's answer for an AskUserQuestion tool call.\n * Writes the answer file to `.sandagent/approvals/{toolCallId}.json` in the sandbox workdir.\n *\n * @example\n * ```typescript\n * import { submitAnswer } from \"@sandagent/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 ?? \".sandagent/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/.sandagent/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","import type {\n JSONObject,\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 type Message,\n type RunnerSpec,\n SandAgent,\n type SandAgentCodingRunBody,\n streamCodingRunFromSandbox,\n} from \"@sandagent/manager\";\nimport { getProviderLogger } from \"./logging\";\nimport type {\n Logger,\n SandAgentModelId,\n SandAgentProviderSettings,\n} from \"./types\";\n\n/**\n * Options for creating a SandAgent language model instance.\n */\nexport interface SandAgentLanguageModelOptions {\n id: SandAgentModelId;\n options: SandAgentProviderSettings & { 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 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 },\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 * SandAgent Language Model implementation for AI SDK.\n */\nexport class SandAgentLanguageModel 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: SandAgentProviderSettings & { 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 constructor(modelOptions: SandAgentLanguageModelOptions) {\n this.modelId = modelOptions.id;\n this.options = modelOptions.options;\n this.logger = getProviderLogger(modelOptions.options);\n this.provider = modelOptions.options.daemonUrl\n ? \"sandagent-daemon\"\n : \"sandagent\";\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 `[sandagent] Starting stream with ${messages.length} messages`,\n );\n\n const sandbox = this.options.sandbox;\n if (!sandbox) {\n throw new Error(\n \"SandAgent 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: SandAgentCodingRunBody = {\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 SandAgent({\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 ): SandAgentCodingRunBody {\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 };\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 `[sandagent] Artifact processor error: ${e}`,\n );\n });\n }\n }\n }\n }\n } catch (e) {\n // daemon /api/coding/run may emit plain text lines; ignore non-JSON fragments.\n const msg = e instanceof Error ? e.message : String(e);\n if (!msg.includes(\"Unexpected token\")) {\n self.logger.error(\n `[sandagent] Failed to parse stream data: ${e}`,\n );\n }\n }\n }\n\n if (foundDone) {\n controller.close();\n return;\n }\n }\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n self.logger.info(\"[sandagent] Stream aborted by user\");\n } else {\n self.logger.error(\n `[sandagent] Stream error: ${formatErrorForLog(error)}`,\n );\n }\n controller.error(error);\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 {\n // ignore trailing non-JSON lines on stream close\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 sandagent: {\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 `[sandagent] 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 sandagent: {\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 messageMetadata = parsed.messageMetadata as\n | { usage?: Record<string, unknown> }\n | undefined;\n const rawUsage = messageMetadata?.usage;\n const usage = this.convertUsage(rawUsage);\n\n parts.push({\n type: \"finish\",\n finishReason,\n usage,\n providerMetadata: {\n sandagent: {\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 private convertUsage(\n data: Record<string, unknown> | undefined,\n ): LanguageModelV3Usage {\n if (!data) {\n return createEmptyUsage();\n }\n\n if (\"inputTokens\" in data && \"outputTokens\" in data) {\n const inputTokens = data.inputTokens as Record<string, number>;\n const outputTokens = data.outputTokens as Record<string, number>;\n // Check if there's a raw field in the data\n const rawData =\n \"raw\" in data ? (data.raw as Record<string, unknown>) : data;\n\n return {\n inputTokens: {\n total: inputTokens.total ?? 0,\n noCache: inputTokens.noCache ?? 0,\n cacheRead: inputTokens.cacheRead ?? 0,\n cacheWrite: inputTokens.cacheWrite ?? 0,\n },\n outputTokens: {\n total: outputTokens.total ?? 0,\n text: outputTokens.text ?? outputTokens.textTokens ?? undefined,\n reasoning:\n outputTokens.reasoning ?? outputTokens.reasoningTokens ?? undefined,\n },\n raw: rawData as JSONObject,\n };\n }\n\n const usage = (data.usage ?? data) as Record<string, number | undefined>;\n\n if (\"input_tokens\" in usage || \"output_tokens\" in usage) {\n const inputTokens = (usage.input_tokens as number) ?? 0;\n const outputTokens = (usage.output_tokens as number) ?? 0;\n const cacheWrite = (usage.cache_creation_input_tokens as number) ?? 0;\n const cacheRead = (usage.cache_read_input_tokens as number) ?? 0;\n // Check for text/reasoning tokens if available\n const textTokens = (usage.text_tokens as number) ?? undefined;\n const reasoningTokens = (usage.reasoning_tokens as number) ?? undefined;\n\n return {\n inputTokens: {\n total: inputTokens + cacheWrite + cacheRead,\n noCache: inputTokens,\n cacheRead,\n cacheWrite,\n },\n outputTokens: {\n total: outputTokens,\n text: textTokens,\n reasoning: reasoningTokens,\n },\n raw: usage as JSONObject,\n };\n }\n\n return createEmptyUsage();\n }\n}\n","import type { Logger, SandAgentProviderSettings } from \"./types\";\n\n/** Shared logger factory for provider and language model. */\nexport function getProviderLogger(\n settings: Partial<SandAgentProviderSettings>,\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 EmbeddingModelV3,\n ImageModelV3,\n LanguageModelV3,\n ProviderV3,\n} from \"@ai-sdk/provider\";\nimport { NoSuchModelError } from \"@ai-sdk/provider\";\nimport type { RunnerSpec } from \"@sandagent/manager\";\nimport { getProviderLogger } from \"./logging\";\nimport { SandAgentLanguageModel } from \"./sandagent-language-model\";\nimport type { SandAgentModelId, SandAgentProviderSettings } from \"./types\";\n\nexport type { SandAgentProviderSettings } from \"./types\";\n\n/**\n * SandAgent provider interface that extends the AI SDK's ProviderV3.\n */\nexport interface SandAgentProvider extends ProviderV3 {\n (\n modelId: SandAgentModelId,\n options?: Partial<SandAgentProviderSettings>,\n ): LanguageModelV3;\n\n languageModel(\n modelId: SandAgentModelId,\n options?: Partial<SandAgentProviderSettings>,\n ): LanguageModelV3;\n\n chat(\n modelId: SandAgentModelId,\n options?: Partial<SandAgentProviderSettings>,\n ): LanguageModelV3;\n\n embeddingModel(modelId: string): EmbeddingModelV3;\n textEmbeddingModel(modelId: string): EmbeddingModelV3;\n imageModel(modelId: string): ImageModelV3;\n}\n\n/**\n * Creates a SandAgent provider instance with the specified configuration.\n *\n * @example\n * ```typescript\n * import { createSandAgent } from '@sandagent/sdk';\n * import { E2BSandbox } from '@sandagent/sandbox-e2b';\n * import { generateText } from 'ai';\n *\n * const sandagent = createSandAgent({\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: sandagent('sonnet'),\n * prompt: 'Create a hello world program',\n * });\n * ```\n */\nexport function createSandAgent(\n defaultOptions: SandAgentProviderSettings,\n): SandAgentProvider {\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 sandagent-daemon (no automatic `/healthz` probe). Use `isSandagentDaemonHealthy` from `@sandagent/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: SandAgentModelId,\n options: Partial<SandAgentProviderSettings> = {},\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 SandAgentProviderSettings & { runner: RunnerSpec };\n\n logger.debug(\n `[sandagent] Creating model: ${modelId}${runner.runnerType ? ` (runnerType: ${runner.runnerType})` : \"\"}${runner.skillPaths?.length ? ` skillPaths=${runner.skillPaths.length}` : \"\"}`,\n );\n\n return new SandAgentLanguageModel({\n id: modelId,\n options: mergedOptions,\n });\n };\n\n const provider = function (\n modelId: SandAgentModelId,\n options?: Partial<SandAgentProviderSettings>,\n ) {\n if (new.target) {\n throw new Error(\n \"The SandAgent 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 SandAgentProvider;\n}\n","import type { LanguageModelV3StreamPart } from \"@ai-sdk/provider\";\nimport type { SandAgentOptions, SandboxAdapter } from \"@sandagent/manager\";\n\n/**\n * Artifact Processor result\n */\nexport interface ArtifactResult {\n artifactId: string;\n content: string;\n mimeType?: string;\n}\n\n/**\n * Stream writer interface for writing data parts\n */\nexport interface StreamWriter {\n write(chunk: {\n type: string;\n id?: string;\n data?: unknown;\n transient?: boolean;\n }): void;\n}\n\n/**\n * Artifact Processor interface\n */\nexport interface ArtifactProcessor {\n /**\n * Invoked when a stream part is received\n * @param event - Stream part event\n * @param sessionId - Current session ID (taskId)\n */\n onChange(event: LanguageModelV3StreamPart, sessionId: string): Promise<void>;\n}\n\n/**\n * Question structure for AskUserQuestion tool\n */\nexport interface Question {\n question: string;\n header?: string;\n options?: Array<{ label: string; description?: string }>;\n multiSelect?: boolean;\n}\n\n/**\n * Parameters for submitting an answer\n */\nexport interface SubmitAnswerParams {\n /** Tool call ID from the AskUserQuestion tool */\n toolCallId: string;\n /** Original questions from the tool */\n questions: Question[];\n /** User's answers keyed by question text */\n answers: Record<string, string>;\n}\n\n/**\n * Logger interface for custom logging.\n */\nexport interface Logger {\n debug: (message: string) => void;\n info: (message: string) => void;\n warn: (message: string) => void;\n error: (message: string) => void;\n}\n\n/**\n * CLI runner type passed to `sandagent run --runner <runnerType>`.\n */\nexport type SandAgentRunnerType =\n | \"claude\"\n | \"pi\"\n | \"codex\"\n | \"gemini\"\n | \"opencode\";\n\n/**\n * AI Provider specific settings that extend SandAgentOptions.\n * Requires a `sandbox`. Optional `daemonUrl` streams via sandagent-daemon HTTP\n * (`POST /api/coding/run`) inside the sandbox. The SDK does **not** probe `/healthz`\n * on each request — call `isSandagentDaemonHealthy` (re-exported from\n * `@sandagent/sdk`) when you want to check readiness and omit `daemonUrl` to fall\n * back to the CLI runner, or set `daemonUrl` and handle HTTP errors yourself.\n */\nexport interface SandAgentProviderSettings\n extends Omit<SandAgentOptions, \"runner\" | \"sandboxId\" | \"sandbox\"> {\n /** Required. All transports run relative to this adapter. */\n sandbox: SandboxAdapter;\n /**\n * sandagent-daemon base URL **inside** the sandbox (e.g. SandAgent image:\n * `http://127.0.0.1:3080`). When set, the SDK uses HTTP streaming only (no\n * automatic health probe or CLI fallback).\n */\n daemonUrl?: string;\n /**\n * Which runner implementation to use: claude (default), pi, codex, gemini, opencode.\n * Maps to `sandagent run --runner <runnerType>`.\n */\n runnerType?: SandAgentRunnerType;\n /** Working directory for CLI operations inside the sandbox. */\n cwd?: string;\n /** Resume session ID for multi-turn conversation. */\n resume?: string;\n /** Enable verbose logging for debugging. */\n verbose?: boolean;\n /** Custom logger for handling warnings and errors. */\n logger?: Logger | false;\n /** Artifact processors for handling artifact events. */\n artifactProcessors?: ArtifactProcessor[];\n /** Limit the number of back-and-forth iterations */\n maxTurns?: number;\n /** Optional system prompt override (overrides template's default) */\n systemPrompt?: string;\n /** Additional skill paths (files or directories) for pi runner */\n skillPaths?: string[];\n /** Allowed tools for the runner (undefined = template defaults). */\n allowedTools?: string[];\n}\n\n/**\n * Model identifier: user passes whatever the runner expects (e.g. Claude model id, Pi model id).\n */\nexport type SandAgentModelId = string;\n\n/**\n * Default sandagent-daemon base URL inside the SandAgent Docker image / local\n * daemon (`http://127.0.0.1:3080`). Pass as `daemonUrl` with a `sandbox`.\n */\nexport const DEFAULT_SANDAGENT_DAEMON_URL = \"http://127.0.0.1:3080\";\n"],"mappings":"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","names":["sandboxEnv"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sandagent/sdk",
3
- "version": "0.9.9-beta.1",
3
+ "version": "0.9.9-beta.3",
4
4
  "description": "SandAgent 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
- "@sandagent/manager": "0.9.9-beta.1"
55
+ "@sandagent/manager": "0.9.9-beta.3"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@types/node": "^20.10.0",