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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions