import { env } from "../../../../env.js";
import { getLogger as getLogger$1 } from "../../../../logger.js";
import { setSpanWithError as setSpanWithError$1, tracer } from "../../utils/tracer.js";
import { SPAN_NAMES } from "@inkeep/agents-core";
import { context, propagation } from "@opentelemetry/api";
import { getWritable } from "workflow";

//#region src/domains/run/workflow/steps/agentExecutionSteps.ts
const logger = getLogger$1("agentExecutionSteps");
async function buildAgentForStep(params) {
	const { tenantId, projectId, agentId, currentSubAgentId, resolvedRef, forwardedHeaders } = params;
	const { getFullProjectWithRelationIds: getFullProjectWithRelationIds$1, getMcpToolById: getMcpToolById$1, withRef: withRef$1 } = await import("@inkeep/agents-core");
	const { default: manageDbPool } = await import("../../../../data/db/manageDbPool.js");
	const { Agent } = await import("../../agents/Agent.js");
	const { createTaskHandlerConfig } = await import("../../agents/generateTaskHandler.js");
	const { buildTransferRelationConfig } = await import("../../agents/relationTools.js");
	const { enhanceInternalRelation, enhanceTeamRelation, getArtifactComponentsForSubAgent, getDataComponentsForSubAgent, getSkillsForSubAgent, getSubAgentRelations, getToolsForSubAgent } = await import("../../utils/project.js");
	const project = await withRef$1(manageDbPool, resolvedRef, (db) => getFullProjectWithRelationIds$1(db)({ scopes: {
		tenantId,
		projectId
	} }));
	if (!project) throw new Error(`Project ${projectId} not found`);
	const agentEntry = project.agents?.[agentId];
	if (!agentEntry) throw new Error(`Agent ${agentId} not found in project`);
	const defaultSubAgentId = agentEntry.defaultSubAgentId;
	if (!defaultSubAgentId) throw new Error(`Agent ${agentId} has no default sub-agent`);
	const currentSubAgent = agentEntry.subAgents?.[currentSubAgentId];
	if (!currentSubAgent) throw new Error(`Sub-agent ${currentSubAgentId} not found`);
	const executionContext = {
		tenantId,
		projectId,
		agentId,
		baseUrl: env.INKEEP_AGENTS_API_URL || "http://localhost:3002",
		apiKey: env.INKEEP_AGENTS_RUN_API_BYPASS_SECRET || "",
		apiKeyId: "durable-execution",
		resolvedRef,
		project,
		metadata: {}
	};
	const taskHandlerConfig = await createTaskHandlerConfig({
		executionContext,
		subAgentId: currentSubAgentId,
		baseUrl: executionContext.baseUrl,
		apiKey: executionContext.apiKey
	});
	const { externalRelations, teamRelations, transferRelations, internalDelegateRelations } = getSubAgentRelations({
		agent: agentEntry,
		project,
		subAgent: currentSubAgent
	});
	const allInternalRelations = [...transferRelations, ...internalDelegateRelations];
	const toolsForAgent = getToolsForSubAgent({
		agent: agentEntry,
		project,
		subAgent: currentSubAgent
	});
	const dataComponents = getDataComponentsForSubAgent({
		project,
		subAgent: currentSubAgent
	});
	const artifactComponents = getArtifactComponentsForSubAgent({
		project,
		subAgent: currentSubAgent
	});
	const enhancedInternalRelations = allInternalRelations.map((relation) => {
		try {
			return enhanceInternalRelation({
				relation,
				agent: agentEntry,
				project
			});
		} catch {
			return relation;
		}
	});
	const enhancedTeamRelations = teamRelations.map((relation) => {
		try {
			return enhanceTeamRelation({
				relation,
				project
			});
		} catch {
			return relation;
		}
	});
	const toolsForAgentResult = await withRef$1(manageDbPool, resolvedRef, async (db) => {
		return await Promise.all(toolsForAgent.map(async (item) => {
			const mcpTool = await getMcpToolById$1(db)({
				scopes: {
					tenantId,
					projectId
				},
				toolId: item.tool.id,
				credentialStoreRegistry: void 0,
				userId: void 0
			});
			if (!mcpTool) throw new Error(`Tool not found: ${item.tool.id}`);
			if (item.relationshipId) mcpTool.relationshipId = item.relationshipId;
			if (item.selectedTools && item.selectedTools.length > 0) {
				const selectedToolsSet = new Set(item.selectedTools);
				mcpTool.availableTools = mcpTool.availableTools?.filter((t) => selectedToolsSet.has(t.name)) || [];
			}
			return mcpTool;
		}));
	}) ?? [];
	const skills = getSkillsForSubAgent({
		project,
		subAgent: currentSubAgent
	});
	const { agentSchema } = taskHandlerConfig;
	const prompt = "prompt" in agentSchema ? agentSchema.prompt || void 0 : "";
	const models = "models" in agentSchema ? agentSchema.models : void 0;
	const stopWhen = "stopWhen" in agentSchema ? agentSchema.stopWhen : void 0;
	return {
		agent: new Agent({
			id: currentSubAgentId,
			tenantId,
			projectId,
			agentId,
			agentName: agentEntry.name,
			baseUrl: executionContext.baseUrl,
			apiKey: executionContext.apiKey,
			userId: void 0,
			name: currentSubAgent.name,
			description: currentSubAgent.description || "",
			prompt,
			models: models || void 0,
			stopWhen: stopWhen || void 0,
			skills,
			subAgentRelations: enhancedInternalRelations.map((relation) => ({
				id: relation.id,
				tenantId,
				projectId,
				agentId,
				baseUrl: executionContext.baseUrl,
				apiKey: executionContext.apiKey,
				name: relation.name,
				description: relation.description || void 0,
				prompt: "",
				delegateRelations: [],
				subAgentRelations: [],
				transferRelations: [],
				relationId: relation.relationId
			})),
			transferRelations: await Promise.all(enhancedInternalRelations.filter((r) => r.relationType === "transfer").map((r) => buildTransferRelationConfig({
				relation: r,
				executionContext,
				baseUrl: executionContext.baseUrl,
				apiKey: executionContext.apiKey
			}, void 0))),
			delegateRelations: [
				...enhancedInternalRelations.filter((r) => r.relationType === "delegate").map((r) => ({
					type: "internal",
					config: {
						id: r.id,
						relationId: r.relationId,
						tenantId,
						projectId,
						agentId,
						baseUrl: executionContext.baseUrl,
						apiKey: executionContext.apiKey,
						name: r.name,
						description: r.description || void 0,
						prompt: "",
						delegateRelations: [],
						subAgentRelations: [],
						transferRelations: [],
						tools: [],
						project
					}
				})),
				...externalRelations.map((r) => ({
					type: "external",
					config: {
						id: r.externalAgent.id,
						name: r.externalAgent.name,
						description: r.externalAgent.description || "",
						ref: resolvedRef,
						baseUrl: r.externalAgent.baseUrl,
						headers: r.headers,
						credentialReferenceId: r.externalAgent.credentialReferenceId,
						relationId: r.relationId,
						relationType: "delegate"
					}
				})),
				...enhancedTeamRelations.map((r) => ({
					type: "team",
					config: {
						id: r.targetAgent.id,
						ref: resolvedRef,
						name: r.targetAgent.name,
						description: r.targetAgent.description || "",
						baseUrl: executionContext.baseUrl,
						headers: r.headers,
						relationId: r.relationId
					}
				}))
			],
			tools: toolsForAgentResult,
			functionTools: [],
			dataComponents,
			artifactComponents,
			contextConfigId: taskHandlerConfig.contextConfigId,
			conversationHistoryConfig: taskHandlerConfig.conversationHistoryConfig,
			forwardedHeaders
		}, executionContext, void 0),
		executionContext,
		defaultSubAgentId
	};
}
async function markWorkflowRunningStep(params) {
	"use step";
	const { payload, workflowRunId } = params;
	const { createWorkflowExecution } = await import("@inkeep/agents-core");
	const { default: runDbClient } = await import("../../../../data/db/runDbClient.js");
	await createWorkflowExecution(runDbClient)({
		id: workflowRunId,
		tenantId: payload.tenantId,
		projectId: payload.projectId,
		agentId: payload.agentId,
		conversationId: payload.conversationId,
		requestId: payload.requestId,
		status: "running"
	});
	logger.info({
		workflowRunId,
		conversationId: payload.conversationId
	}, "Workflow execution marked as running");
}
async function initializeTaskStep(params) {
	"use step";
	const { payload } = params;
	const { tenantId, projectId, agentId, conversationId, requestId } = payload;
	const { AGENT_EXECUTION_TRANSFER_COUNT_DEFAULT: AGENT_EXECUTION_TRANSFER_COUNT_DEFAULT$1, createTask: createTask$1, getFullProjectWithRelationIds: getFullProjectWithRelationIds$1, isUniqueConstraintError: isUniqueConstraintError$1, withRef: withRef$1 } = await import("@inkeep/agents-core");
	const { default: manageDbPool } = await import("../../../../data/db/manageDbPool.js");
	const { default: runDbClient } = await import("../../../../data/db/runDbClient.js");
	const project = await withRef$1(manageDbPool, payload.resolvedRef, (db) => getFullProjectWithRelationIds$1(db)({ scopes: {
		tenantId,
		projectId
	} }));
	if (!project) throw new Error(`Project ${projectId} not found`);
	const agentEntry = project.agents?.[agentId];
	if (!agentEntry) throw new Error(`Agent ${agentId} not found in project`);
	const defaultSubAgentId = agentEntry.defaultSubAgentId;
	if (!defaultSubAgentId) throw new Error(`Agent ${agentId} has no default sub-agent`);
	const maxTransfers = agentEntry.stopWhen?.transferCountIs ?? AGENT_EXECUTION_TRANSFER_COUNT_DEFAULT$1;
	const taskId = `task_${conversationId}-${requestId}`;
	try {
		await createTask$1(runDbClient)({
			id: taskId,
			tenantId,
			projectId,
			agentId,
			subAgentId: defaultSubAgentId,
			contextId: conversationId,
			status: "pending",
			ref: payload.resolvedRef,
			metadata: {
				conversation_id: conversationId,
				message_id: requestId,
				stream_request_id: requestId,
				created_at: (/* @__PURE__ */ new Date()).toISOString(),
				updated_at: (/* @__PURE__ */ new Date()).toISOString(),
				root_sub_agent_id: defaultSubAgentId,
				sub_agent_id: defaultSubAgentId
			}
		});
	} catch (error) {
		if (isUniqueConstraintError$1(error)) logger.info({ taskId }, "Task already exists, reusing");
		else throw error;
	}
	logger.info({
		taskId,
		defaultSubAgentId,
		maxTransfers
	}, "Task initialized");
	return {
		taskId,
		defaultSubAgentId,
		maxTransfers
	};
}
async function callLlmStep(params) {
	"use step";
	const { payload, currentSubAgentId, isFirstMessage, workflowRunId, streamNamespace, taskId } = params;
	const { tenantId, projectId, agentId, conversationId, userMessage, messageParts, requestId, forwardedHeaders, emitOperations, outputFormat } = payload;
	logger.info({
		currentSubAgentId,
		isFirstMessage,
		workflowRunId,
		streamNamespace,
		taskId
	}, "callLlmStep starting");
	const { createMessage: createMessage$1, generateId: generateId$1, updateTask: updateTask$1 } = await import("@inkeep/agents-core");
	const { default: runDbClient } = await import("../../../../data/db/runDbClient.js");
	const { WritableBackedHonoSSEStream, WritableBackedVercelWriter } = await import("../../stream/durable-stream-helper.js");
	const { createSSEStreamHelper, createVercelStreamHelper } = await import("../../stream/stream-helpers.js");
	const { registerStreamHelper, unregisterStreamHelper } = await import("../../stream/stream-registry.js");
	const { agentSessionManager } = await import("../../session/AgentSession.js");
	const { agentInitializingOp, completionOp, errorOp } = await import("../../utils/agent-operations.js");
	const { executeTransfer } = await import("../../a2a/transfer.js");
	const { triggerConversationEvaluation } = await import("../../../evals/services/conversationEvaluation.js");
	const { hasToolCallWithPrefix } = await import("../../agents/agent-types.js");
	const { agent, executionContext } = await buildAgentForStep({
		tenantId,
		projectId,
		agentId,
		currentSubAgentId,
		resolvedRef: payload.resolvedRef,
		forwardedHeaders
	});
	const timestamp = Math.floor(Date.now() / 1e3);
	const writable = getWritable(streamNamespace ? { namespace: streamNamespace } : {});
	let closeable;
	let sseHelper;
	if (outputFormat === "vercel") {
		const vercelWriter = new WritableBackedVercelWriter(writable);
		closeable = vercelWriter;
		sseHelper = createVercelStreamHelper(vercelWriter);
		logger.debug({ requestId }, "callLlmStep: using Vercel stream writer");
	} else {
		const writableStream = new WritableBackedHonoSSEStream(writable);
		closeable = writableStream;
		sseHelper = createSSEStreamHelper(writableStream, requestId, timestamp);
		logger.debug({ requestId }, "callLlmStep: using SSE stream writer");
	}
	agent.streamRequestId = requestId;
	agent.runContext.streamHelper = sseHelper;
	agent.setConversationId(conversationId);
	agent.setDurableWorkflowRunId(workflowRunId);
	registerStreamHelper(requestId, sseHelper);
	agentSessionManager.createSession(requestId, executionContext, conversationId);
	if (emitOperations) agentSessionManager.enableEmitOperations(requestId);
	logger.debug({
		requestId,
		conversationId,
		currentSubAgentId
	}, "callLlmStep: session and stream registered");
	let isTerminal = false;
	const bag = (propagation.getBaggage(context.active()) ?? propagation.createBaggage()).setEntry("conversation.id", { value: conversationId }).setEntry("tenant.id", { value: tenantId }).setEntry("project.id", { value: projectId }).setEntry("agent.id", { value: agentId });
	const ctxWithBaggage = propagation.setBaggage(context.active(), bag);
	return context.with(ctxWithBaggage, async () => {
		try {
			if (isFirstMessage && emitOperations) await sseHelper.writeOperation(agentInitializingOp(requestId, agentId));
			const userParts = isFirstMessage && messageParts && messageParts.length > 0 ? messageParts : [{
				kind: "text",
				text: userMessage
			}];
			const runtimeContext = {
				contextId: conversationId,
				metadata: {
					conversationId,
					threadId: conversationId,
					taskId,
					streamRequestId: requestId,
					apiKey: executionContext.apiKey
				}
			};
			logger.debug({
				requestId,
				currentSubAgentId,
				userPartsCount: userParts.length
			}, "callLlmStep: calling agent.generate");
			const response = await agent.generate(userParts, runtimeContext);
			logger.info({
				requestId,
				currentSubAgentId,
				finishReason: response.finishReason,
				stepCount: response.steps?.length,
				hasText: !!response.text,
				hasPendingApproval: !!agent.runContext.pendingDurableApproval
			}, "callLlmStep: agent.generate completed");
			const pendingApproval = agent.runContext.pendingDurableApproval;
			if (pendingApproval) {
				logger.info({
					toolName: pendingApproval.toolName,
					toolCallId: pendingApproval.toolCallId
				}, "callLlmStep: tool needs approval, suspending");
				isTerminal = true;
				return {
					type: "tool_calls",
					toolCalls: [{
						toolCallId: pendingApproval.toolCallId,
						toolName: pendingApproval.toolName,
						args: pendingApproval.args
					}]
				};
			}
			if (hasToolCallWithPrefix("transfer_to_")(response)) {
				const transferReason = response.steps?.[response.steps.length - 1]?.text || response.text || "";
				const transferToolCall = ((response.steps?.at(-1))?.toolCalls ?? []).find((tc) => tc.toolName.startsWith("transfer_to_"));
				const targetSubAgentId = transferToolCall?.toolName.slice(12);
				logger.info({
					currentSubAgentId,
					targetSubAgentId,
					transferToolName: transferToolCall?.toolName
				}, "callLlmStep: transfer detected");
				if (targetSubAgentId) {
					await createMessage$1(runDbClient)({
						scopes: {
							tenantId,
							projectId
						},
						data: {
							id: generateId$1(),
							conversationId,
							role: "agent",
							content: {
								text: transferReason,
								parts: [{
									kind: "text",
									text: transferReason
								}]
							},
							visibility: "user-facing",
							messageType: "chat",
							fromSubAgentId: currentSubAgentId,
							taskId
						}
					});
					await executeTransfer({
						projectId,
						tenantId,
						threadId: conversationId,
						agentId,
						targetSubAgentId,
						ref: payload.resolvedRef
					});
					return {
						type: "transfer",
						targetSubAgentId
					};
				}
			}
			const textContent = response.steps?.[response.steps.length - 1]?.text || response.text || "";
			return await tracer.startActiveSpan(SPAN_NAMES.EXECUTION_HANDLER_EXECUTE, {}, async (span) => {
				try {
					span.setAttributes({
						"ai.response.content": textContent || "No response content",
						"ai.response.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
						"subAgent.name": agent.runContext.config.name,
						"subAgent.id": currentSubAgentId
					});
					await createMessage$1(runDbClient)({
						scopes: {
							tenantId,
							projectId
						},
						data: {
							id: generateId$1(),
							conversationId,
							role: "agent",
							content: {
								text: textContent,
								parts: response.formattedContent?.parts?.map((part) => ({
									kind: part.kind,
									text: part.kind === "text" ? part.text : void 0,
									data: part.kind === "data" ? part.data : void 0
								})) || [{
									kind: "text",
									text: textContent
								}]
							},
							visibility: "user-facing",
							messageType: "chat",
							fromSubAgentId: currentSubAgentId,
							taskId
						}
					});
					await updateTask$1(runDbClient)({
						taskId,
						scopes: {
							tenantId,
							projectId
						},
						data: {
							status: "completed",
							metadata: {
								completed_at: (/* @__PURE__ */ new Date()).toISOString(),
								response: {
									text: textContent,
									hasText: !!textContent
								}
							}
						}
					});
					if (emitOperations) await sseHelper.writeOperation(completionOp(currentSubAgentId, 1));
					await sseHelper.complete();
					triggerConversationEvaluation({
						tenantId,
						projectId,
						conversationId,
						resolvedRef: payload.resolvedRef
					}).catch((evalError) => {
						logger.error({
							error: evalError,
							conversationId,
							tenantId,
							projectId
						}, "Failed to trigger conversation evaluation (non-blocking)");
					});
					logger.info({
						currentSubAgentId,
						workflowRunId
					}, "callLlmStep: completion");
					isTerminal = true;
					return { type: "completion" };
				} finally {
					span.end();
				}
			});
		} catch (error) {
			const rootCause = error instanceof Error ? error : new Error(String(error));
			logger.error({
				error: rootCause.message,
				stack: rootCause.stack,
				currentSubAgentId,
				requestId
			}, "callLlmStep: error during execution");
			isTerminal = true;
			return await tracer.startActiveSpan(SPAN_NAMES.EXECUTION_HANDLER_EXECUTE, {}, async (span) => {
				try {
					span.setAttributes({
						"ai.response.content": "Hmm.. It seems I might be having some issues right now. Please clear the chat and try again.",
						"ai.response.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
						"subAgent.name": agent.runContext.config.name,
						"subAgent.id": currentSubAgentId
					});
					setSpanWithError$1(span, rootCause);
					try {
						await sseHelper.writeOperation(errorOp(`Execution error: ${rootCause.message}`, currentSubAgentId || "system"));
						await sseHelper.complete();
					} catch (streamErr) {
						logger.warn({
							error: streamErr,
							requestId
						}, "Failed to write error to SSE stream");
					}
					try {
						await updateTask$1(runDbClient)({
							taskId,
							scopes: {
								tenantId,
								projectId
							},
							data: {
								status: "failed",
								metadata: {
									failed_at: (/* @__PURE__ */ new Date()).toISOString(),
									error: rootCause.message
								}
							}
						});
					} catch (taskErr) {
						logger.warn({
							error: taskErr,
							taskId,
							requestId
						}, "Failed to update task status to failed");
					}
					throw error;
				} finally {
					span.end();
				}
			});
		} finally {
			await agentSessionManager.endSession(requestId);
			unregisterStreamHelper(requestId);
			await agent.cleanup();
			if (isTerminal) {
				await closeable.close();
				logger.debug({ requestId }, "callLlmStep: stream closed (terminal)");
			} else {
				closeable.releaseLock();
				logger.debug({ requestId }, "callLlmStep: stream lock released (non-terminal)");
			}
		}
	});
}
async function executeToolStep(params) {
	"use step";
	const { payload, currentSubAgentId, toolCallId, toolName, args, workflowRunId, streamNamespace, preApproved, approvalReason } = params;
	const { tenantId, projectId, agentId, conversationId, requestId, forwardedHeaders, emitOperations, outputFormat } = payload;
	logger.info({
		toolName,
		toolCallId,
		currentSubAgentId,
		workflowRunId,
		streamNamespace
	}, "executeToolStep starting");
	const { WritableBackedHonoSSEStream, WritableBackedVercelWriter } = await import("../../stream/durable-stream-helper.js");
	const { createSSEStreamHelper, createVercelStreamHelper } = await import("../../stream/stream-helpers.js");
	const { registerStreamHelper, unregisterStreamHelper } = await import("../../stream/stream-registry.js");
	const { agentSessionManager } = await import("../../session/AgentSession.js");
	const { loadToolsAndPrompts } = await import("../../agents/generation/tool-loading.js");
	const { errorOp } = await import("../../utils/agent-operations.js");
	const { agent, executionContext } = await buildAgentForStep({
		tenantId,
		projectId,
		agentId,
		currentSubAgentId,
		resolvedRef: payload.resolvedRef,
		forwardedHeaders
	});
	const timestamp = Math.floor(Date.now() / 1e3);
	const writable = getWritable(streamNamespace ? { namespace: streamNamespace } : {});
	let closeable;
	let sseHelper;
	if (outputFormat === "vercel") {
		const vercelWriter = new WritableBackedVercelWriter(writable);
		closeable = vercelWriter;
		sseHelper = createVercelStreamHelper(vercelWriter);
		logger.debug({
			requestId,
			toolName
		}, "executeToolStep: using Vercel stream writer");
	} else {
		const writableStream = new WritableBackedHonoSSEStream(writable);
		closeable = writableStream;
		sseHelper = createSSEStreamHelper(writableStream, requestId, timestamp);
		logger.debug({
			requestId,
			toolName
		}, "executeToolStep: using SSE stream writer");
	}
	registerStreamHelper(requestId, sseHelper);
	agentSessionManager.createSession(requestId, executionContext, conversationId);
	if (emitOperations) agentSessionManager.enableEmitOperations(requestId);
	const bag = (propagation.getBaggage(context.active()) ?? propagation.createBaggage()).setEntry("conversation.id", { value: conversationId }).setEntry("tenant.id", { value: tenantId }).setEntry("project.id", { value: projectId }).setEntry("agent.id", { value: agentId });
	const ctxWithBaggage = propagation.setBaggage(context.active(), bag);
	return context.with(ctxWithBaggage, async () => {
		try {
			agent.streamRequestId = requestId;
			agent.runContext.streamHelper = sseHelper;
			agent.setConversationId(conversationId);
			agent.setDurableWorkflowRunId(workflowRunId);
			if (preApproved !== void 0) agent.setApprovedToolCalls({ [toolName]: [{
				approved: preApproved,
				reason: approvalReason,
				originalToolCallId: toolCallId
			}] });
			const sessionId = requestId;
			const runtimeContext = {
				contextId: conversationId,
				metadata: {
					conversationId,
					threadId: conversationId,
					taskId: params.taskId,
					streamRequestId: requestId,
					apiKey: executionContext.apiKey
				}
			};
			logger.debug({
				toolName,
				toolCallId,
				sessionId
			}, "executeToolStep: loading tools and executing");
			const { sanitizedTools } = await loadToolsAndPrompts(agent.runContext, sessionId, requestId, runtimeContext);
			const toolDef = sanitizedTools[toolName];
			if (!toolDef) throw new Error(`Tool '${toolName}' not found in agent tool set`);
			return await tracer.startActiveSpan(SPAN_NAMES.DURABLE_TOOL_EXECUTION, {}, async (span) => {
				try {
					span.setAttributes({
						"subAgent.id": currentSubAgentId,
						"tool.name": toolName,
						"tool.callId": toolCallId,
						"tool.response.timestamp": (/* @__PURE__ */ new Date()).toISOString()
					});
					await toolDef.execute?.(args, { toolCallId });
					if (agent.runContext.pendingDurableApproval) {
						logger.info({
							toolName,
							toolCallId,
							workflowRunId
						}, "executeToolStep: tool requires approval");
						return { type: "needs_approval" };
					}
					logger.info({
						toolName,
						toolCallId
					}, "executeToolStep: tool executed successfully");
					return { type: "completed" };
				} finally {
					span.end();
				}
			});
		} catch (error) {
			const rootCause = error instanceof Error ? error : new Error(String(error));
			logger.error({
				error: rootCause.message,
				stack: rootCause.stack,
				toolName,
				toolCallId,
				requestId
			}, "executeToolStep: error during tool execution");
			return await tracer.startActiveSpan(SPAN_NAMES.DURABLE_TOOL_EXECUTION, {}, async (span) => {
				try {
					span.setAttributes({
						"tool.response.content": `Tool execution error: ${rootCause.message}`,
						"tool.response.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
						"subAgent.id": currentSubAgentId,
						"tool.name": toolName,
						"tool.callId": toolCallId
					});
					setSpanWithError$1(span, rootCause);
					try {
						await sseHelper.writeOperation(errorOp(`Tool execution error: ${rootCause.message}`, currentSubAgentId || "system"));
					} catch (streamErr) {
						logger.warn({
							error: streamErr,
							requestId
						}, "Failed to write error to SSE stream");
					}
					const { updateTask: updateTask$1 } = await import("@inkeep/agents-core");
					const { default: runDbClient } = await import("../../../../data/db/runDbClient.js");
					try {
						await updateTask$1(runDbClient)({
							taskId: params.taskId,
							scopes: {
								tenantId,
								projectId
							},
							data: {
								status: "failed",
								metadata: {
									failed_at: (/* @__PURE__ */ new Date()).toISOString(),
									error: rootCause.message
								}
							}
						});
					} catch (taskErr) {
						logger.warn({
							error: taskErr,
							taskId: params.taskId,
							requestId
						}, "Failed to update task status to failed");
					}
					throw error;
				} finally {
					span.end();
				}
			});
		} finally {
			await agentSessionManager.endSession(requestId);
			unregisterStreamHelper(requestId);
			await agent.cleanup();
			closeable.releaseLock();
			logger.debug({
				requestId,
				toolName
			}, "executeToolStep: stream lock released");
		}
	});
}
async function markWorkflowSuspendedStep(params) {
	"use step";
	const { tenantId, projectId, workflowRunId, continuationStreamNamespace } = params;
	const { updateWorkflowExecutionStatus } = await import("@inkeep/agents-core");
	const { default: runDbClient } = await import("../../../../data/db/runDbClient.js");
	await updateWorkflowExecutionStatus(runDbClient)({
		tenantId,
		projectId,
		id: workflowRunId,
		status: "suspended",
		metadata: { continuationStreamNamespace }
	});
	logger.info({ workflowRunId }, "Workflow execution marked as suspended (awaiting tool approval)");
}
async function markWorkflowResumingStep(params) {
	"use step";
	const { tenantId, projectId, workflowRunId } = params;
	const { updateWorkflowExecutionStatus } = await import("@inkeep/agents-core");
	const { default: runDbClient } = await import("../../../../data/db/runDbClient.js");
	await updateWorkflowExecutionStatus(runDbClient)({
		tenantId,
		projectId,
		id: workflowRunId,
		status: "running"
	});
	logger.info({ workflowRunId }, "Workflow execution marked as running (resuming after approval)");
}
async function markWorkflowCompleteStep(params) {
	"use step";
	const { tenantId, projectId, workflowRunId } = params;
	const { updateWorkflowExecutionStatus } = await import("@inkeep/agents-core");
	const { default: runDbClient } = await import("../../../../data/db/runDbClient.js");
	await updateWorkflowExecutionStatus(runDbClient)({
		tenantId,
		projectId,
		id: workflowRunId,
		status: "completed"
	});
	logger.info({ workflowRunId }, "Workflow execution marked as completed");
}
async function markWorkflowFailedStep(params) {
	"use step";
	const { tenantId, projectId, workflowRunId, error } = params;
	const { updateWorkflowExecutionStatus } = await import("@inkeep/agents-core");
	const { default: runDbClient } = await import("../../../../data/db/runDbClient.js");
	await updateWorkflowExecutionStatus(runDbClient)({
		tenantId,
		projectId,
		id: workflowRunId,
		status: "failed",
		metadata: { error }
	});
	logger.info({
		workflowRunId,
		error
	}, "Workflow execution marked as failed");
}

//#endregion
export { callLlmStep, executeToolStep, initializeTaskStep, markWorkflowCompleteStep, markWorkflowFailedStep, markWorkflowResumingStep, markWorkflowRunningStep, markWorkflowSuspendedStep };