diff --git a/src/agents/cli-runner.ts b/src/agents/cli-runner.ts index d6ec97081d1..ff02b69d51a 100644 --- a/src/agents/cli-runner.ts +++ b/src/agents/cli-runner.ts @@ -7,7 +7,7 @@ import { createSubsystemLogger } from "../logging/subsystem.js"; import { buildAgentHookContextChannelFields } from "../plugins/hook-agent-context.js"; import { resolveBlockMessage } from "../plugins/hook-decision-types.js"; import { getGlobalHookRunner } from "../plugins/hook-runner-global.js"; -import { appendInlineUserTurnTranscriptMessage } from "../sessions/user-turn-transcript.js"; +import { createUserTurnTranscriptRecorder } from "../sessions/user-turn-transcript.js"; import { loadCliSessionContextEngineMessages, loadCliSessionHistoryMessages, @@ -132,26 +132,25 @@ async function persistApprovedCliUserTurnTranscript(params: RunCliAgentParams): return; } - const transcriptTarget = { - transcriptPath: params.sessionFile, - sessionId: params.sessionId, - agentId: params.agentId, - ...(params.sessionKey ? { sessionKey: params.sessionKey } : {}), - cwd: params.workspaceDir, - ...(params.config ? { config: params.config } : {}), - }; - const persisted = params.userTurnTranscript.message - ? await appendInlineUserTurnTranscriptMessage({ - ...transcriptTarget, - message: params.userTurnTranscript.message, - }) - : await appendInlineUserTurnTranscriptMessage({ - ...transcriptTarget, - input: { - text: params.userTurnTranscript.text, - timestamp: Date.now(), - }, - }); + const recorder = createUserTurnTranscriptRecorder({ + ...(params.userTurnTranscript.message + ? { message: params.userTurnTranscript.message } + : { + input: { + text: params.userTurnTranscript.text, + timestamp: Date.now(), + }, + }), + target: { + transcriptPath: params.sessionFile, + sessionId: params.sessionId, + agentId: params.agentId, + ...(params.sessionKey ? { sessionKey: params.sessionKey } : {}), + cwd: params.workspaceDir, + ...(params.config ? { config: params.config } : {}), + }, + }); + const persisted = await recorder.persistApproved(); if (persisted) { try { const notification = params.onUserMessagePersisted?.(persisted.message); diff --git a/src/sessions/user-turn-transcript.ts b/src/sessions/user-turn-transcript.ts index 9d1e6f59f16..d2d4b904cae 100644 --- a/src/sessions/user-turn-transcript.ts +++ b/src/sessions/user-turn-transcript.ts @@ -74,6 +74,19 @@ export type UserTurnTranscriptPersistenceTarget = Omit< "input" | "message" | "updateMode" >; +export type UserTurnTranscriptFileTarget = { + transcriptPath: string; + sessionId?: string; + agentId?: string; + sessionKey?: string; + cwd?: string; + config?: OpenClawConfig; +}; + +export type UserTurnTranscriptTarget = + | UserTurnTranscriptPersistenceTarget + | UserTurnTranscriptFileTarget; + export type UserTurnTranscriptPersistResult = { sessionFile: string; sessionEntry: SessionEntry | undefined; @@ -82,11 +95,8 @@ export type UserTurnTranscriptPersistResult = { }; export type UserTurnTranscriptTargetResolver = - | UserTurnTranscriptPersistenceTarget - | (() => - | UserTurnTranscriptPersistenceTarget - | undefined - | Promise); + | UserTurnTranscriptTarget + | (() => UserTurnTranscriptTarget | undefined | Promise); export type UserTurnTranscriptRecorder = { readonly message: PersistedUserTurnMessage | undefined; @@ -522,10 +532,16 @@ export async function tryPersistInlineUserTurnTranscript( async function resolveUserTurnTranscriptTarget( target: UserTurnTranscriptTargetResolver, -): Promise { +): Promise { return typeof target === "function" ? await target() : target; } +function isUserTurnTranscriptFileTarget( + target: UserTurnTranscriptTarget, +): target is UserTurnTranscriptFileTarget { + return "transcriptPath" in target; +} + export function createUserTurnTranscriptRecorder( params: CreateUserTurnTranscriptRecorderParams, ): UserTurnTranscriptRecorder { @@ -585,11 +601,25 @@ export function createUserTurnTranscriptRecorder( if (!target) { return undefined; } - const result = await persistUserTurnTranscript({ - ...target, - message, - updateMode: options.updateMode ?? params.updateMode ?? "inline", - }); + const updateMode = options.updateMode ?? params.updateMode ?? "inline"; + const result = isUserTurnTranscriptFileTarget(target) + ? await appendUserTurnTranscriptMessage({ + ...target, + message, + updateMode, + }).then((appended) => + appended + ? { + ...appended, + sessionEntry: undefined, + } + : undefined, + ) + : await persistUserTurnTranscript({ + ...target, + message, + updateMode, + }); if (result) { persisted = true; persistedResult = result;