@darqlabs/curator-sdk-react 0.6.0 → 0.7.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 +18 -0
- package/dist/cjs/CuratorAdapter.d.ts +27 -1
- package/dist/cjs/CuratorAdapter.d.ts.map +1 -1
- package/dist/cjs/CuratorAdapter.js +113 -19
- package/dist/cjs/CuratorAdapter.js.map +1 -1
- package/dist/cjs/CuratorChat.d.ts +8 -0
- package/dist/cjs/CuratorChat.d.ts.map +1 -1
- package/dist/cjs/CuratorChat.js +61 -8
- package/dist/cjs/CuratorChat.js.map +1 -1
- package/dist/cjs/historyMessages.d.ts +20 -1
- package/dist/cjs/historyMessages.d.ts.map +1 -1
- package/dist/cjs/historyMessages.js +25 -3
- package/dist/cjs/historyMessages.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/mcpApps/McpAppContext.d.ts +39 -0
- package/dist/cjs/mcpApps/McpAppContext.d.ts.map +1 -0
- package/dist/cjs/mcpApps/McpAppContext.js +19 -0
- package/dist/cjs/mcpApps/McpAppContext.js.map +1 -0
- package/dist/cjs/mcpApps/McpAppToolPart.d.ts +22 -0
- package/dist/cjs/mcpApps/McpAppToolPart.d.ts.map +1 -0
- package/dist/cjs/mcpApps/McpAppToolPart.js +270 -0
- package/dist/cjs/mcpApps/McpAppToolPart.js.map +1 -0
- package/dist/cjs/mcpApps/hostBridge.d.ts +127 -0
- package/dist/cjs/mcpApps/hostBridge.d.ts.map +1 -0
- package/dist/cjs/mcpApps/hostBridge.js +306 -0
- package/dist/cjs/mcpApps/hostBridge.js.map +1 -0
- package/dist/esm/CuratorAdapter.d.ts +27 -1
- package/dist/esm/CuratorAdapter.d.ts.map +1 -1
- package/dist/esm/CuratorAdapter.js +113 -19
- package/dist/esm/CuratorAdapter.js.map +1 -1
- package/dist/esm/CuratorChat.d.ts +8 -0
- package/dist/esm/CuratorChat.d.ts.map +1 -1
- package/dist/esm/CuratorChat.js +61 -8
- package/dist/esm/CuratorChat.js.map +1 -1
- package/dist/esm/historyMessages.d.ts +20 -1
- package/dist/esm/historyMessages.d.ts.map +1 -1
- package/dist/esm/historyMessages.js +25 -3
- package/dist/esm/historyMessages.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/mcpApps/McpAppContext.d.ts +39 -0
- package/dist/esm/mcpApps/McpAppContext.d.ts.map +1 -0
- package/dist/esm/mcpApps/McpAppContext.js +15 -0
- package/dist/esm/mcpApps/McpAppContext.js.map +1 -0
- package/dist/esm/mcpApps/McpAppToolPart.d.ts +22 -0
- package/dist/esm/mcpApps/McpAppToolPart.d.ts.map +1 -0
- package/dist/esm/mcpApps/McpAppToolPart.js +266 -0
- package/dist/esm/mcpApps/McpAppToolPart.js.map +1 -0
- package/dist/esm/mcpApps/hostBridge.d.ts +127 -0
- package/dist/esm/mcpApps/hostBridge.d.ts.map +1 -0
- package/dist/esm/mcpApps/hostBridge.js +300 -0
- package/dist/esm/mcpApps/hostBridge.js.map +1 -0
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -124,6 +124,24 @@ Non-planned agents never emit it, so adding the handler is always safe.
|
|
|
124
124
|
|
|
125
125
|
`onPlanProgress` is also available on `<CuratorChatLauncher />`.
|
|
126
126
|
|
|
127
|
+
### Interactive MCP Apps (`mcpApps`)
|
|
128
|
+
|
|
129
|
+
An MCP tool attached to the agent may ship its own view (the [MCP Apps](https://apps.extensions.modelcontextprotocol.io/) extension: a `ui://` HTML resource declared in the tool's `_meta`). When the deployment's admin has exposed that tool's call data, the agent's call renders as an interactive view inline in the transcript — a customer picker, a form, a map — sandboxed on a separate origin. Nothing to configure on your side; it is on by default.
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
<CuratorChat
|
|
133
|
+
agent="booking-bot"
|
|
134
|
+
mcpApps={{
|
|
135
|
+
maxHeight: 520, // cap on a view's height (default 480)
|
|
136
|
+
onModelContextUpdate: (ctx) => log(ctx), // `ui/update-model-context` from a view, surfaced to you
|
|
137
|
+
}}
|
|
138
|
+
/>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Pass `mcpApps={{ enabled: false }}` to show a static card instead of a view. Views render only while the widget is consuming a live streaming response; a conversation reloaded from history shows an "Interactive view expired" card where the view was. A turn a view sends on the person's behalf is labelled "via <tool>" in the transcript — it is app-reported, not typed.
|
|
142
|
+
|
|
143
|
+
Your page's Content-Security-Policy must allow `https://*.scf.auiusercontent.com` in `frame-src` for views to load.
|
|
144
|
+
|
|
127
145
|
### Message actions
|
|
128
146
|
|
|
129
147
|
| Prop | Default | Effect |
|
|
@@ -19,7 +19,33 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import type { CuratorAttachmentAdapter } from "./CuratorAttachmentAdapter.js";
|
|
21
21
|
import type { ChatModelAdapter } from "@assistant-ui/react";
|
|
22
|
-
import type { AssistantMessage, Chat, CuratorError, StreamState, StreamPlanProgress } from "@darqlabs/curator-sdk";
|
|
22
|
+
import type { AssistantMessage, Chat, CuratorError, McpCallToolResult, StreamState, StreamPlanProgress } from "@darqlabs/curator-sdk";
|
|
23
|
+
/**
|
|
24
|
+
* A tool-call part as assistant-ui renders it. `mcp.app.serverId` carries the
|
|
25
|
+
* Curator APP SESSION, not a server id: it is the opaque routing key the view
|
|
26
|
+
* renderer threads through every data-plane call, and a session is exactly
|
|
27
|
+
* "which server, which tool call, for whom".
|
|
28
|
+
*/
|
|
29
|
+
/** JSON as assistant-ui types a tool call's arguments. Stream arguments ARE JSON (they were parsed from it). */
|
|
30
|
+
export type JsonValue = string | number | boolean | null | readonly JsonValue[] | JsonObject;
|
|
31
|
+
export type JsonObject = {
|
|
32
|
+
readonly [k: string]: JsonValue;
|
|
33
|
+
};
|
|
34
|
+
export interface McpAppToolCallPart {
|
|
35
|
+
type: "tool-call";
|
|
36
|
+
toolCallId: string;
|
|
37
|
+
toolName: string;
|
|
38
|
+
args: JsonObject;
|
|
39
|
+
argsText: string;
|
|
40
|
+
result?: McpCallToolResult;
|
|
41
|
+
isError?: boolean;
|
|
42
|
+
mcp: {
|
|
43
|
+
app: {
|
|
44
|
+
resourceUri: string;
|
|
45
|
+
serverId: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
}
|
|
23
49
|
export interface CuratorAdapterCallbacks {
|
|
24
50
|
/** Fired once per successfully-returned assistant message. */
|
|
25
51
|
onMessage?: (message: AssistantMessage) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CuratorAdapter.d.ts","sourceRoot":"","sources":["../../src/CuratorAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAA;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,IAAI,EACJ,YAAY,EACZ,WAAW,EACX,kBAAkB,EACnB,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"CuratorAdapter.d.ts","sourceRoot":"","sources":["../../src/CuratorAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAsB,MAAM,qBAAqB,CAAA;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAChB,IAAI,EACJ,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,kBAAkB,EACnB,MAAM,uBAAuB,CAAA;AAG9B;;;;;GAKG;AACH,gHAAgH;AAChH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,SAAS,EAAE,GAAG,UAAU,CAAA;AAC5F,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAE5D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,WAAW,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,EAAE;QAAE,GAAG,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAA;CACxD;AAKD,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAC/C;;;;;OAKG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;IACtC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACvD,gEAAgE;IAChE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,KAAK,IAAI,CAAA;CAChD;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,EACV,SAAS,GAAE,uBAA4B;AACvC;;;;GAIG;AACH,WAAW,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,gBAAgB,CAAC,GAC7D,gBAAgB,CAyPlB"}
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.createCuratorAdapter = createCuratorAdapter;
|
|
23
|
+
const McpAppContext_js_1 = require("./mcpApps/McpAppContext.js");
|
|
23
24
|
function createCuratorAdapter(chat, callbacks = {},
|
|
24
25
|
/**
|
|
25
26
|
* Supplies the storage references for this turn's attachments. Absent when
|
|
@@ -33,6 +34,11 @@ attachments) {
|
|
|
33
34
|
const files = attachments
|
|
34
35
|
? attachments.takeReferences(latestUserAttachmentIds(messages))
|
|
35
36
|
: [];
|
|
37
|
+
// MCP Apps: a turn a rendered VIEW sent (`ui/message`). The session it was
|
|
38
|
+
// rendered under rides on the message metadata and goes to the server as
|
|
39
|
+
// `app_session`, which validates it and stores the row with a `source`
|
|
40
|
+
// marker — the record says a view sent it, never that a person typed it.
|
|
41
|
+
const appSession = latestUserAppSession(messages);
|
|
36
42
|
// A file with no caption is a complete message — the SDK accepts content
|
|
37
43
|
// OR files, and a bill of lading dropped in with nothing typed is the
|
|
38
44
|
// single most common way this widget is used. Returning early on empty
|
|
@@ -49,16 +55,41 @@ attachments) {
|
|
|
49
55
|
// then `done` (whose message is the terminal reply ALONE) replaced the
|
|
50
56
|
// whole thing — so the user watched a paragraph appear and then get
|
|
51
57
|
// overwritten by different text. Segments keep every token the user saw.
|
|
52
|
-
|
|
58
|
+
// Ordered list of settled parts — text segments and MCP App tool-call
|
|
59
|
+
// parts interleaved in arrival order — plus the in-flight text.
|
|
60
|
+
const settled = [];
|
|
61
|
+
/** Live tool-call parts by id, so completed/failed can update in place. */
|
|
62
|
+
const appParts = new Map();
|
|
53
63
|
let acc = "";
|
|
54
|
-
/**
|
|
64
|
+
/** Settled parts plus the in-flight text, as assistant-ui parts. */
|
|
55
65
|
const partsWith = (trailing) => {
|
|
56
|
-
const
|
|
66
|
+
const out = [...settled];
|
|
67
|
+
if (trailing.length > 0)
|
|
68
|
+
out.push({ type: "text", text: trailing });
|
|
57
69
|
// assistant-ui expects at least one part; an empty run yields empty text.
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
70
|
+
return out.length > 0 ? out : [{ type: "text", text: "" }];
|
|
71
|
+
};
|
|
72
|
+
/** Settle the in-flight text as its own segment, if there is any. */
|
|
73
|
+
const settleText = () => {
|
|
74
|
+
if (acc.trim().length > 0)
|
|
75
|
+
settled.push({ type: "text", text: acc });
|
|
76
|
+
acc = "";
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* A view whose call never got a terminal event would spin forever. Give
|
|
80
|
+
* every unresolved app part a valid error result so the frame receives a
|
|
81
|
+
* terminal tool-result.
|
|
82
|
+
*/
|
|
83
|
+
const interruptUnresolvedApps = (text) => {
|
|
84
|
+
for (const [id, p] of appParts) {
|
|
85
|
+
if (p.result !== undefined)
|
|
86
|
+
continue;
|
|
87
|
+
const updated = { ...p, isError: true, result: { isError: true, content: [{ type: "text", text }] } };
|
|
88
|
+
appParts.set(id, updated);
|
|
89
|
+
const idx = settled.indexOf(p);
|
|
90
|
+
if (idx >= 0)
|
|
91
|
+
settled[idx] = updated;
|
|
92
|
+
}
|
|
62
93
|
};
|
|
63
94
|
try {
|
|
64
95
|
// The options object is now always passed, including when there are no
|
|
@@ -73,9 +104,11 @@ attachments) {
|
|
|
73
104
|
// the local stream and left the agent running to completion — burning
|
|
74
105
|
// tokens for a reply nobody would ever see. Checking an abort is not
|
|
75
106
|
// the same as acting on it.
|
|
76
|
-
const stream =
|
|
77
|
-
?
|
|
78
|
-
|
|
107
|
+
const stream = chat.stream(userText, {
|
|
108
|
+
...(files.length ? { files } : {}),
|
|
109
|
+
...(appSession ? { appSession } : {}),
|
|
110
|
+
signal: abortSignal,
|
|
111
|
+
});
|
|
79
112
|
for await (const event of stream) {
|
|
80
113
|
if (abortSignal.aborted)
|
|
81
114
|
return;
|
|
@@ -92,14 +125,58 @@ attachments) {
|
|
|
92
125
|
// Turn boundary: anything streamed before this belongs to the turn
|
|
93
126
|
// that decided to call a tool. Settle it so the next turn's tokens
|
|
94
127
|
// start a new part instead of extending someone else's sentence.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
128
|
+
// (Whitespace-only narration is dropped by settleText.)
|
|
129
|
+
const hadText = acc.trim().length > 0;
|
|
130
|
+
settleText();
|
|
131
|
+
// MCP Apps: a call that renders a view becomes a tool-call part.
|
|
132
|
+
// Only when the server minted a session for it — a plain tool call
|
|
133
|
+
// stays what it always was, a boundary and nothing rendered.
|
|
134
|
+
if (event.app) {
|
|
135
|
+
const partForApp = {
|
|
136
|
+
type: "tool-call",
|
|
137
|
+
toolCallId: event.toolCallId,
|
|
138
|
+
toolName: event.toolName,
|
|
139
|
+
args: (event.arguments ?? {}),
|
|
140
|
+
argsText: JSON.stringify(event.arguments ?? {}),
|
|
141
|
+
mcp: { app: { resourceUri: event.app.resourceUri, serverId: event.app.session } },
|
|
142
|
+
};
|
|
143
|
+
appParts.set(event.toolCallId, partForApp);
|
|
144
|
+
settled.push(partForApp);
|
|
98
145
|
yield { content: partsWith(acc) };
|
|
99
146
|
}
|
|
100
|
-
else {
|
|
101
|
-
|
|
102
|
-
|
|
147
|
+
else if (hadText) {
|
|
148
|
+
yield { content: partsWith(acc) };
|
|
149
|
+
}
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (event.type === "tool_call.completed" || event.type === "tool_call.failed") {
|
|
153
|
+
// Only MCP App parts exist to update; every other tool call was a
|
|
154
|
+
// boundary. Idempotent: a duplicate terminal event for the same id
|
|
155
|
+
// is a no-op once the result is set.
|
|
156
|
+
const existing = appParts.get(event.toolCallId);
|
|
157
|
+
if (existing && existing.result === undefined) {
|
|
158
|
+
const idx = settled.indexOf(existing);
|
|
159
|
+
const updated = event.type === "tool_call.completed"
|
|
160
|
+
? { ...existing, result: event.result ?? { content: [] }, isError: event.result?.isError === true }
|
|
161
|
+
: {
|
|
162
|
+
...existing,
|
|
163
|
+
isError: true,
|
|
164
|
+
result: event.result ?? {
|
|
165
|
+
isError: true,
|
|
166
|
+
content: [
|
|
167
|
+
{
|
|
168
|
+
type: "text",
|
|
169
|
+
text: event.reason === "policy_denied"
|
|
170
|
+
? "This action was not allowed."
|
|
171
|
+
: "The tool could not complete.",
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
appParts.set(event.toolCallId, updated);
|
|
177
|
+
if (idx >= 0)
|
|
178
|
+
settled[idx] = updated;
|
|
179
|
+
yield { content: partsWith(acc) };
|
|
103
180
|
}
|
|
104
181
|
continue;
|
|
105
182
|
}
|
|
@@ -117,6 +194,7 @@ attachments) {
|
|
|
117
194
|
// `done` carries the TERMINAL reply only, so it replaces the
|
|
118
195
|
// in-flight segment — never the settled ones.
|
|
119
196
|
const finalText = event.message?.content ?? acc;
|
|
197
|
+
interruptUnresolvedApps("The turn ended before this view received a result.");
|
|
120
198
|
yield {
|
|
121
199
|
content: partsWith(finalText),
|
|
122
200
|
status: { type: "complete", reason: "stop" },
|
|
@@ -126,8 +204,9 @@ attachments) {
|
|
|
126
204
|
return;
|
|
127
205
|
}
|
|
128
206
|
if (event.type === "error") {
|
|
207
|
+
interruptUnresolvedApps("The agent failed before this view received a result.");
|
|
129
208
|
yield {
|
|
130
|
-
content: [{ type: "text", text: event.message }],
|
|
209
|
+
content: [...settled.filter((p) => p.type === "tool-call"), { type: "text", text: event.message }],
|
|
131
210
|
status: { type: "incomplete", reason: "error" },
|
|
132
211
|
};
|
|
133
212
|
callbacks.onError?.(new Error(event.message));
|
|
@@ -170,10 +249,11 @@ attachments) {
|
|
|
170
249
|
//
|
|
171
250
|
// Anything already streamed is kept — partial text the user watched
|
|
172
251
|
// arrive is real — and the status marks the turn incomplete.
|
|
173
|
-
const
|
|
252
|
+
const hadAnything = settled.some((p) => p.type === "text") || acc.length > 0;
|
|
174
253
|
const truncatedNotice = "The connection to the agent ended unexpectedly. Please try again.";
|
|
254
|
+
interruptUnresolvedApps("The stream was interrupted before this view received a result.");
|
|
175
255
|
yield {
|
|
176
|
-
content: partsWith(
|
|
256
|
+
content: partsWith(hadAnything ? acc : truncatedNotice),
|
|
177
257
|
status: { type: "incomplete", reason: "error" },
|
|
178
258
|
};
|
|
179
259
|
callbacks.onError?.(new Error("Stream ended without a terminal event"));
|
|
@@ -206,6 +286,20 @@ function latestUserAttachmentIds(messages) {
|
|
|
206
286
|
}
|
|
207
287
|
return [];
|
|
208
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* The app session on the latest user turn, when a rendered view sent it.
|
|
291
|
+
* Stamped by `McpAppToolPart` on `metadata.custom`; absent for typed turns.
|
|
292
|
+
*/
|
|
293
|
+
function latestUserAppSession(messages) {
|
|
294
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
295
|
+
const m = messages[i];
|
|
296
|
+
if (m.role !== "user")
|
|
297
|
+
continue;
|
|
298
|
+
const v = m.metadata?.custom?.[McpAppContext_js_1.APP_SESSION_METADATA_KEY];
|
|
299
|
+
return typeof v === "string" && v ? v : undefined;
|
|
300
|
+
}
|
|
301
|
+
return undefined;
|
|
302
|
+
}
|
|
209
303
|
/**
|
|
210
304
|
* Pull the latest user-turn text out of assistant-ui's structured
|
|
211
305
|
* message array. Text parts are concatenated with newlines; other
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CuratorAdapter.js","sourceRoot":"","sources":["../../src/CuratorAdapter.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;
|
|
1
|
+
{"version":3,"file":"CuratorAdapter.js","sourceRoot":"","sources":["../../src/CuratorAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { type CSSProperties, type ReactNode } from "react";
|
|
13
13
|
import type { AssistantMessage, Curator, CuratorError, Environment, StreamState, StreamPlanProgress } from "@darqlabs/curator-sdk";
|
|
14
|
+
import { type McpAppsOptions } from "./mcpApps/McpAppContext.js";
|
|
14
15
|
/**
|
|
15
16
|
* A starter prompt offered in the empty thread.
|
|
16
17
|
*
|
|
@@ -103,6 +104,13 @@ export interface CuratorChatProps {
|
|
|
103
104
|
onPlanProgress?: (progress: StreamPlanProgress) => void;
|
|
104
105
|
/** Fired on any terminal stream error or thrown exception. */
|
|
105
106
|
onError?: (error: CuratorError | Error) => void;
|
|
107
|
+
/**
|
|
108
|
+
* MCP Apps (SEP-1865). When an attached MCP tool declares a `ui://` view AND
|
|
109
|
+
* the deployment's admin exposed its call data, the agent's call renders as
|
|
110
|
+
* an interactive view inline in the transcript, sandboxed on a separate
|
|
111
|
+
* origin. Default: enabled. See `McpAppsOptions`.
|
|
112
|
+
*/
|
|
113
|
+
mcpApps?: McpAppsOptions;
|
|
106
114
|
/**
|
|
107
115
|
* Show a retry (↻) button under the latest assistant message. Default:
|
|
108
116
|
* off. Retry re-sends the preceding user message through the SDK — note
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CuratorChat.d.ts","sourceRoot":"","sources":["../../src/CuratorChat.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAgF,KAAK,aAAa,EAAsB,KAAK,SAAS,EAAmB,MAAM,OAAO,CAAA;AAW7K,OAAO,KAAK,EACV,gBAAgB,EAEhB,OAAO,EACP,YAAY,EACZ,WAAW,EACX,WAAW,EACX,kBAAkB,EACnB,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"CuratorChat.d.ts","sourceRoot":"","sources":["../../src/CuratorChat.tsx"],"names":[],"mappings":"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"}
|
package/dist/cjs/CuratorChat.js
CHANGED
|
@@ -22,8 +22,10 @@ const Markdown_js_1 = require("./Markdown.js");
|
|
|
22
22
|
const attachmentEnvelope_js_1 = require("./attachmentEnvelope.js");
|
|
23
23
|
const CuratorAttachmentAdapter_js_1 = require("./CuratorAttachmentAdapter.js");
|
|
24
24
|
const historyMessages_js_1 = require("./historyMessages.js");
|
|
25
|
+
const McpAppContext_js_1 = require("./mcpApps/McpAppContext.js");
|
|
26
|
+
const McpAppToolPart_js_1 = require("./mcpApps/McpAppToolPart.js");
|
|
25
27
|
function CuratorChat(props) {
|
|
26
|
-
const { curator, agent, project, environment, system, conversationId, title = "Chat", placeholder = "Type a message…", welcomeMessage, theme = "light", className, style, onClose, loadingIndicator, onMessage, onState, onPlanProgress, onError, enableRetry = false, enableCopy = false, showTimestamps = true, enableAttachments = false, hideHeader = false, historyLimit = 50, prompts, tokens, acceptedFileTypes, maxFileSize, queueWhileRunning = true, } = props;
|
|
28
|
+
const { curator, agent, project, environment, system, conversationId, title = "Chat", placeholder = "Type a message…", welcomeMessage, theme = "light", className, style, onClose, loadingIndicator, onMessage, onState, onPlanProgress, onError, mcpApps, enableRetry = false, enableCopy = false, showTimestamps = true, enableAttachments = false, hideHeader = false, historyLimit = 50, prompts, tokens, acceptedFileTypes, maxFileSize, queueWhileRunning = true, } = props;
|
|
27
29
|
const contextClient = (0, CuratorProvider_js_1.useCuratorOrNull)();
|
|
28
30
|
const client = curator ?? contextClient;
|
|
29
31
|
if (!client) {
|
|
@@ -45,8 +47,45 @@ function CuratorChat(props) {
|
|
|
45
47
|
maxFileSize,
|
|
46
48
|
})
|
|
47
49
|
: undefined, [client, chat, enableAttachments, acceptedFileTypes, maxFileSize]);
|
|
48
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Callbacks are held in a ref so their IDENTITY cannot rebuild the adapter.
|
|
52
|
+
*
|
|
53
|
+
* They used to be memo dependencies, which made this self-defeating in the
|
|
54
|
+
* most ordinary usage there is — a consumer writing
|
|
55
|
+
* `<CuratorChat onState={(s) => setLiveState(s)} />`. That arrow is a new
|
|
56
|
+
* function on every host render, so:
|
|
57
|
+
*
|
|
58
|
+
* 1. `onState` fires mid-stream (that is its entire purpose).
|
|
59
|
+
* 2. The host setStates and re-renders.
|
|
60
|
+
* 3. Every callback prop gets a fresh identity.
|
|
61
|
+
* 4. This memo rebuilds the adapter, `useLocalRuntime` swaps it, and the
|
|
62
|
+
* in-flight async generator is abandoned mid-turn.
|
|
63
|
+
* 5. The `done` event it was about to yield lands in a runtime nobody is
|
|
64
|
+
* reading. The reply never renders — though it is durably stored, so a
|
|
65
|
+
* refresh shows it, which is what made this look like a delivery bug.
|
|
66
|
+
*
|
|
67
|
+
* The callback that exists to deliver live state was destroying the stream
|
|
68
|
+
* delivering it. It stayed hidden while state emission was unreliable and
|
|
69
|
+
* surfaced the moment that started working, which is the wrong order to
|
|
70
|
+
* discover a feedback loop in.
|
|
71
|
+
*
|
|
72
|
+
* The ref is updated during render rather than in an effect: an event can
|
|
73
|
+
* arrive between render and effect flush, and calling the previous render's
|
|
74
|
+
* closure there would hand a consumer stale state.
|
|
75
|
+
*/
|
|
76
|
+
const callbacksRef = (0, react_1.useRef)({ onMessage, onState, onPlanProgress, onError });
|
|
77
|
+
callbacksRef.current = { onMessage, onState, onPlanProgress, onError };
|
|
78
|
+
const adapter = (0, react_1.useMemo)(() => (0, CuratorAdapter_js_1.createCuratorAdapter)(chat, {
|
|
79
|
+
onMessage: (message) => callbacksRef.current.onMessage?.(message),
|
|
80
|
+
onState: (state) => callbacksRef.current.onState?.(state),
|
|
81
|
+
onPlanProgress: (progress) => callbacksRef.current.onPlanProgress?.(progress),
|
|
82
|
+
onError: (error) => callbacksRef.current.onError?.(error),
|
|
83
|
+
}, attachmentAdapter), [chat, attachmentAdapter]);
|
|
49
84
|
const runtime = (0, react_2.useLocalRuntime)(adapter, attachmentAdapter ? { adapters: { attachments: attachmentAdapter } } : undefined);
|
|
85
|
+
// MCP Apps: what a rendered view needs from the widget. The data plane is
|
|
86
|
+
// the same Chat handle the adapter streams on, so a view's calls carry the
|
|
87
|
+
// same API key / end-user identity as the person's own messages.
|
|
88
|
+
const mcpAppContextValue = (0, react_1.useMemo)(() => ({ chat, theme, options: mcpApps ?? {} }), [chat, theme, mcpApps]);
|
|
50
89
|
// Branding is a server-resolved entitlement (org subscription tier), not a
|
|
51
90
|
// client prop — the widget runs on the customer's own page, so a local
|
|
52
91
|
// boolean would be trivially flippable. We fetch the deployment config on
|
|
@@ -139,10 +178,10 @@ function CuratorChat(props) {
|
|
|
139
178
|
...containerStyle,
|
|
140
179
|
...style,
|
|
141
180
|
};
|
|
142
|
-
return ((0, jsx_runtime_1.jsxs)("div", { ref: hostRef, className: className, style: wrapperStyle, "data-curator-chat": true, "data-theme": theme, children: [!hideHeader && (0, jsx_runtime_1.jsx)(Header, { title: title, onClose: onClose }), (0, jsx_runtime_1.jsx)(LoadingIndicatorContext.Provider, { value: loadingIndicator ?? (0, jsx_runtime_1.jsx)(TypingDots, {}), children: (0, jsx_runtime_1.jsx)(RetryEnabledContext.Provider, { value: enableRetry, children: (0, jsx_runtime_1.jsx)(CopyEnabledContext.Provider, { value: enableCopy, children: (0, jsx_runtime_1.jsx)(TimestampsEnabledContext.Provider, { value: showTimestamps, children: (0, jsx_runtime_1.jsx)(react_2.AssistantRuntimeProvider, { runtime: runtime, children: (0, jsx_runtime_1.jsxs)(react_2.ThreadPrimitive.Root, { "data-curator-part": "thread", style: threadRootStyle, children: [(0, jsx_runtime_1.jsxs)(react_2.ThreadPrimitive.Viewport, { autoScroll: true, "data-curator-part": "viewport", style: viewportStyle, children: [(0, jsx_runtime_1.jsx)(react_2.ThreadPrimitive.Empty, { children: !historyLoading && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [welcomeMessage ? (0, jsx_runtime_1.jsx)(Welcome, { text: welcomeMessage }) : null, prompts && prompts.length > 0 && (0, jsx_runtime_1.jsx)(Prompts, { prompts: prompts })] })) }), (0, jsx_runtime_1.jsx)(react_2.ThreadPrimitive.Messages, { components: {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
181
|
+
return ((0, jsx_runtime_1.jsxs)("div", { ref: hostRef, className: className, style: wrapperStyle, "data-curator-chat": true, "data-theme": theme, children: [!hideHeader && (0, jsx_runtime_1.jsx)(Header, { title: title, onClose: onClose }), (0, jsx_runtime_1.jsx)(LoadingIndicatorContext.Provider, { value: loadingIndicator ?? (0, jsx_runtime_1.jsx)(TypingDots, {}), children: (0, jsx_runtime_1.jsx)(RetryEnabledContext.Provider, { value: enableRetry, children: (0, jsx_runtime_1.jsx)(CopyEnabledContext.Provider, { value: enableCopy, children: (0, jsx_runtime_1.jsx)(TimestampsEnabledContext.Provider, { value: showTimestamps, children: (0, jsx_runtime_1.jsx)(react_2.AssistantRuntimeProvider, { runtime: runtime, children: (0, jsx_runtime_1.jsx)(McpAppContext_js_1.McpAppContext.Provider, { value: mcpAppContextValue, children: (0, jsx_runtime_1.jsxs)(react_2.ThreadPrimitive.Root, { "data-curator-part": "thread", style: threadRootStyle, children: [(0, jsx_runtime_1.jsxs)(react_2.ThreadPrimitive.Viewport, { autoScroll: true, "data-curator-part": "viewport", style: viewportStyle, children: [(0, jsx_runtime_1.jsx)(react_2.ThreadPrimitive.Empty, { children: !historyLoading && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [welcomeMessage ? (0, jsx_runtime_1.jsx)(Welcome, { text: welcomeMessage }) : null, prompts && prompts.length > 0 && (0, jsx_runtime_1.jsx)(Prompts, { prompts: prompts })] })) }), (0, jsx_runtime_1.jsx)(react_2.ThreadPrimitive.Messages, { components: {
|
|
182
|
+
UserMessage,
|
|
183
|
+
AssistantMessage,
|
|
184
|
+
} })] }), (0, jsx_runtime_1.jsx)(Composer, { placeholder: placeholder, allowQueue: queueWhileRunning, allowAttachments: !!attachmentAdapter })] }) }) }) }) }) }) }), hidePoweredBy === false && (0, jsx_runtime_1.jsx)(brand_js_1.PoweredByCurator, {})] }));
|
|
146
185
|
}
|
|
147
186
|
// Context for threading the loading indicator into the message-component
|
|
148
187
|
// callbacks without remounting them on every render. Default is rendered
|
|
@@ -194,11 +233,19 @@ function UserMessage() {
|
|
|
194
233
|
// `UserTextPart` is the fallback for transcripts written before the server
|
|
195
234
|
// stored them as a field; both render the same chip.
|
|
196
235
|
const attachments = (0, react_2.useAuiState)((s) => s.message?.attachments) ?? [];
|
|
236
|
+
// MCP Apps: a turn a rendered view sent on the person's behalf. Labelled so
|
|
237
|
+
// the transcript never presents app-reported text as something typed.
|
|
238
|
+
const viaApp = (0, react_2.useAuiState)((s) => {
|
|
239
|
+
const custom = s.message?.metadata?.custom;
|
|
240
|
+
const session = custom?.[McpAppContext_js_1.APP_SESSION_METADATA_KEY];
|
|
241
|
+
const tool = custom?.[McpAppContext_js_1.APP_TOOL_METADATA_KEY];
|
|
242
|
+
return typeof session === "string" && session ? (typeof tool === "string" ? tool : "app") : null;
|
|
243
|
+
});
|
|
197
244
|
const hasText = (0, react_2.useAuiState)((s) => s.message?.content?.some((p) => p.type === "text" && p.text.length > 0) ?? false);
|
|
198
245
|
return ((0, jsx_runtime_1.jsxs)(react_2.MessagePrimitive.Root, { "data-curator-part": "message message-user", style: rowEndStyle, children: [(0, jsx_runtime_1.jsxs)("div", { "data-curator-part": "bubble bubble-user", style: { ...bubbleBaseStyle, ...userBubbleStyle }, children: [attachments.map((a, i) => ((0, jsx_runtime_1.jsx)(SentAttachmentChip, { name: a.name,
|
|
199
246
|
// A file sent with no caption is the common case; the chip is then
|
|
200
247
|
// the whole bubble and must not carry a top margin.
|
|
201
|
-
first: i === 0 && !hasText }, a.id))), (0, jsx_runtime_1.jsx)(react_2.MessagePrimitive.Parts, { components: { Text: UserTextPart } })] }), (0, jsx_runtime_1.jsx)(Timestamp, { align: "end" })] }));
|
|
248
|
+
first: i === 0 && !hasText }, a.id))), (0, jsx_runtime_1.jsx)(react_2.MessagePrimitive.Parts, { components: { Text: UserTextPart } }), viaApp && ((0, jsx_runtime_1.jsxs)("span", { "data-curator-part": "via-app", style: viaAppStyle, title: "Sent by an interactive view, not typed", children: ["via ", (0, McpAppToolPart_js_1.humanizeToolName)(viaApp)] }))] }), (0, jsx_runtime_1.jsx)(Timestamp, { align: "end" })] }));
|
|
202
249
|
}
|
|
203
250
|
/** One attachment on a sent message. Shared by the structural and envelope paths. */
|
|
204
251
|
function SentAttachmentChip({ name, size, mimeType, first, }) {
|
|
@@ -241,7 +288,7 @@ function AssistantMessage() {
|
|
|
241
288
|
const indicator = (0, react_1.useContext)(LoadingIndicatorContext);
|
|
242
289
|
const retryEnabled = (0, react_1.useContext)(RetryEnabledContext);
|
|
243
290
|
const copyEnabled = (0, react_1.useContext)(CopyEnabledContext);
|
|
244
|
-
return ((0, jsx_runtime_1.jsxs)(react_2.MessagePrimitive.Root, { "data-curator-part": "message message-assistant", style: rowStartStyle, children: [(0, jsx_runtime_1.jsxs)("div", { "data-curator-part": "bubble bubble-assistant", style: { ...bubbleBaseStyle, ...assistantBubbleStyle }, children: [(0, jsx_runtime_1.jsx)(react_2.MessagePrimitive.If, { hasContent: false, children: indicator }), (0, jsx_runtime_1.jsx)(react_2.MessagePrimitive.Parts, { components: { Text: AssistantTextPart } })] }), (0, jsx_runtime_1.jsxs)("div", { "data-curator-part": "message-meta", style: messageMetaStyle, children: [(0, jsx_runtime_1.jsx)(Timestamp, { align: "start" }), (retryEnabled || copyEnabled) && (
|
|
291
|
+
return ((0, jsx_runtime_1.jsxs)(react_2.MessagePrimitive.Root, { "data-curator-part": "message message-assistant", style: rowStartStyle, children: [(0, jsx_runtime_1.jsxs)("div", { "data-curator-part": "bubble bubble-assistant", style: { ...bubbleBaseStyle, ...assistantBubbleStyle }, children: [(0, jsx_runtime_1.jsx)(react_2.MessagePrimitive.If, { hasContent: false, children: indicator }), (0, jsx_runtime_1.jsx)(react_2.MessagePrimitive.Parts, { components: { Text: AssistantTextPart, tools: { Fallback: McpAppToolPart_js_1.McpAppToolPart } } })] }), (0, jsx_runtime_1.jsxs)("div", { "data-curator-part": "message-meta", style: messageMetaStyle, children: [(0, jsx_runtime_1.jsx)(Timestamp, { align: "start" }), (retryEnabled || copyEnabled) && (
|
|
245
292
|
// `hideWhenRunning` still applies: actions on a half-written reply
|
|
246
293
|
// would copy a fragment.
|
|
247
294
|
(0, jsx_runtime_1.jsxs)(react_2.ActionBarPrimitive.Root, { hideWhenRunning: true, "data-curator-part": "action-bar", style: actionBarStyle, children: [copyEnabled && ((0, jsx_runtime_1.jsxs)(react_2.ActionBarPrimitive.Copy, { "aria-label": "Copy", "data-curator-part": "action-button", style: actionButtonStyle, children: [(0, jsx_runtime_1.jsx)(react_2.MessagePrimitive.If, { copied: true, children: (0, jsx_runtime_1.jsx)(CheckGlyph, {}) }), (0, jsx_runtime_1.jsx)(react_2.MessagePrimitive.If, { copied: false, children: (0, jsx_runtime_1.jsx)(CopyGlyph, {}) })] })), retryEnabled && ((0, jsx_runtime_1.jsx)(react_2.ActionBarPrimitive.Reload, { "aria-label": "Retry", "data-curator-part": "action-button", style: actionButtonStyle, children: (0, jsx_runtime_1.jsx)(RetryGlyph, {}) }))] }))] })] }));
|
|
@@ -742,6 +789,12 @@ const actionButtonStyle = {
|
|
|
742
789
|
cursor: "pointer",
|
|
743
790
|
transition: "color 120ms ease, background 120ms ease",
|
|
744
791
|
};
|
|
792
|
+
const viaAppStyle = {
|
|
793
|
+
display: "block",
|
|
794
|
+
marginTop: 4,
|
|
795
|
+
fontSize: 11,
|
|
796
|
+
opacity: 0.7,
|
|
797
|
+
};
|
|
745
798
|
const bubbleBaseStyle = {
|
|
746
799
|
// Two caps, both needed. The percentage keeps the bubble proportional in a
|
|
747
800
|
// narrow widget; the absolute stops a bubble spanning a 2000px-wide desktop
|