@copilotz/chat-adapter 0.1.17 → 0.1.19

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.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { ChatUserContext, ChatConfig, ChatCallbacks, MemoryItem, AgentOption, ChatMessage, ChatThread, MediaAttachment } from '@copilotz/chat-ui';
2
+ import { MediaAttachment, ChatUserContext, ChatConfig, ChatCallbacks, MemoryItem, AgentOption, ChatMessage, ChatThread } from '@copilotz/chat-ui';
3
3
  export { ChatCallbacks, ChatConfig, ChatMessage, ChatThread, ChatUserContext, MediaAttachment, MemoryItem } from '@copilotz/chat-ui';
4
4
 
5
5
  /**
@@ -105,9 +105,88 @@ type EventInterceptorResult = void | {
105
105
  type EventInterceptor = (event: unknown) => EventInterceptorResult;
106
106
  type RunErrorInterceptor = (error: unknown) => SpecialChatState | null | undefined;
107
107
 
108
+ type RequestHeadersProvider = () => Record<string, string> | Promise<Record<string, string>>;
109
+ type RestThread = {
110
+ id: string;
111
+ name?: string | null;
112
+ externalId?: string | null;
113
+ description?: string | null;
114
+ participants?: string[] | null;
115
+ status?: string | null;
116
+ metadata?: Record<string, unknown> | null;
117
+ createdAt?: string;
118
+ updatedAt?: string;
119
+ };
120
+ type RestMessage = {
121
+ id: string;
122
+ threadId: string;
123
+ senderId?: string | null;
124
+ senderType: string;
125
+ senderUserId?: string | null;
126
+ content?: string | null;
127
+ metadata?: Record<string, unknown> | null;
128
+ toolCalls?: Array<Record<string, unknown>> | null;
129
+ createdAt?: string;
130
+ updatedAt?: string;
131
+ };
132
+ type StreamCallbacks = {
133
+ onToken?: (token: string, isComplete: boolean, raw?: any) => void;
134
+ onMessageEvent?: (payload: any) => void;
135
+ onAssetEvent?: (payload: any) => void;
136
+ signal?: AbortSignal;
137
+ };
138
+ type RunOptions = {
139
+ threadId?: string;
140
+ threadExternalId?: string;
141
+ content: string;
142
+ user: {
143
+ externalId: string;
144
+ name?: string;
145
+ email?: string;
146
+ metadata?: Record<string, unknown>;
147
+ };
148
+ attachments?: MediaAttachment[];
149
+ metadata?: Record<string, unknown>;
150
+ threadMetadata?: Record<string, unknown>;
151
+ toolCalls?: Array<{
152
+ name: string;
153
+ args: Record<string, unknown>;
154
+ id?: string;
155
+ }>;
156
+ selectedAgent?: string | null;
157
+ getRequestHeaders?: RequestHeadersProvider;
158
+ } & StreamCallbacks;
159
+ type CopilotzStreamResult = {
160
+ text: string;
161
+ messages: any[];
162
+ media: Record<string, string> | null;
163
+ };
164
+ declare class CopilotzRequestError extends Error {
165
+ status: number;
166
+ code?: string;
167
+ details?: unknown;
168
+ constructor(message: string, options: {
169
+ status: number;
170
+ code?: string;
171
+ details?: unknown;
172
+ });
173
+ }
174
+ declare function runCopilotzStream(options: RunOptions): Promise<CopilotzStreamResult>;
175
+ declare function fetchThreads(userId: string, getRequestHeaders?: RequestHeadersProvider): Promise<RestThread[]>;
176
+ declare function fetchThreadMessages(threadId: string, getRequestHeaders?: RequestHeadersProvider): Promise<RestMessage[]>;
177
+ declare function updateThread(threadId: string, updates: Partial<RestThread>, getRequestHeaders?: RequestHeadersProvider): Promise<any>;
178
+ declare function deleteMessagesByThreadId(threadId: string, getRequestHeaders?: RequestHeadersProvider): Promise<void>;
179
+ declare function deleteThread(threadId: string, getRequestHeaders?: RequestHeadersProvider): Promise<boolean>;
180
+ declare const copilotzService: {
181
+ runCopilotzStream: typeof runCopilotzStream;
182
+ fetchThreads: typeof fetchThreads;
183
+ fetchThreadMessages: typeof fetchThreadMessages;
184
+ updateThread: typeof updateThread;
185
+ deleteThread: typeof deleteThread;
186
+ };
187
+
108
188
  interface CopilotzChatProps {
109
189
  userId: string;
110
- authToken?: string | null;
111
190
  userName?: string;
112
191
  userAvatar?: string;
113
192
  userEmail?: string;
@@ -150,6 +229,7 @@ interface CopilotzChatProps {
150
229
  agentOptions?: AgentOption[];
151
230
  selectedAgentId?: string | null;
152
231
  onSelectAgent?: (agentId: string) => void;
232
+ getRequestHeaders?: RequestHeadersProvider;
153
233
  className?: string;
154
234
  eventInterceptor?: EventInterceptor;
155
235
  runErrorInterceptor?: RunErrorInterceptor;
@@ -187,7 +267,6 @@ declare const CopilotzChat: React.FC<CopilotzChatProps>;
187
267
 
188
268
  interface UseCopilotzOptions {
189
269
  userId: string | null;
190
- authToken?: string | null;
191
270
  initialContext?: ChatUserContext;
192
271
  bootstrap?: {
193
272
  initialMessage?: string;
@@ -199,6 +278,7 @@ interface UseCopilotzOptions {
199
278
  defaultThreadName?: string;
200
279
  onToolOutput?: (output: Record<string, unknown>) => void;
201
280
  preferredAgentName?: string | null;
281
+ getRequestHeaders?: RequestHeadersProvider;
202
282
  eventInterceptor?: EventInterceptor;
203
283
  runErrorInterceptor?: RunErrorInterceptor;
204
284
  /**
@@ -219,7 +299,7 @@ interface UseCopilotzOptions {
219
299
  */
220
300
  urlSync?: UrlSyncConfig;
221
301
  }
222
- declare function useCopilotz({ userId, authToken, initialContext, bootstrap, defaultThreadName, onToolOutput, preferredAgentName, eventInterceptor, runErrorInterceptor, urlSync, }: UseCopilotzOptions): {
302
+ declare function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onToolOutput, preferredAgentName, getRequestHeaders, eventInterceptor, runErrorInterceptor, urlSync, }: UseCopilotzOptions): {
223
303
  messages: ChatMessage[];
224
304
  isMessagesLoading: boolean;
225
305
  threads: ChatThread[];
@@ -248,85 +328,6 @@ declare function useCopilotz({ userId, authToken, initialContext, bootstrap, def
248
328
  setUrlAgentId: (agentId: string | null) => void;
249
329
  };
250
330
 
251
- type RestThread = {
252
- id: string;
253
- name?: string | null;
254
- externalId?: string | null;
255
- description?: string | null;
256
- participants?: string[] | null;
257
- status?: string | null;
258
- metadata?: Record<string, unknown> | null;
259
- createdAt?: string;
260
- updatedAt?: string;
261
- };
262
- type RestMessage = {
263
- id: string;
264
- threadId: string;
265
- senderId?: string | null;
266
- senderType: string;
267
- senderUserId?: string | null;
268
- content?: string | null;
269
- metadata?: Record<string, unknown> | null;
270
- toolCalls?: Array<Record<string, unknown>> | null;
271
- createdAt?: string;
272
- updatedAt?: string;
273
- };
274
- type StreamCallbacks = {
275
- onToken?: (token: string, isComplete: boolean, raw?: any) => void;
276
- onMessageEvent?: (payload: any) => void;
277
- onAssetEvent?: (payload: any) => void;
278
- signal?: AbortSignal;
279
- };
280
- type RunOptions = {
281
- authToken?: string | null;
282
- threadId?: string;
283
- threadExternalId?: string;
284
- content: string;
285
- user: {
286
- externalId: string;
287
- name?: string;
288
- email?: string;
289
- metadata?: Record<string, unknown>;
290
- };
291
- attachments?: MediaAttachment[];
292
- metadata?: Record<string, unknown>;
293
- threadMetadata?: Record<string, unknown>;
294
- toolCalls?: Array<{
295
- name: string;
296
- args: Record<string, unknown>;
297
- id?: string;
298
- }>;
299
- selectedAgent?: string | null;
300
- } & StreamCallbacks;
301
- type CopilotzStreamResult = {
302
- text: string;
303
- messages: any[];
304
- media: Record<string, string> | null;
305
- };
306
- declare class CopilotzRequestError extends Error {
307
- status: number;
308
- code?: string;
309
- details?: unknown;
310
- constructor(message: string, options: {
311
- status: number;
312
- code?: string;
313
- details?: unknown;
314
- });
315
- }
316
- declare function runCopilotzStream(options: RunOptions): Promise<CopilotzStreamResult>;
317
- declare function fetchThreads(userId: string, authToken?: string | null): Promise<RestThread[]>;
318
- declare function fetchThreadMessages(threadId: string, authToken?: string | null): Promise<RestMessage[]>;
319
- declare function updateThread(threadId: string, updates: Partial<RestThread>, authToken?: string | null): Promise<any>;
320
- declare function deleteMessagesByThreadId(threadId: string, authToken?: string | null): Promise<void>;
321
- declare function deleteThread(threadId: string, authToken?: string | null): Promise<boolean>;
322
- declare const copilotzService: {
323
- runCopilotzStream: typeof runCopilotzStream;
324
- fetchThreads: typeof fetchThreads;
325
- fetchThreadMessages: typeof fetchThreadMessages;
326
- updateThread: typeof updateThread;
327
- deleteThread: typeof deleteThread;
328
- };
329
-
330
331
  declare function getAssetDataUrl(refOrId: string): Promise<{
331
332
  dataUrl: string;
332
333
  mime?: string;
@@ -337,4 +338,4 @@ type WithMetadata = {
337
338
  };
338
339
  declare function resolveAssetsInMessages<T extends WithMetadata>(messages: T[]): Promise<T[]>;
339
340
 
340
- export { CopilotzChat, CopilotzRequestError, type CopilotzStreamResult, type EventInterceptor, type EventInterceptorResult, type RenderSpecialState, type RunErrorInterceptor, type SpecialChatState, type SpecialStateControls, type UrlParamsConfig, type UrlState, type UrlSyncConfig, type UseUrlStateReturn, copilotzService, deleteMessagesByThreadId, deleteThread, fetchThreadMessages, fetchThreads, getAssetDataUrl, resolveAssetsInMessages, runCopilotzStream, updateThread, useCopilotz, useUrlState };
341
+ export { CopilotzChat, CopilotzRequestError, type CopilotzStreamResult, type EventInterceptor, type EventInterceptorResult, type RenderSpecialState, type RequestHeadersProvider, type RunErrorInterceptor, type SpecialChatState, type SpecialStateControls, type UrlParamsConfig, type UrlState, type UrlSyncConfig, type UseUrlStateReturn, copilotzService, deleteMessagesByThreadId, deleteThread, fetchThreadMessages, fetchThreads, getAssetDataUrl, resolveAssetsInMessages, runCopilotzStream, updateThread, useCopilotz, useUrlState };
package/dist/index.js CHANGED
@@ -118,10 +118,13 @@ var API_KEY = (() => {
118
118
  ];
119
119
  return candidates.find((value) => typeof value === "string" && value.length > 0);
120
120
  })();
121
- var withAuthHeaders = (headers = {}, authToken) => {
122
- const token = authToken || API_KEY;
123
- if (token) {
124
- return { ...headers, Authorization: `Bearer ${token}` };
121
+ var withAuthHeaders = async (headers = {}, getRequestHeaders) => {
122
+ const providedHeaders = getRequestHeaders ? await getRequestHeaders() : void 0;
123
+ if (providedHeaders && Object.keys(providedHeaders).length > 0) {
124
+ return { ...headers, ...providedHeaders };
125
+ }
126
+ if (API_KEY) {
127
+ return { ...headers, Authorization: `Bearer ${API_KEY}` };
125
128
  }
126
129
  return headers;
127
130
  };
@@ -272,7 +275,6 @@ var convertAudioDataUrlToWavBase64 = async (dataUrl) => {
272
275
  };
273
276
  async function runCopilotzStream(options) {
274
277
  const {
275
- authToken,
276
278
  threadId,
277
279
  threadExternalId,
278
280
  content,
@@ -282,6 +284,7 @@ async function runCopilotzStream(options) {
282
284
  threadMetadata,
283
285
  toolCalls,
284
286
  selectedAgent,
287
+ getRequestHeaders,
285
288
  onToken,
286
289
  onMessageEvent,
287
290
  onAssetEvent,
@@ -379,9 +382,9 @@ async function runCopilotzStream(options) {
379
382
  };
380
383
  const response = await fetch(apiUrl("/v1/providers/web"), {
381
384
  method: "POST",
382
- headers: withAuthHeaders({
385
+ headers: await withAuthHeaders({
383
386
  "Content-Type": "application/json"
384
- }, authToken),
387
+ }, getRequestHeaders),
385
388
  body: JSON.stringify(payload),
386
389
  signal: controller.signal
387
390
  });
@@ -491,12 +494,12 @@ async function runCopilotzStream(options) {
491
494
  media: collectedMedia
492
495
  };
493
496
  }
494
- async function fetchThreads(userId, authToken) {
497
+ async function fetchThreads(userId, getRequestHeaders) {
495
498
  const params = new URLSearchParams();
496
499
  params.set("filters", JSON.stringify({ "metadata.userExternalId": userId }));
497
500
  params.set("sort", "-updatedAt");
498
501
  const res = await fetch(apiUrl(`/v1/rest/threads?${params.toString()}`), {
499
- headers: withAuthHeaders({ Accept: "application/json" }, authToken)
502
+ headers: await withAuthHeaders({ Accept: "application/json" }, getRequestHeaders)
500
503
  });
501
504
  if (!res.ok) {
502
505
  const errorText = await res.text().catch(() => res.statusText);
@@ -508,13 +511,13 @@ async function fetchThreads(userId, authToken) {
508
511
  }
509
512
  return data;
510
513
  }
511
- async function fetchThreadMessages(threadId, authToken) {
514
+ async function fetchThreadMessages(threadId, getRequestHeaders) {
512
515
  const graphParams = new URLSearchParams();
513
516
  graphParams.set("threadId", threadId);
514
517
  graphParams.set("limit", "500");
515
518
  try {
516
519
  const graphRes = await fetch(apiUrl(`/v1/messages?${graphParams.toString()}`), {
517
- headers: withAuthHeaders({ Accept: "application/json" }, authToken)
520
+ headers: await withAuthHeaders({ Accept: "application/json" }, getRequestHeaders)
518
521
  });
519
522
  if (graphRes.ok) {
520
523
  const graphData = await graphRes.json();
@@ -540,7 +543,7 @@ async function fetchThreadMessages(threadId, authToken) {
540
543
  params.set("filters", JSON.stringify({ threadId }));
541
544
  params.set("sort", "createdAt:asc");
542
545
  const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {
543
- headers: withAuthHeaders({ Accept: "application/json" }, authToken)
546
+ headers: await withAuthHeaders({ Accept: "application/json" }, getRequestHeaders)
544
547
  });
545
548
  if (!res.ok) {
546
549
  const errorText = await res.text().catch(() => res.statusText);
@@ -552,10 +555,10 @@ async function fetchThreadMessages(threadId, authToken) {
552
555
  }
553
556
  return data;
554
557
  }
555
- async function updateThread(threadId, updates, authToken) {
558
+ async function updateThread(threadId, updates, getRequestHeaders) {
556
559
  const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {
557
560
  method: "PUT",
558
- headers: withAuthHeaders({ "Content-Type": "application/json", Accept: "application/json" }, authToken),
561
+ headers: await withAuthHeaders({ "Content-Type": "application/json", Accept: "application/json" }, getRequestHeaders),
559
562
  body: JSON.stringify(updates)
560
563
  });
561
564
  if (!res.ok) {
@@ -565,13 +568,13 @@ async function updateThread(threadId, updates, authToken) {
565
568
  const data = await res.json();
566
569
  return data?.body ?? data;
567
570
  }
568
- async function deleteMessagesByThreadId(threadId, authToken) {
571
+ async function deleteMessagesByThreadId(threadId, getRequestHeaders) {
569
572
  const graphParams = new URLSearchParams();
570
573
  graphParams.set("threadId", threadId);
571
574
  try {
572
575
  const graphRes = await fetch(apiUrl(`/v1/messages?${graphParams.toString()}`), {
573
576
  method: "DELETE",
574
- headers: withAuthHeaders({ Accept: "application/json" }, authToken)
577
+ headers: await withAuthHeaders({ Accept: "application/json" }, getRequestHeaders)
575
578
  });
576
579
  if (!graphRes.ok && ![404, 405, 501].includes(graphRes.status)) {
577
580
  const errorText = await graphRes.text().catch(() => graphRes.statusText);
@@ -586,7 +589,7 @@ async function deleteMessagesByThreadId(threadId, authToken) {
586
589
  const params = new URLSearchParams();
587
590
  params.set("filters", JSON.stringify({ threadId }));
588
591
  const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {
589
- headers: withAuthHeaders({ Accept: "application/json" }, authToken)
592
+ headers: await withAuthHeaders({ Accept: "application/json" }, getRequestHeaders)
590
593
  });
591
594
  if (!res.ok) {
592
595
  console.warn("Could not fetch messages for deletion:", res.status);
@@ -601,18 +604,18 @@ async function deleteMessagesByThreadId(threadId, authToken) {
601
604
  try {
602
605
  await fetch(apiUrl(`/v1/rest/messages/${msg.id}`), {
603
606
  method: "DELETE",
604
- headers: withAuthHeaders({ Accept: "application/json" }, authToken)
607
+ headers: await withAuthHeaders({ Accept: "application/json" }, getRequestHeaders)
605
608
  });
606
609
  } catch {
607
610
  }
608
611
  }
609
612
  }
610
613
  }
611
- async function deleteThread(threadId, authToken) {
612
- await deleteMessagesByThreadId(threadId, authToken);
614
+ async function deleteThread(threadId, getRequestHeaders) {
615
+ await deleteMessagesByThreadId(threadId, getRequestHeaders);
613
616
  const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {
614
617
  method: "DELETE",
615
- headers: withAuthHeaders({ Accept: "application/json" }, authToken)
618
+ headers: await withAuthHeaders({ Accept: "application/json" }, getRequestHeaders)
616
619
  });
617
620
  if (!res.ok) {
618
621
  const errorText = await res.text().catch(() => res.statusText);
@@ -795,6 +798,13 @@ var generateId = () => globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${
795
798
  var isAbortError = (error) => error instanceof DOMException && error.name === "AbortError" || typeof error === "object" && error !== null && "name" in error && error.name === "AbortError";
796
799
  var getEventPayload = (event) => event?.payload ?? event;
797
800
  var getEventSenderType = (payload) => payload?.senderType || payload?.sender?.type;
801
+ var hasVisibleAssistantOutput = (message) => {
802
+ if (message.role !== "assistant") return false;
803
+ if (typeof message.content === "string" && message.content.trim().length > 0) return true;
804
+ if (Array.isArray(message.attachments) && message.attachments.length > 0) return true;
805
+ if (Array.isArray(message.toolCalls) && message.toolCalls.length > 0) return true;
806
+ return false;
807
+ };
798
808
  var normalizeToolStatus = (status) => {
799
809
  if (status === "pending") return "pending";
800
810
  if (status === "running" || status === "processing") return "running";
@@ -960,12 +970,12 @@ var convertServerMessage = (msg) => {
960
970
  };
961
971
  function useCopilotz({
962
972
  userId,
963
- authToken,
964
973
  initialContext,
965
974
  bootstrap,
966
975
  defaultThreadName,
967
976
  onToolOutput,
968
977
  preferredAgentName,
978
+ getRequestHeaders,
969
979
  eventInterceptor,
970
980
  runErrorInterceptor,
971
981
  urlSync
@@ -1027,7 +1037,7 @@ function useCopilotz({
1027
1037
  if (!eventInterceptor) return void 0;
1028
1038
  try {
1029
1039
  const result = eventInterceptor(event);
1030
- if (result && typeof result === "object" && result.specialState) {
1040
+ if (result?.specialState) {
1031
1041
  setSpecialState(result.specialState);
1032
1042
  }
1033
1043
  return result;
@@ -1162,20 +1172,20 @@ function useCopilotz({
1162
1172
  }, []);
1163
1173
  const fetchAndSetThreadsState = useCallback2(async (uid, preferredExternalId) => {
1164
1174
  try {
1165
- const rawThreads = await fetchThreads(uid, authToken);
1175
+ const rawThreads = await fetchThreads(uid, getRequestHeaders);
1166
1176
  return updateThreadsState(rawThreads, preferredExternalId);
1167
1177
  } catch (error) {
1168
1178
  if (isAbortError(error)) return;
1169
1179
  console.error("Error loading threads", error);
1170
1180
  return null;
1171
1181
  }
1172
- }, [authToken, updateThreadsState]);
1182
+ }, [updateThreadsState, getRequestHeaders]);
1173
1183
  const loadThreadMessages = useCallback2(async (threadId) => {
1174
1184
  const requestId = messagesRequestRef.current + 1;
1175
1185
  messagesRequestRef.current = requestId;
1176
1186
  setIsMessagesLoading(true);
1177
1187
  try {
1178
- const rawMessages = await fetchThreadMessages(threadId, authToken);
1188
+ const rawMessages = await fetchThreadMessages(threadId, getRequestHeaders);
1179
1189
  const resolvedMessages = await resolveAssetsInMessages(rawMessages);
1180
1190
  if (messagesRequestRef.current !== requestId) return;
1181
1191
  resolvedMessages.forEach((msg) => {
@@ -1207,7 +1217,7 @@ function useCopilotz({
1207
1217
  setIsMessagesLoading(false);
1208
1218
  }
1209
1219
  }
1210
- }, [authToken, processToolOutput]);
1220
+ }, [processToolOutput, getRequestHeaders]);
1211
1221
  const handleSelectThread = useCallback2(async (threadId) => {
1212
1222
  setCurrentThreadId(threadId);
1213
1223
  setMessages([]);
@@ -1250,7 +1260,7 @@ function useCopilotz({
1250
1260
  }));
1251
1261
  } else {
1252
1262
  try {
1253
- await updateThread(threadId, { name: trimmedTitle }, authToken);
1263
+ await updateThread(threadId, { name: trimmedTitle }, getRequestHeaders);
1254
1264
  } catch (error) {
1255
1265
  console.error("Failed to rename thread:", error);
1256
1266
  if (userId) {
@@ -1258,7 +1268,7 @@ function useCopilotz({
1258
1268
  }
1259
1269
  }
1260
1270
  }
1261
- }, [authToken, userId, fetchAndSetThreadsState]);
1271
+ }, [userId, fetchAndSetThreadsState, getRequestHeaders]);
1262
1272
  const handleArchiveThread = useCallback2(async (threadId) => {
1263
1273
  const thread = threadsRef.current.find((t) => t.id === threadId);
1264
1274
  if (!thread) return;
@@ -1270,7 +1280,7 @@ function useCopilotz({
1270
1280
  const isPlaceholder = extMap[threadId] === threadId;
1271
1281
  if (!isPlaceholder) {
1272
1282
  try {
1273
- await updateThread(threadId, { status: newArchivedStatus ? "archived" : "active" }, authToken);
1283
+ await updateThread(threadId, { status: newArchivedStatus ? "archived" : "active" }, getRequestHeaders);
1274
1284
  } catch (error) {
1275
1285
  console.error("Failed to archive thread:", error);
1276
1286
  if (userId) {
@@ -1278,7 +1288,7 @@ function useCopilotz({
1278
1288
  }
1279
1289
  }
1280
1290
  }
1281
- }, [authToken, userId, fetchAndSetThreadsState]);
1291
+ }, [userId, fetchAndSetThreadsState, getRequestHeaders]);
1282
1292
  const handleDeleteThread = useCallback2(async (threadId) => {
1283
1293
  const extMap = threadExternalIdMapRef.current;
1284
1294
  const isPlaceholder = extMap[threadId] === threadId;
@@ -1307,7 +1317,7 @@ function useCopilotz({
1307
1317
  }
1308
1318
  if (!isPlaceholder) {
1309
1319
  try {
1310
- await deleteThread(threadId, authToken);
1320
+ await deleteThread(threadId, getRequestHeaders);
1311
1321
  } catch (error) {
1312
1322
  console.error("Failed to delete thread:", error);
1313
1323
  if (userId) {
@@ -1315,7 +1325,7 @@ function useCopilotz({
1315
1325
  }
1316
1326
  }
1317
1327
  }
1318
- }, [authToken, userId, fetchAndSetThreadsState, loadThreadMessages]);
1328
+ }, [userId, fetchAndSetThreadsState, loadThreadMessages, getRequestHeaders]);
1319
1329
  const handleStop = useCallback2(() => {
1320
1330
  abortControllerRef.current?.abort();
1321
1331
  abortControllerRef.current = null;
@@ -1518,7 +1528,6 @@ function useCopilotz({
1518
1528
  };
1519
1529
  const finalMetadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : void 0;
1520
1530
  await runCopilotzStream({
1521
- authToken,
1522
1531
  threadId: params.threadId ?? void 0,
1523
1532
  threadExternalId: params.threadExternalId ?? void 0,
1524
1533
  content: requestContent,
@@ -1535,10 +1544,11 @@ function useCopilotz({
1535
1544
  threadMetadata: params.threadMetadata ?? threadMetadata,
1536
1545
  toolCalls: params.toolCalls,
1537
1546
  selectedAgent: params.agentName ?? preferredAgentRef.current ?? null,
1547
+ getRequestHeaders,
1538
1548
  onToken: (token) => updateStreamingMessage(token),
1539
1549
  onMessageEvent: async (event) => {
1540
1550
  const intercepted = applyEventInterceptor(event);
1541
- if (intercepted && typeof intercepted === "object" && intercepted.handled) {
1551
+ if (intercepted?.handled) {
1542
1552
  return;
1543
1553
  }
1544
1554
  const type = event?.type || "";
@@ -1674,7 +1684,7 @@ function useCopilotz({
1674
1684
  },
1675
1685
  onAssetEvent: async (payload) => {
1676
1686
  const intercepted = applyEventInterceptor({ type: "ASSET_CREATED", payload });
1677
- if (intercepted && typeof intercepted === "object" && intercepted.handled) {
1687
+ if (intercepted?.handled) {
1678
1688
  return;
1679
1689
  }
1680
1690
  await (async () => {
@@ -1701,7 +1711,7 @@ function useCopilotz({
1701
1711
  abortControllerRef.current = null;
1702
1712
  }
1703
1713
  return currentAssistantId;
1704
- }, [authToken, applyEventInterceptor, handleStreamMessageEvent, handleStreamAssetEvent]);
1714
+ }, [applyEventInterceptor, handleStreamMessageEvent, handleStreamAssetEvent, getRequestHeaders]);
1705
1715
  const handleSendMessage = useCallback2(async (content, attachments = []) => {
1706
1716
  if (!content.trim() && attachments.length === 0) return;
1707
1717
  if (!userId) return;
@@ -1778,14 +1788,37 @@ function useCopilotz({
1778
1788
  setMessages((prev) => prev.filter((msg) => !msg.isStreaming));
1779
1789
  return;
1780
1790
  }
1781
- setMessages((prev) => prev.map((msg) => msg.isStreaming ? {
1782
- ...msg,
1783
- isStreaming: false,
1784
- isComplete: true,
1785
- content: "Desculpe, ocorreu um erro ao gerar a resposta. Por favor, tente novamente."
1786
- } : msg));
1791
+ setMessages((prev) => {
1792
+ const finalized = prev.map((msg) => msg.isStreaming ? { ...msg, isStreaming: false, isComplete: true } : msg);
1793
+ if (finalized.some(hasVisibleAssistantOutput)) {
1794
+ return finalized;
1795
+ }
1796
+ for (let i = finalized.length - 1; i >= 0; i--) {
1797
+ const message = finalized[i];
1798
+ if (message.role !== "assistant") continue;
1799
+ const updated = [...finalized];
1800
+ updated[i] = {
1801
+ ...message,
1802
+ content: "Desculpe, ocorreu um erro ao gerar a resposta. Por favor, tente novamente.",
1803
+ isStreaming: false,
1804
+ isComplete: true
1805
+ };
1806
+ return updated;
1807
+ }
1808
+ return [
1809
+ ...finalized,
1810
+ {
1811
+ id: generateId(),
1812
+ role: "assistant",
1813
+ content: "Desculpe, ocorreu um erro ao gerar a resposta. Por favor, tente novamente.",
1814
+ timestamp: nowTs(),
1815
+ isStreaming: false,
1816
+ isComplete: true
1817
+ }
1818
+ ];
1819
+ });
1787
1820
  }
1788
- }, [userId, authToken, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, getSpecialStateFromError]);
1821
+ }, [userId, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, getSpecialStateFromError]);
1789
1822
  const bootstrapConversation = useCallback2(async (uid) => {
1790
1823
  if (!bootstrap?.initialToolCalls && !bootstrap?.initialMessage) return;
1791
1824
  const bootstrapThreadExternalId = generateId();
@@ -1828,7 +1861,7 @@ function useCopilotz({
1828
1861
  }
1829
1862
  ]);
1830
1863
  }
1831
- }, [authToken, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName, getSpecialStateFromError]);
1864
+ }, [fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName, getSpecialStateFromError]);
1832
1865
  const reset = useCallback2(() => {
1833
1866
  messagesRequestRef.current += 1;
1834
1867
  setThreads([]);
@@ -1863,7 +1896,7 @@ function useCopilotz({
1863
1896
  initializationRef.current = { userId: null, started: false };
1864
1897
  reset();
1865
1898
  }
1866
- }, [userId, authToken, fetchAndSetThreadsState, loadThreadMessages, bootstrapConversation, reset, bootstrap, isUrlSyncEnabled, urlState.threadId]);
1899
+ }, [userId, fetchAndSetThreadsState, loadThreadMessages, bootstrapConversation, reset, bootstrap, isUrlSyncEnabled, urlState.threadId]);
1867
1900
  useEffect2(() => {
1868
1901
  if (!isUrlSyncEnabled) return;
1869
1902
  if (!initializationRef.current.started) return;
@@ -1912,7 +1945,6 @@ function useCopilotz({
1912
1945
  import { jsx } from "react/jsx-runtime";
1913
1946
  var CopilotzChat = ({
1914
1947
  userId,
1915
- authToken,
1916
1948
  userName,
1917
1949
  userAvatar,
1918
1950
  userEmail,
@@ -1931,6 +1963,7 @@ var CopilotzChat = ({
1931
1963
  agentOptions = [],
1932
1964
  selectedAgentId = null,
1933
1965
  onSelectAgent,
1966
+ getRequestHeaders,
1934
1967
  className,
1935
1968
  eventInterceptor,
1936
1969
  runErrorInterceptor,
@@ -1960,12 +1993,12 @@ var CopilotzChat = ({
1960
1993
  setUrlAgentId
1961
1994
  } = useCopilotz({
1962
1995
  userId,
1963
- authToken,
1964
1996
  initialContext,
1965
1997
  bootstrap,
1966
1998
  defaultThreadName: userConfig?.labels?.defaultThreadName,
1967
1999
  onToolOutput,
1968
2000
  preferredAgentName: selectedAgent?.name ?? null,
2001
+ getRequestHeaders,
1969
2002
  eventInterceptor,
1970
2003
  runErrorInterceptor,
1971
2004
  urlSync