{"_id":"@aganzefelicite/responsekit-react","_rev":"7-4b1ee59c10a06a69624e66f6a47c4ce5","name":"@aganzefelicite/responsekit-react","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@aganzefelicite/responsekit-react","version":"0.1.0","keywords":["react","ai","sse","streaming","renderer","analytics","charts"],"author":{"name":"aganzefelicite"},"license":"MIT","_id":"@aganzefelicite/responsekit-react@0.1.0","maintainers":[{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"}],"dist":{"shasum":"9282965c1b129b402b0e45ddfd9076c6384d827c","tarball":"https://registry.npmjs.org/@aganzefelicite/responsekit-react/-/responsekit-react-0.1.0.tgz","fileCount":17,"integrity":"sha512-xkrbuOCbbOgdpL0M5mder9AvNtpLzU2blhX50BeS0Hy0jvCLpt3oyheB+z9a63hZBLxJ4joiL78fkiVrCTIXKw==","signatures":[{"sig":"MEUCIQCrrViUp3TWfm/r6V/PdvWe8aGn+BSUf+k3w/gCb7gg+wIgLo7mwc6Qugkbe7Nz5ytunj2Y3+rBpgKonoQLiSEVqas=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1165912},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css"},"gitHead":"8ed4b9183e70d7926c44790289f86147aa5edb49","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"},"_npmVersion":"11.11.0","description":"Render your AI backend's responses as interactive React UI: AiRenderer, AiStream, useChat.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.0","dependencies":{"recharts":"^2.12.7","remark-gfm":"^4.0.0","react-markdown":"^9.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.4","jsdom":"^25.0.0","react":"^18.3.1","vitest":"^2.0.5","react-dom":"^18.3.1","typescript":"^5.5.4","@types/react":"^18.3.5","@types/react-dom":"^18.3.0","@responsekit/schema":"workspace:*","@testing-library/react":"^16.0.1","@testing-library/jest-dom":"^6.5.0"},"peerDependencies":{"react":">=18","react-dom":">=18"},"_npmOperationalInternal":{"tmp":"tmp/responsekit-react_0.1.0_1784836674631_0.8305535325567119","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aganzefelicite/responsekit-react","version":"0.2.0","keywords":["react","ai","sse","streaming","renderer","analytics","charts"],"author":{"name":"aganzefelicite"},"license":"MIT","_id":"@aganzefelicite/responsekit-react@0.2.0","maintainers":[{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"}],"dist":{"shasum":"aa7bc2f699608c1cc6b9d9423814be317637a1f5","tarball":"https://registry.npmjs.org/@aganzefelicite/responsekit-react/-/responsekit-react-0.2.0.tgz","fileCount":17,"integrity":"sha512-lpTxbtfhqRnGderex6t8ri5tmcpgvTzzP+1KEwQdGtRwJ0Hwn2f+zahlx+4pXP0KqS/yKveSUnPSPAfW+FBG0A==","signatures":[{"sig":"MEUCIALN/MwKxucFzQVofMuBVPyWAzbNiKdWfEmlxUbXdnlxAiEAnqmty5TQvwgkEe6PwNgwMLvVkmNKoMR4dBd7Mu1Pkns=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1233700},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css"},"gitHead":"e9dea026aede1c412a0d3abfcb491e064faac138","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"},"_npmVersion":"11.11.0","description":"Render your AI backend's responses as interactive React UI: AiRenderer, AiStream, useChat.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.0","dependencies":{"recharts":"^2.12.7","remark-gfm":"^4.0.0","react-markdown":"^9.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.4","jsdom":"^25.0.0","react":"^18.3.1","vitest":"^2.0.5","react-dom":"^18.3.1","typescript":"^5.5.4","@types/react":"^18.3.5","@types/react-dom":"^18.3.0","@responsekit/schema":"workspace:*","@testing-library/react":"^16.0.1","@testing-library/jest-dom":"^6.5.0"},"peerDependencies":{"react":">=18","react-dom":">=18"},"_npmOperationalInternal":{"tmp":"tmp/responsekit-react_0.2.0_1784872981402_0.1221266634254059","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@aganzefelicite/responsekit-react","version":"0.2.1","keywords":["react","ai","sse","streaming","renderer","analytics","charts"],"author":{"name":"aganzefelicite"},"license":"MIT","_id":"@aganzefelicite/responsekit-react@0.2.1","maintainers":[{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"}],"dist":{"shasum":"0306ee856b3c4b0ca94499d319055519e3598de8","tarball":"https://registry.npmjs.org/@aganzefelicite/responsekit-react/-/responsekit-react-0.2.1.tgz","fileCount":17,"integrity":"sha512-Q6AwNsJ1WVlZlN58GGHChS6XB6y8o+uTjsuIlMZKhf4/Ye3LLHE4tq6N5cAaNMs5WhsfI5QLon/b+JcO8I4ZSg==","signatures":[{"sig":"MEUCIQD3Sjp3gz3rQanAc/zNWvCyZRn3omOJ+d0I6DAmBAV2CwIgP/yQ3b2DNreUsfN2Tcdl5XawmALGfR6eNZgAKkFLogo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1233700},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css"},"gitHead":"6c8f8c08e3c55e7449a4137662b2928d01ed5821","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"},"_npmVersion":"11.11.0","description":"Render your AI backend's responses as interactive React UI: AiRenderer, AiStream, useChat.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.0","dependencies":{"recharts":"^2.12.7","remark-gfm":"^4.0.0","react-markdown":"^9.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.4","jsdom":"^25.0.0","react":"^18.3.1","vitest":"^2.0.5","react-dom":"^18.3.1","typescript":"^5.5.4","@types/react":"^18.3.5","@types/react-dom":"^18.3.0","@responsekit/schema":"workspace:*","@testing-library/react":"^16.0.1","@testing-library/jest-dom":"^6.5.0"},"peerDependencies":{"react":">=18","react-dom":">=18"},"_npmOperationalInternal":{"tmp":"tmp/responsekit-react_0.2.1_1784906137727_0.03988967599629345","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aganzefelicite/responsekit-react","version":"0.3.0","keywords":["react","ai","sse","streaming","renderer","analytics","charts"],"author":{"name":"aganzefelicite"},"license":"MIT","_id":"@aganzefelicite/responsekit-react@0.3.0","maintainers":[{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"}],"dist":{"shasum":"b1f0f2f8e13745f45f4657068b85dcf71908b8fb","tarball":"https://registry.npmjs.org/@aganzefelicite/responsekit-react/-/responsekit-react-0.3.0.tgz","fileCount":17,"integrity":"sha512-i/TAAAoAtVrfDPkvErM5cBHlDj2u41ydX6dwkTZu4mBMA/IwohkyMi+QDMHiMO6+Uj/Y1rlG7+KHpkat9jeRzg==","signatures":[{"sig":"MEQCIHX01LG/RlnM54NPDgbPOvbz+FxmNGyOLEFGQ2CJTVL5AiBAEWTB7Lepnlw5pOcmZY2AT38magnQAX5JDMS145+34Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1236039},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css"},"gitHead":"6c8f8c08e3c55e7449a4137662b2928d01ed5821","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"},"_npmVersion":"11.11.0","description":"Render your AI backend's responses as interactive React UI: AiRenderer, AiStream, useChat.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.0","dependencies":{"recharts":"^2.12.7","remark-gfm":"^4.0.0","react-markdown":"^9.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.4","jsdom":"^25.0.0","react":"^18.3.1","vitest":"^2.0.5","react-dom":"^18.3.1","typescript":"^5.5.4","@types/react":"^18.3.5","@types/react-dom":"^18.3.0","@responsekit/schema":"workspace:*","@testing-library/react":"^16.0.1","@testing-library/jest-dom":"^6.5.0"},"peerDependencies":{"react":">=18","react-dom":">=18"},"_npmOperationalInternal":{"tmp":"tmp/responsekit-react_0.3.0_1784908628413_0.12375737399620568","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@aganzefelicite/responsekit-react","version":"0.3.1","keywords":["react","ai","sse","streaming","renderer","analytics","charts"],"author":{"name":"aganzefelicite"},"license":"MIT","_id":"@aganzefelicite/responsekit-react@0.3.1","maintainers":[{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"}],"dist":{"shasum":"5c0f0776bfc11a4200787b648b8f17b43e05c63e","tarball":"https://registry.npmjs.org/@aganzefelicite/responsekit-react/-/responsekit-react-0.3.1.tgz","fileCount":2,"integrity":"sha512-ftlEA7jF/UgRgybITLoNtTYsJ+3ujINzNQZT5Ri8JVe6hSlrwTz/usDhzE00jMBJVV6hpQBKGw8vR6zPI6dG6Q==","signatures":[{"sig":"MEUCIQCBC2L5Y/E3u5qemfvjExltcQXML+/kb0FZRyKFlrO2BgIgHwEibgFLnjs54aoNTdSv1ARrBHpLa6oCqUUVj4efoyU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":5573},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css"},"gitHead":"e7a60f67ea58da2c10a6a6ff67dda9b027f874f7","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"},"_npmVersion":"11.11.0","description":"Render your AI backend's responses as interactive React UI: AiRenderer, AiStream, useChat.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.0","dependencies":{"recharts":"^2.12.7","remark-gfm":"^4.0.0","react-markdown":"^9.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.4","jsdom":"^25.0.0","react":"^18.3.1","vitest":"^2.0.5","react-dom":"^18.3.1","typescript":"^5.5.4","@types/react":"^18.3.5","@types/react-dom":"^18.3.0","@responsekit/schema":"workspace:*","@testing-library/react":"^16.0.1","@testing-library/jest-dom":"^6.5.0"},"peerDependencies":{"react":">=18","react-dom":">=18"},"_npmOperationalInternal":{"tmp":"tmp/responsekit-react_0.3.1_1785261759005_0.892935949211491","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@aganzefelicite/responsekit-react","version":"0.3.2","keywords":["react","ai","sse","streaming","renderer","analytics","charts"],"author":{"name":"aganzefelicite"},"license":"MIT","_id":"@aganzefelicite/responsekit-react@0.3.2","maintainers":[{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"}],"dist":{"shasum":"92f4067dfd620f33066254153beb9ab61ade87ff","tarball":"https://registry.npmjs.org/@aganzefelicite/responsekit-react/-/responsekit-react-0.3.2.tgz","fileCount":17,"integrity":"sha512-oa2ezy/q3VBWY5g3In2tA0chzL3RGVwly0FicxZWYSqCJvLUSCTS98+Ijc2+hUMa+qv3C4h5UhivHUxNSWTXXw==","signatures":[{"sig":"MEQCIFcGIT84bgQHctsCOhdWuaKMLf6QFVO5I1c0Y7o8h8cfAiB2wrMdK/LV0Z8WFl7ZETegXKH3YGXBzb9fHdz6VOI5yw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1267829},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css"},"gitHead":"e7a60f67ea58da2c10a6a6ff67dda9b027f874f7","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","prepack":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"},"_npmVersion":"11.11.0","description":"Render your AI backend's responses as interactive React UI: AiRenderer, AiStream, useChat.","directories":{},"sideEffects":false,"_nodeVersion":"25.8.0","dependencies":{"recharts":"^2.12.7","remark-gfm":"^4.0.0","react-markdown":"^9.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.4","jsdom":"^25.0.0","react":"^18.3.1","vitest":"^2.0.5","react-dom":"^18.3.1","typescript":"^5.5.4","@types/react":"^18.3.5","@types/react-dom":"^18.3.0","@responsekit/schema":"workspace:*","@testing-library/react":"^16.0.1","@testing-library/jest-dom":"^6.5.0"},"peerDependencies":{"react":">=18","react-dom":">=18"},"_npmOperationalInternal":{"tmp":"tmp/responsekit-react_0.3.2_1785262396054_0.38444067454322295","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@aganzefelicite/responsekit-react","version":"0.4.0","description":"Render your AI backend's responses as interactive React UI: branded AiChat, login, AiRenderer, AiStream, useChat, admin client.","license":"MIT","author":{"name":"aganzefelicite"},"keywords":["react","ai","sse","streaming","renderer","analytics","charts"],"type":"module","sideEffects":false,"publishConfig":{"access":"public"},"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"},"./styles.css":"./dist/styles.css"},"dependencies":{"react-markdown":"^9.0.1","recharts":"^2.12.7","remark-gfm":"^4.0.0"},"peerDependencies":{"react":">=18","react-dom":">=18"},"devDependencies":{"@testing-library/react":"^16.0.1","@testing-library/jest-dom":"^6.5.0","@types/react":"^18.3.5","@types/react-dom":"^18.3.0","jsdom":"^25.0.0","react":"^18.3.1","react-dom":"^18.3.1","tsup":"^8.2.4","typescript":"^5.5.4","vitest":"^2.0.5","@responsekit/schema":"0.0.0"},"scripts":{"build":"tsup","dev":"tsup --watch","typecheck":"tsc --noEmit","test":"vitest run"},"_id":"@aganzefelicite/responsekit-react@0.4.0","_integrity":"sha512-KIbPGhopFA+0xWfGFi7gSaMxEBLfOVgx4PZOg163Gwg4+SmL+mrzHmt2Qy98o1JvjYHFUgTFfycjfE3tu7Jgtw==","_resolved":"/private/var/folders/m2/tylvd3013jngqvcnkfmkjs3m0000gn/T/7982f5319a50118d109c5d70e0b96241/aganzefelicite-responsekit-react-0.4.0.tgz","_from":"file:aganzefelicite-responsekit-react-0.4.0.tgz","_nodeVersion":"25.8.0","_npmVersion":"11.11.0","dist":{"integrity":"sha512-KIbPGhopFA+0xWfGFi7gSaMxEBLfOVgx4PZOg163Gwg4+SmL+mrzHmt2Qy98o1JvjYHFUgTFfycjfE3tu7Jgtw==","shasum":"22d7aec5a956252569c213509d4d7fb7c0a9bbb3","tarball":"https://registry.npmjs.org/@aganzefelicite/responsekit-react/-/responsekit-react-0.4.0.tgz","fileCount":17,"unpackedSize":1465227,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD2wrBZbs+W/wdNqQgMlxc7YabGIa0kQxAHXyAKv7tgpwIhAN8tAu77rlu+1gFlC1i/Mi4IkYEKNVhfN8e80PtfDwMQ"}]},"_npmUser":{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"},"directories":{},"maintainers":[{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/responsekit-react_0.4.0_1785350309294_0.8346573709498306"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-23T19:57:54.448Z","modified":"2026-07-29T18:38:29.615Z","0.1.0":"2026-07-23T19:57:54.796Z","0.2.0":"2026-07-24T06:03:01.551Z","0.2.1":"2026-07-24T15:15:38.002Z","0.3.0":"2026-07-24T15:57:08.563Z","0.3.1":"2026-07-28T18:02:39.150Z","0.3.2":"2026-07-28T18:13:16.223Z","0.4.0":"2026-07-29T18:38:29.451Z"},"author":{"name":"aganzefelicite"},"license":"MIT","keywords":["react","ai","sse","streaming","renderer","analytics","charts"],"description":"Render your AI backend's responses as interactive React UI: branded AiChat, login, AiRenderer, AiStream, useChat, admin client.","maintainers":[{"name":"aganzefelicite","email":"feliciteaganze@gmail.com"}],"readme":"# @aganzefelicite/responsekit-react\n\nRender your AI backend's responses as interactive React UI. Point it at your backend and\nit turns the standardized response contract (streamed as SSE or a single object) into\ncomponents — safely, and without ever crashing on unknown or invalid data.\n\n- **Renders only** — never calls an AI model or generates responses.\n- **Never crashes** — unknown block types / missing fields degrade to a safe fallback.\n- **Safe by default** — AI text is GitHub-flavored Markdown with **no raw HTML**; data\n  values are escaped. No `dangerouslySetInnerHTML`.\n- **Lean bundle** — tree-shakeable ESM, React as a peer dep; charts (Recharts) are\n  lazy-loaded into their own chunk.\n\n> Full walkthrough: **[Adding ResponseKit to an existing project](../../docs/INTEGRATION.md)**.\n\n## Install\n\n```bash\npnpm add @aganzefelicite/responsekit-react react react-dom\n```\n\n```ts\nimport \"@aganzefelicite/responsekit-react/styles.css\"; // optional default styling\n```\n\nThe response-contract package (types + zod validators + SSE reducer) is bundled in and\nre-exported, so there's nothing else to install. `react`/`react-dom` are peer deps (>=18).\n\n## Drop-in branded chat (`<AiChat />`)\n\nThe fastest path: paste the **URL the admin platform generated** and get a fully branded,\nauthenticated chat. `<AiChat>` fetches the branding (name, theme, colors, logo) from the\nbackend, shows a login form, then renders the chat — scoped to that user's own conversations.\n\n```tsx\nimport { AiChat } from \"@aganzefelicite/responsekit-react\";\nimport \"@aganzefelicite/responsekit-react/styles.css\";\n\n// The URL an admin generated in the admin console.\n<AiChat baseUrl=\"https://assistant.acme.com\" />;\n```\n\n- `floating` (default `true`) renders the draggable widget; set `false` to embed inline.\n- The session token is persisted in `localStorage`; a `Log out` button clears it.\n- Theme comes from the admin's branding (`data-theme` + `--rk-primary` / `--rk-accent`).\n\nPrefer to build your own UI? Use the pieces directly:\n\n```tsx\nimport { useAuth, useWorkspaceConfig, useChat } from \"@aganzefelicite/responsekit-react\";\n\nconst { config } = useWorkspaceConfig(baseUrl);                        // branding\nconst { token, user, login, logout, headers } = useAuth({ baseUrl });  // login + token\nconst chat = useChat({ baseUrl, headers });                            // authenticated chat\n```\n\n## Admin client\n\nFor building an admin console (or scripts), `admin.*` wraps the platform's `/api/admin/**`\nendpoints. Every call takes an ADMIN `token`.\n\n```ts\nimport { admin } from \"@aganzefelicite/responsekit-react\";\n\nawait admin.updateWorkspace({ baseUrl, token, name: \"Acme Insights\", theme: \"dark\" });\nawait admin.uploadLogo({ baseUrl, token, file });\nawait admin.createUser({ baseUrl, token, username: \"bob\", password: \"••••••••\", role: \"USER\" });\nawait admin.updateContext({ baseUrl, token, text: \"Orders = one row per order…\" });\nawait admin.testDatabase({ baseUrl, token, uri: \"postgresql://readonly:••@db/analytics\" });\nawait admin.updateDatabase({ baseUrl, token, uri }); // probes, persists, reconnects MCP\n```\n\n## Quick start\n\n```tsx\nimport { AiRenderer, AiStream, useChat } from \"@aganzefelicite/responsekit-react\";\n\n// 1) Render a response you already have\n<AiRenderer response={response} onAction={(a) => {}} />;\n\n// 2) Stream one message\n<AiStream baseUrl=\"\" conversationId={id} message=\"How many open cases?\" onAction={(a) => {}} />;\n\n// 3) A whole conversation\nconst { turns, send, isStreaming, newConversation } = useChat({ baseUrl: \"\" });\n```\n\n`baseUrl` is prepended to the API paths; `\"\"` means same-origin (proxy `/api` to your\nbackend). The message endpoint is POST + `text/event-stream`; the SDK drives\n`fetch` + `ReadableStream` internally (native `EventSource` can't POST).\n\n## API\n\n**Components** — `AiRenderer`, `AiStream`, `AiWidget` (draggable/resizable pop-up)\n**Hooks** — `useAiStream`, `useChat`\n**Actions** — `withDefaultActions`, `runDefaultAction`, `performDownload`, `performOpenLink`, `triggerDownload`\n**Registry** — `registerBlock`, `unregisterBlock`, `resolveBlockComponent`\n**Default blocks** — `TextBlock`, `KpiBlock`, `ChartBlock`, `TableBlock`, `InsightBlock`,\n`RecommendationBlock`, `FilterBlock`, `FallbackBlock`, `defaultBlockComponents`\n**Conversation REST** — `createConversation`, `listConversations`, `getConversation`,\n`renameConversation`, `deleteConversation`, `getMessages`\n**Transport** — `streamMessage`, `messageUrl`\n**Misc** — `Markdown`, `ErrorBoundary`, action types, and everything re-exported from\n[`@responsekit/schema`](../schema) (types, validators, the stream reducer).\n\n## Overrides & custom blocks\n\n```tsx\n// override built-ins for one render\n<AiRenderer response={r} components={{ KPI: MyKpi, CHART: MyChart }} />;\n\n// register a custom/unknown block type globally\nimport { registerBlock } from \"@aganzefelicite/responsekit-react\";\nregisterBlock({ type: \"MAP\", component: RwandaMap });\n```\n\nResolution order per block type: `components` prop → globally registered → built-in default\n→ graceful fallback.\n\n## Floating widget\n\nWrap any content in a draggable, resizable pop-up with a launcher button:\n\n```tsx\nimport { AiWidget } from \"@aganzefelicite/responsekit-react\";\n\n<AiWidget title=\"Assistant\" defaultOpen>\n  {/* useChat + AiRenderer, a single AiRenderer, or your own chat UI */}\n</AiWidget>;\n```\n\nDrag by the header, resize from the bottom-right corner, toggle via the launcher (or\ncontrol `open`/`onOpenChange`). Chrome only — it never touches your data flow.\n\n## Actions\n\nBlocks emit intent through one `onAction(action)` callback (`DOWNLOAD`, `OPEN_LINK`,\n`REFRESH`, `CUSTOM`, or host-defined). The SDK never runs business logic — but for the two\nactions with an obvious browser behavior it ships a default. Wrap your handler with\n`withDefaultActions` and CSV/JSON/Blob downloads and link-opens work out of the box:\n\n```tsx\nimport { withDefaultActions } from \"@aganzefelicite/responsekit-react\";\n<AiRenderer response={r} onAction={withDefaultActions((a) => track(a))} />;\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}