// ../packages/runtime-core/dist/index.js
var RUNTIME_KINDS = ["native-sdk", "app-server", "compatible-sdk", "cli-fallback"];
var initialRuntimeState = {
  status: "idle",
  acceptedMessages: [],
  queuedMessages: []
};
function reduceRuntimeState(state = initialRuntimeState, action) {
  switch (action.type) {
    case "preflight_start":
      return { ...state, status: "preflighting", lastError: void 0 };
    case "preflight_ok":
      return { ...state, status: "ready", lastError: void 0 };
    case "preflight_error":
      return { ...state, status: "failed", lastError: action.error };
    case "starting":
      if (state.status === "ready" || state.status === "idle") {
        return { ...state, status: "starting" };
      }
      return state;
    case "send_message":
      if (state.status === "running" || state.status === "waiting_for_permission") {
        return {
          ...state,
          queuedMessages: [...state.queuedMessages, action.message]
        };
      }
      return {
        ...state,
        status: "running",
        acceptedMessages: [...state.acceptedMessages, action.message]
      };
    case "permission_request":
      return {
        ...state,
        status: "waiting_for_permission",
        waitingPermissionRequestId: action.requestId
      };
    case "permission_response":
      return {
        ...state,
        status: "running",
        waitingPermissionRequestId: void 0
      };
    case "turn_completed":
      if (state.status === "running") {
        return { ...state, status: "turn_completed" };
      }
      return state;
    case "complete": {
      if (state.status === "turn_completed") {
        const [nextMessage2, ...remaining2] = state.queuedMessages;
        if (nextMessage2) {
          return {
            ...state,
            status: "running",
            acceptedMessages: [...state.acceptedMessages, nextMessage2],
            queuedMessages: remaining2
          };
        }
        return { ...state, status: "ready" };
      }
      const [nextMessage, ...remaining] = state.queuedMessages;
      if (nextMessage) {
        return {
          ...state,
          status: "running",
          acceptedMessages: [...state.acceptedMessages, nextMessage],
          queuedMessages: remaining
        };
      }
      return { ...state, status: "ready" };
    }
    case "abort":
      return {
        ...state,
        status: "ready",
        lastError: action.reason,
        queuedMessages: [],
        waitingPermissionRequestId: void 0
      };
    case "error":
      return { ...state, status: "failed", lastError: action.error };
    case "dispose":
      return {
        ...state,
        status: "disposed",
        queuedMessages: [],
        waitingPermissionRequestId: void 0
      };
  }
}
function createRuntimeExtensionContext(context = {}) {
  return {
    policy: context.policy,
    sources: context.sources ? { enabledSourceSlugs: unique(context.sources.enabledSourceSlugs) } : void 0,
    skills: context.skills ? { activeSkillSlugs: unique(context.skills.activeSkillSlugs) } : void 0,
    commandOrigin: context.commandOrigin,
    hostServices: context.hostServices
  };
}
function sanitizeProviderSourceTools(sourceTools) {
  if (!sourceTools || sourceTools.length === 0) return [];
  const sanitized = [];
  for (const sourceTool of sourceTools) {
    if (sourceTool.kind === "api-source") {
      const defaultHeaders = sourceTool.defaultHeaders ? copyNonCredentialStringRecord(sourceTool.defaultHeaders) : void 0;
      sanitized.push({
        kind: "api-source",
        sourceSlug: sourceTool.sourceSlug,
        baseUrl: sourceTool.baseUrl,
        authType: sourceTool.authType,
        ...defaultHeaders && Object.keys(defaultHeaders).length > 0 ? { defaultHeaders } : {},
        ...sourceTool.credentialRef ? { credentialRef: sanitizeSourceCredentialRef(sourceTool.credentialRef) } : {}
      });
      continue;
    }
    if (sourceTool.kind === "local-source") {
      sanitized.push({
        kind: "local-source",
        sourceSlug: sourceTool.sourceSlug,
        path: sourceTool.path,
        ...sourceTool.format ? { format: sourceTool.format } : {}
      });
      continue;
    }
    if (sourceTool.kind === "mcp-server") {
      const env = sourceTool.env ? copyNonCredentialStringRecord(sourceTool.env) : void 0;
      const headers = sourceTool.headers ? copyNonCredentialStringRecord(sourceTool.headers) : void 0;
      sanitized.push({
        kind: "mcp-server",
        sourceSlug: sourceTool.sourceSlug,
        transport: sourceTool.transport,
        ...sourceTool.url ? { url: sourceTool.url } : {},
        ...sourceTool.command ? { command: sourceTool.command } : {},
        ...sourceTool.args ? { args: sourceTool.args.filter((value) => typeof value === "string") } : {},
        ...env && Object.keys(env).length > 0 ? { env } : {},
        ...headers && Object.keys(headers).length > 0 ? { headers } : {},
        ...sourceTool.credentialRef ? { credentialRef: sanitizeSourceCredentialRef(sourceTool.credentialRef) } : {}
      });
    }
  }
  return sanitized;
}
var sessionToolRequestCounter = 0;
async function invokeSessionTool(options) {
  const requestId = `session-tool-${++sessionToolRequestCounter}`;
  const origin = originFromSessionToolRequest(options.request) ?? options.commandOrigin;
  const policyDecision = await evaluateSessionToolPolicy(options, requestId);
  const timelineRefs = [];
  const append = (item) => {
    const envelope = options.appendTimeline?.(item);
    if (envelope) {
      timelineRefs.push({ epoch: envelope.epoch, seq: envelope.seq });
    }
  };
  if (policyDecision.decision !== "allow") {
    const reason = policyDecision.decision === "deny" ? policyDecision.reason : policyDecision.reason;
    append({
      type: "host_state_changed",
      state: {
        kind: "host_tool_denied",
        requestId,
        toolName: options.toolName,
        reason
      }
    });
    return {
      ok: false,
      requestId,
      toolName: options.toolName,
      origin,
      policyDecision,
      reason,
      timelineRefs
    };
  }
  append({
    type: "host_state_changed",
    state: {
      kind: "host_tool_invoked",
      requestId,
      toolName: options.toolName,
      ...origin ? { origin } : {}
    }
  });
  const callback = options.bridge[options.toolName];
  if (!callback) {
    const reason = `Session tool bridge callback is not registered: ${String(options.toolName)}`;
    append({
      type: "host_state_changed",
      state: {
        kind: "host_tool_result",
        requestId,
        toolName: options.toolName,
        ok: false,
        reason
      }
    });
    return {
      ok: false,
      requestId,
      toolName: options.toolName,
      origin,
      policyDecision,
      reason,
      timelineRefs
    };
  }
  try {
    const result = await callback(options.request);
    append({
      type: "host_state_changed",
      state: {
        kind: "host_tool_result",
        requestId,
        toolName: options.toolName,
        ok: true
      }
    });
    return {
      ok: true,
      requestId,
      toolName: options.toolName,
      origin,
      policyDecision,
      result,
      timelineRefs
    };
  } catch (error) {
    const reason = error instanceof Error ? error.message : String(error);
    append({
      type: "host_state_changed",
      state: {
        kind: "host_tool_result",
        requestId,
        toolName: options.toolName,
        ok: false,
        reason
      }
    });
    return {
      ok: false,
      requestId,
      toolName: options.toolName,
      origin,
      policyDecision,
      reason,
      timelineRefs
    };
  }
}
async function evaluateSessionToolPolicy(options, requestId) {
  if (!options.policy) return { decision: "allow" };
  return options.policy({
    toolName: `host.${String(options.toolName)}`,
    input: recordFromSessionToolRequest(options.request),
    toolIntent: { kind: "unknown", toolName: `host.${String(options.toolName)}` },
    scope: { type: "session", sessionId: options.sessionId }
  });
}
function originFromSessionToolRequest(request) {
  const record = recordFromSessionToolRequest(request);
  const origin = record.origin ?? record.commandOrigin;
  return isCommandOrigin(origin) ? origin : void 0;
}
function recordFromSessionToolRequest(request) {
  return request && typeof request === "object" ? { ...request } : {};
}
function isCommandOrigin(value) {
  if (!value || typeof value !== "object") return false;
  const type = value.type;
  return type === "user" || type === "automation" || type === "scheduler" || type === "host" || type === "replay" || type === "system";
}
function unique(values) {
  return [...new Set(values)];
}
function sanitizeSourceCredentialRef(credentialRef) {
  return {
    type: credentialRef.type,
    sourceSlug: credentialRef.sourceSlug,
    ...credentialRef.workspaceId ? { workspaceId: credentialRef.workspaceId } : {}
  };
}
function copyStringRecord(record) {
  return Object.fromEntries(
    Object.entries(record).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string")
  );
}
function copyNonCredentialStringRecord(record) {
  return Object.fromEntries(
    Object.entries(copyStringRecord(record)).filter(([key]) => !isCredentialKey(key))
  );
}
function isCredentialKey(key) {
  const normalized = key.toLowerCase();
  return normalized === "authorization" || normalized === "proxy-authorization" || normalized === "cookie" || normalized === "set-cookie" || normalized.includes("api-key") || normalized.includes("apikey") || normalized.includes("token") || normalized.includes("secret") || normalized.includes("password");
}
function findCandidate(candidates, kind) {
  return candidates.find((candidate) => candidate.kind === kind);
}
function defaultRuntimeKindOrder(provider) {
  if (provider === "codex") {
    return ["app-server", "native-sdk", "compatible-sdk", "cli-fallback"];
  }
  return RUNTIME_KINDS;
}
function firstAvailableCandidate(candidates, provider) {
  for (const kind of defaultRuntimeKindOrder(provider)) {
    const candidate = findCandidate(candidates, kind);
    if (candidate?.available) return candidate;
  }
  return void 0;
}
function selectRuntimeCandidate(options) {
  const preferred = options.preferredRuntime ? findCandidate(options.candidates, options.preferredRuntime) : void 0;
  if (preferred?.available) {
    return { selected: preferred.kind, fallback: false };
  }
  if (preferred && options.allowFallback !== true) {
    return {
      fallback: false,
      error: preferred.reason ?? `${preferred.kind} runtime is unavailable`
    };
  }
  const selected = firstAvailableCandidate(options.candidates, options.provider);
  if (!selected) {
    return {
      fallback: false,
      error: options.candidates.map((candidate) => candidate.reason).filter(Boolean).join("; ") || "No runtime candidates are available"
    };
  }
  const fallback = Boolean(preferred && selected.kind !== preferred.kind);
  return {
    selected: selected.kind,
    fallback,
    fallbackReason: fallback ? preferred?.reason ?? `${preferred?.kind ?? "preferred"} runtime is unavailable` : void 0
  };
}
function createRuntimeCapabilityReport(options) {
  const selection = selectRuntimeCandidate(options);
  const extensionCapabilities = normalizeExtensionCapabilities(options.extensionCapabilities);
  return {
    provider: options.provider,
    candidates: options.candidates,
    preferredRuntime: options.preferredRuntime,
    allowFallback: options.allowFallback === true,
    auth: options.auth,
    ...extensionCapabilities,
    ...selection
  };
}
function normalizeExtensionCapabilities(capabilities = {}) {
  return {
    policyCapabilities: capabilities.policy ?? {
      supported: false,
      modes: [],
      approvals: false,
      toolPolicy: false
    },
    sourceCapabilities: capabilities.sources ?? {
      supported: false
    },
    skillCapabilities: capabilities.skills ?? {
      supported: false
    },
    automationCapabilities: capabilities.automations ?? {
      supported: false,
      eventBus: false,
      schedulerHost: false,
      promptAction: false,
      webhookAction: false
    },
    hostToolCapabilities: capabilities.hostTools ?? {
      supported: false,
      sessionTools: false,
      workflowTransitions: false,
      browserActions: false,
      metadataWrites: false
    }
  };
}

export {
  initialRuntimeState,
  reduceRuntimeState,
  createRuntimeExtensionContext,
  sanitizeProviderSourceTools,
  invokeSessionTool,
  selectRuntimeCandidate,
  createRuntimeCapabilityReport
};
