UNPKG

@openai/agents-core

Version:

The OpenAI Agents SDK is a lightweight yet powerful framework for building multi-agent workflows.

1,153 lines • 54.1 kB
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.nextStepSchema = void 0;
exports.preflightModelResponseToolInvocations = preflightModelResponseToolInvocations;
exports.preflightToolInvocations = preflightToolInvocations;
exports.filterSuppressedToolCallItems = filterSuppressedToolCallItems;
exports.resolveInterruptedTurn = resolveInterruptedTurn;
exports.resolveTurnAfterModelResponse = resolveTurnAfterModelResponse;
const zod_1 = require("zod");
const agentToolSourceRegistry_1 = require("../agentToolSourceRegistry.js");
const errors_1 = require("../errors.js");
const items_1 = require("../items.js");
const logger_1 = __importStar(require("../logger.js"));
const messages_1 = require("../utils/messages.js");
const safeExecute_1 = require("../utils/safeExecute.js");
const finalOutputError_1 = require("../utils/finalOutputError.js");
const standardSchema_1 = require("../utils/standardSchema.js");
const context_1 = require("../tracing/context.js");
const steps_1 = require("./steps.js");
Object.defineProperty(exports, "nextStepSchema", { enumerable: true, get: function () { return steps_1.nextStepSchema; } });
const toolExecution_1 = require("./toolExecution.js");
const invocationContext_1 = require("./invocationContext.js");
const mcpApprovals_1 = require("./mcpApprovals.js");
const toolIdentity_1 = require("../toolIdentity.js");
const errorHandlers_1 = require("./errorHandlers.js");
const items_2 = require("./items.js");
const streamReconciliation_1 = require("./streamReconciliation.js");
const siblingCancellation_1 = require("./siblingCancellation.js");
const toolInvocation_1 = require("../toolInvocation.js");
const DEFAULT_TOOL_NOT_FOUND_MESSAGE = (toolName) => `Tool '${toolName}' not found.`;
function preflightModelResponseToolInvocations(agent, state, modelResponse, tools, handoffs, runner, signal) {
    const functionMap = (0, toolIdentity_1.buildFunctionToolLookupMap)(tools.filter((tool) => tool.type === 'function'));
    const handoffMap = new Map(handoffs.map((handoff) => [handoff.toolName, handoff]));
    const computer = tools.find((tool) => tool.type === 'computer');
    const shell = tools.find((tool) => tool.type === 'shell');
    const applyPatch = tools.find((tool) => tool.type === 'apply_patch');
    const seen = new Map();
    let selectedHandoff;
    const validate = (toolName, rawItem) => {
        if (!toolName) {
            return false;
        }
        const { callId, fingerprint } = state._context._validateToolInvocation(agent, toolName, rawItem);
        const completed = state._preflightToolInvocation(agent, callId, fingerprint);
        const previous = seen.get(callId);
        if (previous !== undefined && previous !== fingerprint) {
            throw new errors_1.ModelBehaviorError(`Tool call ID ${callId} was reused for different tool invocations in the same model response.`, state);
        }
        seen.set(callId, fingerprint);
        return !completed && previous !== fingerprint;
    };
    for (const output of modelResponse.output) {
        if (output.type === 'function_call') {
            const handoff = !(0, toolIdentity_1.getToolCallNamespace)(output)
                ? handoffMap.get(output.name)
                : undefined;
            if (handoff) {
                const shouldRun = validate((0, toolInvocation_1.getHandoffToolInvocationName)(handoff.toolName), output);
                if (shouldRun && !selectedHandoff) {
                    selectedHandoff = handoff;
                }
                continue;
            }
            const resolvedTool = (0, toolIdentity_1.resolveFunctionToolCall)(output, functionMap);
            validate(resolvedTool
                ? (0, toolIdentity_1.getFunctionToolStateKeyForResolvedCall)(output, resolvedTool)
                : (0, toolIdentity_1.getFunctionToolStateKeyForCall)(output, output.name), output);
            continue;
        }
        if (output.type === 'computer_call') {
            validate(computer?.name ?? 'computer', output);
            continue;
        }
        if (output.type === 'shell_call') {
            validate(shell?.name ?? 'shell', output);
            continue;
        }
        if (output.type === 'apply_patch_call') {
            validate(applyPatch?.name ?? 'apply_patch', output);
            continue;
        }
        if (output.type === 'hosted_tool_call' &&
            (output.providerData?.type === 'mcp_approval_request' ||
                output.name === 'mcp_approval_request')) {
            const providerData = output.providerData;
            validate(typeof providerData?.name === 'string'
                ? providerData.name
                : output.name, output);
        }
    }
    if (selectedHandoff && !signal?.aborted) {
        validateHandoffInputFilter(selectedHandoff, runner, state);
    }
}
function preflightToolInvocations(agent, state, processedResponse) {
    const suppressed = new Set();
    const seen = new Map();
    const observe = (toolName, rawItem) => {
        if (!toolName) {
            return undefined;
        }
        const { callId, fingerprint } = state._context._validateToolInvocation(agent, toolName, rawItem);
        const completed = state._observeToolInvocation(agent, callId, fingerprint);
        const previous = seen.get(callId);
        const shouldSuppress = completed || previous === fingerprint;
        if (shouldSuppress) {
            suppressed.add(rawItem);
        }
        seen.set(callId, fingerprint);
        return { callId, fingerprint, shouldSuppress };
    };
    for (const run of processedResponse.functions ?? []) {
        const toolName = (0, toolIdentity_1.getFunctionToolStateKey)(run.tool) ??
            (0, toolIdentity_1.getFunctionToolStateKeyForCall)(run.toolCall, run.tool.name);
        const observation = observe(toolName, run.toolCall);
        if (observation &&
            !observation.shouldSuppress &&
            !(0, toolIdentity_1.matchesFunctionToolRecipient)(run.mcpToolBinding ?? null, run.tool) &&
            state._context.isToolApproved({
                toolName: toolName,
                callId: observation.callId,
                agent,
                functionTool: false,
            }) !== false) {
            throw new errors_1.UserError('Cannot resume a function tool call with a missing or different MCP recipient binding. Restore the original MCP configuration and tool listing, or start a new run.', state);
        }
    }
    for (const run of processedResponse.functionToolsNotFound ?? []) {
        observe((0, toolIdentity_1.getFunctionToolStateKeyForCall)(run.toolCall, run.toolName), run.toolCall);
    }
    for (const run of processedResponse.computerActions ?? []) {
        observe(run.computer.name, run.toolCall);
    }
    for (const run of processedResponse.shellActions ?? []) {
        observe(run.shell.name, run.toolCall);
    }
    for (const run of processedResponse.applyPatchActions ?? []) {
        observe(run.applyPatch.name, run.toolCall);
    }
    const claimedHostedMcpItems = new Set();
    for (const run of processedResponse.mcpApprovalRequests ?? []) {
        const toolName = run.requestItem.name;
        const observation = observe(toolName, run.requestItem.rawItem);
        if (!toolName || !observation) {
            continue;
        }
        const sourceRawItems = [];
        for (const item of processedResponse.newItems) {
            if (!(item instanceof items_1.RunToolCallItem) ||
                item.rawItem.type !== 'hosted_tool_call') {
                continue;
            }
            const rawItem = item.rawItem;
            if (claimedHostedMcpItems.has(rawItem)) {
                continue;
            }
            const providerData = rawItem.providerData;
            const isApprovalRequest = providerData?.type === 'mcp_approval_request' ||
                rawItem.name === 'mcp_approval_request';
            const sourceReferenceId = typeof providerData?.id === 'string'
                ? providerData.id
                : (0, toolInvocation_1.getToolInvocationCallId)(rawItem);
            if (isApprovalRequest && sourceReferenceId === observation.callId) {
                sourceRawItems.push(rawItem);
            }
        }
        if (sourceRawItems.length !== 1) {
            throw new errors_1.ModelBehaviorError(`Hosted MCP approval request ${observation.callId} does not have exactly one source tool invocation.`);
        }
        const sourceRawItem = sourceRawItems[0];
        claimedHostedMcpItems.add(sourceRawItem);
        if ((0, toolInvocation_1.getToolInvocationFingerprint)(toolName, sourceRawItem) !==
            observation.fingerprint) {
            throw new errors_1.ModelBehaviorError(`Hosted MCP approval request ${observation.callId} does not match its source tool invocation.`);
        }
        if (observation.shouldSuppress) {
            suppressed.add(sourceRawItem);
        }
    }
    for (const run of processedResponse.handoffs ?? []) {
        observe((0, toolInvocation_1.getHandoffToolInvocationName)(run.handoff.toolName), run.toolCall);
    }
    return suppressed;
}
function validateAgentToolSources(functionRuns, validateAgent) {
    if (!validateAgent) {
        return;
    }
    for (const run of functionRuns) {
        const sourceAgent = (0, agentToolSourceRegistry_1.getAgentToolSourceAgent)(run.tool);
        if (sourceAgent) {
            validateAgent(sourceAgent);
        }
    }
}
function isSuppressedToolCallItem(item, suppressed) {
    if (!(item instanceof items_1.RunToolCallItem) &&
        !(item instanceof items_1.RunHandoffCallItem) &&
        !(item instanceof items_1.RunToolApprovalItem)) {
        return false;
    }
    const rawItem = item.rawItem;
    if (rawItem.type !== 'function_call' &&
        rawItem.type !== 'computer_call' &&
        rawItem.type !== 'shell_call' &&
        rawItem.type !== 'apply_patch_call' &&
        rawItem.type !== 'hosted_tool_call') {
        return false;
    }
    return suppressed.has(rawItem);
}
function filterSuppressedToolCallItems(items, suppressed) {
    return items.filter((item) => !isSuppressedToolCallItem(item, suppressed));
}
async function resolveToolNotFoundMessage(state, toolRun, toolErrorFormatter) {
    const defaultMessage = toolRun.reason === 'not_loaded'
        ? `Error: Tool ${toolRun.toolName} is not loaded for the current agent. The requested function was not executed. Call tool_search to load it, then retry the original function call with the same arguments.`
        : DEFAULT_TOOL_NOT_FOUND_MESSAGE(toolRun.toolName);
    if (!toolErrorFormatter) {
        return defaultMessage;
    }
    try {
        const formattedMessage = await toolErrorFormatter({
            kind: 'tool_not_found',
            toolType: 'function',
            toolName: toolRun.toolName,
            callId: toolRun.toolCall.callId,
            defaultMessage,
            runContext: state._context,
        });
        if (typeof formattedMessage === 'string') {
            return formattedMessage;
        }
        if (typeof formattedMessage !== 'undefined') {
            logger_1.default.warn('toolErrorFormatter returned a non-string value. Falling back to the default tool not found message.');
        }
    }
    catch (error) {
        (0, logger_1.logToolActionWarning)(logger_1.default, 'toolErrorFormatter threw while formatting tool not found:', error);
    }
    return defaultMessage;
}
async function buildToolNotFoundOutputItems(agent, state, toolRuns, toolErrorFormatter) {
    const items = [];
    for (const toolRun of toolRuns) {
        const message = await resolveToolNotFoundMessage(state, toolRun, toolErrorFormatter);
        items.push(new items_1.RunToolCallOutputItem((0, toolExecution_1.getToolCallOutputItem)(toolRun.toolCall, message), agent, message));
    }
    return items;
}
const APPROVAL_ITEM_TYPES = [
    'function_call',
    'computer_call',
    'hosted_tool_call',
    'shell_call',
    'apply_patch_call',
];
function isHostedMcpApprovalItem(item) {
    return (0, toolIdentity_1.getHostedMcpApprovalRequestIdentity)(item) !== undefined;
}
function resolveApprovalState(item, state, processedResponse) {
    if (isHostedMcpApprovalItem(item)) {
        return 'pending';
    }
    const rawItem = item.rawItem;
    const toolName = item.toolName ??
        ('name' in rawItem && typeof rawItem.name === 'string'
            ? rawItem.name
            : undefined);
    const callId = 'callId' in rawItem && typeof rawItem.callId === 'string'
        ? rawItem.callId
        : 'id' in rawItem && typeof rawItem.id === 'string'
            ? rawItem.id
            : undefined;
    if (!toolName || !callId) {
        return 'pending';
    }
    let toolNames = [toolName];
    if (rawItem.type === 'function_call') {
        const functionRun = item.agent === state._currentAgent
            ? processedResponse.functions.find((run) => run.toolCall.callId === callId)
            : undefined;
        if (functionRun) {
            const stateKey = (0, toolIdentity_1.getFunctionToolStateKey)(functionRun.tool);
            toolNames = stateKey ? [stateKey] : toolNames;
        }
        else {
            const stateKey = item.functionToolStateKey ??
                (0, toolIdentity_1.getFunctionToolStateKeyForCall)(rawItem, toolName);
            toolNames = stateKey ? [stateKey] : toolNames;
        }
    }
    const approval = toolNames
        .map((candidate) => state._context._resolveToolInvocationApproval(item.agent, candidate, rawItem))
        .find((decision) => typeof decision !== 'undefined');
    if (approval === true) {
        return 'approved';
    }
    if (approval === false) {
        return 'rejected';
    }
    return 'pending';
}
function isApprovalItemLike(value) {
    if (!value || typeof value !== 'object') {
        return false;
    }
    if (!('rawItem' in value)) {
        return false;
    }
    const rawItem = value.rawItem;
    if (!rawItem || typeof rawItem !== 'object') {
        return false;
    }
    const itemType = rawItem.type;
    return APPROVAL_ITEM_TYPES.includes(itemType);
}
function getApprovalIdentity(approval) {
    const rawItem = approval.rawItem;
    if (!rawItem) {
        return undefined;
    }
    const agent = 'agent' in approval ? approval.agent : undefined;
    if (rawItem.type === 'function_call' && rawItem.callId) {
        return { agent, value: `function_call:${rawItem.callId}` };
    }
    if ('callId' in rawItem && rawItem.callId) {
        return { agent, value: `${rawItem.type}:${rawItem.callId}` };
    }
    const id = 'id' in rawItem ? rawItem.id : undefined;
    if (id) {
        return { agent, value: `${rawItem.type}:${id}` };
    }
    const providerData = typeof rawItem.providerData === 'object' && rawItem.providerData
        ? rawItem.providerData
        : undefined;
    if (providerData?.id) {
        return { agent, value: `${rawItem.type}:provider:${providerData.id}` };
    }
    const agentName = 'agent' in approval && approval.agent ? approval.agent.name : '';
    try {
        return {
            agent,
            value: `${agentName}:${rawItem.type}:${JSON.stringify(rawItem)}`,
        };
    }
    catch {
        return { agent, value: `${agentName}:${rawItem.type}` };
    }
}
function hasApprovalIdentity(identities, identity) {
    return identities.get(identity.agent)?.has(identity.value) ?? false;
}
function addApprovalIdentity(identities, identity) {
    const values = identities.get(identity.agent) ?? new Set();
    values.add(identity.value);
    identities.set(identity.agent, values);
}
function buildAppendContext(existingItems) {
    const seenItems = new Set(existingItems);
    const seenApprovalIdentities = new Map();
    for (const item of existingItems) {
        if (item instanceof items_1.RunToolApprovalItem) {
            const identity = getApprovalIdentity(item);
            if (identity) {
                addApprovalIdentity(seenApprovalIdentities, identity);
            }
        }
    }
    return { seenItems, seenApprovalIdentities };
}
function appendRunItemIfNew(item, target, context) {
    if (context.seenItems.has(item)) {
        return;
    }
    if (item instanceof items_1.RunToolApprovalItem) {
        const identity = getApprovalIdentity(item);
        if (identity) {
            if (hasApprovalIdentity(context.seenApprovalIdentities, identity)) {
                return;
            }
            addApprovalIdentity(context.seenApprovalIdentities, identity);
        }
    }
    context.seenItems.add(item);
    target.push(item);
}
function buildApprovedCallIdSet(items, type) {
    const callIds = new Set();
    for (const item of items) {
        if (!(item instanceof items_1.RunToolApprovalItem)) {
            continue;
        }
        const rawItem = item.rawItem;
        if (!rawItem || rawItem.type !== type) {
            continue;
        }
        const callKey = getToolActionKey(rawItem);
        if (callKey) {
            callIds.add(callKey);
        }
    }
    return callIds;
}
function collectCompletedCallIds(items, type, agent) {
    const completed = new Set();
    for (const item of items) {
        const rawItem = item.rawItem;
        if (!rawItem || typeof rawItem !== 'object') {
            continue;
        }
        if (rawItem.type !== type) {
            continue;
        }
        if (agent && (!('agent' in item) || item.agent !== agent)) {
            continue;
        }
        const callId = rawItem.callId;
        if (typeof callId === 'string') {
            completed.add(callId);
        }
    }
    return completed;
}
function filterActionsByApproval(preStepItems, actions, type) {
    const allowedCallIds = buildApprovedCallIdSet(preStepItems, type);
    if (allowedCallIds.size === 0) {
        return [];
    }
    return actions.filter((action) => {
        const callKey = getToolActionKey(action.toolCall);
        return typeof callKey === 'string' && allowedCallIds.has(callKey);
    });
}
function filterPendingActions(actions, options) {
    return actions.filter((action) => {
        const callId = action.toolCall.callId;
        const hasCallId = typeof callId === 'string';
        if (options.allowedCallIds && options.allowedCallIds.size > 0) {
            if (!hasCallId || !options.allowedCallIds.has(callId)) {
                return false;
            }
        }
        if (hasCallId && options.completedCallIds.has(callId)) {
            return false;
        }
        return true;
    });
}
function queueActionsByCallId(actions) {
    const queued = {
        byCallId: new Map(),
        withoutCallId: [],
    };
    for (const action of actions) {
        const callKey = getToolActionKey(action.toolCall);
        if (!callKey) {
            queued.withoutCallId.push(action);
            continue;
        }
        const actionsForCallId = queued.byCallId.get(callKey) ?? [];
        actionsForCallId.push(action);
        queued.byCallId.set(callKey, actionsForCallId);
    }
    return queued;
}
function takeQueuedAction(actionsByCallId, callId) {
    const queued = actionsByCallId.get(callId);
    const action = queued?.shift();
    if (!queued || queued.length === 0) {
        actionsByCallId.delete(callId);
    }
    return action;
}
function appendRemainingQueuedActions(target, actionsByCallId) {
    for (const queued of actionsByCallId.values()) {
        target.push(...queued);
    }
}
function orderShellAndApplyPatchActions(sourceItems, shellActions, applyPatchActions) {
    const shellActionsByCallId = queueActionsByCallId(shellActions);
    const applyPatchActionsByCallId = queueActionsByCallId(applyPatchActions);
    const orderedActions = [];
    for (const item of sourceItems) {
        const rawItem = item.rawItem;
        if (rawItem?.type === 'shell_call') {
            const callKey = getToolActionKey(rawItem);
            const action = takeQueuedAction(shellActionsByCallId.byCallId, callKey ?? '');
            if (action) {
                orderedActions.push({ type: 'shell', action });
            }
            continue;
        }
        if (rawItem?.type === 'apply_patch_call') {
            const callKey = getToolActionKey(rawItem);
            const action = takeQueuedAction(applyPatchActionsByCallId.byCallId, callKey ?? '');
            if (action) {
                orderedActions.push({ type: 'apply_patch', action });
            }
        }
    }
    const remainingShellActions = [];
    appendRemainingQueuedActions(remainingShellActions, shellActionsByCallId.byCallId);
    remainingShellActions.push(...shellActionsByCallId.withoutCallId);
    for (const action of remainingShellActions) {
        orderedActions.push({ type: 'shell', action });
    }
    const remainingApplyPatchActions = [];
    appendRemainingQueuedActions(remainingApplyPatchActions, applyPatchActionsByCallId.byCallId);
    remainingApplyPatchActions.push(...applyPatchActionsByCallId.withoutCallId);
    for (const action of remainingApplyPatchActions) {
        orderedActions.push({ type: 'apply_patch', action });
    }
    return orderedActions;
}
function getToolActionKey(value) {
    if (typeof value.callId === 'string' && value.callId.length > 0) {
        return value.callId;
    }
    if (typeof value.id === 'string' && value.id.length > 0) {
        return value.id;
    }
    return undefined;
}
async function executeShellAndApplyPatchActionsInOrder(args) {
    const results = [];
    for (const action of orderShellAndApplyPatchActions(args.sourceItems, args.shellActions, args.applyPatchActions)) {
        if (args.signal?.aborted) {
            const rawItem = action.type === 'shell'
                ? (0, streamReconciliation_1.buildShellAbortResult)(action.action.toolCall)
                : (0, streamReconciliation_1.buildApplyPatchAbortResult)(action.action.toolCall);
            results.push(new items_1.RunToolCallOutputItem(rawItem, args.agent, 'aborted'));
            continue;
        }
        const items = action.type === 'shell'
            ? await (0, toolExecution_1.executeShellActions)(args.agent, [action.action], args.runner, args.state._context, undefined, args.toolErrorFormatter)
            : await (0, toolExecution_1.executeApplyPatchOperations)(args.agent, [action.action], args.runner, args.state._context, undefined, args.toolErrorFormatter);
        results.push(...items);
    }
    return results;
}
function truncateForDeveloper(message, maxLength = 160) {
    const trimmed = message.trim();
    if (!trimmed) {
        return 'Schema validation failed.';
    }
    if (trimmed.length <= maxLength) {
        return trimmed;
    }
    return `${trimmed.slice(0, maxLength - 3)}...`;
}
function formatFinalOutputTypeError(error) {
    // Surface structured output validation hints without echoing potentially large or sensitive payloads.
    try {
        if (error instanceof zod_1.z.ZodError) {
            const issue = error.issues[0];
            if (issue) {
                const issuePathParts = Array.isArray(issue.path) ? issue.path : [];
                const issuePath = issuePathParts.length > 0
                    ? issuePathParts.map((part) => String(part)).join('.')
                    : '(root)';
                const message = truncateForDeveloper(issue.message ?? '');
                return `Invalid output type: final assistant output failed schema validation at "${issuePath}" (${message}).`;
            }
            return 'Invalid output type: final assistant output failed schema validation.';
        }
        if (error instanceof Error && error.message) {
            return `Invalid output type: ${truncateForDeveloper(error.message)}`;
        }
    }
    catch {
        // Swallow formatting errors so we can return a generic message below.
    }
    return 'Invalid output type: final assistant output did not match the expected schema.';
}
function buildTurnRunErrorData(state, agent, originalInput, preStepItems, newItems) {
    const generatedItems = preStepItems.concat(newItems);
    return {
        input: originalInput,
        newItems: generatedItems,
        history: (0, items_2.getTurnInput)(originalInput, generatedItems, state._reasoningItemIdPolicy),
        output: (0, items_2.getRunOutput)(generatedItems, state._reasoningItemIdPolicy),
        rawResponses: state._modelResponses,
        lastAgent: agent,
        state,
    };
}
async function resolveInvalidFinalOutput(args) {
    return (0, errorHandlers_1.preserveInvalidFinalOutputRedaction)(async (redactFromStart) => {
        const handlerResult = await (0, errorHandlers_1.resolveRunErrorHandler)({
            error: args.error,
            errorKind: 'invalidFinalOutput',
            errorHandlers: args.errorHandlers,
            context: args.state._context,
            runData: buildTurnRunErrorData(args.state, args.agent, args.originalInput, args.preStepItems, args.newItems),
            attemptedErrors: args.attemptedErrors,
        });
        if (!handlerResult) {
            (0, errorHandlers_1.invalidateAcceptedResponseReplayEvidence)(args.state);
            return undefined;
        }
        const outputText = (0, errorHandlers_1.formatRunErrorFinalOutput)(args.agent, handlerResult.finalOutput);
        (0, errorHandlers_1.validateRunErrorHandlerFinalOutput)(args.agent, outputText, true, redactFromStart);
        if (handlerResult.includeInHistory !== false) {
            args.newItems.push((0, errorHandlers_1.createRunErrorFinalOutputItem)(args.agent, outputText));
        }
        return outputText;
    }, (0, finalOutputError_1.isDataRedactedError)(args.error));
}
/**
 * @internal
 * Continues a turn that was previously interrupted waiting for tool approval. Executes the now
 * approved tools and returns the resulting step transition.
 */
async function resolveInterruptedTurn(agent, originalInput, originalPreStepItems, newResponse, processedResponse, runner, state, toolErrorFormatter, agentToolParentRunConfig, signal, validateHandoffAgent, beforeHandoffInputFilter) {
    const suppressedToolCalls = preflightToolInvocations(agent, state, processedResponse);
    const handoffRuns = processedResponse.handoffs.filter((run) => !suppressedToolCalls.has(run.toolCall));
    if (handoffRuns.length > 0) {
        if (!signal?.aborted) {
            validateHandoffInputFilter(handoffRuns[0].handoff, runner, state);
        }
        validateHandoffAgent?.(handoffRuns[0].handoff.agent);
    }
    // call_ids for function tools
    const functionCallIds = originalPreStepItems
        .filter((item) => item instanceof items_1.RunToolApprovalItem &&
        item.agent === agent &&
        'callId' in item.rawItem &&
        item.rawItem.type === 'function_call')
        .map((item) => item.rawItem.callId);
    const completedFunctionCallIds = collectCompletedCallIds(originalPreStepItems, 'function_call_result', agent);
    const completedComputerCallIds = collectCompletedCallIds(originalPreStepItems, 'computer_call_result');
    const completedShellCallIds = collectCompletedCallIds(originalPreStepItems, 'shell_call_output');
    const completedApplyPatchCallIds = collectCompletedCallIds(originalPreStepItems, 'apply_patch_call_output');
    // We already persisted the turn once when the approval interrupt was raised, so the
    // counter reflects the approval items as "flushed". When we resume the same turn we need
    // to rewind it so the eventual tool output for this call is still written to the session.
    const pendingApprovalItems = state
        .getInterruptions()
        .filter(isApprovalItemLike);
    const pendingApprovalIdentities = new Map();
    for (const approval of pendingApprovalItems) {
        if (!(approval instanceof items_1.RunToolApprovalItem)) {
            continue;
        }
        if (isHostedMcpApprovalItem(approval)) {
            continue;
        }
        const rawItem = approval.rawItem;
        if (rawItem.type === 'function_call' &&
            approval.agent === agent &&
            rawItem.callId &&
            completedFunctionCallIds.has(rawItem.callId)) {
            continue;
        }
        if (rawItem.type === 'computer_call' &&
            rawItem.callId &&
            completedComputerCallIds.has(rawItem.callId)) {
            continue;
        }
        if (rawItem.type === 'shell_call' &&
            rawItem.callId &&
            completedShellCallIds.has(rawItem.callId)) {
            continue;
        }
        if (rawItem.type === 'apply_patch_call' &&
            rawItem.callId &&
            completedApplyPatchCallIds.has(rawItem.callId)) {
            continue;
        }
        const identity = getApprovalIdentity(approval);
        if (identity) {
            if (resolveApprovalState(approval, state, processedResponse) === 'pending') {
                addApprovalIdentity(pendingApprovalIdentities, identity);
            }
        }
    }
    // Run function tools that require approval or are resuming a nested agent tool run.
    const functionToolRuns = processedResponse.functions.filter((run) => {
        if (suppressedToolCalls.has(run.toolCall)) {
            return false;
        }
        const callId = run.toolCall.callId;
        if (!callId) {
            return false;
        }
        const isApprovedCall = functionCallIds.includes(callId);
        const isPendingNested = (0, toolIdentity_1.getFunctionToolStateKeys)(run.tool, run.availableFunctionTools ?? [run.tool]).some((stateKey) => state.hasPendingAgentToolRun(stateKey, callId));
        if (!isApprovedCall && !isPendingNested) {
            return false;
        }
        return !completedFunctionCallIds.has(callId);
    });
    validateAgentToolSources(functionToolRuns, validateHandoffAgent);
    const shellRuns = filterPendingActions(filterActionsByApproval(originalPreStepItems, (processedResponse.shellActions ?? []).filter((run) => !suppressedToolCalls.has(run.toolCall)), 'shell_call'), {
        completedCallIds: completedShellCallIds,
    });
    const pendingComputerActions = filterPendingActions(filterActionsByApproval(originalPreStepItems, (processedResponse.computerActions ?? []).filter((run) => !suppressedToolCalls.has(run.toolCall)), 'computer_call'), {
        completedCallIds: completedComputerCallIds,
    });
    const applyPatchRuns = filterPendingActions(filterActionsByApproval(originalPreStepItems, (processedResponse.applyPatchActions ?? []).filter((run) => !suppressedToolCalls.has(run.toolCall)), 'apply_patch_call'), {
        completedCallIds: completedApplyPatchCallIds,
    });
    const functionResults = await (0, toolExecution_1.executeFunctionToolCalls)(agent, functionToolRuns, runner, state, toolErrorFormatter, agentToolParentRunConfig, signal);
    // Computer actions may require approval; only pending approved actions are executed on resume.
    const computerResults = pendingComputerActions.length > 0
        ? await (0, toolExecution_1.executeComputerActions)(agent, pendingComputerActions, runner, state._context, undefined, toolErrorFormatter, signal)
        : [];
    const shellAndApplyPatchResults = shellRuns.length > 0 || applyPatchRuns.length > 0
        ? await executeShellAndApplyPatchActionsInOrder({
            agent,
            sourceItems: originalPreStepItems,
            shellActions: shellRuns,
            applyPatchActions: applyPatchRuns,
            runner,
            state,
            toolErrorFormatter,
            signal,
        })
        : [];
    const pendingFunctionToolsNotFound = filterPendingActions((processedResponse.functionToolsNotFound ?? []).filter((run) => !suppressedToolCalls.has(run.toolCall)), {
        completedCallIds: completedFunctionCallIds,
    });
    const toolNotFoundResults = await buildToolNotFoundOutputItems(agent, state, pendingFunctionToolsNotFound, toolErrorFormatter);
    const newItems = [];
    const appendContext = buildAppendContext(originalPreStepItems);
    const appendIfNew = (item) => appendRunItemIfNew(item, newItems, appendContext);
    for (const result of functionResults) {
        if (result.type === 'function_output' &&
            Array.isArray(result.interruptions) &&
            result.interruptions.length > 0) {
            continue;
        }
        appendIfNew(result.runItem);
    }
    for (const result of toolNotFoundResults) {
        appendIfNew(result);
    }
    for (const result of computerResults) {
        appendIfNew(result);
    }
    for (const result of shellAndApplyPatchResults) {
        appendIfNew(result);
    }
    const additionalInterruptions = (0, toolExecution_1.collectInterruptions)([], [...computerResults, ...shellAndApplyPatchResults]);
    const hostedMcpApprovals = await (0, mcpApprovals_1.handleHostedMcpApprovals)({
        requests: (processedResponse.mcpApprovalRequests ?? []).filter((run) => !suppressedToolCalls.has(run.requestItem.rawItem)),
        agent,
        state,
        functionResults,
        appendIfNew,
        resolveApproval: (rawItem) => {
            if (!(0, toolIdentity_1.getHostedMcpApprovalRequestIdentity)(rawItem)?.requestId) {
                return undefined;
            }
            return state._context._resolveToolInvocationApproval(agent, (0, toolInvocation_1.getHostedMcpApprovalToolName)(rawItem.name, rawItem), rawItem);
        },
        resolveRejectionMessage: (rawItem) => state._context._getToolInvocationRejectionMessage(agent, (0, toolInvocation_1.getHostedMcpApprovalToolName)(rawItem.name, rawItem), rawItem),
    });
    // Server-managed conversations rely on preStepItems to re-surface pending approvals.
    // Keep unresolved hosted MCP approvals in place so HITL flows still have something to approve next turn.
    // Drop resolved approval placeholders so they are not replayed on the next turn, but keep
    // pending approvals in place to signal the outstanding work to the UI and session store.
    const preStepItems = originalPreStepItems.filter((item) => {
        if (!(item instanceof items_1.RunToolApprovalItem)) {
            return true;
        }
        if (isHostedMcpApprovalItem(item)) {
            if (hostedMcpApprovals.pendingApprovals.has(item)) {
                return true;
            }
            const approvalIdentity = (0, toolIdentity_1.getHostedMcpApprovalRequestIdentity)(item.rawItem);
            const approvalRequestKey = approvalIdentity
                ? (0, toolIdentity_1.getHostedMcpApprovalRequestKey)(approvalIdentity)
                : undefined;
            if (approvalRequestKey) {
                return hostedMcpApprovals.pendingApprovalKeys.has(approvalRequestKey);
            }
            return true;
        }
        // Preserve all other approval items so resumptions can continue to reference the
        // original approval requests (e.g., function/shell/apply_patch) ONLY while they are still pending.
        const identity = getApprovalIdentity(item);
        if (!identity) {
            return true;
        }
        return hasApprovalIdentity(pendingApprovalIdentities, identity);
    });
    const keptApprovalItems = new Set();
    for (const item of preStepItems) {
        if (item instanceof items_1.RunToolApprovalItem) {
            keptApprovalItems.add(item);
        }
    }
    let removedApprovalCount = 0;
    for (const item of originalPreStepItems) {
        if (item instanceof items_1.RunToolApprovalItem && !keptApprovalItems.has(item)) {
            removedApprovalCount++;
        }
    }
    if (removedApprovalCount > 0) {
        // Persisting the approval request already advanced the counter once, so undo the increment
        // to make sure we write the final tool output back to the session when the turn resumes.
        state.rewindTurnPersistence(removedApprovalCount);
    }
    const handoffStep = await resolveHandoffAfterTools({
        agent,
        originalInput,
        preStepItems,
        newItems,
        newResponse,
        handoffRuns,
        functionResults,
        additionalInterruptions,
        runner,
        state,
        signal,
        validateHandoffAgent,
        beforeHandoffInputFilter,
    });
    if (handoffStep) {
        return handoffStep;
    }
    const completedStep = await maybeCompleteTurnFromToolResults({
        agent,
        runner,
        state,
        functionResults,
        originalInput,
        newResponse,
        preStepItems,
        newItems,
        additionalInterruptions,
    });
    if (completedStep) {
        return completedStep;
    }
    // we only ran new tools and side effects. We need to run the rest of the agent
    return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, { type: 'next_step_run_again' });
}
/**
 * @internal
 * Executes every follow-up action the model requested (function tools, computer actions, MCP flows),
 * appends their outputs to the run history, and determines the next step for the agent loop.
 */
async function resolveTurnAfterModelResponse(agent, originalInput, originalPreStepItems, newResponse, processedResponse, runner, state, toolErrorFormatter, agentToolParentRunConfig, errorHandlers, signal, preflightedToolCalls, attemptedErrors, validateHandoffAgent) {
    const suppressedToolCalls = preflightedToolCalls ??
        preflightToolInvocations(agent, state, processedResponse);
    // Reuse the same array reference so we can compare object identity when deciding whether to
    // append new items, ensuring we never double-stream existing RunItems.
    const preStepItems = originalPreStepItems;
    const newItems = [];
    const appendContext = buildAppendContext(originalPreStepItems);
    const appendIfNew = (item) => appendRunItemIfNew(item, newItems, appendContext);
    for (const item of processedResponse.newItems) {
        if (isSuppressedToolCallItem(item, suppressedToolCalls)) {
            continue;
        }
        appendIfNew(item);
    }
    const handoffRuns = processedResponse.handoffs.filter((run) => !suppressedToolCalls.has(run.toolCall));
    if (handoffRuns.length > 0) {
        if (!signal?.aborted) {
            validateHandoffInputFilter(handoffRuns[0].handoff, runner, state);
        }
        validateHandoffAgent?.(handoffRuns[0].handoff.agent);
    }
    const functionRuns = processedResponse.functions.filter((run) => !suppressedToolCalls.has(run.toolCall));
    validateAgentToolSources(functionRuns, validateHandoffAgent);
    // Run function tools and computer actions in parallel; neither depends on the other's side effects.
    // Shell and apply_patch actions both mutate the sandbox filesystem, so preserve model order.
    const runFunctionTools = (executionSignal = signal, cancelSiblingCategories) => (0, toolExecution_1.executeFunctionToolCalls)(agent, functionRuns, runner, state, toolErrorFormatter, agentToolParentRunConfig, executionSignal, cancelSiblingCategories);
    const runComputerActions = (executionSignal = signal, cancelSiblingCategories) => (0, toolExecution_1.executeComputerActions)(agent, processedResponse.computerActions.filter((run) => !suppressedToolCalls.has(run.toolCall)), runner, state._context, undefined, toolErrorFormatter, executionSignal, cancelSiblingCategories);
    const [functionResults, computerResults] = processedResponse.functions.some((run) => !suppressedToolCalls.has(run.toolCall)) &&
        processedResponse.computerActions.some((run) => !suppressedToolCalls.has(run.toolCall))
        ? await (0, siblingCancellation_1.runWithSiblingCancellation)([runFunctionTools, runComputerActions], signal)
        : await Promise.all([runFunctionTools(), runComputerActions()]);
    const shellAndApplyPatchResults = processedResponse.shellActions.some((run) => !suppressedToolCalls.has(run.toolCall)) ||
        processedResponse.applyPatchActions.some((run) => !suppressedToolCalls.has(run.toolCall))
        ? await executeShellAndApplyPatchActionsInOrder({
            agent,
            sourceItems: processedResponse.newItems,
            shellActions: processedResponse.shellActions.filter((run) => !suppressedToolCalls.has(run.toolCall)),
            applyPatchActions: processedResponse.applyPatchActions.filter((run) => !suppressedToolCalls.has(run.toolCall)),
            runner,
            state,
            toolErrorFormatter,
            signal,
        })
        : [];
    const toolNotFoundResults = await buildToolNotFoundOutputItems(agent, state, (processedResponse.functionToolsNotFound ?? []).filter((run) => !suppressedToolCalls.has(run.toolCall)), toolErrorFormatter);
    for (const result of functionResults) {
        if (result.type === 'function_output' &&
            Array.isArray(result.interruptions) &&
            result.interruptions.length > 0) {
            continue;
        }
        appendIfNew(result.runItem);
    }
    for (const item of toolNotFoundResults) {
        appendIfNew(item);
    }
    for (const item of computerResults) {
        appendIfNew(item);
    }
    for (const item of shellAndApplyPatchResults) {
        appendIfNew(item);
    }
    const additionalInterruptions = (0, toolExecution_1.collectInterruptions)([], [...computerResults, ...shellAndApplyPatchResults]);
    if (processedResponse.mcpApprovalRequests.length > 0) {
        await (0, mcpApprovals_1.handleHostedMcpApprovals)({
            requests: processedResponse.mcpApprovalRequests.filter((run) => !suppressedToolCalls.has(run.requestItem.rawItem)),
            agent,
            state,
            functionResults,
            appendIfNew,
            resolveApproval: (rawItem) => {
                if (!(0, toolIdentity_1.getHostedMcpApprovalRequestIdentity)(rawItem)?.requestId) {
                    return undefined;
                }
                return state._context._resolveToolInvocationApproval(agent, (0, toolInvocation_1.getHostedMcpApprovalToolName)(rawItem.name, rawItem), rawItem);
            },
            resolveRejectionMessage: (rawItem) => state._context._getToolInvocationRejectionMessage(agent, (0, toolInvocation_1.getHostedMcpApprovalToolName)(rawItem.name, rawItem), rawItem),
        });
    }
    const handoffStep = await resolveHandoffAfterTools({
        agent,
        originalInput,
        preStepItems,
        newItems,
        newResponse,
        handoffRuns,
        functionResults,
        additionalInterruptions,
        runner,
        state,
        signal,
        validateHandoffAgent,
    });
    if (handoffStep) {
        return handoffStep;
    }
    const completedStep = await maybeCompleteTurnFromToolResults({
        agent,
        runner,
        state,
        functionResults,
        originalInput,
        newResponse,
        preStepItems,
        newItems,
        additionalInterruptions,
    });
    if (completedStep) {
        return completedStep;
    }
    // If the model issued any tool calls or handoffs in this turn,
    // we must NOT treat any assistant message in the same turn as the final output.
    // We should run the loop again so the model can see the tool results and respond.
    if (processedResponse.hasToolsOrApprovalsToRun()) {
        return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, { type: 'next_step_run_again' });
    }
    // No tool calls/actions in this turn; safe to consider a plain assistant message as final.
    const messageItems = newItems.filter((item) => item instanceof items_1.RunMessageOutputItem);
    // A model response may split assistant text across multiple messages around
    // non-message output items such as reasoning. Preserve all of that text while
    // retaining the last message's refusal semantics.
    const lastMessageText = messageItems.length > 0
        ? (0, messages_1.getTextFromOutputMessage)(messageItems[messageItems.length - 1].rawItem)
        : undefined;
    const potentialFinalOutput = typeof lastMessageText === 'undefined'
        ? undefined
        : (0, messages_1.getOutputText)(newResponse) || lastMessageText;
    // Keep looping if any tool output placeholders still require an approval follow-up.
    const hasPendingToolsOrApprovals = functionResults.some((result) => result.runItem instanceof items_1.RunToolApprovalItem) || additionalInterruptions.length > 0;
    if (!hasPendingToolsOrApprovals && messageItems.length > 0) {
        const refusal = (0, messages_1.getRefusalFromOutputMessage)(messageItems[messageItems.length - 1].rawItem);
        if (refusal && typeof potentialFinalOutput === 'undefined') {
            const refusalError = new errors_1.ModelRefusalError(refusal, state);
            const handlerResult = await (0, errorHandlers_1.resolveRunErrorHandler)({
                error: refusalError,
                errorHandlers,
                context: state._context,
                runData: buildTurnRunErrorData(state, agent, originalInput, preStepItems, newItems),
                attemptedErrors,
            });
            if (!handlerResult) {
                throw refusalError;
            }
            const outputText = (0, errorHandlers_1.formatRunErrorFinalOutput)(agent, handlerResult.finalOutput);
            (0, errorHandlers_1.validateRunErrorHandlerFinalOutput)(agent, outputText);
            if (handlerResult.includeInHistory !== false) {
                newItems.push((0, errorHandlers_1.createRunErrorFinalOutputItem)(agent, outputText));
            }
            return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, { type: 'next_step_final_output', output: outputText }, 'error_handler');
        }
    }
    const isMissingStructuredFinalOutput = agent.outputType !== 'text' && !potentialFinalOutput;
    // Recover missing structured output when configured; otherwise run again.
    if (typeof potentialFinalOutput === 'undefined' ||
        isMissingStructuredFinalOutput) {
        if (!hasPendingToolsOrApprovals && isMissingStructuredFinalOutput) {
            const outputError = new errors_1.ModelBehaviorError('Model returned no final output for the structured output type.');
            const handledOutput = await resolveInvalidFinalOutput({
                error: outputError,
                errorHandlers,
                agent,
                originalInput,
                preStepItems,
                newItems,
                state,
                attemptedErrors,
            });
            if (typeof handledOutput !== 'undefined') {
                return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, { type: 'next_step_final_output', output: handledOutput }, 'error_handler');
            }
        }
        return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, { type: 'next_step_run_again' });
    }
    if (!hasPendingToolsOrApprovals) {
        if (agent.outputType === 'text') {
            return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, {
                type: 'next_step_final_output',
                output: potentialFinalOutput,
            });
        }
        if (agent.outputType !== 'text' && potentialFinalOutput) {
            // Structured output schema => always leads to a final output if we have text.
            const [error] = await (0, safeExecute_1.safeExecute)(() => (0, finalOutputError_1.processFinalOutputWithRedaction)(() => agent.processFinalOutput(potentialFinalOutput)));
            if (error) {
                if ((0, standardSchema_1.isAsyncStandardSchemaValidationError)(error)) {
                    throw error;
                }
                const redacted = (0, finalOutputError_1.isDataRedactedError)(error);
                const outputErrorMessage = redacted
                    ? error.message
                    : formatFinalOutputTypeError(error);
                const includeTraceErrorDetails = runner.config.traceIncludeSensitiveData && !redacted;
                (0, context_1.addErrorToCurrentSpan)({
                    message: includeTraceErrorDetails
                        ? outputErrorMessage
                        : finalOutputError_1.REDACTED_FINAL_OUTPUT_ERROR_MESSAGE,
                    data: includeTraceErrorDetails ? { error: String(error) } : {},
                });
                const outputError = redacted
                    ? error
                    : new errors_1.ModelBehaviorError(outputErrorMessage);
                const handledOutput = await resolveInvalidFinalOutput({
                    error: outputError,
                    errorHandlers,
                    agent,
                    originalInput,
                    preStepItems,
                    newItems,
                    state,
                    attemptedErrors,
                });
                if (typeof handledOutput === 'undefined') {
                    throw outputError;
                }
                return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, { type: 'next_step_final_output', output: handledOutput }, 'error_handler');
            }
            return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, { type: 'next_step_final_output', output: potentialFinalOutput });
        }
    }
    return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, { type: 'next_step_run_again' });
}
// Local handoff filters cannot remove history already owned by the server.
function validateHandoffInputFilter(handoff, runner, state) {
    const inputFilter = handoff.inputFilter ?? runner.config.handoffInputFilter;
    if (inputFilter != null &&
        (state._conversationId || state._previousResponseId)) {
        throw new errors_1.UserError('Handoff input filters cannot be used with conversationId or previousResponseId because server-managed history cannot be filtered locally. Use explicit client-managed history or a Session without either continuation option.');
    }
}
// Handoffs retain precedence over terminal tool behavior, but cannot discard pending approvals.
async function resolveHandoffAfterTools(options) {
    const { agent, originalInput, preStepItems, newItems, newResponse, handoffRuns, functionResults, additionalInterruptions, runner, state, signal, validateHandoffAgent, beforeHandoffInputFilter, } = options;
    if (handoffRuns.length === 0) {
        return undefined;
    }
    if (signal?.aborted) {
        const appendContext = buildAppendContext([...preStepItems, ...newItems]);
        for (const { toolCall } of handoffRuns) {
            const rawItem = (0, streamReconciliation_1.buildFunctionAbortResult)(toolCall);
            appendRunItemIfNew(new items_1.RunToolCallOutputItem(rawItem, agent, rawItem.output), newItems, appendContext);
        }
        return undefined;
    }
    const interruptions = (0, toolExecution_1.collectInterruptions)(functionResults, additionalInterruptions);
    if (interruptions.length > 0) {
        return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, {
            type: 'next_step_interruption',
            data: { interruptions },
        });
    }
    return (0, toolExecution_1.executeHandoffCalls)(agent, originalInput, preStepItems, newItems, newResponse, handoffRuns, runner, state._context, (0, invocationContext_1.getRunStateTurnSpanParent)(state) ?? state._currentAgentSpan, validateHandoffAgent, beforeHandoffInputFilter, signal);
}
// Consolidates the logic that determines whether tool results yielded a final answer,
// triggered an interruption, or require the agent loop to continue running.
async function maybeCompleteTurnFromToolResults({ agent, runner: _runner, state, functionResults, originalInput, newResponse, preStepItems, newItems, additionalInterruptions = [], }) {
    const toolOutcome = await (0, toolExecution_1.checkForFinalOutputFromTools)(agent, functionResults, state, additionalInterruptions);
    if (toolOutcome.isFinalOutput) {
        // Intentional: explicit toolUseBehavior finalization (for example stop_on_first_tool) takes precedence even when other provider-managed work is still pending.
        return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, {
            type: 'next_step_final_output',
            output: toolOutcome.finalOutput,
        }, 'tool_result');
    }
    if (toolOutcome.isInterrupted) {
        return new steps_1.SingleStepResult(originalInput, newResponse, preStepItems, newItems, {
            type: 'next_step_interruption',
            data: {
                interruptions: toolOutcome.interruptions,
            },
        });
    }
    return null;
}
//# sourceMappingURL=turnResolution.js.map