import type { AgentService } from '../agent-service.js';
import type { StreamFrame } from '../spi/token-stream-sink.js';
import type { Actor, PageContext } from '../types.js';
/**
 * What an A2A turn does with an `action` call that parks for approval:
 *  - `'approve-delegated'` (default) — approve it when the caller's delegation grants one of the
 *    tool's roles: the user approved that scope on their own account page, which IS the consent the
 *    in-app approval stands for. Anything else is rejected. An independent proposal
 *    (`actionApprovalMode: 'independent'`) is decided the same way once the run ends, and the turn
 *    waits for it to execute, so the reply never claims an action that did not happen.
 *  - `'reject'` — reject every action; personal agents only read.
 */
export type A2aActionPolicy = 'approve-delegated' | 'reject';
export interface A2aTurnInput {
    actor: Actor;
    text: string;
    /** The registered agent that answers. Omitted → the service's default. */
    agentName?: string;
    /** Continue this thread; omitted → a new (transient) one. */
    threadId?: string;
    /** Scopes the caller's delegation grants; `null` without a delegation. */
    delegatedScopes: string[] | null;
    actions: A2aActionPolicy;
    /** Give up (and cancel the run) after this long. */
    timeoutMs: number;
    /** Called once the run started, with the thread it runs in — before its frames are read. */
    onStarted?: (threadId: string, runId: string) => Promise<void>;
    /** The page context the turn runs with. Default `{ channel: 'a2a' }`. */
    pageContext?: PageContext;
    /** What approvals and answers are recorded as coming through. Default `'a2a'`. */
    via?: string;
    /** Each piece of the reply's text as it streams — for a surface that relays it live. */
    onText?: (delta: string) => void | Promise<void>;
    /** Each component frame other than a permission request, as it arrives. */
    onComponent?: (frame: Extract<StreamFrame, {
        t: 'component';
    }>) => void | Promise<void>;
    /**
     * Execute, in this process, what of the run waits for a worker (`AgentService.drive`) while the
     * turn is read — for a durable runner whose dispatcher only persists a started run.
     */
    drive?: (runId: string) => Promise<void>;
}
export interface A2aTurnAction {
    tool: string;
    argsHash: string;
    /** The delegated scopes that authorized it. */
    scopes: string[];
}
/**
 * An independent proposal that executed during the turn: the app's own summary of it (the
 * confirmation it would have shown the person) and what the tool returned.
 */
export interface A2aTurnOutcome {
    tool: string;
    /**
     * `succeeded` — approved and executed; `failed` — approved but did not run (`error` says why);
     * `rejected` — the policy refused it (no delegated scope, or `actions: 'reject'`).
     */
    status: 'succeeded' | 'failed' | 'rejected';
    summary: {
        title: string;
        detail?: string;
    };
    result?: unknown;
    /** Why a `failed` action did not run. */
    error?: string;
}
export interface A2aTurnResult {
    threadId: string;
    text: string;
    /** Scopes the agent asked the user for (`request_permission`); `null` when it asked for none. */
    permission: string[] | null;
    /** Tools that RAN under a delegated scope (reads and approved actions) — what a receipt lists. */
    actions: A2aTurnAction[];
    /** Approved proposals that executed — the reply carries each as a data part. */
    outcomes: A2aTurnOutcome[];
    /** Why the run failed, when it did. */
    error: string | null;
}
/**
 * What runs an A2A turn: start it, read its frames, settle what it parks on. `AgentService` (the
 * agent provider's) is one; an app with its own runtime — a `runAgentLoop` built per request, say —
 * writes an adapter with the same shape (`defineA2aConfig({ service })`).
 */
export interface A2aTurnService extends Pick<AgentService, 'chat' | 'subscribe' | 'approve' | 'reject' | 'skip' | 'cancel'>, Partial<Pick<AgentService, 'decideActionProposal' | 'listActionProposals'>> {
    /**
     * The roles a tool declares — what an approval and a receipt match the delegated scopes against.
     * Omitted → the shared `ToolRegistry`. An app whose registry is built per turn answers it here.
     */
    toolRoles?(toolName: string): string[] | undefined;
}
/**
 * Run one A2A turn to completion and read its outcome off the stream. A2A's `message:send` is
 * synchronous (PACT §4.2), so the run's frames are consumed here until the stream ends: text is the
 * reply, an approval is decided on the spot by {@link A2aActionPolicy}, a question set is skipped
 * (there is no human on this side to answer it — the agent proceeds on its own assumptions), and a
 * `request_permission` call becomes a step-up.
 */
export declare function runA2aTurn(service: A2aTurnService, 
/** The roles a tool declares (see {@link A2aTurnService.toolRoles}). */
toolRoles: (toolName: string) => string[] | undefined, input: A2aTurnInput): Promise<A2aTurnResult>;
//# sourceMappingURL=turn.d.ts.map