import type { AgentIdentity, AgentTelemetryConfig, AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
declare const adviseSchema: import("arktype/internal/variants/object.ts").ObjectType<{
    note: string;
    severity?: "blocker" | "concern" | "nit" | undefined;
}, {}>;
export type AdviseParams = typeof adviseSchema.infer;
export type AdvisorSeverity = "nit" | "concern" | "blocker";
export interface AdviseDetails {
    note: string;
    severity?: AdvisorSeverity;
    /** Which configured advisor produced this note (omitted for the default advisor). */
    advisor?: string;
}
/** One queued advice note. */
export interface AdvisorNote {
    note: string;
    severity?: AdvisorSeverity;
    /** Which configured advisor produced this note (omitted for the default advisor). */
    advisor?: string;
}
/** Details payload on the batched `advisor` custom message rendered in the transcript. */
export interface AdvisorMessageDetails {
    notes: AdvisorNote[];
}
/**
 * Render a batch of advisor notes as the agent-facing message body: one
 * `<advisory>` element per note, severity as an attribute. Shared by the
 * non-interrupting YieldQueue dispatcher and the interrupting steer path so both
 * build byte-identical content.
 */
export declare function formatAdvisorBatchContent(notes: readonly AdvisorNote[]): string;
/**
 * Whether advice at this severity should interrupt the running agent (delivered
 * via the steering channel, aborting in-flight tools) rather than ride the
 * non-interrupting aside queue that lands at the next step boundary. `concern`
 * and `blocker` interrupt; a plain `nit` queues.
 */
export declare function isInterruptingSeverity(severity: AdvisorSeverity | undefined): boolean;
/** How an advisor note is routed to the primary. */
export type AdvisorDeliveryChannel = "aside" | "steer" | "preserve";
/** Half-open turn-count fence for the post-interrupt cooldown. */
export declare function isAdvisorInterruptImmuneTurnActive(opts: {
    completedTurns: number;
    immuneTurnStart: number | undefined;
    immuneTurns: number;
}): boolean;
/**
 * Decide how one advisor note reaches the primary agent.
 *
 * - A non-interrupting `nit` always rides the non-interrupting aside queue.
 * - An interrupting `concern`/`blocker` is normally steered into the agent: into
 *   the live turn while one is streaming, or (when idle) a triggered turn so the
 *   advice is acted on immediately.
 * - After a deliberate user interrupt (`autoResumeSuppressed`) the advisor must
 *   not auto-resume the stopped run. While the agent is idle — or still tearing
 *   the interrupted turn down (`aborting`) — the note is preserved as a visible
 *   card instead of restarting the run. But once a turn is actively streaming
 *   again (a resume the user already drove), steering the note in does NOT
 *   auto-resume anything, so it is delivered live. Parking it during an active
 *   run instead strands it (it never reaches the running agent) and the withheld
 *   notes dump as one burst at the next user prompt — the bug this guards.
 * - During the post-interrupt immune-turn window, further `concern`/`blocker`
 *   notes are downgraded to asides; suppression preservation still wins.
 */
export declare function resolveAdvisorDeliveryChannel(opts: {
    severity: AdvisorSeverity | undefined;
    autoResumeSuppressed: boolean;
    streaming: boolean;
    aborting: boolean;
    interruptImmuneTurnActive?: boolean;
}): AdvisorDeliveryChannel;
/**
 * Derive the advisor loop's telemetry from the primary session's config so the
 * advisor model's GenAI spans and usage/cost hooks (onChatUsage, onCostDelta,
 * costEstimator) fire under the same pipeline as every other model call —
 * stamped with the advisor's own agent identity. `conversationId` is cleared so
 * the advisor loop falls back to its own `-advisor` session id for
 * `gen_ai.conversation.id` instead of inheriting the primary's conversation.
 *
 * Returns undefined when the primary has no telemetry (instrumentation off), so
 * the advisor `Agent` stays a zero-overhead no-op as well.
 */
export declare function deriveAdvisorTelemetry(primaryTelemetry: AgentTelemetryConfig | undefined, identity: AgentIdentity): AgentTelemetryConfig | undefined;
/**
 * The tools an advisor receives by default when its config omits `tools` — the
 * read-only investigative set. The full available pool is every built tool the
 * session has (the advisor is a full agent); a config's `tools` selects from it.
 */
export declare const ADVISOR_DEFAULT_TOOL_NAMES: ReadonlySet<string>;
export declare class AdviseTool implements AgentTool<typeof adviseSchema, AdviseDetails> {
    #private;
    private readonly onAdvice;
    readonly name = "advise";
    readonly label = "Advise";
    readonly description: string;
    readonly parameters: import("arktype/internal/variants/object.ts").ObjectType<{
        note: string;
        severity?: "blocker" | "concern" | "nit" | undefined;
    }, {}>;
    readonly intent: "omit";
    constructor(onAdvice: (note: string, severity?: AdviseDetails["severity"]) => void);
    /** Clear delivered-note memory when the advisor starts a fresh conversation. */
    resetDeliveredNotes(): void;
    execute(_toolCallId: string, args: AdviseParams, _signal?: AbortSignal, _onUpdate?: AgentToolUpdateCallback<AdviseDetails>, _context?: AgentToolContext): Promise<AgentToolResult<AdviseDetails>>;
}
export {};
