@helpai/elements 0.45.0 → 0.46.1

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/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-oSJ2nv2G.js';
1
+ export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-C_jlXJAe.js';
2
2
  import 'zod';
3
3
 
4
4
  /**
package/index.mjs CHANGED
@@ -30,7 +30,7 @@ var BRAND = {
30
30
  };
31
31
 
32
32
  // src/core/version.ts
33
- var ELEMENTS_VERSION = true ? "0.45.0" : "0.0.0-dev";
33
+ var ELEMENTS_VERSION = true ? "0.46.1" : "0.0.0-dev";
34
34
  var ELEMENTS_VERSION_PARAM = "_ev";
35
35
 
36
36
  // src/i18n/strings.ts
@@ -1664,13 +1664,11 @@ function buildSendMessageRequest(params) {
1664
1664
  conversationId: params.conversationId,
1665
1665
  trigger: params.trigger ?? "submit-message"
1666
1666
  };
1667
+ if (params.messageId) body.messageId = params.messageId;
1667
1668
  if (params.visitorId) body.visitorId = params.visitorId;
1668
1669
  if (params.userPrefs) body.userPrefs = params.userPrefs;
1669
- const data = {};
1670
1670
  const tools = params.tools?.map(normalizeToolRef).filter((t) => t !== null);
1671
- if (tools?.length) data.tools = tools;
1672
- if (params.responseMode) data.responseMode = params.responseMode;
1673
- if (Object.keys(data).length > 0) body.data = data;
1671
+ if (tools?.length) body.data = { tools };
1674
1672
  return body;
1675
1673
  }
1676
1674
  function isResolvedToolPart(p35) {
@@ -1683,6 +1681,12 @@ function normalizeToolRef(ref) {
1683
1681
  function messageToWireParts(m) {
1684
1682
  const out = [];
1685
1683
  for (const p35 of m.parts) {
1684
+ if (p35.kind === "step-start") {
1685
+ out.push({ type: "step-start" });
1686
+ }
1687
+ if (p35.kind === "reasoning" && p35.text) {
1688
+ out.push({ type: "reasoning", text: p35.text, state: p35.done ? "done" : "streaming" });
1689
+ }
1686
1690
  if (p35.kind === "text" && p35.text) {
1687
1691
  out.push({ text: p35.text, type: "text" });
1688
1692
  }
@@ -2081,9 +2085,9 @@ var AgentTransport = class {
2081
2085
  log6.debug("message \u2192", {
2082
2086
  conversationId: body.conversationId,
2083
2087
  visitorId: body.visitorId,
2088
+ messageId: body.messageId,
2084
2089
  messageCount: body.messages.length,
2085
2090
  trigger: body.trigger,
2086
- responseMode: body.data?.responseMode,
2087
2091
  tools: body.data?.tools?.map((t) => t.code)
2088
2092
  });
2089
2093
  const ctrl = new AbortController();
@@ -2392,6 +2396,17 @@ function fromWireMessage(w) {
2392
2396
  if (part.type === "text") {
2393
2397
  return { kind: "text", id: `${w.id}-t${i}`, textSig: signal(part.text), doneSig: signal(true) };
2394
2398
  }
2399
+ if (part.type === "reasoning") {
2400
+ return {
2401
+ kind: "reasoning",
2402
+ id: `${w.id}-r${i}`,
2403
+ textSig: signal(part.text),
2404
+ doneSig: signal(part.state !== "streaming")
2405
+ };
2406
+ }
2407
+ if (part.type === "step-start") {
2408
+ return { kind: "step-start", id: `${w.id}-ss${i}` };
2409
+ }
2395
2410
  if (part.type === "file") {
2396
2411
  return { kind: "file", url: part.url, mediaType: part.mediaType };
2397
2412
  }
@@ -2510,9 +2525,11 @@ var StreamReducer = class {
2510
2525
  if (!m) return;
2511
2526
  switch (chunk.type) {
2512
2527
  case "start":
2513
- case "start-step":
2514
2528
  case "finish-step":
2515
2529
  return;
2530
+ case "start-step":
2531
+ appendPart(m, { kind: "step-start", id: `ss${m.partsSig.value.length}` });
2532
+ return;
2516
2533
  case "finish":
2517
2534
  log7.debug("finish", { reason: chunk.finishReason, canContinue: chunk.canContinue });
2518
2535
  m.status = "complete";
@@ -2665,18 +2682,6 @@ function applyTool(m, chunk) {
2665
2682
  }
2666
2683
  }
2667
2684
 
2668
- // src/stream/constants.ts
2669
- function isAskUserInputTool(toolName) {
2670
- if (!toolName) return false;
2671
- const name = toolName.startsWith("tool:") ? toolName.slice(5) : toolName;
2672
- return name === "ask-user-input" || name === "ask_user_input" || name === "request-user-input" || name === "request_user_input";
2673
- }
2674
- var TRIGGER = {
2675
- submitMessage: "submit-message",
2676
- toolResult: "tool-result",
2677
- toolApproval: "tool-approval"
2678
- };
2679
-
2680
2685
  // src/core/feedback/index.ts
2681
2686
  import { signal as signal3 } from "@preact/signals";
2682
2687
 
@@ -4783,6 +4788,13 @@ function FormDoneMarker({
4783
4788
  // src/ui/message-bubble.tsx
4784
4789
  import { useComputed as useComputed5 } from "@preact/signals";
4785
4790
 
4791
+ // src/stream/constants.ts
4792
+ function isAskUserInputTool(toolName) {
4793
+ if (!toolName) return false;
4794
+ const name = toolName.startsWith("tool:") ? toolName.slice(5) : toolName;
4795
+ return name === "ask-user-input" || name === "ask_user_input" || name === "request-user-input" || name === "request_user_input";
4796
+ }
4797
+
4786
4798
  // src/ui/markdown.tsx
4787
4799
  import { useLayoutEffect, useMemo, useRef as useRef4 } from "preact/hooks";
4788
4800
  import { effect, signal as signal4 } from "@preact/signals";
@@ -5211,6 +5223,8 @@ function PartView({
5211
5223
  tool
5212
5224
  }) {
5213
5225
  switch (part.kind) {
5226
+ case "step-start":
5227
+ return null;
5214
5228
  case "text":
5215
5229
  return /* @__PURE__ */ jsx17(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
5216
5230
  case "reasoning":
@@ -5276,6 +5290,7 @@ function partKey(part) {
5276
5290
  switch (part.kind) {
5277
5291
  case "text":
5278
5292
  case "reasoning":
5293
+ case "step-start":
5279
5294
  return `${part.kind}:${part.id}`;
5280
5295
  case "tool":
5281
5296
  return `tool:${part.toolCallId}`;
@@ -6936,6 +6951,13 @@ var p34 = BRAND.cssPrefix;
6936
6951
  function makeLocalizedWelcome(w, strings) {
6937
6952
  return makeInstantWelcomeMessage({ ...w, text: localizeText(strings, w.text) });
6938
6953
  }
6954
+ function allToolPartsSettled(msg) {
6955
+ const tools = msg.partsSig.value.filter((p35) => p35.kind === "tool");
6956
+ return tools.length > 0 && tools.every((p35) => {
6957
+ const s = p35.stateSig.value;
6958
+ return s === "output-available" || s === "output-error" || s === "output-denied" || s === "approval-responded";
6959
+ });
6960
+ }
6939
6961
  function App({ options, hostElement, bus }) {
6940
6962
  const [persistence] = useState13(
6941
6963
  () => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
@@ -7402,19 +7424,20 @@ function App({ options, hostElement, bus }) {
7402
7424
  return () => document.removeEventListener("keydown", onKey);
7403
7425
  }, [isOpen, options.mode]);
7404
7426
  const streamAssistant = useCallback6(
7405
- async (assistantMsg, trigger) => {
7427
+ async (assistantMsg, { continueExisting }) => {
7406
7428
  const activeConversationId = conversationIdSig.value ?? uuid7();
7407
7429
  if (!conversationIdSig.value) {
7408
7430
  conversationIdSig.value = activeConversationId;
7409
7431
  persistence.saveConversationId(activeConversationId);
7410
7432
  }
7433
+ const thread = continueExisting ? messagesSig.value : messagesSig.value.slice(0, -1);
7411
7434
  const body = buildSendMessageRequest({
7412
- messages: messagesSig.value.slice(0, -1).map(fromReactive),
7435
+ messages: thread.map(fromReactive),
7413
7436
  conversationId: activeConversationId,
7437
+ // The assistant message being generated / resumed.
7438
+ messageId: assistantMsg.id,
7414
7439
  // textModel + imageModel are backend-only — selected per deployment.
7415
7440
  tools: options.features.tools,
7416
- responseMode: options.responseMode,
7417
- trigger,
7418
7441
  // Identity + preferences ride on every message — server may need
7419
7442
  // them to route, persist, or reconcile in-flight.
7420
7443
  visitorId,
@@ -7448,23 +7471,23 @@ function App({ options, hostElement, bus }) {
7448
7471
  },
7449
7472
  [transport, reducer, messagesSig, conversationIdSig, options, bus, feedback, persistence, visitorId]
7450
7473
  );
7451
- const resolveTool = useCallback6(
7452
- (toolCallId, trigger, mutate) => {
7474
+ const decideTool = useCallback6(
7475
+ (toolCallId, mutate) => {
7453
7476
  if (streaming) return;
7454
7477
  const last = messagesSig.value.at(-1);
7455
7478
  const part = last?.partsSig.value.find(
7456
7479
  (pt) => pt.kind === "tool" && pt.toolCallId === toolCallId
7457
7480
  );
7458
- if (!part) {
7459
- log17.warn("resolveTool: tool part not found", { toolCallId });
7481
+ if (!last || !part) {
7482
+ log17.warn("decideTool: tool part not found", { toolCallId });
7460
7483
  return;
7461
7484
  }
7462
7485
  mutate(part);
7463
- if (last) last.partsSig.value = [...last.partsSig.value];
7464
- const assistantMsg = makeAssistantMessage();
7465
- messagesSig.value = [...messagesSig.value, assistantMsg];
7466
- reducer.attach(assistantMsg);
7467
- void streamAssistant(assistantMsg, trigger);
7486
+ last.partsSig.value = [...last.partsSig.value];
7487
+ if (!allToolPartsSettled(last)) return;
7488
+ last.status = "streaming";
7489
+ reducer.attach(last);
7490
+ void streamAssistant(last, { continueExisting: true });
7468
7491
  },
7469
7492
  [streaming, messagesSig, reducer, streamAssistant]
7470
7493
  );
@@ -7472,24 +7495,24 @@ function App({ options, hostElement, bus }) {
7472
7495
  (toolCallId, output) => {
7473
7496
  log17.info("toolResult", { toolCallId });
7474
7497
  bus.emit("toolResult", { toolCallId });
7475
- resolveTool(toolCallId, TRIGGER.toolResult, (part) => {
7498
+ decideTool(toolCallId, (part) => {
7476
7499
  part.outputSig.value = output;
7477
7500
  part.stateSig.value = "output-available";
7478
7501
  });
7479
7502
  },
7480
- [bus, resolveTool]
7503
+ [bus, decideTool]
7481
7504
  );
7482
7505
  const handleToolDecision = useCallback6(
7483
7506
  (toolCallId, approved, reason) => {
7484
7507
  log17.info("toolDecision", { toolCallId, approved });
7485
7508
  bus.emit("toolDecision", { toolCallId, approved });
7486
- resolveTool(toolCallId, TRIGGER.toolApproval, (part) => {
7509
+ decideTool(toolCallId, (part) => {
7487
7510
  const id = part.approvalSig.value?.id ?? toolCallId;
7488
7511
  part.approvalSig.value = { id, approved, reason };
7489
7512
  part.stateSig.value = "approval-responded";
7490
7513
  });
7491
7514
  },
7492
- [bus, resolveTool]
7515
+ [bus, decideTool]
7493
7516
  );
7494
7517
  const toolInteraction = useMemo3(
7495
7518
  () => ({ humanInLoop: options.features.humanInLoop, onResult: handleToolResult, onDecision: handleToolDecision }),
@@ -7569,7 +7592,7 @@ function App({ options, hostElement, bus }) {
7569
7592
  messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
7570
7593
  reducer.attach(assistantMsg);
7571
7594
  emitMessage(bus, options, "user", text);
7572
- await streamAssistant(assistantMsg, TRIGGER.submitMessage);
7595
+ await streamAssistant(assistantMsg, { continueExisting: false });
7573
7596
  forms.fire("after-messages");
7574
7597
  },
7575
7598
  [streaming, transport, bus, options, suggestions.length, messagesSig, reducer, streamAssistant, forms]
package/package.json CHANGED
@@ -80,5 +80,5 @@
80
80
  ],
81
81
  "type": "module",
82
82
  "types": "./index.d.ts",
83
- "version": "0.45.0"
83
+ "version": "0.46.1"
84
84
  }
package/schema.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-oSJ2nv2G.js';
1
+ export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-C_jlXJAe.js';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
@@ -56,9 +56,9 @@ declare const presentationSchema: z.ZodObject<{
56
56
  inset: z.ZodOptional<z.ZodString>;
57
57
  initialSize: z.ZodDefault<z.ZodEnum<{
58
58
  fullscreen: "fullscreen";
59
- normal: "normal";
60
59
  expanded: "expanded";
61
60
  auto: "auto";
61
+ normal: "normal";
62
62
  }>>;
63
63
  autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
64
64
  }, z.core.$loose>>;
@@ -240,9 +240,9 @@ type LauncherOptions = z.infer<typeof launcherOptionsSchema>;
240
240
 
241
241
  declare const initialSizeSchema: z.ZodEnum<{
242
242
  fullscreen: "fullscreen";
243
- normal: "normal";
244
243
  expanded: "expanded";
245
244
  auto: "auto";
245
+ normal: "normal";
246
246
  }>;
247
247
  declare const resizeOptionsSchema: z.ZodObject<{
248
248
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -269,9 +269,9 @@ declare const sizeOptionsSchema: z.ZodObject<{
269
269
  inset: z.ZodOptional<z.ZodString>;
270
270
  initialSize: z.ZodDefault<z.ZodEnum<{
271
271
  fullscreen: "fullscreen";
272
- normal: "normal";
273
272
  expanded: "expanded";
274
273
  auto: "auto";
274
+ normal: "normal";
275
275
  }>>;
276
276
  autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
277
277
  }, z.core.$loose>;
@@ -323,40 +323,40 @@ type FeatureFlags = z.infer<typeof featureFlagsSchema>;
323
323
  */
324
324
 
325
325
  declare const actionNameSchema: z.ZodEnum<{
326
+ close: "close";
326
327
  expand: "expand";
327
328
  fullscreen: "fullscreen";
328
- close: "close";
329
- language: "language";
329
+ clear: "clear";
330
330
  theme: "theme";
331
+ language: "language";
331
332
  textSize: "textSize";
332
333
  history: "history";
333
- clear: "clear";
334
334
  sound: "sound";
335
335
  }>;
336
336
  type ActionName = z.infer<typeof actionNameSchema>;
337
337
  declare const headerActionsSchema: z.ZodArray<z.ZodEnum<{
338
+ close: "close";
338
339
  expand: "expand";
339
340
  fullscreen: "fullscreen";
340
- close: "close";
341
- language: "language";
341
+ clear: "clear";
342
342
  theme: "theme";
343
+ language: "language";
343
344
  textSize: "textSize";
344
345
  history: "history";
345
- clear: "clear";
346
346
  sound: "sound";
347
347
  }>>;
348
348
  type HeaderActions = z.infer<typeof headerActionsSchema>;
349
349
  /** Section wrapper — `actions` list wrapped under `header` in the dashboard form. */
350
350
  declare const headerSchema: z.ZodObject<{
351
351
  actions: z.ZodOptional<z.ZodArray<z.ZodEnum<{
352
+ close: "close";
352
353
  expand: "expand";
353
354
  fullscreen: "fullscreen";
354
- close: "close";
355
- language: "language";
355
+ clear: "clear";
356
356
  theme: "theme";
357
+ language: "language";
357
358
  textSize: "textSize";
358
359
  history: "history";
359
- clear: "clear";
360
360
  sound: "sound";
361
361
  }>>>;
362
362
  }, z.core.$loose>;
@@ -372,33 +372,33 @@ type HeaderOptions = z.infer<typeof headerSchema>;
372
372
  */
373
373
 
374
374
  declare const feedbackEventSchema: z.ZodEnum<{
375
+ voiceStart: "voiceStart";
376
+ voiceStop: "voiceStop";
375
377
  error: "error";
376
378
  messageReceived: "messageReceived";
377
379
  messageSent: "messageSent";
378
- voiceStart: "voiceStart";
379
- voiceStop: "voiceStop";
380
380
  }>;
381
381
  type FeedbackEvent = z.infer<typeof feedbackEventSchema>;
382
382
  declare const soundOptionsSchema: z.ZodObject<{
383
383
  enabled: z.ZodDefault<z.ZodBoolean>;
384
384
  volume: z.ZodDefault<z.ZodNumber>;
385
385
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
386
+ voiceStart: "voiceStart";
387
+ voiceStop: "voiceStop";
386
388
  error: "error";
387
389
  messageReceived: "messageReceived";
388
390
  messageSent: "messageSent";
389
- voiceStart: "voiceStart";
390
- voiceStop: "voiceStop";
391
391
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
392
392
  }, z.core.$loose>;
393
393
  type SoundOptions = z.infer<typeof soundOptionsSchema>;
394
394
  declare const hapticsOptionsSchema: z.ZodObject<{
395
395
  enabled: z.ZodDefault<z.ZodBoolean>;
396
396
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
397
+ voiceStart: "voiceStart";
398
+ voiceStop: "voiceStop";
397
399
  error: "error";
398
400
  messageReceived: "messageReceived";
399
401
  messageSent: "messageSent";
400
- voiceStart: "voiceStart";
401
- voiceStop: "voiceStop";
402
402
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
403
403
  }, z.core.$loose>;
404
404
  type HapticsOptions = z.infer<typeof hapticsOptionsSchema>;
@@ -407,21 +407,21 @@ declare const feedbackSchema: z.ZodObject<{
407
407
  enabled: z.ZodDefault<z.ZodBoolean>;
408
408
  volume: z.ZodDefault<z.ZodNumber>;
409
409
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
410
+ voiceStart: "voiceStart";
411
+ voiceStop: "voiceStop";
410
412
  error: "error";
411
413
  messageReceived: "messageReceived";
412
414
  messageSent: "messageSent";
413
- voiceStart: "voiceStart";
414
- voiceStop: "voiceStop";
415
415
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
416
416
  }, z.core.$loose>>;
417
417
  haptics: z.ZodOptional<z.ZodObject<{
418
418
  enabled: z.ZodDefault<z.ZodBoolean>;
419
419
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
420
+ voiceStart: "voiceStart";
421
+ voiceStop: "voiceStop";
420
422
  error: "error";
421
423
  messageReceived: "messageReceived";
422
424
  messageSent: "messageSent";
423
- voiceStart: "voiceStart";
424
- voiceStop: "voiceStop";
425
425
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
426
426
  }, z.core.$loose>>;
427
427
  }, z.core.$loose>;
@@ -856,18 +856,18 @@ type I18nOptions = z.infer<typeof i18nSchema>;
856
856
  */
857
857
 
858
858
  declare const moduleLayoutSchema: z.ZodEnum<{
859
+ home: "home";
859
860
  chat: "chat";
860
861
  help: "help";
861
- home: "home";
862
862
  news: "news";
863
863
  }>;
864
864
  type ModuleLayout = z.infer<typeof moduleLayoutSchema>;
865
865
  declare const moduleSchema: z.ZodObject<{
866
866
  label: z.ZodString;
867
867
  layout: z.ZodEnum<{
868
+ home: "home";
868
869
  chat: "chat";
869
870
  help: "help";
870
- home: "home";
871
871
  news: "news";
872
872
  }>;
873
873
  contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -893,9 +893,9 @@ type ModuleOptions = z.infer<typeof moduleSchema>;
893
893
  declare const modulesSchema: z.ZodArray<z.ZodObject<{
894
894
  label: z.ZodString;
895
895
  layout: z.ZodEnum<{
896
+ home: "home";
896
897
  chat: "chat";
897
898
  help: "help";
898
- home: "home";
899
899
  news: "news";
900
900
  }>;
901
901
  contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
package/web-component.mjs CHANGED
@@ -1445,7 +1445,7 @@ function createAuth(opts) {
1445
1445
  }
1446
1446
 
1447
1447
  // src/core/version.ts
1448
- var ELEMENTS_VERSION = true ? "0.45.0" : "0.0.0-dev";
1448
+ var ELEMENTS_VERSION = true ? "0.46.1" : "0.0.0-dev";
1449
1449
  var ELEMENTS_VERSION_PARAM = "_ev";
1450
1450
 
1451
1451
  // src/stream/types.ts
@@ -1623,13 +1623,11 @@ function buildSendMessageRequest(params) {
1623
1623
  conversationId: params.conversationId,
1624
1624
  trigger: params.trigger ?? "submit-message"
1625
1625
  };
1626
+ if (params.messageId) body.messageId = params.messageId;
1626
1627
  if (params.visitorId) body.visitorId = params.visitorId;
1627
1628
  if (params.userPrefs) body.userPrefs = params.userPrefs;
1628
- const data = {};
1629
1629
  const tools = params.tools?.map(normalizeToolRef).filter((t) => t !== null);
1630
- if (tools?.length) data.tools = tools;
1631
- if (params.responseMode) data.responseMode = params.responseMode;
1632
- if (Object.keys(data).length > 0) body.data = data;
1630
+ if (tools?.length) body.data = { tools };
1633
1631
  return body;
1634
1632
  }
1635
1633
  function isResolvedToolPart(p35) {
@@ -1642,6 +1640,12 @@ function normalizeToolRef(ref) {
1642
1640
  function messageToWireParts(m) {
1643
1641
  const out = [];
1644
1642
  for (const p35 of m.parts) {
1643
+ if (p35.kind === "step-start") {
1644
+ out.push({ type: "step-start" });
1645
+ }
1646
+ if (p35.kind === "reasoning" && p35.text) {
1647
+ out.push({ type: "reasoning", text: p35.text, state: p35.done ? "done" : "streaming" });
1648
+ }
1645
1649
  if (p35.kind === "text" && p35.text) {
1646
1650
  out.push({ text: p35.text, type: "text" });
1647
1651
  }
@@ -2040,9 +2044,9 @@ var AgentTransport = class {
2040
2044
  log5.debug("message \u2192", {
2041
2045
  conversationId: body.conversationId,
2042
2046
  visitorId: body.visitorId,
2047
+ messageId: body.messageId,
2043
2048
  messageCount: body.messages.length,
2044
2049
  trigger: body.trigger,
2045
- responseMode: body.data?.responseMode,
2046
2050
  tools: body.data?.tools?.map((t) => t.code)
2047
2051
  });
2048
2052
  const ctrl = new AbortController();
@@ -2351,6 +2355,17 @@ function fromWireMessage(w) {
2351
2355
  if (part.type === "text") {
2352
2356
  return { kind: "text", id: `${w.id}-t${i}`, textSig: signal(part.text), doneSig: signal(true) };
2353
2357
  }
2358
+ if (part.type === "reasoning") {
2359
+ return {
2360
+ kind: "reasoning",
2361
+ id: `${w.id}-r${i}`,
2362
+ textSig: signal(part.text),
2363
+ doneSig: signal(part.state !== "streaming")
2364
+ };
2365
+ }
2366
+ if (part.type === "step-start") {
2367
+ return { kind: "step-start", id: `${w.id}-ss${i}` };
2368
+ }
2354
2369
  if (part.type === "file") {
2355
2370
  return { kind: "file", url: part.url, mediaType: part.mediaType };
2356
2371
  }
@@ -2469,9 +2484,11 @@ var StreamReducer = class {
2469
2484
  if (!m) return;
2470
2485
  switch (chunk.type) {
2471
2486
  case "start":
2472
- case "start-step":
2473
2487
  case "finish-step":
2474
2488
  return;
2489
+ case "start-step":
2490
+ appendPart(m, { kind: "step-start", id: `ss${m.partsSig.value.length}` });
2491
+ return;
2475
2492
  case "finish":
2476
2493
  log6.debug("finish", { reason: chunk.finishReason, canContinue: chunk.canContinue });
2477
2494
  m.status = "complete";
@@ -2624,18 +2641,6 @@ function applyTool(m, chunk) {
2624
2641
  }
2625
2642
  }
2626
2643
 
2627
- // src/stream/constants.ts
2628
- function isAskUserInputTool(toolName) {
2629
- if (!toolName) return false;
2630
- const name = toolName.startsWith("tool:") ? toolName.slice(5) : toolName;
2631
- return name === "ask-user-input" || name === "ask_user_input" || name === "request-user-input" || name === "request_user_input";
2632
- }
2633
- var TRIGGER = {
2634
- submitMessage: "submit-message",
2635
- toolResult: "tool-result",
2636
- toolApproval: "tool-approval"
2637
- };
2638
-
2639
2644
  // src/core/feedback/index.ts
2640
2645
  import { signal as signal3 } from "@preact/signals";
2641
2646
 
@@ -4742,6 +4747,13 @@ function FormDoneMarker({
4742
4747
  // src/ui/message-bubble.tsx
4743
4748
  import { useComputed as useComputed5 } from "@preact/signals";
4744
4749
 
4750
+ // src/stream/constants.ts
4751
+ function isAskUserInputTool(toolName) {
4752
+ if (!toolName) return false;
4753
+ const name = toolName.startsWith("tool:") ? toolName.slice(5) : toolName;
4754
+ return name === "ask-user-input" || name === "ask_user_input" || name === "request-user-input" || name === "request_user_input";
4755
+ }
4756
+
4745
4757
  // src/ui/markdown.tsx
4746
4758
  import { useLayoutEffect, useMemo, useRef as useRef4 } from "preact/hooks";
4747
4759
  import { effect, signal as signal4 } from "@preact/signals";
@@ -5170,6 +5182,8 @@ function PartView({
5170
5182
  tool
5171
5183
  }) {
5172
5184
  switch (part.kind) {
5185
+ case "step-start":
5186
+ return null;
5173
5187
  case "text":
5174
5188
  return /* @__PURE__ */ jsx17(MarkdownView, { textSig: part.textSig, doneSig: part.doneSig });
5175
5189
  case "reasoning":
@@ -5235,6 +5249,7 @@ function partKey(part) {
5235
5249
  switch (part.kind) {
5236
5250
  case "text":
5237
5251
  case "reasoning":
5252
+ case "step-start":
5238
5253
  return `${part.kind}:${part.id}`;
5239
5254
  case "tool":
5240
5255
  return `tool:${part.toolCallId}`;
@@ -6895,6 +6910,13 @@ var p34 = BRAND.cssPrefix;
6895
6910
  function makeLocalizedWelcome(w, strings) {
6896
6911
  return makeInstantWelcomeMessage({ ...w, text: localizeText(strings, w.text) });
6897
6912
  }
6913
+ function allToolPartsSettled(msg) {
6914
+ const tools = msg.partsSig.value.filter((p35) => p35.kind === "tool");
6915
+ return tools.length > 0 && tools.every((p35) => {
6916
+ const s = p35.stateSig.value;
6917
+ return s === "output-available" || s === "output-error" || s === "output-denied" || s === "approval-responded";
6918
+ });
6919
+ }
6898
6920
  function App({ options, hostElement, bus }) {
6899
6921
  const [persistence] = useState13(
6900
6922
  () => createPersistence(options.widgetId, options.storage, options.aiAgentDeploymentId)
@@ -7361,19 +7383,20 @@ function App({ options, hostElement, bus }) {
7361
7383
  return () => document.removeEventListener("keydown", onKey);
7362
7384
  }, [isOpen, options.mode]);
7363
7385
  const streamAssistant = useCallback6(
7364
- async (assistantMsg, trigger) => {
7386
+ async (assistantMsg, { continueExisting }) => {
7365
7387
  const activeConversationId = conversationIdSig.value ?? uuid7();
7366
7388
  if (!conversationIdSig.value) {
7367
7389
  conversationIdSig.value = activeConversationId;
7368
7390
  persistence.saveConversationId(activeConversationId);
7369
7391
  }
7392
+ const thread = continueExisting ? messagesSig.value : messagesSig.value.slice(0, -1);
7370
7393
  const body = buildSendMessageRequest({
7371
- messages: messagesSig.value.slice(0, -1).map(fromReactive),
7394
+ messages: thread.map(fromReactive),
7372
7395
  conversationId: activeConversationId,
7396
+ // The assistant message being generated / resumed.
7397
+ messageId: assistantMsg.id,
7373
7398
  // textModel + imageModel are backend-only — selected per deployment.
7374
7399
  tools: options.features.tools,
7375
- responseMode: options.responseMode,
7376
- trigger,
7377
7400
  // Identity + preferences ride on every message — server may need
7378
7401
  // them to route, persist, or reconcile in-flight.
7379
7402
  visitorId,
@@ -7407,23 +7430,23 @@ function App({ options, hostElement, bus }) {
7407
7430
  },
7408
7431
  [transport, reducer, messagesSig, conversationIdSig, options, bus, feedback, persistence, visitorId]
7409
7432
  );
7410
- const resolveTool = useCallback6(
7411
- (toolCallId, trigger, mutate) => {
7433
+ const decideTool = useCallback6(
7434
+ (toolCallId, mutate) => {
7412
7435
  if (streaming) return;
7413
7436
  const last = messagesSig.value.at(-1);
7414
7437
  const part = last?.partsSig.value.find(
7415
7438
  (pt) => pt.kind === "tool" && pt.toolCallId === toolCallId
7416
7439
  );
7417
- if (!part) {
7418
- log16.warn("resolveTool: tool part not found", { toolCallId });
7440
+ if (!last || !part) {
7441
+ log16.warn("decideTool: tool part not found", { toolCallId });
7419
7442
  return;
7420
7443
  }
7421
7444
  mutate(part);
7422
- if (last) last.partsSig.value = [...last.partsSig.value];
7423
- const assistantMsg = makeAssistantMessage();
7424
- messagesSig.value = [...messagesSig.value, assistantMsg];
7425
- reducer.attach(assistantMsg);
7426
- void streamAssistant(assistantMsg, trigger);
7445
+ last.partsSig.value = [...last.partsSig.value];
7446
+ if (!allToolPartsSettled(last)) return;
7447
+ last.status = "streaming";
7448
+ reducer.attach(last);
7449
+ void streamAssistant(last, { continueExisting: true });
7427
7450
  },
7428
7451
  [streaming, messagesSig, reducer, streamAssistant]
7429
7452
  );
@@ -7431,24 +7454,24 @@ function App({ options, hostElement, bus }) {
7431
7454
  (toolCallId, output) => {
7432
7455
  log16.info("toolResult", { toolCallId });
7433
7456
  bus.emit("toolResult", { toolCallId });
7434
- resolveTool(toolCallId, TRIGGER.toolResult, (part) => {
7457
+ decideTool(toolCallId, (part) => {
7435
7458
  part.outputSig.value = output;
7436
7459
  part.stateSig.value = "output-available";
7437
7460
  });
7438
7461
  },
7439
- [bus, resolveTool]
7462
+ [bus, decideTool]
7440
7463
  );
7441
7464
  const handleToolDecision = useCallback6(
7442
7465
  (toolCallId, approved, reason) => {
7443
7466
  log16.info("toolDecision", { toolCallId, approved });
7444
7467
  bus.emit("toolDecision", { toolCallId, approved });
7445
- resolveTool(toolCallId, TRIGGER.toolApproval, (part) => {
7468
+ decideTool(toolCallId, (part) => {
7446
7469
  const id = part.approvalSig.value?.id ?? toolCallId;
7447
7470
  part.approvalSig.value = { id, approved, reason };
7448
7471
  part.stateSig.value = "approval-responded";
7449
7472
  });
7450
7473
  },
7451
- [bus, resolveTool]
7474
+ [bus, decideTool]
7452
7475
  );
7453
7476
  const toolInteraction = useMemo3(
7454
7477
  () => ({ humanInLoop: options.features.humanInLoop, onResult: handleToolResult, onDecision: handleToolDecision }),
@@ -7528,7 +7551,7 @@ function App({ options, hostElement, bus }) {
7528
7551
  messagesSig.value = [...messagesSig.value, userMsg, assistantMsg];
7529
7552
  reducer.attach(assistantMsg);
7530
7553
  emitMessage(bus, options, "user", text);
7531
- await streamAssistant(assistantMsg, TRIGGER.submitMessage);
7554
+ await streamAssistant(assistantMsg, { continueExisting: false });
7532
7555
  forms.fire("after-messages");
7533
7556
  },
7534
7557
  [streaming, transport, bus, options, suggestions.length, messagesSig, reducer, streamAssistant, forms]