@alexkroman1/aai-ui 13.2.0 → 14.0.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/README.md +159 -69
- package/dist/{_colors-j8XMToi9.js → _colors-CpZO-88A.js} +25 -2
- package/dist/{_module-url-C_4gRVL0.js → _module-url-C13kAJ87.js} +1 -1
- package/dist/_recover-run.d.ts +13 -7
- package/dist/_submission-state.d.ts +92 -0
- package/dist/_upload-files.d.ts +2 -2
- package/dist/_upload-report.d.ts +26 -0
- package/dist/{_utils-B6498_bm.js → _utils-DnQDM9Uy.js} +4 -4
- package/dist/_utils.d.ts +3 -3
- package/dist/_web-storage.d.ts +43 -0
- package/dist/_workflow-files.d.ts +1 -1
- package/dist/{aai-logo-CXZGPSIY.js → aai-logo-CFlomZlS.js} +1 -1
- package/dist/agent-state-labels.d.ts +60 -0
- package/dist/audio.js +21 -15
- package/dist/{chat-view-DDTtrh7N.js → chat-view-C_3T7Ln8.js} +100 -33
- package/dist/{client-config-BT_kWID5.js → client-config-DJQHnYjm.js} +5 -5
- package/dist/client-config.d.ts +4 -4
- package/dist/client-dir.d.ts +1 -1
- package/dist/client-dir.js +2 -2
- package/dist/components/_colors.d.ts +23 -0
- package/dist/components/_form-readiness.d.ts +1 -1
- package/dist/components/bullet-list.d.ts +74 -0
- package/dist/components/button.js +4 -4
- package/dist/components/chat-view.js +1 -1
- package/dist/components/console-shell.d.ts +16 -20
- package/dist/components/controls.js +4 -4
- package/dist/components/facts.d.ts +81 -0
- package/dist/components/form-fields.d.ts +6 -6
- package/dist/components/form-types.d.ts +1 -1
- package/dist/components/form.d.ts +1 -1
- package/dist/components/message-list.js +1 -1
- package/dist/components/session-error-banner.d.ts +69 -0
- package/dist/components/sidebar-layout.js +1 -1
- package/dist/components/start-screen.js +4 -4
- package/dist/components/tool-call-block.js +1 -1
- package/dist/components/tool-config-context.d.ts +1 -1
- package/dist/components/workflow-progress.d.ts +11 -4
- package/dist/context.d.ts +142 -19
- package/dist/context.js +156 -18
- package/dist/default-client/assets/{audio-BuDICbPf.js → audio-9zQsNc1w.js} +1 -1
- package/dist/default-client/assets/index-BTv30Z4F.css +2 -0
- package/dist/default-client/assets/index-RAZ-29Sz.js +284 -0
- package/dist/default-client/index.html +2 -2
- package/dist/default-client.d.ts +1 -1
- package/dist/define-client.d.ts +19 -19
- package/dist/define-client.js +20 -20
- package/dist/{eyebrow-C6ZFuiz6.js → eyebrow-UfmSz9yy.js} +1 -1
- package/dist/hooks.d.ts +44 -8
- package/dist/hooks.js +20 -14
- package/dist/index.d.ts +13 -8
- package/dist/index.js +1447 -1160
- package/dist/internal.d.ts +2 -2
- package/dist/internal.js +5 -5
- package/dist/{message-list-BJYyuIcR.js → message-list-CdOnSh5m.js} +23 -16
- package/dist/page.d.ts +11 -11
- package/dist/session-core-audio-setup.d.ts +1 -1
- package/dist/session-core-dial.d.ts +0 -2
- package/dist/{session-core-DxBYsfHA.js → session-core-gwePM95B.js} +135 -62
- package/dist/session-core-messages.d.ts +2 -2
- package/dist/session-core-types.d.ts +58 -1
- package/dist/session-core.d.ts +6 -6
- package/dist/session-core.js +2 -2
- package/dist/session-resume-store.d.ts +3 -3
- package/dist/{tool-call-block-tcPQAkcP.js → tool-call-block-C2t_5fpp.js} +30 -12
- package/dist/{tool-config-context-DzAofqi_.js → tool-config-context-Es4YUzV2.js} +2 -2
- package/dist/types.d.ts +19 -4
- package/dist/types.js +3 -3
- package/dist/{url-chips-YqhCjWfQ.js → url-chips-BxhzZgk2.js} +5 -5
- package/dist/use-conversation.d.ts +1 -1
- package/dist/use-run-key.d.ts +44 -10
- package/dist/{use-user-transcript-C14qWFu2.js → use-user-transcript-uyHhzy4d.js} +4 -3
- package/dist/use-workflow-form.d.ts +64 -91
- package/dist/{use-workflow-progress-Cu0SxMyg.js → use-workflow-run-CP2ekKPV.js} +254 -257
- package/dist/use-workflow-stream.d.ts +5 -2
- package/dist/use-workflows.d.ts +77 -0
- package/dist/workflow-client.d.ts +1 -1
- package/dist/worklets/capture-processor.js +2 -2
- package/dist/worklets/playback-processor.js +2 -2
- package/package.json +6 -6
- package/styles.css +78 -0
- package/dist/default-client/assets/index-B1_ROnTJ.js +0 -284
- package/dist/default-client/assets/index-S5fkKi6B.css +0 -2
- package/dist/tsdown.config.d.ts +0 -2
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
<title>aai</title>
|
|
7
7
|
<link rel="icon" href="./favicon.ico" />
|
|
8
8
|
<style>html, body { background: #FBF8F2; margin: 0; }</style>
|
|
9
|
-
<script type="module" crossorigin src="./assets/index-
|
|
9
|
+
<script type="module" crossorigin src="./assets/index-RAZ-29Sz.js"></script>
|
|
10
10
|
<link rel="modulepreload" crossorigin href="./assets/client-audio-constants-CP13UQZt.js">
|
|
11
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
11
|
+
<link rel="stylesheet" crossorigin href="./assets/index-BTv30Z4F.css">
|
|
12
12
|
</head>
|
|
13
13
|
<body>
|
|
14
14
|
<main id="app"></main>
|
package/dist/default-client.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** @jsxImportSource react */
|
|
2
|
-
import "
|
|
2
|
+
import "../styles.css";
|
package/dist/define-client.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/** @jsxImportSource react */
|
|
2
2
|
import { type ComponentType, type ReactNode } from "react";
|
|
3
3
|
import { type ToolDisplayConfig } from "./components/tool-config-context.ts";
|
|
4
|
-
import type {
|
|
4
|
+
import type { BrowserSession } from "./session-core-types.ts";
|
|
5
5
|
import type { ClientTheme, VoiceSessionOptions } from "./types.ts";
|
|
6
6
|
/**
|
|
7
|
-
* Configuration passed to {@link
|
|
7
|
+
* Configuration passed to {@link mountClient}.
|
|
8
8
|
*
|
|
9
9
|
* The session-forwarded fields are picked from {@link VoiceSessionOptions}
|
|
10
10
|
* (one source of truth for types and docs) rather than re-declared — a
|
|
11
11
|
* re-declared copy is exactly how doc comments drift. It is NOT the session's
|
|
12
12
|
* own options type: that is {@link VoiceSessionOptions}, which
|
|
13
|
-
* `
|
|
13
|
+
* `createBrowserSession` takes and which three of these fields come from.
|
|
14
14
|
*
|
|
15
15
|
* @remarks
|
|
16
16
|
* **One flat type, not a union of tiers.** `component` is what decides which
|
|
@@ -19,12 +19,12 @@ import type { ClientTheme, VoiceSessionOptions } from "./types.ts";
|
|
|
19
19
|
* and that decision is made at runtime, where every field can be honoured. It
|
|
20
20
|
* used to be a union whose two arms banned each other's fields with `?: never`,
|
|
21
21
|
* and the failure that shape produces is recorded twice in this file's history:
|
|
22
|
-
* `
|
|
22
|
+
* `mountClient({ name, component })` and `mountClient({ component, tools })` were both
|
|
23
23
|
* the natural thing to write, both were refused with *"Type 'string' is not
|
|
24
24
|
* assignable to type 'undefined'"*, and both cost a build round each time
|
|
25
25
|
* before the ban was lifted. What was left banned was `sidebar` beside a
|
|
26
26
|
* `component`, which invited the identical failure for a combination
|
|
27
|
-
* {@link
|
|
27
|
+
* {@link mountClient} can simply render.
|
|
28
28
|
*
|
|
29
29
|
* @public
|
|
30
30
|
*/
|
|
@@ -81,7 +81,7 @@ export type ClientConfig = Pick<VoiceSessionOptions, "onSessionId" | "resumeSess
|
|
|
81
81
|
/**
|
|
82
82
|
* Tool display config: icon and label overrides keyed by tool name.
|
|
83
83
|
*
|
|
84
|
-
* Honoured with a custom `component` too: {@link
|
|
84
|
+
* Honoured with a custom `component` too: {@link mountClient} installs it into
|
|
85
85
|
* `ToolConfigContext`, and the consumer is `ToolCallBlock` — which a custom
|
|
86
86
|
* component renders as soon as it uses `MessageList` or `ChatView`, the usual
|
|
87
87
|
* way to build one.
|
|
@@ -89,7 +89,7 @@ export type ClientConfig = Pick<VoiceSessionOptions, "onSessionId" | "resumeSess
|
|
|
89
89
|
tools?: ToolDisplayConfig;
|
|
90
90
|
};
|
|
91
91
|
/**
|
|
92
|
-
* Handle returned by {@link
|
|
92
|
+
* Handle returned by {@link mountClient} for cleanup.
|
|
93
93
|
*
|
|
94
94
|
* Implements `Disposable` so it can be used with `using`.
|
|
95
95
|
*
|
|
@@ -97,7 +97,7 @@ export type ClientConfig = Pick<VoiceSessionOptions, "onSessionId" | "resumeSess
|
|
|
97
97
|
*/
|
|
98
98
|
export type ClientHandle = {
|
|
99
99
|
/** The underlying session core. */
|
|
100
|
-
session:
|
|
100
|
+
session: BrowserSession;
|
|
101
101
|
/** Unmount the UI and disconnect the session. */
|
|
102
102
|
dispose(): void;
|
|
103
103
|
/** Alias for `dispose` for use with `using`. */
|
|
@@ -106,7 +106,7 @@ export type ClientHandle = {
|
|
|
106
106
|
/**
|
|
107
107
|
* The element a mount renders into.
|
|
108
108
|
*
|
|
109
|
-
* Exported so `
|
|
109
|
+
* Exported so `mountPage()` resolves its target the same way `mountClient()` does — the
|
|
110
110
|
* default selector and the "element not found" sentence are part of what an
|
|
111
111
|
* author has learned, and a second copy is how the two mounts come to disagree
|
|
112
112
|
* about which one they were given.
|
|
@@ -120,7 +120,7 @@ export declare function resolveContainer(target?: string | HTMLElement): HTMLEle
|
|
|
120
120
|
* @internal
|
|
121
121
|
*/
|
|
122
122
|
export type MountedRoot = {
|
|
123
|
-
/** Unmount the React tree (and, for `
|
|
123
|
+
/** Unmount the React tree (and, for `mountClient()`, dispose the session). */
|
|
124
124
|
dispose(): void;
|
|
125
125
|
/** Alias for `dispose` for use with `using`. */
|
|
126
126
|
[Symbol.dispose](): void;
|
|
@@ -128,15 +128,15 @@ export type MountedRoot = {
|
|
|
128
128
|
/**
|
|
129
129
|
* Render `node` into `container` and hand back its teardown.
|
|
130
130
|
*
|
|
131
|
-
* Shared by {@link
|
|
131
|
+
* Shared by {@link mountClient} and `mountPage()` because the plumbing is identical and
|
|
132
132
|
* the two decisions in it are not obvious enough to be re-derived: the root is
|
|
133
133
|
* created here rather than by the caller so nothing else can hold one, and the
|
|
134
134
|
* render is `flushSync` so the mount is observable to the caller's NEXT
|
|
135
|
-
* STATEMENT (and to a test) rather than scheduled — `
|
|
136
|
-
* whose session is expected to be live, and `
|
|
135
|
+
* STATEMENT (and to a test) rather than scheduled — `mountClient()` returns a handle
|
|
136
|
+
* whose session is expected to be live, and `mountPage()` returns one a caller may
|
|
137
137
|
* dispose immediately.
|
|
138
138
|
*
|
|
139
|
-
* `onDispose` runs after the unmount, which is the order `
|
|
139
|
+
* `onDispose` runs after the unmount, which is the order `mountClient()` needs: the
|
|
140
140
|
* tree comes down before the session under it goes away.
|
|
141
141
|
*
|
|
142
142
|
* @internal
|
|
@@ -159,13 +159,13 @@ export declare function mountRoot(container: HTMLElement, node: ReactNode, onDis
|
|
|
159
159
|
*
|
|
160
160
|
* @example The default shell
|
|
161
161
|
* ```tsx
|
|
162
|
-
* import {
|
|
162
|
+
* import { mountClient } from "@alexkroman1/aai-ui";
|
|
163
163
|
*
|
|
164
164
|
* function OrderPanel() {
|
|
165
165
|
* return <div>Cart</div>;
|
|
166
166
|
* }
|
|
167
167
|
*
|
|
168
|
-
*
|
|
168
|
+
* mountClient({
|
|
169
169
|
* name: "Pizza Ordering",
|
|
170
170
|
* theme: { bg: "#1a1a1a", primary: "#e55" },
|
|
171
171
|
* sidebar: OrderPanel,
|
|
@@ -175,14 +175,14 @@ export declare function mountRoot(container: HTMLElement, node: ReactNode, onDis
|
|
|
175
175
|
*
|
|
176
176
|
* @example A custom component
|
|
177
177
|
* ```tsx
|
|
178
|
-
* import {
|
|
178
|
+
* import { mountClient, useSession } from "@alexkroman1/aai-ui";
|
|
179
179
|
*
|
|
180
180
|
* function MyCustomApp() {
|
|
181
181
|
* const session = useSession();
|
|
182
182
|
* return <div>{session.state}</div>;
|
|
183
183
|
* }
|
|
184
184
|
*
|
|
185
|
-
*
|
|
185
|
+
* mountClient({ component: MyCustomApp });
|
|
186
186
|
* ```
|
|
187
187
|
*
|
|
188
188
|
* @returns A {@link ClientHandle} for cleanup.
|
|
@@ -190,4 +190,4 @@ export declare function mountRoot(container: HTMLElement, node: ReactNode, onDis
|
|
|
190
190
|
*
|
|
191
191
|
* @public
|
|
192
192
|
*/
|
|
193
|
-
export declare function
|
|
193
|
+
export declare function mountClient(config: ClientConfig): ClientHandle;
|
package/dist/define-client.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { n as fetchClientConfig } from "./client-config-
|
|
1
|
+
import { n as fetchClientConfig } from "./client-config-DJQHnYjm.js";
|
|
2
2
|
import { SessionProvider, ThemeProvider } from "./context.js";
|
|
3
|
-
import { t as ChatView } from "./chat-view-
|
|
4
|
-
import { n as setPageTitle, t as pageBaseUrl } from "./_utils-
|
|
5
|
-
import { t as ToolConfigContext } from "./tool-config-context-
|
|
3
|
+
import { t as ChatView } from "./chat-view-C_3T7Ln8.js";
|
|
4
|
+
import { n as setPageTitle, t as pageBaseUrl } from "./_utils-DnQDM9Uy.js";
|
|
5
|
+
import { t as ToolConfigContext } from "./tool-config-context-Es4YUzV2.js";
|
|
6
6
|
import { SidebarLayout } from "./components/sidebar-layout.js";
|
|
7
7
|
import { StartScreen } from "./components/start-screen.js";
|
|
8
|
-
import { t as
|
|
8
|
+
import { t as createBrowserSession } from "./session-core-gwePM95B.js";
|
|
9
9
|
import { jsx } from "react/jsx-runtime";
|
|
10
10
|
import { createElement, useEffect, useState } from "react";
|
|
11
11
|
import { flushSync } from "react-dom";
|
|
12
12
|
import { createRoot } from "react-dom/client";
|
|
13
|
-
//#region define-client.tsx
|
|
13
|
+
//#region src/define-client.tsx
|
|
14
14
|
/** @jsxImportSource react */
|
|
15
15
|
/**
|
|
16
16
|
* The element a mount renders into.
|
|
17
17
|
*
|
|
18
|
-
* Exported so `
|
|
18
|
+
* Exported so `mountPage()` resolves its target the same way `mountClient()` does — the
|
|
19
19
|
* default selector and the "element not found" sentence are part of what an
|
|
20
20
|
* author has learned, and a second copy is how the two mounts come to disagree
|
|
21
21
|
* about which one they were given.
|
|
@@ -31,15 +31,15 @@ function resolveContainer(target = "#app") {
|
|
|
31
31
|
/**
|
|
32
32
|
* Render `node` into `container` and hand back its teardown.
|
|
33
33
|
*
|
|
34
|
-
* Shared by {@link
|
|
34
|
+
* Shared by {@link mountClient} and `mountPage()` because the plumbing is identical and
|
|
35
35
|
* the two decisions in it are not obvious enough to be re-derived: the root is
|
|
36
36
|
* created here rather than by the caller so nothing else can hold one, and the
|
|
37
37
|
* render is `flushSync` so the mount is observable to the caller's NEXT
|
|
38
|
-
* STATEMENT (and to a test) rather than scheduled — `
|
|
39
|
-
* whose session is expected to be live, and `
|
|
38
|
+
* STATEMENT (and to a test) rather than scheduled — `mountClient()` returns a handle
|
|
39
|
+
* whose session is expected to be live, and `mountPage()` returns one a caller may
|
|
40
40
|
* dispose immediately.
|
|
41
41
|
*
|
|
42
|
-
* `onDispose` runs after the unmount, which is the order `
|
|
42
|
+
* `onDispose` runs after the unmount, which is the order `mountClient()` needs: the
|
|
43
43
|
* tree comes down before the session under it goes away.
|
|
44
44
|
*
|
|
45
45
|
* @internal
|
|
@@ -90,7 +90,7 @@ function DefaultShell({ name, icon, subtitle, buttonText, Sidebar, ...layout })
|
|
|
90
90
|
*
|
|
91
91
|
* **The lookup is SKIPPED when the caller already named the agent.** The
|
|
92
92
|
* response's only consumer here is the fallback below, so with an explicit
|
|
93
|
-
* `
|
|
93
|
+
* `mountClient({ name })` the request was issued and its answer thrown away — and on
|
|
94
94
|
* the platform this endpoint is the BROKER, so the discarded request is one that
|
|
95
95
|
* can boot a sandbox. The session's own per-attempt lookup
|
|
96
96
|
* (`session-core.ts`'s URL provider) is a different question and deliberately
|
|
@@ -122,7 +122,7 @@ function DefaultRoot({ platformUrl, ...display }) {
|
|
|
122
122
|
*
|
|
123
123
|
* A custom component owns the whole page, so there is no header to hang a
|
|
124
124
|
* `sidebar` off — but the layout the default shell uses is right here, and
|
|
125
|
-
* `
|
|
125
|
+
* `mountClient({ component, sidebar })` names one pane and one aside, which is
|
|
126
126
|
* exactly what it renders. Honouring the combination rather than ignoring it is
|
|
127
127
|
* the same call this file already made for `name` and `tools`.
|
|
128
128
|
*/
|
|
@@ -164,13 +164,13 @@ function rootFor(config, platformUrl) {
|
|
|
164
164
|
*
|
|
165
165
|
* @example The default shell
|
|
166
166
|
* ```tsx
|
|
167
|
-
* import {
|
|
167
|
+
* import { mountClient } from "@alexkroman1/aai-ui";
|
|
168
168
|
*
|
|
169
169
|
* function OrderPanel() {
|
|
170
170
|
* return <div>Cart</div>;
|
|
171
171
|
* }
|
|
172
172
|
*
|
|
173
|
-
*
|
|
173
|
+
* mountClient({
|
|
174
174
|
* name: "Pizza Ordering",
|
|
175
175
|
* theme: { bg: "#1a1a1a", primary: "#e55" },
|
|
176
176
|
* sidebar: OrderPanel,
|
|
@@ -180,14 +180,14 @@ function rootFor(config, platformUrl) {
|
|
|
180
180
|
*
|
|
181
181
|
* @example A custom component
|
|
182
182
|
* ```tsx
|
|
183
|
-
* import {
|
|
183
|
+
* import { mountClient, useSession } from "@alexkroman1/aai-ui";
|
|
184
184
|
*
|
|
185
185
|
* function MyCustomApp() {
|
|
186
186
|
* const session = useSession();
|
|
187
187
|
* return <div>{session.state}</div>;
|
|
188
188
|
* }
|
|
189
189
|
*
|
|
190
|
-
*
|
|
190
|
+
* mountClient({ component: MyCustomApp });
|
|
191
191
|
* ```
|
|
192
192
|
*
|
|
193
193
|
* @returns A {@link ClientHandle} for cleanup.
|
|
@@ -195,10 +195,10 @@ function rootFor(config, platformUrl) {
|
|
|
195
195
|
*
|
|
196
196
|
* @public
|
|
197
197
|
*/
|
|
198
|
-
function
|
|
198
|
+
function mountClient(config) {
|
|
199
199
|
const container = resolveContainer(config.target);
|
|
200
200
|
const platformUrl = config.platformUrl ?? pageBaseUrl();
|
|
201
|
-
const session =
|
|
201
|
+
const session = createBrowserSession({
|
|
202
202
|
platformUrl,
|
|
203
203
|
onSessionId: config.onSessionId,
|
|
204
204
|
resumeSessionId: config.resumeSessionId,
|
|
@@ -213,4 +213,4 @@ function client(config) {
|
|
|
213
213
|
};
|
|
214
214
|
}
|
|
215
215
|
//#endregion
|
|
216
|
-
export {
|
|
216
|
+
export { mountClient, mountRoot, resolveContainer };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useTheme } from "./context.js";
|
|
2
2
|
import clsx from "clsx";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
//#region components/eyebrow.tsx
|
|
4
|
+
//#region src/components/eyebrow.tsx
|
|
5
5
|
/** @jsxImportSource react */
|
|
6
6
|
/**
|
|
7
7
|
* Eyebrow label — the design system's small outlined pill with ALL-CAPS,
|
package/dist/hooks.d.ts
CHANGED
|
@@ -24,15 +24,26 @@ import type { ToolCallInfo } from "./types.ts";
|
|
|
24
24
|
* }
|
|
25
25
|
* ```
|
|
26
26
|
*
|
|
27
|
-
* @typeParam R - The result shape. Defaults to
|
|
28
|
-
* (`any`)
|
|
29
|
-
* `
|
|
27
|
+
* @typeParam R - The result shape. Defaults to `unknown`, NOT to
|
|
28
|
+
* {@link DefaultToolResult} (`any`): the return type is inferred perfectly
|
|
29
|
+
* at `tool()` and this hook is the one place a client reads it, so an `any`
|
|
30
|
+
* default threw the whole inference away exactly where it was wanted —
|
|
31
|
+
* `useToolResult("get_order", (r) => r.a.b.c.d.e)` reported nothing. It is
|
|
32
|
+
* the tool's own shape that belongs here, and the spelling that costs a
|
|
33
|
+
* browser bundle nothing is a TYPE-ONLY import of the tool module:
|
|
34
|
+
* `import type getOrder from "./tools/get_order.ts"` is erased, so
|
|
35
|
+
* `useToolResult<InferToolOutput<typeof getOrder>>(…)` pulls no host code
|
|
36
|
+
* into the client graph. `useToolResult<Quote>(…)` against a hand-written
|
|
37
|
+
* shape is the other spelling. {@link DefaultToolResult} itself stays `any`
|
|
38
|
+
* — see `ToolCallInfo.args` for why a value the framework cannot see is
|
|
39
|
+
* typed that way at REST; the argument does not extend to a call site whose
|
|
40
|
+
* whole job is to name the shape.
|
|
30
41
|
* @param toolName - Only calls of this tool fire the callback.
|
|
31
42
|
* @param callback - Called with the parsed result and the call itself.
|
|
32
43
|
*
|
|
33
44
|
* @public
|
|
34
45
|
*/
|
|
35
|
-
export declare function useToolResult<R =
|
|
46
|
+
export declare function useToolResult<R = unknown>(toolName: string, callback: (result: R, toolCall: ToolCallInfo) => void): void;
|
|
36
47
|
/**
|
|
37
48
|
* Fire a callback when ANY tool call settles — the tool's name is the
|
|
38
49
|
* callback's first argument.
|
|
@@ -54,13 +65,16 @@ export declare function useToolResult<R = DefaultToolResult>(toolName: string, c
|
|
|
54
65
|
* }
|
|
55
66
|
* ```
|
|
56
67
|
*
|
|
57
|
-
* @typeParam R - The result shape. Defaults to
|
|
68
|
+
* @typeParam R - The result shape. Defaults to `unknown`, for the reason the
|
|
69
|
+
* filtered overload's `@typeParam` gives. A log renderer is the one caller
|
|
70
|
+
* that legitimately wants no shape, and `unknown` is what it should say:
|
|
71
|
+
* `JSON.stringify(result)` takes it unchanged.
|
|
58
72
|
* @param callback - Called with the tool's name, the parsed result, and the
|
|
59
73
|
* call itself.
|
|
60
74
|
*
|
|
61
75
|
* @public
|
|
62
76
|
*/
|
|
63
|
-
export declare function useToolResult<R =
|
|
77
|
+
export declare function useToolResult<R = unknown>(callback: (name: string, result: R, toolCall: ToolCallInfo) => void): void;
|
|
64
78
|
/**
|
|
65
79
|
* The agent's projected session state, or `null` before the first push.
|
|
66
80
|
*
|
|
@@ -198,12 +212,28 @@ export declare function useEvent<T = unknown>(event: string, callback: (data: T)
|
|
|
198
212
|
* }
|
|
199
213
|
* ```
|
|
200
214
|
*
|
|
215
|
+
* @typeParam A - The tool's ARGUMENT shape. Defaults to
|
|
216
|
+
* `ToolCallInfo["args"]`, which is `Record<string, any>` — so an
|
|
217
|
+
* un-parameterized call behaves exactly as it always has, and
|
|
218
|
+
* `toolCall.args.totally_made_up_field` still compiles. That default is a
|
|
219
|
+
* property of {@link ToolCallInfo} rather than a choice made here (its doc
|
|
220
|
+
* carries the argument, and the escape hatch it recommends —
|
|
221
|
+
* `args as { url: string }` — is what this type parameter replaces); until
|
|
222
|
+
* that field is tightened there is nothing stricter for this hook to fall
|
|
223
|
+
* back to. What was missing was any way to opt IN: there was no type
|
|
224
|
+
* parameter at all, so a custom client could not check args even when it
|
|
225
|
+
* knew the shape. Name it — `useToolCallStart<{ query: string }>(…)` — or
|
|
226
|
+
* derive it from the tool with a TYPE-ONLY import, which is erased and so
|
|
227
|
+
* pulls no host code into the browser graph:
|
|
228
|
+
* `useToolCallStart<InferToolInput<typeof search>>("search", …)`.
|
|
201
229
|
* @param toolName - Only calls of this tool fire the callback.
|
|
202
230
|
* @param callback - Called with the pending call.
|
|
203
231
|
*
|
|
204
232
|
* @public
|
|
205
233
|
*/
|
|
206
|
-
export declare function useToolCallStart(toolName: string, callback: (toolCall: ToolCallInfo
|
|
234
|
+
export declare function useToolCallStart<A = ToolCallInfo["args"]>(toolName: string, callback: (toolCall: Omit<ToolCallInfo, "args"> & {
|
|
235
|
+
args: A;
|
|
236
|
+
}) => void): void;
|
|
207
237
|
/**
|
|
208
238
|
* Fire a callback when ANY tool call starts — read the tool's name off the
|
|
209
239
|
* call itself (`toolCall.name`).
|
|
@@ -220,8 +250,14 @@ export declare function useToolCallStart(toolName: string, callback: (toolCall:
|
|
|
220
250
|
* }
|
|
221
251
|
* ```
|
|
222
252
|
*
|
|
253
|
+
* @typeParam A - The tool's ARGUMENT shape; see the filtered overload. On the
|
|
254
|
+
* unfiltered form every tool's call arrives, so naming one shape here is
|
|
255
|
+
* only right for a page that switches on `toolCall.name` and narrows it
|
|
256
|
+
* itself — the default is the honest answer for a log renderer.
|
|
223
257
|
* @param callback - Called with the pending call.
|
|
224
258
|
*
|
|
225
259
|
* @public
|
|
226
260
|
*/
|
|
227
|
-
export declare function useToolCallStart(callback: (toolCall: ToolCallInfo
|
|
261
|
+
export declare function useToolCallStart<A = ToolCallInfo["args"]>(callback: (toolCall: Omit<ToolCallInfo, "args"> & {
|
|
262
|
+
args: A;
|
|
263
|
+
}) => void): void;
|
package/dist/hooks.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useSessionSelector } from "./context.js";
|
|
2
|
-
import { i as tryParseJSON } from "./_utils-
|
|
2
|
+
import { i as tryParseJSON } from "./_utils-DnQDM9Uy.js";
|
|
3
3
|
import { useEffect, useMemo, useRef } from "react";
|
|
4
|
-
//#region hooks.ts
|
|
4
|
+
//#region src/hooks.ts
|
|
5
5
|
/** Index of the first item whose sequence number is above the watermark (tail scan from the end). */
|
|
6
6
|
function tailStart(items, seqOf, watermark) {
|
|
7
7
|
let start = items.length;
|
|
@@ -39,6 +39,19 @@ function processToolCallTail(toolCalls, cursor, isSettled, onNew) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
42
|
+
* The two `fire` implementations, at module scope so they are stable across
|
|
43
|
+
* renders — which is what lets `useToolCallEffect` name `fire` as a plain
|
|
44
|
+
* dependency instead of holding it in a ref.
|
|
45
|
+
*/
|
|
46
|
+
const fireResult = (callback, tc, filtered) => {
|
|
47
|
+
const parsed = tryParseJSON(tc.result);
|
|
48
|
+
if (filtered) callback(parsed, tc);
|
|
49
|
+
else callback(tc.name, parsed, tc);
|
|
50
|
+
};
|
|
51
|
+
const fireStart = (callback, tc) => {
|
|
52
|
+
callback(tc);
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
42
55
|
* Shared scaffold for the tool-call lifecycle hooks: parses the optional
|
|
43
56
|
* `(toolName, callback)` / `(callback)` overload args, dedups by call ID,
|
|
44
57
|
* and invokes `fire` once per tool call reaching `status`.
|
|
@@ -55,28 +68,23 @@ function useToolCallEffect(status, args, fire) {
|
|
|
55
68
|
const mountedRef = useRef(false);
|
|
56
69
|
const callbackRef = useRef(callback);
|
|
57
70
|
callbackRef.current = callback;
|
|
58
|
-
const fireRef = useRef(fire);
|
|
59
|
-
fireRef.current = fire;
|
|
60
71
|
useEffect(() => {
|
|
61
72
|
const firstRun = !mountedRef.current;
|
|
62
73
|
mountedRef.current = true;
|
|
63
74
|
processToolCallTail(toolCalls, cursorRef.current, (tc) => status === "pending" || tc.status === status, (tc) => {
|
|
64
75
|
if (tc.status !== status && firstRun) return;
|
|
65
76
|
if (filterName && tc.name !== filterName) return;
|
|
66
|
-
|
|
77
|
+
fire(callbackRef.current, tc, filterName !== null);
|
|
67
78
|
});
|
|
68
79
|
}, [
|
|
69
80
|
toolCalls,
|
|
70
81
|
filterName,
|
|
71
|
-
status
|
|
82
|
+
status,
|
|
83
|
+
fire
|
|
72
84
|
]);
|
|
73
85
|
}
|
|
74
86
|
function useToolResult(...args) {
|
|
75
|
-
useToolCallEffect("done", args,
|
|
76
|
-
const parsed = tryParseJSON(tc.result);
|
|
77
|
-
if (filtered) callback(parsed, tc);
|
|
78
|
-
else callback(tc.name, parsed, tc);
|
|
79
|
-
});
|
|
87
|
+
useToolCallEffect("done", args, fireResult);
|
|
80
88
|
}
|
|
81
89
|
function useAgentState(fallback) {
|
|
82
90
|
const state = useSessionSelector((snapshot) => snapshot.agentState);
|
|
@@ -132,9 +140,7 @@ function useEvent(event, callback) {
|
|
|
132
140
|
}, [customEvents, event]);
|
|
133
141
|
}
|
|
134
142
|
function useToolCallStart(...args) {
|
|
135
|
-
useToolCallEffect("pending", args,
|
|
136
|
-
callback(tc);
|
|
137
|
-
});
|
|
143
|
+
useToolCallEffect("pending", args, fireStart);
|
|
138
144
|
}
|
|
139
145
|
//#endregion
|
|
140
146
|
export { useAgentState, useEvent, useToolCallStart, useToolResult };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
export { AGENT_STATE_LABELS } from "./agent-state-labels.ts";
|
|
1
2
|
export { type ClientConfigResponse, fetchClientConfig, } from "./client-config.ts";
|
|
2
3
|
export { AutoScroll } from "./components/auto-scroll.tsx";
|
|
4
|
+
export { BulletList, type BulletListProps } from "./components/bullet-list.tsx";
|
|
3
5
|
export { Button, type ButtonSize, type ButtonVariant } from "./components/button.tsx";
|
|
4
6
|
export { ChatView } from "./components/chat-view.tsx";
|
|
5
7
|
export { ConsoleShell, type ConsoleShellProps } from "./components/console-shell.tsx";
|
|
6
8
|
export { Controls, type ControlsProps } from "./components/controls.tsx";
|
|
7
|
-
export {
|
|
9
|
+
export { Facts, type FactsProps } from "./components/facts.tsx";
|
|
10
|
+
export { CheckboxField, Field, type FieldShell, FileField, type FileReadMode, type FileValue, Form, type FormProps, type FormValues, NumberField, SelectField, SubmitButton, TextAreaField, TextField, } from "./components/form.tsx";
|
|
8
11
|
export { Markdown, type MarkdownProps, type MarkdownVariant } from "./components/markdown.tsx";
|
|
9
12
|
export { MessageList, type MessageListProps } from "./components/message-list.tsx";
|
|
13
|
+
export { SessionErrorBanner, type SessionErrorBannerProps, } from "./components/session-error-banner.tsx";
|
|
10
14
|
export { SidebarLayout } from "./components/sidebar-layout.tsx";
|
|
11
15
|
export { StartScreen } from "./components/start-screen.tsx";
|
|
12
16
|
export { ToolCallRow, type ToolCallRowProps, type ToolCallRowVariant, } from "./components/tool-call-row.tsx";
|
|
@@ -14,24 +18,25 @@ export type { ToolDisplayConfig } from "./components/tool-config-context.ts";
|
|
|
14
18
|
export { UploadProgressBar } from "./components/upload-progress.tsx";
|
|
15
19
|
export { WorkflowFields } from "./components/workflow-fields.tsx";
|
|
16
20
|
export { WorkflowProgress } from "./components/workflow-progress.tsx";
|
|
17
|
-
export type { Session } from "./context.ts";
|
|
18
|
-
export { useSession, useSessionSelector, useTheme } from "./context.ts";
|
|
21
|
+
export type { Session, SessionActions } from "./context.ts";
|
|
22
|
+
export { useSession, useSessionActions, useSessionError, useSessionSelector, useSessionStatus, useTheme, } from "./context.ts";
|
|
19
23
|
export type { ClientConfig, ClientHandle } from "./define-client.tsx";
|
|
20
|
-
export {
|
|
24
|
+
export { mountClient } from "./define-client.tsx";
|
|
21
25
|
export { useAgentState, useEvent, useToolCallStart, useToolResult } from "./hooks.ts";
|
|
22
|
-
export { type PageConfig, type PageHandle
|
|
23
|
-
export {
|
|
24
|
-
export type { AgentCustomEvent,
|
|
26
|
+
export { mountPage, type PageConfig, type PageHandle } from "./page.tsx";
|
|
27
|
+
export { createBrowserSession } from "./session-core.ts";
|
|
28
|
+
export type { AgentCustomEvent, BrowserSession, SessionSnapshot, } from "./session-core-types.ts";
|
|
25
29
|
export type { AgentState, ChatMessage, ClientTheme, SessionError, SessionErrorCode, ToolCallInfo, VoiceSessionOptions, WebSocketConstructor, } from "./types.ts";
|
|
26
30
|
export { type ConversationItem, type UseConversationResult, useConversation, } from "./use-conversation.ts";
|
|
27
31
|
export { type UseDownloadUrlOptions, type UseDownloadUrlResult, useDownloadUrl, } from "./use-download-url.ts";
|
|
28
32
|
export { useRunKey } from "./use-run-key.ts";
|
|
29
33
|
export { type UseUserTranscriptResult, useUserTranscript } from "./use-user-transcript.ts";
|
|
30
|
-
export { type UploadStatus, type UseWorkflowSubmitOptions,
|
|
34
|
+
export { type UploadStatus, type UseWorkflowSubmitOptions, useWorkflowSubmit, type WorkflowSubmission, } from "./use-workflow-form.ts";
|
|
31
35
|
export { type UseWorkflowProgressResult, useWorkflowProgress, } from "./use-workflow-progress.ts";
|
|
32
36
|
export { type UseWorkflowRunResult, useWorkflowRun } from "./use-workflow-run.ts";
|
|
33
37
|
export { type UseWorkflowRunsOptions, type UseWorkflowRunsResult, useWorkflowRuns, } from "./use-workflow-runs.ts";
|
|
34
38
|
export { type UseWorkflowStreamOptions, useWorkflowStream, type WorkflowStreamSubmission, } from "./use-workflow-stream.ts";
|
|
39
|
+
export { type UseWorkflowsOptions, type UseWorkflowsResult, useWorkflows, } from "./use-workflows.ts";
|
|
35
40
|
export { createWorkflowApi, isTerminal, type WorkflowApi, type WorkflowApiOptions, type WorkflowInputOf, type WorkflowOutputOf, type WorkflowRun, type WorkflowRunStatus, type WorkflowSummary, } from "./workflow-client.ts";
|
|
36
41
|
export type { SubmitInputOf } from "./workflow-def-types.ts";
|
|
37
42
|
export { WORKFLOW_STATUS_LABELS } from "./workflow-status-labels.ts";
|