mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 20:35:39 -06:00
refactor: route chat send user transcripts through sessions
This commit is contained in:
@@ -4331,6 +4331,15 @@ describe("chat directive tag stripping for non-streaming final payloads", () =>
|
||||
expect(message?.role).toBe("user");
|
||||
expect(message?.content).toBe("quick command");
|
||||
expect(typeof message?.timestamp).toBe("number");
|
||||
const persistedUser = readTranscriptJsonLines(mockState.transcriptPath)
|
||||
.map((entry) => entry.message)
|
||||
.find(
|
||||
(candidate): candidate is Record<string, unknown> =>
|
||||
typeof candidate === "object" &&
|
||||
candidate !== null &&
|
||||
(candidate as { role?: unknown }).role === "user",
|
||||
);
|
||||
expect(persistedUser?.content).toBe("quick command");
|
||||
});
|
||||
|
||||
it("emits a user transcript update when chat.send fails before an agent run starts", async () => {
|
||||
@@ -4356,6 +4365,15 @@ describe("chat directive tag stripping for non-streaming final payloads", () =>
|
||||
expect(message?.role).toBe("user");
|
||||
expect(message?.content).toBe("hello from failed dispatch");
|
||||
expect(typeof message?.timestamp).toBe("number");
|
||||
const persistedUser = readTranscriptJsonLines(mockState.transcriptPath)
|
||||
.map((entry) => entry.message)
|
||||
.find(
|
||||
(candidate): candidate is Record<string, unknown> =>
|
||||
typeof candidate === "object" &&
|
||||
candidate !== null &&
|
||||
(candidate as { role?: unknown }).role === "user",
|
||||
);
|
||||
expect(persistedUser?.content).toBe("hello from failed dispatch");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,9 +51,8 @@ import { isPluginOwnedSessionBindingRecord } from "../../plugins/conversation-bi
|
||||
import { normalizeInputProvenance, type InputProvenance } from "../../sessions/input-provenance.js";
|
||||
import { resolveSendPolicy } from "../../sessions/send-policy.js";
|
||||
import { parseAgentSessionKey } from "../../sessions/session-key-utils.js";
|
||||
import { emitSessionTranscriptUpdate } from "../../sessions/transcript-events.js";
|
||||
import {
|
||||
buildPersistedUserTurnMessage,
|
||||
persistUserTurnTranscript,
|
||||
type UserTurnInput,
|
||||
} from "../../sessions/user-turn-transcript.js";
|
||||
import { uniqueStrings } from "../../shared/string-normalization.js";
|
||||
@@ -2677,14 +2676,14 @@ export const chatHandlers: GatewayRequestHandlers = {
|
||||
let appendedWebchatAgentMedia = false;
|
||||
let userTranscriptUpdatePromise: Promise<void> | null = null;
|
||||
let agentRunStarted = false;
|
||||
const emitGatewayUserTranscriptUpdate = async () => {
|
||||
const persistGatewayUserTurnTranscript = async () => {
|
||||
if (userTranscriptUpdatePromise) {
|
||||
await userTranscriptUpdatePromise;
|
||||
return;
|
||||
}
|
||||
userTranscriptUpdatePromise = (async () => {
|
||||
await measureDiagnosticsTimelineSpan(
|
||||
"gateway.chat_send.emit_user_transcript",
|
||||
"gateway.chat_send.persist_user_transcript",
|
||||
async () => {
|
||||
const { storePath: latestStorePath, entry: latestEntry } =
|
||||
loadSessionEntry(sessionKey);
|
||||
@@ -2692,27 +2691,21 @@ export const chatHandlers: GatewayRequestHandlers = {
|
||||
if (!resolvedSessionId) {
|
||||
return;
|
||||
}
|
||||
const transcriptPath = resolveTranscriptPath({
|
||||
sessionId: resolvedSessionId,
|
||||
storePath: latestStorePath,
|
||||
sessionFile: latestEntry?.sessionFile ?? entry?.sessionFile,
|
||||
agentId,
|
||||
});
|
||||
if (!transcriptPath) {
|
||||
return;
|
||||
}
|
||||
const persistedImages = await getPersistedMediaForTranscript();
|
||||
const userTurnInput = await userTurnInputPromise;
|
||||
emitSessionTranscriptUpdate({
|
||||
sessionFile: transcriptPath,
|
||||
await persistUserTurnTranscript({
|
||||
sessionId: resolvedSessionId,
|
||||
sessionKey,
|
||||
message: buildPersistedUserTurnMessage(
|
||||
userTurnInput ?? {
|
||||
text: parsedMessage,
|
||||
media: persistedImages,
|
||||
timestamp: now,
|
||||
},
|
||||
),
|
||||
sessionEntry: latestEntry ?? entry,
|
||||
storePath: latestStorePath,
|
||||
agentId,
|
||||
config: cfg,
|
||||
input: userTurnInput ?? {
|
||||
text: parsedMessage,
|
||||
media: persistedImages,
|
||||
timestamp: now,
|
||||
},
|
||||
updateMode: "inline",
|
||||
});
|
||||
},
|
||||
{
|
||||
@@ -2919,7 +2912,7 @@ export const chatHandlers: GatewayRequestHandlers = {
|
||||
// assistant turn, so it appends a gateway-injected assistant entry before
|
||||
// broadcasting the final UI event.
|
||||
if (!agentRunStarted) {
|
||||
await emitGatewayUserTranscriptUpdate();
|
||||
await persistGatewayUserTurnTranscript();
|
||||
const btwReplies = deliveredReplies
|
||||
.map((entry) => entry.payload)
|
||||
.filter(isBtwReplyPayload);
|
||||
@@ -3456,7 +3449,7 @@ export const chatHandlers: GatewayRequestHandlers = {
|
||||
.catch(async (err) => {
|
||||
const emitAfterError = agentRunStarted
|
||||
? Promise.resolve()
|
||||
: emitGatewayUserTranscriptUpdate();
|
||||
: persistGatewayUserTurnTranscript();
|
||||
await emitAfterError.catch((transcriptErr) => {
|
||||
context.logGateway.warn(
|
||||
`webchat user transcript update failed after error: ${formatForLog(transcriptErr)}`,
|
||||
|
||||
Reference in New Issue
Block a user