fix(events): 保留用户消息提交时间

This commit is contained in:
AgentRun Codex
2026-07-20 05:37:30 +02:00
parent 0df2b80eb3
commit 40b1c4e75a
2 changed files with 57 additions and 2 deletions
+10 -2
View File
@@ -52,12 +52,14 @@ export function userMessagePayloadForCommand(run: RunRecord, command: CommandRec
const text = promptBearingText(command.payload); const text = promptBearingText(command.payload);
if (text === null) return null; if (text === null) return null;
const targetTraceId = command.type === "steer" ? nonEmptyText(command.payload.targetTraceId) : null; const targetTraceId = command.type === "steer" ? nonEmptyText(command.payload.targetTraceId) : null;
const submittedAt = isoTimestamp(command.payload.submittedAt);
return { return {
commandId: command.id, commandId: command.id,
traceId: agentRunBusinessTraceId(run, command), traceId: agentRunBusinessTraceId(run, command),
userMessageId: nonEmptyText(command.payload.userMessageId) ?? `msg_${command.id}_user`, userMessageId: nonEmptyText(command.payload.userMessageId) ?? `msg_${command.id}_user`,
text, text,
source: command.type === "steer" ? "agentrun-steer-command-payload" : "agentrun-turn-command-payload", source: command.type === "steer" ? "agentrun-steer-command-payload" : "agentrun-turn-command-payload",
...(submittedAt ? { submittedAt } : {}),
...(targetTraceId ? { targetTraceId } : {}), ...(targetTraceId ? { targetTraceId } : {}),
valuesPrinted: false, valuesPrinted: false,
}; };
@@ -103,16 +105,22 @@ function normalizeCommandOutputPayload(payload: JsonRecord): JsonRecord {
} }
function normalizeUserMessagePayload(payload: JsonRecord): JsonRecord { function normalizeUserMessagePayload(payload: JsonRecord): JsonRecord {
const { targetTraceId: _targetTraceId, ...rest } = payload; const { targetTraceId: _targetTraceId, submittedAt: _submittedAt, ...rest } = payload;
const commandId = nonEmptyText(payload.commandId); const commandId = nonEmptyText(payload.commandId);
const userMessageId = nonEmptyText(payload.userMessageId); const userMessageId = nonEmptyText(payload.userMessageId);
const text = typeof payload.text === "string" && payload.text.trim().length > 0 ? redactText(payload.text) : null; const text = typeof payload.text === "string" && payload.text.trim().length > 0 ? redactText(payload.text) : null;
const source = nonEmptyText(payload.source); const source = nonEmptyText(payload.source);
const targetTraceId = nonEmptyText(payload.targetTraceId); const targetTraceId = nonEmptyText(payload.targetTraceId);
const submittedAt = isoTimestamp(payload.submittedAt);
if (!commandId || !userMessageId || text === null || !source) { if (!commandId || !userMessageId || text === null || !source) {
throw new AgentRunError("schema-invalid", "user_message event requires commandId, userMessageId, non-empty text, and source", { httpStatus: 400 }); throw new AgentRunError("schema-invalid", "user_message event requires commandId, userMessageId, non-empty text, and source", { httpStatus: 400 });
} }
return { ...rest, commandId, userMessageId, text, source, ...(targetTraceId ? { targetTraceId } : {}), valuesPrinted: false }; return { ...rest, commandId, userMessageId, text, source, ...(targetTraceId ? { targetTraceId } : {}), ...(submittedAt ? { submittedAt } : {}), valuesPrinted: false };
}
function isoTimestamp(value: unknown): string | null {
const timestamp = nonEmptyText(value);
return timestamp && Number.isFinite(Date.parse(timestamp)) ? new Date(Date.parse(timestamp)).toISOString() : null;
} }
function promptBearingText(payload: JsonRecord): string | null { function promptBearingText(payload: JsonRecord): string | null {
@@ -0,0 +1,47 @@
import assert from "node:assert/strict";
import type { CreateRunInput } from "../../common/types.js";
import { MemoryAgentRunStore } from "../../mgr/store.js";
import type { SelfTestCase } from "../harness.js";
const selfTest: SelfTestCase = () => {
const store = new MemoryAgentRunStore();
const run = store.createRun(runInput());
const submittedAt = "2026-07-20T01:13:07.699Z";
const command = store.createCommand(run.id, {
type: "turn",
idempotencyKey: "user-submitted-at",
payload: {
prompt: "hi",
traceId: "trc_user_submitted_at",
userMessageId: "msg_user_submitted_at",
submittedAt,
},
});
const event = store.listEvents(run.id, 0, 10)
.find((candidate) => candidate.type === "user_message" && candidate.payload.commandId === command.id);
assert.equal(event?.payload.submittedAt, submittedAt);
return { name: "user-submitted-at", tests: ["command-user-message-preserves-submitted-at"] };
};
function runInput(): CreateRunInput {
return {
tenantId: "hwlab",
projectId: "pikasTech/HWLAB",
workspaceRef: { kind: "host-path", path: "/tmp/agentrun-user-submitted-at" },
sessionRef: { sessionId: "ses_user_submitted_at", metadata: { hwlabSessionId: "ses_user_submitted_at" } },
resourceBundleRef: null,
providerId: "NC01",
backendProfile: "gpt-pika",
executionPolicy: {
sandbox: "danger-full-access",
approval: "never",
timeoutMs: 60_000,
network: "enabled",
secretScope: { allowCredentialEcho: false, providerCredentials: [] },
},
traceSink: null,
};
}
export default selfTest;