refactor: extract gateway transcript append helper

This commit is contained in:
Peter Steinberger
2026-02-22 14:43:44 +00:00
parent 8e6b465fa8
commit 142c0a7f7d
5 changed files with 121 additions and 109 deletions

View File

@@ -1,6 +1,6 @@
import fs from "node:fs";
import path from "node:path";
import { CURRENT_SESSION_VERSION, SessionManager } from "@mariozechner/pi-coding-agent";
import { CURRENT_SESSION_VERSION } from "@mariozechner/pi-coding-agent";
import { resolveSessionAgentId } from "../../agents/agent-scope.js";
import { resolveThinkingDefault } from "../../agents/model-selection.js";
import { resolveAgentTimeoutMs } from "../../agents/timeout.js";
@@ -45,6 +45,7 @@ import {
import { formatForLog } from "../ws-log.js";
import { injectTimestamp, timestampOptsFromConfig } from "./agent-timestamp.js";
import { normalizeRpcAttachmentsToChatAttachments } from "./attachment-normalize.js";
import { appendInjectedAssistantMessageToTranscript } from "./chat-transcript-inject.js";
import type { GatewayRequestContext, GatewayRequestHandlers } from "./types.js";
type TranscriptAppendResult = {
@@ -54,7 +55,6 @@ type TranscriptAppendResult = {
error?: string;
};
type AppendMessageArg = Parameters<SessionManager["appendMessage"]>[0];
type AbortOrigin = "rpc" | "stop-command";
type AbortedPartialSnapshot = {
@@ -376,55 +376,13 @@ function appendAssistantTranscriptMessage(params: {
return { ok: true };
}
const now = Date.now();
const labelPrefix = params.label ? `[${params.label}]\n\n` : "";
const usage = {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
totalTokens: 0,
cost: {
input: 0,
output: 0,
cacheRead: 0,
cacheWrite: 0,
total: 0,
},
};
const messageBody: AppendMessageArg & Record<string, unknown> = {
role: "assistant",
content: [{ type: "text", text: `${labelPrefix}${params.message}` }],
timestamp: now,
// Pi stopReason is a strict enum; this is not model output, but we still store it as a
// normal assistant message so it participates in the session parentId chain.
stopReason: "stop",
usage,
// Make these explicit so downstream tooling never treats this as model output.
api: "openai-responses",
provider: "openclaw",
model: "gateway-injected",
...(params.idempotencyKey ? { idempotencyKey: params.idempotencyKey } : {}),
...(params.abortMeta
? {
openclawAbort: {
aborted: true,
origin: params.abortMeta.origin,
runId: params.abortMeta.runId,
},
}
: {}),
};
try {
// IMPORTANT: Use SessionManager so the entry is attached to the current leaf via parentId.
// Raw jsonl appends break the parent chain and can hide compaction summaries from context.
const sessionManager = SessionManager.open(transcriptPath);
const messageId = sessionManager.appendMessage(messageBody);
return { ok: true, messageId, message: messageBody };
} catch (err) {
return { ok: false, error: err instanceof Error ? err.message : String(err) };
}
return appendInjectedAssistantMessageToTranscript({
transcriptPath,
message: params.message,
label: params.label,
idempotencyKey: params.idempotencyKey,
abortMeta: params.abortMeta,
});
}
function collectSessionAbortPartials(params: {