import * as i0 from '@angular/core';
import { InjectionToken, Signal, ResourceStatus as ResourceStatus$1, Provider, WritableSignal } from '@angular/core';
import { BaseMessage, AIMessage } from '@langchain/core/messages';
import * as _langchain_langgraph_sdk from '@langchain/langgraph-sdk';
import { Config, Checkpoint, Command, Metadata, StreamMode, Run, ThreadState, BagTemplate, Interrupt, ToolCallWithResult, ToolProgress, Client } from '@langchain/langgraph-sdk';
export { BagTemplate, InferBag, Interrupt, ThreadState } from '@langchain/langgraph-sdk';
import { AgentErrorKind, AgentRuntimeTelemetrySink, AgentWithHistory, AgentInterrupt, AgentSubmitInput, AgentSubmitOptions, ClientToolsCapability, AgentRef, Message, AgentStatus, AgentError, ToolCall, Subagent, AgentCheckpoint, MockAgent, MockAgentOptions, Citation, Thread } from '@threadplane/chat';
import { MessageMetadata } from '@langchain/langgraph-sdk/ui';
export { SubmitOptions } from '@langchain/langgraph-sdk/ui';
import { FakeAgentConfig } from '@threadplane/chat/testing';

interface AgentLifecycle {
    /** Epoch ms of the first stream chunk arrival. Resets on switchThread(). */
    readonly streamStartedAt: Signal<number | null>;
    /**
     * Epoch ms + failure class of the most recent stream error. Resets on switchThread().
     *
     * `kind` is the {@link AgentErrorKind} of the normalized `AgentError`
     * (`connection` | `auth` | `server` | `interrupted` | `aborted`) — the same
     * value `agent.error()?.kind` carries. For a failure the runtime could not
     * normalize it falls back to the error's constructor name.
     */
    readonly streamErrorAt: Signal<{
        at: number;
        kind: AgentErrorKind | string;
    } | null>;
    /** Epoch ms of the first interrupt$ non-null in this stream. Resets on switchThread(). */
    readonly interruptReceivedAt: Signal<number | null>;
    /** Epoch ms of the most recent submit({ resume }) call. Resets on switchThread(). */
    readonly interruptResolvedAt: Signal<number | null>;
    /** Epoch ms when the agent's "create new thread" branch fired. Resets on switchThread(). */
    readonly threadCreatedAt: Signal<number | null>;
    /** Epoch ms when an existing thread was restored from server (proves persistence). Resets on switchThread(). */
    readonly threadPersistedAt: Signal<number | null>;
    /** Epoch ms of the first tool call append. Resets on switchThread(). */
    readonly toolCallStartedAt: Signal<number | null>;
    /** Epoch ms of the first tool call result transition. Resets on switchThread(). */
    readonly toolCallCompletedAt: Signal<number | null>;
}
declare const AGENT_LIFECYCLE: InjectionToken<AgentLifecycle>;

type OwnedCheckpointPosition = {
    readonly thread_id: string;
    readonly checkpoint_ns: '';
    readonly checkpoint_id: string;
    readonly checkpoint_map: Readonly<Record<string, string>>;
};

/** An event emitted by a LangGraph stream. */
interface StreamEvent {
    /** Event type identifier (e.g., 'values', 'messages', 'error', 'interrupt'). */
    type: 'values' | `values|${string}` | 'messages' | `messages|${string}` | `messages/${string}` | `messages/${string}|${string}` | 'updates' | `updates|${string}` | 'tools' | `tools|${string}` | 'custom' | `custom|${string}` | 'error' | `error|${string}` | 'metadata' | 'checkpoints' | `checkpoints|${string}` | 'tasks' | `tasks|${string}` | 'debug' | `debug|${string}` | 'events' | `events|${string}` | 'interrupt' | 'interrupts';
    /** @internal Reserved SDK SSE cursor; application payloads cannot supply it. */
    sseId?: string;
    namespace?: string[];
    messages?: unknown[];
    messageMetadata?: Record<string, unknown>;
    [key: string]: unknown;
}
/** Strategy for handling concurrent LangGraph runs on the same thread. */
type LangGraphMultitaskStrategy = 'reject' | 'interrupt' | 'rollback' | 'enqueue';
type LangGraphDurability = 'exit' | 'async' | 'sync';
type LangGraphOnCompletion = 'complete' | 'continue';
type LangGraphOnDisconnect = 'cancel' | 'continue';
/** Options accepted by LangGraph-backed submit calls. */
interface LangGraphSubmitOptions {
    signal?: AbortSignal;
    config?: Config;
    context?: unknown;
    checkpoint?: Omit<Checkpoint, 'thread_id'> | null;
    checkpointId?: string;
    command?: Command;
    metadata?: Metadata;
    checkpointDuring?: boolean;
    durability?: LangGraphDurability;
    interruptBefore?: '*' | string[];
    interruptAfter?: '*' | string[];
    onCompletion?: LangGraphOnCompletion;
    webhook?: string;
    onDisconnect?: LangGraphOnDisconnect;
    afterSeconds?: number;
    ifNotExists?: 'create' | 'reject';
    onRunCreated?: (params: {
        run_id: string;
        thread_id?: string;
    }) => void;
    streamMode?: StreamMode[];
    streamSubgraphs?: boolean;
    streamResumable?: boolean;
    feedbackKeys?: string[];
    /** Convenience alias normalized to `command.resume` before invoking LangGraph. */
    resume?: unknown;
    /** Strategy for handling concurrent runs on the same thread. */
    multitaskStrategy?: LangGraphMultitaskStrategy;
}
/** A queued server-side LangGraph run. */
interface AgentQueueEntry<T = unknown> {
    /** Server-side run ID. */
    id: string;
    /** Thread that owns the queued run. */
    threadId: string;
    /** Values submitted for the queued run. */
    values: T | null | undefined;
    /** Submit options used when the queued run was created. */
    options?: LangGraphSubmitOptions;
    /** Timestamp when the queued run was registered locally. */
    createdAt: Date;
}
/** Public queue surface for pending server-side LangGraph runs. */
interface AgentQueue<T = unknown> {
    /** Read-only pending queue entries. */
    readonly entries: ReadonlyArray<AgentQueueEntry<T>>;
    /** Number of pending queue entries. */
    readonly size: number;
    /** Cancel a specific pending run by server run ID. */
    cancel: (id: string) => Promise<boolean>;
    /** Cancel all pending runs and clear the queue. */
    clear: () => Promise<void>;
}
/** Transport interface for connecting to a LangGraph agent. */
interface AgentTransport {
    /** Open a streaming connection to an agent and yield events. */
    stream(assistantId: string, threadId: string | null, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
    /** Optional: join an already-started run without creating a new one. */
    joinStream?(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal, options?: {
        streamMode?: StreamMode[];
    }): AsyncIterable<StreamEvent>;
    /** @internal Inspect the exact owned physical run, without thread-history inference. */
    getRunStatus?(threadId: string, runId: string, signal: AbortSignal): Promise<Run['status']>;
    /** Optional: create a server-side queued run without joining it immediately. */
    createQueuedRun?(assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise<AgentQueueEntry>;
    /** Optional: cancel a server-side run. */
    cancelRun?(threadId: string, runId: string, signal: AbortSignal): Promise<void>;
    /** Optional: load persisted checkpoint history for a thread. */
    getHistory?(threadId: string, signal: AbortSignal): Promise<ThreadState[]>;
    /**
     * Optional: read the newest checkpoint a child graph saved under one
     * checkpoint namespace of a thread (for a delegation tool call, `tools:<task
     * id>`). Used to restore a subagent's transcript when a thread is reloaded;
     * without it, a reloaded subagent shows its status and result but no
     * messages. Resolve `undefined` when the namespace has no saved state.
     */
    getChildState?(threadId: string, checkpointNs: string, signal: AbortSignal): Promise<ThreadState | undefined>;
    /** Exact saved root read. Branch effects must not infer authority from latest. */
    getState?(threadId: string, checkpoint: OwnedCheckpointPosition, signal: AbortSignal): Promise<ThreadState>;
    /**
     * Optional: update server-side thread state (e.g. to emit RemoveMessage
     * entries for regenerate rollback). Forwards to the LangGraph
     * `threads.updateState` API.
     *
     * `options.asNode` corresponds to LangGraph's `as_node` parameter — the
     * server treats the update as if that node had just produced the values,
     * which determines what the next pull resumes. `regenerate()` passes
     * `asNode: '__start__'` so the next `submit(null)` resumes at the entry
     * node and re-runs `generate` against the rolled-back state.
     */
    updateState?(threadId: string, values: Record<string, unknown>, signal: AbortSignal, options?: {
        asNode?: string;
        checkpoint?: OwnedCheckpointPosition;
    }): Promise<void | OwnedCheckpointPosition>;
}
/**
 * Tuning options for the underlying LangGraph SDK `Client` constructed by the
 * default {@link FetchStreamTransport}. Ignored when a custom `transport` is
 * supplied (the transport owns its own client).
 */
interface LangGraphClientOptions {
    /**
     * Headers attached to every request the SDK client makes, including the run
     * stream. Use this for a per-user session token that your LangGraph
     * deployment's custom `authenticate` handler validates.
     *
     * There is deliberately no `apiKey` option: a deployment credential passed
     * from Angular is bundled into the browser build like any other constant.
     * Keep deployment keys on a same-origin proxy or gateway you own, and point
     * `apiUrl` at it. The client is constructed with `apiKey: null`, so the SDK
     * never attaches a key from the environment either.
     */
    defaultHeaders?: Record<string, string>;
    /**
     * How many times a failed request — including the initial stream connect —
     * is retried with exponential backoff before the error surfaces. Maps to the
     * SDK's `callerOptions.maxRetries`. Omitted → the SDK default (currently 4).
     *
     * Set `0` to fail fast: useful for e2e tests that force a connection failure
     * and assert the error surfaces promptly, rather than after the full
     * multi-second backoff window.
     */
    maxRetries?: number;
}

/**
 * Runtime constant mirroring Angular's ResourceStatus string-union type.
 * Angular 21 ships ResourceStatus as a pure string-union type (no runtime value),
 * so we provide a const-object shim for code that needs runtime comparisons.
 */
declare const ResourceStatus: {
    readonly Idle: "idle";
    readonly Loading: "loading";
    readonly Reloading: "reloading";
    readonly Resolved: "resolved";
    readonly Error: "error";
    readonly Local: "local";
};
type ResourceStatus = ResourceStatus$1;
/** A checkpoint entry in the experimental branch tree. */
interface AgentBranchTreeNode<T = unknown> {
    type: 'node';
    value: ThreadState<T>;
    path: string[];
}
/** A branch fork where each item is an alternate checkpoint sequence. */
interface AgentBranchTreeFork<T = unknown> {
    type: 'fork';
    items: AgentBranchTree<T>[];
}
/** Tree representation of LangGraph checkpoint history for time-travel UIs. */
interface AgentBranchTree<T = unknown> {
    type: 'sequence';
    items: Array<AgentBranchTreeNode<T> | AgentBranchTreeFork<T>>;
}
/** A custom event emitted by the LangGraph backend via adispatch_custom_event(). */
interface CustomStreamEvent {
    /** Event name set by the backend (e.g., 'state_update'). */
    name: string;
    /** Arbitrary payload from the backend. */
    data: unknown;
}
/** Options for creating a LangGraph-backed agent via {@link agent}. */
interface AgentOptions<T, _ResolvedBag extends BagTemplate> {
    /** Base URL of the LangGraph Platform API. Defaults to `provideAgent({ apiUrl })` when omitted. */
    apiUrl?: string;
    /** Agent or graph identifier on the LangGraph platform. */
    assistantId: string;
    /** Thread ID to connect to. Pass a Signal for reactive thread switching. */
    threadId?: Signal<string | null> | string | null;
    /** Called when a new thread is auto-created by the transport. */
    onThreadId?: (id: string) => void;
    /** Initial state values before the first stream response arrives. */
    initialValues?: Partial<T>;
    /** Throttle signal updates in milliseconds. `false` to disable. */
    throttle?: number | false;
    /** Custom message deserializer for non-standard message formats. */
    toMessage?: (msg: unknown) => BaseMessage;
    /**
     * Custom transport. Defaults to FetchStreamTransport.
     *
     * A custom transport owns its own thread creation, so the runtime cannot
     * observe it directly: report every thread id the transport creates through
     * this config's {@link AgentOptions.onThreadId} or through the `threadId`
     * signal, otherwise the runtime keeps sending `null` and a new thread is
     * created on each submit.
     */
    transport?: AgentTransport;
    /** Tuning options for the default transport's LangGraph SDK client (e.g. retry budget). */
    clientOptions?: LangGraphClientOptions;
    /**
     * Omit to enable automatic development-only collection. Set `false` to disable.
     * An app-owned sink replaces the automatic destination and receives the
     * existing runtime lifecycle callbacks.
     */
    telemetry?: AgentRuntimeTelemetrySink | false;
    /** Tool names that indicate a subagent invocation. */
    subagentToolNames?: string[];
    /**
     * A2UI client capabilities (catalog negotiation) to advertise to the graph.
     * When set, every plain-object run payload carries them under the
     * `a2ui_client_capabilities` state key — mirroring how `client_tools`
     * rides the payload. Read server-side via threadplane-middleware's
     * `a2ui_client_capabilities(state)`. Use `@threadplane/chat`'s
     * `a2uiClientCapabilities()` for the renderer's standard value.
     */
    a2uiClientCapabilities?: {
        supportedCatalogIds: string[];
        inlineCatalogs?: unknown[];
    };
    /**
     * LangGraph node names whose `messages-tuple` LLM chunks should be projected
     * into the main chat transcript. Omit to accept all top-level message chunks.
     * Child-graph (namespaced) chunks never reach the transcript regardless of
     * this option — they belong to their child stream in `subagents()`.
     *
     * Use this when a graph has side-effect LLM nodes, such as title generation,
     * whose streamed model output should not render as assistant chat content.
     */
    transcriptNodeNames?: string[];
}
/** Reference to a subagent's streaming state. */
interface SubagentStreamRef {
    /** The tool call ID that spawned this subagent. */
    toolCallId: string;
    /** Optional human-readable subagent type/name. */
    name?: string;
    /** Current execution status of the subagent. */
    status: Signal<'pending' | 'running' | 'complete' | 'error'>;
    /** Current state values from the subagent. */
    values: Signal<Record<string, unknown>>;
    /** Messages from the subagent conversation. */
    messages: Signal<BaseMessage[]>;
}
/**
 * Unified LangGraph agent surface returned by `injectAgent()`.
 *
 * Extends the runtime-neutral `AgentWithHistory` contract (chat-consumable)
 * with the full LangGraph-specific API. One object drives both `<chat>` and
 * any LangGraph-specific demo. Raw LangGraph signals are prefixed with
 * `langGraph` to avoid collision with the runtime-neutral names.
 */
interface LangGraphAgent<T = unknown, ResolvedBag extends BagTemplate = BagTemplate> extends AgentWithHistory<T> {
    /**
     * Current human-in-the-loop pause, or `undefined` when the run is not paused.
     *
     * Narrowed from the neutral `Agent` contract, where `interrupt` is optional
     * because a runtime without human-in-the-loop support omits it. The LangGraph
     * adapter always provides it, so `injectAgent().interrupt()` type-checks
     * directly under `strictNullChecks` — no `?.()` needed.
     */
    interrupt: Signal<AgentInterrupt | undefined>;
    /** Raw LangChain BaseMessage list. Use `messages` for chat rendering. */
    langGraphMessages: Signal<BaseMessage[]>;
    /** All interrupts received during the current run (raw LangGraph shape). */
    langGraphInterrupts: Signal<Interrupt<ResolvedBag['InterruptType']>[]>;
    /** Raw LangGraph tool calls (with run-state). Use `toolCalls` for chat rendering. */
    langGraphToolCalls: Signal<ToolCallWithResult[]>;
    /** Raw LangGraph history (ThreadState[]). Use `history` for AgentCheckpoint[]. */
    langGraphHistory: Signal<ThreadState<T>[]>;
    /** Experimental branch tree derived from LangGraph checkpoint history. */
    experimentalBranchTree: Signal<AgentBranchTree<T>>;
    /** Submit input, resume commands, checkpoint forks, or other LangGraph run options. */
    submit: (input: AgentSubmitInput | null | undefined, opts?: AgentSubmitOptions & LangGraphSubmitOptions) => Promise<void>;
    /**
     * Client-declared, client-executed tools. Call setCatalog() to register
     * tool specs; the catalog is automatically shipped with every run via
     * `input.client_tools`. Pending tool calls appear in pending() after
     * the run ends; resolve() returns a result and continues the run.
     */
    clientTools: ClientToolsCapability;
    /** Current agent state values (raw, typed per the type parameter T). */
    value: Signal<T>;
    /** True once at least one value or message has been received. */
    hasValue: Signal<boolean>;
    /** Re-submit the last input to restart the stream. */
    reload: () => void;
    /**
     * Discards the assistant message at the given index AND all messages after
     * it, then re-runs the agent against the trimmed conversation tail. The
     * preceding user message (at index - 1) is preserved and re-submitted as
     * the agent's input. No new user message is added to the history.
     *
     * Throws if the message at `index` is not 'assistant' role, or if the
     * agent is currently loading another response.
     */
    regenerate: (assistantMessageIndex: number) => Promise<void>;
    /** Progress updates for currently executing tools. */
    toolProgress: Signal<ToolProgress[]>;
    /** Pending server-side runs created via `multitaskStrategy: 'enqueue'`. */
    queue: Signal<AgentQueue>;
    /** Filtered list of subagents with status 'running'. */
    activeSubagents: Signal<SubagentStreamRef[]>;
    /** Get a subagent stream by the tool call ID that spawned it. */
    getSubagent: (toolCallId: string) => SubagentStreamRef | undefined;
    /** Get subagent streams by their configured subagent type/name. */
    getSubagentsByType: (type: string) => SubagentStreamRef[];
    /** Get subagent streams spawned by the tool calls on a specific AI message. */
    getSubagentsByMessage: (msg: AIMessage) => SubagentStreamRef[];
    /** Raw custom events stream (signal of array). The runtime-neutral
     *  `events$` Observable is derived from this. */
    customEvents: Signal<CustomStreamEvent[]>;
    /** Current branch identifier for time-travel navigation. */
    branch: Signal<string>;
    /** Set the active branch for time-travel navigation. */
    setBranch: (branch: string) => void;
    /** True while a thread switch is loading state from the server. */
    isThreadLoading: Signal<boolean>;
    /** Switch to a different thread, resetting derived state. */
    switchThread: (threadId: string | null) => void;
    /** Join an already-running stream by run ID. */
    joinStream: (runId: string, lastEventId?: string) => Promise<void>;
    /** Get metadata for a specific message by index. */
    getMessagesMetadata: (msg: BaseMessage, idx?: number) => MessageMetadata<Record<string, unknown>> | undefined;
    /** Get tool call results associated with an AI message (LangGraph types). */
    getToolCalls: (msg: AIMessage) => ToolCallWithResult[];
    /**
     * Lifecycle signals for observability/telemetry. Eight read-only signals
     * capture key transitions (first stream chunk, first interrupt, tool
     * call start/complete, thread create/persist, errors). All reset on
     * `switchThread()`. See {@link AgentLifecycle}.
     */
    lifecycle: AgentLifecycle;
}

/**
 * Configuration for an agent instance.
 * Combines connection defaults with per-component options so the
 * agent can be constructed once at provider time and injected
 * everywhere it is needed.
 */
interface AgentConfig<T = Record<string, unknown>, _Bag extends BagTemplate = BagTemplate> {
    /** Base URL of the LangGraph Platform API (e.g., `'http://localhost:2024'`). */
    apiUrl?: string;
    /** Agent or graph identifier on the LangGraph platform. */
    assistantId?: string;
    /** Thread ID to connect to. Pass a Signal for reactive thread switching. */
    threadId?: Signal<string | null> | string | null;
    /** Called when a new thread is auto-created by the transport. */
    onThreadId?: (id: string) => void;
    /** Initial state values before the first stream response arrives. */
    initialValues?: Partial<T>;
    /** Throttle signal updates in milliseconds. `false` to disable. */
    throttle?: number | false;
    /** Custom message deserializer for non-standard message formats. */
    toMessage?: (msg: unknown) => BaseMessage;
    /**
     * Custom transport. Defaults to {@link FetchStreamTransport}.
     *
     * A custom transport owns its own thread creation, so the runtime cannot
     * observe it directly: report every thread id the transport creates through
     * {@link AgentConfig.onThreadId} or through the `threadId` signal, otherwise
     * the runtime keeps sending `null` and a new thread is created on each submit.
     */
    transport?: AgentTransport;
    /** Tuning options for the default transport's LangGraph SDK client (e.g. retry budget). */
    clientOptions?: LangGraphClientOptions;
    /**
     * Omit to enable automatic development-only collection. Set `false` to disable.
     * An app-owned sink replaces the automatic destination and receives the
     * existing runtime lifecycle callbacks.
     */
    telemetry?: AgentRuntimeTelemetrySink | false;
    /** Tool names that indicate a subagent invocation. */
    subagentToolNames?: string[];
    /**
     * LangGraph node names whose `messages-tuple` LLM chunks should be projected
     * into the main chat transcript. Omit to accept all top-level message chunks.
     * Child-graph (namespaced) chunks never reach the transcript regardless of
     * this option — they belong to their child stream in `subagents()`.
     */
    transcriptNodeNames?: string[];
}
/**
 * Wire the LangGraph adapter into Angular's dependency injection.
 *
 * Registers a singleton `LangGraphAgent` constructed from `config`. Retrieve it
 * in any component with `injectAgent()`. Provide this at the application root
 * (`app.config.ts`) for an app-wide agent.
 *
 * To use a different agent in a component subtree, re-provide
 * `provideAgent({...})` in that component's `providers: []` array —
 * Angular's hierarchical DI scopes the singleton accordingly.
 *
 * **Static vs factory config.** Pass a plain `AgentConfig` object when the
 * config is known up front. Pass a `() => AgentConfig` factory when the config
 * depends on runtime/DI state — the factory runs inside an Angular injection
 * context, so it may call `inject()` to read services, route params, or
 * component-scoped signals.
 *
 * **Typed state via AgentRef.** Pass a typed ref as the first argument to flow
 * the state shape from `provideAgent` to `injectAgent` without repeating the
 * generic at every call site.
 *
 * **Several agents at one injector level.** Each `provideAgent(ref, …)` call
 * builds its own agent from its own config, so two (or more) refs may be
 * provided side by side in a single `providers` array and `injectAgent(refA)`
 * / `injectAgent(refB)` return distinct agents. The ref-less `injectAgent()`
 * resolves a single shared token, which can only point at one of them: when
 * more than one ref is provided at the same level the **last** call wins, and
 * resolving it in dev mode logs a `console.warn` naming every competing ref.
 * The `AGENT_LIFECYCLE` token follows the same rule. Always inject by ref when
 * an injector provides more than one agent.
 *
 * **Lifecycle token.** Every form also provides `AGENT_LIFECYCLE`, so
 * `inject(AGENT_LIFECYCLE)` returns the same object as `injectAgent().lifecycle`
 * without reaching for the agent itself.
 *
 * @example Two agents in one providers array
 * ```ts
 * export const LIVE = createAgentRef<ChatState>('live');
 * export const REPLAY = createAgentRef<ChatState>('replay');
 * providers: [
 *   provideAgent(LIVE, { assistantId: 'chat' }),
 *   provideAgent(REPLAY, { assistantId: 'chat', transport: replayTransport }),
 * ];
 * // component: injectAgent(LIVE) !== injectAgent(REPLAY)
 * ```
 * @example Factory config reading route params
 * ```ts
 * providers: [
 *   provideAgent(() => {
 *     const route = inject(ActivatedRoute);
 *     return { assistantId: 'chat', threadId: toSignal(route.paramMap) };
 *   }),
 * ];
 * ```
 * @example Typed state via AgentRef
 * ```ts
 * export const TRIP = createAgentRef<TripState>('trip');
 * // app.config.ts:
 * providers: [provideAgent(TRIP, { assistantId: 'trip-graph' })]
 * // component:
 * const agent = injectAgent(TRIP); // LangGraphAgent<TripState>
 * ```
 */
declare function provideAgent<T = Record<string, unknown>>(ref: AgentRef<T>, configOrFactory: AgentConfig<T> | (() => AgentConfig<T>)): Provider[];
declare function provideAgent<T = Record<string, unknown>>(configOrFactory: AgentConfig<T> | (() => AgentConfig<T>)): Provider[];

/**
 * Retrieve the LangGraph-backed Agent from the current Angular injection context.
 *
 * Mirrors `@threadplane/ag-ui`'s `injectAgent()` so consumer code is identical
 * regardless of which adapter is wired in `app.config.ts`. The agent is a
 * singleton scoped to the injector that called `provideAgent()` — re-provide
 * in a child component's `providers: []` to scope a different agent to that
 * subtree (Angular's hierarchical DI handles the rest).
 *
 * **Typed state via AgentRef.** Pass the same ref that was supplied to
 * `provideAgent(ref, …)` to carry the state type through DI without repeating
 * the generic at every call site. The no-arg form defaults to
 * `LangGraphAgent<Record<string, unknown>>`.
 *
 * @example Typed state via AgentRef
 * ```ts
 * const agent = injectAgent(TRIP); // LangGraphAgent<TripState>
 * ```
 */
declare function injectAgent(): LangGraphAgent<Record<string, unknown>>;
declare function injectAgent<T, ResolvedBag extends BagTemplate = BagTemplate>(ref: AgentRef<T>): LangGraphAgent<T, ResolvedBag>;

/**
 * Application-wide registry of every live agent's {@link AgentLifecycle}.
 *
 * It is `providedIn: 'root'`, so it always exists and every agent registers
 * into the same instance regardless of which injector built it — an agent
 * created in a route or component injector is still visible from the root.
 * External instrumentation packages read `lifecycles()` to observe every agent
 * in the application without owning the provider graph.
 *
 * Registration is scoped to the agent's lifetime: an agent unregisters when the
 * injector that created it is destroyed, so `lifecycles()` never accumulates
 * lifecycles for agents that are gone.
 */
declare class AgentLifecycleRegistry {
    private readonly _lifecycles;
    /** Reactive list of the lifecycles of every currently live agent. */
    readonly lifecycles: Signal<readonly AgentLifecycle[]>;
    register(lifecycle: AgentLifecycle): void;
    /** Drop a lifecycle when its agent's injector is destroyed. */
    unregister(lifecycle: AgentLifecycle): void;
    static ɵfac: i0.ɵɵFactoryDeclaration<AgentLifecycleRegistry, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<AgentLifecycleRegistry>;
}

/**
 * Test transport for deterministic agent testing without a real LangGraph server.
 *
 * Script event batches upfront, then emit them manually or step through them
 * in your test specs. Supports error injection and close control.
 *
 * `emit()`, `emitError()`, `close()` and `flush()` are awaitable: the returned
 * promise settles once the adapter has consumed everything queued so far (and
 * one macrotask later, so throttled signal writes have landed), which removes
 * the hand-rolled `await new Promise(resolve => setTimeout(resolve, 0))` flush
 * from specs.
 *
 * @example
 * ```typescript
 * const transport = new MockAgentTransport([
 *   [{ type: 'values', messages: [aiMsg('Hello')] }],
 *   [{ type: 'values', messages: [aiMsg('Done')] }],
 * ]);
 * await transport.emit(transport.nextBatch());
 * ```
 */
declare class MockAgentTransport implements AgentTransport {
    history: ThreadState[];
    /** Child-namespace checkpoints served by `getChildState`, keyed by checkpoint namespace. */
    childStates: Map<string, ThreadState<_langchain_langgraph_sdk.DefaultValues>>;
    readonly childStateCalls: Array<{
        threadId: string;
        checkpointNs: string;
    }>;
    readonly historyCalls: string[];
    readonly streams: Array<{
        threadId: string | null;
        payload: unknown;
        options?: LangGraphSubmitOptions;
    }>;
    readonly createdQueuedRuns: AgentQueueEntry[];
    readonly cancelledRuns: Array<{
        threadId: string;
        runId: string;
    }>;
    readonly joinedRuns: Array<{
        threadId: string;
        runId: string;
    }>;
    private script;
    private scriptIndex;
    private streaming;
    private eventQueue;
    private resolvers;
    private consumers;
    private closed;
    private pendingError;
    /** True while the stream loop is suspended with an empty queue. */
    private idle;
    /** True once a stream run has ended (or before any run has started). */
    private finished;
    /** @param script - Array of event batches. Each batch is emitted as a group. */
    constructor(script?: StreamEvent[][]);
    /** Advance to the next scripted batch. Pass the returned events to `emit()`. */
    nextBatch(): StreamEvent[];
    /**
     * Manually emit events into the stream.
     *
     * Await the returned promise: it resolves once the adapter has pulled this
     * batch out of the stream (or the run has ended), so signals are settled and
     * assertions read live state rather than the value from before the emit.
     */
    emit(events: StreamEvent[]): Promise<void>;
    /** Inject an error into the stream. Resolves once the stream has thrown. */
    emitError(err: Error): Promise<void>;
    /**
     * Close the stream. Remaining queued events are drained before completion.
     * Resolves once the run has finished.
     */
    close(): Promise<void>;
    /**
     * Resolve once everything emitted so far has been consumed, without emitting
     * anything new. Useful after driving the agent by some other route (a
     * `submit()`, a `switchThread()`) that has to reach the transport first.
     */
    flush(): Promise<void>;
    /** Returns true if a stream is currently active. */
    isStreaming(): boolean;
    stream(_assistantId: string, _threadId: string | null, _payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
    createQueuedRun(_assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise<AgentQueueEntry>;
    cancelRun(threadId: string, runId: string, signal: AbortSignal): Promise<void>;
    getHistory(threadId: string, signal: AbortSignal): Promise<ThreadState[]>;
    getChildState(threadId: string, checkpointNs: string, signal: AbortSignal): Promise<ThreadState | undefined>;
    joinStream(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal): AsyncIterable<StreamEvent>;
    /** Rouse the suspended stream loop so it re-checks queue/error/closed state. */
    private wake;
    /**
     * A promise for "everything queued right now has been consumed". Resolved on
     * a macrotask so throttled signal writes inside the adapter have landed.
     */
    private consumed;
    private settleConsumers;
}

type RuntimeOperationFailureReporter = (code: 'unauthorized' | 'network_blocked') => void;

/**
 * Production transport that connects to a LangGraph Platform API via HTTP and SSE.
 *
 * Creates threads automatically if no threadId is provided, and streams events
 * using the LangGraph SDK client.
 *
 * @example
 * ```typescript
 * const transport = new FetchStreamTransport(
 *   'http://localhost:2024',
 *   (id) => console.log('New thread:', id),
 * );
 * ```
 */
declare class FetchStreamTransport implements AgentTransport {
    private client;
    private onThreadId?;
    private readonly protectErrors;
    private readonly reportOperationFailure?;
    /** @internal True only when this adapter installed its SDK error boundary. */
    readonly protectsOperationErrors: boolean;
    /**
     * @param apiUrl - Base URL of the LangGraph Platform API
     * @param onThreadId - Optional callback invoked when a new thread is created
     * @param clientOptions - Optional SDK client tuning (e.g. `maxRetries`)
     */
    constructor(apiUrl: string, onThreadId?: (id: string) => void, clientOptions?: LangGraphClientOptions, 
    /** @internal Cockpit generation-bound failure reporting hook. */
    reportOperationFailure?: RuntimeOperationFailureReporter);
    /** Open a streaming connection, creating a thread if needed. */
    stream(assistantId: string, threadId: string | null, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
    /** Join an already-started run without creating a new thread. */
    joinStream(threadId: string, runId: string, lastEventId: string | undefined, signal: AbortSignal, options?: {
        streamMode?: StreamMode[];
    }): AsyncIterable<StreamEvent>;
    /** @internal Exact-run inspection for the private owned reconnect command. */
    getRunStatus(threadId: string, runId: string, signal: AbortSignal): Promise<Run['status']>;
    /** Create a pending server-side run using LangGraph's enqueue strategy. */
    createQueuedRun(assistantId: string, threadId: string, payload: unknown, signal: AbortSignal, options?: LangGraphSubmitOptions): Promise<AgentQueueEntry>;
    /** Cancel a server-side run. */
    cancelRun(threadId: string, runId: string, signal: AbortSignal): Promise<void>;
    /** Load persisted checkpoint history for a thread. */
    getHistory(threadId: string, signal: AbortSignal): Promise<ThreadState[]>;
    /** Read the newest checkpoint saved under one child checkpoint namespace. */
    getChildState(threadId: string, checkpointNs: string, signal: AbortSignal): Promise<ThreadState | undefined>;
    /** Read one exact saved checkpoint with the command's cancellation signal. */
    getState(threadId: string, checkpoint: OwnedCheckpointPosition, signal: AbortSignal): Promise<ThreadState>;
    /** Update state once and return only usable root routing, when supplied. */
    updateState(threadId: string, values: Record<string, unknown>, signal: AbortSignal, options?: {
        asNode?: string;
        checkpoint?: OwnedCheckpointPosition;
    }): Promise<void | OwnedCheckpointPosition>;
    private rethrowOperationError;
    private rethrowLocalError;
    private iterateSdkRun;
}

/**
 * A LangGraphAgent mock with writable signals for easy test control.
 *
 * Builds on the runtime-neutral {@link MockAgent} from `@threadplane/chat`
 * (which supplies the neutral `Agent`-contract writable signals plus
 * `submit`/`stop`/`regenerate` call tracking) and layers the LangGraph-specific
 * writable signals on top.
 *
 * Cast the result of `mockLangGraphAgent()` to this type to access
 * writable signals without unsafe casts in test files.
 */
interface MockLangGraphAgent extends LangGraphAgent<any, any> {
    messages: WritableSignal<Message[]>;
    status: WritableSignal<AgentStatus>;
    isLoading: WritableSignal<boolean>;
    error: WritableSignal<AgentError | undefined>;
    toolCalls: WritableSignal<ToolCall[]>;
    interrupt: WritableSignal<AgentInterrupt | undefined>;
    subagents: WritableSignal<Map<string, Subagent>>;
    history: WritableSignal<AgentCheckpoint[]>;
    submitCalls: MockAgent['submitCalls'];
    stopCount: MockAgent['stopCount'];
    _internal: MockAgent['_internal'];
    langGraphMessages: WritableSignal<BaseMessage[]>;
    hasValue: WritableSignal<boolean>;
    value: WritableSignal<any>;
    langGraphInterrupts: WritableSignal<Interrupt<any>[]>;
    langGraphToolCalls: WritableSignal<ToolCallWithResult[]>;
    toolProgress: WritableSignal<ToolProgress[]>;
    queue: WritableSignal<AgentQueue>;
    branch: WritableSignal<string>;
    langGraphHistory: WritableSignal<ThreadState<any>[]>;
    experimentalBranchTree: WritableSignal<AgentBranchTree<any>>;
    isThreadLoading: WritableSignal<boolean>;
    activeSubagents: WritableSignal<SubagentStreamRef[]>;
    customEvents: WritableSignal<CustomStreamEvent[]>;
}
/**
 * Creates a mock LangGraphAgent with writable signals for testing.
 * Control state by writing to the returned writable signals directly.
 *
 * Neutral `Agent`-contract signals come from {@link mockAgent}; LangGraph-specific
 * signals are declared here and layered on top.
 *
 * @example
 * ```ts
 * const agent = mockLangGraphAgent({ isThreadLoading: true });
 * agent.messages.set([{ id: '1', role: 'assistant', content: 'Hi' }]);
 * ```
 */
declare function mockLangGraphAgent(initial?: MockAgentOptions & {
    langGraphMessages?: BaseMessage[];
    hasValue?: boolean;
    isThreadLoading?: boolean;
}): MockLangGraphAgent;

/**
 * Wire an in-process fake LangGraph agent into Angular DI.
 *
 * Streams a canned assistant reply (see FakeAgentConfig) with no backend —
 * the symmetric counterpart to @threadplane/ag-ui's provideFakeAgent(). For
 * advanced manual scripting (tool calls, interrupts, multi-batch), provide
 * the agent yourself with
 * `provideAgent({ assistantId, transport: new MockAgentTransport(...) })`.
 *
 * @example
 * ```ts
 * TestBed.configureTestingModule({
 *   providers: [provideFakeAgent({ tokens: ['Hi from the fake LangGraph agent'] })],
 * });
 * ```
 */
declare function provideFakeAgent(config?: FakeAgentConfig): Provider[];

/**
 * In-process AgentTransport that auto-streams a canned assistant reply.
 *
 * Backs `provideFakeAgent()`. Unlike `MockAgentTransport` (passive, driven
 * manually from specs), this transport emits its tokens automatically on
 * `stream()`, then completes — suitable for offline demos and integration tests.
 *
 * NOT for production use.
 */
declare class FakeStreamTransport implements AgentTransport {
    private readonly tokens;
    private readonly reasoningTokens;
    private readonly delayMs;
    constructor(config?: FakeAgentConfig);
    stream(_assistantId: string, _threadId: string | null, _payload: unknown, signal: AbortSignal, _options?: LangGraphSubmitOptions): AsyncIterable<StreamEvent>;
    createQueuedRun(_assistantId: string, threadId: string, payload: unknown, _signal: AbortSignal, options?: LangGraphSubmitOptions): Promise<AgentQueueEntry>;
    cancelRun(_threadId: string, _runId: string, _signal: AbortSignal): Promise<void>;
    getHistory(_threadId: string, _signal: AbortSignal): Promise<ThreadState[]>;
    joinStream(): AsyncIterable<StreamEvent>;
}

interface KwargsLike {
    additional_kwargs?: Record<string, unknown> | undefined;
}
/**
 * Normalize {@link Citation}s out of a message's `additional_kwargs` (reading
 * `citations` or `sources`). Exposed for advanced consumers building custom
 * adapters or bridging non-LangGraph message shapes into the neutral
 * `Citation[]` form.
 *
 * @param msg Any object with an `additional_kwargs` bag (e.g. a LangChain message).
 * @returns The normalized citations, or `undefined` when none are present.
 * @example
 * ```ts
 * const citations = extractCitations(lcMessage);
 * ```
 */
declare function extractCitations(msg: KwargsLike): Citation[] | undefined;

/**
 * Construct a LangGraph SDK Client that accepts both absolute URLs
 * (`http://localhost:2024`) and relative `/api`-style paths that get
 * proxied by middleware in production. The SDK itself rejects
 * relative URLs, so this helper rewrites them against
 * `window.location.origin` when running in the browser.
 *
 * Single source of truth for the absolute-URL rewrite — the streaming
 * transport (`fetch-stream.transport.ts`) and the threads adapter
 * (`LangGraphThreadsAdapter`) both go through here.
 *
 * `clientOptions.maxRetries` maps to the SDK's `callerOptions.maxRetries`,
 * which governs how many times a failed request (including the initial
 * stream connect) is retried with exponential backoff before the error
 * surfaces. Omitted → the SDK default (currently 4). Apps under test set
 * `0` so a forced connection failure surfaces immediately instead of after
 * the full backoff window.
 *
 * @example
 * ```ts
 * const client = createLangGraphClient(environment.langGraphApiUrl);
 * const threads = await client.threads.search({ limit: 50 });
 * ```
 */
declare function createLangGraphClient(apiUrl: string, clientOptions?: LangGraphClientOptions): Client;
/** Exported separately so non-Client callers (e.g. raw fetch) can
 *  share the same normalization logic. */
declare function toAbsoluteApiUrl(apiUrl: string): string;

/**
 * App-wide LangGraph SDK client tuning (e.g. `maxRetries`). Provide once at the
 * app root; both the agent's default {@link FetchStreamTransport} and the
 * {@link LangGraphThreadsAdapter} read it so the retry budget is configured in
 * one place. A call-site `agent({ clientOptions })` or per-agent
 * `provideAgent({ clientOptions })` overrides it for that agent.
 * Absent → the SDK default.
 */
declare const LANGGRAPH_CLIENT_OPTIONS: InjectionToken<LangGraphClientOptions>;

/** @internal Cockpit-only, generation-bound operation failure reporter. */
declare const ɵLANGGRAPH_RUNTIME_OPERATION_REPORTER: InjectionToken<RuntimeOperationFailureReporter>;

/**
 * Configuration consumed by {@link LangGraphThreadsAdapter}. Provide
 * via {@link LANGGRAPH_THREADS_CONFIG} (typically in app.config.ts):
 *
 * ```ts
 * providers: [
 *   { provide: LANGGRAPH_THREADS_CONFIG, useValue: {
 *       apiUrl: environment.langGraphApiUrl,
 *   }},
 * ],
 * ```
 *
 * The adapter expects backends to write the thread title to
 * `metadata.title`. Spec 2026-05-19-llm-generated-labels-design.md
 * originally proposed `metadata.thread_title` for cockpit caps but
 * we converged on `title` to match the canonical demo and avoid a
 * per-cap configuration knob.
 */
interface LangGraphThreadsConfig {
    /** Base URL for the LangGraph Platform API. Accepts both absolute
     *  URLs and relative `/api`-style paths. */
    apiUrl: string;
    /** Fallback label for threads whose title hasn't been written yet
     *  (e.g. created but never sent). Defaults to `'Untitled'`. */
    titleFallback?: string;
}
declare const LANGGRAPH_THREADS_CONFIG: InjectionToken<LangGraphThreadsConfig>;
/** Optional adapter clients can pass an explicit Client (e.g. for
 *  testing). When omitted, the adapter constructs one via
 *  {@link createLangGraphClient}. */
declare const LANGGRAPH_CLIENT: InjectionToken<Client<_langchain_langgraph_sdk.DefaultValues, _langchain_langgraph_sdk.DefaultValues, unknown>>;
/**
 * SDK-backed thread store. Wraps `client.threads.*` and maps SDK
 * threads to the framework's {@link Thread} type for direct use with
 * `<chat-thread-list>` / `<chat-sidenav>`.
 *
 * Consumers wire the framework's `ThreadActionAdapter` to instance
 * methods (rename/delete/archive/pin/...) so the right-click menu
 * round-trips through the LangGraph SDK without per-app boilerplate.
 *
 * @example
 * ```ts
 * const svc = inject(LangGraphThreadsAdapter);
 * const actions: ThreadActionAdapter = {
 *   rename: (id, t) => svc.rename(id, t),
 *   delete: (id) => svc.delete(id),
 * };
 * ```
 */
declare class LangGraphThreadsAdapter {
    private readonly config;
    private readonly clientState;
    private readonly client;
    private readonly fallback;
    private readonly _threads;
    private readonly _archived;
    /** Active (non-archived) threads, sorted with pinned first. */
    readonly threads: Signal<Thread[]>;
    /** Threads whose `metadata.archived === true`. */
    readonly archivedThreads: Signal<Thread[]>;
    /** Fetch the latest thread list from the server. Failures are
     *  logged via `console.error` (not swallowed silently — silent
     *  catches have masked prod issues in the past).
     *
     *  Invocation and resolution are logged at `console.debug` so prod
     *  inspection can distinguish "never called" from "called but
     *  resolved empty" from "called and threw." This was prompted by a
     *  demo.threadplane.ai cold-load bug where the sidenav stayed empty
     *  with no visible signal. Tighten the log volume if it becomes
     *  noisy. */
    refresh(): Promise<void>;
    /** Fetch a single thread by id. Returns `null` when the server
     *  returns 404 (thread doesn't exist) so callers can distinguish
     *  "missing" from "couldn't reach the server" — genuine network
     *  errors rethrow. Used by URL-based thread routing to validate a
     *  pasted/shared thread id before activating it. */
    getThread(threadId: string): Promise<Thread | null>;
    create(metadata?: Record<string, unknown>): Promise<string | null>;
    delete(threadId: string): Promise<void>;
    rename(threadId: string, newTitle: string): Promise<void>;
    archive(threadId: string): Promise<void>;
    unarchive(threadId: string): Promise<void>;
    pin(threadId: string): Promise<void>;
    unpin(threadId: string): Promise<void>;
    moveToProject(threadId: string, projectId: string | null): Promise<void>;
    /** Re-stamp `metadata.pinnedOrder = 0,1,2,...` for the pinned slice
     *  to reflect the new ordering. */
    reorderPinned(threadId: string, beforeId: string | null): Promise<void>;
    private request;
    private safeError;
    private toThread;
    static ɵfac: i0.ɵɵFactoryDeclaration<LangGraphThreadsAdapter, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<LangGraphThreadsAdapter>;
}

/**
 * Call `fn` whenever the agent's status transitions out of `'running'`
 * (i.e. when a run completes — success, error, or interrupt). Useful
 * for refreshing thread lists, telemetry, or any other state that
 * lags the agent.
 *
 * Must be called within an injection context (constructor or
 * `runInInjectionContext`) — uses Angular's `effect` under the hood.
 *
 * @example
 * ```ts
 * constructor() {
 *   refreshOnRunEnd(this.agent, () => this.threads.refresh());
 * }
 * ```
 */
declare function refreshOnRunEnd(agent: LangGraphAgent, fn: () => void | Promise<void>): void;
/**
 * Call `fn` whenever any of the watched signals transitions from a
 * truthy "active" value to a non-active value. Generic version of
 * {@link refreshOnRunEnd} for callers tracking custom state machines.
 *
 * Must be called within an injection context.
 */
declare function refreshOnTransition<T>(watch: Signal<T>, isActive: (v: T) => boolean, fn: () => void | Promise<void>): void;

export { AGENT_LIFECYCLE, AgentLifecycleRegistry, FakeStreamTransport, FetchStreamTransport, LANGGRAPH_CLIENT, LANGGRAPH_CLIENT_OPTIONS, LANGGRAPH_THREADS_CONFIG, LangGraphThreadsAdapter, MockAgentTransport, ResourceStatus, createLangGraphClient, extractCitations, injectAgent, mockLangGraphAgent, provideAgent, provideFakeAgent, refreshOnRunEnd, refreshOnTransition, toAbsoluteApiUrl, ɵLANGGRAPH_RUNTIME_OPERATION_REPORTER };
export type { AgentBranchTree, AgentBranchTreeFork, AgentBranchTreeNode, AgentConfig, AgentLifecycle, AgentOptions, AgentQueue, AgentQueueEntry, AgentTransport, CustomStreamEvent, LangGraphAgent, LangGraphClientOptions, LangGraphMultitaskStrategy, LangGraphSubmitOptions, LangGraphThreadsConfig, MockLangGraphAgent, StreamEvent, SubagentStreamRef, RuntimeOperationFailureReporter as ɵLangGraphRuntimeOperationFailureReporter };
