zidane 5.13.26 → 5.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/dist/{acp-CjAoILwj.js → acp-DgKEJH3P.js} +7 -7
  2. package/dist/{acp-CjAoILwj.js.map → acp-DgKEJH3P.js.map} +1 -1
  3. package/dist/acp-cli.js +11 -6
  4. package/dist/acp-cli.js.map +1 -1
  5. package/dist/acp.d.ts +2 -2
  6. package/dist/acp.js +1 -1
  7. package/dist/{tools-B32lZXLE.js → agent-B-cKanSC.js} +8035 -9459
  8. package/dist/agent-B-cKanSC.js.map +1 -0
  9. package/dist/{agent-DQIL5BFk.d.ts → agent-BAgOgS37.d.ts} +367 -208
  10. package/dist/agent-BAgOgS37.d.ts.map +1 -0
  11. package/dist/agent.d.ts +3 -0
  12. package/dist/agent.js +5 -0
  13. package/dist/anthropic-RGqsJlC8.js +807 -0
  14. package/dist/anthropic-RGqsJlC8.js.map +1 -0
  15. package/dist/{atomic-write-Bgtr5JPu.js → atomic-write-B7zr1ddF.js} +2 -2
  16. package/dist/{atomic-write-Bgtr5JPu.js.map → atomic-write-B7zr1ddF.js.map} +1 -1
  17. package/dist/{auth-DPrSP1YV.js → auth-C-ms5N2x.js} +33 -5
  18. package/dist/{auth-DPrSP1YV.js.map → auth-C-ms5N2x.js.map} +1 -1
  19. package/dist/cache-telemetry-BKAwsNxm.js +169 -0
  20. package/dist/cache-telemetry-BKAwsNxm.js.map +1 -0
  21. package/dist/chat/pure.d.ts +3 -3
  22. package/dist/chat/pure.js +1 -1
  23. package/dist/chat.d.ts +21 -7
  24. package/dist/chat.d.ts.map +1 -1
  25. package/dist/chat.js +30 -5
  26. package/dist/chat.js.map +1 -1
  27. package/dist/contexts/daytona.d.ts +1 -1
  28. package/dist/contexts/docker.js +0 -1
  29. package/dist/contexts/docker.js.map +1 -1
  30. package/dist/contexts/e2b.d.ts +1 -1
  31. package/dist/errors-CkTvg97v.d.ts +203 -0
  32. package/dist/errors-CkTvg97v.d.ts.map +1 -0
  33. package/dist/errors.d.ts +3 -0
  34. package/dist/errors.js +3 -0
  35. package/dist/eval.d.ts +1 -1
  36. package/dist/eval.js +2 -2
  37. package/dist/headless.d.ts +1 -1
  38. package/dist/headless.js +406 -1
  39. package/dist/headless.js.map +1 -0
  40. package/dist/{index-YY3vp2F2.d.ts → index-CLuLFFLa.d.ts} +88 -418
  41. package/dist/index-CLuLFFLa.d.ts.map +1 -0
  42. package/dist/{index-C5qw3pj7.d.ts → index-CgBIl2mX.d.ts} +2 -2
  43. package/dist/{index-C5qw3pj7.d.ts.map → index-CgBIl2mX.d.ts.map} +1 -1
  44. package/dist/index.d.ts +9 -5
  45. package/dist/index.js +113 -167
  46. package/dist/index.js.map +1 -1
  47. package/dist/{logger-C2ngE8CY.d.ts → logger-CJ-lpKPy.d.ts} +2 -2
  48. package/dist/{logger-C2ngE8CY.d.ts.map → logger-CJ-lpKPy.d.ts.map} +1 -1
  49. package/dist/mcp.d.ts +1 -1
  50. package/dist/messages-YZQLKaz2.js +1157 -0
  51. package/dist/messages-YZQLKaz2.js.map +1 -0
  52. package/dist/oauth-8LqbeI_Q.js +292 -0
  53. package/dist/oauth-8LqbeI_Q.js.map +1 -0
  54. package/dist/{messages-Iy_vEycX.js → openai-compat-0Y7jcncn.js} +27 -1379
  55. package/dist/openai-compat-0Y7jcncn.js.map +1 -0
  56. package/dist/output/stream-json.d.ts +2 -2
  57. package/dist/output/stream-json.js +1 -1
  58. package/dist/output/terminal.d.ts +2 -2
  59. package/dist/{presets-B9nDwmaz.js → presets-Pr02ZNcy.js} +3 -2
  60. package/dist/{presets-B9nDwmaz.js.map → presets-Pr02ZNcy.js.map} +1 -1
  61. package/dist/presets.d.ts +2 -2
  62. package/dist/presets.js +1 -1
  63. package/dist/prompt.d.ts +2 -0
  64. package/dist/prompt.js +210 -0
  65. package/dist/prompt.js.map +1 -0
  66. package/dist/providers/anthropic.d.ts +2 -0
  67. package/dist/providers/anthropic.js +2 -0
  68. package/dist/providers/arcee.d.ts +2 -0
  69. package/dist/providers/arcee.js +42 -0
  70. package/dist/providers/arcee.js.map +1 -0
  71. package/dist/providers/baseten.d.ts +2 -0
  72. package/dist/providers/baseten.js +66 -0
  73. package/dist/providers/baseten.js.map +1 -0
  74. package/dist/providers/cerebras.d.ts +2 -0
  75. package/dist/providers/cerebras.js +31 -0
  76. package/dist/providers/cerebras.js.map +1 -0
  77. package/dist/providers/local.d.ts +2 -0
  78. package/dist/providers/local.js +44 -0
  79. package/dist/providers/local.js.map +1 -0
  80. package/dist/providers/openai-compat.d.ts +2 -0
  81. package/dist/providers/openai-compat.js +2 -0
  82. package/dist/providers/openai.d.ts +2 -0
  83. package/dist/providers/openai.js +504 -0
  84. package/dist/providers/openai.js.map +1 -0
  85. package/dist/providers/openrouter.d.ts +2 -0
  86. package/dist/providers/openrouter.js +52 -0
  87. package/dist/providers/openrouter.js.map +1 -0
  88. package/dist/providers/xai.d.ts +2 -0
  89. package/dist/providers/xai.js +2 -0
  90. package/dist/providers-DgmdYGKm.js +168 -0
  91. package/dist/providers-DgmdYGKm.js.map +1 -0
  92. package/dist/providers.d.ts +1 -1
  93. package/dist/providers.js +10 -2
  94. package/dist/restate.d.ts +1 -1
  95. package/dist/run-summary-DAnBZnrt.d.ts +249 -0
  96. package/dist/run-summary-DAnBZnrt.d.ts.map +1 -0
  97. package/dist/run-summary-nD3IQ4ZQ.js +253 -0
  98. package/dist/run-summary-nD3IQ4ZQ.js.map +1 -0
  99. package/dist/session/sqlite.d.ts +1 -1
  100. package/dist/{session-CiA1_8SB.js → session-CqrAFAKJ.js} +2 -2
  101. package/dist/{session-CiA1_8SB.js.map → session-CqrAFAKJ.js.map} +1 -1
  102. package/dist/session.d.ts +1 -1
  103. package/dist/session.js +2 -2
  104. package/dist/skills.d.ts +2 -2
  105. package/dist/system-prompt-BlsdjcUi.d.ts +139 -0
  106. package/dist/system-prompt-BlsdjcUi.d.ts.map +1 -0
  107. package/dist/timeout-CpFm0jJ6.d.ts +10 -0
  108. package/dist/timeout-CpFm0jJ6.d.ts.map +1 -0
  109. package/dist/timeout-kGGSXagK.js +84 -0
  110. package/dist/timeout-kGGSXagK.js.map +1 -0
  111. package/dist/{tool-formatters-w5oaoCS4.d.ts → tool-formatters-Ch8oRpYR.d.ts} +2 -2
  112. package/dist/{tool-formatters-w5oaoCS4.d.ts.map → tool-formatters-Ch8oRpYR.d.ts.map} +1 -1
  113. package/dist/tools/fetch-url.d.ts +1 -1
  114. package/dist/tools/web-search.d.ts +1 -1
  115. package/dist/tools-00_Nqazv.js +1689 -0
  116. package/dist/tools-00_Nqazv.js.map +1 -0
  117. package/dist/tools.d.ts +2 -2
  118. package/dist/tools.js +2 -1
  119. package/dist/{transcript-anchors-BUtOd-qa.js → transcript-anchors-BUmvPnis.js} +10 -9
  120. package/dist/{transcript-anchors-BUtOd-qa.js.map → transcript-anchors-BUmvPnis.js.map} +1 -1
  121. package/dist/{transcript-anchors-BJ-ESWnm.d.ts → transcript-anchors-CL9UM_M4.d.ts} +4 -4
  122. package/dist/{transcript-anchors-BJ-ESWnm.d.ts.map → transcript-anchors-CL9UM_M4.d.ts.map} +1 -1
  123. package/dist/tui.d.ts +3 -3
  124. package/dist/tui.js +38 -13
  125. package/dist/tui.js.map +1 -1
  126. package/dist/{turn-operations-BSSQHNq1.d.ts → turn-operations-Cj6v_ypW.d.ts} +3 -3
  127. package/dist/{turn-operations-BSSQHNq1.d.ts.map → turn-operations-Cj6v_ypW.d.ts.map} +1 -1
  128. package/dist/{turn-operations-B_XeuNp-.js → turn-operations-tG0vuBNc.js} +2 -2
  129. package/dist/{turn-operations-B_XeuNp-.js.map → turn-operations-tG0vuBNc.js.map} +1 -1
  130. package/dist/types-CyVGdbia.js.map +1 -1
  131. package/dist/types.d.ts +4 -3
  132. package/dist/xai-tPdbAGkq.js +379 -0
  133. package/dist/xai-tPdbAGkq.js.map +1 -0
  134. package/docs/ARCHITECTURE.md +4 -2
  135. package/docs/CHAT.md +4 -0
  136. package/docs/SKILL.md +31 -5
  137. package/package.json +63 -1
  138. package/dist/agent-DQIL5BFk.d.ts.map +0 -1
  139. package/dist/headless-2SH7dvoW.js +0 -656
  140. package/dist/headless-2SH7dvoW.js.map +0 -1
  141. package/dist/index-YY3vp2F2.d.ts.map +0 -1
  142. package/dist/messages-Iy_vEycX.js.map +0 -1
  143. package/dist/providers-BMw1D_lj.js +0 -2332
  144. package/dist/providers-BMw1D_lj.js.map +0 -1
  145. package/dist/tools-B32lZXLE.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { s as ExecResult } from "../types-Bs2oY7Ux.js";
2
2
  import { t as SandboxProvider } from "../sandbox-B-bMq3K6.js";
3
- import { a as Logger } from "../logger-C2ngE8CY.js";
3
+ import { a as Logger } from "../logger-CJ-lpKPy.js";
4
4
  import { Buffer } from "node:buffer";
5
5
 
6
6
  //#region src/contexts/daytona.d.ts
@@ -1,5 +1,4 @@
1
1
  import { t as globFilesViaShell } from "../glob-shell-rJMoCIGb.js";
2
- import "../glob-D56-KpBp.js";
3
2
  import { t as alwaysQuote } from "../shell-quote-BmnhZmdM.js";
4
3
  //#region src/contexts/docker.ts
5
4
  const SINGLE_QUOTE_RE = /'/g;
@@ -1 +1 @@
1
- {"version":3,"file":"docker.js","names":[],"sources":["../../src/contexts/docker.ts"],"sourcesContent":["/**\n * Docker execution context.\n *\n * Runs tools inside a Docker container via dockerode.\n * Full isolation with configurable resource limits.\n *\n * Requires `dockerode` as an optional peer dependency.\n */\n\nimport type { Buffer } from 'node:buffer'\nimport type { ContextCapabilities, ExecResult, ExecutionContext, ExecutionHandle, ListFilesEntry, SpawnConfig } from './types'\nimport { alwaysQuote } from '../tools/shell-quote'\nimport { globFilesViaShell } from './glob'\n\nconst SINGLE_QUOTE_RE = /'/g\n\n/**\n * dockerode surfaces HTTP errors with a `statusCode`. 304 = container\n * already stopped, 404 = already gone — both are fine during teardown.\n */\nfunction isGoneOrAlreadyStopped(err: unknown): boolean {\n const code = (err as { statusCode?: number } | null)?.statusCode\n return code === 304 || code === 404\n}\n\ninterface ContainerRef {\n handle: ExecutionHandle\n container: any\n docker: any\n}\n\nexport function createDockerContext(config?: SpawnConfig): ExecutionContext {\n let counter = 0\n const containers = new Map<string, ContainerRef>()\n const defaultImage = config?.image ?? 'oven/bun:latest'\n const defaultCwd = config?.cwd ?? '/workspace'\n const defaultEnv = config?.env\n const defaultLimits = config?.limits\n const defaultMounts = config?.mounts ?? []\n const defaultName = config?.name\n\n async function getDockerode() {\n try {\n const Dockerode = (await import('dockerode')).default\n return new Dockerode()\n }\n catch {\n throw new Error('dockerode is required for Docker execution context. Install it with: bun add dockerode')\n }\n }\n\n const ctx: ExecutionContext = {\n type: 'docker',\n\n capabilities: {\n shell: true,\n filesystem: true,\n glob: true,\n network: true,\n gpu: false,\n } satisfies ContextCapabilities,\n\n async spawn(overrides?: SpawnConfig): Promise<ExecutionHandle> {\n const docker = await getDockerode()\n const id = `docker-${++counter}`\n const image = overrides?.image ?? defaultImage\n const cwd = overrides?.cwd ?? defaultCwd\n const mounts = [...defaultMounts, ...(overrides?.mounts ?? [])]\n const name = overrides?.name ?? defaultName\n\n // Pull image if not available\n try {\n await docker.getImage(image).inspect()\n }\n catch {\n await new Promise<void>((resolve, reject) => {\n docker.pull(image, (err: Error | null, stream: NodeJS.ReadableStream) => {\n if (err)\n return reject(err)\n docker.modem.followProgress(stream, (err2: Error | null) => {\n err2 ? reject(err2) : resolve()\n })\n })\n })\n }\n\n const limits = { ...defaultLimits, ...overrides?.limits }\n const hostConfig: Record<string, unknown> = {}\n\n if (limits?.memory) {\n hostConfig.Memory = limits.memory * 1024 * 1024\n }\n if (limits?.cpu) {\n hostConfig.NanoCpus = Number.parseFloat(limits.cpu) * 1e9\n }\n\n // Opt-in hardening (all OFF by default — see ContextHardening).\n const hardening = { ...config?.hardening, ...overrides?.hardening }\n if (hardening.dropAllCapabilities)\n hostConfig.CapDrop = ['ALL']\n if (hardening.noNewPrivileges)\n hostConfig.SecurityOpt = ['no-new-privileges']\n if (hardening.readonlyRootfs)\n hostConfig.ReadonlyRootfs = true\n if (hardening.pidsLimit != null)\n hostConfig.PidsLimit = hardening.pidsLimit\n\n const env = { ...defaultEnv, ...overrides?.env }\n\n const bindSpecs = buildBindSpecs(mounts)\n if (bindSpecs.length > 0) {\n hostConfig.Binds = bindSpecs\n }\n\n const portSpec = overrides?.ports ?? config?.ports\n const exposedPorts: Record<string, Record<string, never>> = {}\n const portBindings: Record<string, Array<{ HostPort: string }>> = {}\n\n if (portSpec?.length) {\n for (const p of portSpec) {\n const key = `${p.container}/${p.proto ?? 'tcp'}`\n exposedPorts[key] = {}\n portBindings[key] = [{ HostPort: p.host == null ? '' : String(p.host) }]\n }\n hostConfig.PortBindings = portBindings\n }\n\n const user = overrides?.user ?? config?.user\n const network = overrides?.network ?? config?.network\n if (network) {\n hostConfig.NetworkMode = network\n }\n\n const labels = { ...config?.labels, ...overrides?.labels }\n\n const container = await docker.createContainer({\n // Suffix with a short random token so a crashed run's leftover container\n // (same prefix) never blocks a fresh one with HTTP 409 name conflict.\n ...(name ? { name: `${name}-${counter}-${Math.random().toString(36).slice(2, 8)}` } : {}),\n Image: image,\n Cmd: ['sleep', 'infinity'],\n WorkingDir: cwd,\n Env: Object.entries(env).map(([k, v]) => `${k}=${v}`),\n HostConfig: hostConfig,\n ...(Object.keys(exposedPorts).length ? { ExposedPorts: exposedPorts } : {}),\n ...(user ? { User: user } : {}),\n ...(Object.keys(labels).length ? { Labels: labels } : {}),\n })\n\n try {\n await container.start()\n }\n catch (err) {\n // The container was created but never started — remove it so a\n // failed spawn doesn't leak a stopped container on the daemon.\n await container.remove({ force: true }).catch(() => {})\n throw err\n }\n\n const handle: ExecutionHandle = { id, type: 'docker', cwd }\n containers.set(id, { handle, container, docker })\n\n return handle\n },\n\n async exec(handle: ExecutionHandle, command: string, options?: { cwd?: string, env?: Record<string, string>, timeout?: number }): Promise<ExecResult> {\n const ref = containers.get(handle.id)\n if (!ref)\n throw new Error(`Container ${handle.id} not found`)\n\n const execCwd = options?.cwd ?? handle.cwd\n const env = options?.env\n ? Object.entries(options.env).map(([k, v]) => `${k}=${v}`)\n : []\n\n const timeout = options?.timeout ?? defaultLimits?.timeout ?? 30\n\n const exec = await ref.container.exec({\n // Wrap with coreutils `timeout` so a runaway command is killed\n // server-side too — the host-side timer below only detaches the\n // stream; without this the process would keep running in the\n // container until destroy(). Exec-array form avoids re-quoting the\n // command. `timeout` exits 124 on expiry, matching the host\n // sentinel. (Default image oven/bun is Debian-based → coreutils.)\n Cmd: ['timeout', String(timeout), 'sh', '-c', command],\n WorkingDir: execCwd,\n Env: env,\n AttachStdout: true,\n AttachStderr: true,\n })\n\n const stream = await exec.start({ Detach: false })\n\n return new Promise<ExecResult>((resolve) => {\n let stdout = ''\n let stderr = ''\n let resolved = false\n\n // Docker's exec stream is a multiplexed protocol — a single byte\n // stream that interleaves stdout/stderr frames. `demuxStream`\n // splits the two onto separate writable sinks. Without it, every\n // byte landed on `stdout` and `stderr` was permanently empty.\n const stdoutSink = {\n write(chunk: Buffer | string) {\n stdout += typeof chunk === 'string' ? chunk : chunk.toString('utf-8')\n return true\n },\n end() {},\n on() {},\n once() {},\n emit() { return true },\n }\n const stderrSink = {\n write(chunk: Buffer | string) {\n stderr += typeof chunk === 'string' ? chunk : chunk.toString('utf-8')\n return true\n },\n end() {},\n on() {},\n once() {},\n emit() { return true },\n }\n try {\n ref.docker.modem.demuxStream(stream, stdoutSink, stderrSink)\n }\n catch {\n // Older / different transports may not be multiplexed (TTY mode);\n // fall back to a raw stdout reader so we don't lose output entirely.\n stream.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf-8')\n })\n }\n\n // Host-side fallback timer. The server-side `timeout` wrapper is\n // the primary kill mechanism; give it a grace second so the\n // stream-end path (which carries the real exit code) usually wins.\n const timer = setTimeout(() => {\n if (resolved)\n return\n resolved = true\n // Best-effort: detach the stream so we stop accumulating bytes.\n // The server-side `timeout` wrapper kills the process itself.\n try { stream.destroy?.() }\n catch { /* swallow */ }\n resolve({ stdout, stderr: stderr ? `${stderr}\\n[timeout]` : '[timeout]', exitCode: 124 })\n }, timeout * 1000 + 1000)\n\n stream.on('end', async () => {\n if (resolved)\n return\n resolved = true\n clearTimeout(timer)\n let exitCode: number\n let inspectNote = ''\n try {\n const inspect = await exec.inspect()\n // `ExitCode: null` means Docker hasn't recorded an exit yet —\n // the outcome is unknown, not success. Use a sentinel so\n // callers don't mistake it for a clean exit.\n if (inspect.ExitCode == null) {\n exitCode = -1\n inspectNote = '[exit code unavailable: exec still marked running by daemon]'\n }\n else {\n exitCode = inspect.ExitCode\n }\n }\n catch (err) {\n exitCode = -1\n inspectNote = `[exit code unavailable: exec inspect failed: ${(err as Error)?.message ?? String(err)}]`\n }\n resolve({\n stdout,\n stderr: inspectNote ? (stderr ? `${stderr}\\n${inspectNote}` : inspectNote) : stderr,\n exitCode,\n })\n })\n\n stream.on('error', (err: Error) => {\n if (resolved)\n return\n resolved = true\n clearTimeout(timer)\n resolve({ stdout, stderr: stderr ? `${stderr}\\n${err.message}` : err.message, exitCode: 1 })\n })\n })\n },\n\n // Paths are model-supplied — single-quote them (`alwaysQuote`) rather\n // than JSON.stringify: `$(…)` and backticks still expand inside the\n // double quotes JSON produces, which was a command-injection vector.\n async readFile(handle: ExecutionHandle, path: string): Promise<string> {\n const result = await ctx.exec(handle, `cat ${alwaysQuote(path)}`)\n if (result.exitCode !== 0)\n throw new Error(`Failed to read file: ${result.stderr}`)\n return result.stdout\n },\n\n async writeFile(handle: ExecutionHandle, path: string, content: string): Promise<void> {\n const escaped = content.replace(SINGLE_QUOTE_RE, String.raw`'\\''`)\n const result = await ctx.exec(handle, `mkdir -p \"$(dirname ${alwaysQuote(path)})\" && printf '%s' '${escaped}' > ${alwaysQuote(path)}`)\n if (result.exitCode !== 0)\n throw new Error(`Failed to write file: ${result.stderr}`)\n },\n\n async listFiles(handle: ExecutionHandle, path: string, options): Promise<ListFilesEntry[]> {\n if (options?.glob)\n return globFilesViaShell(path, command => ctx.exec(handle, command), options?.limit ?? 1000)\n const result = await ctx.exec(handle, `ls -1 ${alwaysQuote(path)}`)\n if (result.exitCode !== 0)\n return []\n return result.stdout.trim().split('\\n').filter(Boolean)\n },\n\n async getMappedPort(handle: ExecutionHandle, containerPort: number): Promise<number | null> {\n const ref = containers.get(handle.id)\n if (!ref)\n return null\n\n const info = await ref.container.inspect()\n const bindings = info?.NetworkSettings?.Ports ?? {}\n\n for (const proto of ['tcp', 'udp']) {\n const list = bindings[`${containerPort}/${proto}`]\n if (Array.isArray(list) && list.length > 0 && list[0]?.HostPort) {\n return Number.parseInt(list[0].HostPort, 10)\n }\n }\n\n return null\n },\n\n async destroy(handle: ExecutionHandle): Promise<void> {\n const ref = containers.get(handle.id)\n if (!ref)\n return\n\n try {\n try {\n await ref.container.stop({ t: 5 })\n }\n catch {\n // 304 (already stopped) / 404 (already gone) are expected here.\n // Any other stop failure must not prevent the remove({force})\n // below — force removal also works on running containers.\n }\n try {\n await ref.container.remove({ force: true })\n }\n catch (err) {\n if (!isGoneOrAlreadyStopped(err))\n throw err\n }\n }\n finally {\n containers.delete(handle.id)\n }\n },\n }\n\n return ctx\n}\n\n/**\n * Format one {@link ContextMount} as a dockerode `HostConfig.Binds` entry.\n * Supports read-only (`:ro`) and SELinux shared-label (`:z`) options; the two\n * are mutually exclusive (a read-only mount can't also be a shared rw mount).\n */\nfunction formatBindMount(mount: NonNullable<SpawnConfig['mounts']>[number]): string {\n if (!mount.source)\n throw new Error('Docker mount source is required')\n if (!mount.target || !mount.target.startsWith('/'))\n throw new Error(`Docker mount target must be an absolute path: ${mount.target}`)\n if (mount.readonly && mount.shared)\n throw new Error(`Docker mount cannot be both readonly and shared: ${mount.target}`)\n const opts = mount.readonly ? ':ro' : mount.shared ? ':z' : ''\n return `${mount.source}:${mount.target}${opts}`\n}\n\n/** Assemble dockerode `HostConfig.Binds` from the context's `mounts`. */\nexport function buildBindSpecs(mounts: NonNullable<SpawnConfig['mounts']>): string[] {\n return mounts.map(formatBindMount)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"docker.js","names":[],"sources":["../../src/contexts/docker.ts"],"sourcesContent":["/**\n * Docker execution context.\n *\n * Runs tools inside a Docker container via dockerode.\n * Full isolation with configurable resource limits.\n *\n * Requires `dockerode` as an optional peer dependency.\n */\n\nimport type { Buffer } from 'node:buffer'\nimport type { ContextCapabilities, ExecResult, ExecutionContext, ExecutionHandle, ListFilesEntry, SpawnConfig } from './types'\nimport { alwaysQuote } from '../tools/shell-quote'\nimport { globFilesViaShell } from './glob'\n\nconst SINGLE_QUOTE_RE = /'/g\n\n/**\n * dockerode surfaces HTTP errors with a `statusCode`. 304 = container\n * already stopped, 404 = already gone — both are fine during teardown.\n */\nfunction isGoneOrAlreadyStopped(err: unknown): boolean {\n const code = (err as { statusCode?: number } | null)?.statusCode\n return code === 304 || code === 404\n}\n\ninterface ContainerRef {\n handle: ExecutionHandle\n container: any\n docker: any\n}\n\nexport function createDockerContext(config?: SpawnConfig): ExecutionContext {\n let counter = 0\n const containers = new Map<string, ContainerRef>()\n const defaultImage = config?.image ?? 'oven/bun:latest'\n const defaultCwd = config?.cwd ?? '/workspace'\n const defaultEnv = config?.env\n const defaultLimits = config?.limits\n const defaultMounts = config?.mounts ?? []\n const defaultName = config?.name\n\n async function getDockerode() {\n try {\n const Dockerode = (await import('dockerode')).default\n return new Dockerode()\n }\n catch {\n throw new Error('dockerode is required for Docker execution context. Install it with: bun add dockerode')\n }\n }\n\n const ctx: ExecutionContext = {\n type: 'docker',\n\n capabilities: {\n shell: true,\n filesystem: true,\n glob: true,\n network: true,\n gpu: false,\n } satisfies ContextCapabilities,\n\n async spawn(overrides?: SpawnConfig): Promise<ExecutionHandle> {\n const docker = await getDockerode()\n const id = `docker-${++counter}`\n const image = overrides?.image ?? defaultImage\n const cwd = overrides?.cwd ?? defaultCwd\n const mounts = [...defaultMounts, ...(overrides?.mounts ?? [])]\n const name = overrides?.name ?? defaultName\n\n // Pull image if not available\n try {\n await docker.getImage(image).inspect()\n }\n catch {\n await new Promise<void>((resolve, reject) => {\n docker.pull(image, (err: Error | null, stream: NodeJS.ReadableStream) => {\n if (err)\n return reject(err)\n docker.modem.followProgress(stream, (err2: Error | null) => {\n err2 ? reject(err2) : resolve()\n })\n })\n })\n }\n\n const limits = { ...defaultLimits, ...overrides?.limits }\n const hostConfig: Record<string, unknown> = {}\n\n if (limits?.memory) {\n hostConfig.Memory = limits.memory * 1024 * 1024\n }\n if (limits?.cpu) {\n hostConfig.NanoCpus = Number.parseFloat(limits.cpu) * 1e9\n }\n\n // Opt-in hardening (all OFF by default — see ContextHardening).\n const hardening = { ...config?.hardening, ...overrides?.hardening }\n if (hardening.dropAllCapabilities)\n hostConfig.CapDrop = ['ALL']\n if (hardening.noNewPrivileges)\n hostConfig.SecurityOpt = ['no-new-privileges']\n if (hardening.readonlyRootfs)\n hostConfig.ReadonlyRootfs = true\n if (hardening.pidsLimit != null)\n hostConfig.PidsLimit = hardening.pidsLimit\n\n const env = { ...defaultEnv, ...overrides?.env }\n\n const bindSpecs = buildBindSpecs(mounts)\n if (bindSpecs.length > 0) {\n hostConfig.Binds = bindSpecs\n }\n\n const portSpec = overrides?.ports ?? config?.ports\n const exposedPorts: Record<string, Record<string, never>> = {}\n const portBindings: Record<string, Array<{ HostPort: string }>> = {}\n\n if (portSpec?.length) {\n for (const p of portSpec) {\n const key = `${p.container}/${p.proto ?? 'tcp'}`\n exposedPorts[key] = {}\n portBindings[key] = [{ HostPort: p.host == null ? '' : String(p.host) }]\n }\n hostConfig.PortBindings = portBindings\n }\n\n const user = overrides?.user ?? config?.user\n const network = overrides?.network ?? config?.network\n if (network) {\n hostConfig.NetworkMode = network\n }\n\n const labels = { ...config?.labels, ...overrides?.labels }\n\n const container = await docker.createContainer({\n // Suffix with a short random token so a crashed run's leftover container\n // (same prefix) never blocks a fresh one with HTTP 409 name conflict.\n ...(name ? { name: `${name}-${counter}-${Math.random().toString(36).slice(2, 8)}` } : {}),\n Image: image,\n Cmd: ['sleep', 'infinity'],\n WorkingDir: cwd,\n Env: Object.entries(env).map(([k, v]) => `${k}=${v}`),\n HostConfig: hostConfig,\n ...(Object.keys(exposedPorts).length ? { ExposedPorts: exposedPorts } : {}),\n ...(user ? { User: user } : {}),\n ...(Object.keys(labels).length ? { Labels: labels } : {}),\n })\n\n try {\n await container.start()\n }\n catch (err) {\n // The container was created but never started — remove it so a\n // failed spawn doesn't leak a stopped container on the daemon.\n await container.remove({ force: true }).catch(() => {})\n throw err\n }\n\n const handle: ExecutionHandle = { id, type: 'docker', cwd }\n containers.set(id, { handle, container, docker })\n\n return handle\n },\n\n async exec(handle: ExecutionHandle, command: string, options?: { cwd?: string, env?: Record<string, string>, timeout?: number }): Promise<ExecResult> {\n const ref = containers.get(handle.id)\n if (!ref)\n throw new Error(`Container ${handle.id} not found`)\n\n const execCwd = options?.cwd ?? handle.cwd\n const env = options?.env\n ? Object.entries(options.env).map(([k, v]) => `${k}=${v}`)\n : []\n\n const timeout = options?.timeout ?? defaultLimits?.timeout ?? 30\n\n const exec = await ref.container.exec({\n // Wrap with coreutils `timeout` so a runaway command is killed\n // server-side too — the host-side timer below only detaches the\n // stream; without this the process would keep running in the\n // container until destroy(). Exec-array form avoids re-quoting the\n // command. `timeout` exits 124 on expiry, matching the host\n // sentinel. (Default image oven/bun is Debian-based → coreutils.)\n Cmd: ['timeout', String(timeout), 'sh', '-c', command],\n WorkingDir: execCwd,\n Env: env,\n AttachStdout: true,\n AttachStderr: true,\n })\n\n const stream = await exec.start({ Detach: false })\n\n return new Promise<ExecResult>((resolve) => {\n let stdout = ''\n let stderr = ''\n let resolved = false\n\n // Docker's exec stream is a multiplexed protocol — a single byte\n // stream that interleaves stdout/stderr frames. `demuxStream`\n // splits the two onto separate writable sinks. Without it, every\n // byte landed on `stdout` and `stderr` was permanently empty.\n const stdoutSink = {\n write(chunk: Buffer | string) {\n stdout += typeof chunk === 'string' ? chunk : chunk.toString('utf-8')\n return true\n },\n end() {},\n on() {},\n once() {},\n emit() { return true },\n }\n const stderrSink = {\n write(chunk: Buffer | string) {\n stderr += typeof chunk === 'string' ? chunk : chunk.toString('utf-8')\n return true\n },\n end() {},\n on() {},\n once() {},\n emit() { return true },\n }\n try {\n ref.docker.modem.demuxStream(stream, stdoutSink, stderrSink)\n }\n catch {\n // Older / different transports may not be multiplexed (TTY mode);\n // fall back to a raw stdout reader so we don't lose output entirely.\n stream.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf-8')\n })\n }\n\n // Host-side fallback timer. The server-side `timeout` wrapper is\n // the primary kill mechanism; give it a grace second so the\n // stream-end path (which carries the real exit code) usually wins.\n const timer = setTimeout(() => {\n if (resolved)\n return\n resolved = true\n // Best-effort: detach the stream so we stop accumulating bytes.\n // The server-side `timeout` wrapper kills the process itself.\n try { stream.destroy?.() }\n catch { /* swallow */ }\n resolve({ stdout, stderr: stderr ? `${stderr}\\n[timeout]` : '[timeout]', exitCode: 124 })\n }, timeout * 1000 + 1000)\n\n stream.on('end', async () => {\n if (resolved)\n return\n resolved = true\n clearTimeout(timer)\n let exitCode: number\n let inspectNote = ''\n try {\n const inspect = await exec.inspect()\n // `ExitCode: null` means Docker hasn't recorded an exit yet —\n // the outcome is unknown, not success. Use a sentinel so\n // callers don't mistake it for a clean exit.\n if (inspect.ExitCode == null) {\n exitCode = -1\n inspectNote = '[exit code unavailable: exec still marked running by daemon]'\n }\n else {\n exitCode = inspect.ExitCode\n }\n }\n catch (err) {\n exitCode = -1\n inspectNote = `[exit code unavailable: exec inspect failed: ${(err as Error)?.message ?? String(err)}]`\n }\n resolve({\n stdout,\n stderr: inspectNote ? (stderr ? `${stderr}\\n${inspectNote}` : inspectNote) : stderr,\n exitCode,\n })\n })\n\n stream.on('error', (err: Error) => {\n if (resolved)\n return\n resolved = true\n clearTimeout(timer)\n resolve({ stdout, stderr: stderr ? `${stderr}\\n${err.message}` : err.message, exitCode: 1 })\n })\n })\n },\n\n // Paths are model-supplied — single-quote them (`alwaysQuote`) rather\n // than JSON.stringify: `$(…)` and backticks still expand inside the\n // double quotes JSON produces, which was a command-injection vector.\n async readFile(handle: ExecutionHandle, path: string): Promise<string> {\n const result = await ctx.exec(handle, `cat ${alwaysQuote(path)}`)\n if (result.exitCode !== 0)\n throw new Error(`Failed to read file: ${result.stderr}`)\n return result.stdout\n },\n\n async writeFile(handle: ExecutionHandle, path: string, content: string): Promise<void> {\n const escaped = content.replace(SINGLE_QUOTE_RE, String.raw`'\\''`)\n const result = await ctx.exec(handle, `mkdir -p \"$(dirname ${alwaysQuote(path)})\" && printf '%s' '${escaped}' > ${alwaysQuote(path)}`)\n if (result.exitCode !== 0)\n throw new Error(`Failed to write file: ${result.stderr}`)\n },\n\n async listFiles(handle: ExecutionHandle, path: string, options): Promise<ListFilesEntry[]> {\n if (options?.glob)\n return globFilesViaShell(path, command => ctx.exec(handle, command), options?.limit ?? 1000)\n const result = await ctx.exec(handle, `ls -1 ${alwaysQuote(path)}`)\n if (result.exitCode !== 0)\n return []\n return result.stdout.trim().split('\\n').filter(Boolean)\n },\n\n async getMappedPort(handle: ExecutionHandle, containerPort: number): Promise<number | null> {\n const ref = containers.get(handle.id)\n if (!ref)\n return null\n\n const info = await ref.container.inspect()\n const bindings = info?.NetworkSettings?.Ports ?? {}\n\n for (const proto of ['tcp', 'udp']) {\n const list = bindings[`${containerPort}/${proto}`]\n if (Array.isArray(list) && list.length > 0 && list[0]?.HostPort) {\n return Number.parseInt(list[0].HostPort, 10)\n }\n }\n\n return null\n },\n\n async destroy(handle: ExecutionHandle): Promise<void> {\n const ref = containers.get(handle.id)\n if (!ref)\n return\n\n try {\n try {\n await ref.container.stop({ t: 5 })\n }\n catch {\n // 304 (already stopped) / 404 (already gone) are expected here.\n // Any other stop failure must not prevent the remove({force})\n // below — force removal also works on running containers.\n }\n try {\n await ref.container.remove({ force: true })\n }\n catch (err) {\n if (!isGoneOrAlreadyStopped(err))\n throw err\n }\n }\n finally {\n containers.delete(handle.id)\n }\n },\n }\n\n return ctx\n}\n\n/**\n * Format one {@link ContextMount} as a dockerode `HostConfig.Binds` entry.\n * Supports read-only (`:ro`) and SELinux shared-label (`:z`) options; the two\n * are mutually exclusive (a read-only mount can't also be a shared rw mount).\n */\nfunction formatBindMount(mount: NonNullable<SpawnConfig['mounts']>[number]): string {\n if (!mount.source)\n throw new Error('Docker mount source is required')\n if (!mount.target || !mount.target.startsWith('/'))\n throw new Error(`Docker mount target must be an absolute path: ${mount.target}`)\n if (mount.readonly && mount.shared)\n throw new Error(`Docker mount cannot be both readonly and shared: ${mount.target}`)\n const opts = mount.readonly ? ':ro' : mount.shared ? ':z' : ''\n return `${mount.source}:${mount.target}${opts}`\n}\n\n/** Assemble dockerode `HostConfig.Binds` from the context's `mounts`. */\nexport function buildBindSpecs(mounts: NonNullable<SpawnConfig['mounts']>): string[] {\n return mounts.map(formatBindMount)\n}\n"],"mappings":";;;AAcA,MAAM,kBAAkB;;;;;AAMxB,SAAS,uBAAuB,KAAuB;CACrD,MAAM,OAAQ,KAAwC;CACtD,OAAO,SAAS,OAAO,SAAS;AAClC;AAQA,SAAgB,oBAAoB,QAAwC;CAC1E,IAAI,UAAU;CACd,MAAM,6BAAa,IAAI,IAA0B;CACjD,MAAM,eAAe,QAAQ,SAAS;CACtC,MAAM,aAAa,QAAQ,OAAO;CAClC,MAAM,aAAa,QAAQ;CAC3B,MAAM,gBAAgB,QAAQ;CAC9B,MAAM,gBAAgB,QAAQ,UAAU,CAAC;CACzC,MAAM,cAAc,QAAQ;CAE5B,eAAe,eAAe;EAC5B,IAAI;GACF,MAAM,aAAa,MAAM,OAAO,cAAc;GAC9C,OAAO,IAAI,UAAU;EACvB,QACM;GACJ,MAAM,IAAI,MAAM,wFAAwF;EAC1G;CACF;CAEA,MAAM,MAAwB;EAC5B,MAAM;EAEN,cAAc;GACZ,OAAO;GACP,YAAY;GACZ,MAAM;GACN,SAAS;GACT,KAAK;EACP;EAEA,MAAM,MAAM,WAAmD;GAC7D,MAAM,SAAS,MAAM,aAAa;GAClC,MAAM,KAAK,UAAU,EAAE;GACvB,MAAM,QAAQ,WAAW,SAAS;GAClC,MAAM,MAAM,WAAW,OAAO;GAC9B,MAAM,SAAS,CAAC,GAAG,eAAe,GAAI,WAAW,UAAU,CAAC,CAAE;GAC9D,MAAM,OAAO,WAAW,QAAQ;GAGhC,IAAI;IACF,MAAM,OAAO,SAAS,KAAK,EAAE,QAAQ;GACvC,QACM;IACJ,MAAM,IAAI,SAAe,SAAS,WAAW;KAC3C,OAAO,KAAK,QAAQ,KAAmB,WAAkC;MACvE,IAAI,KACF,OAAO,OAAO,GAAG;MACnB,OAAO,MAAM,eAAe,SAAS,SAAuB;OAC1D,OAAO,OAAO,IAAI,IAAI,QAAQ;MAChC,CAAC;KACH,CAAC;IACH,CAAC;GACH;GAEA,MAAM,SAAS;IAAE,GAAG;IAAe,GAAG,WAAW;GAAO;GACxD,MAAM,aAAsC,CAAC;GAE7C,IAAI,QAAQ,QACV,WAAW,SAAS,OAAO,SAAS,OAAO;GAE7C,IAAI,QAAQ,KACV,WAAW,WAAW,OAAO,WAAW,OAAO,GAAG,IAAI;GAIxD,MAAM,YAAY;IAAE,GAAG,QAAQ;IAAW,GAAG,WAAW;GAAU;GAClE,IAAI,UAAU,qBACZ,WAAW,UAAU,CAAC,KAAK;GAC7B,IAAI,UAAU,iBACZ,WAAW,cAAc,CAAC,mBAAmB;GAC/C,IAAI,UAAU,gBACZ,WAAW,iBAAiB;GAC9B,IAAI,UAAU,aAAa,MACzB,WAAW,YAAY,UAAU;GAEnC,MAAM,MAAM;IAAE,GAAG;IAAY,GAAG,WAAW;GAAI;GAE/C,MAAM,YAAY,eAAe,MAAM;GACvC,IAAI,UAAU,SAAS,GACrB,WAAW,QAAQ;GAGrB,MAAM,WAAW,WAAW,SAAS,QAAQ;GAC7C,MAAM,eAAsD,CAAC;GAC7D,MAAM,eAA4D,CAAC;GAEnE,IAAI,UAAU,QAAQ;IACpB,KAAK,MAAM,KAAK,UAAU;KACxB,MAAM,MAAM,GAAG,EAAE,UAAU,GAAG,EAAE,SAAS;KACzC,aAAa,OAAO,CAAC;KACrB,aAAa,OAAO,CAAC,EAAE,UAAU,EAAE,QAAQ,OAAO,KAAK,OAAO,EAAE,IAAI,EAAE,CAAC;IACzE;IACA,WAAW,eAAe;GAC5B;GAEA,MAAM,OAAO,WAAW,QAAQ,QAAQ;GACxC,MAAM,UAAU,WAAW,WAAW,QAAQ;GAC9C,IAAI,SACF,WAAW,cAAc;GAG3B,MAAM,SAAS;IAAE,GAAG,QAAQ;IAAQ,GAAG,WAAW;GAAO;GAEzD,MAAM,YAAY,MAAM,OAAO,gBAAgB;IAG7C,GAAI,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC;IACvF,OAAO;IACP,KAAK,CAAC,SAAS,UAAU;IACzB,YAAY;IACZ,KAAK,OAAO,QAAQ,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,GAAG,EAAE,GAAG,GAAG;IACpD,YAAY;IACZ,GAAI,OAAO,KAAK,YAAY,EAAE,SAAS,EAAE,cAAc,aAAa,IAAI,CAAC;IACzE,GAAI,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAI,OAAO,KAAK,MAAM,EAAE,SAAS,EAAE,QAAQ,OAAO,IAAI,CAAC;GACzD,CAAC;GAED,IAAI;IACF,MAAM,UAAU,MAAM;GACxB,SACO,KAAK;IAGV,MAAM,UAAU,OAAO,EAAE,OAAO,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC;IACtD,MAAM;GACR;GAEA,MAAM,SAA0B;IAAE;IAAI,MAAM;IAAU;GAAI;GAC1D,WAAW,IAAI,IAAI;IAAE;IAAQ;IAAW;GAAO,CAAC;GAEhD,OAAO;EACT;EAEA,MAAM,KAAK,QAAyB,SAAiB,SAAiG;GACpJ,MAAM,MAAM,WAAW,IAAI,OAAO,EAAE;GACpC,IAAI,CAAC,KACH,MAAM,IAAI,MAAM,aAAa,OAAO,GAAG,WAAW;GAEpD,MAAM,UAAU,SAAS,OAAO,OAAO;GACvC,MAAM,MAAM,SAAS,MACjB,OAAO,QAAQ,QAAQ,GAAG,EAAE,KAAK,CAAC,GAAG,OAAO,GAAG,EAAE,GAAG,GAAG,IACvD,CAAC;GAEL,MAAM,UAAU,SAAS,WAAW,eAAe,WAAW;GAE9D,MAAM,OAAO,MAAM,IAAI,UAAU,KAAK;IAOpC,KAAK;KAAC;KAAW,OAAO,OAAO;KAAG;KAAM;KAAM;IAAO;IACrD,YAAY;IACZ,KAAK;IACL,cAAc;IACd,cAAc;GAChB,CAAC;GAED,MAAM,SAAS,MAAM,KAAK,MAAM,EAAE,QAAQ,MAAM,CAAC;GAEjD,OAAO,IAAI,SAAqB,YAAY;IAC1C,IAAI,SAAS;IACb,IAAI,SAAS;IACb,IAAI,WAAW;IAMf,MAAM,aAAa;KACjB,MAAM,OAAwB;MAC5B,UAAU,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS,OAAO;MACpE,OAAO;KACT;KACA,MAAM,CAAC;KACP,KAAK,CAAC;KACN,OAAO,CAAC;KACR,OAAO;MAAE,OAAO;KAAK;IACvB;IACA,MAAM,aAAa;KACjB,MAAM,OAAwB;MAC5B,UAAU,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS,OAAO;MACpE,OAAO;KACT;KACA,MAAM,CAAC;KACP,KAAK,CAAC;KACN,OAAO,CAAC;KACR,OAAO;MAAE,OAAO;KAAK;IACvB;IACA,IAAI;KACF,IAAI,OAAO,MAAM,YAAY,QAAQ,YAAY,UAAU;IAC7D,QACM;KAGJ,OAAO,GAAG,SAAS,UAAkB;MACnC,UAAU,MAAM,SAAS,OAAO;KAClC,CAAC;IACH;IAKA,MAAM,QAAQ,iBAAiB;KAC7B,IAAI,UACF;KACF,WAAW;KAGX,IAAI;MAAE,OAAO,UAAU;KAAE,QACnB,CAAgB;KACtB,QAAQ;MAAE;MAAQ,QAAQ,SAAS,GAAG,OAAO,eAAe;MAAa,UAAU;KAAI,CAAC;IAC1F,GAAG,UAAU,MAAO,GAAI;IAExB,OAAO,GAAG,OAAO,YAAY;KAC3B,IAAI,UACF;KACF,WAAW;KACX,aAAa,KAAK;KAClB,IAAI;KACJ,IAAI,cAAc;KAClB,IAAI;MACF,MAAM,UAAU,MAAM,KAAK,QAAQ;MAInC,IAAI,QAAQ,YAAY,MAAM;OAC5B,WAAW;OACX,cAAc;MAChB,OAEE,WAAW,QAAQ;KAEvB,SACO,KAAK;MACV,WAAW;MACX,cAAc,gDAAiD,KAAe,WAAW,OAAO,GAAG,EAAE;KACvG;KACA,QAAQ;MACN;MACA,QAAQ,cAAe,SAAS,GAAG,OAAO,IAAI,gBAAgB,cAAe;MAC7E;KACF,CAAC;IACH,CAAC;IAED,OAAO,GAAG,UAAU,QAAe;KACjC,IAAI,UACF;KACF,WAAW;KACX,aAAa,KAAK;KAClB,QAAQ;MAAE;MAAQ,QAAQ,SAAS,GAAG,OAAO,IAAI,IAAI,YAAY,IAAI;MAAS,UAAU;KAAE,CAAC;IAC7F,CAAC;GACH,CAAC;EACH;EAKA,MAAM,SAAS,QAAyB,MAA+B;GACrE,MAAM,SAAS,MAAM,IAAI,KAAK,QAAQ,OAAO,YAAY,IAAI,GAAG;GAChE,IAAI,OAAO,aAAa,GACtB,MAAM,IAAI,MAAM,wBAAwB,OAAO,QAAQ;GACzD,OAAO,OAAO;EAChB;EAEA,MAAM,UAAU,QAAyB,MAAc,SAAgC;GACrF,MAAM,UAAU,QAAQ,QAAQ,iBAAiB,OAAO,GAAG,MAAM;GACjE,MAAM,SAAS,MAAM,IAAI,KAAK,QAAQ,uBAAuB,YAAY,IAAI,EAAE,qBAAqB,QAAQ,MAAM,YAAY,IAAI,GAAG;GACrI,IAAI,OAAO,aAAa,GACtB,MAAM,IAAI,MAAM,yBAAyB,OAAO,QAAQ;EAC5D;EAEA,MAAM,UAAU,QAAyB,MAAc,SAAoC;GACzF,IAAI,SAAS,MACX,OAAO,kBAAkB,OAAM,YAAW,IAAI,KAAK,QAAQ,OAAO,GAAG,SAAS,SAAS,GAAI;GAC7F,MAAM,SAAS,MAAM,IAAI,KAAK,QAAQ,SAAS,YAAY,IAAI,GAAG;GAClE,IAAI,OAAO,aAAa,GACtB,OAAO,CAAC;GACV,OAAO,OAAO,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,OAAO,OAAO;EACxD;EAEA,MAAM,cAAc,QAAyB,eAA+C;GAC1F,MAAM,MAAM,WAAW,IAAI,OAAO,EAAE;GACpC,IAAI,CAAC,KACH,OAAO;GAGT,MAAM,YAAW,MADE,IAAI,UAAU,QAAQ,IAClB,iBAAiB,SAAS,CAAC;GAElD,KAAK,MAAM,SAAS,CAAC,OAAO,KAAK,GAAG;IAClC,MAAM,OAAO,SAAS,GAAG,cAAc,GAAG;IAC1C,IAAI,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,KAAK,KAAK,IAAI,UACrD,OAAO,OAAO,SAAS,KAAK,GAAG,UAAU,EAAE;GAE/C;GAEA,OAAO;EACT;EAEA,MAAM,QAAQ,QAAwC;GACpD,MAAM,MAAM,WAAW,IAAI,OAAO,EAAE;GACpC,IAAI,CAAC,KACH;GAEF,IAAI;IACF,IAAI;KACF,MAAM,IAAI,UAAU,KAAK,EAAE,GAAG,EAAE,CAAC;IACnC,QACM,CAIN;IACA,IAAI;KACF,MAAM,IAAI,UAAU,OAAO,EAAE,OAAO,KAAK,CAAC;IAC5C,SACO,KAAK;KACV,IAAI,CAAC,uBAAuB,GAAG,GAC7B,MAAM;IACV;GACF,UACQ;IACN,WAAW,OAAO,OAAO,EAAE;GAC7B;EACF;CACF;CAEA,OAAO;AACT;;;;;;AAOA,SAAS,gBAAgB,OAA2D;CAClF,IAAI,CAAC,MAAM,QACT,MAAM,IAAI,MAAM,iCAAiC;CACnD,IAAI,CAAC,MAAM,UAAU,CAAC,MAAM,OAAO,WAAW,GAAG,GAC/C,MAAM,IAAI,MAAM,iDAAiD,MAAM,QAAQ;CACjF,IAAI,MAAM,YAAY,MAAM,QAC1B,MAAM,IAAI,MAAM,oDAAoD,MAAM,QAAQ;CACpF,MAAM,OAAO,MAAM,WAAW,QAAQ,MAAM,SAAS,OAAO;CAC5D,OAAO,GAAG,MAAM,OAAO,GAAG,MAAM,SAAS;AAC3C;;AAGA,SAAgB,eAAe,QAAsD;CACnF,OAAO,OAAO,IAAI,eAAe;AACnC"}
@@ -1,5 +1,5 @@
1
1
  import { t as SandboxProvider } from "../sandbox-B-bMq3K6.js";
2
- import { a as Logger } from "../logger-C2ngE8CY.js";
2
+ import { a as Logger } from "../logger-CJ-lpKPy.js";
3
3
 
4
4
  //#region src/contexts/e2b.d.ts
5
5
  interface E2BCommandResult {
@@ -0,0 +1,203 @@
1
+ //#region src/errors.d.ts
2
+ /**
3
+ * Typed error classes for agent runs.
4
+ *
5
+ * Providers classify native errors into one of these so downstream consumers
6
+ * can react without string-sniffing messages.
7
+ *
8
+ * Provider authors: implement `Provider.classifyError` to map native errors
9
+ * (SDK exceptions, HTTP responses) to a `ClassifiedError`. The loop wraps
10
+ * unclassified errors in `AgentProviderError` automatically.
11
+ */
12
+ /** Kind of classified provider error */
13
+ type ClassifiedErrorKind = 'context_exceeded' | 'provider_error' | 'aborted' | 'tool_pairing_corruption';
14
+ /** Structured classification returned by `Provider.classifyError` */
15
+ interface ClassifiedError {
16
+ kind: ClassifiedErrorKind;
17
+ /** Upstream error code as surfaced by the provider (e.g. `context_length_exceeded`). Optional. */
18
+ providerCode?: string;
19
+ /** Optional human-readable message override. Falls back to the underlying error's message. */
20
+ message?: string;
21
+ /**
22
+ * Hint that the error is transient and a retry with backoff is reasonable
23
+ * (e.g. 429, 5xx, truncated stream). Omitted when the provider can't decide;
24
+ * callers should default to "do not retry" when absent to avoid hammering
25
+ * terminal failures (auth, invalid request).
26
+ */
27
+ retryable?: boolean;
28
+ }
29
+ interface TypedErrorOptions {
30
+ /** Provider name, always set (e.g. `anthropic`, `openrouter`) */
31
+ provider: string;
32
+ /** Optional upstream error code */
33
+ providerCode?: string;
34
+ /** Original error from the provider SDK/HTTP layer */
35
+ cause?: unknown;
36
+ /** See {@link ClassifiedError.retryable}. */
37
+ retryable?: boolean;
38
+ }
39
+ /**
40
+ * Thrown when the model or provider signals that the context window was exceeded.
41
+ * Downstream consumers should catch this, prune history, and retry.
42
+ */
43
+ declare class AgentContextExceededError extends Error {
44
+ readonly code: "context_exceeded";
45
+ readonly provider: string;
46
+ readonly providerCode?: string;
47
+ constructor(message: string, options: TypedErrorOptions);
48
+ }
49
+ /**
50
+ * Thrown when the provider returns a non-context error (auth, rate limit, server error, etc.).
51
+ * Catch-all for unclassified provider failures.
52
+ */
53
+ declare class AgentProviderError extends Error {
54
+ readonly code: "provider_error";
55
+ readonly provider: string;
56
+ readonly providerCode?: string;
57
+ /**
58
+ * Whether a retry with backoff is likely to succeed. See
59
+ * {@link ClassifiedError.retryable}. Absent when the provider did not
60
+ * classify the error — callers should treat absent as "don't retry".
61
+ */
62
+ readonly retryable?: boolean;
63
+ constructor(message: string, options: TypedErrorOptions);
64
+ }
65
+ /**
66
+ * Thrown when a run is aborted by the consumer via `agent.abort()` or an external `AbortSignal`.
67
+ */
68
+ declare class AgentAbortedError extends Error {
69
+ readonly code: "aborted";
70
+ constructor(message?: string, options?: {
71
+ cause?: unknown;
72
+ });
73
+ }
74
+ /**
75
+ * Thrown by the loop when a run's cumulative cost, token consumption, or
76
+ * wall-clock elapsed time crosses a ceiling configured on
77
+ * {@link AgentBehavior.maxCostUsd} / {@link AgentBehavior.maxTotalTokens} /
78
+ * {@link AgentBehavior.maxWallMs}. Acts as a programmable circuit
79
+ * breaker for unattended runs — without this, the only built-in safety net
80
+ * is {@link AgentBehavior.maxTurns}, which doesn't bound a single very
81
+ * expensive turn (large context, deep reasoning).
82
+ *
83
+ * The breach is checked **after** each turn completes (post-`turn:after`),
84
+ * so the run may exceed the budget by one turn's worth of usage before
85
+ * tripping. Callers wanting a tighter pre-turn estimate should layer their
86
+ * own check on top of the `usage` hook.
87
+ *
88
+ * The harness treats this the same way as {@link AgentAbortedError}: the
89
+ * session run is finalized as `'aborted'`, persisted stats reflect what
90
+ * was actually consumed, and the parent agent re-throws so a caller's
91
+ * `try`/`catch` can branch on `err instanceof AgentBudgetExceededError`
92
+ * without string-sniffing.
93
+ */
94
+ declare class AgentBudgetExceededError extends Error {
95
+ readonly code: "budget_exceeded";
96
+ /** Which ceiling tripped. `'cost'` → `maxCostUsd`, `'tokens'` → `maxTotalTokens`, `'wallClock'` → `maxWallMs`. */
97
+ readonly limit: 'cost' | 'tokens' | 'wallClock';
98
+ /** The configured cap (USD for `cost`, total tokens for `tokens`, ms for `wallClock`). */
99
+ readonly limitValue: number;
100
+ /** Actual consumed value at the moment the cap was crossed (same units as `limitValue`). */
101
+ readonly actualValue: number;
102
+ constructor(options: {
103
+ limit: 'cost' | 'tokens' | 'wallClock';
104
+ limitValue: number;
105
+ actualValue: number;
106
+ cause?: unknown;
107
+ });
108
+ }
109
+ /**
110
+ * Thrown by the pre-send pairing repair when {@link AgentBehavior.strictToolPairing}
111
+ * is `true` and {@link ensureToolResultPairing} would otherwise patch over
112
+ * corruption. Strict mode opts into fail-fast for training-data collectors and
113
+ * any consumer that prefers to bail out rather than ship a transcript carrying
114
+ * a {@link SYNTHETIC_TOOL_RESULT_PLACEHOLDER}.
115
+ *
116
+ * The `repairs` field carries every repair the loop would have made — useful
117
+ * for postmortems and for surfacing exactly which transcripts were rejected.
118
+ *
119
+ * Note: callers consuming the chat layer (TUI/SDK presets) typically leave
120
+ * `strictToolPairing` off so user-facing sessions auto-heal instead of
121
+ * crashing.
122
+ */
123
+ declare class AgentToolPairingError extends Error {
124
+ readonly code: "tool_pairing_corruption";
125
+ /** Provider whose wire format the corruption would have hit. */
126
+ readonly provider?: string;
127
+ /** Upstream error code when the corruption was detected from a 400 response. */
128
+ readonly providerCode?: string;
129
+ /**
130
+ * Repairs the harness would have performed had strict mode been off.
131
+ * Preserves the full diagnostic so consumers can route to telemetry,
132
+ * `/rewind` flows, or training-data quarantine without re-walking the
133
+ * transcript.
134
+ */
135
+ readonly repairs: ReadonlyArray<{
136
+ mode: string;
137
+ callId?: string;
138
+ messageIndex: number;
139
+ }>;
140
+ constructor(options: {
141
+ message: string;
142
+ provider?: string;
143
+ providerCode?: string;
144
+ repairs: ReadonlyArray<{
145
+ mode: string;
146
+ callId?: string;
147
+ messageIndex: number;
148
+ }>;
149
+ cause?: unknown;
150
+ });
151
+ }
152
+ /**
153
+ * Thrown (well — constructed; attach via the `tool:gate` block signal) when the
154
+ * union of `allowed-tools` across active skills does not permit a tool call.
155
+ *
156
+ * Produced by the allowed-tools middleware registered on `tool:gate` /
157
+ * `mcp:tool:gate`. The gate's `block = true` + `reason` carry the same message
158
+ * so consumers that don't look at this typed error still get a useful string.
159
+ */
160
+ declare class AgentToolNotAllowedError extends Error {
161
+ readonly code: "tool_not_allowed";
162
+ /** Canonical tool name the agent tried to call. */
163
+ readonly toolName: string;
164
+ /** Aliased / wire name the LLM saw. */
165
+ readonly displayName: string;
166
+ /** Flattened union of `allowedTools` patterns across active skills. */
167
+ readonly allowedUnion: readonly string[];
168
+ /** Names of the skills currently active when the block fired. */
169
+ readonly activeSkills: readonly string[];
170
+ constructor(options: {
171
+ toolName: string;
172
+ displayName: string;
173
+ allowedUnion: readonly string[];
174
+ activeSkills: readonly string[];
175
+ cause?: unknown;
176
+ });
177
+ }
178
+ /**
179
+ * Regex patterns matching common "context window exceeded" messages across providers.
180
+ *
181
+ * Use {@link matchesContextExceeded} to test a free-form error message against them.
182
+ * Provider authors can also compose these into their own `classifyError` fallbacks.
183
+ */
184
+ declare const CONTEXT_EXCEEDED_MESSAGE_PATTERNS: readonly RegExp[];
185
+ /**
186
+ * Return true when `message` matches any of the known "context window exceeded"
187
+ * phrasings. Safe for `''` / non-strings (returns false).
188
+ */
189
+ declare function matchesContextExceeded(message: unknown): boolean;
190
+ /**
191
+ * Extract a printable message from an unknown thrown value.
192
+ *
193
+ * Standardizes the `err instanceof Error ? err.message : String(err)` idiom
194
+ * that every `catch (err)` block was reaching for.
195
+ */
196
+ declare function errorMessage(err: unknown): string;
197
+ /**
198
+ * Convert a `ClassifiedError` + underlying cause into the matching typed error instance.
199
+ */
200
+ declare function toTypedError(classification: ClassifiedError, provider: string, cause: unknown): AgentContextExceededError | AgentProviderError | AgentAbortedError | AgentToolPairingError;
201
+ //#endregion
202
+ export { AgentToolNotAllowedError as a, ClassifiedError as c, matchesContextExceeded as d, toTypedError as f, AgentProviderError as i, ClassifiedErrorKind as l, AgentBudgetExceededError as n, AgentToolPairingError as o, AgentContextExceededError as r, CONTEXT_EXCEEDED_MESSAGE_PATTERNS as s, AgentAbortedError as t, errorMessage as u };
203
+ //# sourceMappingURL=errors-CkTvg97v.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors-CkTvg97v.d.ts","names":[],"sources":["../src/errors.ts"],"mappings":";;AAYA;;;;AAA+B;AAG/B;;;;;KAHY,mBAAA;;UAGK,eAAA;EACf,IAAA,EAAM,mBAAmB;EAWhB;EATT,YAAA;EAYQ;EAVR,OAAA;;;;;;;EAOA,SAAA;AAAA;AAAA,UAGQ,iBAAA;EAe6B;EAbrC,QAAA;EAakD;EAXlD,YAAA;EAYS;EAVT,KAAA;EAYS;EAVT,SAAA;AAAA;;;;AAYuD;cAL5C,yBAAA,SAAkC,KAAK;EAAA,SACzC,IAAA;EAAA,SACA,QAAA;EAAA,SACA,YAAA;cAEG,OAAA,UAAiB,OAAA,EAAS,iBAAA;AAAA;;;;;cAY3B,kBAAA,SAA2B,KAAK;EAAA,SAClC,IAAA;EAAA,SACA,QAAA;EAAA,SACA,YAAA;EAQ8C;AAYzD;;;;EAZyD,SAF9C,SAAA;cAEG,OAAA,UAAiB,OAAA,EAAS,iBAAA;AAAA;;;;cAY3B,iBAAA,SAA0B,KAAK;EAAA,SACjC,IAAA;cAEG,OAAA,WAA+B,OAAA;IAAY,KAAA;EAAA;AAAA;;;;;;;;;;;;;AAwCtD;AA2BH;;;;;;;cAzCa,wBAAA,SAAiC,KAAK;EAAA,SACxC,IAAA;EAyCA;EAAA,SAvCA,KAAA;EA2CA;EAAA,SAzCA,UAAA;EAgDS;EAAA,SA9CT,WAAA;cAEG,OAAA;IACV,KAAA;IACA,UAAA;IACA,WAAA;IACA,KAAA;EAAA;AAAA;;;;;;;;AAoDD;AAiBH;;;;;;cAzCa,qBAAA,SAA8B,KAAA;EAAA,SAChC,IAAA;EA+CA;EAAA,SA7CA,QAAA;;WAEA,YAAA;EAiDP;;;;;;EAAA,SA1CO,OAAA,EAAS,aAAA;IAChB,IAAA;IACA,MAAA;IACA,YAAA;EAAA;cAGU,OAAA;IACV,OAAA;IACA,QAAA;IACA,YAAA;IACA,OAAA,EAAS,aAAA;MAAgB,IAAA;MAAc,MAAA;MAAiB,YAAA;IAAA;IACxD,KAAA;EAAA;AAAA;;;;;;;;;cAkBS,wBAAA,SAAiC,KAAK;EAAA,SACxC,IAAA;EAiKT;EAAA,SA/JS,QAAA;EAiKT;EAAA,SA/JS,WAAA;EAgKoB;EAAA,SA9JpB,YAAA;EA8J6D;EAAA,SA5J7D,YAAA;cAEG,OAAA;IACV,QAAA;IACA,WAAA;IACA,YAAA;IACA,YAAA;IACA,KAAA;EAAA;AAAA;;;;;;;cA+BS,iCAAA,WAA4C,MAAM;;;;;iBA8B/C,sBAAA,CAAuB,OAAgB;;;;;;;iBA0DvC,YAAA,CAAa,GAAY;;;;iBA0BzB,YAAA,CACd,cAAA,EAAgB,eAAA,EAChB,QAAA,UACA,KAAA,YACC,yBAAA,GAA4B,kBAAA,GAAqB,iBAAA,GAAoB,qBAAA"}
@@ -0,0 +1,3 @@
1
+ import { a as AgentToolNotAllowedError, c as ClassifiedError, d as matchesContextExceeded, f as toTypedError, i as AgentProviderError, l as ClassifiedErrorKind, n as AgentBudgetExceededError, o as AgentToolPairingError, r as AgentContextExceededError, s as CONTEXT_EXCEEDED_MESSAGE_PATTERNS, t as AgentAbortedError, u as errorMessage } from "./errors-CkTvg97v.js";
2
+ import { t as OperationTimeoutError } from "./timeout-CpFm0jJ6.js";
3
+ export { AgentAbortedError, AgentBudgetExceededError, AgentContextExceededError, AgentProviderError, AgentToolNotAllowedError, AgentToolPairingError, CONTEXT_EXCEEDED_MESSAGE_PATTERNS, type ClassifiedError, type ClassifiedErrorKind, OperationTimeoutError, errorMessage, matchesContextExceeded, toTypedError };
package/dist/errors.js ADDED
@@ -0,0 +1,3 @@
1
+ import { a as AgentToolNotAllowedError, f as matchesContextExceeded, i as AgentProviderError, l as errorMessage, m as toTypedError, n as AgentBudgetExceededError, o as AgentToolPairingError, r as AgentContextExceededError, s as CONTEXT_EXCEEDED_MESSAGE_PATTERNS, t as AgentAbortedError } from "./errors-DJUxZg9b.js";
2
+ import { t as OperationTimeoutError } from "./timeout-kGGSXagK.js";
3
+ export { AgentAbortedError, AgentBudgetExceededError, AgentContextExceededError, AgentProviderError, AgentToolNotAllowedError, AgentToolPairingError, CONTEXT_EXCEEDED_MESSAGE_PATTERNS, OperationTimeoutError, errorMessage, matchesContextExceeded, toTypedError };
package/dist/eval.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $t as buildEvalRunSummary, At as EvalRunSummary, Bt as EvalWorkspaceSnapshot, Cn as relativeArtifactPath, Ct as EvalDefinition, Dt as EvalRunMetricAggregate, Et as EvalMetricError, Ft as EvalScorerContext, Gt as MetricSpecMap, Ht as MetricDirection, It as EvalTestRunner, Jt as ReusableExecutionContext, Kt as MetricStats, Lt as EvalVariantSummary, Mt as EvalRunUsage, Nt as EvalScore, Ot as EvalRunReporter, Pt as EvalScorer, Qt as artifactPath, Rt as EvalWorkspaceFile, Sn as registerEvalTests, St as EvalCaseResult, Tn as statusCompleted, Tt as EvalMetric, Ut as MetricEmitter, Vt as LlmJudgeOptions, Wt as MetricSpec, Xt as TrajectoryStep, Yt as Trajectory, Zt as TrajectoryStepKind, _n as formatEvalRunSummary, _t as EvalAgentRunResult, an as createEvalRunReporter, bn as llmJudge, bt as EvalArtifacts, cn as defineMetrics, dn as fileContains, en as buildRegisteredEvals, fn as fileContentQuality, ft as CreateEvalAgentOptions, gn as formatEvalCaseSummary, gt as EvalAgentRunOptions, hn as finalizeEvalMetrics, ht as EvalAgentMcpServers, in as createEvalAgent, jt as EvalRunSummaryCase, kt as EvalRunReporterOptions, ln as efficiencyMetricValues, mn as fileExistsOneOf, mt as EvalAgent, nn as clearRegisteredEvals, on as createReusableExecutionContext, pn as fileExists, pt as EFFICIENCY_METRICS, qt as RegisterEvalTestsOptions, rn as computeEvalTagScores, sn as defineEval, tn as buildTrajectory, un as emitEfficiencyMetrics, vn as formatTrajectoryLine, vt as EvalAgentRunStats, wn as runEvalCase, wt as EvalDefinitionContext, xn as normalizeMetric, xt as EvalCaseOptions, yn as functionalityMetric, yt as EvalAgentStats, zt as EvalWorkspaceOptions } from "./index-YY3vp2F2.js";
1
+ import { $t as createReusableExecutionContext, At as EvalVariantSummary, Bt as RegisterEvalTestsOptions, Ct as EvalRunSummary, Dt as EvalScorer, Et as EvalScore, Ft as MetricDirection, Gt as artifactPath, Ht as Trajectory, It as MetricEmitter, Jt as buildTrajectory, Kt as buildEvalRunSummary, Lt as MetricSpec, Mt as EvalWorkspaceOptions, Nt as EvalWorkspaceSnapshot, Ot as EvalScorerContext, Pt as LlmJudgeOptions, Qt as createEvalRunReporter, Rt as MetricSpecMap, St as EvalRunReporterOptions, Tt as EvalRunUsage, Ut as TrajectoryStep, Vt as ReusableExecutionContext, Wt as TrajectoryStepKind, Xt as computeEvalTagScores, Yt as clearRegisteredEvals, Zt as createEvalAgent, _n as runEvalCase, _t as EvalDefinitionContext, an as fileContentQuality, at as CreateEvalAgentOptions, bt as EvalRunMetricAggregate, cn as finalizeEvalMetrics, ct as EvalAgentMcpServers, dn as formatTrajectoryLine, dt as EvalAgentRunStats, en as defineEval, fn as functionalityMetric, ft as EvalAgentStats, gn as relativeArtifactPath, gt as EvalDefinition, hn as registerEvalTests, ht as EvalCaseResult, in as fileContains, jt as EvalWorkspaceFile, kt as EvalTestRunner, ln as formatEvalCaseSummary, lt as EvalAgentRunOptions, mn as normalizeMetric, mt as EvalCaseOptions, nn as efficiencyMetricValues, on as fileExists, ot as EFFICIENCY_METRICS, pn as llmJudge, pt as EvalArtifacts, qt as buildRegisteredEvals, rn as emitEfficiencyMetrics, sn as fileExistsOneOf, st as EvalAgent, tn as defineMetrics, un as formatEvalRunSummary, ut as EvalAgentRunResult, vn as statusCompleted, vt as EvalMetric, wt as EvalRunSummaryCase, xt as EvalRunReporter, yt as EvalMetricError, zt as MetricStats } from "./index-CLuLFFLa.js";
2
2
  export { CreateEvalAgentOptions, EFFICIENCY_METRICS, EvalAgent, EvalAgentMcpServers, EvalAgentRunOptions, EvalAgentRunResult, EvalAgentRunStats, EvalAgentStats, EvalArtifacts, EvalCaseOptions, EvalCaseResult, EvalDefinition, EvalDefinitionContext, EvalMetric, EvalMetricError, EvalRunMetricAggregate, EvalRunReporter, EvalRunReporterOptions, EvalRunSummary, EvalRunSummaryCase, EvalRunUsage, EvalScore, EvalScorer, EvalScorerContext, EvalTestRunner, EvalVariantSummary, EvalWorkspaceFile, EvalWorkspaceOptions, EvalWorkspaceSnapshot, LlmJudgeOptions, MetricDirection, MetricEmitter, MetricSpec, MetricSpecMap, MetricStats, RegisterEvalTestsOptions, ReusableExecutionContext, Trajectory, TrajectoryStep, TrajectoryStepKind, artifactPath, buildEvalRunSummary, buildRegisteredEvals, buildTrajectory, clearRegisteredEvals, computeEvalTagScores, createEvalAgent, createEvalRunReporter, createReusableExecutionContext, defineEval, defineMetrics, efficiencyMetricValues, emitEfficiencyMetrics, fileContains, fileContentQuality, fileExists, fileExistsOneOf, finalizeEvalMetrics, formatEvalCaseSummary, formatEvalRunSummary, formatTrajectoryLine, functionalityMetric, llmJudge, normalizeMetric, registerEvalTests, relativeArtifactPath, runEvalCase, statusCompleted };
package/dist/eval.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { n as createProcessContext } from "./contexts-BebciJyQ.js";
2
2
  import { t as alwaysQuote } from "./shell-quote-BmnhZmdM.js";
3
- import { a as headlessEventToJsonl, c as runHeadless } from "./headless-2SH7dvoW.js";
4
- import { a as createMemoryStore, t as createSession } from "./session-CiA1_8SB.js";
3
+ import { a as createMemoryStore, t as createSession } from "./session-CqrAFAKJ.js";
4
+ import { headlessEventToJsonl, runHeadless } from "./headless.js";
5
5
  import { join, relative, resolve } from "node:path";
6
6
  import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
7
7
  import { tmpdir } from "node:os";
@@ -1,2 +1,2 @@
1
- import { An as HeadlessOptions, Bn as formatHeadlessTurnEvent, Dn as FormattedHeadlessTurnEvent, En as FormattedHeadlessResult, Fn as OpenAIChatContentPart, Gn as runHeadless, Hn as headlessEventToJsonl, In as OpenAIChatMessage, Kn as transcriptToOpenAIMessages, Ln as ProviderTranscriptFormat, Mn as HeadlessResult, Nn as HeadlessStatus, On as HeadlessErrorInfo, Pn as HeadlessUsage, Rn as exitCodeForHeadlessResult, Un as installHeadlessEventAdapter, Vn as formattedHeadlessTurnEventToJsonl, Wn as providerTranscriptFormatForProvider, jn as HeadlessOutputFormat, kn as HeadlessEvent, qn as transcriptToProviderMessages, zn as formatHeadlessResult } from "./index-YY3vp2F2.js";
1
+ import { An as ProviderTranscriptFormat, Bn as transcriptToProviderMessages, Cn as HeadlessOptions, Dn as HeadlessUsage, En as HeadlessStatus, Fn as headlessEventToJsonl, In as installHeadlessEventAdapter, Ln as providerTranscriptFormatForProvider, Mn as formatHeadlessResult, Nn as formatHeadlessTurnEvent, On as OpenAIChatContentPart, Pn as formattedHeadlessTurnEventToJsonl, Rn as runHeadless, Sn as HeadlessEvent, Tn as HeadlessResult, bn as FormattedHeadlessTurnEvent, jn as exitCodeForHeadlessResult, kn as OpenAIChatMessage, wn as HeadlessOutputFormat, xn as HeadlessErrorInfo, yn as FormattedHeadlessResult, zn as transcriptToOpenAIMessages } from "./index-CLuLFFLa.js";
2
2
  export { FormattedHeadlessResult, FormattedHeadlessTurnEvent, HeadlessErrorInfo, HeadlessEvent, HeadlessOptions, HeadlessOutputFormat, HeadlessResult, HeadlessStatus, HeadlessUsage, OpenAIChatContentPart, OpenAIChatMessage, ProviderTranscriptFormat, exitCodeForHeadlessResult, formatHeadlessResult, formatHeadlessTurnEvent, formattedHeadlessTurnEventToJsonl, headlessEventToJsonl, installHeadlessEventAdapter, providerTranscriptFormatForProvider, runHeadless, transcriptToOpenAIMessages, transcriptToProviderMessages };