@darqlabs/curator-sdk-react 0.4.1 → 0.5.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/cjs/CuratorChat.d.ts +15 -1
- package/dist/cjs/CuratorChat.d.ts.map +1 -1
- package/dist/cjs/CuratorChat.js +162 -26
- package/dist/cjs/CuratorChat.js.map +1 -1
- package/dist/cjs/historyMessages.d.ts +68 -0
- package/dist/cjs/historyMessages.d.ts.map +1 -0
- package/dist/cjs/historyMessages.js +79 -0
- package/dist/cjs/historyMessages.js.map +1 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/useCuratorChat.d.ts +14 -0
- package/dist/cjs/useCuratorChat.d.ts.map +1 -1
- package/dist/cjs/useCuratorChat.js +75 -1
- package/dist/cjs/useCuratorChat.js.map +1 -1
- package/dist/esm/CuratorChat.d.ts +15 -1
- package/dist/esm/CuratorChat.d.ts.map +1 -1
- package/dist/esm/CuratorChat.js +164 -28
- package/dist/esm/CuratorChat.js.map +1 -1
- package/dist/esm/historyMessages.d.ts +68 -0
- package/dist/esm/historyMessages.d.ts.map +1 -0
- package/dist/esm/historyMessages.js +75 -0
- package/dist/esm/historyMessages.js.map +1 -0
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/useCuratorChat.d.ts +14 -0
- package/dist/esm/useCuratorChat.d.ts.map +1 -1
- package/dist/esm/useCuratorChat.js +75 -1
- package/dist/esm/useCuratorChat.js.map +1 -1
- package/package.json +3 -3
package/dist/cjs/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export type { CuratorChatProps, CuratorTokens, CuratorPrompt } from "./CuratorCh
|
|
|
3
3
|
export { CuratorChatLauncher } from "./CuratorChatLauncher.js";
|
|
4
4
|
export type { CuratorChatLauncherProps, LauncherPlacement, } from "./CuratorChatLauncher.js";
|
|
5
5
|
export { useCuratorChat } from "./useCuratorChat.js";
|
|
6
|
+
export { normalizeHistory, toThreadMessages } from "./historyMessages.js";
|
|
7
|
+
export type { NormalizedHistoryMessage } from "./historyMessages.js";
|
|
6
8
|
export { CuratorAttachmentAdapter } from "./CuratorAttachmentAdapter.js";
|
|
7
9
|
export type { CuratorAttachmentAdapterOptions } from "./CuratorAttachmentAdapter.js";
|
|
8
10
|
export type { ChatBubble, UseCuratorChatOptions, UseCuratorChatResult, SendArgs, } from "./useCuratorChat.js";
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,YAAY,EACV,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,YAAY,EACV,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAKpD,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACzE,YAAY,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAA;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AACxE,YAAY,EAAE,+BAA+B,EAAE,MAAM,+BAA+B,CAAA;AACpF,YAAY,EACV,UAAU,EACV,qBAAqB,EACrB,oBAAoB,EACpB,QAAQ,GACT,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AACpF,YAAY,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG1D,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AACvF,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.formatAttachmentSize = exports.splitAttachmentEnvelope = exports.CuratorMark = exports.PoweredByCurator = exports.useCuratorOrNull = exports.useCurator = exports.CuratorProvider = exports.CuratorAttachmentAdapter = exports.useCuratorChat = exports.CuratorChatLauncher = exports.CuratorChat = void 0;
|
|
3
|
+
exports.formatAttachmentSize = exports.splitAttachmentEnvelope = exports.CuratorMark = exports.PoweredByCurator = exports.useCuratorOrNull = exports.useCurator = exports.CuratorProvider = exports.CuratorAttachmentAdapter = exports.toThreadMessages = exports.normalizeHistory = exports.useCuratorChat = exports.CuratorChatLauncher = exports.CuratorChat = void 0;
|
|
4
4
|
var CuratorChat_js_1 = require("./CuratorChat.js");
|
|
5
5
|
Object.defineProperty(exports, "CuratorChat", { enumerable: true, get: function () { return CuratorChat_js_1.CuratorChat; } });
|
|
6
6
|
var CuratorChatLauncher_js_1 = require("./CuratorChatLauncher.js");
|
|
@@ -9,6 +9,11 @@ var useCuratorChat_js_1 = require("./useCuratorChat.js");
|
|
|
9
9
|
Object.defineProperty(exports, "useCuratorChat", { enumerable: true, get: function () { return useCuratorChat_js_1.useCuratorChat; } });
|
|
10
10
|
// Exported so a consumer driving their own composer on the hook can reuse the
|
|
11
11
|
// same upload path the widget uses, rather than reimplementing presign + PUT.
|
|
12
|
+
// Exported so a consumer rendering their own transcript gets the same
|
|
13
|
+
// normalization the widget uses — tool rows dropped, envelope fallback.
|
|
14
|
+
var historyMessages_js_1 = require("./historyMessages.js");
|
|
15
|
+
Object.defineProperty(exports, "normalizeHistory", { enumerable: true, get: function () { return historyMessages_js_1.normalizeHistory; } });
|
|
16
|
+
Object.defineProperty(exports, "toThreadMessages", { enumerable: true, get: function () { return historyMessages_js_1.toThreadMessages; } });
|
|
12
17
|
var CuratorAttachmentAdapter_js_1 = require("./CuratorAttachmentAdapter.js");
|
|
13
18
|
Object.defineProperty(exports, "CuratorAttachmentAdapter", { enumerable: true, get: function () { return CuratorAttachmentAdapter_js_1.CuratorAttachmentAdapter; } });
|
|
14
19
|
var CuratorProvider_js_1 = require("./CuratorProvider.js");
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAA8C;AAArC,6GAAA,WAAW,OAAA;AAEpB,mEAA8D;AAArD,6HAAA,mBAAmB,OAAA;AAK5B,yDAAoD;AAA3C,mHAAA,cAAc,OAAA;AACvB,8EAA8E;AAC9E,8EAA8E;AAC9E,6EAAwE;AAA/D,uIAAA,wBAAwB,OAAA;AAQjC,2DAAoF;AAA3E,qHAAA,eAAe,OAAA;AAAE,gHAAA,UAAU,OAAA;AAAE,sHAAA,gBAAgB,OAAA;AAEtD,uCAA0D;AAAjD,4GAAA,gBAAgB,OAAA;AAAE,uGAAA,WAAW,OAAA;AACtC,yEAAyE;AACzE,4CAA4C;AAC5C,iEAAuF;AAA9E,gIAAA,uBAAuB,OAAA;AAAE,6HAAA,oBAAoB,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mDAA8C;AAArC,6GAAA,WAAW,OAAA;AAEpB,mEAA8D;AAArD,6HAAA,mBAAmB,OAAA;AAK5B,yDAAoD;AAA3C,mHAAA,cAAc,OAAA;AACvB,8EAA8E;AAC9E,8EAA8E;AAC9E,sEAAsE;AACtE,wEAAwE;AACxE,2DAAyE;AAAhE,sHAAA,gBAAgB,OAAA;AAAE,sHAAA,gBAAgB,OAAA;AAE3C,6EAAwE;AAA/D,uIAAA,wBAAwB,OAAA;AAQjC,2DAAoF;AAA3E,qHAAA,eAAe,OAAA;AAAE,gHAAA,UAAU,OAAA;AAAE,sHAAA,gBAAgB,OAAA;AAEtD,uCAA0D;AAAjD,4GAAA,gBAAgB,OAAA;AAAE,uGAAA,WAAW,OAAA;AACtC,yEAAyE;AACzE,4CAA4C;AAC5C,iEAAuF;AAA9E,gIAAA,uBAAuB,OAAA;AAAE,6HAAA,oBAAoB,OAAA"}
|
|
@@ -66,8 +66,15 @@ export interface UseCuratorChatOptions {
|
|
|
66
66
|
/**
|
|
67
67
|
* Reattach to an existing conversation id instead of opening a fresh one.
|
|
68
68
|
* Useful for resuming across sessions.
|
|
69
|
+
*
|
|
70
|
+
* Prior messages are fetched into `messages` on attach. Before this, only the
|
|
71
|
+
* server side resumed: the doc promised "resuming across sessions" while
|
|
72
|
+
* `messages` started empty, so a resumed conversation looked brand new to the
|
|
73
|
+
* person in it.
|
|
69
74
|
*/
|
|
70
75
|
conversationId?: string;
|
|
76
|
+
/** How many recent messages to load when reattaching. Default 50. */
|
|
77
|
+
historyLimit?: number;
|
|
71
78
|
/** Fired once per successfully-returned assistant message. */
|
|
72
79
|
onMessage?: (message: AssistantMessage) => void;
|
|
73
80
|
/** Fired on any send-time error (typed SDK error or unknown). */
|
|
@@ -81,6 +88,13 @@ export interface SendArgs {
|
|
|
81
88
|
export interface UseCuratorChatResult {
|
|
82
89
|
/** All bubbles, in chronological order. */
|
|
83
90
|
messages: ChatBubble[];
|
|
91
|
+
/**
|
|
92
|
+
* True while prior messages are being fetched for a reattached conversation.
|
|
93
|
+
*
|
|
94
|
+
* Exposed because the alternative is a consumer rendering their empty state
|
|
95
|
+
* over a transcript that is one tick from arriving.
|
|
96
|
+
*/
|
|
97
|
+
loadingHistory: boolean;
|
|
84
98
|
/** Send a user message and await the assistant's reply. */
|
|
85
99
|
send: (content: string, args?: SendArgs) => Promise<void>;
|
|
86
100
|
/** True while a send is in flight. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCuratorChat.d.ts","sourceRoot":"","sources":["../../src/useCuratorChat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACpB,IAAI,EACJ,OAAO,EACP,WAAW,EACX,cAAc,EACf,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAEL,YAAY,EAEb,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"useCuratorChat.d.ts","sourceRoot":"","sources":["../../src/useCuratorChat.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,6 +14,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
14
14
|
exports.useCuratorChat = useCuratorChat;
|
|
15
15
|
const react_1 = require("react");
|
|
16
16
|
const curator_sdk_1 = require("@darqlabs/curator-sdk");
|
|
17
|
+
const historyMessages_js_1 = require("./historyMessages.js");
|
|
17
18
|
const CuratorProvider_js_1 = require("./CuratorProvider.js");
|
|
18
19
|
let counter = 0;
|
|
19
20
|
function localId() {
|
|
@@ -21,7 +22,7 @@ function localId() {
|
|
|
21
22
|
return `local_${Date.now().toString(36)}_${counter}`;
|
|
22
23
|
}
|
|
23
24
|
function useCuratorChat(opts) {
|
|
24
|
-
const { agent, project, environment, system, conversationId, onMessage, onError } = opts;
|
|
25
|
+
const { agent, project, environment, system, conversationId, historyLimit = 50, onMessage, onError } = opts;
|
|
25
26
|
// Resolve the client: explicit prop wins, then context, then fail loud.
|
|
26
27
|
const contextClient = (0, CuratorProvider_js_1.useCuratorOrNull)();
|
|
27
28
|
const curator = opts.curator ?? contextClient;
|
|
@@ -53,6 +54,78 @@ function useCuratorChat(opts) {
|
|
|
53
54
|
setConversationIdState(chat.id);
|
|
54
55
|
}
|
|
55
56
|
}, [chat]);
|
|
57
|
+
// Load prior messages for a reattached conversation.
|
|
58
|
+
//
|
|
59
|
+
// Cancelled on unmount and on a handle swap: the await means the page can
|
|
60
|
+
// land after the consumer has moved to another conversation, and splicing one
|
|
61
|
+
// transcript's history into another's is worse than showing none.
|
|
62
|
+
const [loadingHistory, setLoadingHistory] = (0, react_1.useState)(!!conversationId);
|
|
63
|
+
(0, react_1.useEffect)(() => {
|
|
64
|
+
if (!conversationId) {
|
|
65
|
+
setLoadingHistory(false);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Not every handle provides history — a wrapper, a stub, or an older
|
|
69
|
+
// core SDK may not. Rendering an empty transcript is the previous
|
|
70
|
+
// behaviour and an acceptable one; throwing inside an effect is not.
|
|
71
|
+
if (typeof chat.history !== "function") {
|
|
72
|
+
setLoadingHistory(false);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
let cancelled = false;
|
|
76
|
+
setLoadingHistory(true);
|
|
77
|
+
chat
|
|
78
|
+
.history({ limit: historyLimit })
|
|
79
|
+
.then((page) => {
|
|
80
|
+
if (cancelled)
|
|
81
|
+
return;
|
|
82
|
+
const prior = (0, historyMessages_js_1.normalizeHistory)(page.messages).map((m) => m.role === "user"
|
|
83
|
+
? {
|
|
84
|
+
kind: "user",
|
|
85
|
+
content: m.text,
|
|
86
|
+
...(m.attachments.length > 0
|
|
87
|
+
? {
|
|
88
|
+
attachments: m.attachments.map((a) => ({
|
|
89
|
+
// History says what a file was, not where it lives. The
|
|
90
|
+
// storage key is not part of a rendered transcript, and
|
|
91
|
+
// a chip needs only the name, type and size.
|
|
92
|
+
storageKey: "",
|
|
93
|
+
filename: a.filename,
|
|
94
|
+
mimeType: a.mimeType,
|
|
95
|
+
size: a.size,
|
|
96
|
+
})),
|
|
97
|
+
}
|
|
98
|
+
: {}),
|
|
99
|
+
createdAt: m.createdAt ?? new Date().toISOString(),
|
|
100
|
+
localId: localId(),
|
|
101
|
+
}
|
|
102
|
+
: {
|
|
103
|
+
kind: "assistant",
|
|
104
|
+
content: m.text,
|
|
105
|
+
sequence: 0,
|
|
106
|
+
stepId: null,
|
|
107
|
+
createdAt: m.createdAt ?? new Date().toISOString(),
|
|
108
|
+
runId: "",
|
|
109
|
+
});
|
|
110
|
+
// Replaces rather than appends: this runs on attach, when anything
|
|
111
|
+
// already in the list belongs to a different conversation.
|
|
112
|
+
setMessages(prior);
|
|
113
|
+
})
|
|
114
|
+
.catch((err) => {
|
|
115
|
+
// A transcript that will not load must not stop someone sending.
|
|
116
|
+
if (cancelled)
|
|
117
|
+
return;
|
|
118
|
+
setError(err);
|
|
119
|
+
onError?.(err);
|
|
120
|
+
})
|
|
121
|
+
.finally(() => {
|
|
122
|
+
if (!cancelled)
|
|
123
|
+
setLoadingHistory(false);
|
|
124
|
+
});
|
|
125
|
+
return () => {
|
|
126
|
+
cancelled = true;
|
|
127
|
+
};
|
|
128
|
+
}, [chat, conversationId, historyLimit, onError]);
|
|
56
129
|
const send = (0, react_1.useCallback)(async (content, args = {}) => {
|
|
57
130
|
const trimmed = content.trim();
|
|
58
131
|
if (!trimmed && !args.files?.length)
|
|
@@ -145,6 +218,7 @@ function useCuratorChat(opts) {
|
|
|
145
218
|
error,
|
|
146
219
|
chat,
|
|
147
220
|
conversationId: conversationIdState,
|
|
221
|
+
loadingHistory,
|
|
148
222
|
reset,
|
|
149
223
|
pendingAuthorization,
|
|
150
224
|
connect,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCuratorChat.js","sourceRoot":"","sources":["../../src/useCuratorChat.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;
|
|
1
|
+
{"version":3,"file":"useCuratorChat.js","sourceRoot":"","sources":["../../src/useCuratorChat.ts"],"names":[],"mappings":"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"}
|
|
@@ -37,8 +37,22 @@ export interface CuratorChatProps {
|
|
|
37
37
|
environment?: Environment;
|
|
38
38
|
/** Address a system-scoped deployment. */
|
|
39
39
|
system?: boolean;
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Reattach to an existing conversation id instead of starting fresh.
|
|
42
|
+
*
|
|
43
|
+
* Prior messages are fetched and replayed on mount, so the transcript shows
|
|
44
|
+
* what came before rather than an empty thread against a live conversation.
|
|
45
|
+
*/
|
|
41
46
|
conversationId?: string;
|
|
47
|
+
/**
|
|
48
|
+
* How many recent messages to replay when reattaching. Default 50.
|
|
49
|
+
*
|
|
50
|
+
* The most recent page, not the whole conversation: a widget shows the tail
|
|
51
|
+
* of a discussion, and pulling an unbounded history to render a panel that
|
|
52
|
+
* displays the last few turns costs the consumer a large response for
|
|
53
|
+
* nothing.
|
|
54
|
+
*/
|
|
55
|
+
historyLimit?: number;
|
|
42
56
|
/** Header title. Default: "Chat". */
|
|
43
57
|
title?: string;
|
|
44
58
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CuratorChat.d.ts","sourceRoot":"","sources":["../../src/CuratorChat.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"CuratorChat.d.ts","sourceRoot":"","sources":["../../src/CuratorChat.tsx"],"names":[],"mappings":"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"}
|
package/dist/esm/CuratorChat.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* <CuratorChat /> — drop-in chat widget backed by a Curator SDK client.
|
|
4
4
|
*
|
|
@@ -10,7 +10,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
10
10
|
* (header, brand footer, theme tokens, close button) and the bubble
|
|
11
11
|
* layout stay ours so the widget keeps its identity across themes.
|
|
12
12
|
*/
|
|
13
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react";
|
|
13
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useLayoutEffect } from "react";
|
|
14
14
|
import { ActionBarPrimitive, AssistantRuntimeProvider, MessagePrimitive, ThreadPrimitive, useAui, useAuiState, useLocalRuntime, } from "@assistant-ui/react";
|
|
15
15
|
import { useCuratorOrNull } from "./CuratorProvider.js";
|
|
16
16
|
import { createCuratorAdapter } from "./CuratorAdapter.js";
|
|
@@ -18,8 +18,9 @@ import { PoweredByCurator } from "./brand.js";
|
|
|
18
18
|
import { Markdown } from "./Markdown.js";
|
|
19
19
|
import { splitAttachmentEnvelope, formatAttachmentSize } from "./attachmentEnvelope.js";
|
|
20
20
|
import { CuratorAttachmentAdapter } from "./CuratorAttachmentAdapter.js";
|
|
21
|
+
import { toThreadMessages } from "./historyMessages.js";
|
|
21
22
|
export function CuratorChat(props) {
|
|
22
|
-
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, prompts, tokens, acceptedFileTypes, maxFileSize, queueWhileRunning = true, } = props;
|
|
23
|
+
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;
|
|
23
24
|
const contextClient = useCuratorOrNull();
|
|
24
25
|
const client = curator ?? contextClient;
|
|
25
26
|
if (!client) {
|
|
@@ -72,6 +73,61 @@ export function CuratorChat(props) {
|
|
|
72
73
|
// Order is the contract: non-colour defaults, then the theme's palette, then
|
|
73
74
|
// the consumer's tokens, then the raw `style` prop — each able to override
|
|
74
75
|
// everything before it, with `style` still winning as it always has.
|
|
76
|
+
// Replay prior messages when reattaching.
|
|
77
|
+
//
|
|
78
|
+
// `conversationId` used to attach the handle and nothing else, so the server
|
|
79
|
+
// resumed the conversation while the panel rendered empty — the transcript
|
|
80
|
+
// and the run disagreeing about what had happened. Seeding the runtime is the
|
|
81
|
+
// client half of the same resume.
|
|
82
|
+
//
|
|
83
|
+
// Guarded against the late reply: an await means the fetch can land after the
|
|
84
|
+
// handle has been swapped or the widget unmounted, and importing into a
|
|
85
|
+
// runtime that has moved on would splice one conversation's history into
|
|
86
|
+
// another's thread.
|
|
87
|
+
const [historyLoading, setHistoryLoading] = useState(!!conversationId);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (!conversationId) {
|
|
90
|
+
setHistoryLoading(false);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Not every handle provides history — a wrapper, a stub, or an older
|
|
94
|
+
// core SDK may not. Rendering an empty transcript is the previous
|
|
95
|
+
// behaviour and an acceptable one; throwing inside an effect is not.
|
|
96
|
+
if (typeof chat.history !== "function") {
|
|
97
|
+
setHistoryLoading(false);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
let cancelled = false;
|
|
101
|
+
setHistoryLoading(true);
|
|
102
|
+
chat
|
|
103
|
+
.history({ limit: historyLimit })
|
|
104
|
+
.then((page) => {
|
|
105
|
+
if (cancelled)
|
|
106
|
+
return;
|
|
107
|
+
const seeded = toThreadMessages(page.messages);
|
|
108
|
+
if (seeded.length > 0)
|
|
109
|
+
runtime.thread.reset(seeded);
|
|
110
|
+
})
|
|
111
|
+
.catch((err) => {
|
|
112
|
+
// A transcript that will not load is not a reason to break a
|
|
113
|
+
// conversation that otherwise works; the person can still send.
|
|
114
|
+
if (!cancelled)
|
|
115
|
+
onError?.(err);
|
|
116
|
+
})
|
|
117
|
+
.finally(() => {
|
|
118
|
+
if (!cancelled)
|
|
119
|
+
setHistoryLoading(false);
|
|
120
|
+
});
|
|
121
|
+
return () => {
|
|
122
|
+
cancelled = true;
|
|
123
|
+
};
|
|
124
|
+
}, [chat, conversationId, historyLimit, runtime, onError]);
|
|
125
|
+
// Layout effect, not effect: the sheet must be in place before the browser
|
|
126
|
+
// paints, or the first frame renders unstyled and visibly settles.
|
|
127
|
+
const hostRef = useRef(null);
|
|
128
|
+
useIsomorphicLayoutEffect(() => {
|
|
129
|
+
injectCuratorStyles(hostRef.current);
|
|
130
|
+
}, []);
|
|
75
131
|
const palette = theme === "dark" ? DARK_VARS : LIGHT_VARS;
|
|
76
132
|
const wrapperStyle = {
|
|
77
133
|
...BASE_TOKENS,
|
|
@@ -80,7 +136,7 @@ export function CuratorChat(props) {
|
|
|
80
136
|
...containerStyle,
|
|
81
137
|
...style,
|
|
82
138
|
};
|
|
83
|
-
return (_jsxs("div", { className: className, style: wrapperStyle, "data-curator-chat": true, "data-theme": theme, children: [!hideHeader && _jsx(Header, { title: title, onClose: onClose }), _jsx(LoadingIndicatorContext.Provider, { value: loadingIndicator ?? _jsx(TypingDots, {}), children: _jsx(RetryEnabledContext.Provider, { value: enableRetry, children: _jsx(CopyEnabledContext.Provider, { value: enableCopy, children: _jsx(TimestampsEnabledContext.Provider, { value: showTimestamps, children: _jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsxs(ThreadPrimitive.Root, { "data-curator-part": "thread", style: threadRootStyle, children: [_jsxs(ThreadPrimitive.Viewport, { autoScroll: true, "data-curator-part": "viewport", style: viewportStyle, children: [
|
|
139
|
+
return (_jsxs("div", { ref: hostRef, className: className, style: wrapperStyle, "data-curator-chat": true, "data-theme": theme, children: [!hideHeader && _jsx(Header, { title: title, onClose: onClose }), _jsx(LoadingIndicatorContext.Provider, { value: loadingIndicator ?? _jsx(TypingDots, {}), children: _jsx(RetryEnabledContext.Provider, { value: enableRetry, children: _jsx(CopyEnabledContext.Provider, { value: enableCopy, children: _jsx(TimestampsEnabledContext.Provider, { value: showTimestamps, children: _jsx(AssistantRuntimeProvider, { runtime: runtime, children: _jsxs(ThreadPrimitive.Root, { "data-curator-part": "thread", style: threadRootStyle, children: [_jsxs(ThreadPrimitive.Viewport, { autoScroll: true, "data-curator-part": "viewport", style: viewportStyle, children: [_jsx(ThreadPrimitive.Empty, { children: !historyLoading && (_jsxs(_Fragment, { children: [welcomeMessage ? _jsx(Welcome, { text: welcomeMessage }) : null, prompts && prompts.length > 0 && _jsx(Prompts, { prompts: prompts })] })) }), _jsx(ThreadPrimitive.Messages, { components: {
|
|
84
140
|
UserMessage,
|
|
85
141
|
AssistantMessage,
|
|
86
142
|
} })] }), _jsx(Composer, { placeholder: placeholder, allowQueue: queueWhileRunning, allowAttachments: !!attachmentAdapter })] }) }) }) }) }) }), hidePoweredBy === false && _jsx(PoweredByCurator, {})] }));
|
|
@@ -88,6 +144,14 @@ export function CuratorChat(props) {
|
|
|
88
144
|
// Context for threading the loading indicator into the message-component
|
|
89
145
|
// callbacks without remounting them on every render. Default is rendered
|
|
90
146
|
// when no consumer-supplied node is provided.
|
|
147
|
+
/**
|
|
148
|
+
* `useLayoutEffect` in the browser, `useEffect` on the server.
|
|
149
|
+
*
|
|
150
|
+
* The widget is embeddable in SSR frameworks, where a bare `useLayoutEffect`
|
|
151
|
+
* logs a warning on every render. The effect it guards does nothing on the
|
|
152
|
+
* server anyway — there is no DOM to inject into.
|
|
153
|
+
*/
|
|
154
|
+
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
91
155
|
const LoadingIndicatorContext = createContext(null);
|
|
92
156
|
// Threads the `enableRetry` prop into AssistantMessage, which assistant-ui
|
|
93
157
|
// instantiates itself (no direct prop passing). Default off.
|
|
@@ -174,10 +238,10 @@ function AssistantMessage() {
|
|
|
174
238
|
const indicator = useContext(LoadingIndicatorContext);
|
|
175
239
|
const retryEnabled = useContext(RetryEnabledContext);
|
|
176
240
|
const copyEnabled = useContext(CopyEnabledContext);
|
|
177
|
-
return (_jsxs(MessagePrimitive.Root, { "data-curator-part": "message message-assistant", style: rowStartStyle, children: [_jsxs("div", { "data-curator-part": "bubble bubble-assistant", style: { ...bubbleBaseStyle, ...assistantBubbleStyle }, children: [_jsx(MessagePrimitive.If, { hasContent: false, children: indicator }), _jsx(MessagePrimitive.Parts, { components: { Text: AssistantTextPart } })] }), _jsx(Timestamp, { align: "start" }), (retryEnabled || copyEnabled) && (
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
241
|
+
return (_jsxs(MessagePrimitive.Root, { "data-curator-part": "message message-assistant", style: rowStartStyle, children: [_jsxs("div", { "data-curator-part": "bubble bubble-assistant", style: { ...bubbleBaseStyle, ...assistantBubbleStyle }, children: [_jsx(MessagePrimitive.If, { hasContent: false, children: indicator }), _jsx(MessagePrimitive.Parts, { components: { Text: AssistantTextPart } })] }), _jsxs("div", { "data-curator-part": "message-meta", style: messageMetaStyle, children: [_jsx(Timestamp, { align: "start" }), (retryEnabled || copyEnabled) && (
|
|
242
|
+
// `hideWhenRunning` still applies: actions on a half-written reply
|
|
243
|
+
// would copy a fragment.
|
|
244
|
+
_jsxs(ActionBarPrimitive.Root, { hideWhenRunning: true, "data-curator-part": "action-bar", style: actionBarStyle, children: [copyEnabled && (_jsxs(ActionBarPrimitive.Copy, { "aria-label": "Copy", "data-curator-part": "action-button", style: actionButtonStyle, children: [_jsx(MessagePrimitive.If, { copied: true, children: _jsx(CheckGlyph, {}) }), _jsx(MessagePrimitive.If, { copied: false, children: _jsx(CopyGlyph, {}) })] })), retryEnabled && (_jsx(ActionBarPrimitive.Reload, { "aria-label": "Retry", "data-curator-part": "action-button", style: actionButtonStyle, children: _jsx(RetryGlyph, {}) }))] }))] })] }));
|
|
181
245
|
}
|
|
182
246
|
/**
|
|
183
247
|
* Waiting state for a reply that has not started streaming.
|
|
@@ -364,6 +428,7 @@ const BASE_TOKENS = {
|
|
|
364
428
|
["--curator-space-4"]: "16px",
|
|
365
429
|
["--curator-radius-md"]: "10px",
|
|
366
430
|
["--curator-radius-sm"]: "8px",
|
|
431
|
+
["--curator-border-width"]: "1px",
|
|
367
432
|
};
|
|
368
433
|
/**
|
|
369
434
|
* Consumer-facing token names, mapped to the variables they set.
|
|
@@ -393,6 +458,7 @@ const TOKEN_VARS = {
|
|
|
393
458
|
radius: "--curator-radius",
|
|
394
459
|
radiusMd: "--curator-radius-md",
|
|
395
460
|
radiusSm: "--curator-radius-sm",
|
|
461
|
+
borderWidth: "--curator-border-width",
|
|
396
462
|
background: "--curator-bg",
|
|
397
463
|
surface: "--curator-surface",
|
|
398
464
|
text: "--curator-text",
|
|
@@ -488,8 +554,8 @@ const containerStyle = {
|
|
|
488
554
|
minHeight: 360,
|
|
489
555
|
background: "var(--curator-bg)",
|
|
490
556
|
color: "var(--curator-text)",
|
|
491
|
-
border: "1px solid var(--curator-border)",
|
|
492
|
-
borderRadius:
|
|
557
|
+
border: "var(--curator-border-width, 1px) solid var(--curator-border)",
|
|
558
|
+
borderRadius: RADIUS_LG,
|
|
493
559
|
overflow: "hidden",
|
|
494
560
|
fontFamily: "var(--curator-font-family)",
|
|
495
561
|
fontSize: FONT_BASE,
|
|
@@ -523,7 +589,7 @@ const headerActionStyle = {
|
|
|
523
589
|
alignItems: "center",
|
|
524
590
|
justifyContent: "center",
|
|
525
591
|
border: "none",
|
|
526
|
-
borderRadius:
|
|
592
|
+
borderRadius: RADIUS_SM,
|
|
527
593
|
background: "transparent",
|
|
528
594
|
color: "var(--curator-muted)",
|
|
529
595
|
cursor: "pointer",
|
|
@@ -603,19 +669,31 @@ const rowEndStyle = {
|
|
|
603
669
|
// refuses to shrink and the cap on the bubble inside it never binds.
|
|
604
670
|
minWidth: 0,
|
|
605
671
|
};
|
|
672
|
+
/**
|
|
673
|
+
* The strip under an assistant message: time on the left, actions beside it.
|
|
674
|
+
*
|
|
675
|
+
* `minHeight` is the whole point — it holds the row open at the height the
|
|
676
|
+
* action buttons need, from first render, so neither hovering nor the end of a
|
|
677
|
+
* stream changes the column's height.
|
|
678
|
+
*/
|
|
679
|
+
const messageMetaStyle = {
|
|
680
|
+
display: "flex",
|
|
681
|
+
alignItems: "center",
|
|
682
|
+
gap: 6,
|
|
683
|
+
minHeight: 22,
|
|
684
|
+
marginTop: 2,
|
|
685
|
+
};
|
|
606
686
|
const actionBarStyle = {
|
|
607
687
|
display: "flex",
|
|
608
688
|
alignItems: "center",
|
|
609
|
-
gap:
|
|
610
|
-
marginTop: 4,
|
|
611
|
-
paddingLeft: 2,
|
|
689
|
+
gap: 2,
|
|
612
690
|
};
|
|
613
691
|
const actionButtonStyle = {
|
|
614
692
|
display: "inline-flex",
|
|
615
693
|
alignItems: "center",
|
|
616
694
|
justifyContent: "center",
|
|
617
|
-
width:
|
|
618
|
-
height:
|
|
695
|
+
width: 22,
|
|
696
|
+
height: 22,
|
|
619
697
|
padding: 0,
|
|
620
698
|
border: "none",
|
|
621
699
|
borderRadius: RADIUS_SM,
|
|
@@ -737,7 +815,6 @@ const timestampStyle = {
|
|
|
737
815
|
fontSize: FONT_XS,
|
|
738
816
|
color: "var(--curator-muted)",
|
|
739
817
|
opacity: 0.7,
|
|
740
|
-
marginTop: 4,
|
|
741
818
|
padding: "0 2px",
|
|
742
819
|
userSelect: "none",
|
|
743
820
|
};
|
|
@@ -820,16 +897,29 @@ const sendButtonStyle = {
|
|
|
820
897
|
flexShrink: 0,
|
|
821
898
|
cursor: "pointer",
|
|
822
899
|
};
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
900
|
+
/**
|
|
901
|
+
* Stylesheet injection, scoped to the tree the widget is actually in.
|
|
902
|
+
*
|
|
903
|
+
* This used to run at module load and append to `document.head`, which assumes
|
|
904
|
+
* the widget owns the document. It does not when it is embedded in a shadow
|
|
905
|
+
* root: styles in the host document do not cross a shadow boundary, so every
|
|
906
|
+
* rule below was silently lost — the typing dots stopped animating, the prompt
|
|
907
|
+
* hover and action-bar reveal never fired, the composer focus ring vanished,
|
|
908
|
+
* and all markdown formatting went with them. Nothing errors; the widget just
|
|
909
|
+
* quietly renders unstyled in one embedding mode.
|
|
910
|
+
*
|
|
911
|
+
* Injecting into the host element's own `getRootNode()` fixes both cases at
|
|
912
|
+
* once: that resolves to the document normally and to the shadow root when
|
|
913
|
+
* embedded, so a consumer does not have to know which they are in or mirror the
|
|
914
|
+
* sheet themselves.
|
|
915
|
+
*
|
|
916
|
+
* Reported by a consumer who had worked around it downstream by copying the
|
|
917
|
+
* sheet into their shadow root — a workaround nobody should need.
|
|
918
|
+
*/
|
|
919
|
+
const STYLE_PREFIX = "curator-chat-styles";
|
|
920
|
+
/** Bump when the rules change; superseded sheets are removed on inject. */
|
|
921
|
+
const STYLE_ID = `${STYLE_PREFIX}-v6`;
|
|
922
|
+
const STYLE_TEXT = `
|
|
833
923
|
@keyframes curator-wave {
|
|
834
924
|
0%, 60%, 100% { transform: translateY(0); opacity: 0.35; }
|
|
835
925
|
30% { transform: translateY(-4px); opacity: 0.95; }
|
|
@@ -846,6 +936,22 @@ if (typeof document !== "undefined") {
|
|
|
846
936
|
transform: none;
|
|
847
937
|
}
|
|
848
938
|
}
|
|
939
|
+
/* Hidden by opacity rather than by unmounting, so the row keeps its height.
|
|
940
|
+
pointer-events follows visibility so an invisible button is not clickable,
|
|
941
|
+
and focus-within keeps it reachable by keyboard, where there is no hover. */
|
|
942
|
+
[data-curator-chat] [data-curator-part~="action-bar"] {
|
|
943
|
+
opacity: 0;
|
|
944
|
+
pointer-events: none;
|
|
945
|
+
transition: opacity 120ms ease;
|
|
946
|
+
}
|
|
947
|
+
[data-curator-chat] [data-curator-part~="message"]:hover [data-curator-part~="action-bar"],
|
|
948
|
+
[data-curator-chat] [data-curator-part~="action-bar"]:focus-within {
|
|
949
|
+
opacity: 1;
|
|
950
|
+
pointer-events: auto;
|
|
951
|
+
}
|
|
952
|
+
@media (prefers-reduced-motion: reduce) {
|
|
953
|
+
[data-curator-chat] [data-curator-part~="action-bar"] { transition: none; }
|
|
954
|
+
}
|
|
849
955
|
[data-curator-chat] [data-curator-part~="prompt"]:hover {
|
|
850
956
|
background-color: var(--curator-user-bubble);
|
|
851
957
|
border-color: var(--curator-muted);
|
|
@@ -945,7 +1051,37 @@ if (typeof document !== "undefined") {
|
|
|
945
1051
|
[data-curator-md] th, [data-curator-md] td { border: 1px solid currentColor; padding: 4px 8px; }
|
|
946
1052
|
[data-curator-md] th { font-weight: 600; }
|
|
947
1053
|
`;
|
|
948
|
-
|
|
1054
|
+
/**
|
|
1055
|
+
* Put the sheet in `host`'s root, once per root.
|
|
1056
|
+
*
|
|
1057
|
+
* Runs on mount rather than at import: the root is only knowable from a mounted
|
|
1058
|
+
* element, and a lazily-loaded route chunk can import this module long before —
|
|
1059
|
+
* or well after — the tree it will live in exists.
|
|
1060
|
+
*
|
|
1061
|
+
* Not removed on unmount. Two widgets can share a root, and reference-counting
|
|
1062
|
+
* a `<style>` element costs more than the element does; a shadow root that is
|
|
1063
|
+
* torn down takes its copy with it.
|
|
1064
|
+
*/
|
|
1065
|
+
function injectCuratorStyles(host) {
|
|
1066
|
+
if (!host || typeof document === "undefined")
|
|
1067
|
+
return;
|
|
1068
|
+
const root = host.getRootNode();
|
|
1069
|
+
// A Document takes the sheet in `head`; a ShadowRoot has no head and takes it
|
|
1070
|
+
// directly. Both accept an element created by the owning document.
|
|
1071
|
+
const container = root.head ?? root;
|
|
1072
|
+
if (!container || typeof container.querySelector !== "function")
|
|
1073
|
+
return;
|
|
1074
|
+
if (container.querySelector(`#${STYLE_ID}`))
|
|
1075
|
+
return;
|
|
1076
|
+
// Drop superseded versions in THIS root. Without it an upgraded page would
|
|
1077
|
+
// apply two generations of rules at once, with the older one winning wherever
|
|
1078
|
+
// it happened to be more specific.
|
|
1079
|
+
for (const stale of Array.from(container.querySelectorAll(`[id^="${STYLE_PREFIX}-"]`))) {
|
|
1080
|
+
stale.remove();
|
|
949
1081
|
}
|
|
1082
|
+
const el = document.createElement("style");
|
|
1083
|
+
el.id = STYLE_ID;
|
|
1084
|
+
el.textContent = STYLE_TEXT;
|
|
1085
|
+
container.appendChild(el);
|
|
950
1086
|
}
|
|
951
1087
|
//# sourceMappingURL=CuratorChat.js.map
|