#!/usr/bin/env node
import { L as state, M as getEnvString, c as logger } from "./logger-4ntIRWmf.js";
import { i as resolvePackageEntryPoint, o as safeResolve, r as importModule } from "./esm-BOYGx5J1.js";
import { at as sanitizeBody, et as emitTurnMarkerSpan, nt as getGenAITracer, ot as withGenAISpan, rt as getTraceparent } from "./util-DAS7mIn_.js";
import { i as initializeAgenticCache, o as resolveAgenticWorkingDir, r as getCachedResponse, t as cacheResponse } from "./agentic-utils-vF_Yu2eT.js";
import { t as transformMCPConfigToClaudeCode } from "./transform-jttM7xdw.js";
import { t as ANTHROPIC_MODELS } from "./util-D33gmFiU.js";
import { n as PROMPTFOO_RESOURCE_ATTR_TRACE_ID, t as PROMPTFOO_RESOURCE_ATTR_PARENT_SPAN_ID } from "./resourceAttributes-DO68Chok.js";
import path from "node:path";
import fsPromises from "node:fs/promises";
import dedent from "dedent";
import { SpanStatusCode, trace } from "@opentelemetry/api";
import os from "node:os";
//#region src/providers/claude-agent-sdk.ts
/** Hard cap for attribute body length on synthesized tool spans. */
const TOOL_SPAN_BODY_LIMIT = 4096;
/**
* Append promptfoo-specific resource-attribute kvs to a W3C-style
* `OTEL_RESOURCE_ATTRIBUTES` string, removing trailing whitespace/commas from
* the existing value and stripping any previous occurrence of our keys so the
* producer can't double-up. Returns the new string. Exported for tests.
*/
function appendPromptfooResourceAttrs(existing, traceId, parentSpanId) {
	const incoming = `${PROMPTFOO_RESOURCE_ATTR_TRACE_ID}=${traceId},${PROMPTFOO_RESOURCE_ATTR_PARENT_SPAN_ID}=${parentSpanId}`;
	if (!existing) return incoming;
	const cleaned = existing.split(",").map((pair) => pair.trim()).filter((pair) => pair.length > 0 && !pair.startsWith(`promptfoo.trace_id=`) && !pair.startsWith(`promptfoo.parent_span_id=`)).join(",");
	return cleaned.length > 0 ? `${cleaned},${incoming}` : incoming;
}
function stringifyForSpan(value) {
	if (value === void 0 || value === null) return;
	let raw;
	if (typeof value === "string") raw = value;
	else try {
		raw = JSON.stringify(value);
	} catch {
		return "<unserializable>";
	}
	if (raw === void 0) return;
	const sanitized = sanitizeBody(raw);
	return sanitized.length > TOOL_SPAN_BODY_LIMIT ? `${sanitized.slice(0, TOOL_SPAN_BODY_LIMIT - 15)}... [truncated]` : sanitized;
}
/**
* Emit a child span for a single tool call. Parents to the currently active
* span (the provider's GenAI wrapper) so the UI shows an agent → tool hierarchy
* similar to the OpenAI Agents SDK.
*
* When `incomplete` is true the call never produced a matching `tool_result`
* (aborted run, stop hook, or the stream ended mid-tool). Such spans are
* flagged via `tool.incomplete` and marked ERROR so traces surface the gap
* instead of silently dropping the tool.
*/
function emitToolSpan(entry, startTimeMs, endTimeMs, isError, incomplete = false, turnIndex) {
	try {
		const tracer = getGenAITracer();
		const attributes = {
			"tool.name": entry.name,
			"tool.is_error": isError
		};
		if (incomplete) attributes["tool.incomplete"] = true;
		const input = stringifyForSpan(entry.input);
		if (input !== void 0) attributes["tool.input"] = input;
		const output = stringifyForSpan(entry.output);
		if (output !== void 0) attributes["tool.output"] = output;
		if (entry.parentToolUseId) attributes["tool.parent_id"] = entry.parentToolUseId;
		if (typeof turnIndex === "number") attributes["gen_ai.turn.index"] = turnIndex;
		const span = tracer.startSpan(`tool ${entry.name}`, {
			startTime: startTimeMs,
			attributes
		});
		span.setStatus({ code: isError || incomplete ? SpanStatusCode.ERROR : SpanStatusCode.OK });
		span.end(endTimeMs);
	} catch (err) {
		logger.warn(`[ClaudeAgentSDK] Failed to emit tool span for ${entry.name}: ${err}`);
	}
}
function deriveSkillCalls(toolCalls) {
	return toolCalls.filter((toolCall) => toolCall.name === "Skill").flatMap((toolCall) => {
		const skillName = toolCall.input && typeof toolCall.input === "object" && typeof toolCall.input.skill === "string" ? toolCall.input.skill.trim() : "";
		if (!skillName) return [];
		return [{
			name: skillName,
			input: toolCall.input,
			is_error: toolCall.is_error,
			source: "tool"
		}];
	});
}
/**
* Claude Agent SDK Provider
*
* This provider requires the @anthropic-ai/claude-agent-sdk package to be installed separately:
*   npm install @anthropic-ai/claude-agent-sdk
*
* Two default configurations:
* - No working_dir: Runs in temp directory with no tools - behaves like plain chat API
* - With working_dir: Runs in specified directory with read-only file tools (Read/Grep/Glob/LS)
*
* User can override tool permissions with 'custom_allowed_tools', 'append_allowed_tools', 'disallowed_tools', and 'permission_mode'.
*
* For side effects (file writes, system calls, etc.), user can override permissions and use a custom working directory. They're then responsible for setup/teardown and security considerations.
*
* MCP server connection details are passed through from config. strict_mcp_config is true by default to only allow explicitly configured MCP servers.
*/
const FS_READONLY_ALLOWED_TOOLS = [
	"Read",
	"Grep",
	"Glob",
	"LS"
].sort();
const CLAUDE_CODE_MODEL_ALIASES = [
	"default",
	"sonnet",
	"opus",
	"haiku",
	"sonnet[1m]",
	"opusplan"
];
/**
* Helper to load the Claude Agent SDK ESM module
* Uses resolvePackageEntryPoint to handle ESM-only packages with restrictive exports
*/
async function loadClaudeCodeSDK() {
	const basePath = state.basePath && path.isAbsolute(state.basePath) ? state.basePath : process.cwd();
	const claudeCodePath = resolvePackageEntryPoint("@anthropic-ai/claude-agent-sdk", basePath);
	if (!claudeCodePath) throw new Error(dedent`The @anthropic-ai/claude-agent-sdk package could not be resolved from ${basePath}.

      To use the Claude Agent SDK provider, install it with:
        npm install @anthropic-ai/claude-agent-sdk

      If the package is already installed elsewhere, run promptfoo from the
      project root (or point the config at that root) so node_modules is on
      the resolution path.

      For more information, see: https://www.promptfoo.dev/docs/providers/claude-agent-sdk/`);
	try {
		return importModule(claudeCodePath);
	} catch (err) {
		logger.error(`Failed to load Claude Agent SDK: ${err}`);
		if (err.stack) logger.error(err.stack);
		throw new Error(dedent`Failed to load @anthropic-ai/claude-agent-sdk.

      The package was found but could not be loaded. This may be due to:
      - Incompatible Node.js version (requires Node.js ^20.20.0 or >=22.22.0)
      - Corrupted installation

      Try reinstalling:
        npm install @anthropic-ai/claude-agent-sdk

      For more information, see: https://www.promptfoo.dev/docs/providers/claude-agent-sdk/`);
	}
}
/**
* Creates a canUseTool callback for handling AskUserQuestion tool in automated evaluations.
* This provides automated responses to questions that would normally require user input.
*
* The callback wraps an optional user-provided canUseTool and handles AskUserQuestion specifically,
* deferring to the wrapped callback for all other tools.
*/
function createAskUserQuestionCanUseTool(behavior = "first_option", wrappedCanUseTool) {
	return async (toolName, input, options) => {
		if (toolName !== "AskUserQuestion") {
			if (wrappedCanUseTool) return wrappedCanUseTool(toolName, input, options);
			return {
				behavior: "allow",
				updatedInput: input
			};
		}
		if (behavior === "deny") return {
			behavior: "deny",
			message: "AskUserQuestion is disabled in automated evaluation mode"
		};
		const toolInput = input;
		const answers = {};
		for (const question of toolInput.questions) {
			if (!question.options || question.options.length === 0) continue;
			let selectedLabels;
			if (behavior === "random") {
				const randomIndex = Math.floor(Math.random() * question.options.length);
				selectedLabels = [question.options[randomIndex].label];
			} else selectedLabels = [question.options[0].label];
			answers[question.question] = selectedLabels.join(", ");
		}
		return {
			behavior: "allow",
			updatedInput: {
				questions: toolInput.questions,
				answers
			}
		};
	};
}
var ClaudeCodeSDKProvider = class ClaudeCodeSDKProvider {
	static ANTHROPIC_MODELS = ANTHROPIC_MODELS;
	static ANTHROPIC_MODELS_NAMES = ANTHROPIC_MODELS.map((model) => model.id);
	config;
	env;
	apiKey;
	providerId = "anthropic:claude-agent-sdk";
	claudeCodeModule;
	constructor(options = {}) {
		const { config, env, id } = options;
		this.config = config ?? {};
		this.env = env;
		this.apiKey = this.getApiKey();
		this.providerId = id ?? this.providerId;
		if (this.config.model && !ClaudeCodeSDKProvider.ANTHROPIC_MODELS_NAMES.includes(this.config.model) && !CLAUDE_CODE_MODEL_ALIASES.includes(this.config.model)) logger.warn(`Using unknown model for Claude Agent SDK: ${this.config.model}`);
		if (this.config.fallback_model && !ClaudeCodeSDKProvider.ANTHROPIC_MODELS_NAMES.includes(this.config.fallback_model) && !CLAUDE_CODE_MODEL_ALIASES.includes(this.config.fallback_model)) logger.warn(`Using unknown model for Claude Agent SDK fallback: ${this.config.fallback_model}`);
	}
	id() {
		return this.providerId;
	}
	async callApi(prompt, context, callOptions) {
		const config = {
			...this.config,
			...context?.prompt?.config
		};
		const env = {};
		for (const key of Object.keys(process.env).sort()) if (process.env[key] !== void 0) env[key] = process.env[key];
		if (config.env) for (const key of Object.keys(config.env).sort()) {
			const value = config.env[key];
			if (value !== void 0) env[key] = value;
		}
		if (this.env) for (const key of Object.keys(this.env).sort()) {
			const value = this.env[key];
			if (value !== void 0) env[key] = value;
		}
		if (this.apiKey) env.ANTHROPIC_API_KEY = this.apiKey;
		if (!this.apiKey && !(config.apiKeyRequired === false || env.CLAUDE_CODE_USE_BEDROCK || env.CLAUDE_CODE_USE_VERTEX)) throw new Error(dedent`Anthropic API key is not set. Set the ANTHROPIC_API_KEY environment variable or add "apiKey" to the provider config.

        Use CLAUDE_CODE_USE_BEDROCK or CLAUDE_CODE_USE_VERTEX environment variables to use Bedrock or Vertex instead.`);
		if (config.allow_all_tools && ("custom_allowed_tools" in config || "append_allowed_tools" in config)) throw new Error("Cannot specify both allow_all_tools and custom_allowed_tools or append_allowed_tools");
		if ("custom_allowed_tools" in config && "append_allowed_tools" in config) throw new Error("Cannot specify both custom_allowed_tools and append_allowed_tools");
		if (config.permission_mode === "bypassPermissions" && !config.allow_dangerously_skip_permissions) throw new Error("permission_mode 'bypassPermissions' requires allow_dangerously_skip_permissions: true as a safety measure");
		if (config.title && (config.resume || config.continue)) logger.warn("[ClaudeAgentSDK] `title` is ignored when `resume` or `continue` is set; the persisted session title is used instead.");
		const defaultAllowedTools = config.working_dir ? FS_READONLY_ALLOWED_TOOLS : [];
		let allowedTools = config.allow_all_tools ? void 0 : defaultAllowedTools;
		if ("custom_allowed_tools" in config) allowedTools = Array.from(new Set(config.custom_allowed_tools ?? [])).sort();
		else if (config.append_allowed_tools) allowedTools = Array.from(new Set([...defaultAllowedTools, ...config.append_allowed_tools])).sort();
		const disallowedTools = config.disallowed_tools ? Array.from(new Set(config.disallowed_tools)).sort() : void 0;
		const basePath = state.basePath ? path.resolve(state.basePath) : process.cwd();
		let isTempDir = false;
		let workingDir;
		if (config.working_dir) workingDir = resolveAgenticWorkingDir(config.working_dir, basePath);
		else isTempDir = true;
		let canUseTool = config.can_use_tool;
		if (config.ask_user_question) canUseTool = createAskUserQuestionCanUseTool(config.ask_user_question.behavior, config.can_use_tool);
		const cacheKeyQueryOptions = {
			maxTurns: config.max_turns,
			model: config.model,
			fallbackModel: config.fallback_model,
			strictMcpConfig: config.strict_mcp_config ?? true,
			permissionMode: config.permission_mode,
			planModeInstructions: config.plan_mode_instructions,
			systemPrompt: config.custom_system_prompt ? config.custom_system_prompt : {
				type: "preset",
				preset: "claude_code",
				append: config.append_system_prompt,
				...config.exclude_dynamic_sections ? { excludeDynamicSections: true } : {}
			},
			maxThinkingTokens: config.max_thinking_tokens,
			allowedTools,
			disallowedTools,
			plugins: config.plugins?.map((plugin) => ({
				...plugin,
				path: safeResolve(basePath, plugin.path)
			})),
			skills: config.skills,
			maxBudgetUsd: config.max_budget_usd,
			additionalDirectories: config.additional_directories?.map((dir) => safeResolve(basePath, dir)),
			resume: config.resume,
			forkSession: config.fork_session,
			resumeSessionAt: config.resume_session_at,
			continue: config.continue,
			agents: config.agents,
			outputFormat: config.output_format,
			hooks: config.hooks,
			includePartialMessages: config.include_partial_messages,
			includeHookEvents: config.include_hook_events,
			forwardSubagentText: config.forward_subagent_text,
			toolConfig: config.tool_config,
			promptSuggestions: config.prompt_suggestions,
			agentProgressSummaries: config.agent_progress_summaries,
			settings: typeof config.settings === "string" && config.settings ? safeResolve(basePath, config.settings) : config.settings,
			managedSettings: config.managed_settings,
			betas: config.betas,
			thinking: config.thinking,
			effort: config.effort,
			agent: config.agent,
			sessionId: config.session_id,
			debug: config.debug,
			debugFile: config.debug_file ? safeResolve(basePath, config.debug_file) : void 0,
			sandbox: config.sandbox,
			allowDangerouslySkipPermissions: config.allow_dangerously_skip_permissions,
			permissionPromptToolName: config.permission_prompt_tool_name,
			executable: config.executable,
			executableArgs: config.executable_args,
			extraArgs: config.extra_args,
			pathToClaudeCodeExecutable: config.path_to_claude_code_executable ? safeResolve(basePath, config.path_to_claude_code_executable) : void 0,
			settingSources: config.setting_sources,
			tools: config.tools,
			enableFileCheckpointing: config.enable_file_checkpointing,
			persistSession: config.persist_session,
			taskBudget: config.task_budget,
			env
		};
		const userProvidedCanUseTool = Boolean(config.can_use_tool);
		if (userProvidedCanUseTool) logger.debug("[ClaudeCodeSDKProvider] Bypassing cache: user-supplied can_use_tool callback present");
		const cacheResult = userProvidedCanUseTool ? {
			shouldCache: false,
			shouldReadCache: false,
			shouldWriteCache: false
		} : await initializeAgenticCache({
			cacheKeyPrefix: "anthropic:claude-agent-sdk",
			workingDir,
			bustCache: context?.bustCache,
			mcp: config.mcp?.servers?.length ? config.mcp : void 0,
			cacheMcp: config.cache_mcp
		}, {
			prompt,
			cacheKeyQueryOptions
		});
		const cachedResponse = await getCachedResponse(cacheResult, "Claude Agent SDK");
		if (cachedResponse) return cachedResponse;
		const mcpServers = config.mcp ? await transformMCPConfigToClaudeCode(config.mcp) : {};
		if (workingDir) {
			let stats;
			try {
				stats = await fsPromises.stat(workingDir);
			} catch (err) {
				throw new Error(`Working dir ${config.working_dir} does not exist or isn't accessible: ${err.message}`);
			}
			if (!stats.isDirectory()) throw new Error(`Working dir ${config.working_dir} is not a directory`);
		} else if (isTempDir) workingDir = await fsPromises.mkdtemp(path.join(os.tmpdir(), "promptfoo-claude-agent-sdk-"));
		if (callOptions?.abortSignal?.aborted) return { error: "Claude Agent SDK call aborted before it started" };
		const abortController = new AbortController();
		let abortHandler;
		if (callOptions?.abortSignal) {
			abortHandler = () => {
				abortController.abort(callOptions.abortSignal.reason);
			};
			callOptions.abortSignal.addEventListener("abort", abortHandler);
		}
		const options = {
			...cacheKeyQueryOptions,
			abortController,
			mcpServers,
			cwd: workingDir,
			stderr: config.stderr,
			spawnClaudeCodeProcess: config.spawn_claude_code_process,
			canUseTool,
			onElicitation: config.on_elicitation,
			title: config.title
		};
		const queryParams = {
			prompt,
			options
		};
		logger.debug(`Calling Claude Agent SDK: ${JSON.stringify({
			prompt,
			options: {
				...options,
				mcpServers: options.mcpServers ? Object.keys(options.mcpServers) : void 0,
				env: Object.keys(env).length > 0 ? Object.keys(env) : void 0
			}
		})}`);
		try {
			return await withGenAISpan({
				system: "anthropic",
				operationName: "chat",
				model: config.model || "default",
				providerId: this.providerId,
				traceparent: context?.traceparent,
				maxTokens: config.max_thinking_tokens,
				requestBody: prompt
			}, async () => {
				const ZERO_TRACE_ID = "00000000000000000000000000000000";
				const active = getTraceparent();
				const traceparent = (active && !active.includes(ZERO_TRACE_ID) ? active : void 0) ?? context?.traceparent;
				if (traceparent && !env.TRACEPARENT) env.TRACEPARENT = traceparent;
				const [, tpTraceId, tpSpanId] = traceparent ? traceparent.split("-") : [];
				if (tpTraceId && tpSpanId) env.OTEL_RESOURCE_ATTRIBUTES = appendPromptfooResourceAttrs(env.OTEL_RESOURCE_ATTRIBUTES, tpTraceId, tpSpanId);
				if (!this.claudeCodeModule) this.claudeCodeModule = await loadClaudeCodeSDK();
				const res = await this.claudeCodeModule.query(queryParams);
				const toolCallsMap = /* @__PURE__ */ new Map();
				const assistantErrors = [];
				const toolStartTimes = /* @__PURE__ */ new Map();
				let turnCount = 0;
				const toolTurnIndex = /* @__PURE__ */ new Map();
				const emitTurnSpan = (msg) => {
					const index = turnCount + 1;
					turnCount = index;
					const attributes = {
						"gen_ai.turn.index": index,
						"gen_ai.system": "anthropic"
					};
					if (msg.parent_tool_use_id) {
						attributes["gen_ai.turn.parent_tool_use_id"] = msg.parent_tool_use_id;
						attributes["gen_ai.turn.is_subagent"] = true;
					}
					if (msg.subagent_type) attributes["gen_ai.turn.subagent_type"] = msg.subagent_type;
					if (msg.message?.model) attributes["gen_ai.response.model"] = msg.message.model;
					const usage = msg.message?.usage;
					if (usage) {
						if (typeof usage.input_tokens === "number") attributes["gen_ai.usage.input_tokens"] = usage.input_tokens;
						if (typeof usage.output_tokens === "number") attributes["gen_ai.usage.output_tokens"] = usage.output_tokens;
					}
					if (msg.error) attributes["gen_ai.turn.error"] = msg.error;
					const now = Date.now();
					emitTurnMarkerSpan({
						tracer: getGenAITracer(),
						index,
						startTime: now,
						endTime: now,
						attributes,
						errorMessage: msg.error,
						logLabel: "ClaudeAgentSDK"
					});
					return index;
				};
				const drainOrphans = () => {
					if (toolStartTimes.size === 0) return;
					const endedAt = Date.now();
					for (const [toolUseId, startMs] of toolStartTimes) {
						const entry = toolCallsMap.get(toolUseId);
						if (entry) emitToolSpan(entry, startMs, endedAt, false, true, toolTurnIndex.get(toolUseId));
					}
					toolStartTimes.clear();
					toolTurnIndex.clear();
				};
				let lastResultMsg;
				let lastMainResultMsg;
				let resultMsgCount = 0;
				for await (const msg of res) if (msg.type === "assistant") {
					const turnIndex = emitTurnSpan(msg);
					for (const block of msg.message.content) if (block.type === "tool_use") {
						toolCallsMap.set(block.id, {
							id: block.id,
							name: block.name,
							input: block.input,
							output: void 0,
							is_error: false,
							parentToolUseId: msg.parent_tool_use_id
						});
						toolStartTimes.set(block.id, Date.now());
						toolTurnIndex.set(block.id, turnIndex);
					}
					if (msg.error) assistantErrors.push({
						error: msg.error,
						uuid: msg.uuid,
						parentToolUseId: msg.parent_tool_use_id,
						...msg.request_id ? { request_id: msg.request_id } : {},
						...msg.subagent_type ? { subagent_type: msg.subagent_type } : {},
						...msg.task_description ? { task_description: msg.task_description } : {}
					});
				} else if (msg.type === "user") {
					const content = msg.message?.content;
					if (Array.isArray(content)) {
						for (const block of content) if (block.type === "tool_result") {
							const entry = toolCallsMap.get(block.tool_use_id);
							if (entry) {
								entry.output = block.content;
								entry.is_error = block.is_error ?? false;
								const startMs = toolStartTimes.get(block.tool_use_id);
								if (startMs !== void 0) {
									emitToolSpan(entry, startMs, Date.now(), entry.is_error, false, toolTurnIndex.get(block.tool_use_id));
									toolStartTimes.delete(block.tool_use_id);
									toolTurnIndex.delete(block.tool_use_id);
								}
							}
						}
					}
				} else if (msg.type === "result") {
					lastResultMsg = msg;
					resultMsgCount++;
					if (msg.origin?.kind !== "task-notification") lastMainResultMsg = msg;
				}
				drainOrphans();
				const finalMsg = lastMainResultMsg ?? lastResultMsg;
				if (!finalMsg) return { error: "Claude Agent SDK call didn't return a result" };
				if ((!lastMainResultMsg || lastMainResultMsg.origin === void 0) && resultMsgCount > 1 && finalMsg.subtype === "success" && finalMsg.terminal_reason === void 0) {
					logger.warn(`[ClaudeAgentSDK] Stream produced ${resultMsgCount} result messages and the last had no terminal_reason; returning it as the main-agent result, but the stream may have been truncated.`);
					trace.getActiveSpan()?.setStatus({
						code: SpanStatusCode.ERROR,
						message: "stream closed without terminal_reason after multiple result messages"
					});
				}
				const raw = JSON.stringify(finalMsg);
				const tokenUsage = {
					prompt: finalMsg.usage?.input_tokens,
					completion: finalMsg.usage?.output_tokens,
					total: finalMsg.usage?.input_tokens && finalMsg.usage?.output_tokens ? finalMsg.usage?.input_tokens + finalMsg.usage?.output_tokens : void 0
				};
				const cost = finalMsg.total_cost_usd ?? 0;
				const sessionId = finalMsg.session_id;
				const toolCallsArray = Array.from(toolCallsMap.values());
				const skillCalls = deriveSkillCalls(toolCallsArray);
				const abortedTerminalReason = typeof finalMsg.terminal_reason === "string" && (finalMsg.terminal_reason.startsWith("aborted_") || finalMsg.terminal_reason === "hook_stopped") ? finalMsg.terminal_reason : void 0;
				if (abortedTerminalReason) trace.getActiveSpan()?.setStatus({
					code: SpanStatusCode.ERROR,
					message: `aborted: ${abortedTerminalReason}`
				});
				const apiErrorStatus = "api_error_status" in finalMsg ? finalMsg.api_error_status : void 0;
				if (finalMsg.subtype === "success") {
					logger.debug(`Claude Agent SDK response: ${raw}`);
					const response = {
						output: finalMsg.structured_output === void 0 ? finalMsg.result : finalMsg.structured_output,
						tokenUsage,
						cost,
						raw,
						sessionId,
						metadata: {
							skillCalls,
							toolCalls: toolCallsArray,
							numTurns: finalMsg.num_turns,
							durationMs: finalMsg.duration_ms,
							durationApiMs: finalMsg.duration_api_ms,
							modelUsage: finalMsg.modelUsage,
							permissionDenials: finalMsg.permission_denials,
							...finalMsg.terminal_reason === void 0 ? {} : { terminalReason: finalMsg.terminal_reason },
							...finalMsg.structured_output === void 0 ? {} : { structuredOutput: finalMsg.structured_output },
							...apiErrorStatus === void 0 || apiErrorStatus === null ? {} : { apiErrorStatus },
							...assistantErrors.length > 0 ? { assistantErrors } : {}
						}
					};
					await cacheResponse(cacheResult, response, "Claude Agent SDK");
					return response;
				}
				const lastAssistantError = assistantErrors.length > 0 ? assistantErrors[assistantErrors.length - 1].error : void 0;
				return {
					error: lastAssistantError ? `Claude Agent SDK call failed: ${finalMsg.subtype} (${lastAssistantError})` : `Claude Agent SDK call failed: ${finalMsg.subtype}`,
					tokenUsage,
					cost,
					raw,
					sessionId,
					metadata: {
						skillCalls,
						toolCalls: toolCallsArray,
						numTurns: finalMsg.num_turns,
						durationMs: finalMsg.duration_ms,
						durationApiMs: finalMsg.duration_api_ms,
						modelUsage: finalMsg.modelUsage,
						permissionDenials: finalMsg.permission_denials,
						...finalMsg.terminal_reason === void 0 ? {} : { terminalReason: finalMsg.terminal_reason },
						...apiErrorStatus === void 0 || apiErrorStatus === null ? {} : { apiErrorStatus },
						...assistantErrors.length > 0 ? { assistantErrors } : {}
					}
				};
			}, (response) => {
				const metadata = response.metadata ?? {};
				const additional = {};
				if (typeof metadata.numTurns === "number") additional["gen_ai.agent.num_turns"] = metadata.numTurns;
				if (typeof metadata.durationApiMs === "number") additional["gen_ai.agent.duration_api_ms"] = metadata.durationApiMs;
				if (typeof response.cost === "number" && response.cost > 0) additional["gen_ai.agent.cost_usd"] = response.cost;
				const toolCalls = metadata.toolCalls;
				if (Array.isArray(toolCalls) && toolCalls.length > 0) additional["gen_ai.agent.tool_call_count"] = toolCalls.length;
				let responseModel;
				const modelUsage = metadata.modelUsage;
				if (modelUsage && typeof modelUsage === "object" && !Array.isArray(modelUsage)) {
					let topUsage = -1;
					for (const [key, usage] of Object.entries(modelUsage)) {
						if (typeof key !== "string" || key.length === 0 || key === "undefined") continue;
						const total = (usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0);
						if (total > topUsage) {
							topUsage = total;
							responseModel = key;
						}
					}
				}
				const finishReasons = typeof metadata.terminalReason === "string" ? [metadata.terminalReason] : void 0;
				return {
					tokenUsage: response.tokenUsage,
					responseModel,
					responseId: response.sessionId,
					finishReasons,
					cacheHit: response.cached,
					responseBody: typeof response.output === "string" ? response.output : response.output === void 0 ? void 0 : JSON.stringify(response.output),
					additionalAttributes: Object.keys(additional).length > 0 ? additional : void 0
				};
			});
		} catch (error) {
			if (error?.name === "AbortError" || callOptions?.abortSignal?.aborted) {
				logger.warn("Claude Agent SDK call aborted");
				return { error: "Claude Agent SDK call aborted" };
			}
			logger.error(`Error calling Claude Agent SDK: ${error}`);
			return { error: `Error calling Claude Agent SDK: ${error}` };
		} finally {
			if (isTempDir && workingDir) await fsPromises.rm(workingDir, {
				recursive: true,
				force: true
			});
			if (callOptions?.abortSignal && abortHandler) callOptions.abortSignal.removeEventListener("abort", abortHandler);
		}
	}
	toString() {
		return "[Anthropic Claude Agent SDK Provider]";
	}
	/**
	* For normal Claude Agent SDK support, just use the Anthropic API key
	* Users can also use Bedrock (with CLAUDE_CODE_USE_BEDROCK env var) or Vertex (with CLAUDE_CODE_USE_VERTEX env var)
	*/
	requiresApiKey() {
		if (this.config.apiKeyRequired === false) return false;
		return !(this.env?.CLAUDE_CODE_USE_BEDROCK || this.env?.CLAUDE_CODE_USE_VERTEX || getEnvString("CLAUDE_CODE_USE_BEDROCK") || getEnvString("CLAUDE_CODE_USE_VERTEX"));
	}
	getApiKey() {
		return this.config?.apiKey || this.env?.ANTHROPIC_API_KEY || getEnvString("ANTHROPIC_API_KEY");
	}
	async cleanup() {}
};
//#endregion
export { ClaudeCodeSDKProvider };

//# sourceMappingURL=claude-agent-sdk-cPkmlt-r.js.map