juneau 0.3.4 → 0.4.1
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/README.md +64 -2
- package/dist/adapters/dashboardAdapter.d.ts.map +1 -1
- package/dist/adapters/mockAdapter.d.ts.map +1 -1
- package/dist/components/AiChat/AiChat.d.ts +8 -1
- package/dist/components/AiChat/AiChat.d.ts.map +1 -1
- package/dist/components/AiInput/AiInput.d.ts.map +1 -1
- package/dist/components/AiMessageBubble/AiMessageBubble.d.ts +4 -1
- package/dist/components/AiMessageBubble/AiMessageBubble.d.ts.map +1 -1
- package/dist/components/AiMessageList/AiMessageList.d.ts +4 -1
- package/dist/components/AiMessageList/AiMessageList.d.ts.map +1 -1
- package/dist/components/AiSidebar/AiSidebar.d.ts +8 -1
- package/dist/components/AiSidebar/AiSidebar.d.ts.map +1 -1
- package/dist/components/parts/AiMessagePartRenderer.d.ts +11 -1
- package/dist/components/parts/AiMessagePartRenderer.d.ts.map +1 -1
- package/dist/core/types.d.ts +14 -4
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.cjs +28 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2769 -2743
- package/dist/index.js.map +1 -1
- package/dist/server/createSkillSet.d.ts +0 -6
- package/dist/server/createSkillSet.d.ts.map +1 -1
- package/dist/server/index.cjs +9 -6
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +156 -123
- package/dist/server/index.js.map +1 -1
- package/dist/server/skillIndex.d.ts +25 -0
- package/dist/server/skillIndex.d.ts.map +1 -0
- package/dist/server/types.d.ts +45 -2
- package/dist/server/types.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -187,7 +187,7 @@ export const myAdapter: AiBackendAdapter = {
|
|
|
187
187
|
If your backend uses ai-sdk, Juneau ships server-side helpers that eliminate the boilerplate of history mapping, activity streaming, and tool failure recovery. Import from the `/server` subpath — zod stays out of the browser bundle.
|
|
188
188
|
|
|
189
189
|
```ts
|
|
190
|
-
import { toSdkMessages, createSkillSet, withToolRecovery } from 'juneau/server';
|
|
190
|
+
import { toSdkMessages, createSkillSet, buildSkillIndex, selectSkills, withToolRecovery } from 'juneau/server';
|
|
191
191
|
```
|
|
192
192
|
|
|
193
193
|
**Full integration in ~15 lines:**
|
|
@@ -199,7 +199,9 @@ import { z } from 'zod';
|
|
|
199
199
|
|
|
200
200
|
const skillSet = createSkillSet({
|
|
201
201
|
search: {
|
|
202
|
+
title: 'Record Search',
|
|
202
203
|
description: 'Search for records.',
|
|
204
|
+
instructions: 'Present results concisely. If cards are shown, write one sentence only.',
|
|
203
205
|
input: z.object({ query: z.string() }),
|
|
204
206
|
labels: {
|
|
205
207
|
running: { en: 'Searching…', cs: 'Vyhledávám…' },
|
|
@@ -226,10 +228,37 @@ Converts `AiMessage[]` to `CoreMessage[]` for ai-sdk. Extracts text from parts,
|
|
|
226
228
|
|
|
227
229
|
Wraps skill definitions into ai-sdk `tools` with a built-in activity buffer. Each tool call automatically emits `running` / `done` / `failed` Juneau wire SSE strings — no manual activity handling needed.
|
|
228
230
|
|
|
229
|
-
`
|
|
231
|
+
`execute` receives a `SkillExecuteContext` as its second argument with an `emit(part)` callback — push custom part wire events into the stream alongside the activities, e.g. an invoice card widget the frontend renders via `renderPart`:
|
|
232
|
+
|
|
233
|
+
```ts
|
|
234
|
+
execute: async ({ query }, { emit }) => {
|
|
235
|
+
const inv = await db.findInvoice(query);
|
|
236
|
+
emit({ type: 'invoice-card', invoiceNumber: inv.number, amount: inv.total });
|
|
237
|
+
return { found: 1, invoice: inv }; // returned to the model as the tool result
|
|
238
|
+
},
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Emitted parts share the activity buffer and are drained by `streamToWire` at the same points — they appear in the stream in emit order, before the model's text response.
|
|
242
|
+
|
|
243
|
+
Skill metadata: `title` (human-readable name), `instructions?` (agent workflow text — lazily loaded via `selectSkills`), `readOnly?` (default `true`), `requiresConfirmation?` (default `false`), `tools?` (skill composition — validated at startup, `createSkillSet` throws on a reference to an unknown skill).
|
|
244
|
+
|
|
245
|
+
`SkillSet` members: `tools`, `skills`, `calledSkillNames`, `drainActivities()`, `hadFailure`, `failureContext`.
|
|
230
246
|
|
|
231
247
|
`SkillSetOptions`: `language?` — selects label variant (`'en'` default). `debug?` — emit `console.debug` logs per skill execution (default: `false`).
|
|
232
248
|
|
|
249
|
+
#### `buildSkillIndex(skillSet)`
|
|
250
|
+
|
|
251
|
+
Generates a compact one-liner-per-skill index for the system prompt — registry-driven, so the prompt never drifts from the actual skills:
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
- invoiceSearch (read): Find invoices by number, supplier, date, or status.
|
|
255
|
+
- invoiceApprove (write, requires confirmation): Approve an invoice.
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
#### `selectSkills(skillSet, skillNames)`
|
|
259
|
+
|
|
260
|
+
Returns concatenated `instructions` for the given skill names — typically `skillSet.calledSkillNames` after phase 1, injected into phase 3's system prompt. Workflow instructions load lazily, only for skills the model actually used.
|
|
261
|
+
|
|
233
262
|
#### `streamToWire(fullStream, skillSet?, options?)`
|
|
234
263
|
|
|
235
264
|
Converts ai-sdk `fullStream` to Juneau wire SSE strings. Handles all ai-sdk v7 text chunk types (`text-delta` and `text`), drains activity buffer at the right moment, emits `done` at the end. Pass `{ debug: true }` to log every chunk received from ai-sdk.
|
|
@@ -453,6 +482,39 @@ function MyPage() {
|
|
|
453
482
|
| `actions` | `AiInputAction[]` | Toolbar buttons. |
|
|
454
483
|
| `sendIcon` | `ReactNode` | Override send button icon. |
|
|
455
484
|
| `placeholder` | `string` | Input placeholder text. |
|
|
485
|
+
| `renderPart` | `RenderPartFn` | Custom part renderer — see below. |
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## Custom part rendering — `renderPart`
|
|
490
|
+
|
|
491
|
+
Both `AiSidebar` and `AiChat` accept a `renderPart` prop — an escape hatch for rendering consumer-defined part types (or overriding built-in ones):
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
type RenderPartFn = (part: AiMessagePart) => ReactNode | null | undefined;
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
It is called **before** the built-in renderers for every message part. Return a ReactNode to render it; return `null`/`undefined` to fall through to the built-ins (`text`, `table`, `proposal`, `activity`, `error`).
|
|
498
|
+
|
|
499
|
+
The backend can stream any custom part through the standard wire protocol:
|
|
500
|
+
|
|
501
|
+
```json
|
|
502
|
+
{ "type": "part", "part": { "type": "invoice-card", "invoiceNumber": "23251", "amount": "1200.00" } }
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
`AiCustomPart` (`{ type: string; [key: string]: unknown }`) is part of the `AiMessagePart` union, so TypeScript accepts custom shapes on both ends. Juneau applies **no validation or narrowing** to custom parts — the consumer owns all type assertions:
|
|
506
|
+
|
|
507
|
+
```tsx
|
|
508
|
+
// Define your part type wherever you like — Juneau doesn't need to know about it
|
|
509
|
+
type InvoiceCardPart = { type: 'invoice-card'; invoiceNumber: string; amount: string };
|
|
510
|
+
|
|
511
|
+
<AiSidebar renderPart={part => {
|
|
512
|
+
if (part.type === 'invoice-card') return <InvoiceCard part={part as InvoiceCardPart} />;
|
|
513
|
+
return null; // everything else falls through to the built-ins
|
|
514
|
+
}} />
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
Unhandled custom part types show a dashed warning outline in development (so they're never a silent mystery) and render nothing in production.
|
|
456
518
|
|
|
457
519
|
---
|
|
458
520
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dashboardAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/dashboardAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAiC,MAAM,eAAe,CAAC;AAErF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"dashboardAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/dashboardAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAiC,MAAM,eAAe,CAAC;AAErF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,EAAE,gBAe9B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/mockAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAiC,MAAM,eAAe,CAAC;AAErF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"mockAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/mockAdapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAiC,MAAM,eAAe,CAAC;AAErF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,gBAmBzB,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import type { AiMessage } from '../../core/types';
|
|
3
3
|
import type { AiInputAction } from '../AiInput/AiInput';
|
|
4
|
+
import type { RenderPartFn } from '../parts/AiMessagePartRenderer';
|
|
4
5
|
type Props = {
|
|
5
6
|
messages: AiMessage[];
|
|
6
7
|
input: string;
|
|
@@ -24,6 +25,12 @@ type Props = {
|
|
|
24
25
|
actions?: AiInputAction[];
|
|
25
26
|
/** Override the send button icon. Defaults to a paper-plane icon. */
|
|
26
27
|
sendIcon?: ReactNode;
|
|
28
|
+
/**
|
|
29
|
+
* Custom part renderer — called before the built-in renderers for every
|
|
30
|
+
* message part. Return a ReactNode to render it, or null/undefined to fall
|
|
31
|
+
* through to the built-ins. Enables custom part types like invoice cards.
|
|
32
|
+
*/
|
|
33
|
+
renderPart?: RenderPartFn;
|
|
27
34
|
className?: string;
|
|
28
35
|
style?: CSSProperties;
|
|
29
36
|
};
|
|
@@ -35,6 +42,6 @@ type Props = {
|
|
|
35
42
|
* Used by AiSidebar (inside the sidebar chrome) and directly in dashboard
|
|
36
43
|
* or any other layout where you want chat without the sidebar wrapper.
|
|
37
44
|
*/
|
|
38
|
-
export declare function AiChat({ messages, input, isLoading, isConnecting, error, onInputChange, onSend, onStop, onProposalConfirm, onProposalCancel, placeholder, assistantIcon, actions, sendIcon, className, style, }: Props): import("react").JSX.Element;
|
|
45
|
+
export declare function AiChat({ messages, input, isLoading, isConnecting, error, onInputChange, onSend, onStop, onProposalConfirm, onProposalCancel, placeholder, assistantIcon, actions, sendIcon, renderPart, className, style, }: Props): import("react").JSX.Element;
|
|
39
46
|
export {};
|
|
40
47
|
//# sourceMappingURL=AiChat.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiChat.d.ts","sourceRoot":"","sources":["../../../src/components/AiChat/AiChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"AiChat.d.ts","sourceRoot":"","sources":["../../../src/components/AiChat/AiChat.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACtD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iGAAiG;IACjG,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClE,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B;;;;OAIG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,EACrB,QAAQ,EACR,KAAK,EACL,SAAS,EACT,YAAY,EACZ,KAAK,EACL,aAAa,EACb,MAAM,EACN,MAAM,EACN,iBAAiB,EACjB,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,OAAO,EACP,QAAQ,EACR,UAAU,EACV,SAAS,EACT,KAAK,GACN,EAAE,KAAK,+BA8BP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiInput.d.ts","sourceRoot":"","sources":["../../../src/components/AiInput/AiInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"AiInput.d.ts","sourceRoot":"","sources":["../../../src/components/AiInput/AiInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,OAAO,CAAC;AAatD,MAAM,MAAM,aAAa,GAAG;IAC1B,uCAAuC;IACvC,IAAI,EAAE,SAAS,CAAC;IAChB,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,KAAK,+BAmG5G"}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { AiMessage } from '../../core/types';
|
|
3
|
+
import type { RenderPartFn } from '../parts/AiMessagePartRenderer';
|
|
3
4
|
type Props = {
|
|
4
5
|
message: AiMessage;
|
|
5
6
|
onProposalConfirm: (proposalId: string, payload: unknown) => void;
|
|
6
7
|
onProposalCancel: (proposalId: string) => void;
|
|
7
8
|
/** Override the assistant avatar icon. Pass any ReactNode — an SVG, img, or component. Defaults to a brain icon. */
|
|
8
9
|
assistantIcon?: ReactNode;
|
|
10
|
+
/** Custom part renderer — forwarded to every AiMessagePartRenderer. */
|
|
11
|
+
renderPart?: RenderPartFn;
|
|
9
12
|
};
|
|
10
|
-
export declare function AiMessageBubble({ message, onProposalConfirm, onProposalCancel, assistantIcon }: Props): import("react").JSX.Element;
|
|
13
|
+
export declare function AiMessageBubble({ message, onProposalConfirm, onProposalCancel, assistantIcon, renderPart }: Props): import("react").JSX.Element;
|
|
11
14
|
export {};
|
|
12
15
|
//# sourceMappingURL=AiMessageBubble.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiMessageBubble.d.ts","sourceRoot":"","sources":["../../../src/components/AiMessageBubble/AiMessageBubble.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"AiMessageBubble.d.ts","sourceRoot":"","sources":["../../../src/components/AiMessageBubble/AiMessageBubble.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAGlD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,KAAK,KAAK,GAAG;IACX,OAAO,EAAE,SAAS,CAAC;IACnB,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClE,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,oHAAoH;IACpH,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,uEAAuE;IACvE,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,KAAK,+BA4BjH"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactNode } from 'react';
|
|
2
2
|
import type { AiMessage } from '../../core/types';
|
|
3
|
+
import type { RenderPartFn } from '../parts/AiMessagePartRenderer';
|
|
3
4
|
type Props = {
|
|
4
5
|
messages: AiMessage[];
|
|
5
6
|
isLoading: boolean;
|
|
@@ -9,7 +10,9 @@ type Props = {
|
|
|
9
10
|
onProposalCancel: (proposalId: string) => void;
|
|
10
11
|
/** Override the assistant avatar icon. Forwarded to every AiMessageBubble. */
|
|
11
12
|
assistantIcon?: ReactNode;
|
|
13
|
+
/** Custom part renderer — forwarded to every AiMessageBubble. */
|
|
14
|
+
renderPart?: RenderPartFn;
|
|
12
15
|
};
|
|
13
|
-
export declare function AiMessageList({ messages, isLoading, isConnecting, onProposalConfirm, onProposalCancel, assistantIcon }: Props): import("react").JSX.Element;
|
|
16
|
+
export declare function AiMessageList({ messages, isLoading, isConnecting, onProposalConfirm, onProposalCancel, assistantIcon, renderPart }: Props): import("react").JSX.Element;
|
|
14
17
|
export {};
|
|
15
18
|
//# sourceMappingURL=AiMessageList.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiMessageList.d.ts","sourceRoot":"","sources":["../../../src/components/AiMessageList/AiMessageList.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"AiMessageList.d.ts","sourceRoot":"","sources":["../../../src/components/AiMessageList/AiMessageList.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAIlD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,KAAK,KAAK,GAAG;IACX,QAAQ,EAAE,SAAS,EAAE,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,uGAAuG;IACvG,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClE,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,8EAA8E;IAC9E,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,iEAAiE;IACjE,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,KAAK,+BAoCzI"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from 'react';
|
|
2
2
|
import type { AiInputAction } from '../AiInput/AiInput';
|
|
3
|
+
import type { RenderPartFn } from '../parts/AiMessagePartRenderer';
|
|
3
4
|
type Props = {
|
|
4
5
|
/** Overrides the `sidebarTitle` label for this instance only. */
|
|
5
6
|
title?: string;
|
|
@@ -25,7 +26,13 @@ type Props = {
|
|
|
25
26
|
* and then invokes this callback — no wrapper component needed.
|
|
26
27
|
*/
|
|
27
28
|
onReset?: () => void;
|
|
29
|
+
/**
|
|
30
|
+
* Custom part renderer — called before the built-in renderers for every
|
|
31
|
+
* message part. Return a ReactNode to render it, or null/undefined to fall
|
|
32
|
+
* through to the built-ins. Enables custom part types like invoice cards.
|
|
33
|
+
*/
|
|
34
|
+
renderPart?: RenderPartFn;
|
|
28
35
|
};
|
|
29
|
-
export declare function AiSidebar({ title, icon, actions, sendIcon, height, className, style, onReset, }: Props): import("react").JSX.Element;
|
|
36
|
+
export declare function AiSidebar({ title, icon, actions, sendIcon, height, className, style, onReset, renderPart, }: Props): import("react").JSX.Element;
|
|
30
37
|
export {};
|
|
31
38
|
//# sourceMappingURL=AiSidebar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiSidebar.d.ts","sourceRoot":"","sources":["../../../src/components/AiSidebar/AiSidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"AiSidebar.d.ts","sourceRoot":"","sources":["../../../src/components/AiSidebar/AiSidebar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAGnE,KAAK,KAAK,GAAG;IACX,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,MAAe,EACf,SAAS,EACT,KAAK,EACL,OAAO,EACP,UAAU,GACX,EAAE,KAAK,+BAsDP"}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
1
2
|
import type { AiMessagePart } from '../../core/types';
|
|
3
|
+
/**
|
|
4
|
+
* Consumer escape hatch for rendering custom part types (or overriding
|
|
5
|
+
* built-in ones). Receives the raw part object with no narrowing or
|
|
6
|
+
* validation applied — the consumer owns all type assertions.
|
|
7
|
+
* Return null/undefined to fall through to the built-in renderers.
|
|
8
|
+
*/
|
|
9
|
+
export type RenderPartFn = (part: AiMessagePart) => ReactNode | null | undefined;
|
|
2
10
|
type Props = {
|
|
3
11
|
part: AiMessagePart;
|
|
4
12
|
onProposalConfirm: (proposalId: string, payload: unknown) => void;
|
|
5
13
|
onProposalCancel: (proposalId: string) => void;
|
|
14
|
+
/** Called before the built-in switch — a non-nullish return value wins. */
|
|
15
|
+
renderPart?: RenderPartFn;
|
|
6
16
|
};
|
|
7
|
-
export declare function AiMessagePartRenderer({ part, onProposalConfirm, onProposalCancel }: Props): import("react").JSX.Element;
|
|
17
|
+
export declare function AiMessagePartRenderer({ part, onProposalConfirm, onProposalCancel, renderPart }: Props): import("react").JSX.Element | null;
|
|
8
18
|
export {};
|
|
9
19
|
//# sourceMappingURL=AiMessagePartRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiMessagePartRenderer.d.ts","sourceRoot":"","sources":["../../../src/components/parts/AiMessagePartRenderer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AiMessagePartRenderer.d.ts","sourceRoot":"","sources":["../../../src/components/parts/AiMessagePartRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EACV,aAAa,EAMd,MAAM,kBAAkB,CAAC;AAO1B;;;;;GAKG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE,aAAa,KAAK,SAAS,GAAG,IAAI,GAAG,SAAS,CAAC;AAEjF,KAAK,KAAK,GAAG;IACX,IAAI,EAAE,aAAa,CAAC;IACpB,iBAAiB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAClE,gBAAgB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,2EAA2E;IAC3E,UAAU,CAAC,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,wBAAgB,qBAAqB,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,UAAU,EAAE,EAAE,KAAK,sCAsDrG"}
|
package/dist/core/types.d.ts
CHANGED
|
@@ -38,7 +38,17 @@ export type AiActivityPart = {
|
|
|
38
38
|
status: AiActivityStatus;
|
|
39
39
|
metadata?: Record<string, unknown>;
|
|
40
40
|
};
|
|
41
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Escape hatch for consumer-defined part types. Any part shape with a `type`
|
|
43
|
+
* string that isn't one of the built-ins flows through the wire protocol and
|
|
44
|
+
* message state untouched. Juneau applies no validation or narrowing — the
|
|
45
|
+
* consumer owns all type assertions in their `renderPart` implementation.
|
|
46
|
+
*/
|
|
47
|
+
export type AiCustomPart = {
|
|
48
|
+
type: string;
|
|
49
|
+
[key: string]: unknown;
|
|
50
|
+
};
|
|
51
|
+
export type AiMessagePart = AiTextPart | AiTablePart | AiProposalPart | AiActivityPart | AiErrorPart | AiCustomPart;
|
|
42
52
|
export type AiMessage = {
|
|
43
53
|
id: string;
|
|
44
54
|
role: AiMessageRole;
|
|
@@ -51,7 +61,7 @@ export type AiStreamTextEvent = {
|
|
|
51
61
|
};
|
|
52
62
|
export type AiStreamPartEvent = {
|
|
53
63
|
type: 'part';
|
|
54
|
-
part: AiTablePart | AiProposalPart | AiActivityPart | AiErrorPart;
|
|
64
|
+
part: AiTablePart | AiProposalPart | AiActivityPart | AiErrorPart | AiCustomPart;
|
|
55
65
|
};
|
|
56
66
|
export type AiStreamDoneEvent = {
|
|
57
67
|
type: 'done';
|
|
@@ -89,10 +99,10 @@ export type JuneauWireActivity = {
|
|
|
89
99
|
*/
|
|
90
100
|
metadata?: Record<string, unknown>;
|
|
91
101
|
};
|
|
92
|
-
/** Structured rich block — table or
|
|
102
|
+
/** Structured rich block — table, proposal, or any consumer-defined custom part */
|
|
93
103
|
export type JuneauWirePart = {
|
|
94
104
|
type: 'part';
|
|
95
|
-
part: AiTablePart | AiProposalPart;
|
|
105
|
+
part: AiTablePart | AiProposalPart | AiCustomPart;
|
|
96
106
|
};
|
|
97
107
|
/** Stream finished cleanly */
|
|
98
108
|
export type JuneauWireDone = {
|
package/dist/core/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;AAG5D,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,UAAU,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7D,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|