/**
 * PersistentGoalService — owns the "/goal" runtime: continuation scheduling,
 * the `PersistentGoalApis` bag that command handlers receive, and the post-turn
 * verdict hook called from `OutboundCoordinator`.
 *
 * Previously this logic was scattered across `AgentService`:
 *   - `setPersistentGoalWebchatContinuationScheduler` + a private callback field
 *   - `schedulePersistentGoalContinuation` (bus vs webchat fork)
 *   - `getPersistentGoalApisForCommand` (~40-line API factory)
 *   - `recordPersistentGoalStreamOutcome` / `takePersistentGoalStreamOutcome`
 *   - the `/goal` half of `emitSessionTurnComplete` (delegated to
 *     `handlePersistentGoalPostTurn`)
 *
 * Concentrating it here gives the rest of `AgentService` a cleaner surface
 * (one collaborator instead of five methods) and makes the goal runtime
 * unit-testable in isolation.
 */
import type { Config } from '../../config/schema.js';
import type { MessageBus } from '../../infra/bus/index.js';
import type { ModelManager } from '../models/index.js';
import type { SessionStore } from '../../session/store.js';
import type { SessionStateBag } from '../session/index.js';
import type { PersistentGoalApis } from './persistent-goal-apis.js';
export interface PersistentGoalRouting {
    sessionKey: string;
    channel: string;
    chatId: string;
    inboundMetadata?: Record<string, unknown>;
}
export interface SessionTurnCompletionForGoal {
    sessionKey: string;
    channel: string;
    chatId: string;
    assistantPlainText: string;
    aborted: boolean;
    streamError?: string;
    skipPersistentGoalPostTurn?: boolean;
    outboundMetadata?: Record<string, unknown>;
}
export interface PersistentGoalServiceOptions {
    bus: MessageBus;
    sessionStore: SessionStore;
    modelManager: ModelManager;
    sessionState: SessionStateBag;
    /** Effective config snapshot accessor. */
    getConfig: () => Config | undefined;
    /** Resolve the workspace directory for `appendAssistantReceipt` writes. */
    getResolvedWorkspaceForSession: (sessionKey: string) => string;
    /** Notify the gateway UI after a metadata change (replaces the in-bag emit). */
    onSessionMetadataUpdated?: (sessionKey: string) => void;
    /** Push an assistant token + transcript refresh into a live webchat stream. */
    notifyWebchatTranscriptAppend: (sessionKey: string, assistantText: string) => void;
}
export declare class PersistentGoalService {
    private readonly opts;
    /** Gateway only: webchat continuations bypass the bus and reuse `runGatewayAgent`. */
    private webchatContinuationScheduler?;
    constructor(opts: PersistentGoalServiceOptions);
    /** Register the gateway-side webchat continuation hook (set from `web-agent` wiring). */
    setWebchatContinuationScheduler(fn: ((sessionKey: string, message: string) => void) | undefined): void;
    /**
     * Continue a session after `/goal` decides the previous turn needs follow-up.
     * Webchat sessions go through the scheduler; bus-driven channels re-publish the
     * follow-up message as an inbound bus event so the existing inbound loop picks it up.
     */
    scheduleContinuation(sessionKey: string, message: string, routing: {
        channel: string;
        chatId: string;
        inboundMetadata?: Record<string, unknown>;
    }): void;
    /** Build the per-command `PersistentGoalApis` bag (transcript writers + scheduler closures). */
    buildApisForRouting(routing: PersistentGoalRouting): PersistentGoalApis;
    recordStreamOutcome(sessionKey: string, outcome: {
        skipPersistentGoalPostTurn: boolean;
    }): void;
    takeStreamOutcome(sessionKey: string): {
        skipPersistentGoalPostTurn: boolean;
    } | undefined;
    /**
     * Run the `/goal` post-turn verdict for a completed user turn (called from
     * `OutboundCoordinator.emitSessionTurnComplete`).
     */
    runPostTurn(payload: SessionTurnCompletionForGoal): Promise<void>;
}
