'use strict';

var fs = require('fs');
var path = require('path');
var os = require('os');

function _interopNamespace(e) {
  if (e && e.__esModule) return e;
  var n = Object.create(null);
  if (e) {
    Object.keys(e).forEach(function (k) {
      if (k !== 'default') {
        var d = Object.getOwnPropertyDescriptor(e, k);
        Object.defineProperty(n, k, d.get ? d : {
          enumerable: true,
          get: function () { return e[k]; }
        });
      }
    });
  }
  n.default = e;
  return Object.freeze(n);
}

var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
var path__namespace = /*#__PURE__*/_interopNamespace(path);
var os__namespace = /*#__PURE__*/_interopNamespace(os);

// src/types/errors.ts
var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
  ErrorCode2["AUTH_EXPIRED"] = "AUTH_EXPIRED";
  ErrorCode2["AUTH_INVALID"] = "AUTH_INVALID";
  ErrorCode2["RATE_LIMIT"] = "RATE_LIMIT";
  ErrorCode2["NETWORK"] = "NETWORK";
  ErrorCode2["TIMEOUT"] = "TIMEOUT";
  ErrorCode2["PROVIDER_ERROR"] = "PROVIDER_ERROR";
  ErrorCode2["MODEL_NOT_FOUND"] = "MODEL_NOT_FOUND";
  ErrorCode2["MODEL_OVERLOADED"] = "MODEL_OVERLOADED";
  ErrorCode2["CONTEXT_OVERFLOW"] = "CONTEXT_OVERFLOW";
  ErrorCode2["INVALID_INPUT"] = "INVALID_INPUT";
  ErrorCode2["INVALID_RESPONSE"] = "INVALID_RESPONSE";
  ErrorCode2["REENTRANCY"] = "REENTRANCY";
  ErrorCode2["DISPOSED"] = "DISPOSED";
  ErrorCode2["ABORTED"] = "ABORTED";
  ErrorCode2["INVALID_TRANSITION"] = "INVALID_TRANSITION";
  ErrorCode2["DEPENDENCY_MISSING"] = "DEPENDENCY_MISSING";
  ErrorCode2["BACKEND_NOT_INSTALLED"] = "BACKEND_NOT_INSTALLED";
  ErrorCode2["TOOL_EXECUTION"] = "TOOL_EXECUTION";
  ErrorCode2["PERMISSION_DENIED"] = "PERMISSION_DENIED";
  ErrorCode2["SESSION_NOT_FOUND"] = "SESSION_NOT_FOUND";
  ErrorCode2["SESSION_EXPIRED"] = "SESSION_EXPIRED";
  ErrorCode2["PROVIDER_NOT_FOUND"] = "PROVIDER_NOT_FOUND";
  ErrorCode2["AUTH_REQUIRED"] = "AUTH_REQUIRED";
  ErrorCode2["STORAGE_ERROR"] = "STORAGE_ERROR";
  ErrorCode2["STORAGE_NOT_FOUND"] = "STORAGE_NOT_FOUND";
  ErrorCode2["STORAGE_DUPLICATE_KEY"] = "STORAGE_DUPLICATE_KEY";
  ErrorCode2["STORAGE_IO_ERROR"] = "STORAGE_IO_ERROR";
  ErrorCode2["STORAGE_SERIALIZATION_ERROR"] = "STORAGE_SERIALIZATION_ERROR";
  return ErrorCode2;
})(ErrorCode || {});
var RECOVERABLE_CODES = /* @__PURE__ */ new Set([
  "TIMEOUT" /* TIMEOUT */,
  "RATE_LIMIT" /* RATE_LIMIT */,
  "NETWORK" /* NETWORK */,
  "TOOL_EXECUTION" /* TOOL_EXECUTION */,
  "MODEL_OVERLOADED" /* MODEL_OVERLOADED */,
  "PROVIDER_ERROR" /* PROVIDER_ERROR */
]);
function isRecoverableErrorCode(code) {
  return RECOVERABLE_CODES.has(code);
}
function classifyAgentError(error) {
  const msg = (error instanceof Error ? error.message : error).toLowerCase();
  if (msg.includes("timeout") || msg.includes("timed out") || msg.includes("timedout") || msg.includes("etimedout")) {
    return "TIMEOUT" /* TIMEOUT */;
  }
  if (msg.includes("rate limit") || msg.includes("rate_limit") || msg.includes("429") || msg.includes("too many requests")) {
    return "RATE_LIMIT" /* RATE_LIMIT */;
  }
  if (msg.includes("unauthorized") || msg.includes("401") || msg.includes("auth") && (msg.includes("expired") || msg.includes("invalid") || msg.includes("denied") || msg.includes("failed"))) {
    return "AUTH_EXPIRED" /* AUTH_EXPIRED */;
  }
  if (msg.includes("econnrefused") || msg.includes("econnreset") || msg.includes("enotfound") || msg.includes("network") || msg.includes("fetch failed") || msg.includes("socket hang up")) {
    return "NETWORK" /* NETWORK */;
  }
  if (msg.includes("subprocess") || msg.includes("process exited") || msg.includes("spawn") || msg.includes("enoent") || msg.includes("killed")) {
    return "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */;
  }
  if (msg.includes("abort") || msg.includes("cancel")) {
    return "ABORTED" /* ABORTED */;
  }
  if (msg.includes("500") || msg.includes("502") || msg.includes("503") || msg.includes("internal server error") || msg.includes("service unavailable") || msg.includes("bad gateway") || msg.includes("overloaded")) {
    return "PROVIDER_ERROR" /* PROVIDER_ERROR */;
  }
  return "PROVIDER_ERROR" /* PROVIDER_ERROR */;
}

// src/types/guards.ts
function isToolDefinition(tool) {
  return "execute" in tool && typeof tool.execute === "function";
}
function isTextContent(content) {
  return typeof content === "string";
}
function isMultiPartContent(content) {
  return Array.isArray(content);
}
function getTextContent(content) {
  if (typeof content === "string") return content;
  return content.filter((p) => p.type === "text").map((p) => p.text).join("\n");
}

// src/errors.ts
var AgentSDKError = class extends Error {
  /** @internal Marker for cross-bundle identity checks */
  _agentSDKError = true;
  /** Machine-readable error code. Prefer values from the ErrorCode enum. */
  code;
  /** Whether this error is safe to retry */
  retryable;
  /** HTTP status code hint for error classification */
  httpStatus;
  constructor(message, options) {
    super(message, options);
    this.name = "AgentSDKError";
    this.code = options?.code;
    this.retryable = options?.retryable ?? false;
    this.httpStatus = options?.httpStatus;
  }
  /** Check if an error is an AgentSDKError (works across bundled copies) */
  static is(error) {
    return error instanceof Error && "_agentSDKError" in error && error._agentSDKError === true;
  }
};
var ReentrancyError = class extends AgentSDKError {
  constructor() {
    super("Agent is already running. Await the current run before starting another.", {
      code: "REENTRANCY" /* REENTRANCY */
    });
    this.name = "ReentrancyError";
  }
};
var DisposedError = class extends AgentSDKError {
  constructor(entity) {
    super(`${entity} has been disposed and cannot be used.`, {
      code: "DISPOSED" /* DISPOSED */
    });
    this.name = "DisposedError";
  }
};
var BackendNotFoundError = class extends AgentSDKError {
  constructor(backend) {
    super(
      `Unknown backend: "${backend}". Built-in: copilot, claude, vercel-ai. Custom: use registerBackend() first.`,
      { code: "BACKEND_NOT_INSTALLED" /* BACKEND_NOT_INSTALLED */ }
    );
    this.name = "BackendNotFoundError";
  }
};
var BackendAlreadyRegisteredError = class extends AgentSDKError {
  constructor(backend) {
    super(`Backend "${backend}" is already registered. Use a different name or unregister first.`);
    this.name = "BackendAlreadyRegisteredError";
  }
};
var SubprocessError = class extends AgentSDKError {
  constructor(message, options) {
    super(message, { ...options, code: "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */ });
    this.name = "SubprocessError";
  }
};
var DependencyError = class extends AgentSDKError {
  packageName;
  constructor(packageName) {
    super(`${packageName} is not installed. Install it: npm install ${packageName}`, {
      code: "DEPENDENCY_MISSING" /* DEPENDENCY_MISSING */
    });
    this.name = "DependencyError";
    this.packageName = packageName;
  }
};
var AbortError = class extends AgentSDKError {
  constructor() {
    super("Agent run was aborted.", { code: "ABORTED" /* ABORTED */ });
    this.name = "AbortError";
  }
};
var ToolExecutionError = class extends AgentSDKError {
  toolName;
  constructor(toolName, message, options) {
    super(`Tool "${toolName}" failed: ${message}`, { ...options, code: "TOOL_EXECUTION" /* TOOL_EXECUTION */ });
    this.name = "ToolExecutionError";
    this.toolName = toolName;
  }
};
var ActivityTimeoutError = class extends AgentSDKError {
  constructor(timeoutMs) {
    super(`Stream activity timeout: no event received within ${timeoutMs}ms.`, {
      code: "TIMEOUT" /* TIMEOUT */,
      retryable: true
    });
    this.name = "ActivityTimeoutError";
  }
};
var StructuredOutputError = class extends AgentSDKError {
  constructor(message, options) {
    super(`Structured output error: ${message}`, { ...options, code: "INVALID_RESPONSE" /* INVALID_RESPONSE */ });
    this.name = "StructuredOutputError";
  }
};

// src/registry.ts
var registry = /* @__PURE__ */ new Map();
var serviceCache = /* @__PURE__ */ new Map();
function configCacheKey(name, configId) {
  return `${name}:${configId}`;
}
function registerBackend(name, factory) {
  if (registry.has(name)) {
    throw new BackendAlreadyRegisteredError(name);
  }
  registry.set(name, { factory, builtin: false });
}
function unregisterBackend(name) {
  return registry.delete(name);
}
function hasBackend(name) {
  return registry.has(name) || lazyLoaders.has(name);
}
function listBackends() {
  const names = new Set(registry.keys());
  for (const name of lazyLoaders.keys()) {
    names.add(name);
  }
  return [...names];
}
function resetRegistry() {
  registry.clear();
  serviceCache.clear();
}
async function disposeBackend(name, configId) {
  if (configId !== void 0) {
    const key = configCacheKey(name, configId);
    const svc = serviceCache.get(key);
    if (!svc) return 0;
    serviceCache.delete(key);
    await svc.dispose();
    return 1;
  }
  const prefix = `${name}:`;
  const toDispose = [];
  for (const [key, svc] of serviceCache) {
    if (key.startsWith(prefix)) {
      toDispose.push(svc);
      serviceCache.delete(key);
    }
  }
  await Promise.all(toDispose.map((s) => s.dispose()));
  return toDispose.length;
}
function listConfigs(name) {
  const prefix = `${name}:`;
  const ids = [];
  for (const key of serviceCache.keys()) {
    if (key.startsWith(prefix)) {
      ids.push(key.slice(prefix.length));
    }
  }
  return ids;
}
var lazyLoaders = /* @__PURE__ */ new Map([
  [
    "copilot",
    async () => {
      const mod = await import('./backends/copilot.js');
      return (opts) => mod.createCopilotService(opts);
    }
  ],
  [
    "claude",
    async () => {
      const mod = await import('./backends/claude.js');
      return (opts) => mod.createClaudeService(opts);
    }
  ],
  [
    "vercel-ai",
    async () => {
      const mod = await import('./backends/vercel-ai.js');
      return (opts) => mod.createVercelAIService(opts);
    }
  ]
]);
function registerLazyBackend(name, loader) {
  lazyLoaders.set(name, loader);
}
async function createAgentService(name, options, configId) {
  if (configId !== void 0) {
    const key = configCacheKey(name, configId);
    const cached = serviceCache.get(key);
    if (cached) return cached;
    const service = await createServiceInstance(name, options);
    serviceCache.set(key, service);
    return service;
  }
  return createServiceInstance(name, options);
}
async function createServiceInstance(name, options) {
  const entry = registry.get(name);
  if (entry) {
    return entry.factory(options);
  }
  const loader = lazyLoaders.get(name);
  if (loader) {
    const factory = await loader();
    registry.set(name, { factory, builtin: true });
    return factory(options);
  }
  throw new BackendNotFoundError(name);
}

// src/base-agent.ts
var BaseAgent = class {
  state = "idle";
  abortController = null;
  config;
  _cleanupExternalSignal = null;
  _streamMiddleware = [];
  /** CLI session ID for persistent mode. Override in backends that support it. */
  get sessionId() {
    return void 0;
  }
  constructor(config) {
    this.config = Object.freeze({ ...config });
  }
  // ─── Public Interface ─────────────────────────────────────────
  async run(prompt, options) {
    this.guardReentrancy();
    this.guardDisposed();
    const ac = this.createAbortController(options?.signal);
    this.state = "running";
    try {
      const messages = [{ role: "user", content: prompt }];
      const result = await this.withRetry(
        () => this.executeRun(messages, options, ac.signal),
        options
      );
      this.enrichAndNotifyUsage(result, options);
      return result;
    } finally {
      this.cleanupRun();
    }
  }
  async runWithContext(messages, options) {
    this.guardReentrancy();
    this.guardDisposed();
    const ac = this.createAbortController(options?.signal);
    this.state = "running";
    try {
      const result = await this.withRetry(
        () => this.executeRun(messages, options, ac.signal),
        options
      );
      this.enrichAndNotifyUsage(result, options);
      return result;
    } finally {
      this.cleanupRun();
    }
  }
  async runStructured(prompt, schema, options) {
    this.guardReentrancy();
    this.guardDisposed();
    const ac = this.createAbortController(options?.signal);
    this.state = "running";
    try {
      const messages = [{ role: "user", content: prompt }];
      const result = await this.withRetry(
        () => this.executeRunStructured(messages, schema, options, ac.signal),
        options
      );
      this.enrichAndNotifyUsage(result, options);
      return result;
    } finally {
      this.cleanupRun();
    }
  }
  async *stream(prompt, options) {
    this.guardReentrancy();
    this.guardDisposed();
    const ac = this.createAbortController(options?.signal);
    this.state = "streaming";
    try {
      const messages = [{ role: "user", content: prompt }];
      yield* this.streamWithRetry(
        () => this.applyStreamPipeline(this.executeStream(messages, options, ac.signal), options, ac),
        options
      );
    } finally {
      this.cleanupRun();
    }
  }
  async *streamWithContext(messages, options) {
    this.guardReentrancy();
    this.guardDisposed();
    const ac = this.createAbortController(options?.signal);
    this.state = "streaming";
    try {
      yield* this.streamWithRetry(
        () => this.applyStreamPipeline(this.executeStream(messages, options, ac.signal), options, ac),
        options
      );
    } finally {
      this.cleanupRun();
    }
  }
  /** Register a stream middleware. Applied in registration order after built-in transforms. */
  addStreamMiddleware(middleware) {
    this.guardDisposed();
    this._streamMiddleware.push(middleware);
  }
  /** Apply built-in transforms (enrich→timeout→heartbeat) then custom middleware */
  async *applyStreamPipeline(source, options, ac) {
    let stream = this.enrichStream(source, options);
    stream = this.activityTimeoutStream(stream, options?.activityTimeoutMs, ac);
    stream = this.heartbeatStream(stream);
    if (this._streamMiddleware.length > 0) {
      const ctx = {
        model: options.model,
        backend: this.backendName,
        abortController: ac,
        config: Object.freeze({ ...this.config })
      };
      for (const mw of this._streamMiddleware) {
        stream = mw(stream, ctx);
      }
    }
    yield* stream;
  }
  abort() {
    if (this.abortController) {
      this.abortController.abort();
    }
  }
  /** Default interrupt — falls back to abort(). Backends may override with graceful shutdown. */
  async interrupt() {
    this.abort();
  }
  getState() {
    return this.state;
  }
  getConfig() {
    return this.config;
  }
  /** Mark agent as disposed. Override to add cleanup. */
  dispose() {
    this._cleanupExternalSignal?.();
    this._cleanupExternalSignal = null;
    this.abort();
    this.state = "disposed";
  }
  // ─── Retry Logic ─────────────────────────────────────────────
  /** Check if an error should be retried given the retry configuration. */
  isRetryableError(error, retry) {
    if (error instanceof AbortError || error instanceof ReentrancyError || error instanceof DisposedError) {
      return false;
    }
    if (AgentSDKError.is(error)) {
      if (retry.retryableErrors && retry.retryableErrors.length > 0 && error.code) {
        return retry.retryableErrors.includes(error.code);
      }
      if (error.retryable) return true;
      if (error.code) return isRecoverableErrorCode(error.code);
    }
    return false;
  }
  /** Execute a function with retry logic per RetryConfig. */
  async withRetry(fn, options) {
    const retry = options?.retry;
    if (!retry || !retry.maxRetries || retry.maxRetries <= 0) {
      return fn();
    }
    const maxRetries = retry.maxRetries;
    const initialDelay = retry.initialDelayMs ?? 1e3;
    const multiplier = retry.backoffMultiplier ?? 2;
    let lastError;
    for (let attempt = 0; attempt <= maxRetries; attempt++) {
      try {
        return await fn();
      } catch (err) {
        lastError = err;
        if (attempt >= maxRetries || !this.isRetryableError(err, retry)) {
          throw err;
        }
        const delay = initialDelay * Math.pow(multiplier, attempt);
        await new Promise((resolve2) => setTimeout(resolve2, delay));
        if (options?.signal?.aborted || this.abortController?.signal.aborted) {
          throw err;
        }
      }
    }
    throw lastError;
  }
  /** Execute a stream factory with pre-stream retry: retries until first event, then committed. */
  async *streamWithRetry(factory, options) {
    const retry = options?.retry;
    if (!retry || !retry.maxRetries || retry.maxRetries <= 0) {
      yield* factory();
      return;
    }
    const maxRetries = retry.maxRetries;
    const initialDelay = retry.initialDelayMs ?? 1e3;
    const multiplier = retry.backoffMultiplier ?? 2;
    for (let attempt = 0; attempt <= maxRetries; attempt++) {
      try {
        const stream = factory();
        const iterator = stream[Symbol.asyncIterator]();
        const first = await iterator.next();
        if (first.done) return;
        yield first.value;
        while (true) {
          const next = await iterator.next();
          if (next.done) break;
          yield next.value;
        }
        return;
      } catch (err) {
        if (attempt >= maxRetries || !this.isRetryableError(err, retry)) {
          throw err;
        }
        const delay = initialDelay * Math.pow(multiplier, attempt);
        await new Promise((resolve2) => setTimeout(resolve2, delay));
        if (options?.signal?.aborted || this.abortController?.signal.aborted) {
          throw err;
        }
      }
    }
  }
  // ─── CallOptions Resolution ──────────────────────────────────
  /** Resolve tools to use for this call (per-call override > config default) */
  resolveTools(options) {
    return options?.tools ?? this.config.tools ?? [];
  }
  // ─── Usage Enrichment ───────────────────────────────────────────
  /** Enrich result usage with model/backend and fire onUsage callback */
  enrichAndNotifyUsage(result, options) {
    if (result.usage) {
      result.usage = {
        ...result.usage,
        model: options.model,
        backend: this.backendName
      };
      this.callOnUsage(result.usage);
    }
  }
  /** Wrap a stream to enrich usage_update events and fire onUsage callback */
  async *enrichStream(source, options) {
    const model = options.model;
    for await (const event of source) {
      if (event.type === "usage_update") {
        const usage = {
          promptTokens: event.promptTokens,
          completionTokens: event.completionTokens,
          model,
          backend: this.backendName
        };
        this.callOnUsage(usage);
        yield { type: "usage_update", ...usage };
      } else {
        yield event;
      }
    }
  }
  /** Fire onUsage callback (fire-and-forget: errors logged, not propagated) */
  callOnUsage(usage) {
    if (!this.config.onUsage) return;
    try {
      this.config.onUsage(usage);
    } catch (e) {
      console.warn(
        "[agent-sdk] onUsage callback error:",
        e instanceof Error ? e.message : String(e)
      );
    }
  }
  // ─── Heartbeat ───────────────────────────────────────────────
  /** Wrap a stream to emit heartbeat events at configured intervals.
   *  When heartbeatInterval is not set, passes through directly. */
  async *heartbeatStream(source) {
    const interval = this.config.heartbeatInterval;
    if (!interval || interval <= 0) {
      yield* source;
      return;
    }
    const iterator = source[Symbol.asyncIterator]();
    let pendingEvent = null;
    let heartbeatResolve = null;
    const timer = setInterval(() => {
      if (heartbeatResolve) {
        const resolve2 = heartbeatResolve;
        heartbeatResolve = null;
        resolve2();
      }
    }, interval);
    try {
      while (true) {
        if (!pendingEvent) {
          pendingEvent = iterator.next();
        }
        const heartbeatPromise = new Promise((resolve2) => {
          heartbeatResolve = resolve2;
        });
        const eventDone = pendingEvent.then(
          (r) => ({ kind: "event", result: r })
        );
        const heartbeatDone = heartbeatPromise.then(
          () => ({ kind: "heartbeat" })
        );
        const winner = await Promise.race([eventDone, heartbeatDone]);
        if (winner.kind === "heartbeat") {
          yield { type: "heartbeat" };
        } else {
          pendingEvent = null;
          heartbeatResolve = null;
          if (winner.result.done) break;
          yield winner.result.value;
        }
      }
    } finally {
      clearInterval(timer);
      heartbeatResolve = null;
    }
  }
  // ─── Activity Timeout ────────────────────────────────────────
  /** Wrap a stream to abort on inactivity. Resets timer on every event.
   *  When timeoutMs is not set, passes through directly. */
  async *activityTimeoutStream(source, timeoutMs, ac) {
    if (!timeoutMs || timeoutMs <= 0) {
      yield* source;
      return;
    }
    const iterator = source[Symbol.asyncIterator]();
    let timerId;
    try {
      while (true) {
        const timeoutPromise = new Promise((_, reject) => {
          timerId = setTimeout(() => reject(new ActivityTimeoutError(timeoutMs)), timeoutMs);
        });
        const result = await Promise.race([iterator.next(), timeoutPromise]);
        clearTimeout(timerId);
        if (result.done) break;
        yield result.value;
      }
    } catch (err) {
      if (err instanceof ActivityTimeoutError) {
        ac.abort(err);
      }
      throw err;
    } finally {
      clearTimeout(timerId);
    }
  }
  // ─── Guards ───────────────────────────────────────────────────
  guardReentrancy() {
    if (this.state === "running" || this.state === "streaming") {
      throw new ReentrancyError();
    }
  }
  guardDisposed() {
    if (this.state === "disposed") {
      throw new DisposedError("Agent");
    }
  }
  /** Throw AbortError if signal is already aborted */
  checkAbort(signal) {
    if (signal.aborted) {
      throw new AbortError();
    }
  }
  // ─── Internal Helpers ─────────────────────────────────────────
  /** Clean up after a run completes (success, error, or abort). */
  cleanupRun() {
    this._cleanupExternalSignal?.();
    this._cleanupExternalSignal = null;
    this.state = "idle";
    this.abortController = null;
  }
  createAbortController(externalSignal) {
    const ac = new AbortController();
    this.abortController = ac;
    this._cleanupExternalSignal = null;
    if (externalSignal) {
      if (externalSignal.aborted) {
        ac.abort();
      } else {
        const listener = () => ac.abort();
        externalSignal.addEventListener("abort", listener, { once: true });
        this._cleanupExternalSignal = () => externalSignal.removeEventListener("abort", listener);
      }
    }
    return ac;
  }
};

// src/utils/schema.ts
function zodToJsonSchema(schema) {
  const schemaAny = schema;
  if ("toJSONSchema" in schema && typeof schemaAny.toJSONSchema === "function") {
    return schemaAny.toJSONSchema();
  }
  if ("jsonSchema" in schema && typeof schemaAny.jsonSchema === "function") {
    return schemaAny.jsonSchema();
  }
  return extractSchemaFromDef(schema);
}
function extractSchemaFromDef(schema) {
  const def = schema._def;
  const typeName = def.typeName;
  switch (typeName) {
    case "ZodString":
      return { type: "string" };
    case "ZodNumber":
      return { type: "number" };
    case "ZodBoolean":
      return { type: "boolean" };
    case "ZodNull":
      return { type: "null" };
    case "ZodArray":
      return {
        type: "array",
        items: extractSchemaFromDef(def.type)
      };
    case "ZodObject": {
      const shape = schema.shape;
      const properties = {};
      const required = [];
      for (const [key, value] of Object.entries(shape)) {
        const valueDef = value._def;
        if (valueDef.typeName === "ZodOptional") {
          properties[key] = extractSchemaFromDef(valueDef.innerType);
        } else {
          properties[key] = extractSchemaFromDef(value);
          required.push(key);
        }
      }
      return {
        type: "object",
        properties,
        ...required.length > 0 ? { required } : {}
      };
    }
    case "ZodOptional":
      return extractSchemaFromDef(def.innerType);
    case "ZodEnum":
      return { type: "string", enum: def.values };
    default:
      return {};
  }
}

// src/utils/messages.ts
function messagesToPrompt(messages) {
  return messages.map((msg) => {
    switch (msg.role) {
      case "user":
        return contentToText(msg.content);
      case "assistant":
        return contentToText(msg.content);
      case "system":
        return msg.content;
      case "tool":
        return msg.content ?? "";
    }
  }).filter(Boolean).join("\n\n");
}
function contentToText(content) {
  return getTextContent(content);
}
function buildSystemPrompt(base, schemaInstruction) {
  if (!schemaInstruction) return base;
  return `${base}

${schemaInstruction}`;
}
var InMemoryPermissionStore = class {
  approvals = /* @__PURE__ */ new Map();
  async isApproved(toolName) {
    return this.approvals.has(toolName);
  }
  async approve(toolName, scope) {
    if (scope === "once") return;
    this.approvals.set(toolName, scope);
  }
  async revoke(toolName) {
    this.approvals.delete(toolName);
  }
  async clear() {
    this.approvals.clear();
  }
  async dispose() {
    this.approvals.clear();
  }
};
var FilePermissionStore = class {
  filePath;
  constructor(filePath) {
    this.filePath = path__namespace.resolve(filePath);
  }
  async isApproved(toolName) {
    const data = this.readFile();
    return toolName in data.approvals;
  }
  async approve(toolName, scope) {
    if (scope === "once") return;
    const data = this.readFile();
    data.approvals[toolName] = { scope, timestamp: Date.now() };
    this.writeFileAtomic(data);
  }
  async revoke(toolName) {
    const data = this.readFile();
    delete data.approvals[toolName];
    this.writeFileAtomic(data);
  }
  async clear() {
    this.writeFileAtomic({ approvals: {} });
  }
  async dispose() {
  }
  readFile() {
    try {
      const raw = fs__namespace.readFileSync(this.filePath, "utf-8");
      const parsed = JSON.parse(raw);
      if (parsed && typeof parsed.approvals === "object") return parsed;
    } catch {
    }
    return { approvals: {} };
  }
  writeFileAtomic(data) {
    const dir = path__namespace.dirname(this.filePath);
    fs__namespace.mkdirSync(dir, { recursive: true });
    const tmpPath = this.filePath + `.tmp.${process.pid}.${Date.now()}`;
    fs__namespace.writeFileSync(tmpPath, JSON.stringify(data, null, 2), "utf-8");
    fs__namespace.renameSync(tmpPath, this.filePath);
  }
};
var CompositePermissionStore = class {
  sessionStore;
  projectStore;
  userStore;
  constructor(sessionStore, projectStore, userStore) {
    this.sessionStore = sessionStore;
    this.projectStore = projectStore;
    this.userStore = userStore ?? projectStore;
  }
  async isApproved(toolName) {
    return await this.sessionStore.isApproved(toolName) || await this.projectStore.isApproved(toolName) || await this.userStore.isApproved(toolName);
  }
  async approve(toolName, scope) {
    if (scope === "once") return;
    if (scope === "session") {
      await this.sessionStore.approve(toolName, scope);
    } else if (scope === "project") {
      await this.projectStore.approve(toolName, scope);
    } else {
      await this.userStore.approve(toolName, scope);
    }
  }
  async revoke(toolName) {
    await this.sessionStore.revoke(toolName);
    await this.projectStore.revoke(toolName);
    await this.userStore.revoke(toolName);
  }
  async clear() {
    await this.sessionStore.clear();
    await this.projectStore.clear();
    await this.userStore.clear();
  }
  async dispose() {
    await this.sessionStore.dispose();
    await this.projectStore.dispose();
    if (this.userStore !== this.projectStore) {
      await this.userStore.dispose();
    }
  }
};
function createDefaultPermissionStore(projectDir) {
  const sessionStore = new InMemoryPermissionStore();
  const projectPath = projectDir ? path__namespace.join(projectDir, ".agent-sdk", "permissions.json") : path__namespace.join(process.cwd(), ".agent-sdk", "permissions.json");
  const userPath = path__namespace.join(os__namespace.homedir(), ".agent-sdk", "permissions.json");
  const projectStore = new FilePermissionStore(projectPath);
  const userStore = new FilePermissionStore(userPath);
  return new CompositePermissionStore(sessionStore, projectStore, userStore);
}

exports.AbortError = AbortError;
exports.ActivityTimeoutError = ActivityTimeoutError;
exports.AgentSDKError = AgentSDKError;
exports.BackendAlreadyRegisteredError = BackendAlreadyRegisteredError;
exports.BackendNotFoundError = BackendNotFoundError;
exports.BaseAgent = BaseAgent;
exports.CompositePermissionStore = CompositePermissionStore;
exports.DependencyError = DependencyError;
exports.DisposedError = DisposedError;
exports.ErrorCode = ErrorCode;
exports.FilePermissionStore = FilePermissionStore;
exports.InMemoryPermissionStore = InMemoryPermissionStore;
exports.ReentrancyError = ReentrancyError;
exports.StructuredOutputError = StructuredOutputError;
exports.SubprocessError = SubprocessError;
exports.ToolExecutionError = ToolExecutionError;
exports.buildSystemPrompt = buildSystemPrompt;
exports.classifyAgentError = classifyAgentError;
exports.contentToText = contentToText;
exports.createAgentService = createAgentService;
exports.createDefaultPermissionStore = createDefaultPermissionStore;
exports.disposeBackend = disposeBackend;
exports.getTextContent = getTextContent;
exports.hasBackend = hasBackend;
exports.isMultiPartContent = isMultiPartContent;
exports.isRecoverableErrorCode = isRecoverableErrorCode;
exports.isTextContent = isTextContent;
exports.isToolDefinition = isToolDefinition;
exports.listBackends = listBackends;
exports.listConfigs = listConfigs;
exports.messagesToPrompt = messagesToPrompt;
exports.registerBackend = registerBackend;
exports.registerLazyBackend = registerLazyBackend;
exports.resetRegistry = resetRegistry;
exports.unregisterBackend = unregisterBackend;
exports.zodToJsonSchema = zodToJsonSchema;
//# sourceMappingURL=index.cjs.map
//# sourceMappingURL=index.cjs.map