Skip to content

feat(packages): shared ModelSwitcher + credits modal, fetchLLM - #893

Merged
AbhinRustagi merged 35 commits into
mainfrom
abhin/pkg-updates
Jul 29, 2026
Merged

feat(packages): shared ModelSwitcher + credits modal, fetchLLM#893
AbhinRustagi merged 35 commits into
mainfrom
abhin/pkg-updates

Conversation

@AbhinRustagi

@AbhinRustagi AbhinRustagi commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Package updates that the openui-cloud / openui-self-hosted template slimming depends on. Merge + publish before the template PR (#894) so the template deps resolve on the registry.

  • react-ui (v0.14.0): ModelSwitcher block (/blocks + main entry) with theme-aware { light, dark } logo API and Tag-based badges; useSystemThemeMode hook; thread-header defaults (title hides when :empty, actions flex) replacing per-app CSS overrides.
  • react-headless (v0.10.0): fetchLLM gains buildBody; useFetchLLM hook (stable instance, live options); getResponseErrorMessage — the chat store now surfaces server error messages instead of generic status lines.
  • devtools (v0.0.2): OpenUICreditsModal (429 → credits notice via observability); dev-only gating.

Minor (not patch) bumps for react-ui/react-headless: both ship new API + behavior changes, so existing ^0.13.x / ^0.9.x consumers opt in rather than silently receiving them.

- react-ui: ModelSwitcher promoted to /blocks + main entry; theme-aware {light,dark} logo API (ModelLogo); v0.13.3
- react-headless: fetchLLM gains buildBody for custom request bodies (default AG-UI shape unchanged)
- devtools: OpenUICreditsModal (429 -> credits notice via observability) + CreditsModal; dev-only widget

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
AbhinRustagi and others added 15 commits July 28, 2026 19:15
Wraps fetchLLM in a render-tolerant hook — consumers get a stable ChatLLM from one call, no useState(() => fetchLLM(...)) or ref boilerplate. Options are read fresh per send, so a buildBody closing over current state stays live without extra refs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
Drops the custom pill markup + SCSS; the trigger keeps its compact dot (Tag has no icon-only mode).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
… blocks scss

- thread.scss: title self-hides when :empty; actions flex to fill (space-between) — replaces per-app overrides
- modelSwitcher.scss now @forward'ed from components/index.scss like every other component; drop the TS scss import, scss.d.ts, and the cp-css .mjs/.cjs rewrite hack

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
…esponses

Adds getResponseErrorMessage (parses error.message / error / message from the body, falls back to status text); the chat store now throws that instead of a generic 'Request failed: <status>'. Restores the behavior the template's deleted chat-error.ts provided, at the framework level — e.g. the cloud route's 429 billing message reaches the thread error UI again.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
System prefers-color-scheme via useSyncExternalStore; replaces per-app theme providers for system-driven apps.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
Minor (not patch) bumps: both ship new public API and behavior changes (thread-header layout defaults; store error messages). A patch would flow silently into existing ^0.13.x / ^0.9.x consumers — minor makes it opt-in.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
- adapters-and-formats: correct the default body (AG-UI shape, was documented as {threadId, messages}), document buildBody, add useFetchLLM example
- self-hosting/openui-cloud/skills: drop OPENUI_MODEL, hand-rolled ChatLLM example -> useFetchLLM, ModelSwitcher note

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
Raw SSE forwarded untouched instead of NDJSON re-encoding via toReadableStream; signal propagated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR
Comment thread skills/openui/SKILL.md Outdated
Comment thread skills/openui/references/cloud-integration.md Outdated
Comment thread skills/openui/references/cloud-integration.md Outdated
Comment thread packages/react-ui/cp-css.js Outdated
Comment thread packages/react-ui/tsdown.config.ts Outdated
Comment thread packages/react-ui/src/components/AgentInterface/thread.scss Outdated
Comment thread packages/react-headless/src/adapters/useFetchLLM.ts Outdated
Comment thread packages/react-headless/src/adapters/fetchLLM.ts Outdated
Comment thread packages/devtools/package.json Outdated
Comment thread docs/content/docs/agent/reference/self-hosting.mdx Outdated
@AbhinRustagi AbhinRustagi changed the title feat(packages): shared ModelSwitcher + credits modal, fetchLLM buildBody feat(packages): shared ModelSwitcher + credits modal, fetchLLM Jul 29, 2026
Comment thread packages/devtools/src/OpenUICreditsModal.tsx Outdated
Comment thread docs/content/docs/agent/reference/adapters-and-formats.mdx Outdated
Comment thread packages/react-headless/src/store/createChatStore.ts Outdated
abhithesys
abhithesys previously approved these changes Jul 29, 2026
@AbhinRustagi
AbhinRustagi enabled auto-merge (squash) July 29, 2026 12:24
@AbhinRustagi
AbhinRustagi merged commit 19617a2 into main Jul 29, 2026
1 of 2 checks passed
@AbhinRustagi
AbhinRustagi deleted the abhin/pkg-updates branch July 29, 2026 12:47
AbhinRustagi added a commit that referenced this pull request Jul 30, 2026
* refactor(openui-cloud): slim template onto shared @openuidev packages

- ModelSwitcher: use @openuidev/react-ui (drop local model-switcher/); pass provider logos as {light,dark}
- Billing: replace local BillingCreditsDialog with dev-only OpenUICreditsModal from @openuidev/devtools
- LLM: swap createCloudChatLLM for fetchLLM + buildBody (429 flows via observability); hold LLM in a ref
- Cleanup: remove unused deps, cloud-chat-llm, chat-error, cloud-chat-constants, orphaned CSS/logos

Depends on #893 (packages) being merged + published first.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* Update package.json

* refactor(openui-cloud): use the useFetchLLM hook for the chat LLM

Drops the local llmRef + selectedModelRef plumbing for useFetchLLM, which holds a stable instance and reads options fresh per send — buildBody closes over selectedModel directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* refactor(openui-self-hosted): use fetchLLM; drop react-headless/react-lang/tailwind deps

- page.tsx: replace hand-rolled ChatLLM with fetchLLM (imported from @openuidev/react-ui), buildBody sends { messages }
- drop Tailwind (trivial usage): minimal globals.css reset, inline layout style, delete postcss.config.mjs
- package.json: remove @openuidev/react-headless, @openuidev/react-lang, tailwindcss, @tailwindcss/postcss; react-ui -> 0.13.3

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* refactor(openui-cloud): drop thread-header CSS overrides now in react-ui

Title :empty-hide and actions flex are library defaults after the thread.scss change; the openui-cloud-thread-header hook class is unreferenced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* refactor(openui-cloud): adopt ref-commit simplifications

- route.ts: badRequest helper, NextResponse, model allowlist (reject unknown), propagate upstream errors with status — billing.ts deleted (store now surfaces server messages)
- theme: useSystemThemeMode from react-ui; delete use-system-theme.tsx; unwrap ThemeProvider in layout
- globals.css: trim to page shell + artifact compat (~18 lines); drop Tailwind + postcss.config.mjs + tailwind deps + vitest
- frontend-token: NextResponse, propagate upstream status

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* chore(templates): align to react-ui 0.14 / react-headless 0.10; add devtools to self-hosted

- cloud: ^0.14.0 / ^0.10.0
- self-hosted: react-ui ^0.14.0; OpenUIDevtools rendered dev-only in layout (devDependency)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* docs(templates): refresh READMEs for the slimmed starters

- cloud: drop OPENUI_MODEL, point at src/lib/models.tsx + /api/chat validation, list useFetchLLM/ModelSwitcher/devtools, pnpm-only
- self-hosted: add setup section (OPENAI_API_KEY), fix route path, pnpm-only

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* refactor(openui-self-hosted): forward raw SSE via .asResponse() + openAIAdapter

Drops the NDJSON re-encode (toReadableStream); propagates browser aborts via req.signal; model overridable with OPENAI_MODEL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* chore(cli): bump to 0.3.0 for the slimmed templates

Scaffolded output changes substantially (react-ui 0.14 / react-headless 0.10, fetchLLM/useFetchLLM wiring, devtools, removed billing/tailwind) — minor bump, matching the package versioning rationale.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* refactor(openui-cloud): consolidate react-ui imports, extract starters, trim comments

- import everything from @openuidev/react-ui (headless re-export); starters/prompt templates moved to src/lib/starters
- drop the now-trivial handleModelChange wrapper; use the logoPath const
- shorten route/model/component comments to the essentials (tool-loop's safety-rule docs kept)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* fix(openui-self-hosted): base sans font on body (Tailwind preflight used to provide it)

react-ui sets fonts per component, not on body — text that merely inherits fell back to the browser serif once Tailwind's preflight was removed. Same latent gap exists in the reference commit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* feat(openui-self-hosted): load Inter via next/font like the cloud template

Replaces the globals.css font-family fallback — next/font self-hosts Inter with built-in fallbacks, matching react-ui's --openui-font-body token.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MpABGCgS6C4HRdQSrwhPMR

* fix: update docs and match latest changes

* fix: update readme

* fix: add favicon

* fix: version match

* fix: format

* fix: styles

* fix: remove credits modal

* fix: update lockfiles

* update lock files

* Update self-hosting.mdx

* Update SKILL.md

* fix: update minimumReleaseAge rule

* fix: lockfiles

* fix: naming refactor

* rm pnpm-lock

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
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.

2 participants