@paymanai/payman-typescript-ask-sdk 4.0.10 → 4.0.14

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/index.js CHANGED
@@ -15,10 +15,95 @@ function generateId() {
15
15
  });
16
16
  }
17
17
 
18
+ // src/utils/chatStore.ts
19
+ var memoryStore = /* @__PURE__ */ new Map();
20
+ var chatStore = {
21
+ get(key) {
22
+ return memoryStore.get(key) ?? [];
23
+ },
24
+ set(key, messages) {
25
+ memoryStore.set(key, messages);
26
+ },
27
+ delete(key) {
28
+ memoryStore.delete(key);
29
+ }
30
+ };
31
+
32
+ // src/utils/activeStreamStore.ts
33
+ var streams = /* @__PURE__ */ new Map();
34
+ var activeStreamStore = {
35
+ has(key) {
36
+ return streams.has(key);
37
+ },
38
+ get(key) {
39
+ const entry = streams.get(key);
40
+ if (!entry) return null;
41
+ return { messages: entry.messages, isWaiting: entry.isWaiting };
42
+ },
43
+ // Called before startStream — registers the controller and initial messages
44
+ start(key, abortController, initialMessages) {
45
+ const existing = streams.get(key);
46
+ streams.set(key, {
47
+ messages: initialMessages,
48
+ isWaiting: true,
49
+ abortController,
50
+ listeners: existing?.listeners ?? /* @__PURE__ */ new Set()
51
+ });
52
+ },
53
+ // Called by the stream on every event — applies the same updater pattern React uses
54
+ applyMessages(key, updater) {
55
+ const entry = streams.get(key);
56
+ if (!entry) return;
57
+ const next = typeof updater === "function" ? updater(entry.messages) : updater;
58
+ entry.messages = next;
59
+ entry.listeners.forEach((l) => l(next, entry.isWaiting));
60
+ },
61
+ setWaiting(key, waiting) {
62
+ const entry = streams.get(key);
63
+ if (!entry) return;
64
+ entry.isWaiting = waiting;
65
+ entry.listeners.forEach((l) => l(entry.messages, waiting));
66
+ },
67
+ // Called when stream completes — persists to chatStore and cleans up
68
+ complete(key) {
69
+ const entry = streams.get(key);
70
+ if (!entry) return;
71
+ entry.isWaiting = false;
72
+ entry.listeners.forEach((l) => l(entry.messages, false));
73
+ const toSave = entry.messages.filter((m) => !m.isStreaming);
74
+ if (toSave.length > 0) chatStore.set(key, toSave);
75
+ streams.delete(key);
76
+ },
77
+ // Subscribe — returns unsubscribe fn. Component calls this on mount, cleanup on unmount.
78
+ subscribe(key, listener) {
79
+ const entry = streams.get(key);
80
+ if (!entry) return () => {
81
+ };
82
+ entry.listeners.add(listener);
83
+ return () => {
84
+ streams.get(key)?.listeners.delete(listener);
85
+ };
86
+ },
87
+ // Rename an entry — used when the server assigns a new session ID mid-stream
88
+ rename(oldKey, newKey) {
89
+ const entry = streams.get(oldKey);
90
+ if (!entry) return;
91
+ streams.set(newKey, entry);
92
+ streams.delete(oldKey);
93
+ },
94
+ // Explicit user cancel — aborts the controller and removes the entry
95
+ abort(key) {
96
+ const entry = streams.get(key);
97
+ if (!entry) return;
98
+ entry.abortController.abort();
99
+ streams.delete(key);
100
+ }
101
+ };
102
+
18
103
  // src/utils/streamingClient.ts
19
104
  function yieldAfterProgressEvent(event) {
20
105
  const t = event.eventType;
21
- if (t === "RUN_IN_PROGRESS" || t === "INTENT_PROGRESS" || t === "AGGREGATOR_THINKING_CONT" || t === "INTENT_THINKING_CONT" || t === "THINKING_DELTA") {
106
+ if (t === "RUN_IN_PROGRESS" || t === "INTENT_PROGRESS" || t === "THINKING_DELTA") {
22
107
  return new Promise((resolve) => setTimeout(resolve, 0));
23
108
  }
24
109
  return Promise.resolve();
@@ -278,40 +363,10 @@ function classifyUserActionKind(action, schema) {
278
363
  return isVerificationSchema(schema) ? "verification" : "form";
279
364
  }
280
365
  }
281
- function userActionHeader(kind) {
282
- return kind === "verification" ? "**Verification required**" : "**Action required**";
283
- }
284
- function workingPhaseDetailForDisplay(raw) {
285
- const t = raw.trim();
286
- if (!t) return "";
287
- if (/^Identified\s+\d+\s+tasks?\s+to\s+execute\.?$/i.test(t)) {
288
- return "";
289
- }
290
- return t;
291
- }
292
366
  function getEventText(event, field) {
293
367
  const value = event[field];
294
368
  return typeof value === "string" ? value.trim() : "";
295
369
  }
296
- function shouldShowIntentHeader(event) {
297
- const workerName = getEventText(event, "workerName");
298
- const intentId = getEventText(event, "intentId");
299
- return Boolean(workerName && intentId && workerName === intentId);
300
- }
301
- function addThinkingHeader(state, header) {
302
- state.formattedThinkingText += (state.formattedThinkingText ? "\n" : "") + header;
303
- }
304
- function addThinkingDetail(state, detail) {
305
- const trimmed = detail.trim();
306
- if (!trimmed) return;
307
- state.formattedThinkingText += (state.formattedThinkingText ? "\n" : "") + trimmed;
308
- }
309
- function addThinkingLine(state, header, detail) {
310
- state.formattedThinkingText += (state.formattedThinkingText ? "\n" : "") + header + "\n" + detail;
311
- }
312
- function appendThinkingText(state, text) {
313
- state.formattedThinkingText += text;
314
- }
315
370
  function updateExecutionStageMessage(state, msg) {
316
371
  if (!msg) return;
317
372
  for (let i = state.steps.length - 1; i >= 0; i--) {
@@ -332,9 +387,7 @@ function completeLastInProgressStep(steps) {
332
387
  }
333
388
  function createInitialV2State() {
334
389
  return {
335
- formattedThinkingText: "",
336
390
  finalResponse: "",
337
- currentWorker: "",
338
391
  lastEventType: "",
339
392
  sessionId: void 0,
340
393
  executionId: void 0,
@@ -381,10 +434,6 @@ function processStreamEventV2(rawEvent, state) {
381
434
  return state;
382
435
  }
383
436
  if (typeof eventType === "string" && eventType.toUpperCase() === "THINKING_DELTA") {
384
- const text = typeof event.text === "string" ? event.text : "";
385
- if (text) {
386
- appendThinkingText(state, text);
387
- }
388
437
  if (event.executionId) state.executionId = event.executionId;
389
438
  if (event.sessionId) state.sessionId = event.sessionId;
390
439
  state.lastEventType = "THINKING_DELTA";
@@ -395,7 +444,6 @@ function processStreamEventV2(rawEvent, state) {
395
444
  const message = getEventMessage(event);
396
445
  switch (eventType) {
397
446
  case "WORKFLOW_STARTED":
398
- case "STARTED":
399
447
  state.lastEventType = eventType;
400
448
  break;
401
449
  case "INTENT_PROGRESS": {
@@ -408,97 +456,7 @@ function processStreamEventV2(rawEvent, state) {
408
456
  state.lastEventType = eventType;
409
457
  break;
410
458
  }
411
- case "INTENT_THINKING": {
412
- const worker = getEventText(event, "workerName") || "Worker";
413
- const msg = getEventText(event, "message") || "Thinking...";
414
- const showHeader = shouldShowIntentHeader(event);
415
- if (worker !== state.currentWorker) {
416
- state.currentWorker = worker;
417
- if (showHeader && msg && msg !== worker) {
418
- addThinkingLine(state, `**${worker}**`, msg);
419
- } else if (showHeader) {
420
- addThinkingHeader(state, `**${worker}**`);
421
- } else if (msg !== "Thinking...") {
422
- addThinkingDetail(state, msg);
423
- }
424
- } else if ((showHeader || msg !== "Thinking...")) {
425
- appendThinkingText(state, "\n" + msg);
426
- }
427
- const lastInProgress = [...state.steps].reverse().find((s) => s.status === "in_progress");
428
- if (lastInProgress) {
429
- lastInProgress.thinkingText = "";
430
- lastInProgress.isThinking = true;
431
- }
432
- state.lastEventType = "INTENT_THINKING";
433
- break;
434
- }
435
- case "INTENT_THINKING_CONT": {
436
- const msg = event.message || "";
437
- if (!msg) break;
438
- if (state.lastEventType === "INTENT_THINKING") {
439
- appendThinkingText(state, "\n" + msg);
440
- } else {
441
- appendThinkingText(state, msg);
442
- }
443
- const thinkingStep = [...state.steps].reverse().find((s) => s.isThinking);
444
- if (thinkingStep) {
445
- thinkingStep.thinkingText = (thinkingStep.thinkingText || "") + msg;
446
- }
447
- state.lastEventType = "INTENT_THINKING_CONT";
448
- break;
449
- }
450
- case "ORCHESTRATOR_THINKING": {
451
- addThinkingLine(state, "**Planning**", event.message || "Understanding your request...");
452
- const stepId = `step-${state.stepCounter++}`;
453
- state.steps.push({
454
- id: stepId,
455
- eventType,
456
- message,
457
- status: "in_progress",
458
- timestamp: Date.now(),
459
- elapsedMs: event.elapsedMs
460
- });
461
- state.currentExecutingStepId = stepId;
462
- state.lastEventType = eventType;
463
- break;
464
- }
465
- case "ORCHESTRATOR_COMPLETED": {
466
- const workingDetail = workingPhaseDetailForDisplay(message);
467
- if (workingDetail) {
468
- addThinkingLine(state, "**Working**", workingDetail);
469
- } else {
470
- addThinkingHeader(state, "**Working**");
471
- }
472
- state.steps.push({
473
- id: `step-${state.stepCounter++}`,
474
- eventType: "WORKING",
475
- message: workingDetail,
476
- status: "completed",
477
- timestamp: Date.now()
478
- });
479
- const step = state.steps.find((s) => s.eventType === "ORCHESTRATOR_THINKING" && s.status === "in_progress");
480
- if (step) {
481
- step.status = "completed";
482
- if (event.elapsedMs) step.elapsedMs = event.elapsedMs;
483
- if (step.id === state.currentExecutingStepId) state.currentExecutingStepId = void 0;
484
- }
485
- state.lastEventType = eventType;
486
- break;
487
- }
488
459
  case "INTENT_STARTED": {
489
- const worker = getEventText(event, "workerName") || "Worker";
490
- const msg = getEventText(event, "message") || "Starting...";
491
- const showHeader = shouldShowIntentHeader(event);
492
- state.currentWorker = worker;
493
- if (showHeader && msg !== worker) {
494
- addThinkingLine(state, `**${worker}**`, msg);
495
- } else if (showHeader) {
496
- addThinkingHeader(state, `**${worker}**`);
497
- } else {
498
- addThinkingDetail(state, msg);
499
- }
500
- const thinkingStep = state.steps.find((s) => s.isThinking);
501
- if (thinkingStep) thinkingStep.isThinking = false;
502
460
  const stepId = `step-${state.stepCounter++}`;
503
461
  state.steps.push({
504
462
  id: stepId,
@@ -517,55 +475,18 @@ function processStreamEventV2(rawEvent, state) {
517
475
  const intentStep = state.steps.find((s) => s.eventType === "INTENT_STARTED" && s.status === "in_progress");
518
476
  if (intentStep) {
519
477
  intentStep.status = "completed";
520
- intentStep.isThinking = false;
521
478
  if (event.elapsedMs) intentStep.elapsedMs = event.elapsedMs;
522
479
  if (intentStep.id === state.currentExecutingStepId) state.currentExecutingStepId = void 0;
523
480
  }
524
481
  state.lastEventType = eventType;
525
482
  break;
526
483
  }
527
- case "AGGREGATOR_THINKING": {
528
- addThinkingLine(state, "**Finalizing**", event.message || "Preparing response...");
529
- const stepId = `step-${state.stepCounter++}`;
530
- state.steps.push({
531
- id: stepId,
532
- eventType,
533
- message,
534
- status: "in_progress",
535
- timestamp: Date.now(),
536
- elapsedMs: event.elapsedMs
537
- });
538
- state.currentExecutingStepId = stepId;
539
- state.lastEventType = eventType;
540
- break;
541
- }
542
- case "AGGREGATOR_COMPLETED": {
543
- appendThinkingText(state, "\n" + (event.message || "Response ready"));
544
- const step = state.steps.find((s) => s.eventType === "AGGREGATOR_THINKING" && s.status === "in_progress");
545
- if (step) {
546
- step.status = "completed";
547
- if (event.elapsedMs) step.elapsedMs = event.elapsedMs;
548
- if (step.id === state.currentExecutingStepId) state.currentExecutingStepId = void 0;
549
- }
550
- state.lastEventType = eventType;
551
- break;
552
- }
553
- case "WORKFLOW_COMPLETED":
554
- case "COMPLETED": {
484
+ case "WORKFLOW_COMPLETED": {
555
485
  const totalTime = Number(event.totalTimeMs);
556
486
  if (Number.isFinite(totalTime) && totalTime > 0) {
557
487
  state.totalElapsedMs = totalTime;
558
488
  }
559
- let content = extractResponseContent(event.response);
560
- const trace = event.trace && typeof event.trace === "object" ? event.trace : null;
561
- if (!content && trace?.workflowMsg && typeof trace.workflowMsg === "string") {
562
- content = trace.workflowMsg;
563
- }
564
- if (!content && trace?.aggregator && typeof trace.aggregator === "object") {
565
- const agg = trace.aggregator;
566
- if (typeof agg.response === "string") content = agg.response;
567
- else content = extractResponseContent(agg.response);
568
- }
489
+ const content = extractResponseContent(event.response);
569
490
  if (content) {
570
491
  state.finalResponse = content;
571
492
  if (event.trace && typeof event.trace === "object") {
@@ -580,7 +501,6 @@ function processStreamEventV2(rawEvent, state) {
580
501
  state.steps.forEach((step) => {
581
502
  if (step.status === "in_progress") {
582
503
  step.status = "completed";
583
- step.isThinking = false;
584
504
  }
585
505
  });
586
506
  state.lastEventType = eventType;
@@ -599,7 +519,6 @@ function processStreamEventV2(rawEvent, state) {
599
519
  };
600
520
  state.notifications.push(notification);
601
521
  state.lastNotification = notification;
602
- if (promptMessage) addThinkingDetail(state, promptMessage);
603
522
  state.lastEventType = eventType;
604
523
  break;
605
524
  }
@@ -625,9 +544,6 @@ function processStreamEventV2(rawEvent, state) {
625
544
  };
626
545
  upsertUserAction(state, request);
627
546
  state.lastUserAction = request;
628
- const header = userActionHeader(kind);
629
- if (promptMessage) addThinkingLine(state, header, promptMessage);
630
- else addThinkingHeader(state, header);
631
547
  const stepId = `step-${state.stepCounter++}`;
632
548
  state.steps.push({
633
549
  id: stepId,
@@ -651,27 +567,15 @@ function processStreamEventV2(rawEvent, state) {
651
567
  };
652
568
  state.notifications.push(notification);
653
569
  state.lastNotification = notification;
654
- if (noteMessage) addThinkingDetail(state, noteMessage);
655
570
  }
656
571
  state.lastEventType = eventType;
657
572
  break;
658
573
  }
659
574
  case "WORKFLOW_ERROR":
660
- case "ERROR":
661
575
  state.hasError = true;
662
576
  state.errorMessage = event.errorMessage || event.message || "Workflow error";
663
577
  state.lastEventType = eventType;
664
578
  break;
665
- case "INTENT_ERROR": {
666
- state.errorMessage = message || event.errorMessage || "An error occurred";
667
- const intentStep = state.steps.find((s) => s.eventType === "INTENT_STARTED" && s.status === "in_progress");
668
- if (intentStep) {
669
- intentStep.status = "error";
670
- intentStep.isThinking = false;
671
- }
672
- state.lastEventType = eventType;
673
- break;
674
- }
675
579
  // ---- K2 pipeline stage lifecycle events ----
676
580
  //
677
581
  // The k2-server playground streaming API emits
@@ -792,84 +696,6 @@ function processStreamEventV2(rawEvent, state) {
792
696
  return state;
793
697
  }
794
698
 
795
- // src/utils/messageStateManager.ts
796
- function buildFormattedThinking(steps, allThinkingText) {
797
- const parts = [];
798
- const safeSteps = steps ?? [];
799
- const cleanAll = allThinkingText.replace(/^\s+/, "");
800
- if (cleanAll) {
801
- const firstStepWithThinking = safeSteps.find(
802
- (s) => s.thinkingText && s.thinkingText.trim()
803
- );
804
- if (!firstStepWithThinking) {
805
- parts.push("**Preflight**");
806
- parts.push(cleanAll);
807
- } else {
808
- const stepText = firstStepWithThinking.thinkingText.trim();
809
- const idx = cleanAll.indexOf(stepText);
810
- if (idx > 0) {
811
- const orphaned = cleanAll.substring(0, idx).replace(/\s+$/, "");
812
- if (orphaned) {
813
- parts.push("**Preflight**");
814
- parts.push(orphaned);
815
- }
816
- }
817
- }
818
- }
819
- for (const step of safeSteps) {
820
- switch (step.eventType) {
821
- case "STAGE_STARTED": {
822
- if (step.message) parts.push(`**${step.message}**`);
823
- break;
824
- }
825
- case "ORCHESTRATOR_THINKING":
826
- parts.push("**Planning**");
827
- if (step.message) parts.push(step.message);
828
- break;
829
- case "INTENT_STARTED": {
830
- let label = step.message || "Processing";
831
- const started = label.match(/^(.+?)\s+started$/i);
832
- const progress = label.match(/^(.+?)\s+in progress$/i);
833
- if (started) label = started[1];
834
- else if (progress) label = progress[1];
835
- parts.push(`**${label}**`);
836
- if (step.thinkingText) parts.push(step.thinkingText);
837
- break;
838
- }
839
- case "INTENT_PROGRESS": {
840
- if (step.thinkingText) parts.push(step.thinkingText);
841
- else if (step.message) parts.push(step.message);
842
- break;
843
- }
844
- case "AGGREGATOR_THINKING":
845
- parts.push("**Finalizing**");
846
- if (step.message) parts.push(step.message);
847
- break;
848
- case "USER_ACTION_REQUIRED":
849
- parts.push("**Action required**");
850
- if (step.message) parts.push(step.message);
851
- break;
852
- }
853
- }
854
- return parts.length > 0 ? parts.join("\n") : allThinkingText;
855
- }
856
- function createCancelledMessageUpdate(steps, currentMessage) {
857
- const updatedSteps = steps.map((step) => {
858
- if (step.status === "in_progress") {
859
- return { ...step, status: "pending" };
860
- }
861
- return step;
862
- });
863
- return {
864
- isStreaming: false,
865
- isCancelled: true,
866
- steps: updatedSteps,
867
- currentExecutingStepId: void 0,
868
- // Preserve currentMessage so UI can show it with X icon
869
- currentMessage: currentMessage || "Thinking..."
870
- };
871
- }
872
-
873
699
  // src/utils/requestBuilder.ts
874
700
  var DEFAULT_STREAM_ENDPOINT = "/api/playground/ask/stream";
875
701
  function buildRequestBody(config, userMessage, sessionId, options) {
@@ -943,129 +769,6 @@ function buildRequestHeaders(config) {
943
769
  return headers;
944
770
  }
945
771
 
946
- // src/utils/userActionClient.ts
947
- var UserActionStaleError = class extends Error {
948
- constructor(userActionId, message = "User action is no longer actionable") {
949
- super(message);
950
- __publicField(this, "userActionId");
951
- this.name = "UserActionStaleError";
952
- this.userActionId = userActionId;
953
- }
954
- };
955
- async function sendUserActionRequest(config, userActionId, action, data) {
956
- const url = buildUserActionUrl(config, userActionId, action);
957
- const baseHeaders = buildRequestHeaders(config);
958
- const hasBody = data !== void 0;
959
- const headers = hasBody ? { "Content-Type": "application/json", ...baseHeaders } : baseHeaders;
960
- const response = await fetch(url, {
961
- method: "POST",
962
- headers,
963
- body: hasBody ? JSON.stringify(data) : void 0
964
- });
965
- if (response.status === 404) {
966
- throw new UserActionStaleError(userActionId);
967
- }
968
- if (!response.ok) {
969
- const errorText = await response.text();
970
- throw new Error(`HTTP ${response.status}: ${errorText}`);
971
- }
972
- return await response.json();
973
- }
974
- async function submitUserAction(config, userActionId, content) {
975
- return sendUserActionRequest(config, userActionId, "submit", content ?? {});
976
- }
977
- async function cancelUserAction(config, userActionId) {
978
- return sendUserActionRequest(config, userActionId, "cancel");
979
- }
980
- async function resendUserAction(config, userActionId) {
981
- return sendUserActionRequest(config, userActionId, "resend");
982
- }
983
-
984
- // src/utils/chatStore.ts
985
- var memoryStore = /* @__PURE__ */ new Map();
986
- var chatStore = {
987
- get(key) {
988
- return memoryStore.get(key) ?? [];
989
- },
990
- set(key, messages) {
991
- memoryStore.set(key, messages);
992
- },
993
- delete(key) {
994
- memoryStore.delete(key);
995
- }
996
- };
997
-
998
- // src/utils/activeStreamStore.ts
999
- var streams = /* @__PURE__ */ new Map();
1000
- var activeStreamStore = {
1001
- has(key) {
1002
- return streams.has(key);
1003
- },
1004
- get(key) {
1005
- const entry = streams.get(key);
1006
- if (!entry) return null;
1007
- return { messages: entry.messages, isWaiting: entry.isWaiting };
1008
- },
1009
- // Called before startStream — registers the controller and initial messages
1010
- start(key, abortController, initialMessages) {
1011
- const existing = streams.get(key);
1012
- streams.set(key, {
1013
- messages: initialMessages,
1014
- isWaiting: true,
1015
- abortController,
1016
- listeners: existing?.listeners ?? /* @__PURE__ */ new Set()
1017
- });
1018
- },
1019
- // Called by the stream on every event — applies the same updater pattern React uses
1020
- applyMessages(key, updater) {
1021
- const entry = streams.get(key);
1022
- if (!entry) return;
1023
- const next = typeof updater === "function" ? updater(entry.messages) : updater;
1024
- entry.messages = next;
1025
- entry.listeners.forEach((l) => l(next, entry.isWaiting));
1026
- },
1027
- setWaiting(key, waiting) {
1028
- const entry = streams.get(key);
1029
- if (!entry) return;
1030
- entry.isWaiting = waiting;
1031
- entry.listeners.forEach((l) => l(entry.messages, waiting));
1032
- },
1033
- // Called when stream completes — persists to chatStore and cleans up
1034
- complete(key) {
1035
- const entry = streams.get(key);
1036
- if (!entry) return;
1037
- entry.isWaiting = false;
1038
- entry.listeners.forEach((l) => l(entry.messages, false));
1039
- const toSave = entry.messages.filter((m) => !m.isStreaming);
1040
- if (toSave.length > 0) chatStore.set(key, toSave);
1041
- streams.delete(key);
1042
- },
1043
- // Subscribe — returns unsubscribe fn. Component calls this on mount, cleanup on unmount.
1044
- subscribe(key, listener) {
1045
- const entry = streams.get(key);
1046
- if (!entry) return () => {
1047
- };
1048
- entry.listeners.add(listener);
1049
- return () => {
1050
- streams.get(key)?.listeners.delete(listener);
1051
- };
1052
- },
1053
- // Rename an entry — used when the server assigns a new session ID mid-stream
1054
- rename(oldKey, newKey) {
1055
- const entry = streams.get(oldKey);
1056
- if (!entry) return;
1057
- streams.set(newKey, entry);
1058
- streams.delete(oldKey);
1059
- },
1060
- // Explicit user cancel — aborts the controller and removes the entry
1061
- abort(key) {
1062
- const entry = streams.get(key);
1063
- if (!entry) return;
1064
- entry.abortController.abort();
1065
- streams.delete(key);
1066
- }
1067
- };
1068
-
1069
772
  // src/utils/ragImageResolver.ts
1070
773
  var RAG_IMAGE_REGEX = /\/api\/rag\/chunks\/[^"'\s]+\/image/;
1071
774
  function hasRagImages(content) {
@@ -1180,7 +883,6 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1180
883
  streamProgress: "error",
1181
884
  isError: true,
1182
885
  errorDetails: state.errorMessage,
1183
- formattedThinkingText: state.formattedThinkingText || void 0,
1184
886
  steps: [...state.steps],
1185
887
  currentExecutingStepId: void 0,
1186
888
  executionId: state.executionId,
@@ -1193,7 +895,6 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1193
895
  currentMessage,
1194
896
  streamProgress: "processing",
1195
897
  isError: false,
1196
- formattedThinkingText: state.formattedThinkingText || void 0,
1197
898
  steps: [...state.steps],
1198
899
  currentExecutingStepId: state.currentExecutingStepId,
1199
900
  executionId: state.executionId,
@@ -1220,7 +921,6 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1220
921
  errorDetails: isAborted ? void 0 : error.message,
1221
922
  content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
1222
923
  currentMessage: isAborted ? "Thinking..." : void 0,
1223
- formattedThinkingText: state.formattedThinkingText || void 0,
1224
924
  steps: [...state.steps].map((step) => {
1225
925
  if (step.status === "in_progress" && isAborted) {
1226
926
  return { ...step, status: "pending" };
@@ -1259,7 +959,6 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1259
959
  steps: state.hasError ? [] : [...state.steps],
1260
960
  isCancelled: false,
1261
961
  currentExecutingStepId: void 0,
1262
- formattedThinkingText: state.hasError ? void 0 : state.formattedThinkingText || void 0,
1263
962
  isResolvingImages: needsImageResolve,
1264
963
  totalElapsedMs: state.hasError ? void 0 : state.totalElapsedMs
1265
964
  };
@@ -1312,7 +1011,6 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1312
1011
  isCancelled: isAborted,
1313
1012
  errorDetails: isAborted ? void 0 : error.message,
1314
1013
  content: isAborted ? state.finalResponse || "" : state.finalResponse || FRIENDLY_ERROR_MESSAGE,
1315
- formattedThinkingText: state.formattedThinkingText || void 0,
1316
1014
  steps: [...state.steps].map((step) => {
1317
1015
  if (step.status === "in_progress" && isAborted) {
1318
1016
  return { ...step, status: "pending" };
@@ -1338,6 +1036,61 @@ function useStreamManagerV2(config, callbacks, setMessages, setIsWaitingForRespo
1338
1036
  };
1339
1037
  }
1340
1038
 
1039
+ // src/utils/messageStateManager.ts
1040
+ function createCancelledMessageUpdate(steps, currentMessage) {
1041
+ const updatedSteps = steps.map((step) => {
1042
+ if (step.status === "in_progress") {
1043
+ return { ...step, status: "pending" };
1044
+ }
1045
+ return step;
1046
+ });
1047
+ return {
1048
+ isStreaming: false,
1049
+ isCancelled: true,
1050
+ steps: updatedSteps,
1051
+ currentExecutingStepId: void 0,
1052
+ currentMessage: currentMessage || "Thinking..."
1053
+ };
1054
+ }
1055
+
1056
+ // src/utils/userActionClient.ts
1057
+ var UserActionStaleError = class extends Error {
1058
+ constructor(userActionId, message = "User action is no longer actionable") {
1059
+ super(message);
1060
+ __publicField(this, "userActionId");
1061
+ this.name = "UserActionStaleError";
1062
+ this.userActionId = userActionId;
1063
+ }
1064
+ };
1065
+ async function sendUserActionRequest(config, userActionId, action, data) {
1066
+ const url = buildUserActionUrl(config, userActionId, action);
1067
+ const baseHeaders = buildRequestHeaders(config);
1068
+ const hasBody = data !== void 0;
1069
+ const headers = hasBody ? { "Content-Type": "application/json", ...baseHeaders } : baseHeaders;
1070
+ const response = await fetch(url, {
1071
+ method: "POST",
1072
+ headers,
1073
+ body: hasBody ? JSON.stringify(data) : void 0
1074
+ });
1075
+ if (response.status === 404) {
1076
+ throw new UserActionStaleError(userActionId);
1077
+ }
1078
+ if (!response.ok) {
1079
+ const errorText = await response.text();
1080
+ throw new Error(`HTTP ${response.status}: ${errorText}`);
1081
+ }
1082
+ return await response.json();
1083
+ }
1084
+ async function submitUserAction(config, userActionId, content) {
1085
+ return sendUserActionRequest(config, userActionId, "submit", content ?? {});
1086
+ }
1087
+ async function cancelUserAction(config, userActionId) {
1088
+ return sendUserActionRequest(config, userActionId, "cancel");
1089
+ }
1090
+ async function resendUserAction(config, userActionId) {
1091
+ return sendUserActionRequest(config, userActionId, "resend");
1092
+ }
1093
+
1341
1094
  // src/hooks/useChatV2.ts
1342
1095
  var EMPTY_USER_ACTION_STATE = { prompts: [], notifications: [] };
1343
1096
  function upsertPrompt(prompts, req) {
@@ -2053,7 +1806,6 @@ function migrateActiveStream(oldUserId, newUserId) {
2053
1806
 
2054
1807
  exports.UserActionStaleError = UserActionStaleError;
2055
1808
  exports.buildContent = buildContent;
2056
- exports.buildFormattedThinking = buildFormattedThinking;
2057
1809
  exports.cancelUserAction = cancelUserAction;
2058
1810
  exports.classifyField = classifyField;
2059
1811
  exports.classifyUserActionKind = classifyUserActionKind;