@flowget/ai-chat 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/LICENSE +105 -0
- package/README.md +228 -0
- package/dist/react.cjs +567 -0
- package/dist/react.d.cts +250 -0
- package/dist/react.d.ts +250 -0
- package/dist/react.js +561 -0
- package/dist/server.cjs +118 -0
- package/dist/server.d.cts +91 -0
- package/dist/server.d.ts +91 -0
- package/dist/server.js +114 -0
- package/dist/styles.css +473 -0
- package/package.json +91 -0
package/dist/react.d.cts
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { ChatModelAdapter } from '@assistant-ui/react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Graph types — deliberately builder-agnostic. `@flowget/ai-chat` never
|
|
7
|
+
* imports `@flowget/builder`; the host maps its own graph to/from these plain
|
|
8
|
+
* structural shapes through the `currentGraph` / `applyGraph` seam on
|
|
9
|
+
* {@link WorkflowChat}. That seam is the whole point of the package: the chat
|
|
10
|
+
* proposes a graph, the host owns how it lands on the canvas.
|
|
11
|
+
*/
|
|
12
|
+
/** A node in a laid-out canvas graph — `position` required. */
|
|
13
|
+
type WorkflowNode = {
|
|
14
|
+
id: string;
|
|
15
|
+
type: string;
|
|
16
|
+
data: Record<string, unknown>;
|
|
17
|
+
position: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/** An edge in a canvas graph. `null` handles belong to the wire, not here. */
|
|
23
|
+
type WorkflowEdge = {
|
|
24
|
+
id: string;
|
|
25
|
+
source: string;
|
|
26
|
+
target: string;
|
|
27
|
+
sourceHandle?: string;
|
|
28
|
+
targetHandle?: string;
|
|
29
|
+
type?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* A laid-out graph, ready to apply to a canvas. Arrays are `readonly` so a
|
|
33
|
+
* host's own (often readonly) graph assigns to `currentGraph` without a cast.
|
|
34
|
+
*/
|
|
35
|
+
type WorkflowGraph = {
|
|
36
|
+
nodes: readonly WorkflowNode[];
|
|
37
|
+
edges: readonly WorkflowEdge[];
|
|
38
|
+
};
|
|
39
|
+
/** A node in a *proposed* graph — `position` optional (the AI omits layout). */
|
|
40
|
+
type ProposedNode = {
|
|
41
|
+
id: string;
|
|
42
|
+
type: string;
|
|
43
|
+
data: Record<string, unknown>;
|
|
44
|
+
position?: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/** An edge in a proposed graph — tolerant of the wire's `null` handles. */
|
|
50
|
+
type ProposedEdge = {
|
|
51
|
+
id: string;
|
|
52
|
+
source: string;
|
|
53
|
+
target: string;
|
|
54
|
+
sourceHandle?: string | null;
|
|
55
|
+
targetHandle?: string | null;
|
|
56
|
+
/** Edge kind (e.g. the host's custom edge type); carried through to the canvas. */
|
|
57
|
+
type?: string | null;
|
|
58
|
+
};
|
|
59
|
+
/** The position-optional graph the server proposes. */
|
|
60
|
+
type ProposedGraph = {
|
|
61
|
+
nodes: readonly ProposedNode[];
|
|
62
|
+
edges: readonly ProposedEdge[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Turn a position-optional proposal into a laid-out graph, given the current
|
|
66
|
+
* canvas as the baseline. The default is the package's zero-dependency
|
|
67
|
+
* `layoutProposal`; a builder-host can inject its own (e.g. a dagre merge) via
|
|
68
|
+
* the `layout` prop on {@link WorkflowChat} to keep ai-chat builder-agnostic.
|
|
69
|
+
*/
|
|
70
|
+
type WorkflowLayout = (proposed: ProposedGraph, current: WorkflowGraph) => WorkflowGraph;
|
|
71
|
+
/**
|
|
72
|
+
* The host-provided seam that lets the chat read + write the canvas without
|
|
73
|
+
* knowing anything about the host's builder. Supplied to {@link WorkflowChat}.
|
|
74
|
+
*/
|
|
75
|
+
type WorkflowChatBridge = {
|
|
76
|
+
/** Read the graph currently on the canvas (edit context + layout baseline). */
|
|
77
|
+
getCurrentGraph: () => WorkflowGraph;
|
|
78
|
+
/** Commit a laid-out graph to the canvas (e.g. the builder store's setGraph). */
|
|
79
|
+
applyGraph: (graph: WorkflowGraph) => void;
|
|
80
|
+
/** Lay a proposal out before applying. Defaults to the built-in layout. */
|
|
81
|
+
layout?: WorkflowLayout;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The wire contract between the client and the authoring backend — a small
|
|
86
|
+
* mirror of `@flowget/ai`'s request/stream shapes, kept local so the client
|
|
87
|
+
* layer never imports the (server-only) engine.
|
|
88
|
+
*
|
|
89
|
+
* A dev-only type-level parity guard (`contract.parity.ts`, not shipped) keeps
|
|
90
|
+
* this hand-mirror from silently drifting from `@flowget/ai`'s contract.
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The caller identity, mirrored from `@flowget/ai`'s `Actor`.
|
|
95
|
+
*
|
|
96
|
+
* **Untrusted by default.** When set on the client `ChatRequest`, it is plain
|
|
97
|
+
* JSON on the request body — the browser can put anything here. Treat it as a
|
|
98
|
+
* *hint*: a server that gates data access on the actor MUST derive/verify it
|
|
99
|
+
* server-side (from its own session/JWT) via `createChatStreamResponse`'s
|
|
100
|
+
* `buildRequest` option and/or a `@flowget/ai` authorizer. See the README
|
|
101
|
+
* "Security" section.
|
|
102
|
+
*/
|
|
103
|
+
type ChatActor = {
|
|
104
|
+
id: string;
|
|
105
|
+
tenantId?: string;
|
|
106
|
+
roles: readonly string[];
|
|
107
|
+
scopes?: readonly string[];
|
|
108
|
+
claims?: Record<string, unknown>;
|
|
109
|
+
};
|
|
110
|
+
/** Body of `POST <endpoint>`. */
|
|
111
|
+
type ChatRequest = {
|
|
112
|
+
command: string;
|
|
113
|
+
/** The graph currently on the canvas — present for a targeted edit. */
|
|
114
|
+
currentGraph?: WorkflowGraph;
|
|
115
|
+
/** Caller identity hint (untrusted on the wire — see {@link ChatActor}). */
|
|
116
|
+
actor?: ChatActor;
|
|
117
|
+
/** Opaque, client-carried continuity payload forwarded to the model. */
|
|
118
|
+
context?: unknown;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* A streamed chat event (mirrors the engine's `AuthorStreamEvent`). Assistant
|
|
122
|
+
* text arrives as `text-delta`s; the stream ends with a terminal `proposal` |
|
|
123
|
+
* `message`, or `error`. Discriminate on `kind` — the same key `@flowget/ai`
|
|
124
|
+
* uses, so `/server` forwards the engine's events verbatim.
|
|
125
|
+
*/
|
|
126
|
+
type ChatStreamEvent = {
|
|
127
|
+
kind: "text-delta";
|
|
128
|
+
delta: string;
|
|
129
|
+
} | {
|
|
130
|
+
kind: "proposal";
|
|
131
|
+
graph: ProposedGraph;
|
|
132
|
+
summary: string;
|
|
133
|
+
} | {
|
|
134
|
+
kind: "message";
|
|
135
|
+
text: string;
|
|
136
|
+
} | {
|
|
137
|
+
kind: "error";
|
|
138
|
+
error: string;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The transport seam — how the browser reaches the authoring backend.
|
|
143
|
+
*
|
|
144
|
+
* The **customer-swappable** boundary: the default streams from the host's BFF
|
|
145
|
+
* over SSE, but a host with a different backend swaps this one async generator
|
|
146
|
+
* without touching the runtime, tool UI, or bridge.
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
/** Streams authoring events (deltas → terminal) for a command + graph. */
|
|
150
|
+
type ChatStreamTransport = (request: ChatRequest, signal?: AbortSignal) => AsyncIterable<ChatStreamEvent>;
|
|
151
|
+
/** Default transport: POST command + graph to the BFF, read the SSE stream. */
|
|
152
|
+
declare function httpChatStreamTransport(endpoint?: string): ChatStreamTransport;
|
|
153
|
+
|
|
154
|
+
type WorkflowChatProps = {
|
|
155
|
+
/** The graph currently on the canvas (edit context + layout baseline). */
|
|
156
|
+
currentGraph: WorkflowGraph;
|
|
157
|
+
/** Commit a laid-out graph to the canvas (e.g. the builder store's setGraph). */
|
|
158
|
+
applyGraph: (graph: WorkflowGraph) => void;
|
|
159
|
+
/** Fully custom backend transport. Overrides `endpoint`. */
|
|
160
|
+
transport?: ChatStreamTransport;
|
|
161
|
+
/** Endpoint for the default SSE transport. Default `/api/chat`. */
|
|
162
|
+
endpoint?: string;
|
|
163
|
+
/** Panel heading. Default `"Workflow AI"`. */
|
|
164
|
+
heading?: string;
|
|
165
|
+
/** Panel subtitle. Default `"Draft & edit with a prompt"`. */
|
|
166
|
+
subtitle?: string;
|
|
167
|
+
/** Empty-state suggestion chips. Pass `[]` to hide them. */
|
|
168
|
+
examples?: readonly string[];
|
|
169
|
+
/**
|
|
170
|
+
* Lay a proposal out before it's applied. Defaults to the built-in
|
|
171
|
+
* `layoutProposal` (BFS layered layout preserving surviving-node positions);
|
|
172
|
+
* a builder-host can inject its own (e.g. a dagre merge) to get proper
|
|
173
|
+
* layout — ai-chat stays builder-agnostic (the host supplies the function).
|
|
174
|
+
*/
|
|
175
|
+
layout?: WorkflowLayout;
|
|
176
|
+
/**
|
|
177
|
+
* Caller identity hint attached to each request. **Untrusted on the wire** —
|
|
178
|
+
* a server that gates on it must derive/verify server-side (see the README
|
|
179
|
+
* "Security" section and `createChatStreamResponse`'s `buildRequest`).
|
|
180
|
+
*/
|
|
181
|
+
actor?: ChatActor;
|
|
182
|
+
/** Opaque continuity payload forwarded to the model with each request. */
|
|
183
|
+
context?: unknown;
|
|
184
|
+
};
|
|
185
|
+
declare function WorkflowChat({ currentGraph, applyGraph, transport, endpoint, heading, subtitle, examples, layout, actor, context, }: WorkflowChatProps): react.JSX.Element;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The assistant-ui `ChatModelAdapter` for workflow authoring.
|
|
189
|
+
*
|
|
190
|
+
* The backend streams the assistant's text as it's generated and ends in a
|
|
191
|
+
* single terminal event, mapping onto `LocalRuntime`'s streaming shape
|
|
192
|
+
* (`async *run`, yielding cumulative content):
|
|
193
|
+
*
|
|
194
|
+
* - `text-delta` → append to the running text and yield it (the "typing" feel).
|
|
195
|
+
* - `message` → terminal plain assistant text turn.
|
|
196
|
+
* - `proposal` → terminal `propose_workflow` tool call carrying an approval
|
|
197
|
+
* gate (`approval:{ id }`) + `requires-action`. The gate PAUSES the run; the
|
|
198
|
+
* proposal card renders Apply / Dismiss. On decision the runtime re-invokes
|
|
199
|
+
* this adapter — we detect the resolved gate on the in-progress message and
|
|
200
|
+
* close the turn WITHOUT re-authoring.
|
|
201
|
+
*/
|
|
202
|
+
|
|
203
|
+
/** Optional per-request metadata carried alongside the command + graph. */
|
|
204
|
+
type ChatRequestMeta = {
|
|
205
|
+
/** Caller identity hint — untrusted on the wire (see {@link ChatActor}). */
|
|
206
|
+
actor?: ChatActor;
|
|
207
|
+
/** Opaque, client-carried continuity payload forwarded to the model. */
|
|
208
|
+
context?: unknown;
|
|
209
|
+
};
|
|
210
|
+
type WorkflowChatAdapterOptions = {
|
|
211
|
+
/** How to reach the authoring backend (streamed). */
|
|
212
|
+
transport: ChatStreamTransport;
|
|
213
|
+
/** Reads the graph currently on the canvas (the edit context). */
|
|
214
|
+
getCurrentGraph: () => WorkflowGraph;
|
|
215
|
+
/** Reads optional `actor` / `context` to attach to each request. Stable. */
|
|
216
|
+
getRequestMeta?: () => ChatRequestMeta;
|
|
217
|
+
};
|
|
218
|
+
declare function createWorkflowChatAdapter({ transport, getCurrentGraph, getRequestMeta, }: WorkflowChatAdapterOptions): ChatModelAdapter;
|
|
219
|
+
|
|
220
|
+
type ChatRuntimeProviderProps = {
|
|
221
|
+
children: ReactNode;
|
|
222
|
+
/** Reads the graph currently on the canvas. Must be referentially stable. */
|
|
223
|
+
getCurrentGraph: () => WorkflowGraph;
|
|
224
|
+
/** Swap the backend seam; defaults to `httpChatStreamTransport(endpoint)`. */
|
|
225
|
+
transport?: ChatStreamTransport;
|
|
226
|
+
/** Reads optional `actor` / `context` for each request. Must be stable. */
|
|
227
|
+
getRequestMeta?: () => ChatRequestMeta;
|
|
228
|
+
};
|
|
229
|
+
declare function ChatRuntimeProvider({ children, getCurrentGraph, transport, getRequestMeta, }: ChatRuntimeProviderProps): react.JSX.Element;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Turn a position-optional *proposed* graph into a laid-out {@link WorkflowGraph}.
|
|
233
|
+
*
|
|
234
|
+
* The AI emits topology + config but no coordinates, so we lay the graph out:
|
|
235
|
+
* 1. **Layout stability on edit** — a node that already exists on the canvas
|
|
236
|
+
* (matched by id) keeps its exact current position; only new nodes move.
|
|
237
|
+
* 2. **New nodes** get a simple left-to-right layered layout (BFS depth →
|
|
238
|
+
* column, order-within-depth → row).
|
|
239
|
+
*
|
|
240
|
+
* Pure + framework-free so the host can also call it directly if it drives its
|
|
241
|
+
* own apply path.
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Merge a proposed graph onto the current canvas graph, preserving the layout
|
|
246
|
+
* of surviving nodes. Returns a laid-out {@link WorkflowGraph}.
|
|
247
|
+
*/
|
|
248
|
+
declare function layoutProposal(proposed: ProposedGraph, current?: WorkflowGraph): WorkflowGraph;
|
|
249
|
+
|
|
250
|
+
export { type ChatActor, type ChatRequest, type ChatRequestMeta, ChatRuntimeProvider, type ChatRuntimeProviderProps, type ChatStreamEvent, type ChatStreamTransport, type ProposedEdge, type ProposedGraph, type ProposedNode, WorkflowChat, type WorkflowChatAdapterOptions, type WorkflowChatBridge, type WorkflowChatProps, type WorkflowEdge, type WorkflowGraph, type WorkflowLayout, type WorkflowNode, createWorkflowChatAdapter, httpChatStreamTransport, layoutProposal };
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { ChatModelAdapter } from '@assistant-ui/react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Graph types — deliberately builder-agnostic. `@flowget/ai-chat` never
|
|
7
|
+
* imports `@flowget/builder`; the host maps its own graph to/from these plain
|
|
8
|
+
* structural shapes through the `currentGraph` / `applyGraph` seam on
|
|
9
|
+
* {@link WorkflowChat}. That seam is the whole point of the package: the chat
|
|
10
|
+
* proposes a graph, the host owns how it lands on the canvas.
|
|
11
|
+
*/
|
|
12
|
+
/** A node in a laid-out canvas graph — `position` required. */
|
|
13
|
+
type WorkflowNode = {
|
|
14
|
+
id: string;
|
|
15
|
+
type: string;
|
|
16
|
+
data: Record<string, unknown>;
|
|
17
|
+
position: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
/** An edge in a canvas graph. `null` handles belong to the wire, not here. */
|
|
23
|
+
type WorkflowEdge = {
|
|
24
|
+
id: string;
|
|
25
|
+
source: string;
|
|
26
|
+
target: string;
|
|
27
|
+
sourceHandle?: string;
|
|
28
|
+
targetHandle?: string;
|
|
29
|
+
type?: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* A laid-out graph, ready to apply to a canvas. Arrays are `readonly` so a
|
|
33
|
+
* host's own (often readonly) graph assigns to `currentGraph` without a cast.
|
|
34
|
+
*/
|
|
35
|
+
type WorkflowGraph = {
|
|
36
|
+
nodes: readonly WorkflowNode[];
|
|
37
|
+
edges: readonly WorkflowEdge[];
|
|
38
|
+
};
|
|
39
|
+
/** A node in a *proposed* graph — `position` optional (the AI omits layout). */
|
|
40
|
+
type ProposedNode = {
|
|
41
|
+
id: string;
|
|
42
|
+
type: string;
|
|
43
|
+
data: Record<string, unknown>;
|
|
44
|
+
position?: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/** An edge in a proposed graph — tolerant of the wire's `null` handles. */
|
|
50
|
+
type ProposedEdge = {
|
|
51
|
+
id: string;
|
|
52
|
+
source: string;
|
|
53
|
+
target: string;
|
|
54
|
+
sourceHandle?: string | null;
|
|
55
|
+
targetHandle?: string | null;
|
|
56
|
+
/** Edge kind (e.g. the host's custom edge type); carried through to the canvas. */
|
|
57
|
+
type?: string | null;
|
|
58
|
+
};
|
|
59
|
+
/** The position-optional graph the server proposes. */
|
|
60
|
+
type ProposedGraph = {
|
|
61
|
+
nodes: readonly ProposedNode[];
|
|
62
|
+
edges: readonly ProposedEdge[];
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Turn a position-optional proposal into a laid-out graph, given the current
|
|
66
|
+
* canvas as the baseline. The default is the package's zero-dependency
|
|
67
|
+
* `layoutProposal`; a builder-host can inject its own (e.g. a dagre merge) via
|
|
68
|
+
* the `layout` prop on {@link WorkflowChat} to keep ai-chat builder-agnostic.
|
|
69
|
+
*/
|
|
70
|
+
type WorkflowLayout = (proposed: ProposedGraph, current: WorkflowGraph) => WorkflowGraph;
|
|
71
|
+
/**
|
|
72
|
+
* The host-provided seam that lets the chat read + write the canvas without
|
|
73
|
+
* knowing anything about the host's builder. Supplied to {@link WorkflowChat}.
|
|
74
|
+
*/
|
|
75
|
+
type WorkflowChatBridge = {
|
|
76
|
+
/** Read the graph currently on the canvas (edit context + layout baseline). */
|
|
77
|
+
getCurrentGraph: () => WorkflowGraph;
|
|
78
|
+
/** Commit a laid-out graph to the canvas (e.g. the builder store's setGraph). */
|
|
79
|
+
applyGraph: (graph: WorkflowGraph) => void;
|
|
80
|
+
/** Lay a proposal out before applying. Defaults to the built-in layout. */
|
|
81
|
+
layout?: WorkflowLayout;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The wire contract between the client and the authoring backend — a small
|
|
86
|
+
* mirror of `@flowget/ai`'s request/stream shapes, kept local so the client
|
|
87
|
+
* layer never imports the (server-only) engine.
|
|
88
|
+
*
|
|
89
|
+
* A dev-only type-level parity guard (`contract.parity.ts`, not shipped) keeps
|
|
90
|
+
* this hand-mirror from silently drifting from `@flowget/ai`'s contract.
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The caller identity, mirrored from `@flowget/ai`'s `Actor`.
|
|
95
|
+
*
|
|
96
|
+
* **Untrusted by default.** When set on the client `ChatRequest`, it is plain
|
|
97
|
+
* JSON on the request body — the browser can put anything here. Treat it as a
|
|
98
|
+
* *hint*: a server that gates data access on the actor MUST derive/verify it
|
|
99
|
+
* server-side (from its own session/JWT) via `createChatStreamResponse`'s
|
|
100
|
+
* `buildRequest` option and/or a `@flowget/ai` authorizer. See the README
|
|
101
|
+
* "Security" section.
|
|
102
|
+
*/
|
|
103
|
+
type ChatActor = {
|
|
104
|
+
id: string;
|
|
105
|
+
tenantId?: string;
|
|
106
|
+
roles: readonly string[];
|
|
107
|
+
scopes?: readonly string[];
|
|
108
|
+
claims?: Record<string, unknown>;
|
|
109
|
+
};
|
|
110
|
+
/** Body of `POST <endpoint>`. */
|
|
111
|
+
type ChatRequest = {
|
|
112
|
+
command: string;
|
|
113
|
+
/** The graph currently on the canvas — present for a targeted edit. */
|
|
114
|
+
currentGraph?: WorkflowGraph;
|
|
115
|
+
/** Caller identity hint (untrusted on the wire — see {@link ChatActor}). */
|
|
116
|
+
actor?: ChatActor;
|
|
117
|
+
/** Opaque, client-carried continuity payload forwarded to the model. */
|
|
118
|
+
context?: unknown;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* A streamed chat event (mirrors the engine's `AuthorStreamEvent`). Assistant
|
|
122
|
+
* text arrives as `text-delta`s; the stream ends with a terminal `proposal` |
|
|
123
|
+
* `message`, or `error`. Discriminate on `kind` — the same key `@flowget/ai`
|
|
124
|
+
* uses, so `/server` forwards the engine's events verbatim.
|
|
125
|
+
*/
|
|
126
|
+
type ChatStreamEvent = {
|
|
127
|
+
kind: "text-delta";
|
|
128
|
+
delta: string;
|
|
129
|
+
} | {
|
|
130
|
+
kind: "proposal";
|
|
131
|
+
graph: ProposedGraph;
|
|
132
|
+
summary: string;
|
|
133
|
+
} | {
|
|
134
|
+
kind: "message";
|
|
135
|
+
text: string;
|
|
136
|
+
} | {
|
|
137
|
+
kind: "error";
|
|
138
|
+
error: string;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* The transport seam — how the browser reaches the authoring backend.
|
|
143
|
+
*
|
|
144
|
+
* The **customer-swappable** boundary: the default streams from the host's BFF
|
|
145
|
+
* over SSE, but a host with a different backend swaps this one async generator
|
|
146
|
+
* without touching the runtime, tool UI, or bridge.
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
/** Streams authoring events (deltas → terminal) for a command + graph. */
|
|
150
|
+
type ChatStreamTransport = (request: ChatRequest, signal?: AbortSignal) => AsyncIterable<ChatStreamEvent>;
|
|
151
|
+
/** Default transport: POST command + graph to the BFF, read the SSE stream. */
|
|
152
|
+
declare function httpChatStreamTransport(endpoint?: string): ChatStreamTransport;
|
|
153
|
+
|
|
154
|
+
type WorkflowChatProps = {
|
|
155
|
+
/** The graph currently on the canvas (edit context + layout baseline). */
|
|
156
|
+
currentGraph: WorkflowGraph;
|
|
157
|
+
/** Commit a laid-out graph to the canvas (e.g. the builder store's setGraph). */
|
|
158
|
+
applyGraph: (graph: WorkflowGraph) => void;
|
|
159
|
+
/** Fully custom backend transport. Overrides `endpoint`. */
|
|
160
|
+
transport?: ChatStreamTransport;
|
|
161
|
+
/** Endpoint for the default SSE transport. Default `/api/chat`. */
|
|
162
|
+
endpoint?: string;
|
|
163
|
+
/** Panel heading. Default `"Workflow AI"`. */
|
|
164
|
+
heading?: string;
|
|
165
|
+
/** Panel subtitle. Default `"Draft & edit with a prompt"`. */
|
|
166
|
+
subtitle?: string;
|
|
167
|
+
/** Empty-state suggestion chips. Pass `[]` to hide them. */
|
|
168
|
+
examples?: readonly string[];
|
|
169
|
+
/**
|
|
170
|
+
* Lay a proposal out before it's applied. Defaults to the built-in
|
|
171
|
+
* `layoutProposal` (BFS layered layout preserving surviving-node positions);
|
|
172
|
+
* a builder-host can inject its own (e.g. a dagre merge) to get proper
|
|
173
|
+
* layout — ai-chat stays builder-agnostic (the host supplies the function).
|
|
174
|
+
*/
|
|
175
|
+
layout?: WorkflowLayout;
|
|
176
|
+
/**
|
|
177
|
+
* Caller identity hint attached to each request. **Untrusted on the wire** —
|
|
178
|
+
* a server that gates on it must derive/verify server-side (see the README
|
|
179
|
+
* "Security" section and `createChatStreamResponse`'s `buildRequest`).
|
|
180
|
+
*/
|
|
181
|
+
actor?: ChatActor;
|
|
182
|
+
/** Opaque continuity payload forwarded to the model with each request. */
|
|
183
|
+
context?: unknown;
|
|
184
|
+
};
|
|
185
|
+
declare function WorkflowChat({ currentGraph, applyGraph, transport, endpoint, heading, subtitle, examples, layout, actor, context, }: WorkflowChatProps): react.JSX.Element;
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* The assistant-ui `ChatModelAdapter` for workflow authoring.
|
|
189
|
+
*
|
|
190
|
+
* The backend streams the assistant's text as it's generated and ends in a
|
|
191
|
+
* single terminal event, mapping onto `LocalRuntime`'s streaming shape
|
|
192
|
+
* (`async *run`, yielding cumulative content):
|
|
193
|
+
*
|
|
194
|
+
* - `text-delta` → append to the running text and yield it (the "typing" feel).
|
|
195
|
+
* - `message` → terminal plain assistant text turn.
|
|
196
|
+
* - `proposal` → terminal `propose_workflow` tool call carrying an approval
|
|
197
|
+
* gate (`approval:{ id }`) + `requires-action`. The gate PAUSES the run; the
|
|
198
|
+
* proposal card renders Apply / Dismiss. On decision the runtime re-invokes
|
|
199
|
+
* this adapter — we detect the resolved gate on the in-progress message and
|
|
200
|
+
* close the turn WITHOUT re-authoring.
|
|
201
|
+
*/
|
|
202
|
+
|
|
203
|
+
/** Optional per-request metadata carried alongside the command + graph. */
|
|
204
|
+
type ChatRequestMeta = {
|
|
205
|
+
/** Caller identity hint — untrusted on the wire (see {@link ChatActor}). */
|
|
206
|
+
actor?: ChatActor;
|
|
207
|
+
/** Opaque, client-carried continuity payload forwarded to the model. */
|
|
208
|
+
context?: unknown;
|
|
209
|
+
};
|
|
210
|
+
type WorkflowChatAdapterOptions = {
|
|
211
|
+
/** How to reach the authoring backend (streamed). */
|
|
212
|
+
transport: ChatStreamTransport;
|
|
213
|
+
/** Reads the graph currently on the canvas (the edit context). */
|
|
214
|
+
getCurrentGraph: () => WorkflowGraph;
|
|
215
|
+
/** Reads optional `actor` / `context` to attach to each request. Stable. */
|
|
216
|
+
getRequestMeta?: () => ChatRequestMeta;
|
|
217
|
+
};
|
|
218
|
+
declare function createWorkflowChatAdapter({ transport, getCurrentGraph, getRequestMeta, }: WorkflowChatAdapterOptions): ChatModelAdapter;
|
|
219
|
+
|
|
220
|
+
type ChatRuntimeProviderProps = {
|
|
221
|
+
children: ReactNode;
|
|
222
|
+
/** Reads the graph currently on the canvas. Must be referentially stable. */
|
|
223
|
+
getCurrentGraph: () => WorkflowGraph;
|
|
224
|
+
/** Swap the backend seam; defaults to `httpChatStreamTransport(endpoint)`. */
|
|
225
|
+
transport?: ChatStreamTransport;
|
|
226
|
+
/** Reads optional `actor` / `context` for each request. Must be stable. */
|
|
227
|
+
getRequestMeta?: () => ChatRequestMeta;
|
|
228
|
+
};
|
|
229
|
+
declare function ChatRuntimeProvider({ children, getCurrentGraph, transport, getRequestMeta, }: ChatRuntimeProviderProps): react.JSX.Element;
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Turn a position-optional *proposed* graph into a laid-out {@link WorkflowGraph}.
|
|
233
|
+
*
|
|
234
|
+
* The AI emits topology + config but no coordinates, so we lay the graph out:
|
|
235
|
+
* 1. **Layout stability on edit** — a node that already exists on the canvas
|
|
236
|
+
* (matched by id) keeps its exact current position; only new nodes move.
|
|
237
|
+
* 2. **New nodes** get a simple left-to-right layered layout (BFS depth →
|
|
238
|
+
* column, order-within-depth → row).
|
|
239
|
+
*
|
|
240
|
+
* Pure + framework-free so the host can also call it directly if it drives its
|
|
241
|
+
* own apply path.
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Merge a proposed graph onto the current canvas graph, preserving the layout
|
|
246
|
+
* of surviving nodes. Returns a laid-out {@link WorkflowGraph}.
|
|
247
|
+
*/
|
|
248
|
+
declare function layoutProposal(proposed: ProposedGraph, current?: WorkflowGraph): WorkflowGraph;
|
|
249
|
+
|
|
250
|
+
export { type ChatActor, type ChatRequest, type ChatRequestMeta, ChatRuntimeProvider, type ChatRuntimeProviderProps, type ChatStreamEvent, type ChatStreamTransport, type ProposedEdge, type ProposedGraph, type ProposedNode, WorkflowChat, type WorkflowChatAdapterOptions, type WorkflowChatBridge, type WorkflowChatProps, type WorkflowEdge, type WorkflowGraph, type WorkflowLayout, type WorkflowNode, createWorkflowChatAdapter, httpChatStreamTransport, layoutProposal };
|