统一 Direct 工具调用时间戳为毫秒
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled

在前端模型入口兼容 Unix 秒时间戳并统一为毫秒

保持耗时展示使用秒和分钟

补充时间戳归一化回归测试
This commit is contained in:
2026-09-16 05:38:11 +08:00
parent c2a5a655e6
commit c1e3e3bf8d
3 changed files with 14 additions and 1 deletions
+3
View File
@@ -244,6 +244,7 @@ import {
type DirectThreadSubscriptionBootstrap,
isDirectTurnInProgress,
} from './features/project-workspace/directThreadEvents';
import { normalizeDirectTimestamp } from './features/project-workspace/directTurnPresentation';
import type { DirectCodexUserContentPart } from './features/project-workspace/generated';
import {
appendMemoryContent,
@@ -1010,6 +1011,8 @@ export function App({
const normalized: GameCreatorDirectToolCall = {
...call,
id,
startedAt: normalizeDirectTimestamp(call.startedAt),
updatedAt: normalizeDirectTimestamp(call.updatedAt),
detail: call.detail ?? { changes: [] },
};
// 起点时间取更早的那个:`completed` 事件不一定带 startedAt。
@@ -26,7 +26,8 @@ export type DirectTurnPresentation = {
endedAt: number;
};
export function directMessageTimestamp(value: number | undefined) {
/** 统一 Direct 时间戳为 Unix 毫秒;历史/异常 payload 可能传 Unix 秒。 */
export function normalizeDirectTimestamp(value: number | undefined) {
const timestamp =
value && Number.isFinite(value) && value > 0
? value < 100_000_000_000
@@ -36,6 +37,8 @@ export function directMessageTimestamp(value: number | undefined) {
return Number.isFinite(new Date(timestamp).getTime()) ? timestamp : 0;
}
export const directMessageTimestamp = normalizeDirectTimestamp;
/** 从唯一呈现来源分区,完成后只把最终回复及失败提示留在过程折叠区之外。 */
export function splitDirectTurnContent(turn: DirectTurnPresentation) {
const assistants = turn.messages.filter(
@@ -8,6 +8,7 @@ import type {
import {
buildDirectTurnPresentations,
directMessageTimestamp,
normalizeDirectTimestamp,
splitDirectTurnContent,
} from '../src/features/project-workspace/directTurnPresentation';
@@ -58,6 +59,12 @@ const build = (
});
describe('DirectProject 回合唯一呈现', () => {
it('把 Unix 秒时间戳归一化为毫秒,已有毫秒值保持不变', () => {
expect(normalizeDirectTimestamp(1_800_000_000)).toBe(1_800_000_000_000);
expect(normalizeDirectTimestamp(1_800_000_000_000)).toBe(1_800_000_000_000);
expect(directMessageTimestamp(1_800_000_000)).toBe(1_800_000_000_000);
});
it('历史仍有未加载切片时,不把那些回合的工具流追加到当前页末尾', () => {
const rows = build(
[user('one')],