fix: preserve user turn provenance metadata · openclaw/openclaw@2e8f1d4
shakkernerd
·
2026-05-27
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1145,13 +1145,15 @@ export async function runPreparedReply(
|
1145 | 1145 | ? (internalOpts?.queuedFollowupAbortSignal ?? opts?.abortSignal) |
1146 | 1146 | : undefined; |
1147 | 1147 | const userTurnMediaForPersistence = buildPersistedUserTurnMediaInputsFromFields(ctx); |
| 1148 | +const inputProvenance = ctx.InputProvenance ?? sessionCtx.InputProvenance; |
1148 | 1149 | const userTurnTranscriptText = resolvePersistedUserTurnText(transcriptBody, { |
1149 | 1150 | hasMedia: userTurnMediaForPersistence.length > 0, |
1150 | 1151 | }); |
1151 | 1152 | const userTurnInput = |
1152 | 1153 | userTurnTranscriptText !== undefined || userTurnMediaForPersistence.length > 0 |
1153 | 1154 | ? { |
1154 | 1155 | text: userTurnTranscriptText, |
| 1156 | + ...(inputProvenance ? { provenance: inputProvenance } : {}), |
1155 | 1157 | ...(userTurnMediaForPersistence.length > 0 |
1156 | 1158 | ? { |
1157 | 1159 | media: userTurnMediaForPersistence, |
@@ -1265,7 +1267,7 @@ export async function runPreparedReply(
|
1265 | 1267 | timeoutMs, |
1266 | 1268 | blockReplyBreak: resolvedBlockStreamingBreak, |
1267 | 1269 | ownerNumbers: command.ownerList.length > 0 ? command.ownerList : undefined, |
1268 | | -inputProvenance: ctx.InputProvenance ?? sessionCtx.InputProvenance, |
| 1270 | + inputProvenance, |
1269 | 1271 | extraSystemPrompt: extraSystemPromptParts.join("\n\n") || undefined, |
1270 | 1272 | sourceReplyDeliveryMode: isRoomEvent ? "message_tool_only" : opts?.sourceReplyDeliveryMode, |
1271 | 1273 | silentReplyPromptMode, |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -2600,6 +2600,7 @@ export const chatHandlers: GatewayRequestHandlers = {
|
2600 | 2600 | text: rawMessage, |
2601 | 2601 | timestamp: now, |
2602 | 2602 | idempotencyKey: `${clientRunId}:user`, |
| 2603 | + ...(systemInputProvenance ? { provenance: systemInputProvenance } : {}), |
2603 | 2604 | }; |
2604 | 2605 | const userTurnInputPromise: Promise<UserTurnInput> = userTurnMediaPromise.then((media) => ({ |
2605 | 2606 | ...baseUserTurnInput, |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -231,6 +231,11 @@ describe("user turn transcript persistence", () => {
|
231 | 231 | text: "What is in this image?", |
232 | 232 | media: [{ path: "/tmp/image.png", contentType: "image/png" }], |
233 | 233 | timestamp: 123, |
| 234 | +provenance: { |
| 235 | +kind: "inter_session", |
| 236 | +sourceSessionKey: "source-main", |
| 237 | +sourceTool: "sessions_send", |
| 238 | +}, |
234 | 239 | }, |
235 | 240 | updateMode: "none", |
236 | 241 | }); |
@@ -245,6 +250,11 @@ describe("user turn transcript persistence", () => {
|
245 | 250 | role: "user", |
246 | 251 | content: "What is in this image?", |
247 | 252 | MediaPath: "/tmp/image.png", |
| 253 | +provenance: { |
| 254 | +kind: "inter_session", |
| 255 | +sourceSessionKey: "source-main", |
| 256 | +sourceTool: "sessions_send", |
| 257 | +}, |
248 | 258 | MediaType: "image/png", |
249 | 259 | }), |
250 | 260 | ]); |
|
| Original file line number | Diff line number | Diff line change |
|---|
@@ -2,6 +2,7 @@ import path from "node:path";
|
2 | 2 | import type { AgentMessage } from "@earendil-works/pi-agent-core"; |
3 | 3 | import { appendSessionTranscriptMessage } from "../config/sessions/transcript-append.js"; |
4 | 4 | import { mimeTypeFromFilePath } from "../media/mime.js"; |
| 5 | +import { applyInputProvenanceToUserMessage, type InputProvenance } from "./input-provenance.js"; |
5 | 6 | import { emitSessionTranscriptUpdate } from "./transcript-events.js"; |
6 | 7 | |
7 | 8 | type TranscriptAppendConfig = Parameters<typeof appendSessionTranscriptMessage>[0]["config"]; |
@@ -34,6 +35,7 @@ export type UserTurnInput = {
|
34 | 35 | media?: readonly PersistedUserTurnMediaInput[] | null; |
35 | 36 | timestamp?: number; |
36 | 37 | idempotencyKey?: string; |
| 38 | +provenance?: InputProvenance; |
37 | 39 | mediaOnlyText?: string; |
38 | 40 | }; |
39 | 41 | |
@@ -285,13 +287,14 @@ function buildPersistedUserTurnMessage(params: UserTurnInput): PersistedUserTurn
|
285 | 287 | const hasMedia = Boolean(mediaFields.MediaPath); |
286 | 288 | const text = normalizeTranscriptText(params.text); |
287 | 289 | const content = text || (hasMedia ? (params.mediaOnlyText ?? "") : ""); |
288 | | -return { |
| 290 | +const message = { |
289 | 291 | role: "user", |
290 | 292 | content, |
291 | 293 | timestamp: params.timestamp ?? Date.now(), |
292 | 294 | ...(params.idempotencyKey ? { idempotencyKey: params.idempotencyKey } : {}), |
293 | 295 | ...mediaFields, |
294 | 296 | } as PersistedUserTurnMessage; |
| 297 | +return applyInputProvenanceToUserMessage(message, params.provenance) as PersistedUserTurnMessage; |
295 | 298 | } |
296 | 299 | |
297 | 300 | function resolvePersistedUserTurnMessage( |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。