@subako-ai/assistant-ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,202 @@
1
+
2
+ Apache License
3
+ Version 2.0, January 2004
4
+ http://www.apache.org/licenses/
5
+
6
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
+
8
+ 1. Definitions.
9
+
10
+ "License" shall mean the terms and conditions for use, reproduction,
11
+ and distribution as defined by Sections 1 through 9 of this document.
12
+
13
+ "Licensor" shall mean the copyright owner or entity authorized by
14
+ the copyright owner that is granting the License.
15
+
16
+ "Legal Entity" shall mean the union of the acting entity and all
17
+ other entities that control, are controlled by, or are under common
18
+ control with that entity. For the purposes of this definition,
19
+ "control" means (i) the power, direct or indirect, to cause the
20
+ direction or management of such entity, whether by contract or
21
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
22
+ outstanding shares, or (iii) beneficial ownership of such entity.
23
+
24
+ "You" (or "Your") shall mean an individual or Legal Entity
25
+ exercising permissions granted by this License.
26
+
27
+ "Source" form shall mean the preferred form for making modifications,
28
+ including but not limited to software source code, documentation
29
+ source, and configuration files.
30
+
31
+ "Object" form shall mean any form resulting from mechanical
32
+ transformation or translation of a Source form, including but
33
+ not limited to compiled object code, generated documentation,
34
+ and conversions to other media types.
35
+
36
+ "Work" shall mean the work of authorship, whether in Source or
37
+ Object form, made available under the License, as indicated by a
38
+ copyright notice that is included in or attached to the work
39
+ (an example is provided in the Appendix below).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based on (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and Derivative Works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control systems,
58
+ and issue tracking systems that are managed by, or on behalf of, the
59
+ Licensor for the purpose of discussing and improving the Work, but
60
+ excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to reproduce, prepare Derivative Works of,
71
+ publicly display, publicly perform, sublicense, and distribute the
72
+ Work and such Derivative Works in Source or Object form.
73
+
74
+ 3. Grant of Patent License. Subject to the terms and conditions of
75
+ this License, each Contributor hereby grants to You a perpetual,
76
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77
+ (except as stated in this section) patent license to make, have made,
78
+ use, offer to sell, sell, import, and otherwise transfer the Work,
79
+ where such license applies only to those patent claims licensable
80
+ by such Contributor that are necessarily infringed by their
81
+ Contribution(s) alone or by combination of their Contribution(s)
82
+ with the Work to which such Contribution(s) was submitted. If You
83
+ institute patent litigation against any entity (including a
84
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
85
+ or a Contribution incorporated within the Work constitutes direct
86
+ or contributory patent infringement, then any patent licenses
87
+ granted to You under this License for that Work shall terminate
88
+ as of the date such litigation is filed.
89
+
90
+ 4. Redistribution. You may reproduce and distribute copies of the
91
+ Work or Derivative Works thereof in any medium, with or without
92
+ modifications, and in Source or Object form, provided that You
93
+ meet the following conditions:
94
+
95
+ (a) You must give any other recipients of the Work or
96
+ Derivative Works a copy of this License; and
97
+
98
+ (b) You must cause any modified files to carry prominent notices
99
+ stating that You changed the files; and
100
+
101
+ (c) You must retain, in the Source form of any Derivative Works
102
+ that You distribute, all copyright, patent, trademark, and
103
+ attribution notices from the Source form of the Work,
104
+ excluding those notices that do not pertain to any part of
105
+ the Derivative Works; and
106
+
107
+ (d) If the Work includes a "NOTICE" text file as part of its
108
+ distribution, then any Derivative Works that You distribute must
109
+ include a readable copy of the attribution notices contained
110
+ within such NOTICE file, excluding those notices that do not
111
+ pertain to any part of the Derivative Works, in at least one
112
+ of the following places: within a NOTICE text file distributed
113
+ as part of the Derivative Works; within the Source form or
114
+ documentation, if provided along with the Derivative Works; or,
115
+ within a display generated by the Derivative Works, if and
116
+ wherever such third-party notices normally appear. The contents
117
+ of the NOTICE file are for informational purposes only and
118
+ do not modify the License. You may add Your own attribution
119
+ notices within Derivative Works that You distribute, alongside
120
+ or as an addendum to the NOTICE text from the Work, provided
121
+ that such additional attribution notices cannot be construed
122
+ as modifying the License.
123
+
124
+ You may add Your own copyright statement to Your modifications and
125
+ may provide additional or different license terms and conditions
126
+ for use, reproduction, or distribution of Your modifications, or
127
+ for any such Derivative Works as a whole, provided Your use,
128
+ reproduction, and distribution of the Work otherwise complies with
129
+ the conditions stated in this License.
130
+
131
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
132
+ any Contribution intentionally submitted for inclusion in the Work
133
+ by You to the Licensor shall be under the terms and conditions of
134
+ this License, without any additional terms or conditions.
135
+ Notwithstanding the above, nothing herein shall supersede or modify
136
+ the terms of any separate license agreement you may have executed
137
+ with Licensor regarding such Contributions.
138
+
139
+ 6. Trademarks. This License does not grant permission to use the trade
140
+ names, trademarks, service marks, or product names of the Licensor,
141
+ except as required for reasonable and customary use in describing the
142
+ origin of the Work and reproducing the content of the NOTICE file.
143
+
144
+ 7. Disclaimer of Warranty. Unless required by applicable law or
145
+ agreed to in writing, Licensor provides the Work (and each
146
+ Contributor provides its Contributions) on an "AS IS" BASIS,
147
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148
+ implied, including, without limitation, any warranties or conditions
149
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150
+ PARTICULAR PURPOSE. You are solely responsible for determining the
151
+ appropriateness of using or redistributing the Work and assume any
152
+ risks associated with Your exercise of permissions under this License.
153
+
154
+ 8. Limitation of Liability. In no event and under no legal theory,
155
+ whether in tort (including negligence), contract, or otherwise,
156
+ unless required by applicable law (such as deliberate and grossly
157
+ negligent acts) or agreed to in writing, shall any Contributor be
158
+ liable to You for damages, including any direct, indirect, special,
159
+ incidental, or consequential damages of any character arising as a
160
+ result of this License or out of the use or inability to use the
161
+ Work (including but not limited to damages for loss of goodwill,
162
+ work stoppage, computer failure or malfunction, or any and all
163
+ other commercial damages or losses), even if such Contributor
164
+ has been advised of the possibility of such damages.
165
+
166
+ 9. Accepting Warranty or Additional Liability. While redistributing
167
+ the Work or Derivative Works thereof, You may choose to offer,
168
+ and charge a fee for, acceptance of support, warranty, indemnity,
169
+ or other liability obligations and/or rights consistent with this
170
+ License. However, in accepting such obligations, You may act only
171
+ on Your own behalf and on Your sole responsibility, not on behalf
172
+ of any other Contributor, and only if You agree to indemnify,
173
+ defend, and hold each Contributor harmless for any liability
174
+ incurred by, or claims asserted against, such Contributor by reason
175
+ of your accepting any such warranty or additional liability.
176
+
177
+ END OF TERMS AND CONDITIONS
178
+
179
+ APPENDIX: How to apply the Apache License to your work.
180
+
181
+ To apply the Apache License to your work, attach the following
182
+ boilerplate notice, with the fields enclosed by brackets "[]"
183
+ replaced with your own identifying information. (Don't include
184
+ the brackets!) The text should be enclosed in the appropriate
185
+ comment syntax for the file format. We also recommend that a
186
+ file or class name and description of purpose be included on the
187
+ same "printed page" as the copyright notice for easier
188
+ identification within third-party archives.
189
+
190
+ Copyright 2026 Kikuvi, Inc.
191
+
192
+ Licensed under the Apache License, Version 2.0 (the "License");
193
+ you may not use this file except in compliance with the License.
194
+ You may obtain a copy of the License at
195
+
196
+ http://www.apache.org/licenses/LICENSE-2.0
197
+
198
+ Unless required by applicable law or agreed to in writing, software
199
+ distributed under the License is distributed on an "AS IS" BASIS,
200
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201
+ See the License for the specific language governing permissions and
202
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,300 @@
1
+ # @subako-ai/assistant-ui
2
+
3
+ [assistant-ui](https://www.assistant-ui.com) over a Subako session: one hook
4
+ that turns the session into an assistant-ui runtime, and one component that
5
+ renders a working chat with no setup at all.
6
+
7
+ Requires **React 19**, **`@assistant-ui/react` 0.15** with
8
+ **`@assistant-ui/react-markdown` 0.14**, and **Node 22 or newer** for the
9
+ build. The package is **ESM only**.
10
+
11
+ ```sh
12
+ pnpm add @subako-ai/assistant-ui @subako-ai/react @subako-ai/sdk @assistant-ui/react @assistant-ui/react-markdown
13
+ ```
14
+
15
+ ## Getting started
16
+
17
+ The provider and the session are `@subako-ai/react`'s; this package is what
18
+ draws them.
19
+
20
+ ```tsx
21
+ import { SubakoSessionClient } from "@subako-ai/sdk";
22
+ import { SubakoProvider, useSession } from "@subako-ai/react";
23
+ import { SubakoChat } from "@subako-ai/assistant-ui";
24
+
25
+ const subako = new SubakoSessionClient({
26
+ baseUrl: "https://api.kikuvi.com",
27
+ getToken: (sessionId) => fetch(`/api/subako/token/${sessionId}`).then((r) => r.text()),
28
+ });
29
+
30
+ function Assistant({ sessionId }: { sessionId: string }) {
31
+ // The app opens the session and hands it down, so the chat opens no second connection.
32
+ return <SubakoChat session={useSession(sessionId)} />;
33
+ }
34
+
35
+ export function App({ sessionId }: { sessionId: string }) {
36
+ return (
37
+ <SubakoProvider client={subako}>
38
+ <Assistant sessionId={sessionId} />
39
+ </SubakoProvider>
40
+ );
41
+ }
42
+ ```
43
+
44
+ That is the whole chat: the transcript, the tool calls with their results, the
45
+ approval prompt, a composer, and a stop button while a run is under way. The
46
+ assistant's text is drawn as markdown, tables and all, with links that open in
47
+ a new tab; what the person typed is shown as typed. The
48
+ `session` is the one the app opened — `useSession` hands back `null` until its
49
+ effect has connected, which the chat renders as an empty thread with a disabled
50
+ composer — so the tools the app declares and the thread share one connection. It
51
+ brings its own small stylesheet, so it renders acceptably with nothing else
52
+ installed — no CSS framework, no shadcn registry, no `@assistant-ui/styles`.
53
+ `className` lands on the root element for an app that wants to style it, and
54
+ the class names below are stable:
55
+
56
+ | Class | What it is |
57
+ | ------------------------------------------ | --------------------------------------------- |
58
+ | `.subako-chat` | The root. |
59
+ | `.subako-viewport` | The scrolling message list. |
60
+ | `.subako-message`, `-user`, `-assistant` | One bubble. |
61
+ | `.subako-markdown` | The assistant's body, as markdown. |
62
+ | `.subako-thinking` | A `thinking` block. |
63
+ | `.subako-tool` | One tool call, folded to its name and status. |
64
+ | `.subako-tool-args`, `.subako-tool-result` | The input and the output behind the fold. |
65
+ | `.subako-approval` | The allow / deny prompt. |
66
+ | `.subako-composer`, `.subako-input` | The composer. |
67
+
68
+ ### Overriding the styles
69
+
70
+ Every rule of the stylesheet sits in a cascade layer named `subako`. A rule
71
+ of the app's own that names one of the classes above wins over it, at any
72
+ specificity and from anywhere in the page:
73
+
74
+ ```css
75
+ .subako-user {
76
+ border-radius: 4px;
77
+ }
78
+ ```
79
+
80
+ A rule that names no class — a reset's `*` and `button`, the app's own `pre` —
81
+ does not reach the chat's own elements. Each of them carries a guard, in no
82
+ layer, that turns unlayered element rules away and takes the layered ones
83
+ instead, so Tailwind v3's preflight, a `normalize.css`, and the app's global
84
+ `button` all leave the chat as it is. The one rule of a reset's that still
85
+ reaches a button is `[type="button"]`, which names an attribute; it takes the
86
+ background only, and the buttons are the colour of the bar they sit on. A tool
87
+ UI the app draws itself is not guarded: that is the app's own markup.
88
+
89
+ An app whose CSS is layered itself — Tailwind v4 is one — says where `subako`
90
+ goes by naming it in its layer order, ahead of anything else that declares a
91
+ layer. After `base`, so preflight does not strip the chat's own buttons;
92
+ before `components` and `utilities`, so a class the app puts on the root, and
93
+ an override the app writes inside a layer of its own, both win:
94
+
95
+ ```css
96
+ @layer theme, base, subako, components, utilities;
97
+ @import "tailwindcss";
98
+ ```
99
+
100
+ Left unnamed, `subako` lands last and the chat's own rules beat the app's
101
+ layered ones.
102
+
103
+ ### A page with a Content Security Policy
104
+
105
+ The stylesheet above is an inline `<style>`, so a page whose `style-src-elem`
106
+ names a nonce drops it and the thread renders unstyled. Hand the chat the same
107
+ nonce the page puts on its own tags:
108
+
109
+ ```tsx
110
+ <SubakoChat session={session} nonce={cspNonce} />
111
+ ```
112
+
113
+ A page with no such policy needs nothing: left out, the attribute is not
114
+ written at all.
115
+
116
+ ### Colours
117
+
118
+ Every surface names its own colour and its own background, so the chat is
119
+ legible on a page of any colour instead of inheriting half of one. They come
120
+ from eight custom properties, light by default and dark under
121
+ `prefers-color-scheme: dark`; the root also carries `color-scheme: light dark`
122
+ so form controls follow. Set the properties on `.subako-chat` itself to theme
123
+ the chat with the app's own palette — a value set above it is shadowed by the
124
+ chat's own defaults — which is how an app
125
+ whose dark mode is a class or a `data-theme`, rather than the OS setting, keeps
126
+ the chat in step:
127
+
128
+ ```css
129
+ .subako-chat {
130
+ --subako-bg: var(--card);
131
+ --subako-fg: var(--ink);
132
+ --subako-muted: var(--dim);
133
+ --subako-accent: var(--accent);
134
+ --subako-accent-fg: #fff;
135
+ --subako-border: var(--line);
136
+ --subako-surface: var(--bg);
137
+ --subako-error: var(--danger);
138
+ color-scheme: inherit;
139
+ }
140
+ ```
141
+
142
+ `--subako-bg` is the panel, the composer and its controls; `--subako-surface`
143
+ is the raised one — the assistant bubble, the tool call's arguments and result,
144
+ the approval bar; `--subako-accent` with `--subako-accent-fg` is the user
145
+ bubble; `--subako-muted` is the reasoning block and the placeholder;
146
+ `--subako-error` is a failed tool result.
147
+
148
+ ## `useSubakoRuntime`
149
+
150
+ ```tsx
151
+ const session = useSession(sessionId);
152
+ const runtime = useSubakoRuntime(session);
153
+ ```
154
+
155
+ `useExternalStoreRuntime` over the session. The log stays the only store: the
156
+ runtime keeps no messages of its own, so a send that fails leaves the thread as
157
+ the server has it. A `null` session — the one `useSession` has yet to open — is
158
+ a thread with no messages and a composer that cannot be typed into.
159
+
160
+ The runtime subscribes to the session itself, with `@subako-ai/react`'s
161
+ `useSessionState`, so the thread follows the log wherever it is mounted. That
162
+ matters because `useSession` only acquires: hand the session to a `<SubakoChat>`
163
+ sitting in some provider's `children` and its props never change, so React would
164
+ never redraw it. Nothing above the chat has to re-render for a new message to
165
+ appear.
166
+
167
+ | assistant-ui | Subako |
168
+ | ------------------------- | -------------------------------------------------------------- |
169
+ | `messages` | `state.transcript`, through `convertMessage` |
170
+ | `isRunning` | `state.isRunning` |
171
+ | `onNew` | `send(text)`, over the text parts of the appended message |
172
+ | `onCancel` | `cancel()` |
173
+ | `onRespondToToolApproval` | `resolveApproval(callId, approved ? "allow" : "deny", reason)` |
174
+
175
+ The argument is anything carrying those members, or `null`, which is what
176
+ `useSession` hands back.
177
+
178
+ ### `convertMessage`
179
+
180
+ The pure half, exported so an app can convert a transcript without a runtime:
181
+
182
+ | Log | assistant-ui |
183
+ | ------------------ | ----------------------------------------------------------- |
184
+ | `text` block | a text part |
185
+ | `thinking` block | a reasoning part |
186
+ | `tool_call` block | a tool-call part, with the joined `tool_result` as its text |
187
+ | a pending approval | an approval with no decision, which is what shows a prompt |
188
+ | a settled approval | the same approval, carrying the decision |
189
+ | the event's `seq` | the message id |
190
+
191
+ The conversion is cached on the identity of the message object, not on the id,
192
+ and the connection's `transcript` folds a new event into the messages it already
193
+ made — replacing only the ones that event touched — so every other message is
194
+ converted once and stays converted. A user message carries where it came from as
195
+ `metadata.custom.source`.
196
+
197
+ ## Your own thread
198
+
199
+ `<SubakoChat>` exists for the first ten minutes. A real app keeps the runtime
200
+ and builds the thread from assistant-ui's primitives, or from the components
201
+ its shadcn registry installs:
202
+
203
+ ```tsx
204
+ function Chat({ sessionId }: { sessionId: string }) {
205
+ const session = useSession(sessionId);
206
+ const runtime = useSubakoRuntime(session);
207
+
208
+ return (
209
+ <AssistantRuntimeProvider runtime={runtime}>
210
+ <ThreadPrimitive.Root>
211
+ <ThreadPrimitive.Viewport>
212
+ <ThreadPrimitive.Messages components={{ UserMessage, AssistantMessage }} />
213
+ </ThreadPrimitive.Viewport>
214
+ <ComposerPrimitive.Root>
215
+ <ComposerPrimitive.Input />
216
+ <ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
217
+ </ComposerPrimitive.Root>
218
+ </ThreadPrimitive.Root>
219
+ </AssistantRuntimeProvider>
220
+ );
221
+ }
222
+ ```
223
+
224
+ The approval prompt is a tool-call part with an `approval` that carries no
225
+ decision; answer it with the part's own `respondToApproval({ approved })`, which
226
+ is what reaches `resolveApproval`. The stop button is
227
+ `<ComposerPrimitive.Cancel>`, which the runtime wires to `cancel()`.
228
+
229
+ ## Tool UI
230
+
231
+ A tool call renders as a row folded to its name and its status — running,
232
+ done, failed, needs approval, denied. Opening the row shows the input and the
233
+ output, laid out as JSON when they are JSON. The approval prompt sits outside
234
+ the fold, so a closed row still asks. To draw one of your tools yourself,
235
+ register a tool UI the ordinary assistant-ui way; it wins over the default row.
236
+ `<SubakoChat>` renders its children inside the runtime, which is where the
237
+ registration has to happen:
238
+
239
+ ```tsx
240
+ import { makeAssistantToolUI } from "@assistant-ui/react";
241
+
242
+ const FillForm = makeAssistantToolUI<{ email?: string }, string>({
243
+ toolName: "client__chat__fill_contact_form",
244
+ render: ({ args, result }) => (result === undefined ? <p>Filling…</p> : <p>Filled {args.email}</p>),
245
+ });
246
+
247
+ <SubakoChat session={session}>
248
+ <FillForm />
249
+ </SubakoChat>;
250
+ ```
251
+
252
+ The name is what the model sees the tool under, which for a client tool is
253
+ `client__<client name>__<tool>`.
254
+
255
+ ### `components`
256
+
257
+ The same renderers go on `<SubakoChat>` as `components`, which takes what
258
+ `MessagePrimitive.Parts` takes: `tools.by_name` for the tools named,
259
+ `tools.Fallback` for every other one in place of the chat's own row, and
260
+ `Text` for the body in place of the chat's own markdown — for a renderer with
261
+ a syntax highlighter, say, built on `MarkdownTextPrimitive` the way the chat's
262
+ is. The chat's body, its reasoning block and its tool row stay wherever nothing
263
+ is named.
264
+
265
+ ```tsx
266
+ function FilledForm({ args, result }: ToolCallMessagePartProps) {
267
+ return result === undefined ? <p>Filling…</p> : <p>Filled {String(args.email)}</p>;
268
+ }
269
+
270
+ <SubakoChat session={session} components={{ tools: { by_name: { client__chat__fill_contact_form: FilledForm } } }} />;
271
+ ```
272
+
273
+ ### `SubakoToolApproval`
274
+
275
+ A tool that needs approval has to ask for it from whatever draws it: a row of
276
+ the app's own gets `approval` and `respondToApproval` like any tool-call part,
277
+ and the run waits until something answers. `SubakoToolApproval` is the chat's
278
+ own prompt, for dropping in — Allow and Deny while the server waits on the
279
+ person, nothing once there is an answer or the run was cancelled:
280
+
281
+ ```tsx
282
+ import { SubakoToolApproval } from "@subako-ai/assistant-ui";
283
+
284
+ function Terse(props: ToolCallMessagePartProps) {
285
+ return (
286
+ <div>
287
+ {props.toolName}
288
+ <SubakoToolApproval {...props} />
289
+ </div>
290
+ );
291
+ }
292
+
293
+ <SubakoChat session={session} components={{ tools: { Fallback: Terse } }} />;
294
+ ```
295
+
296
+ ## What it does not do
297
+
298
+ No thread list, no branching, no editing, no attachments, no speech: the
299
+ session is one conversation, its log is append-only, and the runtime declares
300
+ only what the session can actually do.
package/dist/chat.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import type { ToolCallMessagePartProps } from "@assistant-ui/react";
2
+ import { MessagePrimitive } from "@assistant-ui/react";
3
+ import type { ComponentProps, ReactNode } from "react";
4
+ import type { SubakoSession } from "./runtime.js";
5
+ /** What the approval prompt reads off a tool-call part: the call's name, its approval, and the answer. */
6
+ export type SubakoToolApprovalProps = Pick<ToolCallMessagePartProps, "toolName" | "approval" | "respondToApproval">;
7
+ /**
8
+ * The approval prompt of the chat's own tool row, for a tool UI the app draws
9
+ * itself: Allow and Deny while the server waits on the person, and nothing
10
+ * once there is an answer or the run was cancelled. Spread the tool call's
11
+ * props into it; the answer reaches `resolveApproval` the same way.
12
+ */
13
+ export declare function SubakoToolApproval({ toolName, approval, respondToApproval }: SubakoToolApprovalProps): ReactNode;
14
+ /** The components an assistant message's parts are drawn with, as `MessagePrimitive.Parts` takes them. */
15
+ type PartComponents = NonNullable<ComponentProps<typeof MessagePrimitive.Parts>["components"]>;
16
+ export interface SubakoChatProps {
17
+ /** The connection from `useSession`, which is `null` until its effect has opened one. */
18
+ readonly session: SubakoSession | null;
19
+ /** Added to the root element, for an app that styles the thread itself. */
20
+ readonly className?: string;
21
+ /**
22
+ * The components an assistant message's parts are drawn with, as
23
+ * `MessagePrimitive.Parts` takes them: `Text` for the body, in place of the
24
+ * chat's own markdown; `tools` for the tool calls, whose `Fallback` replaces
25
+ * the chat's own row and whose `by_name` replaces it for the tools named.
26
+ * The chat's body, reasoning block and tool row stay wherever nothing is
27
+ * named.
28
+ */
29
+ readonly components?: PartComponents;
30
+ /**
31
+ * The page's CSP nonce, for a page whose `style-src-elem` names one. Without
32
+ * it the browser drops the chat's own stylesheet and the thread renders
33
+ * unstyled; a page with no such policy needs nothing here.
34
+ */
35
+ readonly nonce?: string;
36
+ /** Rendered inside the runtime, which is where a tool UI registers itself. */
37
+ readonly children?: ReactNode;
38
+ }
39
+ /**
40
+ * One session as a working chat: the transcript, the tool calls with their
41
+ * approvals, a composer, and a stop button while a run is under way. The
42
+ * session is the app's own, so the chat opens no second connection; until it
43
+ * has one the thread is empty and the composer is disabled. It exists for the
44
+ * first ten minutes; an app that wants its own thread keeps `useSubakoRuntime`
45
+ * and builds the rest from assistant-ui's primitives.
46
+ */
47
+ export declare function SubakoChat({ session, className, components, nonce, children }: SubakoChatProps): ReactNode;
48
+ export {};
49
+ //# sourceMappingURL=chat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat.d.ts","sourceRoot":"","sources":["../src/chat.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA6B,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAC/F,OAAO,EAIN,gBAAgB,EAEhB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAyKlD,0GAA0G;AAC1G,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,wBAAwB,EAAE,UAAU,GAAG,UAAU,GAAG,mBAAmB,CAAC,CAAC;AAEpH;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,EAAE,EAAE,uBAAuB,GAAG,SAAS,CAehH;AA8CD,0GAA0G;AAC1G,KAAK,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;AA0C/F,MAAM,WAAW,eAAe;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,eAAe,GAAG,SAAS,CAqB1G"}