import type { ActionChatUIConfig } from "../action-ui.js"; import type { ArtifactReceipt } from "../artifacts/detect.js"; import { type CodeAgentTranscriptEvent as CoreCodeAgentTranscriptEvent } from "../code-agents/transcript-normalizer.js"; import type { AgentMcpAppPayload } from "../mcp-client/app-result.js"; import { type RefusedTurnRetryContext } from "../shared/agent-chat-run-not-started.js"; import type { EngineMessage } from "./engine/types.js"; import type { ActiveRun } from "./run-manager.js"; import type { AgentChatAttachment, AgentChatSteeredUserMessage, RunEvent, UnknownWriteCause } from "./types.js"; interface ContentPart { type: string; text?: string; toolCallId?: string; toolName?: string; executionStepId?: string; inputFingerprint?: string; argsText?: string; args?: Record; result?: string; isError?: boolean; approvalPause?: true; approvalAskId?: string; outcome?: "unknown"; unknownCause?: UnknownWriteCause; completedSideEffect?: boolean; artifacts?: ArtifactReceipt[]; mcpApp?: AgentMcpAppPayload; chatUI?: ActionChatUIConfig; chatUIResult?: unknown; activity?: boolean; approval?: { approvalKey: string; dismissed?: boolean; askId?: string; allowPersistentApproval?: false; }; } interface BuildAssistantMessageOptions { suppressInternalContinuation?: boolean; preserveUnknownToolOutcomes?: boolean; turnId?: string; runDurationMs?: number | undefined; scope?: { type: string; id: string; } | null | undefined; } type AssistantMessage = NonNullable>; type UserMessage = ReturnType; export declare const ASSISTANT_RUN_DURATION_METADATA_KEY = "agentNativeRunDurationMs"; export declare function containsInlineAttachmentPayload(value: unknown): boolean; export declare function buildAssistantMessage(events: RunEvent[], runId?: string, options?: BuildAssistantMessageOptions): { id: string; createdAt: Date; role: "assistant"; content: ContentPart[]; status: { type: "complete"; reason: "stop"; } | { type: "incomplete"; reason: "error"; }; metadata: Record; } | null; export interface SteeredRunSegment { user: UserMessage; /** The message as the run received it, attachments included. */ delivered: AgentChatSteeredUserMessage; assistant: AssistantMessage | null; } /** * A run's reply split at each message the user sent into it with Send now: * the reply before the first one, then each delivered message with the reply * written after it. A run without one is exactly `buildAssistantMessage`. */ export declare function buildAssistantTurnSegments(events: RunEvent[], runId?: string, options?: BuildAssistantMessageOptions): { assistant: AssistantMessage | null; steered: SteeredRunSegment[]; }; /** The id a run writes its output under after delivering `messageId`. */ export declare function steeredContinuationMessageId(runId: string, messageId: string): string; export declare function buildSteeredUserMessage(message: AgentChatSteeredUserMessage, runId: string | undefined): UserMessage; export declare function normalizeThreadRepository(repo: any): any; export interface ThreadDataToEngineMessagesOptions { includeToolCalls?: boolean; } export declare function threadDataToEngineMessages(threadData: string | Record | null | undefined, options?: ThreadDataToEngineMessagesOptions): EngineMessage[]; export declare function recoverThreadHistoryForRequest(threadData: string | Record | null | undefined, limits?: { maxMessages?: number; maxChars?: number; }): EngineMessage[]; /** * History for resuming a stopped turn: earlier turns get the recovery window, * while the turn itself, from its last user message on, stays whole so every * finished tool call keeps its result. Without a user message, the turn's * prompt is not in the thread: `foundTurnPrompt` is false and every message is * returned unbounded. */ export declare function resumeThreadHistoryForRequest(threadData: string | Record | null | undefined): { messages: EngineMessage[]; foundTurnPrompt: boolean; }; export declare function lastUserPromptIndex(messages: EngineMessage[]): number; /** * The turn the thread's newest prompt was sent in, when the server stamped * it. A prompt whose run was refused before it started has no run row, so * this is how a continuation learns a newer prompt is waiting. */ export declare function latestPromptTurnId(threadData: string | Record): string | undefined; export declare function threadMessageTextForEngine(message: any): string; export interface CodeAgentThreadTranscriptEvent { id: string; runId: string; kind?: CoreCodeAgentTranscriptEvent["kind"]; type?: CoreCodeAgentTranscriptEvent["kind"] | "note"; message?: string; text?: string; createdAt: string; metadata?: Record; artifactPath?: string; artifactUrl?: string; signal?: CoreCodeAgentTranscriptEvent["signal"]; } export interface BuildRepositoryFromCodeAgentTranscriptOptions { hideCredentialMessages?: boolean; } export declare function buildRepositoryFromCodeAgentTranscript(events: readonly CodeAgentThreadTranscriptEvent[], options?: BuildRepositoryFromCodeAgentTranscriptOptions): any; export interface MergeThreadDataOptions { preserveExistingQueuedMessages?: boolean; preserveExistingTopLevelKeys?: boolean; onAnnotationConflict?: (conflict: ThreadAnnotationSnapshotConflict) => void; trustedRunSequenceResetIds?: ReadonlySet; } export interface ThreadAnnotationSnapshotConflict { messageId: string; annotationId?: string; operation: "upsert" | "remove"; } export declare function hasClaimedQueuedMessage(repo: any, messageId: string): boolean; export declare function claimQueuedMessage(repo: any, messageId: string): any; /** A Send now message a run took from the queue, kept until its run is folded. */ export interface SteeredQueuedMessageRecord { runId: string; message: AgentChatSteeredUserMessage; continuationMessageId: string; } export declare function steeredQueuedMessageRecords(runId: string, queued: ReadonlyArray<{ id: string; text: string; attachments?: unknown[]; requestAttachments?: unknown[]; }>, deliveredAt: number): SteeredQueuedMessageRecord[]; /** * Claims the delivered ids, so a stale client save never re-queues them, and * keeps each message until the run's fold places it in the transcript. */ export declare function recordSteeredQueuedMessages(repo: unknown, records: readonly SteeredQueuedMessageRecord[]): Record; export declare function applySubmittedUserMessage(repo: any, userMessage: UserMessage, queuedMessage?: { kind?: "queued-message"; id: string; claimId?: string; now?: number; } | { kind: "background-operation"; id: string; }): { status: "submitted" | "already_submitted"; repo: any; } | { status: "already_claimed" | "claim_expired" | "submission_expired"; }; /** * Whether a stored user message is the prompt this run answers, rather than * one sent after it started. Messages saved without the server's turn stamp * fall back to their creation time. */ export declare function isRunPrompt(user: any, run: { runId: string; turnId?: string | null; startedAt: number; }): boolean; export type ThreadSuggestionRun = Pick; export declare function foldThreadRunSuggestions(repo: any, run: ThreadSuggestionRun): any; export declare function mergeThreadDataForClientSave(existingRepo: any, incomingRepo: any, options?: MergeThreadDataOptions): any; export declare function buildUserMessage(opts: { text: string; attachments?: AgentChatAttachment[]; runId?: string; turnId?: string; agentKitMessageId?: string; queuedMessageId?: string; submissionExpiresAt?: unknown; createdAt?: Date; /** The turn was refused before a run started; its retry reads this back. */ refusedRetry?: RefusedTurnRetryContext; }): { id: string; createdAt: Date; role: "user"; content: ContentPart[]; attachments?: any[]; metadata: Record; }; export declare function upsertUserMessage(repo: any, userMsg: UserMessage): any; export declare function upsertAssistantMessage(repo: any, assistantMsg: AssistantMessage, parentId?: string | null): any; export declare function foldAssistantTurn(repo: any, assistantMsg: AssistantMessage, options: { turnId?: string; runId?: string; parentId?: string | null; agentKitOwnsContinuation?: boolean; }): any; /** * Folds a run's reply and the messages delivered into it. Records the run * took from the queue but never journaled are appended after its reply, and * a refold updates the delivered messages in place. */ export declare function foldAssistantTurnWithSteers(repo: unknown, assistantMsg: Parameters[1] | null, steered: readonly SteeredRunSegment[], options: Parameters[2] & { runId: string; }): any; export declare function foldAgentChatRunCompletion(repo: unknown, assistantMsg: Parameters[1] | null, run: ThreadSuggestionRun & Pick, steered?: readonly SteeredRunSegment[]): any; /** * A turn the server refused before any run started (no usable model * credential, AI setup missing) still answers in the thread: a typed * assistant error in the durable history and a failed AgentKit run, keyed by * the turn id the client already uses as the run id, so the transcript shows * the failure card with a retry instead of an unanswered prompt. */ export declare function foldUnstartedTurnFailure(repo: any, failure: { runId: string; threadId: string; turnId?: string; code: string; message: string; at?: Date; }): any; export declare function normalizeThreadTitle(value: unknown): string; export declare function extractThreadMeta(repo: any): { title: string; preview: string; }; export {};