@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.
@@ -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";
@@ -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;AAGpD,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"}
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");
@@ -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;AAG9B;yDACyD;AACzD,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,cAAc,EAAE,CAAA;IAC9B;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAA;CAChB,GACD;IACE,IAAI,EAAE,WAAW,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd,GACD;IACE,IAAI,EAAE,OAAO,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAEL,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,kCAAkC;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,sEAAsE;IACtE,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAC/C,iEAAiE;IACjE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,KAAK,IAAI,CAAA;CAChD;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,cAAc,EAAE,CAAA;IACxB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,QAAQ,EAAE,UAAU,EAAE,CAAA;IACtB,2DAA2D;IAC3D,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAA;IAChB,uEAAuE;IACvE,KAAK,EAAE,YAAY,GAAG,KAAK,GAAG,IAAI,CAAA;IAClC,gEAAgE;IAChE,IAAI,EAAE,IAAI,CAAA;IACV,iEAAiE;IACjE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B;sCACkC;IAClC,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB;;;;OAIG;IACH,oBAAoB,EAAE,oBAAoB,GAAG,IAAI,CAAA;IACjD;;;;;OAKG;IACH,OAAO,EAAE,CAAC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD;;;;OAIG;IACH,eAAe,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CACzD;AAQD,wBAAgB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,oBAAoB,CAyJhF"}
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":"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"}
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
- /** Reattach to an existing conversation id instead of starting fresh. */
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":"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"}
1
+ {"version":3,"file":"CuratorChat.d.ts","sourceRoot":"","sources":["../../src/CuratorChat.tsx"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
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: [_jsxs(ThreadPrimitive.Empty, { children: [welcomeMessage ? _jsx(Welcome, { text: welcomeMessage }) : null, prompts && prompts.length > 0 && _jsx(Prompts, { prompts: prompts })] }), _jsx(ThreadPrimitive.Messages, { components: {
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
- // `autohide="not-last"` shows the bar only on the trailing assistant
179
- // message; `hideWhenRunning` keeps it away while a reply streams.
180
- _jsxs(ActionBarPrimitive.Root, { autohide: "not-last", 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, {}) }))] }))] }));
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: "var(--curator-radius)",
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: 8,
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: 4,
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: 26,
618
- height: 26,
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
- // One-shot stylesheet injection — scoped markdown + focus rules.
824
- // Idempotent. Skipped in SSR. STYLE_ID is bumped when the rules change
825
- // so existing pages re-inject the new sheet on next mount instead of
826
- // reusing the stale element.
827
- if (typeof document !== "undefined") {
828
- const STYLE_ID = "curator-chat-styles-v5";
829
- if (!document.getElementById(STYLE_ID)) {
830
- const el = document.createElement("style");
831
- el.id = STYLE_ID;
832
- el.textContent = `
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
- document.head.appendChild(el);
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