feat(ai-chat): context badge shows current/max (#189) #213
Closed
Ghost
wants to merge 2 commits from
feat/189-context-badge into develop
pull from: feat/189-context-badge
merge into: vvzvlad:develop
vvzvlad:main
vvzvlad:test/244-part-b
vvzvlad:fix/255-ws-redis-adapter-leak
vvzvlad:feat/251-intentional-clear
vvzvlad:fix/252-e2e-open-handles
vvzvlad:feat/184-autonomous-agent-runs
vvzvlad:feat/221-image-captions
vvzvlad:feat/git-sync
vvzvlad:refactor/193-tool-spec-registry
vvzvlad:fix/244-dataloss-bugs
vvzvlad:fix/embeddings-reindex-progress
vvzvlad:develop
vvzvlad:feature/offline-sync
vvzvlad:feat/229-catalog-yaml
vvzvlad:feat/243-blob-sandbox
vvzvlad:feat/228-inline-footnotes
vvzvlad:fix/qa-ui-bugs-216-218
vvzvlad:feature/agent-roles-catalog
vvzvlad:fix/share-alias-rename
vvzvlad:fix/ai-chat-empty-render
vvzvlad:feat/191-chat-doc-binding
vvzvlad:feat/201-temporary-notes
vvzvlad:feat/198-interrupt-agent
vvzvlad:feat/ai-chat-full-history
vvzvlad:feat/199-ai-generate-title
vvzvlad:feat/205-share-aliases
vvzvlad:batch/issues-189-187-170
vvzvlad:feat/170-mcp-test-button
vvzvlad:feat/198-interrupt-agent-send-now
vvzvlad:fix/issues-190-159
vvzvlad:fix/ai-chat-new-chat-during-stream
vvzvlad:fix/ai-chat-stream-perf
vvzvlad:batch/issues-2026-06-25
vvzvlad:feat/ai-chat-persistent-history
vvzvlad:fix/ai-chat-copy-chat-wysiwyg
vvzvlad:fix/ai-stream-reset-resilience
vvzvlad:fix/ai-stream-undici-timeout
vvzvlad:fix/footnote-review-1227-followup
vvzvlad:fix/ai-chat-token-counter-realtime
vvzvlad:docs/manual-qa-test-plan
2 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
88199703fe |
fix(ai): store chatContextWindow as a JSON number, not a ::text string
chatContextWindow (#189) is the first numeric provider field routed through WorkspaceRepo.updateAiProviderSettings, whose patch builder cast every value as `${v}::text`. The DTO validates it as @IsInt(), so a JS number 200000 was stored as the JSON STRING "200000". The client guards require `typeof === "number"` (ai-chat-window.tsx, context-badge.tsx), so the `/ max` badge denominator never rendered and the whole feature silently no-opped. Branch the jsonb_build_object value cast by JS runtime type: numbers -> ::numeric (real JSON number), booleans -> ::boolean, everything else -> ::text (unchanged for the existing string fields). This is the root fix (store as a real number) rather than coercing on read, so every reader sees the correct type. Add a DB round-trip int-spec asserting jsonb_typeof(settings->'ai'->'provider'->'chatContextWindow') = 'number' and that the value re-reads as the number 200000, including the partial-merge path. CHANGELOG: Added entry for the chatContextWindow setting and a Changed entry for the badge's new "used / max" meaning. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
d88fe4cde7 |
feat(ai-chat): context badge shows current/max (#189)
The header badge in the floating AI-chat window flipped meaning between states (a live per-turn token counter while streaming vs. the context size at rest), which made it "reset to 1" on each prompt and confused users. Make it consistently show the current context size, with the model's context window as an optional "/ max" denominator. The max comes from a new admin-set AI setting (chatContextWindow, in tokens) — provider-independent and always exact. The server stamps it onto the assistant message metadata (maxContextTokens) next to contextTokens, so the client reads both from the last row with no client-side model resolution (survives shares / future per-role models). - server: chatContextWindow in AiProviderSettings/keys/masked/resolved, DTO (@IsInt @Min(0)), settings-service resolve/getMasked, repo parity allowlist; flushAssistant writes metadata.maxContextTokens when > 0. - client: ContextBadge component (extracted, shows "current [/ max]", no live mode); removed the liveTurnTokens header path + dead util fn; Context-window NumberInput in AI settings; i18n strings. - live "Thinking · N tokens" feedback in the chat body is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |