Skip to content

feat(threads): record and display model provenance in threads#174

Open
cashcon57 wants to merge 1 commit into
AtomicBot-ai:mainfrom
cashcon57:feat/thread-model-provenance
Open

feat(threads): record and display model provenance in threads#174
cashcon57 wants to merge 1 commit into
AtomicBot-ai:mainfrom
cashcon57:feat/thread-model-provenance

Conversation

@cashcon57

@cashcon57 cashcon57 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Visual

image

Describe Your Changes

Adds model provenance to threads: a quiet divider line showing which model
(and backend) serves the responses that follow, as discussed on Discord.

Recording. Each assistant message gets
metadata.modelProvenance = { modelId, providerId, backend? } stamped as it is
generated, riding the same metadata pipeline that already persists
finishReason / tokenSpeed / usage. The stamp is emitted at stream start
(so it survives an aborted generation) and repeated on finish. backend is the
version_backend setting of the serving provider (e.g. the llama.cpp
TurboQuant build tag), read at send time so a later backend upgrade cannot
rewrite the history of already-generated messages. No storage schema change.

Display. Divider positions are derived from the stamps at render time
(memoized walk in the thread view):

  • First stamped response: Served by <model id> above the prompt that led to it.
  • Any later change of model, provider, or backend build: Switched to <model id>
    above the prompt following the switch. The backend build being part of the
    identity is deliberate: the same model on a different TurboQuant build is a
    provenance change worth surfacing.
  • Regenerating with a different model anchors the line to the regenerated
    response itself (the original response above it was served by the old model).
  • Switching models without sending anything adds nothing; threads that predate
    this feature pick up provenance from their next response onward.

UI. Hairline rule with the model id in small muted text, bookended by the
app's asterisk mark (transparent-logo.png, faded, theme-inverted), deliberately
quiet so it does not compete with the conversation. Hovering shows a tooltip
with the model id, the standard provider display name (via getProviderTitle,
so TurboQuant and upstream llama.cpp are distinguished), and the backend build
when recorded. Strings are localized (en only; other locales fall back to
English per the i18n setup).

Tests. Unit tests for the derivation walk: first response, no-change,
model switch, provider-only change, backend-build-only change, regenerate
anchoring, pre-feature history, malformed stamps.

Fixes Issues

Self Checklist

  • Added relevant comments, esp in complex areas (why the stamp is captured at send time, why backend is part of the identity, anchoring rules)
  • Updated docs (for bug fixes / features): n/a
  • Created issues for follow-up changes or refactoring needed: n/a

@cashcon57
cashcon57 force-pushed the feat/thread-model-provenance branch 2 times, most recently from f3ccd7e to 527b7ae Compare July 13, 2026 21:03
@cashcon57
cashcon57 marked this pull request as ready for review July 14, 2026 14:36
@cashcon57
cashcon57 requested a review from Vect0rM as a code owner July 14, 2026 14:36
Stamp metadata.modelProvenance = { modelId, providerId, backend? } onto
assistant messages as they are generated, riding the same metadata
pipeline that already persists finishReason/tokenSpeed/usage. The stamp
is emitted at stream start (so an aborted response stays attributed for
the rest of the session) and repeated on finish.

At render time, derive divider positions from the stamps: the first
stamped response yields a 'Served by <model>' line above its prompt,
and any later change of model, provider, or backend build yields a
'Switched to <model>' line at that point. A regenerate with a different
model anchors to the regenerated response. Threads that predate the
stamp pick up provenance from their next response onward.

The divider is a quiet hairline rule with the model id in small muted
text; provider and backend build (differentiating llama.cpp TurboQuant
builds from upstream) are shown in a tooltip. All display comes from
the persisted stamp, never live settings, so later backend upgrades
cannot rewrite history.
@cashcon57
cashcon57 force-pushed the feat/thread-model-provenance branch from 527b7ae to 9e7fa99 Compare July 17, 2026 15:06
@cashcon57

Copy link
Copy Markdown
Contributor Author

Apologies for the edits, I forgot to push the final edit that is represented in the image above. All good now!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Record model provenance in threads (which model/backend served each response)

1 participant