/**
 * Session tool-result guard — wraps a pi `SessionManager.appendMessage` to:
 *   1. cap oversized tool-result text + details so they cannot blow up the next
 *      LLM request (size + persistence limits).
 *   2. track pending tool-call IDs so missing tool results can be synthesised
 *      (some providers refuse a turn that has an orphan tool_use block).
 *   3. drop assistant `toolCall` blocks whose tool name is not in the allowlist
 *      (these would also trigger provider 400s).
 *   4. broadcast `xopc:transcript-row` updates so the gateway UI can stream them.
 *
 * Previously this module shipped with three sibling files
 * (`session-tool-result-state.ts`, `session-raw-append-message.ts`,
 * `session-tool-result-guard-wrapper.ts`). They are now consolidated here as
 * private constructs around the `ToolResultGuard` class. Pi-coding-agent owns
 * the `SessionManager` instance and calls `appendMessage` from inside the
 * runtime, so we still need to monkey-patch that method — but the patched
 * implementation is just `guard.guardedAppend.bind(guard)` and all state lives
 * on the class.
 */
import type { AgentMessage } from '@earendil-works/pi-agent-core';
import type { SessionManager } from '@earendil-works/pi-coding-agent';
import type { Config } from '../../config/schema.js';
export type BeforeMessageWriteHookEvent = {
    message: AgentMessage;
};
export type BeforeMessageWriteHookResult = {
    block?: boolean;
    message?: AgentMessage;
} | undefined;
export interface ToolResultGuardOptions {
    /** Optional session key for transcript update broadcasts. */
    sessionKey?: string;
    /** Optional transform applied to any message before persistence. */
    transformMessageForPersistence?: (message: AgentMessage) => AgentMessage;
    /**
     * Optional, synchronous transform applied to toolResult messages *before* they are
     * persisted to the session transcript.
     */
    transformToolResultForPersistence?: (message: AgentMessage, meta: {
        toolCallId?: string;
        toolName?: string;
        isSynthetic?: boolean;
    }) => AgentMessage;
    /**
     * Whether to synthesize missing tool results to satisfy strict providers.
     * Defaults to true.
     */
    allowSyntheticToolResults?: boolean;
    missingToolResultText?: string;
    /**
     * Optional set/list of tool names accepted for assistant toolCall/toolUse blocks.
     * When set, tool calls with unknown names are dropped before persistence.
     */
    allowedToolNames?: Iterable<string>;
    /**
     * Synchronous hook invoked before any message is written to the session JSONL.
     * If the hook returns { block: true }, the message is silently dropped.
     * If it returns { message }, the modified message is written instead.
     */
    beforeMessageWriteHook?: (event: BeforeMessageWriteHookEvent) => BeforeMessageWriteHookResult;
    maxToolResultChars?: number;
}
export interface InstallSessionToolResultGuardResult {
    flushPendingToolResults: () => void;
    clearPendingToolResults: () => void;
    getPendingIds: () => string[];
}
/** Idempotent wrapper that also adds the helper methods consumers expect. */
export type GuardedPiTranscriptManager = SessionManager & {
    flushPendingToolResults?: () => void;
    clearPendingToolResults?: () => void;
};
/**
 * Install the guard on a SessionManager and return its control API.
 * Subsequent assistant/toolResult writes by pi-coding-agent flow through the
 * guard transparently.
 */
export declare function installSessionToolResultGuard(sessionManager: SessionManager, opts?: ToolResultGuardOptions): InstallSessionToolResultGuardResult;
/**
 * Convenience wrapper used by the embedded runner pool: install the guard
 * (idempotent), pin the size cap from the model context window, and expose
 * `flushPendingToolResults` / `clearPendingToolResults` directly on the
 * SessionManager instance so callers do not need to keep the install result.
 */
export declare function guardSessionManager(sessionManager: SessionManager, opts?: {
    agentId?: string;
    sessionKey?: string;
    config?: Config;
    contextWindowTokens?: number;
    allowSyntheticToolResults?: boolean;
    missingToolResultText?: string;
    allowedToolNames?: Iterable<string>;
}): GuardedPiTranscriptManager;
/**
 * Recover the original (un-guarded) appendMessage for a session manager.
 * Useful for callers that need a low-level "bypass the guard" write path.
 */
export declare function getRawSessionAppendMessage(sessionManager: SessionManager): SessionManager['appendMessage'];
