@widgetic/chat 0.1.4 → 0.1.6

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.
@@ -76,11 +76,14 @@
76
76
  return /^Updated \d+ files?/i.test(trimmed) && /\n\nCommit\s+[a-f0-9]{7,40}/i.test(trimmed);
77
77
  }
78
78
 
79
- /** Codegen completion with commit not preview-rebuild status lines. */
79
+ /** Codegen completion or preview-recompiled bubble that carries a commit hash. */
80
80
  function messageHasCommit(message: ChatMessage): boolean {
81
- if (!message.messageContent || isPreviewRecompiledMessage(message)) return false;
81
+ if (!message.messageContent) return false;
82
82
  const trimmed = message.messageContent.trim();
83
83
  if (isCodegenFailure(message)) return false;
84
+ if (isPreviewRecompiledMessage(message) && /commit:?\s+[a-f0-9]{7,40}/i.test(trimmed)) {
85
+ return true;
86
+ }
84
87
  if (/^Code generation completed/i.test(trimmed) && /Commit:?\s+[a-f0-9]{7,40}/i.test(trimmed)) {
85
88
  return true;
86
89
  }
@@ -152,9 +155,15 @@
152
155
  }
153
156
 
154
157
  function isCodegenFailure(message: ChatMessage): boolean {
155
- return message.messageType === 'assistant'
156
- && !!message.messageContent
157
- && /^Code generation failed/i.test(message.messageContent.trim());
158
+ if (message.messageType !== 'assistant' || !message.messageContent) return false;
159
+ const trimmed = message.messageContent.trim();
160
+ return (
161
+ /^Code generation failed/i.test(trimmed) ||
162
+ /^⚠️/.test(trimmed) ||
163
+ /Too many generation requests/i.test(trimmed) ||
164
+ /temporarily unavailable/i.test(trimmed) ||
165
+ /Generation Failed/i.test(trimmed)
166
+ );
158
167
  }
159
168
 
160
169
  function canRestoreToMessage(message: ChatMessage): boolean {
@@ -197,6 +206,10 @@
197
206
  * Previously this was gated to Debug OFF (assistant reply hidden), but we want the buttons
198
207
  * available in Debug ON too — the assistant summary and the user-side chrome coexist. */
199
208
  function showCommitMetaOnUserTurn(turn: ChatTurn): boolean {
209
+ const visibleHead = turn.replies.some(
210
+ (r) => r.isWidgetHead && shouldShowAssistantReply(r) && messageHasCommit(r),
211
+ );
212
+ if (visibleHead) return false;
200
213
  return !!getTurnCommitReply(turn);
201
214
  }
202
215
 
@@ -225,8 +238,18 @@
225
238
  chatTurns = rebalancePreviewRecompiledAcrossTurns(turns);
226
239
  });
227
240
 
228
- function messageImpliesAttachedImage(content: string): boolean {
229
- return /imaginea ata[sș]at[ăa]|attached (reference )?image|reference image|din imagine/i.test(content);
241
+ function messageImpliesAttachedFile(content: string): boolean {
242
+ return /imaginea ata[sș]at[ăa]|attached (reference )?(image|document|file|pdf|video)|reference image|din imagine|ata[sș]at[ăa]?\s+(document|pdf|fi[sș]ier|video)|attached document/i.test(
243
+ content,
244
+ );
245
+ }
246
+
247
+ function turnNeedsRetry(turn: ChatTurn): boolean {
248
+ if (turnHasCodegenFailure(turn)) return true;
249
+ const userMsg = turn.user;
250
+ if (!userMsg?.messageContent) return false;
251
+ const noAttachments = !userMsg.attachments || userMsg.attachments.length === 0;
252
+ return noAttachments && messageImpliesAttachedFile(userMsg.messageContent) && !getTurnCommitReply(turn);
230
253
  }
231
254
 
232
255
  let visibleMessages = $derived(
@@ -296,8 +319,23 @@
296
319
  }
297
320
  }
298
321
 
299
- function handleRetryTurn(turn: ChatTurn) {
300
- const retryContent = turn.user?.messageContent?.trim();
322
+ function getRetryPromptForTurn(turn: ChatTurn, turnIndex: number): string | null {
323
+ const own = turn.user?.messageContent?.trim();
324
+ if (own) return own;
325
+ for (let i = turnIndex - 1; i >= 0; i--) {
326
+ const previous = chatTurns[i]?.user?.messageContent?.trim();
327
+ if (previous) return previous;
328
+ }
329
+ return null;
330
+ }
331
+
332
+ function isLastCodegenFailureInTurn(turn: ChatTurn, reply: ChatMessage): boolean {
333
+ const failures = turn.replies.filter(isCodegenFailure);
334
+ return failures.length > 0 && failures[failures.length - 1]?.id === reply.id;
335
+ }
336
+
337
+ function handleRetryTurn(turn: ChatTurn, turnIndex: number) {
338
+ const retryContent = getRetryPromptForTurn(turn, turnIndex);
301
339
  if (!retryContent) return;
302
340
  chatLog('Retry requested for failed codegen turn:', retryContent.slice(0, 80));
303
341
  onRetryMessage?.(retryContent);
@@ -613,18 +651,33 @@
613
651
  <div class="message-attachments-container">
614
652
  <AttachmentDisplay attachments={userMsg.attachments} variant="message" showPreview={true} />
615
653
  </div>
616
- {:else if userMsg.messageContent && messageImpliesAttachedImage(userMsg.messageContent)}
654
+ {:else if userMsg.messageContent && messageImpliesAttachedFile(userMsg.messageContent)}
617
655
  <div class="wc-missing-attachment-placeholder message-attachments-container flex flex-col items-center gap-1 px-3 pb-3">
618
- <div class="wc-missing-attachment-thumb flex h-20 w-28 flex-col items-center justify-center gap-1 rounded-md border border-dashed border-gray-300 bg-gray-100 text-gray-400" title="Image not available" aria-label="Missing image attachment">
656
+ <div class="wc-missing-attachment-thumb flex h-20 w-28 flex-col items-center justify-center gap-1 rounded-md border border-dashed border-gray-300 bg-gray-100 text-gray-400" title="Attachment not available" aria-label="Missing file attachment">
619
657
  <svg class="h-8 w-8 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
620
658
  <rect x="3" y="5" width="18" height="14" rx="2" />
621
659
  <path d="M4 4l16 16" stroke-linecap="round" />
622
660
  </svg>
623
661
  </div>
624
- <p class="wc-missing-attachment-caption max-w-[12rem] text-center text-xs text-gray-500">Image not saved in chat history. Re-attach with Upload before Send.</p>
662
+ <p class="wc-missing-attachment-caption max-w-[12rem] text-center text-xs text-gray-500">Attachment not saved. Re-attach with Upload, then Retry.</p>
625
663
  </div>
626
664
  {/if}
627
665
  </div>
666
+ {#if turnNeedsRetry(turn) && !isLoading}
667
+ <div class="retry-codegen-row flex justify-end mt-1">
668
+ <button
669
+ class="retry-codegen-btn"
670
+ onclick={() => handleRetryTurn(turn, turnIndex)}
671
+ title="Retry this prompt (same as Retry on the error below)"
672
+ >
673
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
674
+ <path d="M21 12a9 9 0 1 1-2.64-6.36"/>
675
+ <path d="M21 3v6h-6"/>
676
+ </svg>
677
+ Retry
678
+ </button>
679
+ </div>
680
+ {/if}
628
681
  </div>
629
682
 
630
683
  {@const commitReply = getTurnCommitReply(turn)}
@@ -709,12 +762,12 @@
709
762
  </div>
710
763
  {/if}
711
764
 
712
- {#if isCodegenFailure(reply) && turn.user && !isLoading}
765
+ {#if isCodegenFailure(reply) && isLastCodegenFailureInTurn(turn, reply) && getRetryPromptForTurn(turn, turnIndex) && !isLoading}
713
766
  <div class="retry-codegen-row flex justify-start mt-1">
714
767
  <button
715
768
  class="retry-codegen-btn"
716
- onclick={() => handleRetryTurn(turn)}
717
- title="Retry this code generation prompt"
769
+ onclick={() => handleRetryTurn(turn, turnIndex)}
770
+ title="Retry the last user prompt (same generation request)"
718
771
  >
719
772
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
720
773
  <path d="M21 12a9 9 0 1 1-2.64-6.36"/>
package/dist/config.js CHANGED
@@ -27,7 +27,7 @@ if (!env.PUBLIC_PRODUCTION_URL) {
27
27
  throw new Error('PUBLIC_PRODUCTION_URL environment variable is not set');
28
28
  }
29
29
  // Create and export the config object with proper typing
30
- export var config = {
30
+ export const config = {
31
31
  API_URL: env.PUBLIC_API_URL,
32
32
  API_VERSION: env.PUBLIC_API_VERSION,
33
33
  INTERNAL_KEY: env.PUBLIC_INTERNAL_KEY,
@@ -43,23 +43,23 @@ export var config = {
43
43
  */
44
44
  export function createSdkConfig(options) {
45
45
  return new Configuration({
46
- apiKey: function (name) { return (options === null || options === void 0 ? void 0 : options.apiKey) || config.API_KEY || config.INTERNAL_KEY || ''; },
47
- basePath: (options === null || options === void 0 ? void 0 : options.basePath) || getApiUrl()
46
+ apiKey: (name) => options?.apiKey || config.API_KEY || config.INTERNAL_KEY || '',
47
+ basePath: options?.basePath || getApiUrl()
48
48
  });
49
49
  }
50
50
  /**
51
51
  * Gets the full API URL for the current environment
52
52
  */
53
53
  export function getApiUrl() {
54
- var baseUrl = config.NODE_ENV === 'production'
54
+ const baseUrl = config.NODE_ENV === 'production'
55
55
  ? config.PRODUCTION_URL
56
56
  : config.API_URL;
57
- return "".concat(baseUrl).concat(config.API_VERSION);
57
+ return `${baseUrl}${config.API_VERSION}`;
58
58
  }
59
59
  /**
60
60
  * Environment-specific settings
61
61
  */
62
- export var environment = {
62
+ export const environment = {
63
63
  isProduction: config.NODE_ENV === 'production',
64
64
  apiUrl: getApiUrl(),
65
65
  // Use API_KEY if available, fall back to INTERNAL_KEY
@@ -2,7 +2,7 @@
2
2
  * Message background colors for different states
3
3
  * These can be easily modified to change the appearance of messages
4
4
  */
5
- export var MESSAGE_COLORS = {
5
+ export const MESSAGE_COLORS = {
6
6
  /** Background color for user messages in completed chats */
7
7
  USER_COMPLETED: '#C6FFD3', // Light green
8
8
  /** Background color for user messages in active (non-completed) chats */