From a3cc79575ff867c7ff2e522682c22753383d4d56 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 7 Sep 2026 01:41:53 +0000 Subject: [PATCH] docs(plugin-chatbot): compile the README's snippets against the shipped surface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Burns down `packages/plugin-chatbot/README.md`'s `UNGATED_DOCS` row in `scripts/check-doc-snippet-types.mjs` (objectui#5174 batch 30). Ten of the page's eleven `tsx` fences now compile in the gate's covered tier; the eleventh is a declared fragment naming objectui#8214. Two real defects the census found, both decided against the shipped surface: - The Quick Start taught an unannotated `useState([{ role: 'assistant' }])` for a typed prop, so `role` widened to `string` and `Chatbot` refused the array. Annotated `useState` with `ChatMessage[]`, and the new-message literal with `ChatMessage`. - The mapper example passed `onSend`, which `ChatbotEnhancedProps` does not declare and `ChatbotEnhanced.tsx` never reads — `onSend` is a `useObjectChat` option and an SDUI schema key, not a component prop. It also called `useChat({ api })`, a spelling `@ai-sdk/react@4.0.68` retired in favour of a transport. Both repaired to what the package itself writes. The residual is objectui#8214: `uiMessagesToChatMessages` declares its parameter as the package's own `AnyUIMessage[]`, whose `AnyPart.state` is the tool-invocation state union, so `@ai-sdk/react`'s `UIMessage` is refused at the call that export exists for. `src/**` is out of this batch's scope, so the block carries a fragment marker with the measured reason instead. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr --- packages/plugin-chatbot/README.md | 44 ++++++++++++++++++++++++----- scripts/check-doc-snippet-types.mjs | 2 -- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/packages/plugin-chatbot/README.md b/packages/plugin-chatbot/README.md index bc4155b14b..0b607af350 100644 --- a/packages/plugin-chatbot/README.md +++ b/packages/plugin-chatbot/README.md @@ -21,11 +21,17 @@ npm install @object-ui/plugin-chatbot ### Basic (Local/Demo Mode) +`ChatMessage` is this package's runtime message contract, and `role` on it is +the closed union `'user' | 'assistant' | 'system'`. Annotate the state with it: +an unannotated array literal widens `role` to `string`, which `` then +refuses. + ```tsx -import { Chatbot } from '@object-ui/plugin-chatbot'; +import { useState } from 'react'; +import { Chatbot, type ChatMessage } from '@object-ui/plugin-chatbot'; function App() { - const [messages, setMessages] = useState([ + const [messages, setMessages] = useState([ { id: '1', role: 'assistant', @@ -34,7 +40,7 @@ function App() { ]); const handleSend = (content: string) => { - const newMessage = { + const newMessage: ChatMessage = { id: Date.now().toString(), role: 'user', content @@ -344,20 +350,36 @@ of writing your own — they handle `parts: [{ type: 'text' | 'reasoning' | 'tool-*' | 'source-*' }]`, the streaming-cursor flag, and the legacy `msg.toolInvocations` fallback: +> ⚠️ Today this call needs a cast on the reader's side. `uiMessagesToChatMessages` +> declares its parameter as the package's own permissive `AnyUIMessage[]`, whose +> `AnyPart.state` is typed as the tool-invocation state union — so a `TextUIPart` +> carrying `state: 'streaming' | 'done'` is refused, and with it the whole +> `UIMessage[]` that `useChat()` returns. The block below is what you should +> write; it compiles once objectui#8214 widens that member. Nothing about the +> mapper's runtime behaviour is affected. + + + ```tsx import { useChat } from '@ai-sdk/react'; +import { DefaultChatTransport } from 'ai'; import { ChatbotEnhanced, uiMessagesToChatMessages, + type ChatbotEnhancedProps, } from '@object-ui/plugin-chatbot'; +declare const handleSend: ChatbotEnhancedProps['onSendMessage']; + function MyChat() { - const { messages, status } = useChat({ api: '/api/chat' }); + const { messages, status } = useChat({ + transport: new DefaultChatTransport({ api: '/api/chat' }), + }); const isStreaming = status === 'streaming' || status === 'submitted'; return ( ); } @@ -375,11 +397,15 @@ chat routes can use `surface="plain"` to remove the outer panel border and let messages, controls, and the prompt input sit in a continuous workspace: ```tsx +import { ChatbotEnhanced, type ChatMessage } from '@object-ui/plugin-chatbot'; + +declare const messages: ChatMessage[]; + +/>; ``` ### Agent process visibility @@ -394,10 +420,14 @@ Use `processVisibility="debug"` for developer or admin trace surfaces that need the full reasoning panel, raw tool names, tool parameters, and tool results: ```tsx +import { ChatbotEnhanced, type ChatMessage } from '@object-ui/plugin-chatbot'; + +declare const messages: ChatMessage[]; + +/>; ``` Use `processVisibility="hidden"` when a host wants to suppress non-interactive diff --git a/scripts/check-doc-snippet-types.mjs b/scripts/check-doc-snippet-types.mjs index 9a427c58d5..2a761c7dbd 100644 --- a/scripts/check-doc-snippet-types.mjs +++ b/scripts/check-doc-snippet-types.mjs @@ -779,8 +779,6 @@ const UNGATED_DOCS = { '2 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; 1 unresolved-module diagnostic(s)', 'packages/plugin-charts/README.md': '6 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies', - 'packages/plugin-chatbot/README.md': - '5 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; 1 unresolved-module diagnostic(s); plus TS17000x1 TS2322x1 — candidate real defects, un-triaged', 'packages/plugin-editor/README.md': '6 parse diagnostic(s) — blocks fenced `ts` that are bare object literals or elided bodies', 'packages/plugin-map/README.md':