@alexkroman1/aai-ui 13.2.0 → 13.3.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/dist/{_colors-j8XMToi9.js → _colors-CZ6OlPbL.js} +1 -1
- package/dist/{_module-url-C_4gRVL0.js → _module-url-C13kAJ87.js} +1 -1
- package/dist/_recover-run.d.ts +11 -5
- package/dist/{_utils-B6498_bm.js → _utils-CyzjK0gW.js} +1 -1
- package/dist/{aai-logo-CXZGPSIY.js → aai-logo-CFlomZlS.js} +1 -1
- package/dist/audio.js +1 -1
- package/dist/{chat-view-DDTtrh7N.js → chat-view-Bv5VFJIE.js} +6 -6
- package/dist/{client-config-BT_kWID5.js → client-config-DD820zHn.js} +1 -1
- package/dist/client-dir.js +1 -1
- package/dist/components/button.js +2 -2
- package/dist/components/chat-view.js +1 -1
- package/dist/components/controls.js +2 -2
- package/dist/components/message-list.js +1 -1
- 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/context.js +1 -1
- package/dist/default-client.d.ts +1 -1
- package/dist/define-client.js +6 -6
- package/dist/{eyebrow-C6ZFuiz6.js → eyebrow-UfmSz9yy.js} +1 -1
- package/dist/hooks.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1168 -1114
- package/dist/internal.js +5 -5
- package/dist/{message-list-BJYyuIcR.js → message-list-C0pL7x41.js} +7 -7
- package/dist/{session-core-DxBYsfHA.js → session-core-C9elBIdu.js} +11 -11
- package/dist/session-core.js +1 -1
- package/dist/{tool-call-block-tcPQAkcP.js → tool-call-block-Bunc6rCw.js} +6 -6
- package/dist/{tool-config-context-DzAofqi_.js → tool-config-context-Bh8p3DtG.js} +1 -1
- package/dist/types.js +1 -1
- package/dist/{url-chips-YqhCjWfQ.js → url-chips-C2u7QPv8.js} +3 -3
- package/dist/use-run-key.d.ts +44 -10
- package/dist/{use-user-transcript-C14qWFu2.js → use-user-transcript-DFTSEuZN.js} +1 -1
- package/dist/use-workflow-form.d.ts +31 -90
- package/dist/{use-workflow-progress-Cu0SxMyg.js → use-workflow-run-CXGEcM0l.js} +256 -256
- package/dist/use-workflow-stream.d.ts +4 -1
- package/dist/use-workflows.d.ts +77 -0
- package/dist/worklets/capture-processor.js +2 -2
- package/dist/worklets/playback-processor.js +2 -2
- package/package.json +6 -6
- package/dist/tsdown.config.d.ts +0 -2
package/dist/internal.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { r as loadClientConfig, t as buildAgentUrl } from "./client-config-
|
|
1
|
+
import { r as loadClientConfig, t as buildAgentUrl } from "./client-config-DD820zHn.js";
|
|
2
2
|
import { SessionProvider, ThemeProvider } from "./context.js";
|
|
3
|
-
import { n as SessionUrlChips, r as UiUrlChip, t as ApiUrlChip } from "./url-chips-
|
|
4
|
-
import { t as TRANSCRIBING_PLACEHOLDER } from "./use-user-transcript-
|
|
5
|
-
import { t as ToolConfigContext } from "./tool-config-context-
|
|
6
|
-
import { i as
|
|
3
|
+
import { n as SessionUrlChips, r as UiUrlChip, t as ApiUrlChip } from "./url-chips-C2u7QPv8.js";
|
|
4
|
+
import { t as TRANSCRIBING_PLACEHOLDER } from "./use-user-transcript-DFTSEuZN.js";
|
|
5
|
+
import { t as ToolConfigContext } from "./tool-config-context-Bh8p3DtG.js";
|
|
6
|
+
import { i as DEFAULT_PROGRESS_POLL_MS, n as MAX_MISSING_READS, t as DEFAULT_WORKFLOW_POLL_MS } from "./use-workflow-run-CXGEcM0l.js";
|
|
7
7
|
import { VOICE_CAPTURE_CONSTRAINTS } from "./types.js";
|
|
8
8
|
export { ApiUrlChip, DEFAULT_PROGRESS_POLL_MS, DEFAULT_WORKFLOW_POLL_MS, MAX_MISSING_READS, SessionProvider, SessionUrlChips, TRANSCRIBING_PLACEHOLDER, ThemeProvider, ToolConfigContext, UiUrlChip, VOICE_CAPTURE_CONSTRAINTS, buildAgentUrl, loadClientConfig };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { useSessionSelector, useTheme } from "./context.js";
|
|
2
|
-
import { i as primaryTint, r as inkTint } from "./_colors-
|
|
3
|
-
import { n as useUserTranscript } from "./use-user-transcript-
|
|
4
|
-
import { t as ToolCallBlock } from "./tool-call-block-
|
|
2
|
+
import { i as primaryTint, r as inkTint } from "./_colors-CZ6OlPbL.js";
|
|
3
|
+
import { n as useUserTranscript } from "./use-user-transcript-DFTSEuZN.js";
|
|
4
|
+
import { t as ToolCallBlock } from "./tool-call-block-Bunc6rCw.js";
|
|
5
5
|
import clsx from "clsx";
|
|
6
6
|
import { StickToBottom } from "use-stick-to-bottom";
|
|
7
7
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { memo, useMemo } from "react";
|
|
9
9
|
import ReactMarkdown from "react-markdown";
|
|
10
10
|
import remarkGfm from "remark-gfm";
|
|
11
|
-
//#region components/auto-scroll.tsx
|
|
11
|
+
//#region src/components/auto-scroll.tsx
|
|
12
12
|
/** @jsxImportSource react */
|
|
13
13
|
/**
|
|
14
14
|
* A scroll container that stays pinned to the bottom as its content grows,
|
|
@@ -66,7 +66,7 @@ function AutoScroll({ children, className, contentClassName, scrollClassName = "
|
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
//#endregion
|
|
69
|
-
//#region use-conversation.ts
|
|
69
|
+
//#region src/use-conversation.ts
|
|
70
70
|
/**
|
|
71
71
|
* `useConversation` — the exchange, already assembled, with nothing rendered.
|
|
72
72
|
*
|
|
@@ -191,7 +191,7 @@ function useConversation() {
|
|
|
191
191
|
};
|
|
192
192
|
}
|
|
193
193
|
//#endregion
|
|
194
|
-
//#region components/markdown.tsx
|
|
194
|
+
//#region src/components/markdown.tsx
|
|
195
195
|
/** @jsxImportSource react */
|
|
196
196
|
const BARE_ORDERED_MARKER = /^(\s*)(\d{1,9})([.)])\s*$/;
|
|
197
197
|
const BARE_BULLET_MARKER = /^(\s*)([-*+])\s*$/;
|
|
@@ -377,7 +377,7 @@ const Markdown = memo(function Markdown({ text, variant = "default" }) {
|
|
|
377
377
|
});
|
|
378
378
|
});
|
|
379
379
|
//#endregion
|
|
380
|
-
//#region components/message-list.tsx
|
|
380
|
+
//#region src/components/message-list.tsx
|
|
381
381
|
/** @jsxImportSource react */
|
|
382
382
|
const DOT_STYLES = [
|
|
383
383
|
0,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as loadClientConfig, t as buildAgentUrl } from "./client-config-
|
|
1
|
+
import { r as loadClientConfig, t as buildAgentUrl } from "./client-config-DD820zHn.js";
|
|
2
2
|
import { MIC_SEND_MAX_BUFFERED_BYTES } from "./types.js";
|
|
3
3
|
import { SessionEventSchema, lenientParse } from "@alexkroman1/aai/protocol";
|
|
4
4
|
import { errorMessage, safeJsonParse } from "@alexkroman1/aai";
|
|
@@ -6,7 +6,7 @@ import { omitUndefined } from "@alexkroman1/aai/utils";
|
|
|
6
6
|
import { DEFAULT_MAX_HISTORY, WS_OPEN, createEpoch, toArgsRecord } from "@alexkroman1/aai/internal";
|
|
7
7
|
import ReconnectingWebSocket from "partysocket/ws";
|
|
8
8
|
import { and, assign, createActor, not, setup, stateIn } from "xstate";
|
|
9
|
-
//#region session-core-audio-setup.ts
|
|
9
|
+
//#region src/session-core-audio-setup.ts
|
|
10
10
|
/**
|
|
11
11
|
* Audio-path initialization for the voice session core.
|
|
12
12
|
*
|
|
@@ -119,7 +119,7 @@ async function initAudioCapture(conn, msg, deps) {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
//#endregion
|
|
122
|
-
//#region session-core-close.ts
|
|
122
|
+
//#region src/session-core-close.ts
|
|
123
123
|
/**
|
|
124
124
|
* What a socket's CLOSE means to the caller.
|
|
125
125
|
*
|
|
@@ -160,7 +160,7 @@ function closeFailure(event, socketErrored) {
|
|
|
160
160
|
return socketErrored ? "WebSocket connection error" : null;
|
|
161
161
|
}
|
|
162
162
|
//#endregion
|
|
163
|
-
//#region session-core-reconnect.ts
|
|
163
|
+
//#region src/session-core-reconnect.ts
|
|
164
164
|
/**
|
|
165
165
|
* Automatic reconnection for the browser session socket, built on
|
|
166
166
|
* partysocket's `ReconnectingWebSocket`. Kept out of `session-core.ts` so
|
|
@@ -209,7 +209,7 @@ function reconnectPending(socket) {
|
|
|
209
209
|
return socket instanceof ReconnectingWebSocket && socket.shouldReconnect && socket.retryCount < RECONNECT_OPTIONS.maxRetries;
|
|
210
210
|
}
|
|
211
211
|
//#endregion
|
|
212
|
-
//#region session-core-url.ts
|
|
212
|
+
//#region src/session-core-url.ts
|
|
213
213
|
/** Build the session WebSocket URL from the platform URL and resume state. */
|
|
214
214
|
function buildWsUrl(platformUrl, resume, sessionId) {
|
|
215
215
|
return applyResumeParams(buildAgentUrl(platformUrl, "websocket"), resume, sessionId);
|
|
@@ -232,7 +232,7 @@ function applyResumeParams(wsUrl, resume, sessionId) {
|
|
|
232
232
|
return wsUrl;
|
|
233
233
|
}
|
|
234
234
|
//#endregion
|
|
235
|
-
//#region session-resume-store.ts
|
|
235
|
+
//#region src/session-resume-store.ts
|
|
236
236
|
/**
|
|
237
237
|
* Where a session id survives a page RELOAD.
|
|
238
238
|
*
|
|
@@ -300,7 +300,7 @@ function clearStoredSessionId(platformUrl) {
|
|
|
300
300
|
} catch {}
|
|
301
301
|
}
|
|
302
302
|
//#endregion
|
|
303
|
-
//#region session-core-dial.ts
|
|
303
|
+
//#region src/session-core-dial.ts
|
|
304
304
|
/**
|
|
305
305
|
* How the next connection attempt is DIALLED, and the resume identity it dials
|
|
306
306
|
* with.
|
|
@@ -383,7 +383,7 @@ function createDialer(options) {
|
|
|
383
383
|
};
|
|
384
384
|
}
|
|
385
385
|
//#endregion
|
|
386
|
-
//#region session-core-handshake.ts
|
|
386
|
+
//#region src/session-core-handshake.ts
|
|
387
387
|
/**
|
|
388
388
|
* The deadline on a socket that opened but never became a session.
|
|
389
389
|
*
|
|
@@ -463,7 +463,7 @@ function createHandshakeGuard(opts) {
|
|
|
463
463
|
};
|
|
464
464
|
}
|
|
465
465
|
//#endregion
|
|
466
|
-
//#region session-core-messages.ts
|
|
466
|
+
//#region src/session-core-messages.ts
|
|
467
467
|
/**
|
|
468
468
|
* Incoming-message handling for the voice session core.
|
|
469
469
|
*
|
|
@@ -798,7 +798,7 @@ function createMessageHandlers(deps) {
|
|
|
798
798
|
};
|
|
799
799
|
}
|
|
800
800
|
//#endregion
|
|
801
|
-
//#region session-core-state.ts
|
|
801
|
+
//#region src/session-core-state.ts
|
|
802
802
|
/**
|
|
803
803
|
* The browser session's {@link AgentState}, and the error beside it, as a
|
|
804
804
|
* statechart.
|
|
@@ -980,7 +980,7 @@ function createSessionStateMachine() {
|
|
|
980
980
|
};
|
|
981
981
|
}
|
|
982
982
|
//#endregion
|
|
983
|
-
//#region session-core.ts
|
|
983
|
+
//#region src/session-core.ts
|
|
984
984
|
/**
|
|
985
985
|
* Framework-agnostic voice session core.
|
|
986
986
|
*
|
package/dist/session-core.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createSessionCore } from "./session-core-
|
|
1
|
+
import { t as createSessionCore } from "./session-core-C9elBIdu.js";
|
|
2
2
|
export { createSessionCore };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { useTheme } from "./context.js";
|
|
2
|
-
import { r as inkTint } from "./_colors-
|
|
3
|
-
import { t as Eyebrow } from "./eyebrow-
|
|
4
|
-
import { i as tryParseJSON, r as truncate } from "./_utils-
|
|
5
|
-
import { n as useToolConfig } from "./tool-config-context-
|
|
2
|
+
import { r as inkTint } from "./_colors-CZ6OlPbL.js";
|
|
3
|
+
import { t as Eyebrow } from "./eyebrow-UfmSz9yy.js";
|
|
4
|
+
import { i as tryParseJSON, r as truncate } from "./_utils-CyzjK0gW.js";
|
|
5
|
+
import { n as useToolConfig } from "./tool-config-context-Bh8p3DtG.js";
|
|
6
6
|
import clsx from "clsx";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
8
|
import { memo, useMemo, useState } from "react";
|
|
9
|
-
//#region components/tool-call-row.tsx
|
|
9
|
+
//#region src/components/tool-call-row.tsx
|
|
10
10
|
/** @jsxImportSource react */
|
|
11
11
|
const VARIANT_CLASSES = {
|
|
12
12
|
default: {
|
|
@@ -116,7 +116,7 @@ function ToolCallRow({ title, detail, pending = false, icon, variant = "default"
|
|
|
116
116
|
});
|
|
117
117
|
}
|
|
118
118
|
//#endregion
|
|
119
|
-
//#region components/tool-call-block.tsx
|
|
119
|
+
//#region src/components/tool-call-block.tsx
|
|
120
120
|
/** @jsxImportSource react */
|
|
121
121
|
function formatResult(result) {
|
|
122
122
|
const parsed = tryParseJSON(result);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, useContext } from "react";
|
|
2
|
-
//#region components/tool-config-context.ts
|
|
2
|
+
//#region src/components/tool-config-context.ts
|
|
3
3
|
/**
|
|
4
4
|
* Context for tool display configuration. Installed by `client()` from
|
|
5
5
|
* `ClientConfig.tools`; the built-in components read it via `useToolConfig`.
|
package/dist/types.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CAPTURE_STOP_ACK_TIMEOUT_MS, CLIENT_AUDIO_LEAD_MS, HEARD_AUDIO_LAG_MS, MIC_BUFFER_SECONDS, MIC_SEND_MAX_BUFFERED_BYTES, MIC_SILENCE_PROBE_MS, PACER_BURST_MS, PIPELINE_PLAYBACK_GRACE_MS, PLAYBACK_BUFFER_SECONDS, PLAYBACK_CONCEAL_FADE_MS, PLAYBACK_CONCEAL_FLOOR, PLAYBACK_DONE_MAX_WAIT_MS, PLAYBACK_DONE_POLL_MS, PLAYBACK_FILL_MS, PLAYBACK_PROGRESS_INTERVAL_MS } from "@alexkroman1/aai/internal";
|
|
2
|
-
//#region types.ts
|
|
2
|
+
//#region src/types.ts
|
|
3
3
|
/**
|
|
4
4
|
* `getUserMedia` audio constraints for every capture path in this package.
|
|
5
5
|
*
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { useSessionSelector, useTheme } from "./context.js";
|
|
2
|
-
import { r as inkTint } from "./_colors-
|
|
3
|
-
import { t as pageBaseUrl } from "./_utils-
|
|
2
|
+
import { r as inkTint } from "./_colors-CZ6OlPbL.js";
|
|
3
|
+
import { t as pageBaseUrl } from "./_utils-CyzjK0gW.js";
|
|
4
4
|
import clsx from "clsx";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { useEffect, useRef, useState } from "react";
|
|
7
|
-
//#region components/url-chips.tsx
|
|
7
|
+
//#region src/components/url-chips.tsx
|
|
8
8
|
/** @jsxImportSource react */
|
|
9
9
|
/** How long the "Copied" confirmation replaces the label after a click. */
|
|
10
10
|
const COPIED_FEEDBACK_MS = 1500;
|
package/dist/use-run-key.d.ts
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The handle a page keeps on the runs it started, across a reload.
|
|
3
3
|
*
|
|
4
|
-
* `useWorkflowSubmit
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
4
|
+
* `useWorkflowSubmit` is what makes a run survivable — the run id is that
|
|
5
|
+
* hook's own state, so a refresh loses it while the run carries on — and the
|
|
6
|
+
* `key` is what it looks the run up BY, because it is a lookup CAPABILITY:
|
|
7
|
+
* there is no per-user filtering behind `find`, so the key IS the scoping
|
|
8
|
+
* mechanism. Choosing one is easy to get wrong in three separate ways, and six
|
|
9
|
+
* shipped templates had each written the same twenty lines to get it right.
|
|
10
|
+
* This is those lines.
|
|
11
|
+
*
|
|
12
|
+
* **`useWorkflowSubmit` now mints one for itself** ({@link useDefaultRunKey}),
|
|
13
|
+
* so a page resumes its own run across a reload with nothing written at the
|
|
14
|
+
* call site — six of six page templates passed `useRunKey()` and
|
|
15
|
+
* `recover: true`, which is a default in the wrong place. The hook stays
|
|
16
|
+
* PUBLIC for the page that wants to choose: an app with accounts passes the
|
|
17
|
+
* ACCOUNT's own id instead, and a run then follows the person to a new device,
|
|
18
|
+
* which is a promise only a login can keep; a page whose run outlives the tab
|
|
19
|
+
* passes `useRunKey({ storage: "local" })`.
|
|
11
20
|
*
|
|
12
21
|
* ## Three properties, and the rejected alternatives are why each one matters
|
|
13
22
|
*
|
|
@@ -42,7 +51,9 @@
|
|
|
42
51
|
* coming back on Friday to press Stop is the ordinary case rather than an edge
|
|
43
52
|
* one, and a tab-scoped key would answer that with an empty form beside a run
|
|
44
53
|
* still posting somewhere. It is as far as a key can go without a login, and no
|
|
45
|
-
* further. `podcast-digest` is that template
|
|
54
|
+
* further. `podcast-digest` is that template, and the reason this hook is still
|
|
55
|
+
* called by name anywhere; the other five take the tab-scoped default the
|
|
56
|
+
* submit hook mints for them.
|
|
46
57
|
*
|
|
47
58
|
* ## Anything ELSE a page stores back must be VALIDATED on read
|
|
48
59
|
*
|
|
@@ -77,8 +88,31 @@
|
|
|
77
88
|
* failing to render.
|
|
78
89
|
*/
|
|
79
90
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
91
|
+
* The key `useWorkflowSubmit` uses when the page named none.
|
|
92
|
+
*
|
|
93
|
+
* Two things it does that a plain `useRunKey()` at the call site cannot, and
|
|
94
|
+
* both are about a page that DID name one:
|
|
95
|
+
*
|
|
96
|
+
* - **It mints nothing when the caller has a key.** Minting writes to storage,
|
|
97
|
+
* so an unconditional `useRunKey()` inside the hook would leave a slot behind
|
|
98
|
+
* on every page that passes an account id and never reads it back.
|
|
99
|
+
* - **It stays reactive to the caller's key.** A key that arrives late — an
|
|
100
|
+
* account id resolved after a login — must reach the lookup, which re-asks on
|
|
101
|
+
* a changed key by design; freezing it into `useState` would pin the page to
|
|
102
|
+
* whatever it held on its first render.
|
|
103
|
+
*
|
|
104
|
+
* The minted half is still frozen for the component's life, which is what
|
|
105
|
+
* `useRunKey` freezes it for: a fresh key per render would record every run
|
|
106
|
+
* under a name the next load cannot produce.
|
|
107
|
+
*
|
|
108
|
+
* @param explicit - The caller's own key, or undefined for a page with none.
|
|
109
|
+
* @returns The key to record runs under and look them up by.
|
|
110
|
+
*
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
113
|
+
export declare function useDefaultRunKey(explicit: string | undefined): string;
|
|
114
|
+
/**
|
|
115
|
+
* A lookup key for `useWorkflowSubmit({ key })`, stable across reloads.
|
|
82
116
|
*
|
|
83
117
|
* @param options - See the module doc for the whole argument. The storage kind
|
|
84
118
|
* is read once, when the key is minted: a value that changed afterwards would
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The hook a FORM needs, as against the one a status view does.
|
|
3
3
|
*
|
|
4
4
|
* `useWorkflowRun` (`workflow-client.ts`) watches a run you already have.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `useWorkflowRun`.
|
|
5
|
+
* This is what comes before it: `useWorkflowSubmit` starts a run and hands the
|
|
6
|
+
* id straight to `useWorkflowRun`. Its sibling `useWorkflows` — the listing
|
|
7
|
+
* `<WorkflowFields>` renders a form from — is `use-workflows.ts`.
|
|
9
8
|
*
|
|
10
9
|
* ## `useWorkflowSubmit` — a form's two halves in one hook
|
|
11
10
|
*
|
|
@@ -32,76 +31,10 @@
|
|
|
32
31
|
* `wait` here when the page really does want one request, and the run is
|
|
33
32
|
* followed from the same id either way.
|
|
34
33
|
*/
|
|
35
|
-
import type { AnyWorkflowDef, UploadParallel, UploadProgress, WorkflowOutputOf
|
|
34
|
+
import type { AnyWorkflowDef, UploadParallel, UploadProgress, WorkflowOutputOf } from "@alexkroman1/aai/workflow-api";
|
|
36
35
|
import type { FormValues } from "./components/form-types.ts";
|
|
37
36
|
import type { WorkflowApi, WorkflowRun } from "./workflow-client.ts";
|
|
38
37
|
import type { SubmitInputOf } from "./workflow-def-types.ts";
|
|
39
|
-
/** Options for {@link useWorkflows}. */
|
|
40
|
-
export type UseWorkflowsOptions = {
|
|
41
|
-
/** The client to read the listing with. Defaults to one for the page's own agent. */
|
|
42
|
-
api?: WorkflowApi;
|
|
43
|
-
/**
|
|
44
|
-
* Skip the lookup entirely, reporting an empty listing that is not loading.
|
|
45
|
-
*
|
|
46
|
-
* For a caller that may or may not need the listing and cannot decide with a
|
|
47
|
-
* conditional hook — `<WorkflowFields>` handed a summary rather than a name is
|
|
48
|
-
* the one in this package. It reports `loading: false`, because a skipped
|
|
49
|
-
* lookup is finished rather than pending.
|
|
50
|
-
*/
|
|
51
|
-
skip?: boolean;
|
|
52
|
-
};
|
|
53
|
-
/** What {@link useWorkflows} reports. */
|
|
54
|
-
export type UseWorkflowsResult = {
|
|
55
|
-
/** The agent's declared workflows, each with the JSON Schema of its input. */
|
|
56
|
-
workflows: WorkflowSummary[];
|
|
57
|
-
/** True until the listing lands, so a form can hold its fields back. */
|
|
58
|
-
loading: boolean;
|
|
59
|
-
/** The lookup's failure. Set alongside an EMPTY list, which is why it exists. */
|
|
60
|
-
error: string | undefined;
|
|
61
|
-
};
|
|
62
|
-
/**
|
|
63
|
-
* Read the agent's declared workflows.
|
|
64
|
-
*
|
|
65
|
-
* What `<WorkflowFields>` renders a form FROM: each summary carries the JSON
|
|
66
|
-
* Schema of that workflow's input, converted server-side precisely so a browser
|
|
67
|
-
* can read it.
|
|
68
|
-
*
|
|
69
|
-
* The failure is reported rather than swallowed, because the alternative is an
|
|
70
|
-
* empty list — which renders as a form with no fields and reads as "this agent
|
|
71
|
-
* declares no workflows" about an agent that was merely unreachable.
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```tsx
|
|
75
|
-
* import { useWorkflows } from "@alexkroman1/aai-ui";
|
|
76
|
-
*
|
|
77
|
-
* // A page rendering its own chrome from the listing — a picker, say. A form
|
|
78
|
-
* // for ONE workflow wants `<WorkflowFields workflow="name" />` instead,
|
|
79
|
-
* // which does this lookup itself.
|
|
80
|
-
* function WorkflowPicker({ onPick }: { onPick: (name: string) => void }) {
|
|
81
|
-
* const { workflows, loading, error } = useWorkflows();
|
|
82
|
-
* if (loading) return <p>Loading…</p>;
|
|
83
|
-
* if (error !== undefined) return <p role="alert">{error}</p>;
|
|
84
|
-
* return (
|
|
85
|
-
* <ul>
|
|
86
|
-
* {workflows.map((summary) => (
|
|
87
|
-
* <li key={summary.name}>
|
|
88
|
-
* <button type="button" onClick={() => onPick(summary.name)}>
|
|
89
|
-
* {summary.description ?? summary.name}
|
|
90
|
-
* </button>
|
|
91
|
-
* </li>
|
|
92
|
-
* ))}
|
|
93
|
-
* </ul>
|
|
94
|
-
* );
|
|
95
|
-
* }
|
|
96
|
-
* ```
|
|
97
|
-
*
|
|
98
|
-
* @param opts - See {@link UseWorkflowsOptions}.
|
|
99
|
-
* @returns The listing, its loading flag and its failure — see
|
|
100
|
-
* {@link UseWorkflowsResult}.
|
|
101
|
-
*
|
|
102
|
-
* @public
|
|
103
|
-
*/
|
|
104
|
-
export declare function useWorkflows(opts?: UseWorkflowsOptions): UseWorkflowsResult;
|
|
105
38
|
/**
|
|
106
39
|
* What {@link WorkflowSubmission.upload} reports while the bytes are going.
|
|
107
40
|
*
|
|
@@ -229,29 +162,37 @@ export type WorkflowSubmission<R = unknown, I = unknown> = {
|
|
|
229
162
|
export type UseWorkflowSubmitOptions = {
|
|
230
163
|
/** The client to start runs with. Defaults to one for the page's own agent. */
|
|
231
164
|
api?: WorkflowApi;
|
|
232
|
-
/**
|
|
165
|
+
/**
|
|
166
|
+
* Correlation key recorded with the run, for finding it again without the id.
|
|
167
|
+
*
|
|
168
|
+
* **Defaulted**, to an opaque per-page key in `sessionStorage` that the next
|
|
169
|
+
* load produces again — `useRunKey()`'s, minted by the hook. Pass one to
|
|
170
|
+
* scope runs to something the page knows better: an ACCOUNT's own id, which
|
|
171
|
+
* is what makes a run follow the person to a new device, or
|
|
172
|
+
* `useRunKey({ storage: "local" })` for a run that outlives the tab by
|
|
173
|
+
* design. The key is a lookup CAPABILITY (there is no per-user filtering
|
|
174
|
+
* behind `find`), it must fit the route's 256-character bound, and anything
|
|
175
|
+
* derived from a person's own input both collides and carries what they
|
|
176
|
+
* typed — `use-run-key.ts` argues every alternative.
|
|
177
|
+
*/
|
|
233
178
|
key?: string;
|
|
234
179
|
/**
|
|
235
180
|
* On mount, adopt the newest run this `key` already has.
|
|
236
181
|
*
|
|
237
|
-
* **This is what makes a reload survivable.** The run id is
|
|
238
|
-
* state, so a refresh loses it while the run carries on — and
|
|
239
|
-
* cannot name a run cannot show it, cancel it or wake it.
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
244
|
-
* Inert without a `key`, because the key IS the lookup. Opt-in because a
|
|
245
|
-
* `key` on its own means only "record this with the run", which is what a
|
|
246
|
-
* page passing an account id may well want; adopting a run is a decision
|
|
247
|
-
* about the page.
|
|
182
|
+
* **This is what makes a reload survivable, and it is ON.** The run id is
|
|
183
|
+
* this hook's own state, so a refresh loses it while the run carries on — and
|
|
184
|
+
* a page that cannot name a run cannot show it, cancel it or wake it. The
|
|
185
|
+
* hook asks `find(workflow, key)` once as it mounts and follows whatever
|
|
186
|
+
* comes back, so the answer, the progress and the controls are all there
|
|
187
|
+
* again.
|
|
248
188
|
*
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* `
|
|
254
|
-
*
|
|
189
|
+
* It used to be opt-in, on the argument that a `key` alone means only "record
|
|
190
|
+
* this with the run" — true of `ctx.workflows.start({ key })`, where there is
|
|
191
|
+
* no page to put a run back on, and not of a form: six of six page templates
|
|
192
|
+
* passed `useRunKey()` and `recover: true` together, which is a default in
|
|
193
|
+
* the wrong place. `false` is the opt-out, and what it buys is a form that
|
|
194
|
+
* always opens empty — no lookup on mount, and a live run reachable only by
|
|
195
|
+
* an id the page has already lost.
|
|
255
196
|
*/
|
|
256
197
|
recover?: boolean;
|
|
257
198
|
/**
|