// src/runtime/util.ts
async function deleteBoxSafe(box) {
  if (!box || typeof box.delete !== "function") return true;
  try {
    await box.delete();
    return true;
  } catch {
    return false;
  }
}
function randomSuffix(len = 8) {
  return Math.random().toString(36).slice(2, 2 + len);
}
function randomUuid() {
  return crypto.randomUUID();
}
function abortError() {
  const err = new Error("aborted");
  err.name = "AbortError";
  return err;
}
function throwAbort() {
  throw abortError();
}
function throwIfAborted(signal) {
  if (signal?.aborted) throw abortError();
}
function isAbortError(err) {
  return err instanceof Error && err.name === "AbortError";
}
function sleep(ms, signal) {
  return new Promise((resolve) => {
    if (signal?.aborted) {
      resolve();
      return;
    }
    let onAbort;
    const timer = setTimeout(() => {
      if (onAbort && signal) signal.removeEventListener("abort", onAbort);
      resolve();
    }, ms);
    if (signal) {
      onAbort = () => {
        clearTimeout(timer);
        resolve();
      };
      signal.addEventListener("abort", onAbort, { once: true });
    }
  });
}
function withTimeout(promise, ms) {
  return new Promise((resolve) => {
    const timer = setTimeout(() => resolve(void 0), ms);
    promise.then(
      (value) => {
        clearTimeout(timer);
        resolve(value);
      },
      () => {
        clearTimeout(timer);
        resolve(void 0);
      }
    );
  });
}
function stringifySafe(value, opts = {}) {
  let s;
  try {
    if (typeof value === "string") {
      s = value;
    } else {
      const json = opts.pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);
      s = json ?? String(value);
    }
  } catch {
    s = String(value);
  }
  if (opts.max !== void 0 && s.length > opts.max) return `${s.slice(0, opts.max)}\u2026`;
  return s;
}
function zeroTokenUsage() {
  return { input: 0, output: 0 };
}
function addTokenUsage(acc, delta) {
  acc.input += delta.input ?? 0;
  acc.output += delta.output ?? 0;
}
async function mapWithConcurrency(items, limit, fn) {
  const bound = Math.max(1, Math.floor(limit));
  const results = new Array(items.length);
  let next = 0;
  let failed = false;
  const worker = async () => {
    while (!failed) {
      const i = next;
      next += 1;
      if (i >= items.length) return;
      try {
        results[i] = await fn(items[i], i);
      } catch (err) {
        failed = true;
        throw err;
      }
    }
  };
  const workerCount = Math.min(bound, items.length);
  await Promise.all(Array.from({ length: workerCount }, () => worker()));
  return results;
}

// src/runtime/environment-provider.ts
var ValidationError = class extends Error {
  constructor(message, options) {
    super(message, options);
    this.name = "ValidationError";
  }
};
function createAgentEnvironmentProviderRegistry(providers = []) {
  const entries = /* @__PURE__ */ new Map();
  const registry = {
    register(provider, options = {}) {
      if (!provider.name) {
        throw new ValidationError("agent environment provider registry: provider.name required");
      }
      if (!options.replace && entries.has(provider.name)) {
        throw new ValidationError(
          `agent environment provider registry: provider "${provider.name}" already registered`
        );
      }
      entries.set(provider.name, provider);
    },
    has(name) {
      return entries.has(name);
    },
    get(name) {
      return entries.get(name);
    },
    require(name) {
      const provider = entries.get(name);
      if (!provider) {
        const available = Array.from(entries.keys()).sort();
        const suffix = available.length > 0 ? `; available: ${available.join(", ")}` : "";
        throw new ValidationError(
          `agent environment provider registry: provider "${name}" is not registered${suffix}`
        );
      }
      return provider;
    },
    names() {
      return Array.from(entries.keys()).sort();
    },
    providers() {
      return registry.names().map((name) => registry.require(name));
    },
    async capabilities(name) {
      return registry.require(name).capabilities();
    }
  };
  for (const provider of providers) registry.register(provider);
  return registry;
}
function resolveAgentEnvironmentProvider(provider, registry) {
  if (typeof provider !== "string") return provider;
  if (!registry) {
    throw new ValidationError(
      `agent environment provider "${provider}" requires an AgentEnvironmentProviderRegistry`
    );
  }
  return registry.require(provider);
}
function providerAsSandboxClient(provider, options = {}) {
  return {
    async create(createOptions) {
      const mapped = {
        ...options.defaults ?? {},
        ...createInputFromSandboxOptions(createOptions),
        ...options.mapCreateOptions?.(createOptions) ?? {}
      };
      if (mapped.profile === void 0) {
        throw new ValidationError(
          `providerAsSandboxClient(${provider.name}): profile required in defaults or CreateSandboxOptions.backend.profile`
        );
      }
      const environment = await provider.create(mapped);
      return environmentAsSandboxInstance(environment, {
        requireTerminalEvent: options.requireTerminalEvent ?? true
      });
    }
  };
}
function sandboxClientAsProvider(client, options = {}) {
  const providerName = options.name ?? "tangle-sandbox";
  return {
    name: providerName,
    capabilities: async () => {
      if (options.capabilities) {
        return typeof options.capabilities === "function" ? options.capabilities() : options.capabilities;
      }
      return defaultTangleSandboxCapabilities();
    },
    ...options.validateProfile ? { validateProfile: options.validateProfile } : {},
    async create(input) {
      const createOptions = options.mapCreateInput?.(input) ?? sandboxOptionsFromCreateInput(input, options.defaultBackend ?? "opencode");
      const box = await client.create(createOptions);
      return sandboxInstanceAsEnvironment(box, providerName, client);
    },
    ...hasGet(client) ? {
      async get(id) {
        const box = await client.get(id);
        return box ? sandboxInstanceAsEnvironment(box, providerName, client) : null;
      }
    } : {},
    ...hasList(client) ? {
      async list(query) {
        const boxes = await client.list(query?.providerOptions);
        return boxes.map((box) => ({
          id: String(box.id),
          provider: providerName,
          name: typeof box.name === "string" ? box.name : void 0,
          status: statusFromUnknown(readBoxStatus(box)),
          metadata: readBoxMetadata(box)
        }));
      }
    } : {}
  };
}
function providerAsExecutor(provider, options = {}) {
  return (spec, ctx) => createProviderExecutor(provider, spec.profile, ctx, options);
}
function createProviderExecutor(provider, profile, ctx, options) {
  const controller = new AbortController();
  const abortIfSignalled = () => {
    if (ctx.signal.aborted) controller.abort();
  };
  abortIfSignalled();
  if (!ctx.signal.aborted) ctx.signal.addEventListener("abort", abortIfSignalled, { once: true });
  let environment;
  let artifact;
  return {
    runtime: options.runtime ?? provider.name,
    execute(task, signal) {
      return streamProviderExecutor({
        provider,
        profile,
        task,
        signal,
        controller,
        options,
        onEnvironment: (env) => {
          environment = env;
        },
        onArtifact: (next) => {
          artifact = next;
        }
      });
    },
    async teardown(_grace) {
      controller.abort();
      await environment?.destroy?.();
      return { destroyed: true };
    },
    resultArtifact() {
      if (!artifact) {
        throw new ValidationError(
          `providerAsExecutor(${provider.name}): resultArtifact() read before stream drained`
        );
      }
      return artifact;
    }
  };
}
async function* streamProviderExecutor(args) {
  const started = Date.now();
  const linked = mergeAbortSignals(args.signal, args.controller.signal);
  const environment = await args.provider.create({
    ...args.options.defaults ?? {},
    profile: args.profile,
    signal: linked
  });
  args.onEnvironment(environment);
  const turn = args.options.taskToTurn?.(args.task, args.profile) ?? taskToTurnInput(args.task, linked);
  const events = [];
  const tokens = zeroTokenUsage();
  let usd = 0;
  let text = "";
  let terminal = false;
  try {
    for await (const event of environment.stream({ ...turn, signal: linked })) {
      events.push(event);
      text += textFromEnvironmentEvent(event);
      const usage = usageFromEnvironmentEvent(event);
      if (usage.input || usage.output) {
        tokens.input += usage.input;
        tokens.output += usage.output;
        yield { kind: "tokens", input: usage.input, output: usage.output };
      }
      if (usage.usd) {
        usd += usage.usd;
        yield { kind: "cost", usd: usage.usd };
      }
      if (isTerminalEnvironmentEvent(event)) terminal = true;
    }
    if ((args.options.requireTerminalEvent ?? true) && !terminal) {
      throw new ValidationError(
        `providerAsExecutor(${args.provider.name}): stream ended without a terminal result/done/status event`
      );
    }
    yield { kind: "iteration" };
    const result = resultFromEvents(events, text);
    const spent = {
      iterations: 1,
      tokens,
      usd,
      ms: Date.now() - started
    };
    args.onArtifact({
      outRef: contentRef(`provider:${args.provider.name}`, result),
      out: result,
      spent
    });
  } finally {
    if (args.options.destroyOnSettle ?? true) await environment.destroy?.();
  }
}
function createInputFromSandboxOptions(options) {
  const profile = options?.backend?.profile;
  const backend = options?.backend?.type;
  return {
    ...profile !== void 0 ? { profile } : {},
    ...backend ? { backend } : {},
    workspace: {
      ...options?.environment ? { environment: options.environment } : {},
      ...options?.image ? { image: options.image } : {},
      ...options?.git?.url ? { repoUrl: options.git.url } : {},
      ...options?.git?.ref ? { gitRef: options.git.ref } : {}
    },
    ...options?.resources ? { resources: options.resources } : {},
    ...options?.env ? { env: options.env } : {},
    ...options?.secrets ? { secrets: options.secrets } : {},
    ...options?.metadata ? { metadata: options.metadata } : {},
    ...options?.name ? { name: options.name } : {},
    ...options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {},
    providerOptions: { sandboxCreateOptions: options ?? {} }
  };
}
function sandboxOptionsFromCreateInput(input, defaultBackend) {
  const backendType = input.backend ?? defaultBackend;
  const workspace = input.workspace ?? {};
  const providerOptions = input.providerOptions?.sandboxCreateOptions;
  const base = providerOptions && typeof providerOptions === "object" ? { ...providerOptions } : {};
  return {
    ...base,
    ...workspace.environment ? { environment: workspace.environment } : {},
    ...workspace.image ? { image: workspace.image } : {},
    ...workspace.repoUrl ? { git: { url: workspace.repoUrl, ref: workspace.gitRef } } : {},
    ...input.resources ? { resources: input.resources } : {},
    ...input.env ? { env: input.env } : {},
    ...Array.isArray(input.secrets) ? { secrets: input.secrets } : {},
    ...input.metadata ? { metadata: input.metadata } : {},
    ...input.name ? { name: input.name } : {},
    ...input.idempotencyKey ? { idempotencyKey: input.idempotencyKey } : {},
    backend: {
      ...base.backend ?? {},
      type: backendType,
      profile: input.profile
    }
  };
}
function environmentAsSandboxInstance(environment, options) {
  const box = {
    id: environment.id,
    name: environment.name,
    status: "running",
    async refresh() {
      await environment.refresh?.();
    },
    async *streamPrompt(message, promptOptions) {
      let terminal = false;
      const input = turnInputFromPrompt(message, promptOptions);
      for await (const event of environment.stream(input)) {
        if (isTerminalEnvironmentEvent(event)) terminal = true;
        const usageEvent = usageSandboxEvent(event);
        if (usageEvent) yield usageEvent;
        yield sandboxEventFromEnvironmentEvent(event);
      }
      if (options.requireTerminalEvent && !terminal) {
        throw new ValidationError(
          `providerAsSandboxClient(${environment.provider}): stream ended without a terminal result/done/status event`
        );
      }
    },
    async prompt(message, promptOptions) {
      const events = [];
      let text = "";
      let usage;
      let terminal = false;
      for await (const event of environment.stream(turnInputFromPrompt(message, promptOptions))) {
        events.push(event);
        if (isTerminalEnvironmentEvent(event)) terminal = true;
        text += textFromEnvironmentEvent(event);
        usage = mergeTokenUsage(usage, event.usage);
      }
      if (options.requireTerminalEvent && !terminal) {
        throw new ValidationError(
          `providerAsSandboxClient(${environment.provider}): prompt ended without a terminal result/done/status event`
        );
      }
      return promptResultCompat(
        {
          response: resultFromEvents(events, text).content,
          success: true,
          durationMs: 0,
          ...usage ? { usage } : {}
        },
        "success"
      );
    },
    ...environment.dispatch ? {
      async dispatchPrompt(message, promptOptions) {
        const session = await environment.dispatch?.(
          turnInputFromPrompt(message, promptOptions)
        );
        if (!session)
          throw new ValidationError("providerAsSandboxClient: dispatch returned no session");
        return sandboxDispatchResultFromSessionRef(session);
      }
    } : {},
    ...environment.session ? {
      session(id) {
        return sessionAsSandboxSession(environment.session?.(id));
      }
    } : {},
    ...environment.read ? { read: environment.read.bind(environment) } : {},
    ...environment.write ? { write: environment.write.bind(environment) } : {},
    ...environment.exec ? {
      exec: environment.exec.bind(environment)
    } : {},
    ...environment.checkpoint ? {
      async checkpoint(checkpointOptions) {
        const checkpoint = await environment.checkpoint?.(checkpointOptions);
        return { checkpointId: checkpoint?.id, id: checkpoint?.id };
      }
    } : {},
    ...environment.fork ? {
      async fork(checkpointId, forkOptions) {
        const forked = await environment.fork?.({ id: checkpointId }, forkOptions);
        if (!forked)
          throw new ValidationError("providerAsSandboxClient: fork returned no environment");
        return environmentAsSandboxInstance(forked, options);
      }
    } : {},
    async delete() {
      await environment.destroy?.();
    }
  };
  return box;
}
function sandboxInstanceAsEnvironment(box, providerName, client) {
  const environment = {
    id: String(box.id),
    provider: providerName,
    ...typeof box.name === "string" ? { name: box.name } : {},
    async status() {
      await maybeRefresh(box);
      return statusFromUnknown(readBoxStatus(box));
    },
    async *stream(input) {
      for await (const event of box.streamPrompt(
        promptFromTurnInput(input),
        promptOptionsFromTurnInput(input)
      )) {
        yield environmentEventFromSandboxEvent(event);
      }
    },
    ...hasDispatchPrompt(box) ? {
      async dispatch(input) {
        const dispatched = await box.dispatchPrompt(
          promptFromTurnInput(input),
          promptOptionsFromTurnInput(input)
        );
        return sessionRefFromSandboxDispatch(dispatched, providerName);
      }
    } : {},
    ...hasSession(box) ? {
      session(id) {
        return sandboxSessionAsAgentSession(box.session(id));
      }
    } : {},
    ...hasRead(box) ? { read: box.read.bind(box) } : {},
    ...hasWrite(box) ? { write: box.write.bind(box) } : {},
    ...hasExec(box) ? {
      async exec(command, options) {
        return execResultFromSandboxExecResult(await box.exec(command, options));
      }
    } : {},
    ...hasCheckpoint(box) ? {
      async checkpoint(options) {
        const result = await box.checkpoint(options);
        return { id: checkpointIdFromResult(result), provider: providerName };
      }
    } : {},
    ...hasFork(box) ? {
      async fork(checkpoint, options) {
        const forked = await box.fork(checkpoint.id, options);
        return sandboxInstanceAsEnvironment(forked, providerName, client);
      }
    } : {},
    async placement() {
      return placementInfoFromLoopPlacement(client.describePlacement?.(box), box);
    },
    async refresh() {
      await maybeRefresh(box);
    },
    async destroy() {
      await destroyBox(box);
    }
  };
  return environment;
}
function sandboxSessionAsAgentSession(session) {
  return {
    id: session.id,
    async status() {
      const status = await session.status();
      if (!status) return null;
      return sessionStatusFromUnknown(status.status);
    },
    async *events(options) {
      for await (const event of session.events(options))
        yield environmentEventFromSandboxEvent(event);
    },
    async result() {
      return agentTurnResultFromPromptResult(await session.result());
    },
    async prompt(input) {
      return agentTurnResultFromPromptResult(
        await session.prompt(promptFromTurnInput(input), promptOptionsFromTurnInput(input))
      );
    },
    cancel() {
      return session.cancel();
    }
  };
}
function sessionAsSandboxSession(session) {
  if (!session) throw new ValidationError("providerAsSandboxClient: session(id) returned undefined");
  return {
    id: session.id,
    status: session.status.bind(session),
    async *events(options) {
      for await (const event of session.events(options))
        yield sandboxEventFromEnvironmentEvent(event);
    },
    async result() {
      return promptResultFromAgentTurnResult(await session.result());
    },
    async prompt(message, options) {
      return promptResultFromAgentTurnResult(
        await session.prompt(turnInputFromPrompt(message, options))
      );
    },
    cancel: session.cancel.bind(session)
  };
}
function environmentEventFromSandboxEvent(event) {
  const data = event.data && typeof event.data === "object" ? event.data : {};
  return {
    type: String(event.type),
    data,
    ...event.id ? { id: event.id } : {},
    usage: tokenUsageFromData(data),
    providerEvent: event
  };
}
function sandboxEventFromEnvironmentEvent(event) {
  return {
    type: event.type,
    data: {
      ...event.data,
      ...event.usage ? { usage: tokenUsageData(event.usage) } : {}
    },
    ...event.id ? { id: event.id } : {}
  };
}
function usageSandboxEvent(event) {
  if (!event.usage || isUsageType(event.type)) return void 0;
  const usage = tokenUsageData(event.usage);
  if (usage.inputTokens === void 0 && usage.outputTokens === void 0 && usage.totalCostUsd === void 0) {
    return void 0;
  }
  return { type: "llm_call", data: usage };
}
function tokenUsageData(usage) {
  return {
    inputTokens: usage.inputTokens,
    outputTokens: usage.outputTokens,
    totalCostUsd: usage.cost
  };
}
function turnInputFromPrompt(message, options) {
  return {
    ...typeof message === "string" ? { prompt: message } : { parts: message },
    ...options?.sessionId ? { sessionId: options.sessionId } : {},
    ...options?.model ? { model: options.model } : {},
    ...options?.timeoutMs ? { timeoutMs: options.timeoutMs } : {},
    ...options?.executionId ? { executionId: options.executionId } : {},
    ...options?.lastEventId ? { lastEventId: options.lastEventId } : {},
    ...options?.turnId ? { turnId: options.turnId } : {},
    ...options?.detach !== void 0 ? { detach: options.detach } : {},
    ...options?.context ? { context: options.context } : {},
    ...options?.signal ? { signal: options.signal } : {},
    ...options?.backend ? { providerOptions: { backend: options.backend } } : {}
  };
}
function promptFromTurnInput(input) {
  if (input.parts) return input.parts;
  return input.prompt ?? "";
}
function promptOptionsFromTurnInput(input) {
  return {
    ...input.sessionId ? { sessionId: input.sessionId } : {},
    ...input.model ? { model: input.model } : {},
    ...input.timeoutMs ? { timeoutMs: input.timeoutMs } : {},
    ...input.context ? { context: input.context } : {},
    ...input.signal ? { signal: input.signal } : {},
    ...input.executionId ? { executionId: input.executionId } : {},
    ...input.lastEventId ? { lastEventId: input.lastEventId } : {},
    ...input.turnId ? { turnId: input.turnId } : {},
    ...input.detach !== void 0 ? { detach: input.detach } : {}
  };
}
function taskToTurnInput(task, signal) {
  return { prompt: taskToPrompt(task), signal };
}
function taskToPrompt(task) {
  if (typeof task === "string") return task;
  if (task && typeof task === "object") {
    const record = task;
    for (const key of ["prompt", "content", "task", "message"]) {
      if (typeof record[key] === "string") return record[key];
    }
  }
  return JSON.stringify(task);
}
function resultFromEvents(events, fallbackText) {
  for (let i = events.length - 1; i >= 0; i -= 1) {
    const event = events[i];
    const text = event ? resultTextFromData(event.data) : void 0;
    if (text !== void 0) return { content: text, events };
  }
  return { content: fallbackText, events };
}
function textFromEnvironmentEvent(event) {
  if (typeof event.normalized === "object" && event.normalized && event.normalized.type === "message.part.updated") {
    return typeof event.normalized.delta === "string" ? event.normalized.delta : "";
  }
  const data = event.data;
  for (const key of ["delta", "chunk", "content", "text"]) {
    if (typeof data[key] === "string" && !isTerminalEnvironmentEvent(event)) return data[key];
  }
  return "";
}
function resultTextFromData(data) {
  for (const key of ["finalText", "text", "response", "resultSummary", "content"]) {
    if (typeof data[key] === "string") return data[key];
  }
  return void 0;
}
function isTerminalEnvironmentEvent(event) {
  if (event.type === "result" || event.type === "done" || event.type === "final") return true;
  if (event.type.endsWith(".completed") || event.type.endsWith(".failed")) return true;
  if (event.type === "status") {
    const status = event.data.status;
    return status === "completed" || status === "failed" || status === "cancelled";
  }
  return false;
}
function isUsageType(type) {
  return type === "llm_call" || type === "usage" || type === "cost.usage";
}
function usageFromEnvironmentEvent(event) {
  const usage = event.usage ?? tokenUsageFromData(event.data);
  return {
    input: finiteNumber(usage?.inputTokens) ?? 0,
    output: finiteNumber(usage?.outputTokens) ?? 0,
    usd: finiteNumber(usage?.cost) ?? finiteNumber(event.data.costUsd) ?? finiteNumber(event.data.totalCostUsd) ?? 0
  };
}
function tokenUsageFromData(data) {
  const usageRecord = data.usage && typeof data.usage === "object" ? data.usage : data.tokenUsage && typeof data.tokenUsage === "object" ? data.tokenUsage : data;
  const inputTokens = finiteNumber(usageRecord.inputTokens) ?? finiteNumber(usageRecord.tokensIn) ?? finiteNumber(usageRecord.prompt_tokens);
  const outputTokens = finiteNumber(usageRecord.outputTokens) ?? finiteNumber(usageRecord.tokensOut) ?? finiteNumber(usageRecord.completion_tokens);
  const cost = finiteNumber(usageRecord.cost) ?? finiteNumber(usageRecord.costUsd) ?? finiteNumber(usageRecord.totalCostUsd) ?? finiteNumber(data.costUsd) ?? finiteNumber(data.totalCostUsd);
  if (inputTokens === void 0 && outputTokens === void 0 && cost === void 0)
    return void 0;
  return {
    inputTokens: inputTokens ?? 0,
    outputTokens: outputTokens ?? 0,
    ...cost !== void 0 ? { cost } : {}
  };
}
function mergeTokenUsage(left, right) {
  if (!left) return right;
  if (!right) return left;
  return {
    inputTokens: left.inputTokens + right.inputTokens,
    outputTokens: left.outputTokens + right.outputTokens,
    ...left.cost !== void 0 || right.cost !== void 0 ? { cost: (left.cost ?? 0) + (right.cost ?? 0) } : {}
  };
}
function finiteNumber(value) {
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
}
function promptResultCompat(input, status) {
  return { ...input, status };
}
function promptResultFromAgentTurnResult(result) {
  return promptResultCompat(
    {
      response: result.text,
      success: result.success,
      durationMs: 0,
      ...result.error ? { error: result.error } : {},
      ...result.usage ? { usage: result.usage } : {}
    },
    result.success ? "success" : "failed"
  );
}
function agentTurnResultFromPromptResult(result) {
  const record = result;
  const text = typeof record.response === "string" ? record.response : typeof record.text === "string" ? record.text : typeof record.finalText === "string" ? record.finalText : "";
  const success = typeof record.success === "boolean" ? record.success : true;
  return {
    text,
    success,
    ...typeof record.error === "string" ? { error: record.error } : {},
    usage: tokenUsageFromData(record)
  };
}
function sandboxDispatchResultFromSessionRef(session) {
  const hasStatus = session.metadata && Object.hasOwn(session.metadata, "status");
  const status = hasStatus ? sessionStatusFromUnknown(session.metadata?.status) : "running";
  return {
    sessionId: session.id,
    status,
    alreadyExisted: session.metadata?.alreadyExisted === true
  };
}
function sessionRefFromSandboxDispatch(dispatched, providerName) {
  const record = dispatched && typeof dispatched === "object" ? dispatched : void 0;
  const id = record?.sessionId ?? record?.id;
  if (typeof id !== "string" || id.length === 0) {
    throw new ValidationError("sandboxClientAsProvider: dispatch returned no session id");
  }
  if (!record) {
    throw new ValidationError("sandboxClientAsProvider: dispatch returned no session record");
  }
  return {
    id,
    provider: providerName,
    metadata: {
      ...record.status ? { status: record.status } : {},
      ...record.alreadyExisted !== void 0 ? { alreadyExisted: record.alreadyExisted } : {}
    }
  };
}
function execResultFromSandboxExecResult(result) {
  const record = result;
  const exitCode = finiteNumber(record.exitCode) ?? finiteNumber(record.code);
  if (exitCode === void 0) {
    throw new ValidationError("sandboxClientAsProvider: exec returned no exit code");
  }
  return {
    exitCode,
    stdout: typeof record.stdout === "string" ? record.stdout : "",
    stderr: typeof record.stderr === "string" ? record.stderr : ""
  };
}
function statusFromUnknown(status) {
  if (status === "pending" || status === "provisioning" || status === "running") return status;
  if (status === "stopped" || status === "failed" || status === "expired") return status;
  if (status === "completed") return "stopped";
  if (status === "cancelled") return "stopped";
  return "unknown";
}
function sessionStatusFromUnknown(status) {
  if (status === "completed" || status === "cancelled") return status;
  return statusFromUnknown(status);
}
function readBoxStatus(box) {
  return box.status;
}
function readBoxMetadata(box) {
  const metadata = box.metadata;
  return metadata && typeof metadata === "object" ? metadata : void 0;
}
async function maybeRefresh(box) {
  const refresh = box.refresh;
  if (typeof refresh === "function") await refresh.call(box);
}
async function destroyBox(box) {
  const deleteBox = box.delete;
  if (typeof deleteBox === "function") await deleteBox.call(box);
}
function placementInfoFromLoopPlacement(placement, box) {
  if (!placement) return { kind: "sandbox", sandboxId: String(box.id) };
  return {
    kind: placement.kind === "fleet" ? "fleet" : "sandbox",
    ...placement.sandboxId ? { sandboxId: placement.sandboxId } : { sandboxId: String(box.id) },
    ...placement.fleetId ? { fleetId: placement.fleetId } : {},
    ...placement.machineId ? { machineId: placement.machineId } : {}
  };
}
function checkpointIdFromResult(result) {
  const record = result && typeof result === "object" ? result : {};
  const id = record.checkpointId ?? record.id;
  if (typeof id !== "string" || id.length === 0) {
    throw new ValidationError("sandboxClientAsProvider: checkpoint returned no checkpoint id");
  }
  return id;
}
function defaultTangleSandboxCapabilities() {
  return {
    profile: {
      namedProfiles: true,
      systemPrompt: true,
      instructions: true,
      tools: true,
      permissions: true,
      mcp: true,
      subagents: true,
      resources: {
        files: true,
        instructions: true,
        tools: true,
        skills: true,
        agents: true,
        commands: true
      },
      hooks: true,
      modes: true,
      runtimeUpdate: true,
      validation: true
    },
    streaming: { live: true, replay: true, detach: true, turnIdempotency: true },
    sessions: { continue: true, list: true, messages: true },
    workspace: { read: true, write: true, exec: true, git: true, upload: true, download: true },
    branching: { checkpoint: true, fork: true },
    placement: true,
    usage: true,
    confidential: true
  };
}
function mergeAbortSignals(a, b) {
  const controller = new AbortController();
  const abort = () => controller.abort();
  if (a.aborted || b.aborted) controller.abort();
  else {
    a.addEventListener("abort", abort, { once: true });
    b.addEventListener("abort", abort, { once: true });
  }
  return controller.signal;
}
function contentRef(prefix, value) {
  let str;
  try {
    str = JSON.stringify(value) ?? String(value);
  } catch {
    str = String(value);
  }
  let hash = 2166136261;
  for (let i = 0; i < str.length; i += 1) {
    hash ^= str.charCodeAt(i);
    hash = Math.imul(hash, 16777619);
  }
  return `${prefix}:${(hash >>> 0).toString(16).padStart(8, "0")}`;
}
function hasGet(client) {
  return typeof client.get === "function";
}
function hasList(client) {
  return typeof client.list === "function";
}
function hasDispatchPrompt(box) {
  return typeof box.dispatchPrompt === "function";
}
function hasSession(box) {
  return typeof box.session === "function";
}
function hasRead(box) {
  return typeof box.read === "function";
}
function hasWrite(box) {
  return typeof box.write === "function";
}
function hasExec(box) {
  return typeof box.exec === "function";
}
function hasCheckpoint(box) {
  return typeof box.checkpoint === "function";
}
function hasFork(box) {
  return typeof box.fork === "function";
}

export {
  deleteBoxSafe,
  randomSuffix,
  randomUuid,
  throwAbort,
  throwIfAborted,
  isAbortError,
  sleep,
  withTimeout,
  stringifySafe,
  zeroTokenUsage,
  addTokenUsage,
  mapWithConcurrency,
  createAgentEnvironmentProviderRegistry,
  resolveAgentEnvironmentProvider,
  providerAsSandboxClient,
  sandboxClientAsProvider,
  providerAsExecutor
};
//# sourceMappingURL=chunk-BZF3KQ6G.js.map