@paymanai/payman-ask-sdk 1.2.11 → 1.2.12

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.d.mts CHANGED
@@ -31,7 +31,7 @@ type MessageDisplay = {
31
31
  content: string;
32
32
  timestamp: string;
33
33
  isError?: boolean;
34
- /** When set to "WORKFLOW_FAILED" or "STREAM_NOT_STARTED", the UI shows the friendly "Oops, something went wrong" message. Other errors (e.g. subintent failures) do not show it. */
34
+ /** "WORKFLOW_FAILED" and "STREAM_NOT_STARTED" show the friendly fallback; HTTP 409 conflicts render the backend message from the error payload. */
35
35
  errorDetails?: string;
36
36
  chunks?: ChunkDisplay[];
37
37
  tracingData?: unknown;
@@ -171,6 +171,8 @@ type ChatInputProps = {
171
171
  onChange: (value: string) => void;
172
172
  /** On send handler */
173
173
  onSend: () => void;
174
+ /** On pause/cancel handler */
175
+ onPause?: () => void;
174
176
  /** Disabled state */
175
177
  disabled?: boolean;
176
178
  /** Placeholder text */
@@ -337,7 +339,7 @@ type StreamingMessageProps = {
337
339
  currentMessage?: string;
338
340
  /** Stream progress */
339
341
  streamProgress: StreamProgress;
340
- /** When set to "WORKFLOW_FAILED" or "STREAM_NOT_STARTED", the UI shows the friendly error message. Other errors do not. */
342
+ /** "WORKFLOW_FAILED" and "STREAM_NOT_STARTED" show the friendly fallback; HTTP 409 conflicts render the backend message from the error payload. */
341
343
  error?: string;
342
344
  /** Streaming steps */
343
345
  steps?: StreamingStep[];
package/dist/index.d.ts CHANGED
@@ -31,7 +31,7 @@ type MessageDisplay = {
31
31
  content: string;
32
32
  timestamp: string;
33
33
  isError?: boolean;
34
- /** When set to "WORKFLOW_FAILED" or "STREAM_NOT_STARTED", the UI shows the friendly "Oops, something went wrong" message. Other errors (e.g. subintent failures) do not show it. */
34
+ /** "WORKFLOW_FAILED" and "STREAM_NOT_STARTED" show the friendly fallback; HTTP 409 conflicts render the backend message from the error payload. */
35
35
  errorDetails?: string;
36
36
  chunks?: ChunkDisplay[];
37
37
  tracingData?: unknown;
@@ -171,6 +171,8 @@ type ChatInputProps = {
171
171
  onChange: (value: string) => void;
172
172
  /** On send handler */
173
173
  onSend: () => void;
174
+ /** On pause/cancel handler */
175
+ onPause?: () => void;
174
176
  /** Disabled state */
175
177
  disabled?: boolean;
176
178
  /** Placeholder text */
@@ -337,7 +339,7 @@ type StreamingMessageProps = {
337
339
  currentMessage?: string;
338
340
  /** Stream progress */
339
341
  streamProgress: StreamProgress;
340
- /** When set to "WORKFLOW_FAILED" or "STREAM_NOT_STARTED", the UI shows the friendly error message. Other errors do not. */
342
+ /** "WORKFLOW_FAILED" and "STREAM_NOT_STARTED" show the friendly fallback; HTTP 409 conflicts render the backend message from the error payload. */
341
343
  error?: string;
342
344
  /** Streaming steps */
343
345
  steps?: StreamingStep[];
package/dist/index.js CHANGED
@@ -62,6 +62,7 @@ function ChatInput({
62
62
  value,
63
63
  onChange,
64
64
  onSend,
65
+ onPause,
65
66
  disabled = false,
66
67
  placeholder = "Type your message...",
67
68
  isWaitingForResponse = false,
@@ -93,6 +94,7 @@ function ChatInput({
93
94
  }
94
95
  };
95
96
  const isInputDisabled = disabled || isWaitingForResponse;
97
+ const showPauseButton = isWaitingForResponse && onPause;
96
98
  const showVoiceButton = enableVoice && onVoicePress != null;
97
99
  const isVoiceButtonDisabled = isWaitingForResponse || !voiceAvailable || !isSessionParamsConfigured;
98
100
  const canSend = !isInputDisabled && !!value.trim();
@@ -173,7 +175,22 @@ function ChatInput({
173
175
  ]
174
176
  }
175
177
  ),
176
- /* @__PURE__ */ jsxRuntime.jsx(
178
+ showPauseButton ? /* @__PURE__ */ jsxRuntime.jsx(
179
+ "button",
180
+ {
181
+ type: "button",
182
+ onClick: onPause,
183
+ className: cn(
184
+ "flex items-center justify-center",
185
+ "w-8 h-8 rounded-full",
186
+ "payman-chat-input-btn-pause",
187
+ "hover:opacity-90 active:scale-95",
188
+ "transition-all duration-150"
189
+ ),
190
+ "aria-label": "Stop response",
191
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Square, { className: "w-3.5 h-3.5", fill: "currentColor" })
192
+ }
193
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
177
194
  "button",
178
195
  {
179
196
  type: "button",
@@ -197,6 +214,48 @@ function ChatInput({
197
214
  }
198
215
  );
199
216
  }
217
+
218
+ // src/utils/errorMessages.ts
219
+ var WORKFLOW_FAILED = "WORKFLOW_FAILED";
220
+ var STREAM_NOT_STARTED = "STREAM_NOT_STARTED";
221
+ var HTTP_ERROR_PREFIX = /^HTTP\s+(\d+)\s*:\s*([\s\S]+)$/;
222
+ function isFriendlyWorkflowError(errorDetails) {
223
+ if (!errorDetails) return false;
224
+ return errorDetails === WORKFLOW_FAILED || errorDetails === STREAM_NOT_STARTED || errorDetails.includes(WORKFLOW_FAILED);
225
+ }
226
+ function parseErrorPayload(payload) {
227
+ try {
228
+ const parsed = JSON.parse(payload);
229
+ if (typeof parsed === "string") {
230
+ return { message: parsed.trim() || void 0 };
231
+ }
232
+ if (typeof parsed === "object" && parsed !== null) {
233
+ const record = parsed;
234
+ return {
235
+ status: typeof record.status === "number" ? record.status : void 0,
236
+ message: typeof record.message === "string" && record.message.trim() ? record.message.trim() : void 0
237
+ };
238
+ }
239
+ } catch {
240
+ }
241
+ return {};
242
+ }
243
+ function getConflictErrorMessage(errorDetails) {
244
+ if (!errorDetails) return void 0;
245
+ const trimmedError = errorDetails.trim();
246
+ const httpMatch = trimmedError.match(HTTP_ERROR_PREFIX);
247
+ const httpStatus = httpMatch ? Number(httpMatch[1]) : void 0;
248
+ const rawPayload = (httpMatch ? httpMatch[2] : trimmedError).trim();
249
+ const payload = parseErrorPayload(rawPayload);
250
+ const status = payload.status ?? httpStatus;
251
+ if (status !== 409) {
252
+ return void 0;
253
+ }
254
+ if (payload.message) {
255
+ return payload.message;
256
+ }
257
+ return rawPayload || void 0;
258
+ }
200
259
  function ThinkingBlock({ text }) {
201
260
  const [isOpen, setIsOpen] = react.useState(false);
202
261
  const hasContent = typeof text === "string" && text.trim().length > 0;
@@ -238,12 +297,6 @@ function ThinkingBlock({ text }) {
238
297
  ] });
239
298
  }
240
299
  var FRIENDLY_ERROR_MESSAGE = "Oops, something went wrong. Please try again.";
241
- var WORKFLOW_FAILED = "WORKFLOW_FAILED";
242
- var STREAM_NOT_STARTED = "STREAM_NOT_STARTED";
243
- function isFriendlyError(errorDetails) {
244
- if (!errorDetails) return false;
245
- return errorDetails === WORKFLOW_FAILED || errorDetails === STREAM_NOT_STARTED || errorDetails.includes(WORKFLOW_FAILED);
246
- }
247
300
  function looksLikeRawError(text) {
248
301
  if (!text || text.length < 10) return false;
249
302
  return text.includes("errorType=") || /failed:\s*\{/.test(text);
@@ -283,7 +336,8 @@ function AgentMessage({
283
336
  const content = rawContent.replace(/\\n/g, "\n");
284
337
  const hasMeaningfulContent = content.length > 0 && !looksLikeRawError(content);
285
338
  const completedWithNoContent = !isStreaming && !isCancelled && content.length === 0 && (message.streamProgress === "completed" || message.streamProgress === "error");
286
- const isError = (isFriendlyError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
339
+ const conflictErrorMessage = getConflictErrorMessage(message.errorDetails);
340
+ const isError = !!conflictErrorMessage || (isFriendlyWorkflowError(message.errorDetails) || looksLikeRawError(content)) && !hasMeaningfulContent || completedWithNoContent;
287
341
  const activeThinkingText = message.activeThinkingText;
288
342
  const allThinkingText = message.allThinkingText;
289
343
  const currentStep = react.useMemo(
@@ -480,7 +534,7 @@ function AgentMessage({
480
534
  {
481
535
  remarkPlugins: [remarkGfm__default.default],
482
536
  components: markdownComponents(),
483
- children: isError ? FRIENDLY_ERROR_MESSAGE : content || (isStreaming ? "Thinking..." : isCancelled ? "Request was stopped." : "")
537
+ children: isError ? conflictErrorMessage ?? FRIENDLY_ERROR_MESSAGE : content || (isStreaming ? "Thinking..." : isCancelled ? "Request was stopped." : "")
484
538
  }
485
539
  )
486
540
  }
@@ -1556,6 +1610,7 @@ function PaymanChat({
1556
1610
  value: inputValue,
1557
1611
  onChange: setInputValue,
1558
1612
  onSend: handleSend,
1613
+ onPause: cancelStream,
1559
1614
  disabled: isInputDisabled,
1560
1615
  placeholder: isRecording ? "Listening..." : placeholder,
1561
1616
  isWaitingForResponse,