> For the complete documentation index, see [llms.txt](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase40-session11-chat-model-selector-and-context-meter/spec.md).

# Session Specification

**Session ID**: `phase40-session11-chat-model-selector-and-context-meter` **Phase**: 40 - Claude OS v2.10.1 Semantic Port **Status**: Not Started **Created**: 2026-07-03 **Base Commit**: 38814f5d6cacad6087ca9c6d729b2f55e004462e

***

## 1. Session Overview

This session brings the upstream Hermes chat model selector and context meter into the existing AI OS split chat surface. It adds controlled components under the current `src/components/hermes/chat/` owner, keeps active model state in `HermesChatTab`, and uses the Session 04 chat override path instead of mutating Hermes configuration.

This is the next executable Phase 40 session because Sessions 02, 04, and 08 are complete: model body and MoA metadata exist, selected model/provider payloads are accepted by the admin hook, and catalog/context metadata is available to the browser. The work advances the Phase 40 chat UI objective and gives Sessions 12, 13, and 15 stable toolbar placement and selector refresh behavior.

The session stays product-facing. Diagnostics remain in tests and implementation notes; the chat UI should show actionable model, provider, context, and send-state copy without exposing raw local paths, credentials, or private bridge output.

***

## 2. Objectives

1. Render a controlled Hermes model selector and context meter in the chat composer without mobile or desktop overlap.
2. Keep the active model/provider selection in `HermesChatTab` and send ordinary model overrides through the existing admin chat action.
3. Preserve MoA presets in the selector even when configured-provider filtering is active, and send them with provider `moa`.
4. Add focused coverage for draft estimate changes, active model context selection, provider filtering, MoA rows, and responsive layout stability.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase40-session02-models-and-provider-readiness` - Expanded Hermes model body, configured-provider readiness, and MoA preset metadata.
* [x] `phase40-session04-chat-overrides-and-runtime` - Per-chat model/provider override payload path and admin hook validation.
* [x] `phase40-session08-catalog-and-context-metadata` - Catalog context metadata, provider labels, aliases, and fallback context source fields.

### Required Tools Or Knowledge

* Bun and Vitest test workflow.
* React 19 component patterns already used by Hermes chat.
* Local Radix UI primitives in `src/components/ui/`, especially popover, select, button, and tooltip patterns.
* Existing Hermes model contract in `src/lib/hermes-types.ts`.

### Environment Requirements

* Repository dependencies installed with the pinned Bun version.
* No live Hermes credentials are required for planning or unit tests.
* Demo/public mode must remain read-only and fixture-safe.

***

## 4. Scope

### In Scope (MVP)

* AI OS chat users can choose an ordinary configured or catalog model before sending a prompt - Implement a controlled selector using existing model contract data.
* AI OS chat users can select MoA presets even when configured-provider filtering hides non-configured ordinary providers - Treat mixtures as first-class selector rows with provider `moa`.
* AI OS chat users can see approximate draft and conversation context usage - Add an approximate estimator, `~` display copy, fallback context labeling, and a 100-cell popover breakdown.
* Hermes chat sends selected model/provider values through Session 04 admin hook options - Merge model options with existing grounding/toolset options without mutating Hermes config.
* Hermes chat remains usable in live, demo, loading, empty, error, and offline data states - Keep model controls bounded and explicit when model data is unavailable.

### Out Of Scope (Deferred)

* Command menu and slash action UI - Reason: Session 13 owns command UX after compact flow placement is available.
* Compact flow, reply copy, thinking timer, and warning-filter polish - Reason: Session 12 owns these adjacent chat polish changes.
* Ministry builder and direct MoA save UX - Reason: Sessions 14 and 15 own Ministry composition, analytics, and persistence.
* Exact token accounting claims - Reason: this session intentionally ships approximate client estimates only.
* Documentation updates - Reason: Session 17 updates docs after behavior ships and tests pass.

***

## 5. Technical Approach

### Architecture

Add narrow chat-owned components for selector and context display under `src/components/hermes/chat/`. `HermesReadOnlyPage` and Knowledge Graph grounded chat should pass the existing `HermesQueryView<HermesModelsBody>` into `HermesChatTab`; `HermesChatTab` owns the selected model row and passes controlled props to `ChatComposer`, `ModelSelector`, and `ContextMeter`.

Model option derivation should consume `HermesModelsBody.catalog`, `configured`, `default`, `configuredDefault`, and `mixtures`. Ordinary rows should honor configured-provider filtering when configured providers exist. MoA rows should stay visible regardless of ordinary provider filtering because they are locally configured presets, not provider catalog rows.

Context usage should be approximate and browser-local. Estimate prompt and visible conversation text from draft, local messages, selected session detail, and stream output; resolve the active context window from the selected model entry or default fallback; display approximate `~` values and fallback context reasons without claiming exact tokenizer parity.

### Design Patterns

* Controlled component state: `HermesChatTab` owns selected model and passes value/change handlers to child components because sends must use the same selection.
* Parser-owned contracts: reuse `HermesModelsBody`, `HermesModelEntry`, and `HermesModelMixture` types instead of re-parsing bridge payloads in components.
* Product-only UI states: loading, empty, error, offline, demo, and fallback states use concise product copy; raw diagnostics stay in tests.
* Existing admin send boundary: use `admin.chat.sendPrompt(prompt, sessionId, options)` with merged options rather than adding a new bridge path.

***

## 6. Deliverables

### Files To Create

| File                                            | Purpose                                                                                                            | Est. Lines |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ---------- |
| `src/components/hermes/chat/model-selector.tsx` | Controlled model selector, option derivation, configured-provider filtering, MoA rows, and accessible menu states. | \~240      |
| `src/components/hermes/chat/context-meter.tsx`  | Approximate token estimator, active context resolver, status meter, and 100-cell popover breakdown.                | \~220      |

### Files To Modify

| File                                                               | Changes                                                                                                       | Est. Lines |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ---------- |
| `src/components/hermes/chat/hermes-chat-tab.tsx`                   | Add models prop, selected model state, model option merge, context inputs, and send payload integration.      | \~120      |
| `src/components/hermes/chat/chat-composer.tsx`                     | Add stable toolbar slots for selector and context meter with responsive constraints.                          | \~80       |
| `src/components/hermes/chat/chat-types.ts`                         | Add shared selected-model and context-estimate types/helpers used by chat components.                         | \~100      |
| `src/components/hermes/chat/index.ts`                              | Export new chat components and shared types as needed.                                                        | \~10       |
| `src/components/hermes/hermes-read-only-page.tsx`                  | Pass live/demo Hermes model view into the chat tab.                                                           | \~5        |
| `src/components/knowledge-graph/knowledge-graph-grounded-chat.tsx` | Pass Hermes model view into grounded chat without changing graph send options.                                | \~5        |
| `src/components/hermes/chat/__tests__/hermes-chat-tab.test.tsx`    | Cover selector defaults, configured filtering, MoA rows, context estimates, send payloads, and layout guards. | \~220      |
| `src/components/hermes/__tests__/hermes-sections.test.tsx`         | Update direct chat-tab contract tests and page wiring fixtures.                                               | \~40       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Chat composer shows model selection and context status without overlap on mobile and desktop.
* [ ] Configured-provider filtering hides non-configured ordinary provider rows only when configured providers exist.
* [ ] MoA preset rows remain visible regardless of configured-provider filtering.
* [ ] Selecting ordinary models sends the intended `model` and `provider` values to the admin chat action.
* [ ] Selecting MoA presets sends the preset name as `model` with provider `moa`.
* [ ] Context estimates update as draft text, local messages, selected session messages, and streamed output change.
* [ ] Fallback context metadata is visible as approximate context source, not exact tokenizer proof.

### Testing Requirements

* [ ] Focused component tests written and passing for selector, context meter, send payload, and layout behavior.
* [ ] Existing admin hook payload validation tests remain compatible.
* [ ] Existing Hermes model parser tests remain compatible.

### Non-Functional Requirements

* [ ] Selector and meter controls keep stable dimensions and no layout shift during loading, empty, error, and pending states.
* [ ] Browser-facing UI exposes only safe labels and product-facing copy.
* [ ] No generated private data, raw local paths, auth JSON paths, API keys, tokens, account IDs, or raw bridge diagnostics are introduced.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] Primary user-facing surfaces contain product-facing copy only.

***

## 8. Implementation Notes

### Working Assumptions

* `HermesChatTab` should own active model selection instead of persisting selection to Hermes config: Session 11 explicitly says to keep active model state in `HermesChatTab`, Session 04 already accepts per-request model/provider options, and the session is safe to complete without any local config mutation.
* MoA selector rows should be derived from `HermesModelsBody.mixtures` even when no ordinary provider is configured: the Session 11 stub requires configured-provider filtering not to hide MoA presets, and Session 06/08 made MoA discovery and model metadata browser-safe.

### Key Considerations

* Keep the selector and meter inside the Hermes chat component boundary rather than moving model logic into route files.
* Preserve graph grounding send options and image attachment behavior when adding model options.
* Use approximate language consistently for all token/context estimates.
* Do not add docs claims in this session; record behavior through tests and implementation notes for Session 17.

### Potential Challenges

* Selector default drift when model data loads after the chat tab renders: revalidate selection when model view changes and retain a valid current row when possible.
* Provider alias filtering can hide valid rows: use group provider aliases and configured provider IDs rather than model-name string guesses.
* Responsive toolbar crowding: give selector and meter bounded widths, wrap intentionally, and avoid placing cards inside cards.
* Existing grounded chat options can be overwritten accidentally: merge selected model/provider with existing `freshGrounding.sendOptions` explicitly.

### Relevant Considerations

* \[P38] **Upstream ports are semantic, not wholesale**: Build chat-owned AI OS components instead of copying the upstream monolithic route.
* \[P38] **Local control-plane gates are defense in depth**: Preserve the existing admin chat boundary and do not add new bridge writes.
* \[P38] **OpenAI Realtime keys stay environment-only**: Keep provider credentials out of browser bodies, UI state, fixtures, and docs.
* \[P00] **Stack conventions**: Stay within Bun, Vite 8, TanStack Start, React 19, Radix UI, and Cloudflare Worker constraints.
* \[P31-P39] **Public-demo, AI Rogue, and hosted-surface gates stay bundled**: Demo/public mode must remain fixture-only and write-disabled.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Remote model data may be loading, empty, stale, or malformed after parsing; selector and meter need explicit safe states.
* Send payloads can double-submit or lose existing graph/toolset options; selected model options must merge into the existing duplicate-trigger-protected send flow.
* Compact toolbar UI can overlap on small screens; selector, meter, buttons, and status copy need stable responsive constraints.

***

## 9. Testing Strategy

### Unit Tests

* `src/components/hermes/chat/__tests__/hermes-chat-tab.test.tsx`: selector default selection, configured-provider filtering, MoA row visibility, context estimate changes, ordinary and MoA send payloads, grounded option merging, and mobile-safe markup guards.
* `src/hooks/__tests__/use-hermes-admin.test.tsx`: run existing payload serialization and validation tests to prove selected model/provider options still pass the admin hook boundary.
* `src/lib/__tests__/hermes-types.test.ts`: run existing parser tests to prove model/context metadata contract compatibility.

### Integration Tests

* `src/components/hermes/__tests__/hermes-sections.test.tsx`: verify `HermesReadOnlyPage` passes model data into chat and direct `HermesChatTab` contract tests remain valid.

### Runtime Verification

* Start the app with `bun run dev` and inspect `/agents/hermes` chat in live or demo mode at desktop and mobile widths.
* Verify selector, context meter, composer, attach, send, cancel, reset, and Intelligence controls wrap cleanly without overlap.

### Edge Cases

* Model data loading, empty, error, offline, and demo states.
* Configured provider list contains `openai` while catalog has `openai`, `anthropic`, and `openrouter`.
* Configured provider list is empty, so all ordinary catalog rows remain visible.
* MoA mixture exists while configured ordinary providers are filtered.
* Selected model disappears after model data refresh.
* Active model has fallback context metadata.
* Draft reaches or exceeds the active context estimate.

***

## 10. Dependencies

### Other Sessions

* Depends on: `phase40-session02-models-and-provider-readiness`, `phase40-session04-chat-overrides-and-runtime`, `phase40-session08-catalog-and-context-metadata`.
* Depended by: `phase40-session12-compact-and-chat-polish`, `phase40-session13-command-ux-and-slash-actions`, `phase40-session15-ministry-config-analytics-and-save-ux`, `phase40-session18-full-validation-and-handoff`.

***

## Next Steps

Run the `implement` workflow step to begin implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ai-os-and-trend-finder.gitbook.io/ai-os-and-trend-finder-docs/.spec_system/archive/sessions/phase40-session11-chat-model-selector-and-context-meter/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
