@agent-native/core 0.77.6 → 0.77.7

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.
Files changed (159) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +12 -0
  3. package/corpus/core/package.json +3 -3
  4. package/corpus/core/src/agent/thread-data-builder.ts +21 -2
  5. package/corpus/core/src/cli/create.ts +35 -1
  6. package/corpus/core/src/cli/skills.ts +8 -0
  7. package/corpus/core/src/client/AgentPanel.tsx +57 -25
  8. package/corpus/core/src/client/MultiTabAssistantChat.tsx +31 -1
  9. package/corpus/core/src/client/analytics.ts +24 -2
  10. package/corpus/core/src/client/use-agent-engine-configured.ts +29 -15
  11. package/corpus/core/src/client/use-chat-threads.ts +104 -55
  12. package/corpus/core/src/server/analytics.ts +27 -3
  13. package/corpus/core/src/sharing/access.ts +35 -13
  14. package/corpus/core/src/sharing/actions/share-resource.ts +32 -9
  15. package/corpus/core/src/sharing/actions/unshare-resource.ts +25 -2
  16. package/corpus/core/src/sharing/registry.ts +9 -0
  17. package/corpus/core/src/vite/client.ts +3 -0
  18. package/corpus/templates/analytics/actions/data-source-status.ts +25 -14
  19. package/corpus/templates/analytics/app/components/layout/NewAnalysisDialog.tsx +2 -2
  20. package/corpus/templates/analytics/app/lib/data-source-status.ts +47 -6
  21. package/corpus/templates/analytics/app/lib/data-sources.ts +14 -3
  22. package/corpus/templates/analytics/app/pages/DataSources.tsx +24 -5
  23. package/corpus/templates/analytics/app/pages/adhoc/sql-dashboard/PanelEditorDialog.tsx +15 -43
  24. package/corpus/templates/analytics/changelog/2026-06-25-fixed-hubspot-data-source-status-so-private-app-tokens-legac.md +6 -0
  25. package/corpus/templates/analytics/netlify.toml +1 -0
  26. package/corpus/templates/analytics/server/lib/credential-keys.ts +3 -1
  27. package/corpus/templates/analytics/server/routes/api/test-connection.post.ts +12 -3
  28. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +5 -2
  29. package/corpus/templates/assets/changelog/2026-06-25-create-now-returns-from-agent-settings-to-the-asset-chat-eve.md +6 -0
  30. package/corpus/templates/assets/netlify.toml +1 -0
  31. package/corpus/templates/brain/netlify.toml +1 -0
  32. package/corpus/templates/calendar/app/i18n-data.ts +12 -0
  33. package/corpus/templates/calendar/app/lib/clipboard.ts +58 -0
  34. package/corpus/templates/calendar/app/pages/AvailabilitySettings.tsx +15 -9
  35. package/corpus/templates/calendar/app/pages/BookingLinksPage.tsx +6 -2
  36. package/corpus/templates/calendar/changelog/2026-06-25-booking-link-copy-buttons-no-longer-fail-when-clipboard-perm.md +6 -0
  37. package/corpus/templates/calendar/netlify.toml +1 -0
  38. package/corpus/templates/chat/netlify.toml +1 -0
  39. package/corpus/templates/clips/AGENTS.md +9 -7
  40. package/corpus/templates/clips/actions/add-vocabulary-term.ts +2 -2
  41. package/corpus/templates/clips/actions/archive-recording.ts +5 -2
  42. package/corpus/templates/clips/actions/clear-edits.ts +5 -2
  43. package/corpus/templates/clips/actions/create-folder.ts +7 -2
  44. package/corpus/templates/clips/actions/delete-folder.ts +7 -4
  45. package/corpus/templates/clips/actions/delete-recording-permanent.ts +5 -2
  46. package/corpus/templates/clips/actions/finalize-recording.ts +5 -2
  47. package/corpus/templates/clips/actions/import-loom-recording.ts +2 -1
  48. package/corpus/templates/clips/actions/list-notifications.ts +9 -5
  49. package/corpus/templates/clips/actions/list-organization-state.ts +2 -1
  50. package/corpus/templates/clips/actions/list-recordings.ts +4 -1
  51. package/corpus/templates/clips/actions/move-recording.ts +5 -1
  52. package/corpus/templates/clips/actions/rename-folder.ts +6 -3
  53. package/corpus/templates/clips/actions/request-transcript.ts +5 -2
  54. package/corpus/templates/clips/actions/restore-recording.ts +5 -2
  55. package/corpus/templates/clips/actions/save-browser-diagnostics.ts +21 -8
  56. package/corpus/templates/clips/actions/set-chapters.ts +5 -2
  57. package/corpus/templates/clips/actions/set-thumbnail.ts +5 -2
  58. package/corpus/templates/clips/actions/split-recording.ts +5 -2
  59. package/corpus/templates/clips/actions/stitch-recordings.ts +6 -2
  60. package/corpus/templates/clips/actions/trash-recording.ts +5 -2
  61. package/corpus/templates/clips/actions/undo-edit.ts +5 -2
  62. package/corpus/templates/clips/actions/view-screen.ts +2 -1
  63. package/corpus/templates/clips/app/components/library/recording-card.tsx +24 -7
  64. package/corpus/templates/clips/app/lib/browser-diagnostics-capture.ts +5 -1
  65. package/corpus/templates/clips/changelog/2026-06-25-chrome-extension-recordings-now-upload-large-capture-bursts.md +6 -0
  66. package/corpus/templates/clips/changelog/2026-06-25-console-diagnostics-keep-more-useful-non-secret-details-when.md +6 -0
  67. package/corpus/templates/clips/changelog/2026-06-25-fixed-owner-recognition-so-clips-created-from-desktop-and-we.md +6 -0
  68. package/corpus/templates/clips/chrome-extension/package.json +3 -0
  69. package/corpus/templates/clips/chrome-extension/public/manifest.json +1 -1
  70. package/corpus/templates/clips/chrome-extension/src/background.ts +85 -9
  71. package/corpus/templates/clips/chrome-extension/src/content-script.ts +55 -0
  72. package/corpus/templates/clips/chrome-extension/src/offscreen.ts +79 -3
  73. package/corpus/templates/clips/chrome-extension/src/options.ts +10 -0
  74. package/corpus/templates/clips/chrome-extension/src/overlay.ts +6 -0
  75. package/corpus/templates/clips/chrome-extension/src/permission.ts +8 -1
  76. package/corpus/templates/clips/chrome-extension/src/popup.ts +65 -39
  77. package/corpus/templates/clips/chrome-extension/src/sentry.ts +206 -0
  78. package/corpus/templates/clips/chrome-extension/vite.config.ts +47 -0
  79. package/corpus/templates/clips/netlify.toml +1 -0
  80. package/corpus/templates/clips/server/db/index.ts +1 -0
  81. package/corpus/templates/clips/server/lib/google-calendar-oauth.ts +35 -23
  82. package/corpus/templates/clips/server/lib/public-agent-context.ts +8 -1
  83. package/corpus/templates/clips/server/lib/recordings.ts +18 -2
  84. package/corpus/templates/clips/server/lib/slack-oauth.ts +9 -6
  85. package/corpus/templates/clips/server/plugins/onboarding-calendar.ts +6 -2
  86. package/corpus/templates/clips/server/routes/api/public-recording.get.ts +2 -2
  87. package/corpus/templates/clips/server/routes/api/recordings/[recordingId]/thumbnail.post.ts +5 -2
  88. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/abort.post.ts +5 -2
  89. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/chunk.post.ts +5 -2
  90. package/corpus/templates/clips/server/routes/api/uploads/[recordingId]/reset-chunks.post.ts +5 -2
  91. package/corpus/templates/clips/shared/browser-diagnostics.ts +14 -4
  92. package/corpus/templates/content/netlify.toml +1 -0
  93. package/corpus/templates/design/netlify.toml +1 -0
  94. package/corpus/templates/dispatch/netlify.toml +1 -0
  95. package/corpus/templates/forms/netlify.toml +1 -0
  96. package/corpus/templates/macros/netlify.toml +1 -0
  97. package/corpus/templates/mail/app/components/email/EmailList.tsx +7 -3
  98. package/corpus/templates/mail/app/components/email/EmailThread.tsx +4 -1
  99. package/corpus/templates/mail/app/components/layout/AppLayout.tsx +10 -2
  100. package/corpus/templates/mail/app/hooks/use-compose-state.ts +15 -5
  101. package/corpus/templates/mail/app/hooks/use-google-auth.ts +47 -9
  102. package/corpus/templates/mail/changelog/2026-06-25-account-avatars-stay-stable-while-mail-refreshes-google-acco.md +6 -0
  103. package/corpus/templates/mail/changelog/2026-06-25-mail-background-draft-saves-and-thread-prefetches-no-longer.md +6 -0
  104. package/corpus/templates/mail/netlify.toml +1 -0
  105. package/corpus/templates/plan/.agents/skills/visual-plan/references/canvas.md +8 -0
  106. package/corpus/templates/plan/netlify.toml +1 -0
  107. package/corpus/templates/slides/netlify.toml +1 -0
  108. package/corpus/templates/videos/netlify.toml +1 -0
  109. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  110. package/dist/agent/thread-data-builder.js +23 -2
  111. package/dist/agent/thread-data-builder.js.map +1 -1
  112. package/dist/cli/create.d.ts.map +1 -1
  113. package/dist/cli/create.js +28 -1
  114. package/dist/cli/create.js.map +1 -1
  115. package/dist/cli/skills.d.ts +1 -1
  116. package/dist/cli/skills.d.ts.map +1 -1
  117. package/dist/cli/skills.js +8 -0
  118. package/dist/cli/skills.js.map +1 -1
  119. package/dist/client/AgentPanel.d.ts +8 -2
  120. package/dist/client/AgentPanel.d.ts.map +1 -1
  121. package/dist/client/AgentPanel.js +29 -15
  122. package/dist/client/AgentPanel.js.map +1 -1
  123. package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
  124. package/dist/client/MultiTabAssistantChat.js +4 -4
  125. package/dist/client/MultiTabAssistantChat.js.map +1 -1
  126. package/dist/client/analytics.d.ts.map +1 -1
  127. package/dist/client/analytics.js +22 -2
  128. package/dist/client/analytics.js.map +1 -1
  129. package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
  130. package/dist/client/use-agent-engine-configured.js +23 -13
  131. package/dist/client/use-agent-engine-configured.js.map +1 -1
  132. package/dist/client/use-chat-threads.d.ts +4 -0
  133. package/dist/client/use-chat-threads.d.ts.map +1 -1
  134. package/dist/client/use-chat-threads.js +49 -4
  135. package/dist/client/use-chat-threads.js.map +1 -1
  136. package/dist/collab/routes.d.ts +2 -2
  137. package/dist/notifications/routes.d.ts +1 -1
  138. package/dist/observability/routes.d.ts +5 -5
  139. package/dist/resources/handlers.d.ts +2 -2
  140. package/dist/server/agent-engine-api-key-route.d.ts +2 -2
  141. package/dist/server/analytics.d.ts +4 -0
  142. package/dist/server/analytics.d.ts.map +1 -1
  143. package/dist/server/analytics.js +19 -3
  144. package/dist/server/analytics.js.map +1 -1
  145. package/dist/server/transcribe-voice.d.ts +1 -1
  146. package/dist/sharing/access.d.ts.map +1 -1
  147. package/dist/sharing/access.js +26 -12
  148. package/dist/sharing/access.js.map +1 -1
  149. package/dist/sharing/actions/share-resource.js +20 -9
  150. package/dist/sharing/actions/share-resource.js.map +1 -1
  151. package/dist/sharing/actions/unshare-resource.js +13 -2
  152. package/dist/sharing/actions/unshare-resource.js.map +1 -1
  153. package/dist/sharing/registry.d.ts +9 -0
  154. package/dist/sharing/registry.d.ts.map +1 -1
  155. package/dist/sharing/registry.js.map +1 -1
  156. package/dist/vite/client.d.ts.map +1 -1
  157. package/dist/vite/client.js +1 -0
  158. package/dist/vite/client.js.map +1 -1
  159. package/package.json +3 -3
@@ -5,5 +5,6 @@ publish = "templates/macros/dist"
5
5
  functions = "templates/macros/.netlify/functions-internal"
6
6
 
7
7
  [build.environment]
8
+ GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
8
9
  NITRO_PRESET = "netlify"
9
10
  NPM_CONFIG_PRODUCTION = "false"
@@ -569,7 +569,9 @@ export function EmailList({
569
569
  // Enter on a single focused row is a single-thread action — clear any
570
570
  // in-progress multi-selection so shortcuts in detail view start fresh.
571
571
  setSelectedIds(new Set());
572
- void ensureThread(targetThreadId, thread.latestMessage.accountEmail);
572
+ void ensureThread(targetThreadId, thread.latestMessage.accountEmail).catch(
573
+ () => {},
574
+ );
573
575
  onNavigateThread?.(targetThreadId);
574
576
  navigate(`/${view}/${targetThreadId}${routeSearchSuffix}`);
575
577
  if (thread.hasUnread) {
@@ -618,7 +620,9 @@ export function EmailList({
618
620
  // instant down the list.
619
621
  const nextTid =
620
622
  nextThread.latestMessage.threadId || nextThread.latestMessage.id;
621
- void ensureThread(nextTid, nextThread.latestMessage.accountEmail);
623
+ void ensureThread(nextTid, nextThread.latestMessage.accountEmail).catch(
624
+ () => {},
625
+ );
622
626
  } else {
623
627
  setFocusedId(null);
624
628
  }
@@ -1065,7 +1069,7 @@ export function EmailList({
1065
1069
  onDraftOpen(email);
1066
1070
  return;
1067
1071
  }
1068
- void ensureThread(targetThreadId, email.accountEmail);
1072
+ void ensureThread(targetThreadId, email.accountEmail).catch(() => {});
1069
1073
  onNavigateThread?.(targetThreadId);
1070
1074
  navigate(`/${view}/${targetThreadId}${routeSearchSuffix}`);
1071
1075
  if (thread.hasUnread) {
@@ -408,7 +408,10 @@ export function EmailThread({
408
408
  (t.latestMessage.threadId || t.latestMessage.id) === nextThreadId,
409
409
  );
410
410
  setSelectedIds?.(new Set());
411
- void ensureThread(nextThreadId, nextThread?.latestMessage.accountEmail);
411
+ void ensureThread(
412
+ nextThreadId,
413
+ nextThread?.latestMessage.accountEmail,
414
+ ).catch(() => {});
412
415
  onNavigateThread?.(nextThreadId);
413
416
  navigate(`/${view}/${nextThreadId}${routeSearchSuffix}`);
414
417
  },
@@ -99,13 +99,21 @@ function AccountAvatar({
99
99
  fallbackClassName: string;
100
100
  }) {
101
101
  const [imageFailed, setImageFailed] = useState(false);
102
+ const [stablePhotoUrl, setStablePhotoUrl] = useState(photoUrl ?? null);
103
+
104
+ useEffect(() => {
105
+ if (!photoUrl || photoUrl === stablePhotoUrl) return;
106
+ setStablePhotoUrl(photoUrl);
107
+ setImageFailed(false);
108
+ }, [photoUrl, stablePhotoUrl]);
109
+
102
110
  const shouldLoadRemoteAvatar =
103
- !!photoUrl && !isMcpEmbedSurface() && !imageFailed;
111
+ !!stablePhotoUrl && !isMcpEmbedSurface() && !imageFailed;
104
112
 
105
113
  if (shouldLoadRemoteAvatar) {
106
114
  return (
107
115
  <img
108
- src={photoUrl}
116
+ src={stablePhotoUrl}
109
117
  alt=""
110
118
  className={imageClassName}
111
119
  referrerPolicy="no-referrer"
@@ -80,6 +80,16 @@ async function saveDraftToEmails(
80
80
  return result?.draftId;
81
81
  }
82
82
 
83
+ export async function saveDraftToEmailsBestEffort(
84
+ draft: ComposeState,
85
+ ): Promise<string | undefined> {
86
+ try {
87
+ return await saveDraftToEmails(draft);
88
+ } catch {
89
+ return undefined;
90
+ }
91
+ }
92
+
83
93
  export function useComposeState() {
84
94
  const qc = useQueryClient();
85
95
  const [activeId, setActiveId] = useState<string | null>(null);
@@ -225,7 +235,7 @@ export function useComposeState() {
225
235
  ).find((d) => d.id === id);
226
236
  if (!current || !hasDraftContent(current)) return;
227
237
 
228
- saveDraftToEmails(current).then((draftId) => {
238
+ void saveDraftToEmailsBestEffort(current).then((draftId) => {
229
239
  if (draftId && draftId !== current.savedDraftId) {
230
240
  // Store the Gmail draft ID back so subsequent saves update rather than create
231
241
  qc.setQueryData<ComposeState[]>(["compose-drafts"], (old) =>
@@ -306,8 +316,8 @@ export function useComposeState() {
306
316
 
307
317
  // Auto-save to persistent drafts if there's any content
308
318
  if (draft && hasDraftContent(draft)) {
309
- saveDraftToEmails(draft).then(() => {
310
- qc.invalidateQueries({ queryKey: ["emails"] });
319
+ void saveDraftToEmailsBestEffort(draft).then((draftId) => {
320
+ if (draftId) qc.invalidateQueries({ queryKey: ["emails"] });
311
321
  });
312
322
  }
313
323
 
@@ -377,8 +387,8 @@ export function useComposeState() {
377
387
  // Save all drafts with content
378
388
  for (const draft of currentDrafts) {
379
389
  if (hasDraftContent(draft)) {
380
- saveDraftToEmails(draft).then(() => {
381
- qc.invalidateQueries({ queryKey: ["emails"] });
390
+ void saveDraftToEmailsBestEffort(draft).then((draftId) => {
391
+ if (draftId) qc.invalidateQueries({ queryKey: ["emails"] });
382
392
  });
383
393
  }
384
394
  }
@@ -2,14 +2,50 @@ import { agentNativePath, oauthRedirectUri } from "@agent-native/core/client";
2
2
  import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
3
3
  import { useEffect } from "react";
4
4
 
5
- interface GoogleAuthStatus {
5
+ export interface GoogleAuthAccount {
6
+ email: string;
7
+ displayName?: string;
8
+ expiresAt?: string;
9
+ photoUrl?: string;
10
+ }
11
+
12
+ export interface GoogleAuthStatus {
6
13
  connected: boolean;
7
- accounts: Array<{
8
- email: string;
9
- displayName?: string;
10
- expiresAt?: string;
11
- photoUrl?: string;
12
- }>;
14
+ accounts: GoogleAuthAccount[];
15
+ }
16
+
17
+ const stablePhotoUrls = new Map<string, string>();
18
+
19
+ export function mergeStableGoogleAuthStatus(
20
+ status: GoogleAuthStatus,
21
+ photoCache: Map<string, string> = stablePhotoUrls,
22
+ ): GoogleAuthStatus {
23
+ if (!status.connected || status.accounts.length === 0) {
24
+ photoCache.clear();
25
+ return status;
26
+ }
27
+
28
+ const accountEmails = new Set(
29
+ status.accounts.map((account) => account.email),
30
+ );
31
+ for (const email of photoCache.keys()) {
32
+ if (!accountEmails.has(email)) photoCache.delete(email);
33
+ }
34
+
35
+ let changed = false;
36
+ const accounts = status.accounts.map((account) => {
37
+ if (account.photoUrl) {
38
+ photoCache.set(account.email, account.photoUrl);
39
+ return account;
40
+ }
41
+
42
+ const cachedPhotoUrl = photoCache.get(account.email);
43
+ if (!cachedPhotoUrl) return account;
44
+ changed = true;
45
+ return { ...account, photoUrl: cachedPhotoUrl };
46
+ });
47
+
48
+ return changed ? { ...status, accounts } : status;
13
49
  }
14
50
 
15
51
  /**
@@ -86,8 +122,10 @@ export function useGoogleAuthStatus() {
86
122
  return useQuery<GoogleAuthStatus>({
87
123
  queryKey: ["google-status"],
88
124
  queryFn: async () => {
89
- return fetchJson<GoogleAuthStatus>(
90
- agentNativePath("/_agent-native/google/status"),
125
+ return mergeStableGoogleAuthStatus(
126
+ await fetchJson<GoogleAuthStatus>(
127
+ agentNativePath("/_agent-native/google/status"),
128
+ ),
91
129
  );
92
130
  },
93
131
  });
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-25
4
+ ---
5
+
6
+ Account avatars stay stable while Mail refreshes Google account status.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-25
4
+ ---
5
+
6
+ Background draft saves and thread prefetches no longer show as inbox crashes when Gmail returns a transient error.
@@ -5,6 +5,7 @@ publish = "templates/mail/dist"
5
5
  functions = "templates/mail/.netlify/functions-internal"
6
6
 
7
7
  [build.environment]
8
+ GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
8
9
  NITRO_PRESET = "netlify"
9
10
  NPM_CONFIG_PRODUCTION = "false"
10
11
 
@@ -26,6 +26,14 @@ or cross either artboard, remove the label and explain the transition with a
26
26
  nearby annotation instead. Before handoff, inspect the top canvas at default zoom
27
27
  and move any frame whose label, connector, or annotation crosses another frame.
28
28
 
29
+ **Board-unit spacing defaults.** The canvas coordinate system uses approximately 2 board units per screen pixel. `browser` frames occupy roughly 700 × 600 board units; `desktop` frames roughly 900 × 700 board units. Apply these minimum x/y gaps when placing frames explicitly — any less and frames will touch or overlap:
30
+
31
+ - x-gap between `browser` frames: **≥ 1100** (700-unit frame + 400-unit gutter)
32
+ - x-gap between `desktop` frames: **≥ 1300** (900-unit frame + 400-unit gutter)
33
+ - y-gap between rows of any surface: **≥ 1400** (includes frame height + section header + buffer)
34
+
35
+ When in doubt, use larger values — the canvas auto-zooms to fit everything.
36
+
29
37
  **Canvas annotations are designer notes on the artboard.** When a top canvas is
30
38
  present, sprinkle Figma-style notes near the frames they explain: a short
31
39
  heading, supporting text, and bullets — plain text layers, never bordered or
@@ -5,6 +5,7 @@ publish = "templates/plan/dist"
5
5
  functions = "templates/plan/.netlify/functions-internal"
6
6
 
7
7
  [build.environment]
8
+ GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
8
9
  NITRO_PRESET = "netlify"
9
10
  NPM_CONFIG_PRODUCTION = "false"
10
11
 
@@ -5,6 +5,7 @@ publish = "templates/slides/dist"
5
5
  functions = "templates/slides/.netlify/functions-internal"
6
6
 
7
7
  [build.environment]
8
+ GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
8
9
  NITRO_PRESET = "netlify"
9
10
  NPM_CONFIG_PRODUCTION = "false"
10
11
 
@@ -5,6 +5,7 @@ publish = "templates/videos/dist"
5
5
  functions = "templates/videos/.netlify/functions-internal"
6
6
 
7
7
  [build.environment]
8
+ GA_MEASUREMENT_ID = "G-ESF7FYXGN9"
8
9
  NITRO_PRESET = "netlify"
9
10
  NPM_CONFIG_PRODUCTION = "false"
10
11
 
@@ -1 +1 @@
1
- {"version":3,"file":"thread-data-builder.d.ts","sourceRoot":"","sources":["../../src/agent/thread-data-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"thread-data-builder.d.ts","sourceRoot":"","sources":["../../src/agent/thread-data-builder.ts"],"names":[],"mappings":"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"}
@@ -387,11 +387,32 @@ function normalizeAssistantToolCallIds(message) {
387
387
  */
388
388
  export function normalizeThreadRepository(repo) {
389
389
  const normalized = repo && typeof repo === "object" ? { ...repo } : {};
390
- const sourceMessages = Array.isArray(repo?.messages) ? repo.messages : [];
390
+ const sourceMessages = Array.isArray(repo?.messages)
391
+ ? repo.messages
392
+ : [];
393
+ const firstIndexById = new Map();
394
+ const lastEntryById = new Map();
395
+ sourceMessages.forEach((entry, index) => {
396
+ const id = messageId(getStoredMessage(entry));
397
+ if (!id)
398
+ return;
399
+ if (!firstIndexById.has(id))
400
+ firstIndexById.set(id, index);
401
+ lastEntryById.set(id, entry);
402
+ });
403
+ const uniqueSourceMessages = sourceMessages
404
+ .filter((entry, index) => {
405
+ const id = messageId(getStoredMessage(entry));
406
+ return id && firstIndexById.get(id) === index;
407
+ })
408
+ .map((entry) => {
409
+ const id = messageId(getStoredMessage(entry));
410
+ return (id && lastEntryById.get(id)) || entry;
411
+ });
391
412
  const messages = [];
392
413
  const seenIds = new Set();
393
414
  let previousId = null;
394
- for (const entry of sourceMessages) {
415
+ for (const entry of uniqueSourceMessages) {
395
416
  const message = getStoredMessage(entry);
396
417
  const id = messageId(message);
397
418
  if (!id)