Skip to content

ai-persistence: expose finished-run timings (startedAt/finishedAt) in reconstructChat #1061

Description

@archiekd

Use case

Our chat UI shows a "Worked for Xs" duration label on each assistant turn. Live turns time themselves client-side, but after a reload/rehydrate via reconstructChat + persistence: true there is no way to recover run durations through the library:

  • ReconstructedChat returns messages (from MessageStore.loadThreadModelMessage[], no timestamps) and activeRun as a bare { runId } cursor.
  • Finished runs never reach the client, even though RunRecord already carries startedAt/finishedAt in the RunStore contract — the data is sitting in the store the server is already querying.

Today the only options are a parallel app-owned history endpoint (defeats the point of the library owning hydration) or dropping durations on resumed turns (what we chose).

Proposal

Have reconstructChat (optionally?) include the thread's terminal runs — e.g.

interface ReconstructedChat {
  messages: Array<UIMessage>
  activeRun: { runId: string } | null
  runs?: Array<{ runId: string; status: TerminalRunStatus; startedAt: number; finishedAt?: number }>
  interrupts: /* … */
}

requiring only a RunStore.listRuns(threadId) (or similar) addition. An opt-in flag on ReconstructChatOptions would keep the default payload unchanged.

Happy to PR this if the shape sounds right.

Versions: @tanstack/ai@0.43.0, @tanstack/ai-persistence@0.1.0, @tanstack/ai-client@0.23.0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions