@alexkroman1/aai-ui 6.3.0 → 6.4.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/_workflow-files.d.ts +18 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +193 -14
- package/dist/use-workflow-stream.d.ts +122 -0
- package/package.json +2 -2
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which of a submitted form's values are FILES.
|
|
3
|
+
*
|
|
4
|
+
* Its own module because both submit hooks need the identical answer and then do
|
|
5
|
+
* two different things with it — `useWorkflowSubmit` stores each file and passes
|
|
6
|
+
* its id, `useWorkflowStream` cuts it into parts and passes the group they share.
|
|
7
|
+
* A second copy of this predicate would be a form field that one hook treats as a
|
|
8
|
+
* file and the other does not, which is invisible until the run reads the wrong
|
|
9
|
+
* kind of string.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* The files a submitted field carries, if that is what it carries.
|
|
13
|
+
*
|
|
14
|
+
* An array counts only when it is files ALL the way through — a mixed array is
|
|
15
|
+
* some other field's value that happens to contain one, and turning half of it
|
|
16
|
+
* into ids would corrupt it silently.
|
|
17
|
+
*/
|
|
18
|
+
export declare function filesOf(value: unknown): File[];
|
package/dist/index.d.ts
CHANGED
|
@@ -30,4 +30,5 @@ export { type UploadStatus, type UseWorkflowSubmitOptions, type UseWorkflowsOpti
|
|
|
30
30
|
export { DEFAULT_PROGRESS_POLL_MS, type UseWorkflowProgressResult, useWorkflowProgress, } from "./use-workflow-progress.ts";
|
|
31
31
|
export { DEFAULT_WORKFLOW_POLL_MS, MAX_MISSING_READS, type UseWorkflowRunResult, useWorkflowRun, } from "./use-workflow-run.ts";
|
|
32
32
|
export { type UseWorkflowRunsOptions, type UseWorkflowRunsResult, useWorkflowRuns, } from "./use-workflow-runs.ts";
|
|
33
|
+
export { type UseWorkflowStreamOptions, useWorkflowStream, type WorkflowStreamSubmission, } from "./use-workflow-stream.ts";
|
|
33
34
|
export { createWorkflowApi, isTerminal, type WorkflowApi, type WorkflowApiOptions, type WorkflowOutputOf, type WorkflowRun, type WorkflowSummary, } from "./workflow-client.ts";
|
package/dist/index.js
CHANGED
|
@@ -625,6 +625,31 @@ function useWorkflowApiRef(api) {
|
|
|
625
625
|
}, []);
|
|
626
626
|
}
|
|
627
627
|
//#endregion
|
|
628
|
+
//#region _workflow-files.ts
|
|
629
|
+
/**
|
|
630
|
+
* Which of a submitted form's values are FILES.
|
|
631
|
+
*
|
|
632
|
+
* Its own module because both submit hooks need the identical answer and then do
|
|
633
|
+
* two different things with it — `useWorkflowSubmit` stores each file and passes
|
|
634
|
+
* its id, `useWorkflowStream` cuts it into parts and passes the group they share.
|
|
635
|
+
* A second copy of this predicate would be a form field that one hook treats as a
|
|
636
|
+
* file and the other does not, which is invisible until the run reads the wrong
|
|
637
|
+
* kind of string.
|
|
638
|
+
*/
|
|
639
|
+
/**
|
|
640
|
+
* The files a submitted field carries, if that is what it carries.
|
|
641
|
+
*
|
|
642
|
+
* An array counts only when it is files ALL the way through — a mixed array is
|
|
643
|
+
* some other field's value that happens to contain one, and turning half of it
|
|
644
|
+
* into ids would corrupt it silently.
|
|
645
|
+
*/
|
|
646
|
+
function filesOf(value) {
|
|
647
|
+
if (value instanceof File) return [value];
|
|
648
|
+
if (!Array.isArray(value)) return [];
|
|
649
|
+
const files = value.filter((one) => one instanceof File);
|
|
650
|
+
return files.length > 0 && files.length === value.length ? files : [];
|
|
651
|
+
}
|
|
652
|
+
//#endregion
|
|
628
653
|
//#region _repeat-until.ts
|
|
629
654
|
/**
|
|
630
655
|
* A bounded read, re-armed from the SETTLED read — the loop both workflow
|
|
@@ -1031,19 +1056,6 @@ function useWorkflows(opts = {}) {
|
|
|
1031
1056
|
return state;
|
|
1032
1057
|
}
|
|
1033
1058
|
/**
|
|
1034
|
-
* The files a submitted field carries, if that is what it carries.
|
|
1035
|
-
*
|
|
1036
|
-
* An array counts only when it is files ALL the way through — a mixed array is
|
|
1037
|
-
* some other field's value that happens to contain one, and turning half of it
|
|
1038
|
-
* into ids would corrupt it silently.
|
|
1039
|
-
*/
|
|
1040
|
-
function filesOf(value) {
|
|
1041
|
-
if (value instanceof File) return [value];
|
|
1042
|
-
if (!Array.isArray(value)) return [];
|
|
1043
|
-
const files = value.filter((one) => one instanceof File);
|
|
1044
|
-
return files.length > 0 && files.length === value.length ? files : [];
|
|
1045
|
-
}
|
|
1046
|
-
/**
|
|
1047
1059
|
* Replace every `File` in a submitted form with the id of a stored upload,
|
|
1048
1060
|
* reporting how far each one has got.
|
|
1049
1061
|
*
|
|
@@ -1761,4 +1773,171 @@ function useWorkflowRuns(workflow, opts = {}) {
|
|
|
1761
1773
|
};
|
|
1762
1774
|
}
|
|
1763
1775
|
//#endregion
|
|
1764
|
-
|
|
1776
|
+
//#region use-workflow-stream.ts
|
|
1777
|
+
/**
|
|
1778
|
+
* Starting a run BEFORE its file has finished uploading.
|
|
1779
|
+
*
|
|
1780
|
+
* `useWorkflowSubmit` (`use-workflow-form.ts`) stores every file and then starts the
|
|
1781
|
+
* run, because a `POST /workflows/uploads` cannot answer with an id until the last
|
|
1782
|
+
* byte is in — the store writes an ordinary upload's record last, so "incomplete"
|
|
1783
|
+
* and "no such upload" are deliberately the same answer. For a long recording that
|
|
1784
|
+
* order is most of the wall clock.
|
|
1785
|
+
*
|
|
1786
|
+
* This hook inverts it, and it takes ONE extra idea to do so: the id is the
|
|
1787
|
+
* CLIENT's. It mints one, starts the run on it, and `PUT`s the whole file in a
|
|
1788
|
+
* single streaming request; the upload record exists from the first byte with
|
|
1789
|
+
* `complete: false` and its `size` grows, so the run reads whatever has arrived.
|
|
1790
|
+
*
|
|
1791
|
+
* ```text
|
|
1792
|
+
* start run ─┬──────────────────────────────────────────────► (still running)
|
|
1793
|
+
* │
|
|
1794
|
+
* PUT /uploads/<id> ═══════════════════════════════════► wake
|
|
1795
|
+
* (one request; the run polls `size` and `complete`)
|
|
1796
|
+
* ```
|
|
1797
|
+
*
|
|
1798
|
+
* ## What it does NOT do, which is the point
|
|
1799
|
+
*
|
|
1800
|
+
* There is no cutting, no part numbering, no terminator and no per-part request. An
|
|
1801
|
+
* earlier version of this hook took a `cut` callback and uploaded N parts into a
|
|
1802
|
+
* "group" that a separate call had to seal; it worked, and every piece of it was
|
|
1803
|
+
* something the caller had to get right. The whole of that is replaced by the store
|
|
1804
|
+
* publishing `size` as bytes land — which `readUpload` already clamped to — so the
|
|
1805
|
+
* run does exactly what it does over a finished file and simply waits for windows to
|
|
1806
|
+
* become present.
|
|
1807
|
+
*
|
|
1808
|
+
* It also means the FORMAT knowledge stays where it already was. Deciding where a
|
|
1809
|
+
* recording may be divided is the run's business (`planSegments` in the
|
|
1810
|
+
* transcription template), and nothing here needs to know it is audio at all.
|
|
1811
|
+
*
|
|
1812
|
+
* ## Three things it owns
|
|
1813
|
+
*
|
|
1814
|
+
* - **The id.** Minted here, put in the run input where the workflow's `uploads`
|
|
1815
|
+
* list says, and never seen by the page. It is a capability — anyone holding it
|
|
1816
|
+
* can read the bytes back — so it is a `crypto.randomUUID()` rather than anything
|
|
1817
|
+
* derived from the file, and the store refuses a second `PUT` to it.
|
|
1818
|
+
* - **The wake after the upload.** `POST /workflows/runs/:id/wake` ends a pending
|
|
1819
|
+
* `sleep`, and a run waiting on an upload is asleep between polls — so without
|
|
1820
|
+
* this it learns the file is complete up to a poll interval late, every time. On
|
|
1821
|
+
* the transcription template's 5-second interval that is most of the tail it has
|
|
1822
|
+
* left to pay. Best-effort, because a wake that finds nothing sleeping answers 0
|
|
1823
|
+
* and a missed one costs latency rather than correctness.
|
|
1824
|
+
* - **Reporting the bytes.** The same `UploadStatus` `useWorkflowSubmit` reports,
|
|
1825
|
+
* so `<UploadProgressBar>` renders either without knowing which hook it came from.
|
|
1826
|
+
*
|
|
1827
|
+
* ## A failed upload CANCELS the run
|
|
1828
|
+
*
|
|
1829
|
+
* An upload that dies stays in the store, incomplete, and `complete` never becomes
|
|
1830
|
+
* true — so a run left behind polls until its own abandonment bound and then fails,
|
|
1831
|
+
* minutes after the page has already reported the error. Cancelling is the honest
|
|
1832
|
+
* end to a submission that did not happen. The cost is that work already done is
|
|
1833
|
+
* thrown away with the run; a caller who wants to resume instead drives
|
|
1834
|
+
* `api.uploadStream` and `api.uploadInfo` directly.
|
|
1835
|
+
*/
|
|
1836
|
+
/**
|
|
1837
|
+
* Start a workflow run and stream a file into it while it works.
|
|
1838
|
+
*
|
|
1839
|
+
* The workflow declares which input property carries the upload
|
|
1840
|
+
* (`workflow({ uploads: ["recording"] })`) — the same declaration
|
|
1841
|
+
* `useWorkflowSubmit` reads, because what the property carries is an upload id
|
|
1842
|
+
* either way. What differs is only WHEN the id becomes valid.
|
|
1843
|
+
*
|
|
1844
|
+
* @typeParam R - The workflow's output type, which is what makes
|
|
1845
|
+
* `run.status === "completed"` narrow to a typed `run.output`. Derive it with
|
|
1846
|
+
* `WorkflowOutputOf<typeof myWorkflow>`.
|
|
1847
|
+
*
|
|
1848
|
+
* @example
|
|
1849
|
+
* ```tsx no-check
|
|
1850
|
+
* const { submit, run, upload, pending, error } = useWorkflowStream("transcribe");
|
|
1851
|
+
*
|
|
1852
|
+
* <Form onSubmit={(values) => submit(values)} error={error}>
|
|
1853
|
+
* <WorkflowFields workflow="transcribe" />
|
|
1854
|
+
* <UploadProgressBar upload={upload} />
|
|
1855
|
+
* <SubmitButton pending={pending}>Transcribe</SubmitButton>
|
|
1856
|
+
* </Form>
|
|
1857
|
+
* ```
|
|
1858
|
+
*
|
|
1859
|
+
* @public
|
|
1860
|
+
*/
|
|
1861
|
+
function useWorkflowStream(workflow, opts = {}) {
|
|
1862
|
+
const { api, key, intervalMs } = opts;
|
|
1863
|
+
const [runId, setRunId] = useState(void 0);
|
|
1864
|
+
const [starting, setStarting] = useState(false);
|
|
1865
|
+
const [startError, setStartError] = useState(void 0);
|
|
1866
|
+
const [upload, setUpload] = useState(void 0);
|
|
1867
|
+
const getClient = useWorkflowApiRef(api);
|
|
1868
|
+
const tracked = useWorkflowRun(runId, {
|
|
1869
|
+
...api && { api },
|
|
1870
|
+
...omitUndefined({ intervalMs })
|
|
1871
|
+
});
|
|
1872
|
+
return {
|
|
1873
|
+
submit: useCallback(async (input) => {
|
|
1874
|
+
const client = getClient();
|
|
1875
|
+
setStarting(true);
|
|
1876
|
+
setStartError(void 0);
|
|
1877
|
+
setRunId(void 0);
|
|
1878
|
+
let started;
|
|
1879
|
+
try {
|
|
1880
|
+
const field = await uploadField(client, workflow);
|
|
1881
|
+
const chosen = field === void 0 ? void 0 : fileAt(input, field);
|
|
1882
|
+
const id = randomUploadId();
|
|
1883
|
+
const payload = chosen && field ? {
|
|
1884
|
+
...input,
|
|
1885
|
+
[field]: id
|
|
1886
|
+
} : input;
|
|
1887
|
+
started = await client.start(workflow, payload, omitUndefined({ key }));
|
|
1888
|
+
setRunId(started);
|
|
1889
|
+
if (!chosen) return;
|
|
1890
|
+
await client.uploadStream(id, chosen, {
|
|
1891
|
+
name: chosen.name,
|
|
1892
|
+
onProgress: (progress) => setUpload({
|
|
1893
|
+
...progress,
|
|
1894
|
+
name: chosen.name,
|
|
1895
|
+
index: 1,
|
|
1896
|
+
count: 1
|
|
1897
|
+
})
|
|
1898
|
+
});
|
|
1899
|
+
await client.wake(started).catch(() => void 0);
|
|
1900
|
+
} catch (err) {
|
|
1901
|
+
setStartError(errorMessage(err));
|
|
1902
|
+
if (started) await client.cancel(started).catch(() => void 0);
|
|
1903
|
+
} finally {
|
|
1904
|
+
setStarting(false);
|
|
1905
|
+
setUpload(void 0);
|
|
1906
|
+
}
|
|
1907
|
+
}, [
|
|
1908
|
+
workflow,
|
|
1909
|
+
key,
|
|
1910
|
+
getClient
|
|
1911
|
+
]),
|
|
1912
|
+
reset: useCallback(() => {
|
|
1913
|
+
setRunId(void 0);
|
|
1914
|
+
setStartError(void 0);
|
|
1915
|
+
setUpload(void 0);
|
|
1916
|
+
}, []),
|
|
1917
|
+
run: tracked.run,
|
|
1918
|
+
pending: starting || tracked.polling,
|
|
1919
|
+
upload,
|
|
1920
|
+
error: startError ?? tracked.error
|
|
1921
|
+
};
|
|
1922
|
+
}
|
|
1923
|
+
/** A fresh upload id: a capability, so it is random rather than derived. */
|
|
1924
|
+
function randomUploadId() {
|
|
1925
|
+
return crypto.randomUUID().replaceAll("-", "");
|
|
1926
|
+
}
|
|
1927
|
+
/**
|
|
1928
|
+
* Which input property this workflow says carries an upload id.
|
|
1929
|
+
*
|
|
1930
|
+
* `undefined` when the workflow declares none, which is not an error: the caller
|
|
1931
|
+
* may be using this hook against a workflow that takes no file at all, and the run
|
|
1932
|
+
* then starts with the input untouched.
|
|
1933
|
+
*/
|
|
1934
|
+
async function uploadField(client, workflow) {
|
|
1935
|
+
return (await client.list()).find((one) => one.name === workflow)?.uploads?.[0];
|
|
1936
|
+
}
|
|
1937
|
+
/** The `File` at `field`, if that is what the form put there. */
|
|
1938
|
+
function fileAt(input, field) {
|
|
1939
|
+
if (!isRecord(input)) return void 0;
|
|
1940
|
+
return filesOf(input[field])[0];
|
|
1941
|
+
}
|
|
1942
|
+
//#endregion
|
|
1943
|
+
export { ApiUrlChip, AutoScroll, Button, ChatView, CheckboxField, Controls, DEFAULT_PROGRESS_POLL_MS, DEFAULT_WORKFLOW_POLL_MS, Field, FileField, Form, MAX_MISSING_READS, Markdown, MessageList, NumberField, SelectField, SessionProvider, SessionUrlChips, SidebarLayout, StartScreen, SubmitButton, TRANSCRIBING_PLACEHOLDER, TextAreaField, TextField, ThemeProvider, ToolCallRow, ToolConfigContext, UiUrlChip, UploadProgressBar, VOICE_CAPTURE_CONSTRAINTS, WorkflowFields, WorkflowProgress, buildAgentUrl, client, createSessionCore, createWorkflowApi, fetchClientConfig, isTerminal, loadClientConfig, page, useAgentState, useEvent, useSession, useSessionSelector, useTheme, useToolCallStart, useToolResult, useUserTranscript, useWorkflowProgress, useWorkflowRun, useWorkflowRuns, useWorkflowStream, useWorkflowSubmit, useWorkflows };
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Starting a run BEFORE its file has finished uploading.
|
|
3
|
+
*
|
|
4
|
+
* `useWorkflowSubmit` (`use-workflow-form.ts`) stores every file and then starts the
|
|
5
|
+
* run, because a `POST /workflows/uploads` cannot answer with an id until the last
|
|
6
|
+
* byte is in — the store writes an ordinary upload's record last, so "incomplete"
|
|
7
|
+
* and "no such upload" are deliberately the same answer. For a long recording that
|
|
8
|
+
* order is most of the wall clock.
|
|
9
|
+
*
|
|
10
|
+
* This hook inverts it, and it takes ONE extra idea to do so: the id is the
|
|
11
|
+
* CLIENT's. It mints one, starts the run on it, and `PUT`s the whole file in a
|
|
12
|
+
* single streaming request; the upload record exists from the first byte with
|
|
13
|
+
* `complete: false` and its `size` grows, so the run reads whatever has arrived.
|
|
14
|
+
*
|
|
15
|
+
* ```text
|
|
16
|
+
* start run ─┬──────────────────────────────────────────────► (still running)
|
|
17
|
+
* │
|
|
18
|
+
* PUT /uploads/<id> ═══════════════════════════════════► wake
|
|
19
|
+
* (one request; the run polls `size` and `complete`)
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* ## What it does NOT do, which is the point
|
|
23
|
+
*
|
|
24
|
+
* There is no cutting, no part numbering, no terminator and no per-part request. An
|
|
25
|
+
* earlier version of this hook took a `cut` callback and uploaded N parts into a
|
|
26
|
+
* "group" that a separate call had to seal; it worked, and every piece of it was
|
|
27
|
+
* something the caller had to get right. The whole of that is replaced by the store
|
|
28
|
+
* publishing `size` as bytes land — which `readUpload` already clamped to — so the
|
|
29
|
+
* run does exactly what it does over a finished file and simply waits for windows to
|
|
30
|
+
* become present.
|
|
31
|
+
*
|
|
32
|
+
* It also means the FORMAT knowledge stays where it already was. Deciding where a
|
|
33
|
+
* recording may be divided is the run's business (`planSegments` in the
|
|
34
|
+
* transcription template), and nothing here needs to know it is audio at all.
|
|
35
|
+
*
|
|
36
|
+
* ## Three things it owns
|
|
37
|
+
*
|
|
38
|
+
* - **The id.** Minted here, put in the run input where the workflow's `uploads`
|
|
39
|
+
* list says, and never seen by the page. It is a capability — anyone holding it
|
|
40
|
+
* can read the bytes back — so it is a `crypto.randomUUID()` rather than anything
|
|
41
|
+
* derived from the file, and the store refuses a second `PUT` to it.
|
|
42
|
+
* - **The wake after the upload.** `POST /workflows/runs/:id/wake` ends a pending
|
|
43
|
+
* `sleep`, and a run waiting on an upload is asleep between polls — so without
|
|
44
|
+
* this it learns the file is complete up to a poll interval late, every time. On
|
|
45
|
+
* the transcription template's 5-second interval that is most of the tail it has
|
|
46
|
+
* left to pay. Best-effort, because a wake that finds nothing sleeping answers 0
|
|
47
|
+
* and a missed one costs latency rather than correctness.
|
|
48
|
+
* - **Reporting the bytes.** The same `UploadStatus` `useWorkflowSubmit` reports,
|
|
49
|
+
* so `<UploadProgressBar>` renders either without knowing which hook it came from.
|
|
50
|
+
*
|
|
51
|
+
* ## A failed upload CANCELS the run
|
|
52
|
+
*
|
|
53
|
+
* An upload that dies stays in the store, incomplete, and `complete` never becomes
|
|
54
|
+
* true — so a run left behind polls until its own abandonment bound and then fails,
|
|
55
|
+
* minutes after the page has already reported the error. Cancelling is the honest
|
|
56
|
+
* end to a submission that did not happen. The cost is that work already done is
|
|
57
|
+
* thrown away with the run; a caller who wants to resume instead drives
|
|
58
|
+
* `api.uploadStream` and `api.uploadInfo` directly.
|
|
59
|
+
*/
|
|
60
|
+
import type { UploadStatus } from "./use-workflow-form.ts";
|
|
61
|
+
import type { WorkflowApi, WorkflowRun } from "./workflow-client.ts";
|
|
62
|
+
/** Options for {@link useWorkflowStream}. */
|
|
63
|
+
export type UseWorkflowStreamOptions = {
|
|
64
|
+
/** The client to start runs with. Defaults to one for the page's own agent. */
|
|
65
|
+
api?: WorkflowApi;
|
|
66
|
+
/** Correlation key recorded with the run, for finding it again without the id. */
|
|
67
|
+
key?: string;
|
|
68
|
+
/** How often the fallback poll re-reads a live run. */
|
|
69
|
+
intervalMs?: number;
|
|
70
|
+
};
|
|
71
|
+
/** What {@link useWorkflowStream} returns. */
|
|
72
|
+
export type WorkflowStreamSubmission<R = unknown> = {
|
|
73
|
+
/**
|
|
74
|
+
* Start a run and stream this input's file into it.
|
|
75
|
+
*
|
|
76
|
+
* Resolves when the upload finishes, NOT when the run does — the run's own
|
|
77
|
+
* progress arrives through `run`. It resolves rather than rejecting on a failed
|
|
78
|
+
* upload; the failure is reported through `error`, the way a form expects.
|
|
79
|
+
*/
|
|
80
|
+
submit: (input: unknown) => Promise<void>;
|
|
81
|
+
/** Clear the run and any error, putting the form back to its initial state. */
|
|
82
|
+
reset: () => void;
|
|
83
|
+
/**
|
|
84
|
+
* The run, from the moment it EXISTS — which here is before its bytes are in.
|
|
85
|
+
*
|
|
86
|
+
* That is the whole difference from `useWorkflowSubmit`, and what lets a page
|
|
87
|
+
* render `<WorkflowProgress>` beside the upload bar rather than after it.
|
|
88
|
+
*/
|
|
89
|
+
run: WorkflowRun<R> | undefined;
|
|
90
|
+
/** True from `submit()` until the run reaches a terminal status. */
|
|
91
|
+
pending: boolean;
|
|
92
|
+
/** How far the upload has got, while it is still going. */
|
|
93
|
+
upload: UploadStatus | undefined;
|
|
94
|
+
/** The submit's own failure (a rejected input, or an upload that would not store). */
|
|
95
|
+
error: string | undefined;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Start a workflow run and stream a file into it while it works.
|
|
99
|
+
*
|
|
100
|
+
* The workflow declares which input property carries the upload
|
|
101
|
+
* (`workflow({ uploads: ["recording"] })`) — the same declaration
|
|
102
|
+
* `useWorkflowSubmit` reads, because what the property carries is an upload id
|
|
103
|
+
* either way. What differs is only WHEN the id becomes valid.
|
|
104
|
+
*
|
|
105
|
+
* @typeParam R - The workflow's output type, which is what makes
|
|
106
|
+
* `run.status === "completed"` narrow to a typed `run.output`. Derive it with
|
|
107
|
+
* `WorkflowOutputOf<typeof myWorkflow>`.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```tsx no-check
|
|
111
|
+
* const { submit, run, upload, pending, error } = useWorkflowStream("transcribe");
|
|
112
|
+
*
|
|
113
|
+
* <Form onSubmit={(values) => submit(values)} error={error}>
|
|
114
|
+
* <WorkflowFields workflow="transcribe" />
|
|
115
|
+
* <UploadProgressBar upload={upload} />
|
|
116
|
+
* <SubmitButton pending={pending}>Transcribe</SubmitButton>
|
|
117
|
+
* </Form>
|
|
118
|
+
* ```
|
|
119
|
+
*
|
|
120
|
+
* @public
|
|
121
|
+
*/
|
|
122
|
+
export declare function useWorkflowStream<R = unknown>(workflow: string, opts?: UseWorkflowStreamOptions): WorkflowStreamSubmission<R>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alexkroman1/aai-ui",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"remark-gfm": "^4.0.1",
|
|
30
30
|
"use-stick-to-bottom": "^1.1.6",
|
|
31
31
|
"use-sync-external-store": "^1.6.0",
|
|
32
|
-
"@alexkroman1/aai": "6.
|
|
32
|
+
"@alexkroman1/aai": "6.4.0"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
35
|
"react": "^19.0.0",
|