@noodleseed/assistant 1.10.0 → 1.12.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 CHANGED
@@ -182,7 +182,12 @@ export async function POST(request: Request) {
182
182
  clientId: process.env.NOODLE_ASSISTANT_CLIENT_ID!,
183
183
  clientSecret: process.env.NOODLE_ASSISTANT_CLIENT_SECRET!,
184
184
  origin: process.env.PUBLIC_APP_ORIGIN!,
185
- user: { id: user.id, email: user.email, roles: user.roles },
185
+ user: {
186
+ id: user.id,
187
+ email: user.email,
188
+ roles: user.roles,
189
+ scopes: user.scopes,
190
+ },
186
191
  context,
187
192
  preferences: { locale: user.locale, timeZone: user.timeZone },
188
193
  });
@@ -247,6 +252,26 @@ interaction streams a continuation. `principalKey` is browser-local and never se
247
252
  whenever the authenticated user or tenant changes so the hook aborts and clears the previous session and
248
253
  transcript.
249
254
 
255
+ If the product deliberately sends a first turn on mount, make the effect cleanup-aware. React Strict Mode
256
+ discards the provisional effect, so a persistent "already sent" ref can suppress the stable remount:
257
+
258
+ ```tsx
259
+ import { useEffect } from "react";
260
+
261
+ useEffect(() => {
262
+ let active = true;
263
+ queueMicrotask(() => {
264
+ if (active) settle(client.sendMessage(initialMessage));
265
+ });
266
+ return () => {
267
+ active = false;
268
+ };
269
+ }, [client, initialMessage]);
270
+ ```
271
+
272
+ `settle` must await or catch the command promise as in the complete example; the same structured failure
273
+ also appears in the hook's `error` state.
274
+
250
275
  When the customer-owned transcript should render the linked MCP App itself, pass the typed `data-view`
251
276
  payload and the same client to the supported host component:
252
277
 
@@ -320,6 +345,24 @@ Use the lower-level `subscribe(...)` event stream only for transport and session
320
345
  do not belong in the transcript. The package uses the headless `ai` runtime only; React remains an optional
321
346
  peer isolated to the `/react` and `/react/client` entries.
322
347
 
348
+ For a custom progress surface, raw `tool_started` carries the direct invocation's call `id` and technical
349
+ `tool` name before execution. Map known tools through a finite application-owned label table and use a
350
+ neutral fallback such as "Working"; never turn an internal identifier into customer copy mechanically.
351
+ Keep one reserved region with `role="status"` and `aria-live="polite"` from submitted/thinking through tool
352
+ activity and the linked-view skeleton. `view_available` makes that view ready; a raw `error` event or chat
353
+ `error` state replaces the skeleton with `role="alert"`. Keep the skeleton's dimensions stable, mark its
354
+ decorative shapes `aria-hidden="true"`, and disable shimmer/transition animation under
355
+ `@media (prefers-reduced-motion: reduce)`.
356
+
357
+ The transport identity of a view is exactly `view.id + view.resourceUri`; different call IDs are distinct
358
+ invocations and must not be collapsed automatically. If the product intentionally owns one current panel
359
+ for a known resource, define an explicit application-owned slot map and replace only that slot:
360
+
361
+ ```ts
362
+ const viewSlots = new Map([["ui://workspace/current", "current-workspace"]]);
363
+ const renderKey = viewSlots.get(view.resourceUri) ?? `${view.id}:${view.resourceUri}`;
364
+ ```
365
+
323
366
  `clientContext` contains untrusted locale/timezone presentation hints and is evaluated for every turn.
324
367
  The client resolves a turn or interaction only after exactly one valid terminal `done` event followed by
325
368
  stream EOF. A truncated or malformed stream, duplicate `done`, or any frame after `done` is
@@ -8360,6 +8360,11 @@ function toAssistantClientEvent(event) {
8360
8360
  return event;
8361
8361
  }
8362
8362
  break;
8363
+ case "tool_started":
8364
+ if (hasString(value, "id") && hasString(value, "tool") && hasOptionalTurnId(value)) {
8365
+ return event;
8366
+ }
8367
+ break;
8363
8368
  case "tool_proposed":
8364
8369
  if (hasString(value, "id") && hasString(value, "tool") && hasOptionalString(value.title) && hasOptionalString(value.description) && hasOptionalJson(value.arguments) && (value.reviewSchema === void 0 || isRecord2(value.reviewSchema)) && hasOptionalString(value.expiresAt) && (value.requiresConfirmation === void 0 || value.requiresConfirmation === true) && hasOptionalTurnId(value)) {
8365
8370
  return event;
@@ -9086,4 +9091,4 @@ export {
9086
9091
  AssistantClientError,
9087
9092
  createAssistantClient
9088
9093
  };
9089
- //# sourceMappingURL=chunk-RYQBXTLR.js.map
9094
+ //# sourceMappingURL=chunk-KRB2SXFD.js.map