You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The chat stories fake the assistant's reply, so you can see the component but not use it.
Already there:src/components/AI/ozwellChat.ts — askOzwell, askOzwellStream, isOzwellConfigured. Documented in src/components/AI/OZWELL-BACKEND.md.
Gaps:
AIChat.stories.tsx
Five stories still use onSendMessage={(msg) => console.log(...)}
Uses ozwellChat.ts
Only AIChatVoice.stories.tsx and HeyOzwell/HandsFreeChat.stories.tsx
Configuring it
Pasting localStorage.setItem('ozwellConfig', {apiKey, baseURL}) into the console
Tasks
Wire AIChat to ozwellChat.ts, matching how the voice stories do it.
Add argTypes controls: backend (mock | live), environment (dev → https://ozwellapi.os.mieweb.org, prod → https://api.ozwell.ai), session (authenticate from the panel, not the console).
Add to the README: the playground is for playing. Production embedding is the loader script from the API origin, which mounts the widget in its own iframe — never importing this package directly.
// playground only
import { AIChat } from '@mieweb/ui'
// production
<script src="https://api.ozwell.ai/widget"></script>
Without that note, someone copies a story and ships an API key in their bundle.
Why the README note matters
The component lives here → ozwellai-api builds its widget from this package → the playground calls that API back. The loop is intentional, but it makes a story look like an integration example when it isn't.
To decide
Sign in as a real user (mieweb/ozwellai-api#263) or developer-supplies-a-key? Sign-in demos better; a key is less work.
Out of scope
Widget build and serving, the @mieweb/ui pin in ozwellai-api, widget sign-in itself.
Unverified
Whether dev/prod CORS allows a Storybook origin. If not, that's an ozwellai-api change.
The loop
flowchart LR
AIChat(["AIChat component - mieweb/ui"])
Build(["widget build - ozwellai-api"])
DevAPI(["dev API - ozwellapi.os.mieweb.org"])
ProdAPI(["prod API - api.ozwell.ai"])
Storybook(["Storybook - ui.mieweb.org"])
Page(["customer page"])
AIChat -->|"published as @mieweb/ui@next"| Build
AIChat -->|"deployed in"| Storybook
Build -->|"deployed to"| DevAPI
Build -->|"deployed to"| ProdAPI
Page -.->|"loads /widget, runs it in an iframe"| ProdAPI
Storybook -.->|"NEW - chats against dev"| DevAPI
Storybook -.->|"NEW - or against prod"| ProdAPI
Loading
Solid arrows are build and publish — how the code reaches the place it runs. Dashed arrows are runtime calls — who asks whom.
Two hosted pages consume the API. A customer page loads the loader script and gets the widget in an iframe. The Storybook renders the component directly and, once this ticket lands, chats against whichever API its control is set to. The same component reaching both sides is what makes the dependency circular.
The chat stories fake the assistant's reply, so you can see the component but not use it.
Already there:
src/components/AI/ozwellChat.ts—askOzwell,askOzwellStream,isOzwellConfigured. Documented insrc/components/AI/OZWELL-BACKEND.md.Gaps:
AIChat.stories.tsxonSendMessage={(msg) => console.log(...)}ozwellChat.tsAIChatVoice.stories.tsxandHeyOzwell/HandsFreeChat.stories.tsxlocalStorage.setItem('ozwellConfig', {apiKey, baseURL})into the consoleTasks
AIChattoozwellChat.ts, matching how the voice stories do it.argTypescontrols: backend (mock|live), environment (dev→https://ozwellapi.os.mieweb.org,prod→https://api.ozwell.ai), session (authenticate from the panel, not the console).Without that note, someone copies a story and ships an API key in their bundle.
Why the README note matters
The component lives here → ozwellai-api builds its widget from this package → the playground calls that API back. The loop is intentional, but it makes a story look like an integration example when it isn't.
To decide
Sign in as a real user (mieweb/ozwellai-api#263) or developer-supplies-a-key? Sign-in demos better; a key is less work.
Out of scope
Widget build and serving, the
@mieweb/uipin in ozwellai-api, widget sign-in itself.Unverified
Whether dev/prod CORS allows a Storybook origin. If not, that's an ozwellai-api change.
The loop
Solid arrows are build and publish — how the code reaches the place it runs. Dashed arrows are runtime calls — who asks whom.
Two hosted pages consume the API. A customer page loads the loader script and gets the widget in an iframe. The Storybook renders the component directly and, once this ticket lands, chats against whichever API its control is set to. The same component reaching both sides is what makes the dependency circular.