import { EventType, Interrupt, ModelMessage, RunAgentResumeItem, StreamChunk, TokenUsage, Tool, UIMessage } from '../../../types.js';
import { SpecTokenUsage } from '../../../utilities/ag-ui-usage.js';
import { DefinedAgent, SubagentRunContext } from './define-agent.js';
import { ChatMiddleware } from '../middleware/types.js';
import { SubagentTurn } from './turn.js';
export declare const SUBAGENT_STARTED = EventType.SUBAGENT_STARTED;
export declare const SUBAGENT_FINISHED = EventType.SUBAGENT_FINISHED;
export declare const SUBAGENT_ERROR = EventType.SUBAGENT_ERROR;
export type SubagentOrder = 'parallel' | 'sequence';
export interface SubagentRouterPlan {
    names: ReadonlyArray<string>;
    /** Overrides `subagents.order` for this turn. */
    order?: SubagentOrder;
}
export interface SubagentStep {
    names: ReadonlyArray<string>;
    /** Overrides `subagents.order` for this step. */
    order?: SubagentOrder;
}
export interface SubagentStepsPlan {
    steps: ReadonlyArray<SubagentStep>;
}
export type SubagentRouterPick = 'main' | string | ReadonlyArray<string> | SubagentRouterPlan | SubagentStepsPlan;
export interface SubagentsBag<TAgents extends ReadonlyArray<DefinedAgent> = ReadonlyArray<DefinedAgent>> {
    agents: TAgents;
    router?: (ctx: {
        messages: SubagentRunContext['messages'];
        agents: NoInfer<TAgents>;
        abortSignal?: AbortSignal;
    }) => SubagentRouterPick | Promise<SubagentRouterPick>;
    strategy?: 'exclusive' | 'handoff';
    /**
     * How a router list runs. `parallel` starts every name together.
     * `sequence` runs each name after the previous one finishes, and passes
     * that child's text to the next child.
     */
    order?: 'parallel' | 'sequence';
    sandbox?: 'own' | 'inherit';
}
/** What the children of one parent run left behind for the parent terminal. */
export interface SubagentSink {
    interrupts: Array<Interrupt>;
    /** One AG-UI entry per child model call. */
    usage: Array<SpecTokenUsage>;
    /** Summed full usage of the children, including cost. */
    total?: TokenUsage;
}
export declare function createSubagentSink(): SubagentSink;
/** One child to start, or a suspended child to continue. */
export interface SpawnEntry {
    name: string;
    resume?: {
        subagentRunId: string;
        /** The child's own messages from the interrupted run. */
        messages: Array<UIMessage | ModelMessage>;
        entries: Array<RunAgentResumeItem>;
        /** Text the child wrote before it stopped. */
        text: string;
    };
}
interface SpawnContext {
    messages: SubagentRunContext['messages'];
    abortSignal?: AbortSignal;
    threadId: string;
    /** The parent chat run. */
    parentRunId: string;
    /** The interrupted parent run, on a resume. */
    interruptedRunId?: string;
}
export declare function createSubagentId(): string;
/**
 * Bind child interrupts to the parent run. The client resumes the parent run,
 * so each binding must name that run. The resumed child then validates with
 * the parent's interrupted run id.
 */
export declare function rebindInterrupts(interrupts: ReadonlyArray<Interrupt>, runId: string): Array<Interrupt>;
export declare function normalizeRouterPick(pick: SubagentRouterPick, agents: ReadonlyArray<DefinedAgent>): {
    steps: ReadonlyArray<SubagentStep>;
};
/** Add a finished child run's usage to the sink. */
export declare function collectUsage(sink: SubagentSink, finished?: StreamChunk): void;
/** A parent run's last chunk: it completed, or it failed. */
type ParentTerminal = Extract<StreamChunk, {
    type: 'RUN_FINISHED' | 'RUN_ERROR';
}>;
/**
 * Put the children's usage on a parent terminal. `usage[]` keeps one entry per
 * model call. `metadata.tanstack.usage` holds the summed cost and the other
 * TanStack fields, so `fromSpecTokenUsage` reads the full total. Empties the
 * sink, so the next parent terminal does not count it again.
 *
 * `RUN_ERROR` is accepted too: a turn that failed still spent whatever its
 * children spent. Such a chunk carries no usage of its own, so `runUsage` and
 * `fullUsage` return empty for it and the children's total stands alone.
 */
export declare function withChildUsage(chunk: ParentTerminal, sink: SubagentSink): ParentTerminal;
export declare function spawnAgentStream(agent: DefinedAgent, ctx: SubagentRunContext, sink?: SubagentSink, parentToolCallId?: string): AsyncIterable<StreamChunk>;
export declare function spawnNamedAgents(entries: ReadonlyArray<SpawnEntry>, bag: SubagentsBag, ctx: SpawnContext, sink?: SubagentSink): AsyncGenerator<import('../../..').AGUIEvent, void, any>;
/**
 * Text of the named direct children, in `names` order. Text from nested
 * children stays out: their chunks carry their own id.
 */
export declare function collectNamedText(chunks: Array<StreamChunk>, names: ReadonlyArray<string>): string;
/**
 * Record the parent messages when the model calls a subagent tool, so the
 * child reads the conversation as it is at that call.
 */
export declare function subagentCallMessages(names: ReadonlySet<string>): {
    middleware: ChatMiddleware<unknown, never>;
    messagesFor: (toolCallId: string | undefined) => ModelMessage<string | import('../../..').ContentPart<unknown, unknown, unknown, unknown, unknown>[] | null>[] | undefined;
};
export declare function createSyntheticSubagentTools(bag: SubagentsBag, parent: {
    /** Messages the parent run started with. Used when no call was recorded. */
    messages: SubagentRunContext['messages'];
    /** The parent messages at a tool call. See subagentCallMessages. */
    messagesFor?: (toolCallId: string | undefined) => SubagentRunContext['messages'] | undefined;
    threadId: string;
    runId: string;
    interruptedRunId?: string;
    abortSignal?: AbortSignal;
    turn?: SubagentTurn;
    sink: SubagentSink;
}): Array<Tool>;
export {};
