@noodleseed/assistant 1.7.0 → 1.8.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 +73 -20
- package/dist/{chunk-UXPKSCID.js → chunk-3YYTUJPJ.js} +2 -2
- package/dist/{chunk-NSBPE2FW.js → chunk-5FUTL2UF.js} +6 -1
- package/dist/chunk-BLMJHF7U.js +544 -0
- package/dist/chunk-BLMJHF7U.js.map +1 -0
- package/dist/{chunk-35A7REQX.js → chunk-JMBUJSFP.js} +183 -79
- package/dist/chunk-JMBUJSFP.js.map +1 -0
- package/dist/chunk-RYQBXTLR.js +9089 -0
- package/dist/chunk-RYQBXTLR.js.map +1 -0
- package/dist/{client-D2Y9UFh3.d.cts → client-BxoNZkWp.d.cts} +43 -1
- package/dist/{client-DBuETUVD.d.ts → client-ERQCAH_0.d.ts} +43 -1
- package/dist/client.cjs +22976 -92
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +2 -1
- package/dist/client.d.ts +2 -1
- package/dist/client.js +3 -2
- package/dist/index.cjs +10683 -2201
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +4 -4
- package/dist/react/client.cjs +23688 -0
- package/dist/react/client.cjs.map +1 -0
- package/dist/react/client.d.cts +24 -0
- package/dist/react/client.d.ts +24 -0
- package/dist/react/client.js +76 -0
- package/dist/react/client.js.map +1 -0
- package/dist/react.cjs +10683 -2200
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -1
- package/dist/react.d.ts +2 -1
- package/dist/react.js +7 -6
- package/dist/react.js.map +1 -1
- package/dist/server.js +1 -1
- package/dist/token-Y6KCR3JT.js +70 -0
- package/dist/token-Y6KCR3JT.js.map +1 -0
- package/dist/token-util-XFYMRPAB.js +6 -0
- package/dist/{v4-2UXPDMWJ.js → v4-KBRL3YLO.js} +3 -3
- package/dist/v4-KBRL3YLO.js.map +1 -0
- package/package.json +14 -3
- package/dist/chunk-35A7REQX.js.map +0 -1
- package/dist/chunk-7E5HINN4.js +0 -713
- package/dist/chunk-7E5HINN4.js.map +0 -1
- /package/dist/{chunk-UXPKSCID.js.map → chunk-3YYTUJPJ.js.map} +0 -0
- /package/dist/{chunk-NSBPE2FW.js.map → chunk-5FUTL2UF.js.map} +0 -0
- /package/dist/{v4-2UXPDMWJ.js.map → token-util-XFYMRPAB.js.map} +0 -0
package/README.md
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Customer-branded embedded assistant surfaces for Noodle Seed deployments.
|
|
4
4
|
|
|
5
|
-
The package exports the canonical `<noodle-assistant>` Web Component, a React wrapper from
|
|
6
|
-
`@noodleseed/assistant/react`, a
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
The package exports the canonical `<noodle-assistant>` Web Component, a managed React wrapper from
|
|
6
|
+
`@noodleseed/assistant/react`, a renderer-free React hook from
|
|
7
|
+
`@noodleseed/assistant/react/client`, a DOM-free client from `@noodleseed/assistant/client`, and the
|
|
8
|
+
backend-only `createAssistantSession` helper from `@noodleseed/assistant/server`. Light, dark, and automatic
|
|
9
|
+
themes work without configuration; the component inherits the deployed MCP server's brand kit while slots,
|
|
10
|
+
methods, events, and semantic CSS variables let a SaaS developer integrate it without depending on internal
|
|
11
|
+
DOM selectors.
|
|
11
12
|
|
|
12
13
|
Never pass an embed client secret, model key, MCP token, or raw application session into the browser
|
|
13
14
|
component. Exchange the already-authenticated user from the customer backend and return only the short-lived
|
|
@@ -142,10 +143,10 @@ markup-looking text stays text. `presentation.panel.radius` is a bounded panel-s
|
|
|
142
143
|
not a second color or identity source. An HTTPS or packaged SVG referenced by `branding.logo`, `branding.mark`, or
|
|
143
144
|
`branding.avatar` is a bounded asset, not inline renderer markup.
|
|
144
145
|
|
|
145
|
-
If `presentation` is omitted, the
|
|
146
|
-
border/motion, medium brand-mark launcher without status or effect,
|
|
147
|
-
|
|
148
|
-
Partial objects merge with those defaults.
|
|
146
|
+
If `presentation` is omitted, the rounded Halo-inspired baseline remains: a frosted glass panel with a 24px
|
|
147
|
+
radius, soft elevation, subtle border/motion, medium brand-mark launcher without status or effect,
|
|
148
|
+
undecorated header, pill composer and action controls, and rounded user bubbles with plain assistant messages
|
|
149
|
+
at comfortable width. Partial objects merge with those defaults.
|
|
149
150
|
|
|
150
151
|
### Configure and deploy
|
|
151
152
|
|
|
@@ -210,8 +211,44 @@ import { NoodleAssistant } from "@noodleseed/assistant/react";
|
|
|
210
211
|
<NoodleAssistant sessionEndpoint="/api/assistant/session" theme="auto" />;
|
|
211
212
|
```
|
|
212
213
|
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
Or keep the Noodle backend and own every rendered element in React:
|
|
215
|
+
|
|
216
|
+
```tsx
|
|
217
|
+
"use client";
|
|
218
|
+
|
|
219
|
+
import { useNoodleAssistant } from "@noodleseed/assistant/react/client";
|
|
220
|
+
import { YourChatUI } from "./your-chat-ui";
|
|
221
|
+
|
|
222
|
+
export function CustomAssistant({ principalKey }: { principalKey: string }) {
|
|
223
|
+
const { client, messages, status, error } = useNoodleAssistant({
|
|
224
|
+
sessionEndpoint: "/api/assistant/session",
|
|
225
|
+
principalKey,
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
return (
|
|
229
|
+
<YourChatUI
|
|
230
|
+
messages={messages}
|
|
231
|
+
status={status}
|
|
232
|
+
error={error}
|
|
233
|
+
onSend={(text) => client.sendMessage(text)}
|
|
234
|
+
onStop={() => client.abort()}
|
|
235
|
+
onRespond={(id, response) => client.respond(id, response)}
|
|
236
|
+
/>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
`useNoodleAssistant` owns client lifetime and React subscription only. It renders no Noodle markup,
|
|
242
|
+
registers no custom element, and returns `{ client, messages, status, error }`. `client` remains the one
|
|
243
|
+
command surface for messages, interactions, context, Apps requests, session resets, and aborts. A
|
|
244
|
+
customer-owned renderer must present every interaction it supports, await or catch command promises, and
|
|
245
|
+
preserve the typed part semantics; it must not invent user messages when an accepted, declined, or cancelled
|
|
246
|
+
interaction streams a continuation. `principalKey` is browser-local and never sent to Noodle. Change it
|
|
247
|
+
whenever the authenticated user or tenant changes so the hook aborts and clears the previous session and
|
|
248
|
+
transcript.
|
|
249
|
+
|
|
250
|
+
Outside React, subscribe to the DOM-free AI SDK `UIMessage` state without registering a custom element or
|
|
251
|
+
touching browser storage:
|
|
215
252
|
|
|
216
253
|
```ts
|
|
217
254
|
import { createAssistantClient } from "@noodleseed/assistant/client";
|
|
@@ -229,19 +266,34 @@ assistant.updateModelContext({
|
|
|
229
266
|
structuredContent: { widget: { name: "time-off", lifecycle: "mounted" } },
|
|
230
267
|
});
|
|
231
268
|
|
|
232
|
-
const unsubscribe = assistant.
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
269
|
+
const unsubscribe = assistant.subscribeChat((state) => {
|
|
270
|
+
renderUIMessageState(state);
|
|
271
|
+
for (const message of state.messages) {
|
|
272
|
+
for (const part of message.parts) {
|
|
273
|
+
if (part.type === "data-confirmation" && part.data.status === "pending") {
|
|
274
|
+
renderConfirmation(part.data, (response) =>
|
|
275
|
+
assistant.respond(part.data.id, response),
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
if (part.type === "data-view") {
|
|
279
|
+
renderRegisteredView(part.data.resourceUri, part.data.result);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
236
282
|
}
|
|
237
283
|
});
|
|
238
284
|
await assistant.sendMessage("Book next Thursday and Friday off");
|
|
239
|
-
await assistant.respond("interaction_123", { action: "accept" });
|
|
240
|
-
// Resolve one interaction once; alternatives are { action: 'decline' } or { action: 'cancel' }.
|
|
241
285
|
|
|
242
286
|
unsubscribe();
|
|
243
287
|
```
|
|
244
288
|
|
|
289
|
+
`subscribeChat` immediately emits a detached `{ messages, status, error? }` snapshot and then emits as the
|
|
290
|
+
AI SDK `UIMessage.parts` change. Assistant text uses `text`; confirmations, structured input requests, tool
|
|
291
|
+
results, and linked MCP Apps use `data-confirmation`, `data-input-request`, `data-tool-result`, and
|
|
292
|
+
`data-view`. Interaction data moves through `pending`, `submitting`, `accepted`, `declined`, or `cancelled`.
|
|
293
|
+
Use the lower-level `subscribe(...)` event stream only for transport and session lifecycle observations that
|
|
294
|
+
do not belong in the transcript. The package uses the headless `ai` runtime only; React remains an optional
|
|
295
|
+
peer isolated to the `/react` and `/react/client` entries.
|
|
296
|
+
|
|
245
297
|
`clientContext` contains untrusted locale/timezone presentation hints and is evaluated for every turn.
|
|
246
298
|
The client resolves a turn or interaction only after exactly one valid terminal `done` event followed by
|
|
247
299
|
stream EOF. A truncated or malformed stream, duplicate `done`, or any frame after `done` is
|
|
@@ -281,8 +333,9 @@ flow collects all elicited input before its first connector operation.
|
|
|
281
333
|
A completed widget-linked tool emits typed `view_available` data with its call/interaction id, tool,
|
|
282
334
|
`ui://` resource identity, optional title, and bounded/redacted public result. This is an availability
|
|
283
335
|
signal, not proof of rendering. Map the identity to a component already trusted by your application; never
|
|
284
|
-
fetch the `ui://` URI
|
|
285
|
-
|
|
336
|
+
fetch the `ui://` URI, inject `part.data.html`, or assign it to `srcdoc`. The standard element alone mounts
|
|
337
|
+
the service-supplied document through its double-iframe MCP Apps host, and it also forwards the same detail
|
|
338
|
+
as a DOM event:
|
|
286
339
|
|
|
287
340
|
```ts
|
|
288
341
|
element.addEventListener("assistant-view-available", (event) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__export
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-5FUTL2UF.js";
|
|
4
4
|
|
|
5
5
|
// ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
|
|
6
6
|
var external_exports = {};
|
|
@@ -14764,4 +14764,4 @@ export {
|
|
|
14764
14764
|
external_exports,
|
|
14765
14765
|
v4_default
|
|
14766
14766
|
};
|
|
14767
|
-
//# sourceMappingURL=chunk-
|
|
14767
|
+
//# sourceMappingURL=chunk-3YYTUJPJ.js.map
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
3
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
4
|
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
5
|
}) : x)(function(x) {
|
|
5
6
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
7
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
8
|
});
|
|
9
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
10
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
11
|
+
};
|
|
8
12
|
var __export = (target, all) => {
|
|
9
13
|
for (var name in all)
|
|
10
14
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -12,6 +16,7 @@ var __export = (target, all) => {
|
|
|
12
16
|
|
|
13
17
|
export {
|
|
14
18
|
__require,
|
|
19
|
+
__commonJS,
|
|
15
20
|
__export
|
|
16
21
|
};
|
|
17
|
-
//# sourceMappingURL=chunk-
|
|
22
|
+
//# sourceMappingURL=chunk-5FUTL2UF.js.map
|