import type { ToolConfirmation, ToolPresentation, ToolPresentationTone } from '../../../index.js';
import type { AnyToolUIPart, TranscriptToolCall } from '../transcript/model.js';
import { type ToolCatalog } from './phrasing.js';
import { type ResolvedResultView } from './result-view.js';
/**
 * Where one call stands, as a person reads it:
 *  - `running` — input streaming or the tool executing;
 *  - `awaiting-approval` — an `action` call parked on a person;
 *  - `done` / `failed` / `denied` — settled. A tool that RETURNS `{ error }` has failed just as much
 *    as one that threw; the two arrive differently and read the same to a person.
 */
export type ToolCallStatus = 'running' | 'awaiting-approval' | 'done' | 'failed' | 'denied' | 'queued' | 'executing' | 'succeeded';
export interface ToolCallState {
    status: ToolCallStatus;
    isSettled: boolean;
    isFailed: boolean;
    isDenied: boolean;
    output: unknown;
    error: string | null;
}
/** Whether the stream classified this call as an `action` (it parks for approval before it runs). */
export declare function isActionCall(part: AnyToolUIPart): boolean;
export declare function toolCallState(part: AnyToolUIPart): ToolCallState;
/**
 * Which failed calls the model went on to correct, by call id: a call that failed and was followed,
 * in the same run, by a SUCCESS of the same tool. The operator wants to know a retry happened, not
 * to read every attempt. A failed read is not corrected by a successful query.
 */
export declare function correctedCallIds(parts: readonly AnyToolUIPart[]): Set<string>;
/**
 * Which failed calls the model retried AT ONCE, by call id: a failure whose next tool call (in
 * message order) is the same tool and has not failed — it succeeded, or is still running. A chain
 * of failures that ends in a success is retried whole. What a person should not see: the model
 * fixing its own malformed call (a `ui__render` it left the envelope out of) before the view it
 * then drew. A failure the model moved on from, or that the retry failed too, stays.
 */
export declare function retriedCallIds(parts: readonly AnyToolUIPart[]): Set<string>;
/** Everything a surface needs to talk about one call without naming it. */
export interface ToolCallDescription {
    status: ToolCallStatus;
    /** "Querying orders" / "Queried orders" — or the generic fallback when the tool declared nothing. */
    phrase: string;
    /** The server's noun phrase for the tool; `null` when it declared no presentation. */
    label: string | null;
    icon: string | null;
    tone: ToolPresentationTone;
    detail: string | null;
    /** The approval prompt, templated over the call's input; `null` when the tool declared none. */
    confirm: {
        title: string;
        verb: string;
        detail: string | null;
    } | null;
    /** The output read through its view, once the call is `done`; `null` otherwise or when nothing to draw. */
    result: ResolvedResultView | null;
    error: string | null;
    presentation: ToolPresentation | null;
}
export interface DescribeToolCallOptions {
    /** Resolved strings from the call preflight override the tool catalog templates. */
    confirmation?: ToolConfirmation;
    /** Words for a tool the catalog does not describe. Default `Working` / `Done`. */
    fallback?: {
        running: string;
        done: string;
    };
    /** Infer a result view from the output's shape when the tool declared none. Default `false`. */
    inferResult?: boolean;
}
export declare function describeToolCall(part: AnyToolUIPart, catalog: ToolCatalog | undefined, options?: DescribeToolCallOptions): ToolCallDescription;
/**
 * Calls folded under one key — "Database query ×3" — with the state that matters most across them.
 */
export interface ToolActivityGroup {
    key: string;
    /** The server's label for the group's tool; `null` when it declared no presentation. */
    label: string | null;
    icon: string | null;
    /** Worst-first across the calls: running › awaiting-approval › failed › denied › done. */
    status: ToolCallStatus;
    count: number;
    /** The phrase of the group's LATEST call — what is happening now. */
    phrase: string;
    calls: TranscriptToolCall[];
    /** Calls nested under the group's calls (all depths), when nesting was not expanded. */
    innerCount: number;
}
export interface GroupToolActivityOptions {
    catalog?: ToolCatalog;
    /**
     * What makes two calls "the same activity". Default: the tool's presentation `label`, else its
     * name. Flippy-style source grouping passes its own (e.g. `github:search`).
     */
    keyOf?: (call: TranscriptToolCall, presentation: ToolPresentation | undefined) => string;
    /**
     * Replace a call that has nested calls with those calls (recursively), so the activity reads as
     * what the code-mode run DID rather than "ran code". Default `false`: groups are built over the
     * top-level calls, and `innerCount` says how much ran beneath them.
     */
    expandNested?: boolean;
    /** Drop failed calls the model corrected with a later success of the same tool. Default `false`. */
    hideCorrected?: boolean;
    fallback?: {
        running: string;
        done: string;
    };
}
/**
 * Fold a tool run into activity groups, in order of first appearance. Pass `block.roots` (the
 * transcript's call tree) so nesting is honoured; a flat `block.calls` works too and simply has
 * nothing nested.
 */
export declare function groupToolActivity(calls: readonly TranscriptToolCall[], options?: GroupToolActivityOptions): ToolActivityGroup[];
//# sourceMappingURL=tool-activity.d.ts.map