@m6d/cortex-react 1.0.1 → 1.0.3
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 +2 -3662
- package/dist/styles.css +1 -0
- package/package.json +6 -2
package/dist/index.js
CHANGED
|
@@ -1,3662 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { useCallback, useEffect as useEffect6, useMemo as useMemo3, useRef as useRef8, useState as useState9, useSyncExternalStore } from "react";
|
|
3
|
-
|
|
4
|
-
// ../../internal/client/src/api-client.ts
|
|
5
|
-
function resolveTransportHeaders(transport) {
|
|
6
|
-
return Promise.resolve(transport.getHeaders());
|
|
7
|
-
}
|
|
8
|
-
function resolveTransportUrl(transport, path) {
|
|
9
|
-
const baseUrl = transport.baseUrl;
|
|
10
|
-
const base = typeof baseUrl === "string" ? baseUrl : baseUrl();
|
|
11
|
-
return base.replace(/\/$/, "") + path;
|
|
12
|
-
}
|
|
13
|
-
function filenameFrom(disposition) {
|
|
14
|
-
const encoded = disposition?.match(/filename\*\s*=\s*[^']*'[^']*'([^;\r\n]+)/i)?.[1]?.trim().replace(/^"|"$/g, "");
|
|
15
|
-
if (encoded) {
|
|
16
|
-
try {
|
|
17
|
-
return decodeURIComponent(encoded);
|
|
18
|
-
} catch {}
|
|
19
|
-
}
|
|
20
|
-
return disposition?.match(/filename\s*=\s*"?([^";\r\n]+)"?/i)?.[1];
|
|
21
|
-
}
|
|
22
|
-
function createCortexApiClient(getTransport) {
|
|
23
|
-
function resolveHeaders() {
|
|
24
|
-
return resolveTransportHeaders(getTransport());
|
|
25
|
-
}
|
|
26
|
-
function resolveUrl(path) {
|
|
27
|
-
return resolveTransportUrl(getTransport(), path);
|
|
28
|
-
}
|
|
29
|
-
async function send(path, init) {
|
|
30
|
-
const headers = new Headers(await resolveHeaders());
|
|
31
|
-
new Headers(init?.headers).forEach(function(value, name) {
|
|
32
|
-
headers.set(name, value);
|
|
33
|
-
});
|
|
34
|
-
if (init?.body instanceof FormData) {
|
|
35
|
-
headers.delete("Content-Type");
|
|
36
|
-
} else if (!headers.has("Content-Type")) {
|
|
37
|
-
headers.set("Content-Type", "application/json");
|
|
38
|
-
}
|
|
39
|
-
const response = await fetch(resolveUrl(path), {
|
|
40
|
-
...init,
|
|
41
|
-
headers
|
|
42
|
-
});
|
|
43
|
-
if (!response.ok) {
|
|
44
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
45
|
-
}
|
|
46
|
-
const text = await response.text();
|
|
47
|
-
return text ? JSON.parse(text) : undefined;
|
|
48
|
-
}
|
|
49
|
-
return {
|
|
50
|
-
listThreads() {
|
|
51
|
-
return send("/threads");
|
|
52
|
-
},
|
|
53
|
-
createThread(prompt) {
|
|
54
|
-
return send("/threads", {
|
|
55
|
-
method: "POST",
|
|
56
|
-
body: JSON.stringify({ prompt })
|
|
57
|
-
});
|
|
58
|
-
},
|
|
59
|
-
deleteThread(threadId) {
|
|
60
|
-
return send(`/threads/${threadId}`, { method: "DELETE" });
|
|
61
|
-
},
|
|
62
|
-
listMessages(threadId) {
|
|
63
|
-
return send(`/threads/${threadId}/messages`);
|
|
64
|
-
},
|
|
65
|
-
listLlmRequests(messageId) {
|
|
66
|
-
return send(`/messages/${messageId}/llm-requests`);
|
|
67
|
-
},
|
|
68
|
-
abortStream(threadId) {
|
|
69
|
-
return send(`/chat/${threadId}/abort`, { method: "POST" });
|
|
70
|
-
},
|
|
71
|
-
async uploadAttachment(threadId, file) {
|
|
72
|
-
const body = new FormData;
|
|
73
|
-
body.append("file", file);
|
|
74
|
-
return await send(`/threads/${threadId}/files`, {
|
|
75
|
-
method: "POST",
|
|
76
|
-
body
|
|
77
|
-
});
|
|
78
|
-
},
|
|
79
|
-
deleteAttachment(id) {
|
|
80
|
-
return send(`/files/${id}`, { method: "DELETE" });
|
|
81
|
-
},
|
|
82
|
-
async downloadAttachment(id) {
|
|
83
|
-
const response = await fetch(resolveUrl(`/files/${id}`), {
|
|
84
|
-
headers: await resolveHeaders()
|
|
85
|
-
});
|
|
86
|
-
if (!response.ok) {
|
|
87
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
88
|
-
}
|
|
89
|
-
return {
|
|
90
|
-
blob: await response.blob(),
|
|
91
|
-
name: filenameFrom(response.headers.get("Content-Disposition")) ?? id
|
|
92
|
-
};
|
|
93
|
-
},
|
|
94
|
-
resolveHeaders,
|
|
95
|
-
resolveUrl
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
// ../../internal/client/src/utils/pending-tool-calls.ts
|
|
99
|
-
var SETTLED_STATES = new Set(["complete", "error"]);
|
|
100
|
-
function isSettledToolState(state) {
|
|
101
|
-
return SETTLED_STATES.has(state);
|
|
102
|
-
}
|
|
103
|
-
function unansweredToolCalls(messages) {
|
|
104
|
-
const parts = newestAssistantMessage(messages)?.parts ?? [];
|
|
105
|
-
return parts.filter((part) => part.type === "tool-call" && !isSettledToolState(part.state));
|
|
106
|
-
}
|
|
107
|
-
function newestAssistantMessage(messages) {
|
|
108
|
-
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
109
|
-
const message = messages[index];
|
|
110
|
-
if (message?.role === "assistant")
|
|
111
|
-
return message;
|
|
112
|
-
}
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// ../../internal/client/src/tool-call-view.ts
|
|
117
|
-
var STATE_MODIFIERS = {
|
|
118
|
-
complete: "success",
|
|
119
|
-
error: "error",
|
|
120
|
-
"approval-requested": "approval",
|
|
121
|
-
"approval-responded": "approval",
|
|
122
|
-
"awaiting-input": "pending",
|
|
123
|
-
"input-streaming": "pending",
|
|
124
|
-
"input-complete": "pending"
|
|
125
|
-
};
|
|
126
|
-
var BADGE_LABEL_KEYS = {
|
|
127
|
-
"awaiting-input": "translate_calling",
|
|
128
|
-
"input-streaming": "translate_calling",
|
|
129
|
-
"input-complete": "translate_input_ready",
|
|
130
|
-
"approval-requested": "translate_needs_approval",
|
|
131
|
-
"approval-responded": "translate_responded",
|
|
132
|
-
complete: "translate_completed",
|
|
133
|
-
error: "translate_error"
|
|
134
|
-
};
|
|
135
|
-
function toolCallBadge(part) {
|
|
136
|
-
const { state, approval } = part;
|
|
137
|
-
return {
|
|
138
|
-
modifier: STATE_MODIFIERS[state],
|
|
139
|
-
labelKey: state === "approval-responded" && approval?.approved ? "translate_approved" : BADGE_LABEL_KEYS[state],
|
|
140
|
-
pulse: state === "awaiting-input" || state === "input-streaming" ? "default" : state === "approval-requested" ? "violet" : undefined
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
function toolCallOutputText(part) {
|
|
144
|
-
const output = part.output;
|
|
145
|
-
if (output === undefined || output === null)
|
|
146
|
-
return "";
|
|
147
|
-
if (typeof output === "string")
|
|
148
|
-
return output;
|
|
149
|
-
return JSON.stringify(output, null, 2);
|
|
150
|
-
}
|
|
151
|
-
var CODE_FIELDS = {
|
|
152
|
-
code: "javascript",
|
|
153
|
-
query: "cypher"
|
|
154
|
-
};
|
|
155
|
-
function splitToolCallInput(input) {
|
|
156
|
-
const record = input && typeof input === "object" ? input : null;
|
|
157
|
-
const codeSnippets = record ? Object.entries(CODE_FIELDS).flatMap(([key, lang]) => {
|
|
158
|
-
const value = record[key];
|
|
159
|
-
return typeof value === "string" ? [{ key, lang, value: value.replace(/\\n/g, `
|
|
160
|
-
`) }] : [];
|
|
161
|
-
}) : [];
|
|
162
|
-
let remainingInput = input;
|
|
163
|
-
if (record) {
|
|
164
|
-
const rest = Object.fromEntries(Object.entries(record).filter(([key]) => !Object.hasOwn(CODE_FIELDS, key)));
|
|
165
|
-
remainingInput = Object.keys(rest).length > 0 ? rest : null;
|
|
166
|
-
}
|
|
167
|
-
return {
|
|
168
|
-
codeSnippets,
|
|
169
|
-
remainingInput,
|
|
170
|
-
remainingInputText: remainingInput ? JSON.stringify(remainingInput, null, 2) : ""
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
var STATUS_COUNT = 10;
|
|
174
|
-
var ANIM_STATES = {
|
|
175
|
-
"awaiting-input": "starting",
|
|
176
|
-
"input-streaming": "starting",
|
|
177
|
-
"input-complete": "processing",
|
|
178
|
-
"approval-requested": "processing",
|
|
179
|
-
"approval-responded": "processing",
|
|
180
|
-
complete: "complete",
|
|
181
|
-
error: "error"
|
|
182
|
-
};
|
|
183
|
-
function stableIndex(id) {
|
|
184
|
-
let hash = 0;
|
|
185
|
-
for (let i = 0;i < id.length; i++) {
|
|
186
|
-
hash = hash * 31 + id.charCodeAt(i) | 0;
|
|
187
|
-
}
|
|
188
|
-
return Math.abs(hash) % STATUS_COUNT;
|
|
189
|
-
}
|
|
190
|
-
function toolCallAnimation(part) {
|
|
191
|
-
const state = ANIM_STATES[part.state] ?? "processing";
|
|
192
|
-
const family = part.name === "readAttachment" ? "attachment" : "tool";
|
|
193
|
-
const variant = family === "tool" ? `_${stableIndex(part.id)}` : "";
|
|
194
|
-
return {
|
|
195
|
-
state,
|
|
196
|
-
active: state === "starting" || state === "processing",
|
|
197
|
-
titleKey: state === "error" ? "translate_tool_error" : `translate_${family}_${state === "complete" ? "done" : "status"}${variant}`
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
function activityLabelKeys(activity) {
|
|
201
|
-
return Array.from({ length: STATUS_COUNT }, (_, index) => `translate_${activity}_${index}`);
|
|
202
|
-
}
|
|
203
|
-
var SELF_DESCRIBING_TOOLS = ["queryGraph", "executeCode"];
|
|
204
|
-
function isHiddenInAnimatedMode(part, isLast, isStreaming) {
|
|
205
|
-
if (part.type === "thinking")
|
|
206
|
-
return !(isStreaming && isLast);
|
|
207
|
-
if (part.type !== "tool-call")
|
|
208
|
-
return false;
|
|
209
|
-
return SELF_DESCRIBING_TOOLS.includes(part.name) && isSettledToolState(part.state);
|
|
210
|
-
}
|
|
211
|
-
// ../../internal/client/src/chat-connection.ts
|
|
212
|
-
import { EventType } from "@tanstack/ai";
|
|
213
|
-
import { fetchServerSentEvents } from "@tanstack/ai-client";
|
|
214
|
-
function toUiMessage(message) {
|
|
215
|
-
return { id: message.id, role: message.role, parts: message.parts };
|
|
216
|
-
}
|
|
217
|
-
function newestUnsent(messages) {
|
|
218
|
-
for (let index = messages.length - 1;index >= 0; index -= 1) {
|
|
219
|
-
const message = messages[index];
|
|
220
|
-
const answersToolCall = "parts" in message && message.parts.some((part) => part.type === "tool-result");
|
|
221
|
-
if (message.role === "user" || answersToolCall)
|
|
222
|
-
return messages.slice(index, index + 1);
|
|
223
|
-
}
|
|
224
|
-
return messages.slice(-1);
|
|
225
|
-
}
|
|
226
|
-
function metadataByMessageId(rows) {
|
|
227
|
-
return new Map(rows.flatMap((row) => row.metadata ? [[row.id, row.metadata]] : []));
|
|
228
|
-
}
|
|
229
|
-
function createCortexConnection(options) {
|
|
230
|
-
const { api, thread } = options;
|
|
231
|
-
const requestOptions = async () => ({ headers: await api.resolveHeaders() });
|
|
232
|
-
const turn = fetchServerSentEvents(() => api.resolveUrl("/chat"), requestOptions);
|
|
233
|
-
const connect = function(messages, data, abortSignal, runContext) {
|
|
234
|
-
return turn.connect(newestUnsent(messages), data, abortSignal, runContext);
|
|
235
|
-
};
|
|
236
|
-
const join = fetchServerSentEvents(() => api.resolveUrl(`/chat/${thread.id}/stream`), requestOptions);
|
|
237
|
-
let replayBase = [];
|
|
238
|
-
return {
|
|
239
|
-
connect,
|
|
240
|
-
async* joinRun(runId, abortSignal) {
|
|
241
|
-
yield {
|
|
242
|
-
type: EventType.MESSAGES_SNAPSHOT,
|
|
243
|
-
timestamp: Date.now(),
|
|
244
|
-
messages: replayBase
|
|
245
|
-
};
|
|
246
|
-
yield* join.joinRun(runId, abortSignal);
|
|
247
|
-
},
|
|
248
|
-
hydrate: async () => {
|
|
249
|
-
const hydration = await hydrateThread(options);
|
|
250
|
-
replayBase = hydration.messages;
|
|
251
|
-
return hydration;
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
async function hydrateThread(options) {
|
|
256
|
-
const { api, thread, mode } = options;
|
|
257
|
-
const activeRun = thread.isRunning ? { runId: thread.id } : null;
|
|
258
|
-
if (mode === "skip")
|
|
259
|
-
return { messages: [], activeRun, interrupts: null };
|
|
260
|
-
if (mode === "load")
|
|
261
|
-
options.setLoadingMessages?.(true);
|
|
262
|
-
try {
|
|
263
|
-
const rows = await api.listMessages(thread.id);
|
|
264
|
-
const messages = rows.map(toUiMessage);
|
|
265
|
-
options.onHydrated?.(rows, messages);
|
|
266
|
-
return { messages, activeRun, interrupts: null };
|
|
267
|
-
} finally {
|
|
268
|
-
options.setLoadingMessages?.(false);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
async function settleTurn(options) {
|
|
272
|
-
try {
|
|
273
|
-
const rows = await options.api.listMessages(options.threadId);
|
|
274
|
-
if (options.isStale?.())
|
|
275
|
-
return;
|
|
276
|
-
options.absorbMetadata(metadataByMessageId(rows));
|
|
277
|
-
if (options.isStreaming())
|
|
278
|
-
return;
|
|
279
|
-
options.setMessages(rows.map(toUiMessage));
|
|
280
|
-
} catch {}
|
|
281
|
-
}
|
|
282
|
-
// ../../internal/contracts/wire.ts
|
|
283
|
-
var ATTACHMENT_MIME_TYPES = [
|
|
284
|
-
"image/png",
|
|
285
|
-
"image/jpeg",
|
|
286
|
-
"image/webp",
|
|
287
|
-
"application/pdf"
|
|
288
|
-
];
|
|
289
|
-
var ATTACHMENT_MAX_BYTES = 10 * 1024 * 1024;
|
|
290
|
-
var MAX_ATTACHMENTS_PER_MESSAGE = 5;
|
|
291
|
-
function checkAttachmentPolicy(contentType, sizeBytes) {
|
|
292
|
-
if (!ATTACHMENT_MIME_TYPES.some((type) => type === contentType))
|
|
293
|
-
return "type";
|
|
294
|
-
if (sizeBytes > ATTACHMENT_MAX_BYTES)
|
|
295
|
-
return "size";
|
|
296
|
-
return "ok";
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// ../../internal/client/src/attachment-queue.ts
|
|
300
|
-
function createAttachmentQueue(options) {
|
|
301
|
-
const { api } = options;
|
|
302
|
-
const listeners = new Set;
|
|
303
|
-
const cancelled = new Set;
|
|
304
|
-
let items = [];
|
|
305
|
-
let consumed = [];
|
|
306
|
-
function getState() {
|
|
307
|
-
return items;
|
|
308
|
-
}
|
|
309
|
-
function subscribe(listener) {
|
|
310
|
-
listeners.add(listener);
|
|
311
|
-
return () => {
|
|
312
|
-
listeners.delete(listener);
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
function setItems(next) {
|
|
316
|
-
items = next;
|
|
317
|
-
for (const listener of listeners)
|
|
318
|
-
listener();
|
|
319
|
-
}
|
|
320
|
-
function patch(localId, changes) {
|
|
321
|
-
setItems(items.map((item) => item.localId === localId ? { ...item, ...changes } : item));
|
|
322
|
-
}
|
|
323
|
-
function fail(localId) {
|
|
324
|
-
if (cancelled.delete(localId))
|
|
325
|
-
return;
|
|
326
|
-
patch(localId, { status: "error" });
|
|
327
|
-
}
|
|
328
|
-
function accept(files) {
|
|
329
|
-
const accepted = [];
|
|
330
|
-
for (const file of files) {
|
|
331
|
-
const rejected = checkAttachmentPolicy(file.type, file.size) !== "ok" || items.filter((item) => item.status !== "error").length >= MAX_ATTACHMENTS_PER_MESSAGE;
|
|
332
|
-
const localId = crypto.randomUUID();
|
|
333
|
-
setItems([
|
|
334
|
-
...items,
|
|
335
|
-
{ localId, filename: file.name, status: rejected ? "error" : "uploading" }
|
|
336
|
-
]);
|
|
337
|
-
if (!rejected)
|
|
338
|
-
accepted.push({ localId, file });
|
|
339
|
-
}
|
|
340
|
-
if (!accepted.length)
|
|
341
|
-
return;
|
|
342
|
-
options.ensureThread().then((threadId) => {
|
|
343
|
-
for (const { localId, file } of accepted) {
|
|
344
|
-
if (cancelled.delete(localId))
|
|
345
|
-
continue;
|
|
346
|
-
patch(localId, { threadId });
|
|
347
|
-
api.uploadAttachment(threadId, file).then((attachment) => {
|
|
348
|
-
if (cancelled.delete(localId)) {
|
|
349
|
-
api.deleteAttachment(attachment.id).catch(() => {});
|
|
350
|
-
return;
|
|
351
|
-
}
|
|
352
|
-
patch(localId, {
|
|
353
|
-
status: "ready",
|
|
354
|
-
attachmentId: attachment.id,
|
|
355
|
-
summary: attachment
|
|
356
|
-
});
|
|
357
|
-
}, () => fail(localId));
|
|
358
|
-
}
|
|
359
|
-
}, () => {
|
|
360
|
-
for (const { localId } of accepted) {
|
|
361
|
-
fail(localId);
|
|
362
|
-
}
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
function remove(localId) {
|
|
366
|
-
const item = items.find((current) => current.localId === localId);
|
|
367
|
-
if (!item)
|
|
368
|
-
return;
|
|
369
|
-
if (item.status === "uploading") {
|
|
370
|
-
cancelled.add(localId);
|
|
371
|
-
setItems(items.filter((current) => current.localId !== localId));
|
|
372
|
-
return;
|
|
373
|
-
}
|
|
374
|
-
if (item.attachmentId) {
|
|
375
|
-
patch(localId, { status: "deleting" });
|
|
376
|
-
api.deleteAttachment(item.attachmentId).then(() => setItems(items.filter((current) => current.localId !== localId)), () => patch(localId, { status: "error" }));
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
setItems(items.filter((current) => current.localId !== localId));
|
|
380
|
-
}
|
|
381
|
-
function clear(threadId) {
|
|
382
|
-
const retained = [];
|
|
383
|
-
for (const item of items) {
|
|
384
|
-
if (item.threadId !== undefined && item.threadId !== threadId) {
|
|
385
|
-
retained.push(item);
|
|
386
|
-
continue;
|
|
387
|
-
}
|
|
388
|
-
if (item.status === "uploading") {
|
|
389
|
-
cancelled.add(item.localId);
|
|
390
|
-
} else if (item.status === "ready" && item.threadId === threadId && item.attachmentId) {
|
|
391
|
-
api.deleteAttachment(item.attachmentId).catch(() => {});
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
setItems(retained);
|
|
395
|
-
}
|
|
396
|
-
function consumeReady() {
|
|
397
|
-
const attachments = items.flatMap((item) => item.status === "ready" && item.summary ? [{ ...item, status: "ready", summary: item.summary }] : []);
|
|
398
|
-
setItems(items.filter((item) => item.status !== "ready"));
|
|
399
|
-
consumed = attachments;
|
|
400
|
-
return attachments;
|
|
401
|
-
}
|
|
402
|
-
function restoreConsumed(threadId) {
|
|
403
|
-
const attachments = consumed;
|
|
404
|
-
consumed = [];
|
|
405
|
-
if (attachments.some((attachment) => attachment.threadId !== threadId))
|
|
406
|
-
return;
|
|
407
|
-
setItems([
|
|
408
|
-
...attachments.map((attachment) => ({ ...attachment, status: "error" })),
|
|
409
|
-
...items
|
|
410
|
-
]);
|
|
411
|
-
}
|
|
412
|
-
function discardConsumed() {
|
|
413
|
-
consumed = [];
|
|
414
|
-
}
|
|
415
|
-
return {
|
|
416
|
-
getState,
|
|
417
|
-
subscribe,
|
|
418
|
-
accept,
|
|
419
|
-
remove,
|
|
420
|
-
clear,
|
|
421
|
-
consumeReady,
|
|
422
|
-
restoreConsumed,
|
|
423
|
-
discardConsumed
|
|
424
|
-
};
|
|
425
|
-
}
|
|
426
|
-
function attachmentQueueFlags(items) {
|
|
427
|
-
return {
|
|
428
|
-
uploading: items.some((item) => item.status === "uploading"),
|
|
429
|
-
busy: items.some((item) => item.status === "uploading" || item.status === "deleting"),
|
|
430
|
-
hasReady: items.some((item) => item.status === "ready")
|
|
431
|
-
};
|
|
432
|
-
}
|
|
433
|
-
// ../../internal/client/src/websocket.ts
|
|
434
|
-
function wsBackoffDelay(attempt) {
|
|
435
|
-
return Math.min(1000 * 2 ** (attempt - 1), 30000);
|
|
436
|
-
}
|
|
437
|
-
var STABLE_CONNECTION_MS = 1e4;
|
|
438
|
-
function createCortexSocket(options) {
|
|
439
|
-
let ws;
|
|
440
|
-
let reconnectTimer;
|
|
441
|
-
let attempt = 0;
|
|
442
|
-
let closed = false;
|
|
443
|
-
function connect() {
|
|
444
|
-
const wsUrlOption = typeof options.wsUrl === "function" ? options.wsUrl() : options.wsUrl;
|
|
445
|
-
const wsUrl = resolveWsUrl(wsUrlOption, options.transport.baseUrl);
|
|
446
|
-
resolveTransportHeaders(options.transport).then((headers) => {
|
|
447
|
-
if (closed)
|
|
448
|
-
return;
|
|
449
|
-
ws = new WebSocket(appendTokenToUrl(wsUrl, headers));
|
|
450
|
-
ws.addEventListener("open", () => {
|
|
451
|
-
const opened = ws;
|
|
452
|
-
setTimeout(() => {
|
|
453
|
-
if (ws === opened && !closed)
|
|
454
|
-
attempt = 0;
|
|
455
|
-
}, STABLE_CONNECTION_MS);
|
|
456
|
-
options.onOpen?.();
|
|
457
|
-
});
|
|
458
|
-
ws.addEventListener("message", (event) => {
|
|
459
|
-
const raw = event.data;
|
|
460
|
-
if (typeof raw !== "string")
|
|
461
|
-
return;
|
|
462
|
-
let parsed;
|
|
463
|
-
try {
|
|
464
|
-
parsed = JSON.parse(raw);
|
|
465
|
-
} catch {
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
options.onEvent(parsed);
|
|
469
|
-
});
|
|
470
|
-
ws.addEventListener("close", scheduleReconnect);
|
|
471
|
-
}).catch(scheduleReconnect);
|
|
472
|
-
}
|
|
473
|
-
function scheduleReconnect() {
|
|
474
|
-
if (closed || reconnectTimer)
|
|
475
|
-
return;
|
|
476
|
-
attempt += 1;
|
|
477
|
-
reconnectTimer = setTimeout(() => {
|
|
478
|
-
reconnectTimer = undefined;
|
|
479
|
-
connect();
|
|
480
|
-
}, wsBackoffDelay(attempt));
|
|
481
|
-
}
|
|
482
|
-
connect();
|
|
483
|
-
return {
|
|
484
|
-
close() {
|
|
485
|
-
closed = true;
|
|
486
|
-
clearTimeout(reconnectTimer);
|
|
487
|
-
ws?.close();
|
|
488
|
-
}
|
|
489
|
-
};
|
|
490
|
-
}
|
|
491
|
-
function resolveWsUrl(wsUrl, baseUrl) {
|
|
492
|
-
const resolvedUrl = wsUrl ?? deriveWsUrl(baseUrl);
|
|
493
|
-
if (!wsUrl)
|
|
494
|
-
return resolvedUrl;
|
|
495
|
-
const agentId = extractAgentId(baseUrl);
|
|
496
|
-
if (!agentId)
|
|
497
|
-
return resolvedUrl;
|
|
498
|
-
return appendAgentIdToUrl(resolvedUrl, agentId);
|
|
499
|
-
}
|
|
500
|
-
function deriveWsUrl(baseUrl) {
|
|
501
|
-
const url = typeof baseUrl === "string" ? baseUrl : baseUrl();
|
|
502
|
-
const parsed = new URL(url, window.location.origin);
|
|
503
|
-
parsed.protocol = parsed.protocol === "https:" ? "wss:" : "ws:";
|
|
504
|
-
parsed.pathname = parsed.pathname.replace(/\/$/, "") + "/ws";
|
|
505
|
-
return parsed.toString();
|
|
506
|
-
}
|
|
507
|
-
function extractAgentId(baseUrl) {
|
|
508
|
-
const url = typeof baseUrl === "string" ? baseUrl : baseUrl();
|
|
509
|
-
const parsed = new URL(url, window.location.origin);
|
|
510
|
-
const segments = parsed.pathname.split("/").filter(Boolean);
|
|
511
|
-
const agentsIndex = segments.lastIndexOf("agents");
|
|
512
|
-
if (agentsIndex === -1)
|
|
513
|
-
return;
|
|
514
|
-
return segments[agentsIndex + 1];
|
|
515
|
-
}
|
|
516
|
-
function appendAgentIdToUrl(wsUrl, agentId) {
|
|
517
|
-
const parsed = new URL(wsUrl, window.location.origin);
|
|
518
|
-
if (parsed.searchParams.has("agentId") || hasAgentIdInPath(parsed))
|
|
519
|
-
return parsed.toString();
|
|
520
|
-
parsed.searchParams.set("agentId", agentId);
|
|
521
|
-
return parsed.toString();
|
|
522
|
-
}
|
|
523
|
-
function hasAgentIdInPath(url) {
|
|
524
|
-
const segments = url.pathname.split("/").filter(Boolean);
|
|
525
|
-
const agentsIndex = segments.lastIndexOf("agents");
|
|
526
|
-
return agentsIndex !== -1 && Boolean(segments[agentsIndex + 1]);
|
|
527
|
-
}
|
|
528
|
-
function appendTokenToUrl(wsUrl, headers) {
|
|
529
|
-
const authHeader = headers["Authorization"] ?? headers["authorization"];
|
|
530
|
-
if (!authHeader?.startsWith("Bearer "))
|
|
531
|
-
return wsUrl;
|
|
532
|
-
const parsed = new URL(wsUrl, window.location.origin);
|
|
533
|
-
if (parsed.searchParams.has("token"))
|
|
534
|
-
return parsed.toString();
|
|
535
|
-
parsed.searchParams.set("token", authHeader.slice(7));
|
|
536
|
-
return parsed.toString();
|
|
537
|
-
}
|
|
538
|
-
// ../../internal/client/src/threads.ts
|
|
539
|
-
function sortThreads(threads) {
|
|
540
|
-
return [...threads].sort((left, right) => {
|
|
541
|
-
const updatedAtDelta = Date.parse(right.updatedAt) - Date.parse(left.updatedAt);
|
|
542
|
-
if (updatedAtDelta !== 0)
|
|
543
|
-
return updatedAtDelta;
|
|
544
|
-
return Date.parse(right.createdAt) - Date.parse(left.createdAt);
|
|
545
|
-
});
|
|
546
|
-
}
|
|
547
|
-
function upsertThread(threads, thread) {
|
|
548
|
-
const nextThreads = [...threads];
|
|
549
|
-
const existingIndex = nextThreads.findIndex((currentThread) => currentThread.id === thread.id);
|
|
550
|
-
if (existingIndex === -1) {
|
|
551
|
-
nextThreads.push(thread);
|
|
552
|
-
} else {
|
|
553
|
-
nextThreads[existingIndex] = { ...nextThreads[existingIndex], ...thread };
|
|
554
|
-
}
|
|
555
|
-
return sortThreads(nextThreads);
|
|
556
|
-
}
|
|
557
|
-
function removeThread(threads, threadId) {
|
|
558
|
-
return threads.filter((thread) => thread.id !== threadId);
|
|
559
|
-
}
|
|
560
|
-
function applyWsEvent(threads, event) {
|
|
561
|
-
switch (event.type) {
|
|
562
|
-
case "thread:deleted":
|
|
563
|
-
return removeThread(threads, event.payload.threadId);
|
|
564
|
-
case "thread:created":
|
|
565
|
-
case "thread:title-updated":
|
|
566
|
-
case "thread:run-started":
|
|
567
|
-
case "thread:run-finished":
|
|
568
|
-
case "thread:messages-updated":
|
|
569
|
-
return upsertThread(threads, event.payload.thread);
|
|
570
|
-
default:
|
|
571
|
-
return threads;
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
// ../../internal/client/src/markdown.ts
|
|
575
|
-
import { marked } from "marked";
|
|
576
|
-
import DOMPurify from "dompurify";
|
|
577
|
-
function renderMarkdown(value) {
|
|
578
|
-
if (!value) {
|
|
579
|
-
return "";
|
|
580
|
-
}
|
|
581
|
-
let html = marked.parse(value, { async: false });
|
|
582
|
-
html = html.replace(/<table>/g, '<div style="overflow-x:auto"><table style="width:auto">').replace(/<\/table>/g, "</table></div>").replace(/<(t[hd])([\s>])/g, '<$1 style="padding:0.5rem 1rem"$2');
|
|
583
|
-
return DOMPurify.sanitize(html);
|
|
584
|
-
}
|
|
585
|
-
// ../../internal/client/src/highlight.ts
|
|
586
|
-
import hljs from "highlight.js/lib/core";
|
|
587
|
-
import javascript from "highlight.js/lib/languages/javascript";
|
|
588
|
-
import json from "highlight.js/lib/languages/json";
|
|
589
|
-
import sql from "highlight.js/lib/languages/sql";
|
|
590
|
-
var registered = false;
|
|
591
|
-
function ensureLanguages() {
|
|
592
|
-
if (registered)
|
|
593
|
-
return;
|
|
594
|
-
registered = true;
|
|
595
|
-
hljs.registerLanguage("javascript", javascript);
|
|
596
|
-
hljs.registerLanguage("json", json);
|
|
597
|
-
hljs.registerLanguage("cypher", sql);
|
|
598
|
-
}
|
|
599
|
-
function highlightCode(code, lang) {
|
|
600
|
-
if (!code)
|
|
601
|
-
return "";
|
|
602
|
-
ensureLanguages();
|
|
603
|
-
return hljs.getLanguage(lang) ? hljs.highlight(code, { language: lang }).value : escapeHtml(code);
|
|
604
|
-
}
|
|
605
|
-
function escapeHtml(str) {
|
|
606
|
-
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
607
|
-
}
|
|
608
|
-
// ../../internal/client/src/i18n/ar.json
|
|
609
|
-
var ar_default = {
|
|
610
|
-
translate_new: "جديد",
|
|
611
|
-
translate_threads: "المحادثات",
|
|
612
|
-
translate_n_conversations: "{{count}} محادثات",
|
|
613
|
-
translate_one_conversation: "محادثة واحدة",
|
|
614
|
-
translate_no_threads_yet: "لا توجد محادثات بعد",
|
|
615
|
-
translate_start_a_new_conversation: "ابدأ محادثة جديدة",
|
|
616
|
-
translate_untitled: "بدون عنوان",
|
|
617
|
-
translate_new_chat: "محادثة جديدة",
|
|
618
|
-
translate_normal: "عادي",
|
|
619
|
-
translate_debug: "تصحيح",
|
|
620
|
-
translate_type_a_message: "اكتب رسالة...",
|
|
621
|
-
translate_thinking: "جارٍ معالجة الطلب...",
|
|
622
|
-
translate_reasoned: "تم الاستنتاج",
|
|
623
|
-
translate_knowledge_graph_query: "استعلام الرسم البياني المعرفي",
|
|
624
|
-
translate_javascript_code_execution: "تنفيذ كود جافاسكريبت",
|
|
625
|
-
translate_completed: "مكتمل",
|
|
626
|
-
translate_attach_files: "إرفاق ملفات",
|
|
627
|
-
translate_drop_files_here: "أفلت ملفاتك هنا...",
|
|
628
|
-
translate_remove_attachment: "إزالة المرفق",
|
|
629
|
-
translate_attachment_rejected: "لا يمكن إرفاق هذا الملف",
|
|
630
|
-
translate_attachment_caption: "من فضلك اطّلع على الملفات المرفقة.",
|
|
631
|
-
translate_download: "تنزيل",
|
|
632
|
-
translate_tool_status_0: "جارٍ جلب البيانات…",
|
|
633
|
-
translate_tool_status_1: "جارٍ تحليل المعلومات…",
|
|
634
|
-
translate_tool_status_2: "جارٍ معالجة الطلب…",
|
|
635
|
-
translate_tool_status_3: "جارٍ تجميع النتائج…",
|
|
636
|
-
translate_tool_status_4: "جارٍ تحضير الرد…",
|
|
637
|
-
translate_tool_status_5: "جارٍ البحث…",
|
|
638
|
-
translate_tool_status_6: "جارٍ فحص السجلات…",
|
|
639
|
-
translate_tool_status_7: "جارٍ مراجعة التفاصيل…",
|
|
640
|
-
translate_tool_status_8: "جارٍ إجراء الحسابات…",
|
|
641
|
-
translate_tool_status_9: "جارٍ سحب المعلومات…",
|
|
642
|
-
translate_tool_done_0: "تم جلب البيانات بنجاح",
|
|
643
|
-
translate_tool_done_1: "تم التحليل بنجاح",
|
|
644
|
-
translate_tool_done_2: "تمت معالجة الطلب بنجاح",
|
|
645
|
-
translate_tool_done_3: "تم تجميع النتائج بنجاح",
|
|
646
|
-
translate_tool_done_4: "تم تحضير الرد بنجاح",
|
|
647
|
-
translate_tool_done_5: "تم البحث بنجاح",
|
|
648
|
-
translate_tool_done_6: "تم فحص السجلات بنجاح",
|
|
649
|
-
translate_tool_done_7: "تمت المراجعة بنجاح",
|
|
650
|
-
translate_tool_done_8: "تمت الحسابات بنجاح",
|
|
651
|
-
translate_tool_done_9: "تم استرجاع المعلومات بنجاح",
|
|
652
|
-
translate_tool_error: "حدث خطأ",
|
|
653
|
-
translate_attachment_status: "جارٍ قراءة الملف المرفق…",
|
|
654
|
-
translate_attachment_done: "تمت قراءة الملف المرفق",
|
|
655
|
-
translate_graph_0: "جارٍ استكشاف الروابط...",
|
|
656
|
-
translate_graph_1: "جارٍ رسم الخريطة...",
|
|
657
|
-
translate_graph_2: "جارٍ اكتشاف العلاقات...",
|
|
658
|
-
translate_graph_3: "جارٍ تتبع الروابط...",
|
|
659
|
-
translate_graph_4: "جارٍ التنقل في المعرفة...",
|
|
660
|
-
translate_graph_5: "جارٍ كشف الرؤى...",
|
|
661
|
-
translate_graph_6: "جارٍ ربط النقاط...",
|
|
662
|
-
translate_graph_7: "جارٍ تتبع المسار...",
|
|
663
|
-
translate_graph_8: "جارٍ تجميع الأجزاء...",
|
|
664
|
-
translate_graph_9: "جارٍ بناء الصورة...",
|
|
665
|
-
translate_code_0: "جارٍ حساب الأرقام...",
|
|
666
|
-
translate_code_1: "جارٍ معالجة البيانات...",
|
|
667
|
-
translate_code_2: "جارٍ تنفيذ طلبك...",
|
|
668
|
-
translate_code_3: "جارٍ تحليل الأرقام...",
|
|
669
|
-
translate_code_4: "جارٍ تجميع كل شيء...",
|
|
670
|
-
translate_code_5: "جارٍ تحليل النتائج...",
|
|
671
|
-
translate_code_6: "جارٍ العمل خلف الكواليس...",
|
|
672
|
-
translate_code_7: "جارٍ ترتيب التفاصيل...",
|
|
673
|
-
translate_code_8: "جارٍ تحضير إجابتك...",
|
|
674
|
-
translate_code_9: "أوشك على الانتهاء...",
|
|
675
|
-
translate_reasoning_0: "جارٍ التفكير...",
|
|
676
|
-
translate_reasoning_1: "جارٍ دراسة الخيارات...",
|
|
677
|
-
translate_reasoning_2: "جارٍ تقييم الاحتمالات...",
|
|
678
|
-
translate_reasoning_3: "جارٍ التأمل في هذا...",
|
|
679
|
-
translate_reasoning_4: "جارٍ إيجاد الحل...",
|
|
680
|
-
translate_reasoning_5: "جارٍ ترتيب الأفكار...",
|
|
681
|
-
translate_reasoning_6: "جارٍ التمعن في الأمر...",
|
|
682
|
-
translate_reasoning_7: "جارٍ إيجاد أفضل طريقة...",
|
|
683
|
-
translate_reasoning_8: "جارٍ تنظيم أفكاري...",
|
|
684
|
-
translate_reasoning_9: "أوشك على الانتهاء...",
|
|
685
|
-
translate_running: "قيد التنفيذ",
|
|
686
|
-
translate_aborted: "تم الإلغاء",
|
|
687
|
-
translate_input: "المدخلات",
|
|
688
|
-
translate_output: "المخرجات",
|
|
689
|
-
translate_calling: "جارٍ الاستدعاء",
|
|
690
|
-
translate_input_ready: "المدخلات جاهزة",
|
|
691
|
-
translate_needs_approval: "بحاجة إلى موافقة",
|
|
692
|
-
translate_approved: "تمت الموافقة",
|
|
693
|
-
translate_responded: "تم الرد",
|
|
694
|
-
translate_error: "خطأ",
|
|
695
|
-
translate_approval_requested: "طلب موافقة",
|
|
696
|
-
translate_approval_response: "رد الموافقة",
|
|
697
|
-
translate_waiting_for_approval: "في انتظار الموافقة لتنفيذ هذه الأداة.",
|
|
698
|
-
translate_tool_approved: "تمت الموافقة.",
|
|
699
|
-
translate_tool_response_received: "تم استلام الرد.",
|
|
700
|
-
translate_tokens: "رمز",
|
|
701
|
-
translate_fresh: "جديد",
|
|
702
|
-
translate_cache_read: "قراءة من الذاكرة",
|
|
703
|
-
translate_cache_write: "كتابة في الذاكرة",
|
|
704
|
-
translate_n_percent_cached: "{{percent}}٪ مخزّن مؤقتًا",
|
|
705
|
-
translate_text: "نص",
|
|
706
|
-
translate_reasoning: "الاستنتاج",
|
|
707
|
-
translate_read: "قراءة",
|
|
708
|
-
translate_write: "كتابة",
|
|
709
|
-
translate_total: "الإجمالي",
|
|
710
|
-
translate_request: "الطلب",
|
|
711
|
-
translate_response: "الرد",
|
|
712
|
-
translate_step_n: "الخطوة {{number}}",
|
|
713
|
-
translate_inspect_llm_requests: "فحص طلبات النموذج",
|
|
714
|
-
translate_loading: "جارٍ التحميل…",
|
|
715
|
-
translate_no_llm_requests: "لا توجد طلبات نموذج مسجّلة لهذه الرسالة.",
|
|
716
|
-
translate_unhandled_type: "نوع غير مدعوم:"
|
|
717
|
-
};
|
|
718
|
-
// ../../internal/client/src/i18n/en.json
|
|
719
|
-
var en_default = {
|
|
720
|
-
translate_new: "New",
|
|
721
|
-
translate_threads: "Threads",
|
|
722
|
-
translate_n_conversations: "{{count}} conversations",
|
|
723
|
-
translate_one_conversation: "1 conversation",
|
|
724
|
-
translate_no_threads_yet: "No threads yet",
|
|
725
|
-
translate_start_a_new_conversation: "Start a new conversation",
|
|
726
|
-
translate_untitled: "Untitled",
|
|
727
|
-
translate_new_chat: "New Chat",
|
|
728
|
-
translate_normal: "Normal",
|
|
729
|
-
translate_debug: "Debug",
|
|
730
|
-
translate_type_a_message: "Type a message...",
|
|
731
|
-
translate_thinking: "Thinking things through...",
|
|
732
|
-
translate_reasoned: "Reasoned",
|
|
733
|
-
translate_knowledge_graph_query: "Knowledge Graph Query",
|
|
734
|
-
translate_javascript_code_execution: "JavaScript Code Execution",
|
|
735
|
-
translate_completed: "Completed",
|
|
736
|
-
translate_attach_files: "Attach files",
|
|
737
|
-
translate_drop_files_here: "Drop your files here...",
|
|
738
|
-
translate_remove_attachment: "Remove attachment",
|
|
739
|
-
translate_attachment_rejected: "This file cannot be attached",
|
|
740
|
-
translate_attachment_caption: "Please take a look at the attached files.",
|
|
741
|
-
translate_download: "Download",
|
|
742
|
-
translate_tool_status_0: "Fetching data...",
|
|
743
|
-
translate_tool_status_1: "Analyzing information...",
|
|
744
|
-
translate_tool_status_2: "Processing request...",
|
|
745
|
-
translate_tool_status_3: "Gathering results...",
|
|
746
|
-
translate_tool_status_4: "Preparing response...",
|
|
747
|
-
translate_tool_status_5: "Looking things up...",
|
|
748
|
-
translate_tool_status_6: "Checking records...",
|
|
749
|
-
translate_tool_status_7: "Reviewing details...",
|
|
750
|
-
translate_tool_status_8: "Running calculations...",
|
|
751
|
-
translate_tool_status_9: "Pulling information...",
|
|
752
|
-
translate_tool_done_0: "Data fetched successfully",
|
|
753
|
-
translate_tool_done_1: "Analysis completed successfully",
|
|
754
|
-
translate_tool_done_2: "Request processed successfully",
|
|
755
|
-
translate_tool_done_3: "Results gathered successfully",
|
|
756
|
-
translate_tool_done_4: "Response prepared successfully",
|
|
757
|
-
translate_tool_done_5: "Lookup completed successfully",
|
|
758
|
-
translate_tool_done_6: "Records checked successfully",
|
|
759
|
-
translate_tool_done_7: "Review completed successfully",
|
|
760
|
-
translate_tool_done_8: "Calculations completed successfully",
|
|
761
|
-
translate_tool_done_9: "Information retrieved successfully",
|
|
762
|
-
translate_tool_error: "Something went wrong",
|
|
763
|
-
translate_attachment_status: "Reading the attached file...",
|
|
764
|
-
translate_attachment_done: "Finished reading the file",
|
|
765
|
-
translate_graph_0: "Exploring connections...",
|
|
766
|
-
translate_graph_1: "Mapping out the links...",
|
|
767
|
-
translate_graph_2: "Discovering relationships...",
|
|
768
|
-
translate_graph_3: "Tracing the connections...",
|
|
769
|
-
translate_graph_4: "Navigating the knowledge...",
|
|
770
|
-
translate_graph_5: "Uncovering insights...",
|
|
771
|
-
translate_graph_6: "Connecting the dots...",
|
|
772
|
-
translate_graph_7: "Following the trail...",
|
|
773
|
-
translate_graph_8: "Piecing things together...",
|
|
774
|
-
translate_graph_9: "Building the picture...",
|
|
775
|
-
translate_code_0: "Running the numbers...",
|
|
776
|
-
translate_code_1: "Working through the data...",
|
|
777
|
-
translate_code_2: "Processing your request...",
|
|
778
|
-
translate_code_3: "Crunching the figures...",
|
|
779
|
-
translate_code_4: "Putting it all together...",
|
|
780
|
-
translate_code_5: "Analyzing the results...",
|
|
781
|
-
translate_code_6: "Working behind the scenes...",
|
|
782
|
-
translate_code_7: "Sorting through the details...",
|
|
783
|
-
translate_code_8: "Preparing your answer...",
|
|
784
|
-
translate_code_9: "Almost ready...",
|
|
785
|
-
translate_reasoning_0: "Thinking it through...",
|
|
786
|
-
translate_reasoning_1: "Considering the options...",
|
|
787
|
-
translate_reasoning_2: "Weighing the possibilities...",
|
|
788
|
-
translate_reasoning_3: "Reflecting on this...",
|
|
789
|
-
translate_reasoning_4: "Working it out...",
|
|
790
|
-
translate_reasoning_5: "Putting thoughts together...",
|
|
791
|
-
translate_reasoning_6: "Mulling it over...",
|
|
792
|
-
translate_reasoning_7: "Finding the best approach...",
|
|
793
|
-
translate_reasoning_8: "Organizing my thoughts...",
|
|
794
|
-
translate_reasoning_9: "Almost there...",
|
|
795
|
-
translate_running: "Running",
|
|
796
|
-
translate_aborted: "Aborted",
|
|
797
|
-
translate_input: "Input",
|
|
798
|
-
translate_output: "Output",
|
|
799
|
-
translate_calling: "Calling",
|
|
800
|
-
translate_input_ready: "Input ready",
|
|
801
|
-
translate_needs_approval: "Needs approval",
|
|
802
|
-
translate_approved: "Approved",
|
|
803
|
-
translate_responded: "Responded",
|
|
804
|
-
translate_error: "Error",
|
|
805
|
-
translate_approval_requested: "Approval requested",
|
|
806
|
-
translate_approval_response: "Approval response",
|
|
807
|
-
translate_waiting_for_approval: "Waiting for approval to execute this tool.",
|
|
808
|
-
translate_tool_approved: "Approved.",
|
|
809
|
-
translate_tool_response_received: "Response received.",
|
|
810
|
-
translate_tokens: "tokens",
|
|
811
|
-
translate_fresh: "Fresh",
|
|
812
|
-
translate_cache_read: "Cache read",
|
|
813
|
-
translate_cache_write: "Cache write",
|
|
814
|
-
translate_n_percent_cached: "{{percent}}% cached",
|
|
815
|
-
translate_text: "Text",
|
|
816
|
-
translate_reasoning: "Reasoning",
|
|
817
|
-
translate_read: "Read",
|
|
818
|
-
translate_write: "Write",
|
|
819
|
-
translate_total: "Total",
|
|
820
|
-
translate_request: "Request",
|
|
821
|
-
translate_response: "Response",
|
|
822
|
-
translate_step_n: "Step {{number}}",
|
|
823
|
-
translate_inspect_llm_requests: "Inspect LLM requests",
|
|
824
|
-
translate_loading: "loading…",
|
|
825
|
-
translate_no_llm_requests: "No LLM requests recorded for this message.",
|
|
826
|
-
translate_unhandled_type: "Unhandled type:"
|
|
827
|
-
};
|
|
828
|
-
|
|
829
|
-
// ../../internal/client/src/i18n.ts
|
|
830
|
-
var translations = { en: en_default, ar: ar_default };
|
|
831
|
-
function translate(locale, key, params) {
|
|
832
|
-
const table = translations[locale] ?? translations["en"];
|
|
833
|
-
const value = table?.[key] ?? translations["en"]?.[key] ?? key;
|
|
834
|
-
if (!params)
|
|
835
|
-
return value;
|
|
836
|
-
return value.replace(/\{\{\s*(\w+)\s*\}\}/g, (match, name) => (name in params) ? String(params[name]) : match);
|
|
837
|
-
}
|
|
838
|
-
// ../../internal/client/src/utils/deep-parse-json.ts
|
|
839
|
-
function deepParseJson(value) {
|
|
840
|
-
if (typeof value === "string") {
|
|
841
|
-
const trimmed = value.trim();
|
|
842
|
-
const looksLikeJson = trimmed.startsWith("{") && trimmed.endsWith("}") || trimmed.startsWith("[") && trimmed.endsWith("]");
|
|
843
|
-
if (!looksLikeJson)
|
|
844
|
-
return value;
|
|
845
|
-
try {
|
|
846
|
-
return deepParseJson(JSON.parse(trimmed));
|
|
847
|
-
} catch {
|
|
848
|
-
return value;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
if (Array.isArray(value)) {
|
|
852
|
-
return value.map((item) => deepParseJson(item));
|
|
853
|
-
}
|
|
854
|
-
if (value !== null && typeof value === "object") {
|
|
855
|
-
const result = {};
|
|
856
|
-
for (const [key, val] of Object.entries(value)) {
|
|
857
|
-
result[key] = deepParseJson(val);
|
|
858
|
-
}
|
|
859
|
-
return result;
|
|
860
|
-
}
|
|
861
|
-
return value;
|
|
862
|
-
}
|
|
863
|
-
// ../../internal/client/src/utils/describe-json-value.ts
|
|
864
|
-
function describeJsonValue(value, path) {
|
|
865
|
-
if (Array.isArray(value)) {
|
|
866
|
-
const items = value;
|
|
867
|
-
return {
|
|
868
|
-
kind: "container",
|
|
869
|
-
open: "[",
|
|
870
|
-
close: "]",
|
|
871
|
-
summary: count(items.length, "item", "items"),
|
|
872
|
-
entries: items.map((item, index) => ({
|
|
873
|
-
key: null,
|
|
874
|
-
value: item,
|
|
875
|
-
path: `${path}[${index}]`
|
|
876
|
-
}))
|
|
877
|
-
};
|
|
878
|
-
}
|
|
879
|
-
if (value !== null && typeof value === "object") {
|
|
880
|
-
const entries = Object.entries(value);
|
|
881
|
-
return {
|
|
882
|
-
kind: "container",
|
|
883
|
-
open: "{",
|
|
884
|
-
close: "}",
|
|
885
|
-
summary: count(entries.length, "property", "properties"),
|
|
886
|
-
entries: entries.map(([key, entryValue]) => ({
|
|
887
|
-
key,
|
|
888
|
-
value: entryValue,
|
|
889
|
-
path: `${path}.${key}`
|
|
890
|
-
}))
|
|
891
|
-
};
|
|
892
|
-
}
|
|
893
|
-
return {
|
|
894
|
-
kind: "primitive",
|
|
895
|
-
text: formatPrimitive(value),
|
|
896
|
-
className: primitiveClass(value)
|
|
897
|
-
};
|
|
898
|
-
}
|
|
899
|
-
function count(total, singular, plural) {
|
|
900
|
-
return `${total} ${total === 1 ? singular : plural}`;
|
|
901
|
-
}
|
|
902
|
-
function formatPrimitive(value) {
|
|
903
|
-
if (value === null || value === undefined)
|
|
904
|
-
return "null";
|
|
905
|
-
if (typeof value === "string")
|
|
906
|
-
return JSON.stringify(value);
|
|
907
|
-
if (typeof value === "number" || typeof value === "boolean")
|
|
908
|
-
return String(value);
|
|
909
|
-
return JSON.stringify(value) ?? "null";
|
|
910
|
-
}
|
|
911
|
-
function primitiveClass(value) {
|
|
912
|
-
if (value === null || value === undefined)
|
|
913
|
-
return "jt-null";
|
|
914
|
-
if (typeof value === "string")
|
|
915
|
-
return "jt-string";
|
|
916
|
-
if (typeof value === "number")
|
|
917
|
-
return "jt-number";
|
|
918
|
-
if (typeof value === "boolean")
|
|
919
|
-
return "jt-boolean";
|
|
920
|
-
return "";
|
|
921
|
-
}
|
|
922
|
-
// ../../internal/client/src/utils/json-text.ts
|
|
923
|
-
function parseJsonText(value) {
|
|
924
|
-
if (!value)
|
|
925
|
-
return null;
|
|
926
|
-
try {
|
|
927
|
-
return JSON.parse(value);
|
|
928
|
-
} catch {
|
|
929
|
-
return value;
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
function prettyJsonText(value) {
|
|
933
|
-
if (!value)
|
|
934
|
-
return "";
|
|
935
|
-
try {
|
|
936
|
-
return JSON.stringify(JSON.parse(value), null, 2);
|
|
937
|
-
} catch {
|
|
938
|
-
return value;
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
// ../../internal/client/src/utils/relative-time.ts
|
|
942
|
-
var UNITS = [
|
|
943
|
-
["year", 31536000000],
|
|
944
|
-
["month", 2592000000],
|
|
945
|
-
["week", 604800000],
|
|
946
|
-
["day", 86400000],
|
|
947
|
-
["hour", 3600000],
|
|
948
|
-
["minute", 60000],
|
|
949
|
-
["second", 1000]
|
|
950
|
-
];
|
|
951
|
-
function relativeTimeLabel(iso, locale, now = Date.now()) {
|
|
952
|
-
const at = Date.parse(iso);
|
|
953
|
-
if (Number.isNaN(at))
|
|
954
|
-
return "";
|
|
955
|
-
const elapsed = at - now;
|
|
956
|
-
const [unit, ms] = UNITS.find(([, size]) => Math.abs(elapsed) >= size) ?? UNITS[UNITS.length - 1];
|
|
957
|
-
return new Intl.RelativeTimeFormat(locale, { numeric: "auto" }).format(Math.round(elapsed / ms), unit);
|
|
958
|
-
}
|
|
959
|
-
// ../../internal/client/src/utils/save-blob.ts
|
|
960
|
-
function saveBlob(blob, name) {
|
|
961
|
-
const url = URL.createObjectURL(blob);
|
|
962
|
-
const link = document.createElement("a");
|
|
963
|
-
link.href = url;
|
|
964
|
-
link.download = name;
|
|
965
|
-
link.click();
|
|
966
|
-
URL.revokeObjectURL(url);
|
|
967
|
-
}
|
|
968
|
-
// ../../internal/client/src/utils/stream-text-smoother.ts
|
|
969
|
-
class StreamTextSmoother {
|
|
970
|
-
onUpdate;
|
|
971
|
-
fullText = "";
|
|
972
|
-
displayedLength = 0;
|
|
973
|
-
animationFrameId = null;
|
|
974
|
-
isDone = false;
|
|
975
|
-
static DRAIN_FRACTION = 0.03;
|
|
976
|
-
static MIN_CHARS_PER_FRAME = 1;
|
|
977
|
-
static DONE_DRAIN_FRACTION = 0.1;
|
|
978
|
-
constructor(onUpdate) {
|
|
979
|
-
this.onUpdate = onUpdate;
|
|
980
|
-
}
|
|
981
|
-
seed(displayedText) {
|
|
982
|
-
this.fullText = displayedText;
|
|
983
|
-
this.displayedLength = displayedText.length;
|
|
984
|
-
this.onUpdate(displayedText);
|
|
985
|
-
}
|
|
986
|
-
update(newFullText, done) {
|
|
987
|
-
this.fullText = newFullText;
|
|
988
|
-
this.isDone = done;
|
|
989
|
-
this.displayedLength = Math.min(this.displayedLength, this.fullText.length);
|
|
990
|
-
if (done && this.displayedLength >= this.fullText.length) {
|
|
991
|
-
this.onUpdate(this.fullText);
|
|
992
|
-
this.stopAnimation();
|
|
993
|
-
return;
|
|
994
|
-
}
|
|
995
|
-
if (!this.animationFrameId) {
|
|
996
|
-
this.scheduleFrame();
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
destroy() {
|
|
1000
|
-
this.stopAnimation();
|
|
1001
|
-
}
|
|
1002
|
-
scheduleFrame() {
|
|
1003
|
-
this.animationFrameId = requestAnimationFrame(() => this.tick());
|
|
1004
|
-
}
|
|
1005
|
-
tick() {
|
|
1006
|
-
const bufferSize = this.fullText.length - this.displayedLength;
|
|
1007
|
-
if (bufferSize <= 0) {
|
|
1008
|
-
this.animationFrameId = null;
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
|
-
const fraction = this.isDone ? StreamTextSmoother.DONE_DRAIN_FRACTION : StreamTextSmoother.DRAIN_FRACTION;
|
|
1012
|
-
const charsToRelease = Math.max(StreamTextSmoother.MIN_CHARS_PER_FRAME, Math.ceil(bufferSize * fraction));
|
|
1013
|
-
this.displayedLength = Math.min(this.fullText.length, this.displayedLength + charsToRelease);
|
|
1014
|
-
this.onUpdate(this.fullText.substring(0, this.displayedLength));
|
|
1015
|
-
if (this.displayedLength < this.fullText.length) {
|
|
1016
|
-
this.scheduleFrame();
|
|
1017
|
-
} else {
|
|
1018
|
-
this.animationFrameId = null;
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
stopAnimation() {
|
|
1022
|
-
if (this.animationFrameId) {
|
|
1023
|
-
cancelAnimationFrame(this.animationFrameId);
|
|
1024
|
-
this.animationFrameId = null;
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
// ../../internal/client/src/utils/token-usage.ts
|
|
1029
|
-
function cachePercent(usage) {
|
|
1030
|
-
if (usage.input.total <= 0)
|
|
1031
|
-
return null;
|
|
1032
|
-
return Math.round(usage.input.cacheRead / usage.input.total * 100);
|
|
1033
|
-
}
|
|
1034
|
-
// src/chat-session.tsx
|
|
1035
|
-
import { useEffect, useLayoutEffect, useMemo, useRef } from "react";
|
|
1036
|
-
import { useChat } from "@tanstack/ai-react";
|
|
1037
|
-
function ChatSession(props) {
|
|
1038
|
-
const { thread, api, patchUi } = props;
|
|
1039
|
-
const alive = useRef(true);
|
|
1040
|
-
const ownsRun = useRef(false);
|
|
1041
|
-
const serverAnswered = useRef(false);
|
|
1042
|
-
const wasAborted = useRef(false);
|
|
1043
|
-
const wasWorking = useRef(false);
|
|
1044
|
-
const dispatchedToolCalls = useRef(new Set);
|
|
1045
|
-
const refreshing = useRef(Promise.resolve());
|
|
1046
|
-
const connection = useMemo(() => createCortexConnection({
|
|
1047
|
-
api,
|
|
1048
|
-
thread: { id: thread.id, isRunning: thread.isRunning },
|
|
1049
|
-
mode: props.mode,
|
|
1050
|
-
onHydrated: (rows, messages) => {
|
|
1051
|
-
if (!alive.current)
|
|
1052
|
-
return;
|
|
1053
|
-
patchUi({
|
|
1054
|
-
messageMetadata: metadataByMessageId(rows),
|
|
1055
|
-
hasPendingToolCalls: unansweredToolCalls(messages).length > 0
|
|
1056
|
-
});
|
|
1057
|
-
},
|
|
1058
|
-
setLoadingMessages: (loading) => {
|
|
1059
|
-
if (alive.current)
|
|
1060
|
-
patchUi({ isLoadingMessages: loading });
|
|
1061
|
-
}
|
|
1062
|
-
}), []);
|
|
1063
|
-
const chat = useChat({
|
|
1064
|
-
threadId: thread.id,
|
|
1065
|
-
persistence: true,
|
|
1066
|
-
connection,
|
|
1067
|
-
onChunk: () => {
|
|
1068
|
-
if (!alive.current)
|
|
1069
|
-
return;
|
|
1070
|
-
serverAnswered.current = true;
|
|
1071
|
-
},
|
|
1072
|
-
onError: () => {
|
|
1073
|
-
if (!alive.current)
|
|
1074
|
-
return;
|
|
1075
|
-
patchUi({ hasPendingToolCalls: false });
|
|
1076
|
-
if (serverAnswered.current)
|
|
1077
|
-
props.onTurnFinished();
|
|
1078
|
-
else
|
|
1079
|
-
props.onSendFailed();
|
|
1080
|
-
}
|
|
1081
|
-
});
|
|
1082
|
-
const chatRef = useRef(chat);
|
|
1083
|
-
chatRef.current = chat;
|
|
1084
|
-
const isLoadingRef = useRef(chat.isLoading);
|
|
1085
|
-
isLoadingRef.current = chat.isLoading;
|
|
1086
|
-
function syncPendingToolCalls() {
|
|
1087
|
-
const pending = unansweredToolCalls(chatRef.current.messages);
|
|
1088
|
-
patchUi({ hasPendingToolCalls: pending.length > 0 });
|
|
1089
|
-
return pending;
|
|
1090
|
-
}
|
|
1091
|
-
async function resolveToolCall(call, onToolCall) {
|
|
1092
|
-
const result = onToolCall({ toolCallId: call.id, toolName: call.name, input: call.input }, { threadId: thread.id });
|
|
1093
|
-
if (result === null || result === undefined)
|
|
1094
|
-
return;
|
|
1095
|
-
const output = await Promise.resolve(result);
|
|
1096
|
-
if (output === null || output === undefined)
|
|
1097
|
-
return;
|
|
1098
|
-
if (!alive.current)
|
|
1099
|
-
return;
|
|
1100
|
-
await chatRef.current.addToolResult({ toolCallId: call.id, tool: call.name, output });
|
|
1101
|
-
syncPendingToolCalls();
|
|
1102
|
-
}
|
|
1103
|
-
function dispatchPendingToolCalls() {
|
|
1104
|
-
const pending = syncPendingToolCalls();
|
|
1105
|
-
const onToolCall = props.configRef.current.hooks?.onToolCall;
|
|
1106
|
-
if (!onToolCall)
|
|
1107
|
-
return pending.length > 0;
|
|
1108
|
-
for (const call of pending) {
|
|
1109
|
-
if (call.state !== "input-complete")
|
|
1110
|
-
continue;
|
|
1111
|
-
if (dispatchedToolCalls.current.has(call.id))
|
|
1112
|
-
continue;
|
|
1113
|
-
dispatchedToolCalls.current.add(call.id);
|
|
1114
|
-
resolveToolCall(call, onToolCall);
|
|
1115
|
-
}
|
|
1116
|
-
return pending.length > 0;
|
|
1117
|
-
}
|
|
1118
|
-
async function readBackMessages(threadId) {
|
|
1119
|
-
if (!alive.current || threadId !== thread.id)
|
|
1120
|
-
return;
|
|
1121
|
-
await settleTurn({
|
|
1122
|
-
api,
|
|
1123
|
-
threadId,
|
|
1124
|
-
isStale: () => !alive.current,
|
|
1125
|
-
isStreaming: () => isLoadingRef.current,
|
|
1126
|
-
absorbMetadata: (metadata) => patchUi({ messageMetadata: metadata }),
|
|
1127
|
-
setMessages: (messages) => {
|
|
1128
|
-
chatRef.current.setMessages(messages);
|
|
1129
|
-
patchUi({ hasPendingToolCalls: unansweredToolCalls(messages).length > 0 });
|
|
1130
|
-
}
|
|
1131
|
-
});
|
|
1132
|
-
}
|
|
1133
|
-
function refreshMessages(threadId) {
|
|
1134
|
-
refreshing.current = refreshing.current.then(() => readBackMessages(threadId));
|
|
1135
|
-
return refreshing.current;
|
|
1136
|
-
}
|
|
1137
|
-
async function settleSession() {
|
|
1138
|
-
if (wasAborted.current) {
|
|
1139
|
-
wasAborted.current = false;
|
|
1140
|
-
return;
|
|
1141
|
-
}
|
|
1142
|
-
if (ownsRun.current && dispatchPendingToolCalls())
|
|
1143
|
-
return;
|
|
1144
|
-
await refreshMessages(thread.id);
|
|
1145
|
-
}
|
|
1146
|
-
async function performSend(prompt, attachments) {
|
|
1147
|
-
props.setRunning(thread.id, true);
|
|
1148
|
-
ownsRun.current = true;
|
|
1149
|
-
serverAnswered.current = false;
|
|
1150
|
-
const message = {
|
|
1151
|
-
id: crypto.randomUUID(),
|
|
1152
|
-
role: "user",
|
|
1153
|
-
parts: [{ type: "text", content: prompt }]
|
|
1154
|
-
};
|
|
1155
|
-
if (attachments.length) {
|
|
1156
|
-
patchUi((previous) => ({
|
|
1157
|
-
messageMetadata: new Map(previous.messageMetadata).set(message.id, { attachments })
|
|
1158
|
-
}));
|
|
1159
|
-
}
|
|
1160
|
-
await chatRef.current.append(message);
|
|
1161
|
-
}
|
|
1162
|
-
async function abort() {
|
|
1163
|
-
if (!isLoadingRef.current)
|
|
1164
|
-
return;
|
|
1165
|
-
const { aborted } = await api.abortStream(thread.id).catch(() => ({ aborted: false }));
|
|
1166
|
-
if (!alive.current)
|
|
1167
|
-
return;
|
|
1168
|
-
if (aborted) {
|
|
1169
|
-
wasAborted.current = true;
|
|
1170
|
-
props.setRunning(thread.id, false);
|
|
1171
|
-
}
|
|
1172
|
-
chatRef.current.stop();
|
|
1173
|
-
patchUi({ hasPendingToolCalls: false });
|
|
1174
|
-
}
|
|
1175
|
-
function addToolResult(toolCallId, toolName, output) {
|
|
1176
|
-
chatRef.current.addToolResult({ toolCallId, tool: toolName, output }).then(() => syncPendingToolCalls());
|
|
1177
|
-
}
|
|
1178
|
-
function reattach(freshThread) {
|
|
1179
|
-
if (isLoadingRef.current)
|
|
1180
|
-
return;
|
|
1181
|
-
if (freshThread.isRunning) {
|
|
1182
|
-
props.remount(freshThread);
|
|
1183
|
-
return;
|
|
1184
|
-
}
|
|
1185
|
-
refreshMessages(freshThread.id);
|
|
1186
|
-
}
|
|
1187
|
-
useEffect(() => {
|
|
1188
|
-
alive.current = true;
|
|
1189
|
-
return () => {
|
|
1190
|
-
alive.current = false;
|
|
1191
|
-
};
|
|
1192
|
-
}, []);
|
|
1193
|
-
const handleRef = useRef(undefined);
|
|
1194
|
-
handleRef.current = {
|
|
1195
|
-
threadId: thread.id,
|
|
1196
|
-
send: performSend,
|
|
1197
|
-
abort,
|
|
1198
|
-
addToolResult,
|
|
1199
|
-
reattach,
|
|
1200
|
-
refreshMessages: (threadId) => {
|
|
1201
|
-
refreshMessages(threadId);
|
|
1202
|
-
}
|
|
1203
|
-
};
|
|
1204
|
-
useLayoutEffect(() => {
|
|
1205
|
-
props.sessionRef.current = handleRef.current;
|
|
1206
|
-
});
|
|
1207
|
-
useLayoutEffect(() => {
|
|
1208
|
-
return () => {
|
|
1209
|
-
if (props.sessionRef.current === handleRef.current) {
|
|
1210
|
-
props.sessionRef.current = undefined;
|
|
1211
|
-
}
|
|
1212
|
-
};
|
|
1213
|
-
}, []);
|
|
1214
|
-
useEffect(() => {
|
|
1215
|
-
if (!props.pendingSendRef.current.length)
|
|
1216
|
-
return;
|
|
1217
|
-
const timer = setTimeout(() => {
|
|
1218
|
-
const pending = props.pendingSendRef.current;
|
|
1219
|
-
props.pendingSendRef.current = [];
|
|
1220
|
-
(async () => {
|
|
1221
|
-
for (const { prompt, attachments } of pending) {
|
|
1222
|
-
await performSend(prompt, attachments);
|
|
1223
|
-
}
|
|
1224
|
-
})();
|
|
1225
|
-
});
|
|
1226
|
-
return () => clearTimeout(timer);
|
|
1227
|
-
}, []);
|
|
1228
|
-
useEffect(() => {
|
|
1229
|
-
patchUi({ messages: chat.messages });
|
|
1230
|
-
}, [chat.messages]);
|
|
1231
|
-
useEffect(() => {
|
|
1232
|
-
patchUi({ isAgentWorking: chat.isLoading });
|
|
1233
|
-
if (chat.isLoading) {
|
|
1234
|
-
wasWorking.current = true;
|
|
1235
|
-
return;
|
|
1236
|
-
}
|
|
1237
|
-
if (!wasWorking.current)
|
|
1238
|
-
return;
|
|
1239
|
-
wasWorking.current = false;
|
|
1240
|
-
props.onTurnFinished();
|
|
1241
|
-
settleSession();
|
|
1242
|
-
}, [chat.isLoading]);
|
|
1243
|
-
return null;
|
|
1244
|
-
}
|
|
1245
|
-
|
|
1246
|
-
// src/context.ts
|
|
1247
|
-
import { createContext, useContext } from "react";
|
|
1248
|
-
var CortexContext = createContext(undefined);
|
|
1249
|
-
function useCortex() {
|
|
1250
|
-
const value = useContext(CortexContext);
|
|
1251
|
-
if (!value)
|
|
1252
|
-
throw new Error("useCortex must be used inside <CortexChatWidget>");
|
|
1253
|
-
return value;
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
|
-
// src/cx.ts
|
|
1257
|
-
function cx(...parts) {
|
|
1258
|
-
return parts.filter(Boolean).join(" ");
|
|
1259
|
-
}
|
|
1260
|
-
|
|
1261
|
-
// src/components/ChatComposer.tsx
|
|
1262
|
-
import { forwardRef, useEffect as useEffect2, useImperativeHandle, useRef as useRef2, useState } from "react";
|
|
1263
|
-
|
|
1264
|
-
// src/components/AttachmentQueue.tsx
|
|
1265
|
-
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
1266
|
-
function AttachmentQueue() {
|
|
1267
|
-
const { queue, t } = useCortex();
|
|
1268
|
-
if (!queue.items.length)
|
|
1269
|
-
return null;
|
|
1270
|
-
return /* @__PURE__ */ jsxDEV("div", {
|
|
1271
|
-
className: "cortex-attachment-queue",
|
|
1272
|
-
children: queue.items.map((item) => /* @__PURE__ */ jsxDEV("div", {
|
|
1273
|
-
className: cx("cortex-attachment-chip", item.status === "error" && "cortex-attachment-chip--error"),
|
|
1274
|
-
title: item.status === "error" ? t("translate_attachment_rejected") : "",
|
|
1275
|
-
children: [
|
|
1276
|
-
item.status === "uploading" || item.status === "deleting" ? /* @__PURE__ */ jsxDEV("svg", {
|
|
1277
|
-
className: "cortex-attachment-chip__spinner",
|
|
1278
|
-
viewBox: "0 0 16 16",
|
|
1279
|
-
fill: "none",
|
|
1280
|
-
children: [
|
|
1281
|
-
/* @__PURE__ */ jsxDEV("circle", {
|
|
1282
|
-
cx: "8",
|
|
1283
|
-
cy: "8",
|
|
1284
|
-
r: "6",
|
|
1285
|
-
stroke: "currentColor",
|
|
1286
|
-
strokeWidth: "2",
|
|
1287
|
-
className: "cortex-attachment-chip__spinner-track"
|
|
1288
|
-
}, undefined, false, undefined, this),
|
|
1289
|
-
/* @__PURE__ */ jsxDEV("path", {
|
|
1290
|
-
d: "M14 8a6 6 0 0 0-6-6",
|
|
1291
|
-
stroke: "currentColor",
|
|
1292
|
-
strokeWidth: "2",
|
|
1293
|
-
strokeLinecap: "round"
|
|
1294
|
-
}, undefined, false, undefined, this)
|
|
1295
|
-
]
|
|
1296
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV("svg", {
|
|
1297
|
-
viewBox: "0 0 16 16",
|
|
1298
|
-
className: "cortex-attachment-chip__icon",
|
|
1299
|
-
fill: "none",
|
|
1300
|
-
children: [
|
|
1301
|
-
/* @__PURE__ */ jsxDEV("path", {
|
|
1302
|
-
d: "M4 1.5h5.172a2 2 0 0 1 1.414.586l2.328 2.328a2 2 0 0 1 .586 1.414V12.5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2Z",
|
|
1303
|
-
stroke: "currentColor",
|
|
1304
|
-
strokeWidth: "1.25"
|
|
1305
|
-
}, undefined, false, undefined, this),
|
|
1306
|
-
/* @__PURE__ */ jsxDEV("path", {
|
|
1307
|
-
d: "M9.5 1.5v2a2 2 0 0 0 2 2h2",
|
|
1308
|
-
stroke: "currentColor",
|
|
1309
|
-
strokeWidth: "1.25",
|
|
1310
|
-
strokeLinecap: "round"
|
|
1311
|
-
}, undefined, false, undefined, this)
|
|
1312
|
-
]
|
|
1313
|
-
}, undefined, true, undefined, this),
|
|
1314
|
-
/* @__PURE__ */ jsxDEV("span", {
|
|
1315
|
-
className: "cortex-attachment-chip__name",
|
|
1316
|
-
children: item.filename
|
|
1317
|
-
}, undefined, false, undefined, this),
|
|
1318
|
-
/* @__PURE__ */ jsxDEV("button", {
|
|
1319
|
-
type: "button",
|
|
1320
|
-
onClick: () => queue.remove(item.localId),
|
|
1321
|
-
className: "cortex-attachment-chip__remove",
|
|
1322
|
-
disabled: item.status === "deleting",
|
|
1323
|
-
"aria-label": t("translate_remove_attachment"),
|
|
1324
|
-
children: /* @__PURE__ */ jsxDEV("svg", {
|
|
1325
|
-
viewBox: "0 0 16 16",
|
|
1326
|
-
fill: "none",
|
|
1327
|
-
children: /* @__PURE__ */ jsxDEV("path", {
|
|
1328
|
-
d: "M4.5 4.5l7 7m0-7l-7 7",
|
|
1329
|
-
stroke: "currentColor",
|
|
1330
|
-
strokeWidth: "1.5",
|
|
1331
|
-
strokeLinecap: "round"
|
|
1332
|
-
}, undefined, false, undefined, this)
|
|
1333
|
-
}, undefined, false, undefined, this)
|
|
1334
|
-
}, undefined, false, undefined, this)
|
|
1335
|
-
]
|
|
1336
|
-
}, item.localId, true, undefined, this))
|
|
1337
|
-
}, undefined, false, undefined, this);
|
|
1338
|
-
}
|
|
1339
|
-
|
|
1340
|
-
// src/components/ChatComposer.tsx
|
|
1341
|
-
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
1342
|
-
var ACCEPTED_TYPES = ATTACHMENT_MIME_TYPES.join(",");
|
|
1343
|
-
var ChatComposer = forwardRef(function ChatComposer2(_props, ref) {
|
|
1344
|
-
const { t, queue, isAgentWorking, send, abort } = useCortex();
|
|
1345
|
-
const [text, setText] = useState("");
|
|
1346
|
-
const [dragging, setDragging] = useState(false);
|
|
1347
|
-
const messageInput = useRef2(null);
|
|
1348
|
-
const fileInput = useRef2(null);
|
|
1349
|
-
useImperativeHandle(ref, () => ({
|
|
1350
|
-
focusInput: () => messageInput.current?.focus()
|
|
1351
|
-
}));
|
|
1352
|
-
const wasWorking = useRef2(isAgentWorking);
|
|
1353
|
-
useEffect2(() => {
|
|
1354
|
-
if (wasWorking.current && !isAgentWorking)
|
|
1355
|
-
messageInput.current?.focus();
|
|
1356
|
-
wasWorking.current = isAgentWorking;
|
|
1357
|
-
}, [isAgentWorking]);
|
|
1358
|
-
const canSend = !queue.busy && (Boolean(text.trim()) || queue.hasReady);
|
|
1359
|
-
function onSend() {
|
|
1360
|
-
if (isAgentWorking || !canSend) {
|
|
1361
|
-
return;
|
|
1362
|
-
}
|
|
1363
|
-
const captionKey = "translate_attachment_caption";
|
|
1364
|
-
const translated = t(captionKey);
|
|
1365
|
-
const caption = translated !== captionKey ? translated : "Please take a look at the attached files.";
|
|
1366
|
-
const prompt = text.trim() || caption;
|
|
1367
|
-
const attachments = queue.consumeReady();
|
|
1368
|
-
setText("");
|
|
1369
|
-
send(prompt, attachments.map((attachment) => attachment.summary));
|
|
1370
|
-
}
|
|
1371
|
-
function onKeydown(event) {
|
|
1372
|
-
if (event.key === "Enter" && !event.shiftKey) {
|
|
1373
|
-
event.preventDefault();
|
|
1374
|
-
onSend();
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
function onDragOver(event) {
|
|
1378
|
-
event.preventDefault();
|
|
1379
|
-
setDragging(true);
|
|
1380
|
-
}
|
|
1381
|
-
function onDragLeave(event) {
|
|
1382
|
-
const area = event.currentTarget;
|
|
1383
|
-
if (!area.contains(event.relatedTarget)) {
|
|
1384
|
-
setDragging(false);
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
|
-
function onDrop(event) {
|
|
1388
|
-
event.preventDefault();
|
|
1389
|
-
setDragging(false);
|
|
1390
|
-
queue.accept([...event.dataTransfer.files]);
|
|
1391
|
-
}
|
|
1392
|
-
function onPaste(event) {
|
|
1393
|
-
const files = event.clipboardData.files;
|
|
1394
|
-
if (!files.length)
|
|
1395
|
-
return;
|
|
1396
|
-
event.preventDefault();
|
|
1397
|
-
queue.accept([...files]);
|
|
1398
|
-
}
|
|
1399
|
-
return /* @__PURE__ */ jsxDEV2("div", {
|
|
1400
|
-
className: "cortex-widget__input-area",
|
|
1401
|
-
onDragOver,
|
|
1402
|
-
onDragLeave,
|
|
1403
|
-
onDrop,
|
|
1404
|
-
children: [
|
|
1405
|
-
/* @__PURE__ */ jsxDEV2(AttachmentQueue, {}, undefined, false, undefined, this),
|
|
1406
|
-
/* @__PURE__ */ jsxDEV2("div", {
|
|
1407
|
-
className: cx("cortex-widget__input-box", isAgentWorking && "cortex-widget__input-box--disabled", !isAgentWorking && "cortex-widget__input-box--enabled", dragging && "cortex-widget__input-box--dragging"),
|
|
1408
|
-
children: [
|
|
1409
|
-
/* @__PURE__ */ jsxDEV2("textarea", {
|
|
1410
|
-
ref: messageInput,
|
|
1411
|
-
onKeyDown: onKeydown,
|
|
1412
|
-
onPaste,
|
|
1413
|
-
value: text,
|
|
1414
|
-
onChange: (event) => setText(event.target.value),
|
|
1415
|
-
placeholder: dragging ? t("translate_drop_files_here") : isAgentWorking ? "" : t("translate_type_a_message"),
|
|
1416
|
-
disabled: isAgentWorking,
|
|
1417
|
-
rows: 1,
|
|
1418
|
-
className: cx("cortex-widget__textarea", isAgentWorking && "cortex-widget__textarea--disabled")
|
|
1419
|
-
}, undefined, false, undefined, this),
|
|
1420
|
-
isAgentWorking ? /* @__PURE__ */ jsxDEV2("button", {
|
|
1421
|
-
onClick: () => void abort(),
|
|
1422
|
-
className: "cortex-stop-btn",
|
|
1423
|
-
children: [
|
|
1424
|
-
/* @__PURE__ */ jsxDEV2("span", {
|
|
1425
|
-
className: "cortex-stop-btn__ring"
|
|
1426
|
-
}, undefined, false, undefined, this),
|
|
1427
|
-
/* @__PURE__ */ jsxDEV2("svg", {
|
|
1428
|
-
width: "12",
|
|
1429
|
-
height: "12",
|
|
1430
|
-
viewBox: "0 0 12 12",
|
|
1431
|
-
fill: "none",
|
|
1432
|
-
className: "cortex-stop-btn__icon",
|
|
1433
|
-
children: /* @__PURE__ */ jsxDEV2("rect", {
|
|
1434
|
-
x: "1",
|
|
1435
|
-
y: "1",
|
|
1436
|
-
width: "10",
|
|
1437
|
-
height: "10",
|
|
1438
|
-
rx: "2.5",
|
|
1439
|
-
fill: "currentColor"
|
|
1440
|
-
}, undefined, false, undefined, this)
|
|
1441
|
-
}, undefined, false, undefined, this)
|
|
1442
|
-
]
|
|
1443
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV2("div", {
|
|
1444
|
-
className: "cortex-widget__input-actions",
|
|
1445
|
-
children: [
|
|
1446
|
-
/* @__PURE__ */ jsxDEV2("button", {
|
|
1447
|
-
type: "button",
|
|
1448
|
-
onClick: () => fileInput.current?.click(),
|
|
1449
|
-
className: "cortex-widget__attach-btn",
|
|
1450
|
-
"aria-label": t("translate_attach_files"),
|
|
1451
|
-
children: /* @__PURE__ */ jsxDEV2("svg", {
|
|
1452
|
-
width: "16",
|
|
1453
|
-
height: "16",
|
|
1454
|
-
viewBox: "0 0 16 16",
|
|
1455
|
-
fill: "none",
|
|
1456
|
-
children: /* @__PURE__ */ jsxDEV2("path", {
|
|
1457
|
-
d: "M10.5 5.5 6.2 9.8a1.4 1.4 0 0 0 2 2l4.6-4.6a2.8 2.8 0 0 0-4-4L4.2 7.8a4.2 4.2 0 0 0 6 6l4-4",
|
|
1458
|
-
stroke: "currentColor",
|
|
1459
|
-
strokeWidth: "1.3",
|
|
1460
|
-
strokeLinecap: "round",
|
|
1461
|
-
strokeLinejoin: "round"
|
|
1462
|
-
}, undefined, false, undefined, this)
|
|
1463
|
-
}, undefined, false, undefined, this)
|
|
1464
|
-
}, undefined, false, undefined, this),
|
|
1465
|
-
/* @__PURE__ */ jsxDEV2("input", {
|
|
1466
|
-
ref: fileInput,
|
|
1467
|
-
type: "file",
|
|
1468
|
-
multiple: true,
|
|
1469
|
-
accept: ACCEPTED_TYPES,
|
|
1470
|
-
onChange: (event) => {
|
|
1471
|
-
queue.accept([...event.target.files ?? []]);
|
|
1472
|
-
event.target.value = "";
|
|
1473
|
-
},
|
|
1474
|
-
className: "cortex-widget__file-input"
|
|
1475
|
-
}, undefined, false, undefined, this),
|
|
1476
|
-
/* @__PURE__ */ jsxDEV2("button", {
|
|
1477
|
-
onClick: onSend,
|
|
1478
|
-
className: cx("cortex-widget__send-btn", !canSend && "cortex-widget__send-btn--empty", canSend && "cortex-widget__send-btn--ready"),
|
|
1479
|
-
disabled: !canSend,
|
|
1480
|
-
children: /* @__PURE__ */ jsxDEV2("svg", {
|
|
1481
|
-
width: "14",
|
|
1482
|
-
height: "14",
|
|
1483
|
-
viewBox: "0 0 16 16",
|
|
1484
|
-
fill: "none",
|
|
1485
|
-
className: "cortex-widget__send-icon",
|
|
1486
|
-
children: /* @__PURE__ */ jsxDEV2("path", {
|
|
1487
|
-
d: "M3 8h10M9 4l4 4-4 4",
|
|
1488
|
-
stroke: "currentColor",
|
|
1489
|
-
strokeWidth: "1.5",
|
|
1490
|
-
strokeLinecap: "round",
|
|
1491
|
-
strokeLinejoin: "round"
|
|
1492
|
-
}, undefined, false, undefined, this)
|
|
1493
|
-
}, undefined, false, undefined, this)
|
|
1494
|
-
}, undefined, false, undefined, this)
|
|
1495
|
-
]
|
|
1496
|
-
}, undefined, true, undefined, this)
|
|
1497
|
-
]
|
|
1498
|
-
}, undefined, true, undefined, this)
|
|
1499
|
-
]
|
|
1500
|
-
}, undefined, true, undefined, this);
|
|
1501
|
-
});
|
|
1502
|
-
|
|
1503
|
-
// src/components/MessageList.tsx
|
|
1504
|
-
import { useEffect as useEffect5, useRef as useRef7, useState as useState8 } from "react";
|
|
1505
|
-
|
|
1506
|
-
// src/components/MessageAbortedFlag.tsx
|
|
1507
|
-
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
1508
|
-
function MessageAbortedFlag() {
|
|
1509
|
-
const { t } = useCortex();
|
|
1510
|
-
return /* @__PURE__ */ jsxDEV3("div", {
|
|
1511
|
-
className: "cortex-aborted-flag",
|
|
1512
|
-
children: [
|
|
1513
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1514
|
-
className: "cortex-aborted-flag__line"
|
|
1515
|
-
}, undefined, false, undefined, this),
|
|
1516
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1517
|
-
className: "cortex-aborted-flag__label",
|
|
1518
|
-
children: [
|
|
1519
|
-
/* @__PURE__ */ jsxDEV3("svg", {
|
|
1520
|
-
className: "cortex-aborted-flag__icon",
|
|
1521
|
-
width: "12",
|
|
1522
|
-
height: "12",
|
|
1523
|
-
viewBox: "0 0 12 12",
|
|
1524
|
-
fill: "none",
|
|
1525
|
-
children: /* @__PURE__ */ jsxDEV3("path", {
|
|
1526
|
-
d: "M6 1.5v5M6 8.75v.5",
|
|
1527
|
-
stroke: "currentColor",
|
|
1528
|
-
strokeWidth: "1.4",
|
|
1529
|
-
strokeLinecap: "round"
|
|
1530
|
-
}, undefined, false, undefined, this)
|
|
1531
|
-
}, undefined, false, undefined, this),
|
|
1532
|
-
t("translate_aborted")
|
|
1533
|
-
]
|
|
1534
|
-
}, undefined, true, undefined, this),
|
|
1535
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
1536
|
-
className: "cortex-aborted-flag__line"
|
|
1537
|
-
}, undefined, false, undefined, this)
|
|
1538
|
-
]
|
|
1539
|
-
}, undefined, true, undefined, this);
|
|
1540
|
-
}
|
|
1541
|
-
|
|
1542
|
-
// src/components/MessageAttachments.tsx
|
|
1543
|
-
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
1544
|
-
function MessageAttachments(props) {
|
|
1545
|
-
const { api, t } = useCortex();
|
|
1546
|
-
async function download(id) {
|
|
1547
|
-
const { blob, name } = await api.downloadAttachment(id);
|
|
1548
|
-
saveBlob(blob, name);
|
|
1549
|
-
}
|
|
1550
|
-
return /* @__PURE__ */ jsxDEV4("div", {
|
|
1551
|
-
className: "cortex-message-attachments",
|
|
1552
|
-
children: props.attachments.map((attachment) => /* @__PURE__ */ jsxDEV4("button", {
|
|
1553
|
-
type: "button",
|
|
1554
|
-
onClick: () => void download(attachment.id),
|
|
1555
|
-
className: "cortex-message-attachment",
|
|
1556
|
-
"aria-label": `${t("translate_download")}: ${attachment.filename}`,
|
|
1557
|
-
children: [
|
|
1558
|
-
/* @__PURE__ */ jsxDEV4("svg", {
|
|
1559
|
-
viewBox: "0 0 16 16",
|
|
1560
|
-
className: "cortex-message-attachment__icon",
|
|
1561
|
-
fill: "none",
|
|
1562
|
-
children: [
|
|
1563
|
-
/* @__PURE__ */ jsxDEV4("path", {
|
|
1564
|
-
d: "M4 1.5h5.172a2 2 0 0 1 1.414.586l2.328 2.328a2 2 0 0 1 .586 1.414V12.5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2Z",
|
|
1565
|
-
stroke: "currentColor",
|
|
1566
|
-
strokeWidth: "1.25"
|
|
1567
|
-
}, undefined, false, undefined, this),
|
|
1568
|
-
/* @__PURE__ */ jsxDEV4("path", {
|
|
1569
|
-
d: "M9.5 1.5v2a2 2 0 0 0 2 2h2",
|
|
1570
|
-
stroke: "currentColor",
|
|
1571
|
-
strokeWidth: "1.25",
|
|
1572
|
-
strokeLinecap: "round"
|
|
1573
|
-
}, undefined, false, undefined, this)
|
|
1574
|
-
]
|
|
1575
|
-
}, undefined, true, undefined, this),
|
|
1576
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
1577
|
-
className: "cortex-message-attachment__name",
|
|
1578
|
-
children: attachment.filename
|
|
1579
|
-
}, undefined, false, undefined, this),
|
|
1580
|
-
/* @__PURE__ */ jsxDEV4("svg", {
|
|
1581
|
-
viewBox: "0 0 16 16",
|
|
1582
|
-
className: "cortex-message-attachment__dl-icon",
|
|
1583
|
-
fill: "none",
|
|
1584
|
-
children: /* @__PURE__ */ jsxDEV4("path", {
|
|
1585
|
-
d: "M8 3v7m0 0L5.5 7.5M8 10l2.5-2.5M3 13h10",
|
|
1586
|
-
stroke: "currentColor",
|
|
1587
|
-
strokeWidth: "1.5",
|
|
1588
|
-
strokeLinecap: "round",
|
|
1589
|
-
strokeLinejoin: "round"
|
|
1590
|
-
}, undefined, false, undefined, this)
|
|
1591
|
-
}, undefined, false, undefined, this)
|
|
1592
|
-
]
|
|
1593
|
-
}, attachment.id, true, undefined, this))
|
|
1594
|
-
}, undefined, false, undefined, this);
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
// src/components/MessageLlmInspector.tsx
|
|
1598
|
-
import { useRef as useRef4, useState as useState4 } from "react";
|
|
1599
|
-
|
|
1600
|
-
// src/components/CopyButton.tsx
|
|
1601
|
-
import { useRef as useRef3, useState as useState2 } from "react";
|
|
1602
|
-
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
1603
|
-
function CopyButton({ value, className }) {
|
|
1604
|
-
const [copied, setCopied] = useState2(false);
|
|
1605
|
-
const resetTimer = useRef3(null);
|
|
1606
|
-
async function copy(event) {
|
|
1607
|
-
event.stopPropagation();
|
|
1608
|
-
event.preventDefault();
|
|
1609
|
-
try {
|
|
1610
|
-
await navigator.clipboard.writeText(value);
|
|
1611
|
-
setCopied(true);
|
|
1612
|
-
if (resetTimer.current)
|
|
1613
|
-
clearTimeout(resetTimer.current);
|
|
1614
|
-
resetTimer.current = setTimeout(() => setCopied(false), 1500);
|
|
1615
|
-
} catch {}
|
|
1616
|
-
}
|
|
1617
|
-
return /* @__PURE__ */ jsxDEV5("span", {
|
|
1618
|
-
className: cx("cortex-copy-btn", className),
|
|
1619
|
-
children: /* @__PURE__ */ jsxDEV5("button", {
|
|
1620
|
-
className: cx("cortex-copy-btn__button", copied && "cortex-copy-btn__button--copied"),
|
|
1621
|
-
onClick: (event) => void copy(event),
|
|
1622
|
-
"aria-label": copied ? "Copied" : "Copy to clipboard",
|
|
1623
|
-
type: "button",
|
|
1624
|
-
children: copied ? /* @__PURE__ */ jsxDEV5("svg", {
|
|
1625
|
-
className: "cortex-copy-btn__icon cortex-copy-btn__icon--check",
|
|
1626
|
-
width: "13",
|
|
1627
|
-
height: "13",
|
|
1628
|
-
viewBox: "0 0 24 24",
|
|
1629
|
-
fill: "none",
|
|
1630
|
-
children: /* @__PURE__ */ jsxDEV5("path", {
|
|
1631
|
-
d: "M5 13l4 4L19 7",
|
|
1632
|
-
stroke: "currentColor",
|
|
1633
|
-
strokeWidth: "2.5",
|
|
1634
|
-
strokeLinecap: "round",
|
|
1635
|
-
strokeLinejoin: "round"
|
|
1636
|
-
}, undefined, false, undefined, this)
|
|
1637
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5("svg", {
|
|
1638
|
-
className: "cortex-copy-btn__icon",
|
|
1639
|
-
width: "13",
|
|
1640
|
-
height: "13",
|
|
1641
|
-
viewBox: "0 0 24 24",
|
|
1642
|
-
fill: "none",
|
|
1643
|
-
children: [
|
|
1644
|
-
/* @__PURE__ */ jsxDEV5("rect", {
|
|
1645
|
-
x: "9",
|
|
1646
|
-
y: "9",
|
|
1647
|
-
width: "12",
|
|
1648
|
-
height: "12",
|
|
1649
|
-
rx: "2",
|
|
1650
|
-
stroke: "currentColor",
|
|
1651
|
-
strokeWidth: "2"
|
|
1652
|
-
}, undefined, false, undefined, this),
|
|
1653
|
-
/* @__PURE__ */ jsxDEV5("path", {
|
|
1654
|
-
d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",
|
|
1655
|
-
stroke: "currentColor",
|
|
1656
|
-
strokeWidth: "2",
|
|
1657
|
-
strokeLinecap: "round"
|
|
1658
|
-
}, undefined, false, undefined, this)
|
|
1659
|
-
]
|
|
1660
|
-
}, undefined, true, undefined, this)
|
|
1661
|
-
}, undefined, false, undefined, this)
|
|
1662
|
-
}, undefined, false, undefined, this);
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
|
-
// src/components/JsonTree.tsx
|
|
1666
|
-
import { useMemo as useMemo2, useState as useState3 } from "react";
|
|
1667
|
-
import { jsxDEV as jsxDEV6, Fragment } from "react/jsx-dev-runtime";
|
|
1668
|
-
function JsonTree({ data, expandDepth = 1, className }) {
|
|
1669
|
-
const parsedData = useMemo2(() => deepParseJson(data), [data]);
|
|
1670
|
-
const [userToggled, setUserToggled] = useState3({});
|
|
1671
|
-
function isCollapsed(path, depth) {
|
|
1672
|
-
return userToggled[path] ?? depth >= expandDepth;
|
|
1673
|
-
}
|
|
1674
|
-
function toggle(path, depth) {
|
|
1675
|
-
setUserToggled((current) => ({ ...current, [path]: !isCollapsed(path, depth) }));
|
|
1676
|
-
}
|
|
1677
|
-
return /* @__PURE__ */ jsxDEV6("div", {
|
|
1678
|
-
className: cx("cortex-json-tree", className),
|
|
1679
|
-
children: /* @__PURE__ */ jsxDEV6(JsonValue, {
|
|
1680
|
-
value: parsedData,
|
|
1681
|
-
path: "$",
|
|
1682
|
-
depth: 0,
|
|
1683
|
-
isCollapsed,
|
|
1684
|
-
toggle
|
|
1685
|
-
}, undefined, false, undefined, this)
|
|
1686
|
-
}, undefined, false, undefined, this);
|
|
1687
|
-
}
|
|
1688
|
-
function JsonValue({ value, path, depth, isCollapsed, toggle }) {
|
|
1689
|
-
const node = describeJsonValue(value, path);
|
|
1690
|
-
if (node.kind === "primitive")
|
|
1691
|
-
return /* @__PURE__ */ jsxDEV6("span", {
|
|
1692
|
-
className: node.className,
|
|
1693
|
-
children: node.text
|
|
1694
|
-
}, undefined, false, undefined, this);
|
|
1695
|
-
if (node.entries.length === 0) {
|
|
1696
|
-
return /* @__PURE__ */ jsxDEV6("span", {
|
|
1697
|
-
className: "jt-bracket",
|
|
1698
|
-
children: [
|
|
1699
|
-
node.open,
|
|
1700
|
-
node.close
|
|
1701
|
-
]
|
|
1702
|
-
}, undefined, true, undefined, this);
|
|
1703
|
-
}
|
|
1704
|
-
const collapsed = isCollapsed(path, depth);
|
|
1705
|
-
function onToggle(event) {
|
|
1706
|
-
toggle(path, depth);
|
|
1707
|
-
event.stopPropagation();
|
|
1708
|
-
}
|
|
1709
|
-
return /* @__PURE__ */ jsxDEV6(Fragment, {
|
|
1710
|
-
children: [
|
|
1711
|
-
/* @__PURE__ */ jsxDEV6("span", {
|
|
1712
|
-
className: "jt-toggle",
|
|
1713
|
-
onClick: onToggle,
|
|
1714
|
-
role: "button",
|
|
1715
|
-
children: [
|
|
1716
|
-
/* @__PURE__ */ jsxDEV6("span", {
|
|
1717
|
-
className: cx("jt-arrow", collapsed && "jt-arrow--collapsed"),
|
|
1718
|
-
children: "▾"
|
|
1719
|
-
}, undefined, false, undefined, this),
|
|
1720
|
-
/* @__PURE__ */ jsxDEV6("span", {
|
|
1721
|
-
className: "jt-bracket",
|
|
1722
|
-
children: node.open
|
|
1723
|
-
}, undefined, false, undefined, this)
|
|
1724
|
-
]
|
|
1725
|
-
}, undefined, true, undefined, this),
|
|
1726
|
-
collapsed ? /* @__PURE__ */ jsxDEV6(Fragment, {
|
|
1727
|
-
children: [
|
|
1728
|
-
/* @__PURE__ */ jsxDEV6("span", {
|
|
1729
|
-
className: "jt-collapsed-hint",
|
|
1730
|
-
onClick: onToggle,
|
|
1731
|
-
role: "button",
|
|
1732
|
-
children: node.summary
|
|
1733
|
-
}, undefined, false, undefined, this),
|
|
1734
|
-
/* @__PURE__ */ jsxDEV6("span", {
|
|
1735
|
-
className: "jt-bracket",
|
|
1736
|
-
children: node.close
|
|
1737
|
-
}, undefined, false, undefined, this)
|
|
1738
|
-
]
|
|
1739
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV6(Fragment, {
|
|
1740
|
-
children: [
|
|
1741
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
1742
|
-
className: "jt-indent",
|
|
1743
|
-
children: node.entries.map((entry, index) => /* @__PURE__ */ jsxDEV6("div", {
|
|
1744
|
-
className: "jt-line",
|
|
1745
|
-
children: [
|
|
1746
|
-
entry.key !== null && /* @__PURE__ */ jsxDEV6(Fragment, {
|
|
1747
|
-
children: [
|
|
1748
|
-
/* @__PURE__ */ jsxDEV6("span", {
|
|
1749
|
-
className: "jt-key",
|
|
1750
|
-
children: `"${entry.key}"`
|
|
1751
|
-
}, undefined, false, undefined, this),
|
|
1752
|
-
/* @__PURE__ */ jsxDEV6("span", {
|
|
1753
|
-
className: "jt-colon",
|
|
1754
|
-
children: ": "
|
|
1755
|
-
}, undefined, false, undefined, this)
|
|
1756
|
-
]
|
|
1757
|
-
}, undefined, true, undefined, this),
|
|
1758
|
-
/* @__PURE__ */ jsxDEV6(JsonValue, {
|
|
1759
|
-
value: entry.value,
|
|
1760
|
-
path: entry.path,
|
|
1761
|
-
depth: depth + 1,
|
|
1762
|
-
isCollapsed,
|
|
1763
|
-
toggle
|
|
1764
|
-
}, undefined, false, undefined, this),
|
|
1765
|
-
index < node.entries.length - 1 && /* @__PURE__ */ jsxDEV6("span", {
|
|
1766
|
-
className: "jt-comma",
|
|
1767
|
-
children: ","
|
|
1768
|
-
}, undefined, false, undefined, this)
|
|
1769
|
-
]
|
|
1770
|
-
}, entry.path, true, undefined, this))
|
|
1771
|
-
}, undefined, false, undefined, this),
|
|
1772
|
-
/* @__PURE__ */ jsxDEV6("span", {
|
|
1773
|
-
className: "jt-bracket",
|
|
1774
|
-
children: node.close
|
|
1775
|
-
}, undefined, false, undefined, this)
|
|
1776
|
-
]
|
|
1777
|
-
}, undefined, true, undefined, this)
|
|
1778
|
-
]
|
|
1779
|
-
}, undefined, true, undefined, this);
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
// src/format.ts
|
|
1783
|
-
function num(value) {
|
|
1784
|
-
return value.toLocaleString("en-US");
|
|
1785
|
-
}
|
|
1786
|
-
|
|
1787
|
-
// src/components/LlmUsageBreakdown.tsx
|
|
1788
|
-
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
1789
|
-
function LlmUsageBreakdown({ usage }) {
|
|
1790
|
-
const { t } = useCortex();
|
|
1791
|
-
return /* @__PURE__ */ jsxDEV7("div", {
|
|
1792
|
-
className: "cortex-llm-inspector__usage-rows",
|
|
1793
|
-
children: [
|
|
1794
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
1795
|
-
className: "cortex-llm-inspector__usage-row",
|
|
1796
|
-
children: [
|
|
1797
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
1798
|
-
className: "cortex-llm-inspector__usage-lbl",
|
|
1799
|
-
children: t("translate_input")
|
|
1800
|
-
}, undefined, false, undefined, this),
|
|
1801
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
1802
|
-
className: "cortex-llm-inspector__usage-val",
|
|
1803
|
-
children: num(usage.input.total)
|
|
1804
|
-
}, undefined, false, undefined, this),
|
|
1805
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
1806
|
-
className: "cortex-llm-inspector__usage-detail",
|
|
1807
|
-
children: [
|
|
1808
|
-
t("translate_fresh"),
|
|
1809
|
-
" ",
|
|
1810
|
-
num(usage.input.noCache),
|
|
1811
|
-
" · ",
|
|
1812
|
-
t("translate_read"),
|
|
1813
|
-
" ",
|
|
1814
|
-
num(usage.input.cacheRead),
|
|
1815
|
-
" · ",
|
|
1816
|
-
t("translate_write"),
|
|
1817
|
-
" ",
|
|
1818
|
-
num(usage.input.cacheWrite)
|
|
1819
|
-
]
|
|
1820
|
-
}, undefined, true, undefined, this)
|
|
1821
|
-
]
|
|
1822
|
-
}, undefined, true, undefined, this),
|
|
1823
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
1824
|
-
className: "cortex-llm-inspector__usage-row",
|
|
1825
|
-
children: [
|
|
1826
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
1827
|
-
className: "cortex-llm-inspector__usage-lbl",
|
|
1828
|
-
children: t("translate_output")
|
|
1829
|
-
}, undefined, false, undefined, this),
|
|
1830
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
1831
|
-
className: "cortex-llm-inspector__usage-val",
|
|
1832
|
-
children: num(usage.output.total)
|
|
1833
|
-
}, undefined, false, undefined, this),
|
|
1834
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
1835
|
-
className: "cortex-llm-inspector__usage-detail",
|
|
1836
|
-
children: [
|
|
1837
|
-
t("translate_text"),
|
|
1838
|
-
" ",
|
|
1839
|
-
num(usage.output.text),
|
|
1840
|
-
" · ",
|
|
1841
|
-
t("translate_reasoning"),
|
|
1842
|
-
" ",
|
|
1843
|
-
num(usage.output.reasoning)
|
|
1844
|
-
]
|
|
1845
|
-
}, undefined, true, undefined, this)
|
|
1846
|
-
]
|
|
1847
|
-
}, undefined, true, undefined, this),
|
|
1848
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
1849
|
-
className: "cortex-llm-inspector__usage-row cortex-llm-inspector__usage-row--total",
|
|
1850
|
-
children: [
|
|
1851
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
1852
|
-
className: "cortex-llm-inspector__usage-lbl",
|
|
1853
|
-
children: t("translate_total")
|
|
1854
|
-
}, undefined, false, undefined, this),
|
|
1855
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
1856
|
-
className: "cortex-llm-inspector__usage-val",
|
|
1857
|
-
children: num(usage.total)
|
|
1858
|
-
}, undefined, false, undefined, this)
|
|
1859
|
-
]
|
|
1860
|
-
}, undefined, true, undefined, this)
|
|
1861
|
-
]
|
|
1862
|
-
}, undefined, true, undefined, this);
|
|
1863
|
-
}
|
|
1864
|
-
|
|
1865
|
-
// src/components/LlmUsageChips.tsx
|
|
1866
|
-
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
1867
|
-
function LlmUsageChips({ usage }) {
|
|
1868
|
-
const percent = cachePercent(usage);
|
|
1869
|
-
return /* @__PURE__ */ jsxDEV8("span", {
|
|
1870
|
-
children: /* @__PURE__ */ jsxDEV8("span", {
|
|
1871
|
-
className: "cortex-llm-inspector__step-metrics",
|
|
1872
|
-
children: [
|
|
1873
|
-
/* @__PURE__ */ jsxDEV8("span", {
|
|
1874
|
-
className: "cortex-llm-inspector__metric",
|
|
1875
|
-
children: [
|
|
1876
|
-
/* @__PURE__ */ jsxDEV8("span", {
|
|
1877
|
-
className: "cortex-llm-inspector__dot cortex-llm-inspector__dot--input"
|
|
1878
|
-
}, undefined, false, undefined, this),
|
|
1879
|
-
num(usage.input.total)
|
|
1880
|
-
]
|
|
1881
|
-
}, undefined, true, undefined, this),
|
|
1882
|
-
/* @__PURE__ */ jsxDEV8("span", {
|
|
1883
|
-
className: "cortex-llm-inspector__metric",
|
|
1884
|
-
children: [
|
|
1885
|
-
/* @__PURE__ */ jsxDEV8("span", {
|
|
1886
|
-
className: "cortex-llm-inspector__dot cortex-llm-inspector__dot--output"
|
|
1887
|
-
}, undefined, false, undefined, this),
|
|
1888
|
-
num(usage.output.total)
|
|
1889
|
-
]
|
|
1890
|
-
}, undefined, true, undefined, this),
|
|
1891
|
-
percent !== null ? /* @__PURE__ */ jsxDEV8("span", {
|
|
1892
|
-
className: "cortex-llm-inspector__cache-pct",
|
|
1893
|
-
children: [
|
|
1894
|
-
percent,
|
|
1895
|
-
"%"
|
|
1896
|
-
]
|
|
1897
|
-
}, undefined, true, undefined, this) : null
|
|
1898
|
-
]
|
|
1899
|
-
}, undefined, true, undefined, this)
|
|
1900
|
-
}, undefined, false, undefined, this);
|
|
1901
|
-
}
|
|
1902
|
-
|
|
1903
|
-
// src/components/MessageLlmInspector.tsx
|
|
1904
|
-
import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
|
|
1905
|
-
function MessageLlmInspector({ messageId }) {
|
|
1906
|
-
const { t, api } = useCortex();
|
|
1907
|
-
const [open, setOpen] = useState4(false);
|
|
1908
|
-
const [loading, setLoading] = useState4(false);
|
|
1909
|
-
const [requests, setRequests] = useState4([]);
|
|
1910
|
-
const [expandedStep, setExpandedStep] = useState4(null);
|
|
1911
|
-
const [activeTab, setActiveTab] = useState4({});
|
|
1912
|
-
const loaded = useRef4(false);
|
|
1913
|
-
async function toggle() {
|
|
1914
|
-
if (!loaded.current) {
|
|
1915
|
-
setLoading(true);
|
|
1916
|
-
try {
|
|
1917
|
-
setRequests(await api.listLlmRequests(messageId));
|
|
1918
|
-
} finally {
|
|
1919
|
-
setLoading(false);
|
|
1920
|
-
loaded.current = true;
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
setOpen((v) => !v);
|
|
1924
|
-
}
|
|
1925
|
-
function toggleStep(id) {
|
|
1926
|
-
setExpandedStep((current) => current === id ? null : id);
|
|
1927
|
-
}
|
|
1928
|
-
function getTab(id) {
|
|
1929
|
-
return activeTab[id] ?? "prompt";
|
|
1930
|
-
}
|
|
1931
|
-
function setTab(id, tab) {
|
|
1932
|
-
setActiveTab((current) => ({ ...current, [id]: tab }));
|
|
1933
|
-
}
|
|
1934
|
-
return /* @__PURE__ */ jsxDEV9("div", {
|
|
1935
|
-
className: cx("cortex-llm-inspector", open && "cortex-llm-inspector--open"),
|
|
1936
|
-
children: [
|
|
1937
|
-
/* @__PURE__ */ jsxDEV9("button", {
|
|
1938
|
-
className: "cortex-llm-inspector__trigger",
|
|
1939
|
-
onClick: () => void toggle(),
|
|
1940
|
-
children: [
|
|
1941
|
-
/* @__PURE__ */ jsxDEV9("svg", {
|
|
1942
|
-
className: "cortex-llm-inspector__icon",
|
|
1943
|
-
width: "14",
|
|
1944
|
-
height: "14",
|
|
1945
|
-
viewBox: "0 0 16 16",
|
|
1946
|
-
fill: "none",
|
|
1947
|
-
children: /* @__PURE__ */ jsxDEV9("path", {
|
|
1948
|
-
d: "M6 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8ZM0 6a6 6 0 1 1 10.89 3.477l4.817 4.816a1 1 0 0 1-1.414 1.414l-4.816-4.816A6 6 0 0 1 0 6Z",
|
|
1949
|
-
fill: "currentColor"
|
|
1950
|
-
}, undefined, false, undefined, this)
|
|
1951
|
-
}, undefined, false, undefined, this),
|
|
1952
|
-
/* @__PURE__ */ jsxDEV9("span", {
|
|
1953
|
-
children: t("translate_inspect_llm_requests")
|
|
1954
|
-
}, undefined, false, undefined, this),
|
|
1955
|
-
loading ? /* @__PURE__ */ jsxDEV9("span", {
|
|
1956
|
-
className: "cortex-llm-inspector__loading",
|
|
1957
|
-
children: t("translate_loading")
|
|
1958
|
-
}, undefined, false, undefined, this) : requests.length > 0 ? /* @__PURE__ */ jsxDEV9("span", {
|
|
1959
|
-
className: "cortex-llm-inspector__badge",
|
|
1960
|
-
children: requests.length
|
|
1961
|
-
}, undefined, false, undefined, this) : null,
|
|
1962
|
-
/* @__PURE__ */ jsxDEV9("svg", {
|
|
1963
|
-
className: "cortex-llm-inspector__chevron",
|
|
1964
|
-
width: "12",
|
|
1965
|
-
height: "12",
|
|
1966
|
-
viewBox: "0 0 12 12",
|
|
1967
|
-
fill: "none",
|
|
1968
|
-
children: /* @__PURE__ */ jsxDEV9("path", {
|
|
1969
|
-
d: "M3 4.5L6 7.5L9 4.5",
|
|
1970
|
-
stroke: "currentColor",
|
|
1971
|
-
strokeWidth: "1.25",
|
|
1972
|
-
strokeLinecap: "round",
|
|
1973
|
-
strokeLinejoin: "round"
|
|
1974
|
-
}, undefined, false, undefined, this)
|
|
1975
|
-
}, undefined, false, undefined, this)
|
|
1976
|
-
]
|
|
1977
|
-
}, undefined, true, undefined, this),
|
|
1978
|
-
/* @__PURE__ */ jsxDEV9("div", {
|
|
1979
|
-
className: "cortex-llm-inspector__panel-wrapper",
|
|
1980
|
-
children: /* @__PURE__ */ jsxDEV9("div", {
|
|
1981
|
-
className: "cortex-llm-inspector__panel-inner",
|
|
1982
|
-
children: /* @__PURE__ */ jsxDEV9("div", {
|
|
1983
|
-
className: "cortex-llm-inspector__panel",
|
|
1984
|
-
children: [
|
|
1985
|
-
requests.length === 0 && !loading ? /* @__PURE__ */ jsxDEV9("div", {
|
|
1986
|
-
className: "cortex-llm-inspector__empty",
|
|
1987
|
-
children: t("translate_no_llm_requests")
|
|
1988
|
-
}, undefined, false, undefined, this) : null,
|
|
1989
|
-
requests.map((req, idx) => /* @__PURE__ */ jsxDEV9("div", {
|
|
1990
|
-
className: cx("cortex-llm-inspector__step", expandedStep === req.id && "cortex-llm-inspector__step--expanded"),
|
|
1991
|
-
children: [
|
|
1992
|
-
/* @__PURE__ */ jsxDEV9("button", {
|
|
1993
|
-
className: "cortex-llm-inspector__step-header",
|
|
1994
|
-
onClick: () => toggleStep(req.id),
|
|
1995
|
-
children: [
|
|
1996
|
-
/* @__PURE__ */ jsxDEV9("span", {
|
|
1997
|
-
className: "cortex-llm-inspector__step-label",
|
|
1998
|
-
children: t("translate_step_n", { number: idx + 1 })
|
|
1999
|
-
}, undefined, false, undefined, this),
|
|
2000
|
-
req.tokenUsage ? /* @__PURE__ */ jsxDEV9(LlmUsageChips, {
|
|
2001
|
-
usage: req.tokenUsage
|
|
2002
|
-
}, undefined, false, undefined, this) : null,
|
|
2003
|
-
/* @__PURE__ */ jsxDEV9("svg", {
|
|
2004
|
-
className: "cortex-llm-inspector__step-chevron",
|
|
2005
|
-
width: "10",
|
|
2006
|
-
height: "10",
|
|
2007
|
-
viewBox: "0 0 12 12",
|
|
2008
|
-
fill: "none",
|
|
2009
|
-
children: /* @__PURE__ */ jsxDEV9("path", {
|
|
2010
|
-
d: "M3 4.5L6 7.5L9 4.5",
|
|
2011
|
-
stroke: "currentColor",
|
|
2012
|
-
strokeWidth: "1.25",
|
|
2013
|
-
strokeLinecap: "round",
|
|
2014
|
-
strokeLinejoin: "round"
|
|
2015
|
-
}, undefined, false, undefined, this)
|
|
2016
|
-
}, undefined, false, undefined, this)
|
|
2017
|
-
]
|
|
2018
|
-
}, undefined, true, undefined, this),
|
|
2019
|
-
/* @__PURE__ */ jsxDEV9("div", {
|
|
2020
|
-
className: "cortex-llm-inspector__step-body-wrapper",
|
|
2021
|
-
children: /* @__PURE__ */ jsxDEV9("div", {
|
|
2022
|
-
className: "cortex-llm-inspector__step-body-inner",
|
|
2023
|
-
children: /* @__PURE__ */ jsxDEV9("div", {
|
|
2024
|
-
className: "cortex-llm-inspector__step-body",
|
|
2025
|
-
children: [
|
|
2026
|
-
req.tokenUsage ? /* @__PURE__ */ jsxDEV9(LlmUsageBreakdown, {
|
|
2027
|
-
usage: req.tokenUsage
|
|
2028
|
-
}, undefined, false, undefined, this) : null,
|
|
2029
|
-
/* @__PURE__ */ jsxDEV9("div", {
|
|
2030
|
-
className: "cortex-llm-inspector__tabs",
|
|
2031
|
-
children: [
|
|
2032
|
-
/* @__PURE__ */ jsxDEV9("button", {
|
|
2033
|
-
className: cx("cortex-llm-inspector__tab", getTab(req.id) === "prompt" && "cortex-llm-inspector__tab--active"),
|
|
2034
|
-
onClick: () => setTab(req.id, "prompt"),
|
|
2035
|
-
children: t("translate_request")
|
|
2036
|
-
}, undefined, false, undefined, this),
|
|
2037
|
-
/* @__PURE__ */ jsxDEV9("button", {
|
|
2038
|
-
className: cx("cortex-llm-inspector__tab", getTab(req.id) === "response" && "cortex-llm-inspector__tab--active"),
|
|
2039
|
-
onClick: () => setTab(req.id, "response"),
|
|
2040
|
-
children: t("translate_response")
|
|
2041
|
-
}, undefined, false, undefined, this)
|
|
2042
|
-
]
|
|
2043
|
-
}, undefined, true, undefined, this),
|
|
2044
|
-
/* @__PURE__ */ jsxDEV9("div", {
|
|
2045
|
-
className: "cortex-llm-inspector__json-pane",
|
|
2046
|
-
children: [
|
|
2047
|
-
/* @__PURE__ */ jsxDEV9(CopyButton, {
|
|
2048
|
-
className: "cortex-llm-inspector__json-copy",
|
|
2049
|
-
value: getTab(req.id) === "prompt" ? prettyJsonText(req.prompt) : prettyJsonText(req.output)
|
|
2050
|
-
}, undefined, false, undefined, this),
|
|
2051
|
-
getTab(req.id) === "prompt" ? /* @__PURE__ */ jsxDEV9(JsonTree, {
|
|
2052
|
-
data: parseJsonText(req.prompt),
|
|
2053
|
-
expandDepth: 2
|
|
2054
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9(JsonTree, {
|
|
2055
|
-
data: parseJsonText(req.output),
|
|
2056
|
-
expandDepth: 2
|
|
2057
|
-
}, undefined, false, undefined, this)
|
|
2058
|
-
]
|
|
2059
|
-
}, undefined, true, undefined, this)
|
|
2060
|
-
]
|
|
2061
|
-
}, undefined, true, undefined, this)
|
|
2062
|
-
}, undefined, false, undefined, this)
|
|
2063
|
-
}, undefined, false, undefined, this)
|
|
2064
|
-
]
|
|
2065
|
-
}, req.id, true, undefined, this))
|
|
2066
|
-
]
|
|
2067
|
-
}, undefined, true, undefined, this)
|
|
2068
|
-
}, undefined, false, undefined, this)
|
|
2069
|
-
}, undefined, false, undefined, this)
|
|
2070
|
-
]
|
|
2071
|
-
}, undefined, true, undefined, this);
|
|
2072
|
-
}
|
|
2073
|
-
|
|
2074
|
-
// src/components/SubtleActivity.tsx
|
|
2075
|
-
import { useEffect as useEffect3, useRef as useRef5, useState as useState5 } from "react";
|
|
2076
|
-
import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
|
|
2077
|
-
function SubtleActivity({ labels, className }) {
|
|
2078
|
-
const { t } = useCortex();
|
|
2079
|
-
const [currentIndex, setCurrentIndex] = useState5(0);
|
|
2080
|
-
const [labelState, setLabelState] = useState5("idle");
|
|
2081
|
-
const labelCount = useRef5(labels.length);
|
|
2082
|
-
labelCount.current = labels.length;
|
|
2083
|
-
useEffect3(() => {
|
|
2084
|
-
let timeout;
|
|
2085
|
-
let frame;
|
|
2086
|
-
function scheduleNextTransition() {
|
|
2087
|
-
timeout = setTimeout(() => {
|
|
2088
|
-
setLabelState("exiting");
|
|
2089
|
-
timeout = setTimeout(() => {
|
|
2090
|
-
setCurrentIndex((i) => (i + 1) % labelCount.current);
|
|
2091
|
-
setLabelState("enter-start");
|
|
2092
|
-
frame = requestAnimationFrame(() => {
|
|
2093
|
-
setLabelState("entering");
|
|
2094
|
-
timeout = setTimeout(() => {
|
|
2095
|
-
setLabelState("idle");
|
|
2096
|
-
scheduleNextTransition();
|
|
2097
|
-
}, 300);
|
|
2098
|
-
});
|
|
2099
|
-
}, 300);
|
|
2100
|
-
}, 2000);
|
|
2101
|
-
}
|
|
2102
|
-
scheduleNextTransition();
|
|
2103
|
-
return () => {
|
|
2104
|
-
if (timeout)
|
|
2105
|
-
clearTimeout(timeout);
|
|
2106
|
-
if (frame)
|
|
2107
|
-
cancelAnimationFrame(frame);
|
|
2108
|
-
};
|
|
2109
|
-
}, []);
|
|
2110
|
-
return /* @__PURE__ */ jsxDEV10("div", {
|
|
2111
|
-
className: cx("cortex-subtle-activity", className),
|
|
2112
|
-
children: [
|
|
2113
|
-
/* @__PURE__ */ jsxDEV10("div", {
|
|
2114
|
-
className: "cortex-subtle-activity__dots",
|
|
2115
|
-
children: [
|
|
2116
|
-
/* @__PURE__ */ jsxDEV10("span", {
|
|
2117
|
-
className: "cortex-subtle-activity__dot"
|
|
2118
|
-
}, undefined, false, undefined, this),
|
|
2119
|
-
/* @__PURE__ */ jsxDEV10("span", {
|
|
2120
|
-
className: "cortex-subtle-activity__dot cortex-subtle-activity__dot--d1"
|
|
2121
|
-
}, undefined, false, undefined, this),
|
|
2122
|
-
/* @__PURE__ */ jsxDEV10("span", {
|
|
2123
|
-
className: "cortex-subtle-activity__dot cortex-subtle-activity__dot--d2"
|
|
2124
|
-
}, undefined, false, undefined, this)
|
|
2125
|
-
]
|
|
2126
|
-
}, undefined, true, undefined, this),
|
|
2127
|
-
/* @__PURE__ */ jsxDEV10("div", {
|
|
2128
|
-
className: "cortex-subtle-activity__label-mask",
|
|
2129
|
-
children: /* @__PURE__ */ jsxDEV10("span", {
|
|
2130
|
-
className: cx("cortex-subtle-activity__label", `cortex-subtle-activity__label--${labelState}`),
|
|
2131
|
-
children: t(labels[currentIndex])
|
|
2132
|
-
}, undefined, false, undefined, this)
|
|
2133
|
-
}, undefined, false, undefined, this)
|
|
2134
|
-
]
|
|
2135
|
-
}, undefined, true, undefined, this);
|
|
2136
|
-
}
|
|
2137
|
-
|
|
2138
|
-
// src/components/MessageReasoningAnimated.tsx
|
|
2139
|
-
import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
|
|
2140
|
-
var LABELS = activityLabelKeys("reasoning");
|
|
2141
|
-
function MessageReasoningAnimated() {
|
|
2142
|
-
return /* @__PURE__ */ jsxDEV11("div", {
|
|
2143
|
-
className: "cortex-reasoning-animated",
|
|
2144
|
-
children: /* @__PURE__ */ jsxDEV11(SubtleActivity, {
|
|
2145
|
-
labels: LABELS
|
|
2146
|
-
}, undefined, false, undefined, this)
|
|
2147
|
-
}, undefined, false, undefined, this);
|
|
2148
|
-
}
|
|
2149
|
-
|
|
2150
|
-
// src/components/MessageReasoningPart.tsx
|
|
2151
|
-
import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
|
|
2152
|
-
function MessageReasoningPart(props) {
|
|
2153
|
-
const { reasoningPart, streaming = false } = props;
|
|
2154
|
-
const { t } = useCortex();
|
|
2155
|
-
return /* @__PURE__ */ jsxDEV12("details", {
|
|
2156
|
-
className: "cortex-reasoning-details",
|
|
2157
|
-
children: [
|
|
2158
|
-
/* @__PURE__ */ jsxDEV12("summary", {
|
|
2159
|
-
className: "cortex-reasoning-details__summary",
|
|
2160
|
-
children: [
|
|
2161
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
2162
|
-
className: "cortex-reasoning-details__header",
|
|
2163
|
-
children: [
|
|
2164
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
2165
|
-
className: "cortex-reasoning-details__icon",
|
|
2166
|
-
children: /* @__PURE__ */ jsxDEV12("svg", {
|
|
2167
|
-
width: "14",
|
|
2168
|
-
height: "14",
|
|
2169
|
-
viewBox: "0 0 20 20",
|
|
2170
|
-
fill: "none",
|
|
2171
|
-
"aria-hidden": "true",
|
|
2172
|
-
children: [
|
|
2173
|
-
/* @__PURE__ */ jsxDEV12("path", {
|
|
2174
|
-
d: "M10 2C6.686 2 4 4.686 4 8c0 1.655.672 3.154 1.757 4.243.362.363.576.858.576 1.371V14.5a1 1 0 0 0 1 1h5.334a1 1 0 0 0 1-1v-.886c0-.513.214-1.008.576-1.371A5.978 5.978 0 0 0 16 8c0-3.314-2.686-6-6-6Z",
|
|
2175
|
-
stroke: "currentColor",
|
|
2176
|
-
strokeWidth: "1.4",
|
|
2177
|
-
strokeLinecap: "round",
|
|
2178
|
-
strokeLinejoin: "round"
|
|
2179
|
-
}, undefined, false, undefined, this),
|
|
2180
|
-
/* @__PURE__ */ jsxDEV12("path", {
|
|
2181
|
-
d: "M7.5 17.5h5M8.5 8a2 2 0 0 1 2-2",
|
|
2182
|
-
stroke: "currentColor",
|
|
2183
|
-
strokeWidth: "1.4",
|
|
2184
|
-
strokeLinecap: "round",
|
|
2185
|
-
strokeLinejoin: "round"
|
|
2186
|
-
}, undefined, false, undefined, this)
|
|
2187
|
-
]
|
|
2188
|
-
}, undefined, true, undefined, this)
|
|
2189
|
-
}, undefined, false, undefined, this),
|
|
2190
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
2191
|
-
className: "cortex-reasoning-details__title-group",
|
|
2192
|
-
children: /* @__PURE__ */ jsxDEV12("div", {
|
|
2193
|
-
className: "cortex-reasoning-details__title-row",
|
|
2194
|
-
children: [
|
|
2195
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
2196
|
-
className: "cortex-reasoning-details__title",
|
|
2197
|
-
children: t("translate_reasoning")
|
|
2198
|
-
}, undefined, false, undefined, this),
|
|
2199
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
2200
|
-
className: cx("cortex-reasoning-details__badge", streaming ? "cortex-reasoning-details__badge--streaming" : "cortex-reasoning-details__badge--done"),
|
|
2201
|
-
children: streaming ? "Streaming" : "Done"
|
|
2202
|
-
}, undefined, false, undefined, this)
|
|
2203
|
-
]
|
|
2204
|
-
}, undefined, true, undefined, this)
|
|
2205
|
-
}, undefined, false, undefined, this)
|
|
2206
|
-
]
|
|
2207
|
-
}, undefined, true, undefined, this),
|
|
2208
|
-
/* @__PURE__ */ jsxDEV12("span", {
|
|
2209
|
-
className: "cortex-reasoning-details__chevron",
|
|
2210
|
-
"aria-hidden": "true",
|
|
2211
|
-
children: /* @__PURE__ */ jsxDEV12("svg", {
|
|
2212
|
-
width: "14",
|
|
2213
|
-
height: "14",
|
|
2214
|
-
viewBox: "0 0 20 20",
|
|
2215
|
-
fill: "none",
|
|
2216
|
-
children: /* @__PURE__ */ jsxDEV12("path", {
|
|
2217
|
-
d: "m5.75 8.25 4.25 4.25 4.25-4.25",
|
|
2218
|
-
stroke: "currentColor",
|
|
2219
|
-
strokeWidth: "1.5",
|
|
2220
|
-
strokeLinecap: "round",
|
|
2221
|
-
strokeLinejoin: "round"
|
|
2222
|
-
}, undefined, false, undefined, this)
|
|
2223
|
-
}, undefined, false, undefined, this)
|
|
2224
|
-
}, undefined, false, undefined, this)
|
|
2225
|
-
]
|
|
2226
|
-
}, undefined, true, undefined, this),
|
|
2227
|
-
/* @__PURE__ */ jsxDEV12("div", {
|
|
2228
|
-
className: "cortex-reasoning-details__body",
|
|
2229
|
-
children: /* @__PURE__ */ jsxDEV12("div", {
|
|
2230
|
-
className: "cortex-reasoning-details__content",
|
|
2231
|
-
children: /* @__PURE__ */ jsxDEV12("pre", {
|
|
2232
|
-
className: "cortex-reasoning-details__pre",
|
|
2233
|
-
children: reasoningPart.content.trim() ? reasoningPart.content : "No reasoning provided."
|
|
2234
|
-
}, undefined, false, undefined, this)
|
|
2235
|
-
}, undefined, false, undefined, this)
|
|
2236
|
-
}, undefined, false, undefined, this)
|
|
2237
|
-
]
|
|
2238
|
-
}, undefined, true, undefined, this);
|
|
2239
|
-
}
|
|
2240
|
-
|
|
2241
|
-
// src/components/MessageTextPart.tsx
|
|
2242
|
-
import { useEffect as useEffect4, useRef as useRef6, useState as useState6 } from "react";
|
|
2243
|
-
import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
|
|
2244
|
-
function MessageTextPart(props) {
|
|
2245
|
-
const { role, textPart, streaming = false } = props;
|
|
2246
|
-
const initialText = role === "assistant" && streaming ? "" : textPart.content;
|
|
2247
|
-
const [displayedText, setDisplayedText] = useState6(initialText);
|
|
2248
|
-
const displayedTextRef = useRef6(initialText);
|
|
2249
|
-
const smootherRef = useRef6(null);
|
|
2250
|
-
const isFirstRenderRef = useRef6(true);
|
|
2251
|
-
useEffect4(() => {
|
|
2252
|
-
function setText(text) {
|
|
2253
|
-
displayedTextRef.current = text;
|
|
2254
|
-
setDisplayedText(text);
|
|
2255
|
-
}
|
|
2256
|
-
if (role !== "assistant" || !streaming) {
|
|
2257
|
-
smootherRef.current?.destroy();
|
|
2258
|
-
smootherRef.current = null;
|
|
2259
|
-
setText(textPart.content);
|
|
2260
|
-
isFirstRenderRef.current = false;
|
|
2261
|
-
return;
|
|
2262
|
-
}
|
|
2263
|
-
if (!smootherRef.current) {
|
|
2264
|
-
smootherRef.current = new StreamTextSmoother(setText);
|
|
2265
|
-
smootherRef.current.seed(displayedTextRef.current);
|
|
2266
|
-
}
|
|
2267
|
-
if (isFirstRenderRef.current) {
|
|
2268
|
-
isFirstRenderRef.current = false;
|
|
2269
|
-
smootherRef.current.seed(textPart.content);
|
|
2270
|
-
return;
|
|
2271
|
-
}
|
|
2272
|
-
smootherRef.current.update(textPart.content, false);
|
|
2273
|
-
}, [role, streaming, textPart]);
|
|
2274
|
-
useEffect4(() => () => {
|
|
2275
|
-
smootherRef.current?.destroy();
|
|
2276
|
-
smootherRef.current = null;
|
|
2277
|
-
}, []);
|
|
2278
|
-
return /* @__PURE__ */ jsxDEV13("div", {
|
|
2279
|
-
className: cx("cortex-text-part", role === "assistant" && "cortex-text-part--assistant", role === "user" && "cortex-text-part--user"),
|
|
2280
|
-
children: /* @__PURE__ */ jsxDEV13("div", {
|
|
2281
|
-
className: cx("cortex-text-bubble", role === "assistant" && "cortex-text-bubble--assistant", role === "user" && "cortex-text-bubble--user"),
|
|
2282
|
-
dangerouslySetInnerHTML: { __html: renderMarkdown(displayedText) }
|
|
2283
|
-
}, undefined, false, undefined, this)
|
|
2284
|
-
}, undefined, false, undefined, this);
|
|
2285
|
-
}
|
|
2286
|
-
|
|
2287
|
-
// src/components/MessageToolCallOutcome.tsx
|
|
2288
|
-
import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
|
|
2289
|
-
function MessageToolCallOutcome({ toolCallPart }) {
|
|
2290
|
-
const { t } = useCortex();
|
|
2291
|
-
const { state, approval } = toolCallPart;
|
|
2292
|
-
const output = toolCallPart.output;
|
|
2293
|
-
const outputText = toolCallOutputText(toolCallPart);
|
|
2294
|
-
function section() {
|
|
2295
|
-
if (state === "complete") {
|
|
2296
|
-
return /* @__PURE__ */ jsxDEV14("div", {
|
|
2297
|
-
className: "dbg-tool__section dbg-tool__section--success",
|
|
2298
|
-
children: [
|
|
2299
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2300
|
-
className: "dbg-tool__section-bar",
|
|
2301
|
-
children: [
|
|
2302
|
-
/* @__PURE__ */ jsxDEV14("span", {
|
|
2303
|
-
className: "dbg-tool__section-label dbg-tool__section-label--success",
|
|
2304
|
-
children: t("translate_output")
|
|
2305
|
-
}, undefined, false, undefined, this),
|
|
2306
|
-
/* @__PURE__ */ jsxDEV14("span", {
|
|
2307
|
-
className: "dbg-tool__section-lang",
|
|
2308
|
-
children: "json"
|
|
2309
|
-
}, undefined, false, undefined, this),
|
|
2310
|
-
/* @__PURE__ */ jsxDEV14(CopyButton, {
|
|
2311
|
-
value: outputText
|
|
2312
|
-
}, undefined, false, undefined, this)
|
|
2313
|
-
]
|
|
2314
|
-
}, undefined, true, undefined, this),
|
|
2315
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2316
|
-
dir: "ltr",
|
|
2317
|
-
className: "dbg-tool__tree",
|
|
2318
|
-
children: /* @__PURE__ */ jsxDEV14(JsonTree, {
|
|
2319
|
-
data: output,
|
|
2320
|
-
expandDepth: 2
|
|
2321
|
-
}, undefined, false, undefined, this)
|
|
2322
|
-
}, undefined, false, undefined, this)
|
|
2323
|
-
]
|
|
2324
|
-
}, undefined, true, undefined, this);
|
|
2325
|
-
}
|
|
2326
|
-
if (state === "error") {
|
|
2327
|
-
return /* @__PURE__ */ jsxDEV14("div", {
|
|
2328
|
-
className: "dbg-tool__section dbg-tool__section--error",
|
|
2329
|
-
children: [
|
|
2330
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2331
|
-
className: "dbg-tool__section-bar",
|
|
2332
|
-
children: [
|
|
2333
|
-
/* @__PURE__ */ jsxDEV14("span", {
|
|
2334
|
-
className: "dbg-tool__section-label dbg-tool__section-label--error",
|
|
2335
|
-
children: t("translate_error")
|
|
2336
|
-
}, undefined, false, undefined, this),
|
|
2337
|
-
/* @__PURE__ */ jsxDEV14(CopyButton, {
|
|
2338
|
-
value: outputText
|
|
2339
|
-
}, undefined, false, undefined, this)
|
|
2340
|
-
]
|
|
2341
|
-
}, undefined, true, undefined, this),
|
|
2342
|
-
/* @__PURE__ */ jsxDEV14("pre", {
|
|
2343
|
-
dir: "ltr",
|
|
2344
|
-
className: "dbg-tool__error-pre",
|
|
2345
|
-
children: outputText
|
|
2346
|
-
}, undefined, false, undefined, this)
|
|
2347
|
-
]
|
|
2348
|
-
}, undefined, true, undefined, this);
|
|
2349
|
-
}
|
|
2350
|
-
if (state === "approval-requested") {
|
|
2351
|
-
return /* @__PURE__ */ jsxDEV14("div", {
|
|
2352
|
-
className: "dbg-tool__section dbg-tool__section--approval",
|
|
2353
|
-
children: [
|
|
2354
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2355
|
-
className: "dbg-tool__section-bar",
|
|
2356
|
-
children: [
|
|
2357
|
-
/* @__PURE__ */ jsxDEV14("span", {
|
|
2358
|
-
className: "dbg-tool__section-label dbg-tool__section-label--approval",
|
|
2359
|
-
children: t("translate_approval_requested")
|
|
2360
|
-
}, undefined, false, undefined, this),
|
|
2361
|
-
/* @__PURE__ */ jsxDEV14("span", {
|
|
2362
|
-
className: "dbg-tool__section-lang",
|
|
2363
|
-
children: approval?.id
|
|
2364
|
-
}, undefined, false, undefined, this)
|
|
2365
|
-
]
|
|
2366
|
-
}, undefined, true, undefined, this),
|
|
2367
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2368
|
-
className: "dbg-tool__message dbg-tool__message--approval",
|
|
2369
|
-
children: t("translate_waiting_for_approval")
|
|
2370
|
-
}, undefined, false, undefined, this)
|
|
2371
|
-
]
|
|
2372
|
-
}, undefined, true, undefined, this);
|
|
2373
|
-
}
|
|
2374
|
-
if (state === "approval-responded") {
|
|
2375
|
-
return /* @__PURE__ */ jsxDEV14("div", {
|
|
2376
|
-
className: "dbg-tool__section dbg-tool__section--approval",
|
|
2377
|
-
children: [
|
|
2378
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2379
|
-
className: "dbg-tool__section-bar",
|
|
2380
|
-
children: [
|
|
2381
|
-
/* @__PURE__ */ jsxDEV14("span", {
|
|
2382
|
-
className: "dbg-tool__section-label dbg-tool__section-label--approval",
|
|
2383
|
-
children: t("translate_approval_response")
|
|
2384
|
-
}, undefined, false, undefined, this),
|
|
2385
|
-
/* @__PURE__ */ jsxDEV14("span", {
|
|
2386
|
-
className: "dbg-tool__section-lang",
|
|
2387
|
-
children: approval?.id
|
|
2388
|
-
}, undefined, false, undefined, this)
|
|
2389
|
-
]
|
|
2390
|
-
}, undefined, true, undefined, this),
|
|
2391
|
-
/* @__PURE__ */ jsxDEV14("div", {
|
|
2392
|
-
className: "dbg-tool__message dbg-tool__message--approval",
|
|
2393
|
-
children: t(approval?.approved ? "translate_tool_approved" : "translate_tool_response_received")
|
|
2394
|
-
}, undefined, false, undefined, this)
|
|
2395
|
-
]
|
|
2396
|
-
}, undefined, true, undefined, this);
|
|
2397
|
-
}
|
|
2398
|
-
return null;
|
|
2399
|
-
}
|
|
2400
|
-
return /* @__PURE__ */ jsxDEV14("div", {
|
|
2401
|
-
children: section()
|
|
2402
|
-
}, undefined, false, undefined, this);
|
|
2403
|
-
}
|
|
2404
|
-
|
|
2405
|
-
// src/components/MessageToolCallStatus.tsx
|
|
2406
|
-
import { jsxDEV as jsxDEV15 } from "react/jsx-dev-runtime";
|
|
2407
|
-
function MessageToolCallStatus({ toolCallPart }) {
|
|
2408
|
-
const { t } = useCortex();
|
|
2409
|
-
const badge = toolCallBadge(toolCallPart);
|
|
2410
|
-
return /* @__PURE__ */ jsxDEV15("span", {
|
|
2411
|
-
children: /* @__PURE__ */ jsxDEV15("span", {
|
|
2412
|
-
className: cx("dbg-tool__state", badge.modifier && `dbg-tool__state--${badge.modifier}`),
|
|
2413
|
-
children: [
|
|
2414
|
-
badge.pulse && /* @__PURE__ */ jsxDEV15("span", {
|
|
2415
|
-
className: cx("dbg-tool__pulse", badge.pulse === "violet" && "dbg-tool__pulse--violet")
|
|
2416
|
-
}, undefined, false, undefined, this),
|
|
2417
|
-
t(badge.labelKey)
|
|
2418
|
-
]
|
|
2419
|
-
}, undefined, true, undefined, this)
|
|
2420
|
-
}, undefined, false, undefined, this);
|
|
2421
|
-
}
|
|
2422
|
-
|
|
2423
|
-
// src/components/MessageToolCallPart.tsx
|
|
2424
|
-
import { jsxDEV as jsxDEV16 } from "react/jsx-dev-runtime";
|
|
2425
|
-
function MessageToolCallPart({ toolCallPart }) {
|
|
2426
|
-
const { t } = useCortex();
|
|
2427
|
-
const { codeSnippets, remainingInput, remainingInputText } = splitToolCallInput(toolCallPart.input);
|
|
2428
|
-
return /* @__PURE__ */ jsxDEV16("details", {
|
|
2429
|
-
className: "dbg-tool",
|
|
2430
|
-
"data-state": toolCallPart.state,
|
|
2431
|
-
children: [
|
|
2432
|
-
/* @__PURE__ */ jsxDEV16("summary", {
|
|
2433
|
-
className: "dbg-tool__summary",
|
|
2434
|
-
children: /* @__PURE__ */ jsxDEV16("div", {
|
|
2435
|
-
className: "dbg-tool__header",
|
|
2436
|
-
children: [
|
|
2437
|
-
/* @__PURE__ */ jsxDEV16("div", {
|
|
2438
|
-
className: "dbg-tool__meta",
|
|
2439
|
-
children: [
|
|
2440
|
-
/* @__PURE__ */ jsxDEV16("div", {
|
|
2441
|
-
className: "dbg-tool__title-row",
|
|
2442
|
-
children: /* @__PURE__ */ jsxDEV16("span", {
|
|
2443
|
-
className: "dbg-tool__name",
|
|
2444
|
-
title: toolCallPart.name,
|
|
2445
|
-
children: toolCallPart.name
|
|
2446
|
-
}, undefined, false, undefined, this)
|
|
2447
|
-
}, undefined, false, undefined, this),
|
|
2448
|
-
/* @__PURE__ */ jsxDEV16("div", {
|
|
2449
|
-
className: "dbg-tool__id-row",
|
|
2450
|
-
children: /* @__PURE__ */ jsxDEV16("span", {
|
|
2451
|
-
className: "dbg-tool__id",
|
|
2452
|
-
children: toolCallPart.id
|
|
2453
|
-
}, undefined, false, undefined, this)
|
|
2454
|
-
}, undefined, false, undefined, this)
|
|
2455
|
-
]
|
|
2456
|
-
}, undefined, true, undefined, this),
|
|
2457
|
-
/* @__PURE__ */ jsxDEV16("div", {
|
|
2458
|
-
className: "dbg-tool__actions",
|
|
2459
|
-
children: [
|
|
2460
|
-
/* @__PURE__ */ jsxDEV16(MessageToolCallStatus, {
|
|
2461
|
-
toolCallPart
|
|
2462
|
-
}, undefined, false, undefined, this),
|
|
2463
|
-
/* @__PURE__ */ jsxDEV16("svg", {
|
|
2464
|
-
className: "dbg-tool__chevron",
|
|
2465
|
-
width: "14",
|
|
2466
|
-
height: "14",
|
|
2467
|
-
viewBox: "0 0 20 20",
|
|
2468
|
-
fill: "none",
|
|
2469
|
-
children: /* @__PURE__ */ jsxDEV16("path", {
|
|
2470
|
-
d: "m5.75 8.25 4.25 4.25 4.25-4.25",
|
|
2471
|
-
stroke: "currentColor",
|
|
2472
|
-
strokeWidth: "1.5",
|
|
2473
|
-
strokeLinecap: "round",
|
|
2474
|
-
strokeLinejoin: "round"
|
|
2475
|
-
}, undefined, false, undefined, this)
|
|
2476
|
-
}, undefined, false, undefined, this)
|
|
2477
|
-
]
|
|
2478
|
-
}, undefined, true, undefined, this)
|
|
2479
|
-
]
|
|
2480
|
-
}, undefined, true, undefined, this)
|
|
2481
|
-
}, undefined, false, undefined, this),
|
|
2482
|
-
/* @__PURE__ */ jsxDEV16("div", {
|
|
2483
|
-
className: "dbg-tool__body",
|
|
2484
|
-
children: [
|
|
2485
|
-
codeSnippets.map((snippet) => /* @__PURE__ */ jsxDEV16("div", {
|
|
2486
|
-
className: "dbg-tool__section",
|
|
2487
|
-
children: [
|
|
2488
|
-
/* @__PURE__ */ jsxDEV16("div", {
|
|
2489
|
-
className: "dbg-tool__section-bar",
|
|
2490
|
-
children: [
|
|
2491
|
-
/* @__PURE__ */ jsxDEV16("span", {
|
|
2492
|
-
className: "dbg-tool__section-label",
|
|
2493
|
-
children: snippet.key
|
|
2494
|
-
}, undefined, false, undefined, this),
|
|
2495
|
-
/* @__PURE__ */ jsxDEV16("span", {
|
|
2496
|
-
className: "dbg-tool__section-lang",
|
|
2497
|
-
children: snippet.lang
|
|
2498
|
-
}, undefined, false, undefined, this),
|
|
2499
|
-
/* @__PURE__ */ jsxDEV16(CopyButton, {
|
|
2500
|
-
value: snippet.value
|
|
2501
|
-
}, undefined, false, undefined, this)
|
|
2502
|
-
]
|
|
2503
|
-
}, undefined, true, undefined, this),
|
|
2504
|
-
/* @__PURE__ */ jsxDEV16("pre", {
|
|
2505
|
-
dir: "ltr",
|
|
2506
|
-
className: "dbg-tool__pre",
|
|
2507
|
-
children: /* @__PURE__ */ jsxDEV16("code", {
|
|
2508
|
-
className: "hljs",
|
|
2509
|
-
dangerouslySetInnerHTML: { __html: highlightCode(snippet.value, snippet.lang) }
|
|
2510
|
-
}, undefined, false, undefined, this)
|
|
2511
|
-
}, undefined, false, undefined, this)
|
|
2512
|
-
]
|
|
2513
|
-
}, snippet.key, true, undefined, this)),
|
|
2514
|
-
!!remainingInput && /* @__PURE__ */ jsxDEV16("div", {
|
|
2515
|
-
className: "dbg-tool__section",
|
|
2516
|
-
children: [
|
|
2517
|
-
/* @__PURE__ */ jsxDEV16("div", {
|
|
2518
|
-
className: "dbg-tool__section-bar",
|
|
2519
|
-
children: [
|
|
2520
|
-
/* @__PURE__ */ jsxDEV16("span", {
|
|
2521
|
-
className: "dbg-tool__section-label",
|
|
2522
|
-
children: t("translate_input")
|
|
2523
|
-
}, undefined, false, undefined, this),
|
|
2524
|
-
/* @__PURE__ */ jsxDEV16("span", {
|
|
2525
|
-
className: "dbg-tool__section-lang",
|
|
2526
|
-
children: "json"
|
|
2527
|
-
}, undefined, false, undefined, this),
|
|
2528
|
-
/* @__PURE__ */ jsxDEV16(CopyButton, {
|
|
2529
|
-
value: remainingInputText
|
|
2530
|
-
}, undefined, false, undefined, this)
|
|
2531
|
-
]
|
|
2532
|
-
}, undefined, true, undefined, this),
|
|
2533
|
-
/* @__PURE__ */ jsxDEV16("div", {
|
|
2534
|
-
dir: "ltr",
|
|
2535
|
-
className: "dbg-tool__tree",
|
|
2536
|
-
children: /* @__PURE__ */ jsxDEV16(JsonTree, {
|
|
2537
|
-
data: remainingInput,
|
|
2538
|
-
expandDepth: 2
|
|
2539
|
-
}, undefined, false, undefined, this)
|
|
2540
|
-
}, undefined, false, undefined, this)
|
|
2541
|
-
]
|
|
2542
|
-
}, undefined, true, undefined, this),
|
|
2543
|
-
/* @__PURE__ */ jsxDEV16(MessageToolCallOutcome, {
|
|
2544
|
-
toolCallPart
|
|
2545
|
-
}, undefined, false, undefined, this)
|
|
2546
|
-
]
|
|
2547
|
-
}, undefined, true, undefined, this)
|
|
2548
|
-
]
|
|
2549
|
-
}, undefined, true, undefined, this);
|
|
2550
|
-
}
|
|
2551
|
-
|
|
2552
|
-
// src/components/MessageToolCallAnimated.tsx
|
|
2553
|
-
import { jsxDEV as jsxDEV17 } from "react/jsx-dev-runtime";
|
|
2554
|
-
function MessageToolCallAnimated({ message, toolCallPart }) {
|
|
2555
|
-
const { config, t, addToolResult } = useCortex();
|
|
2556
|
-
const Custom = config.toolComponents?.[toolCallPart.name];
|
|
2557
|
-
if (Custom) {
|
|
2558
|
-
return /* @__PURE__ */ jsxDEV17("div", {
|
|
2559
|
-
className: "cortex-tool-call-animated",
|
|
2560
|
-
children: /* @__PURE__ */ jsxDEV17(Custom, {
|
|
2561
|
-
toolCallPart,
|
|
2562
|
-
message,
|
|
2563
|
-
setOutput: (output) => addToolResult(toolCallPart.id, toolCallPart.name, output)
|
|
2564
|
-
}, undefined, false, undefined, this)
|
|
2565
|
-
}, undefined, false, undefined, this);
|
|
2566
|
-
}
|
|
2567
|
-
const { state, active, titleKey } = toolCallAnimation(toolCallPart);
|
|
2568
|
-
return /* @__PURE__ */ jsxDEV17("div", {
|
|
2569
|
-
className: "cortex-tool-call-animated",
|
|
2570
|
-
children: /* @__PURE__ */ jsxDEV17("div", {
|
|
2571
|
-
className: "cortex-tool-pill",
|
|
2572
|
-
children: [
|
|
2573
|
-
/* @__PURE__ */ jsxDEV17("span", {
|
|
2574
|
-
className: "cortex-tool-pill__icon",
|
|
2575
|
-
children: [
|
|
2576
|
-
/* @__PURE__ */ jsxDEV17("span", {
|
|
2577
|
-
className: cx("cortex-tool-pill__spinner", active && "cortex-tool-pill__spinner--visible")
|
|
2578
|
-
}, undefined, false, undefined, this),
|
|
2579
|
-
/* @__PURE__ */ jsxDEV17("svg", {
|
|
2580
|
-
className: cx("cortex-tool-pill__svg", "cortex-tool-pill__svg--check", state === "complete" && "cortex-tool-pill__svg--visible"),
|
|
2581
|
-
viewBox: "0 0 20 20",
|
|
2582
|
-
fill: "none",
|
|
2583
|
-
children: /* @__PURE__ */ jsxDEV17("path", {
|
|
2584
|
-
d: "M5.5 10.5 L8.5 13.5 L14.5 7",
|
|
2585
|
-
stroke: "currentColor",
|
|
2586
|
-
strokeWidth: "2",
|
|
2587
|
-
strokeLinecap: "round",
|
|
2588
|
-
strokeLinejoin: "round"
|
|
2589
|
-
}, undefined, false, undefined, this)
|
|
2590
|
-
}, undefined, false, undefined, this),
|
|
2591
|
-
/* @__PURE__ */ jsxDEV17("svg", {
|
|
2592
|
-
className: cx("cortex-tool-pill__svg", "cortex-tool-pill__svg--error", state === "error" && "cortex-tool-pill__svg--visible"),
|
|
2593
|
-
viewBox: "0 0 20 20",
|
|
2594
|
-
fill: "none",
|
|
2595
|
-
children: /* @__PURE__ */ jsxDEV17("path", {
|
|
2596
|
-
d: "M6.5 6.5 L13.5 13.5 M13.5 6.5 L6.5 13.5",
|
|
2597
|
-
stroke: "currentColor",
|
|
2598
|
-
strokeWidth: "2",
|
|
2599
|
-
strokeLinecap: "round"
|
|
2600
|
-
}, undefined, false, undefined, this)
|
|
2601
|
-
}, undefined, false, undefined, this)
|
|
2602
|
-
]
|
|
2603
|
-
}, undefined, true, undefined, this),
|
|
2604
|
-
/* @__PURE__ */ jsxDEV17("span", {
|
|
2605
|
-
className: cx("cortex-tool-pill__title", state === "error" && "cortex-tool-pill__title--error"),
|
|
2606
|
-
children: t(titleKey)
|
|
2607
|
-
}, undefined, false, undefined, this)
|
|
2608
|
-
]
|
|
2609
|
-
}, undefined, true, undefined, this)
|
|
2610
|
-
}, undefined, false, undefined, this);
|
|
2611
|
-
}
|
|
2612
|
-
|
|
2613
|
-
// src/components/ToolExecuteCodeAnimated.tsx
|
|
2614
|
-
import { jsxDEV as jsxDEV18 } from "react/jsx-dev-runtime";
|
|
2615
|
-
var LABELS2 = activityLabelKeys("code");
|
|
2616
|
-
function ToolExecuteCodeAnimated() {
|
|
2617
|
-
return /* @__PURE__ */ jsxDEV18(SubtleActivity, {
|
|
2618
|
-
labels: LABELS2
|
|
2619
|
-
}, undefined, false, undefined, this);
|
|
2620
|
-
}
|
|
2621
|
-
|
|
2622
|
-
// src/components/ToolQueryGraphAnimated.tsx
|
|
2623
|
-
import { jsxDEV as jsxDEV19 } from "react/jsx-dev-runtime";
|
|
2624
|
-
var LABELS3 = activityLabelKeys("graph");
|
|
2625
|
-
function ToolQueryGraphAnimated() {
|
|
2626
|
-
return /* @__PURE__ */ jsxDEV19(SubtleActivity, {
|
|
2627
|
-
labels: LABELS3
|
|
2628
|
-
}, undefined, false, undefined, this);
|
|
2629
|
-
}
|
|
2630
|
-
|
|
2631
|
-
// src/components/ToolAnimation.tsx
|
|
2632
|
-
import { jsxDEV as jsxDEV20 } from "react/jsx-dev-runtime";
|
|
2633
|
-
function ToolAnimation({ message, toolCallPart }) {
|
|
2634
|
-
if (toolCallPart.name === "queryGraph")
|
|
2635
|
-
return /* @__PURE__ */ jsxDEV20(ToolQueryGraphAnimated, {}, undefined, false, undefined, this);
|
|
2636
|
-
if (toolCallPart.name === "executeCode")
|
|
2637
|
-
return /* @__PURE__ */ jsxDEV20(ToolExecuteCodeAnimated, {}, undefined, false, undefined, this);
|
|
2638
|
-
return /* @__PURE__ */ jsxDEV20(MessageToolCallAnimated, {
|
|
2639
|
-
toolCallPart,
|
|
2640
|
-
message
|
|
2641
|
-
}, undefined, false, undefined, this);
|
|
2642
|
-
}
|
|
2643
|
-
|
|
2644
|
-
// src/components/MessagePart.tsx
|
|
2645
|
-
import { jsxDEV as jsxDEV21 } from "react/jsx-dev-runtime";
|
|
2646
|
-
function MessagePart(props) {
|
|
2647
|
-
const { message, part, debugMode = false, animate = false, streaming = false } = props;
|
|
2648
|
-
const { t } = useCortex();
|
|
2649
|
-
function renderPart() {
|
|
2650
|
-
switch (part.type) {
|
|
2651
|
-
case "text":
|
|
2652
|
-
return /* @__PURE__ */ jsxDEV21(MessageTextPart, {
|
|
2653
|
-
textPart: part,
|
|
2654
|
-
role: message.role,
|
|
2655
|
-
streaming
|
|
2656
|
-
}, undefined, false, undefined, this);
|
|
2657
|
-
case "thinking":
|
|
2658
|
-
return debugMode ? /* @__PURE__ */ jsxDEV21(MessageReasoningPart, {
|
|
2659
|
-
reasoningPart: part,
|
|
2660
|
-
streaming
|
|
2661
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV21(MessageReasoningAnimated, {}, undefined, false, undefined, this);
|
|
2662
|
-
case "tool-call":
|
|
2663
|
-
return debugMode ? /* @__PURE__ */ jsxDEV21(MessageToolCallPart, {
|
|
2664
|
-
toolCallPart: part
|
|
2665
|
-
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV21(ToolAnimation, {
|
|
2666
|
-
toolCallPart: part,
|
|
2667
|
-
message
|
|
2668
|
-
}, undefined, false, undefined, this);
|
|
2669
|
-
default:
|
|
2670
|
-
return /* @__PURE__ */ jsxDEV21("p", {
|
|
2671
|
-
className: "cortex-unhandled-type",
|
|
2672
|
-
children: [
|
|
2673
|
-
t("translate_unhandled_type"),
|
|
2674
|
-
" ",
|
|
2675
|
-
part.type
|
|
2676
|
-
]
|
|
2677
|
-
}, undefined, true, undefined, this);
|
|
2678
|
-
}
|
|
2679
|
-
}
|
|
2680
|
-
return /* @__PURE__ */ jsxDEV21("div", {
|
|
2681
|
-
className: cx("cortex-message-part", animate && "cortex-message-part--animated"),
|
|
2682
|
-
children: renderPart()
|
|
2683
|
-
}, undefined, false, undefined, this);
|
|
2684
|
-
}
|
|
2685
|
-
|
|
2686
|
-
// src/components/MessageTokenUsage.tsx
|
|
2687
|
-
import { useState as useState7 } from "react";
|
|
2688
|
-
import { jsxDEV as jsxDEV22 } from "react/jsx-dev-runtime";
|
|
2689
|
-
function MessageTokenUsage({ usage, modelId }) {
|
|
2690
|
-
const { t } = useCortex();
|
|
2691
|
-
const [expanded, setExpanded] = useState7(false);
|
|
2692
|
-
const cacheRatio = cachePercent(usage) ?? 0;
|
|
2693
|
-
return /* @__PURE__ */ jsxDEV22("div", {
|
|
2694
|
-
className: cx("cortex-token-usage", expanded && "cortex-token-usage--expanded"),
|
|
2695
|
-
children: [
|
|
2696
|
-
/* @__PURE__ */ jsxDEV22("button", {
|
|
2697
|
-
className: "cortex-token-usage__summary",
|
|
2698
|
-
onClick: () => setExpanded((v) => !v),
|
|
2699
|
-
children: [
|
|
2700
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2701
|
-
className: "cortex-token-usage__total",
|
|
2702
|
-
children: [
|
|
2703
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2704
|
-
className: "cortex-token-usage__total-number",
|
|
2705
|
-
children: num(usage.total)
|
|
2706
|
-
}, undefined, false, undefined, this),
|
|
2707
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2708
|
-
className: "cortex-token-usage__total-label",
|
|
2709
|
-
children: t("translate_tokens")
|
|
2710
|
-
}, undefined, false, undefined, this)
|
|
2711
|
-
]
|
|
2712
|
-
}, undefined, true, undefined, this),
|
|
2713
|
-
modelId ? /* @__PURE__ */ jsxDEV22("span", {
|
|
2714
|
-
className: "cortex-token-usage__model",
|
|
2715
|
-
children: modelId
|
|
2716
|
-
}, undefined, false, undefined, this) : null,
|
|
2717
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2718
|
-
className: "cortex-token-usage__pills",
|
|
2719
|
-
children: [
|
|
2720
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2721
|
-
className: "cortex-token-usage__pill",
|
|
2722
|
-
children: [
|
|
2723
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2724
|
-
className: "cortex-token-usage__dot cortex-token-usage__dot--input"
|
|
2725
|
-
}, undefined, false, undefined, this),
|
|
2726
|
-
num(usage.input.total)
|
|
2727
|
-
]
|
|
2728
|
-
}, undefined, true, undefined, this),
|
|
2729
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2730
|
-
className: "cortex-token-usage__pill",
|
|
2731
|
-
children: [
|
|
2732
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2733
|
-
className: "cortex-token-usage__dot cortex-token-usage__dot--output"
|
|
2734
|
-
}, undefined, false, undefined, this),
|
|
2735
|
-
num(usage.output.total)
|
|
2736
|
-
]
|
|
2737
|
-
}, undefined, true, undefined, this)
|
|
2738
|
-
]
|
|
2739
|
-
}, undefined, true, undefined, this),
|
|
2740
|
-
cacheRatio > 0 ? /* @__PURE__ */ jsxDEV22("span", {
|
|
2741
|
-
className: "cortex-token-usage__cache-badge",
|
|
2742
|
-
children: [
|
|
2743
|
-
cacheRatio,
|
|
2744
|
-
"%"
|
|
2745
|
-
]
|
|
2746
|
-
}, undefined, true, undefined, this) : null,
|
|
2747
|
-
/* @__PURE__ */ jsxDEV22("svg", {
|
|
2748
|
-
className: "cortex-token-usage__chevron",
|
|
2749
|
-
width: "12",
|
|
2750
|
-
height: "12",
|
|
2751
|
-
viewBox: "0 0 12 12",
|
|
2752
|
-
fill: "none",
|
|
2753
|
-
children: /* @__PURE__ */ jsxDEV22("path", {
|
|
2754
|
-
d: "M3 4.5L6 7.5L9 4.5",
|
|
2755
|
-
stroke: "currentColor",
|
|
2756
|
-
strokeWidth: "1.25",
|
|
2757
|
-
strokeLinecap: "round",
|
|
2758
|
-
strokeLinejoin: "round"
|
|
2759
|
-
}, undefined, false, undefined, this)
|
|
2760
|
-
}, undefined, false, undefined, this)
|
|
2761
|
-
]
|
|
2762
|
-
}, undefined, true, undefined, this),
|
|
2763
|
-
/* @__PURE__ */ jsxDEV22("div", {
|
|
2764
|
-
className: "cortex-token-usage__details",
|
|
2765
|
-
children: /* @__PURE__ */ jsxDEV22("div", {
|
|
2766
|
-
className: "cortex-token-usage__details-inner",
|
|
2767
|
-
children: /* @__PURE__ */ jsxDEV22("div", {
|
|
2768
|
-
className: "cortex-token-usage__columns",
|
|
2769
|
-
children: [
|
|
2770
|
-
/* @__PURE__ */ jsxDEV22("div", {
|
|
2771
|
-
className: "cortex-token-usage__col",
|
|
2772
|
-
children: [
|
|
2773
|
-
/* @__PURE__ */ jsxDEV22("div", {
|
|
2774
|
-
className: "cortex-token-usage__col-header",
|
|
2775
|
-
children: [
|
|
2776
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2777
|
-
className: "cortex-token-usage__dot cortex-token-usage__dot--input"
|
|
2778
|
-
}, undefined, false, undefined, this),
|
|
2779
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2780
|
-
className: "cortex-token-usage__col-label",
|
|
2781
|
-
children: t("translate_input")
|
|
2782
|
-
}, undefined, false, undefined, this),
|
|
2783
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2784
|
-
className: "cortex-token-usage__col-total",
|
|
2785
|
-
children: num(usage.input.total)
|
|
2786
|
-
}, undefined, false, undefined, this)
|
|
2787
|
-
]
|
|
2788
|
-
}, undefined, true, undefined, this),
|
|
2789
|
-
/* @__PURE__ */ jsxDEV22("div", {
|
|
2790
|
-
className: "cortex-token-usage__rows",
|
|
2791
|
-
children: [
|
|
2792
|
-
usage.input.noCache ? /* @__PURE__ */ jsxDEV22("div", {
|
|
2793
|
-
className: "cortex-token-usage__row",
|
|
2794
|
-
children: [
|
|
2795
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2796
|
-
className: "cortex-token-usage__row-label",
|
|
2797
|
-
children: t("translate_fresh")
|
|
2798
|
-
}, undefined, false, undefined, this),
|
|
2799
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2800
|
-
className: "cortex-token-usage__row-value",
|
|
2801
|
-
children: num(usage.input.noCache)
|
|
2802
|
-
}, undefined, false, undefined, this)
|
|
2803
|
-
]
|
|
2804
|
-
}, undefined, true, undefined, this) : null,
|
|
2805
|
-
usage.input.cacheRead ? /* @__PURE__ */ jsxDEV22("div", {
|
|
2806
|
-
className: "cortex-token-usage__row",
|
|
2807
|
-
children: [
|
|
2808
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2809
|
-
className: "cortex-token-usage__row-label",
|
|
2810
|
-
children: t("translate_cache_read")
|
|
2811
|
-
}, undefined, false, undefined, this),
|
|
2812
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2813
|
-
className: "cortex-token-usage__row-value",
|
|
2814
|
-
children: num(usage.input.cacheRead)
|
|
2815
|
-
}, undefined, false, undefined, this)
|
|
2816
|
-
]
|
|
2817
|
-
}, undefined, true, undefined, this) : null,
|
|
2818
|
-
usage.input.cacheWrite ? /* @__PURE__ */ jsxDEV22("div", {
|
|
2819
|
-
className: "cortex-token-usage__row",
|
|
2820
|
-
children: [
|
|
2821
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2822
|
-
className: "cortex-token-usage__row-label",
|
|
2823
|
-
children: t("translate_cache_write")
|
|
2824
|
-
}, undefined, false, undefined, this),
|
|
2825
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2826
|
-
className: "cortex-token-usage__row-value",
|
|
2827
|
-
children: num(usage.input.cacheWrite)
|
|
2828
|
-
}, undefined, false, undefined, this)
|
|
2829
|
-
]
|
|
2830
|
-
}, undefined, true, undefined, this) : null
|
|
2831
|
-
]
|
|
2832
|
-
}, undefined, true, undefined, this),
|
|
2833
|
-
cacheRatio > 0 ? /* @__PURE__ */ jsxDEV22("div", {
|
|
2834
|
-
className: "cortex-token-usage__cache-bar-row",
|
|
2835
|
-
children: [
|
|
2836
|
-
/* @__PURE__ */ jsxDEV22("div", {
|
|
2837
|
-
className: "cortex-token-usage__cache-bar",
|
|
2838
|
-
children: /* @__PURE__ */ jsxDEV22("div", {
|
|
2839
|
-
className: "cortex-token-usage__cache-fill",
|
|
2840
|
-
style: { width: `${cacheRatio}%` }
|
|
2841
|
-
}, undefined, false, undefined, this)
|
|
2842
|
-
}, undefined, false, undefined, this),
|
|
2843
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2844
|
-
className: "cortex-token-usage__cache-label",
|
|
2845
|
-
children: t("translate_n_percent_cached", { percent: cacheRatio })
|
|
2846
|
-
}, undefined, false, undefined, this)
|
|
2847
|
-
]
|
|
2848
|
-
}, undefined, true, undefined, this) : null
|
|
2849
|
-
]
|
|
2850
|
-
}, undefined, true, undefined, this),
|
|
2851
|
-
/* @__PURE__ */ jsxDEV22("div", {
|
|
2852
|
-
className: "cortex-token-usage__col",
|
|
2853
|
-
children: [
|
|
2854
|
-
/* @__PURE__ */ jsxDEV22("div", {
|
|
2855
|
-
className: "cortex-token-usage__col-header",
|
|
2856
|
-
children: [
|
|
2857
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2858
|
-
className: "cortex-token-usage__dot cortex-token-usage__dot--output"
|
|
2859
|
-
}, undefined, false, undefined, this),
|
|
2860
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2861
|
-
className: "cortex-token-usage__col-label",
|
|
2862
|
-
children: t("translate_output")
|
|
2863
|
-
}, undefined, false, undefined, this),
|
|
2864
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2865
|
-
className: "cortex-token-usage__col-total",
|
|
2866
|
-
children: num(usage.output.total)
|
|
2867
|
-
}, undefined, false, undefined, this)
|
|
2868
|
-
]
|
|
2869
|
-
}, undefined, true, undefined, this),
|
|
2870
|
-
/* @__PURE__ */ jsxDEV22("div", {
|
|
2871
|
-
className: "cortex-token-usage__rows",
|
|
2872
|
-
children: [
|
|
2873
|
-
usage.output.text ? /* @__PURE__ */ jsxDEV22("div", {
|
|
2874
|
-
className: "cortex-token-usage__row",
|
|
2875
|
-
children: [
|
|
2876
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2877
|
-
className: "cortex-token-usage__row-label",
|
|
2878
|
-
children: t("translate_text")
|
|
2879
|
-
}, undefined, false, undefined, this),
|
|
2880
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2881
|
-
className: "cortex-token-usage__row-value",
|
|
2882
|
-
children: num(usage.output.text)
|
|
2883
|
-
}, undefined, false, undefined, this)
|
|
2884
|
-
]
|
|
2885
|
-
}, undefined, true, undefined, this) : null,
|
|
2886
|
-
usage.output.reasoning ? /* @__PURE__ */ jsxDEV22("div", {
|
|
2887
|
-
className: "cortex-token-usage__row",
|
|
2888
|
-
children: [
|
|
2889
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2890
|
-
className: "cortex-token-usage__row-label",
|
|
2891
|
-
children: t("translate_reasoning")
|
|
2892
|
-
}, undefined, false, undefined, this),
|
|
2893
|
-
/* @__PURE__ */ jsxDEV22("span", {
|
|
2894
|
-
className: "cortex-token-usage__row-value",
|
|
2895
|
-
children: num(usage.output.reasoning)
|
|
2896
|
-
}, undefined, false, undefined, this)
|
|
2897
|
-
]
|
|
2898
|
-
}, undefined, true, undefined, this) : null
|
|
2899
|
-
]
|
|
2900
|
-
}, undefined, true, undefined, this)
|
|
2901
|
-
]
|
|
2902
|
-
}, undefined, true, undefined, this)
|
|
2903
|
-
]
|
|
2904
|
-
}, undefined, true, undefined, this)
|
|
2905
|
-
}, undefined, false, undefined, this)
|
|
2906
|
-
}, undefined, false, undefined, this)
|
|
2907
|
-
]
|
|
2908
|
-
}, undefined, true, undefined, this);
|
|
2909
|
-
}
|
|
2910
|
-
|
|
2911
|
-
// src/components/Message.tsx
|
|
2912
|
-
import { jsxDEV as jsxDEV23 } from "react/jsx-dev-runtime";
|
|
2913
|
-
function Message(props) {
|
|
2914
|
-
const { message, debugMode = false, animate = false } = props;
|
|
2915
|
-
const { messages, isAgentWorking, messageMetadata } = useCortex();
|
|
2916
|
-
const isStreaming = isAgentWorking && newestAssistantMessage(messages)?.id === message.id;
|
|
2917
|
-
const isAssistant = message.role === "assistant";
|
|
2918
|
-
const parts = message.parts;
|
|
2919
|
-
const visibleParts = parts.filter((part, index) => {
|
|
2920
|
-
if (part.type === "tool-result")
|
|
2921
|
-
return false;
|
|
2922
|
-
return debugMode || !isHiddenInAnimatedMode(part, index === parts.length - 1, isStreaming);
|
|
2923
|
-
});
|
|
2924
|
-
const streamingPartIndex = isStreaming ? visibleParts.length - 1 : -1;
|
|
2925
|
-
const metadata = messageMetadata.get(message.id);
|
|
2926
|
-
const isAborted = Boolean(metadata?.isAborted);
|
|
2927
|
-
const tokenUsage = metadata?.tokenUsage;
|
|
2928
|
-
const attachments = message.role === "user" ? metadata?.attachments ?? [] : [];
|
|
2929
|
-
const showsDebugZone = debugMode && !isStreaming && (Boolean(tokenUsage) || isAssistant);
|
|
2930
|
-
return /* @__PURE__ */ jsxDEV23("div", {
|
|
2931
|
-
className: "cortex-message",
|
|
2932
|
-
children: visibleParts.length > 0 && /* @__PURE__ */ jsxDEV23("div", {
|
|
2933
|
-
className: "cortex-message-parts",
|
|
2934
|
-
children: [
|
|
2935
|
-
visibleParts.map((part, index) => /* @__PURE__ */ jsxDEV23(MessagePart, {
|
|
2936
|
-
part,
|
|
2937
|
-
message,
|
|
2938
|
-
debugMode,
|
|
2939
|
-
animate,
|
|
2940
|
-
streaming: index === streamingPartIndex
|
|
2941
|
-
}, index, false, undefined, this)),
|
|
2942
|
-
attachments.length > 0 && /* @__PURE__ */ jsxDEV23(MessageAttachments, {
|
|
2943
|
-
attachments
|
|
2944
|
-
}, undefined, false, undefined, this),
|
|
2945
|
-
isAborted && /* @__PURE__ */ jsxDEV23(MessageAbortedFlag, {}, undefined, false, undefined, this),
|
|
2946
|
-
showsDebugZone && /* @__PURE__ */ jsxDEV23("div", {
|
|
2947
|
-
className: "cortex-message-debug-zone",
|
|
2948
|
-
children: [
|
|
2949
|
-
tokenUsage && /* @__PURE__ */ jsxDEV23(MessageTokenUsage, {
|
|
2950
|
-
usage: tokenUsage,
|
|
2951
|
-
modelId: metadata?.modelId
|
|
2952
|
-
}, undefined, false, undefined, this),
|
|
2953
|
-
isAssistant && /* @__PURE__ */ jsxDEV23(MessageLlmInspector, {
|
|
2954
|
-
messageId: message.id
|
|
2955
|
-
}, undefined, false, undefined, this)
|
|
2956
|
-
]
|
|
2957
|
-
}, undefined, true, undefined, this)
|
|
2958
|
-
]
|
|
2959
|
-
}, undefined, true, undefined, this)
|
|
2960
|
-
}, undefined, false, undefined, this);
|
|
2961
|
-
}
|
|
2962
|
-
|
|
2963
|
-
// src/components/MessageList.tsx
|
|
2964
|
-
import { jsxDEV as jsxDEV24 } from "react/jsx-dev-runtime";
|
|
2965
|
-
function MessageList(props) {
|
|
2966
|
-
const { messages, selectedThread } = useCortex();
|
|
2967
|
-
const containerRef = useRef7(null);
|
|
2968
|
-
const shouldScrollToBottom = useRef7(true);
|
|
2969
|
-
const isNearBottom = useRef7(true);
|
|
2970
|
-
const scrollToBottomQueued = useRef7(false);
|
|
2971
|
-
const [animateNewParts, setAnimateNewParts] = useState8(false);
|
|
2972
|
-
function scrollToBottom() {
|
|
2973
|
-
const el = containerRef.current;
|
|
2974
|
-
if (el)
|
|
2975
|
-
el.scrollTop = el.scrollHeight;
|
|
2976
|
-
}
|
|
2977
|
-
function scheduleScrollToBottom() {
|
|
2978
|
-
if (scrollToBottomQueued.current)
|
|
2979
|
-
return;
|
|
2980
|
-
scrollToBottomQueued.current = true;
|
|
2981
|
-
queueMicrotask(() => {
|
|
2982
|
-
scrollToBottomQueued.current = false;
|
|
2983
|
-
scrollToBottom();
|
|
2984
|
-
shouldScrollToBottom.current = false;
|
|
2985
|
-
});
|
|
2986
|
-
}
|
|
2987
|
-
useEffect5(() => {
|
|
2988
|
-
const el = containerRef.current;
|
|
2989
|
-
scheduleScrollToBottom();
|
|
2990
|
-
setAnimateNewParts(true);
|
|
2991
|
-
if (!el || typeof MutationObserver === "undefined")
|
|
2992
|
-
return;
|
|
2993
|
-
const observer = new MutationObserver(() => {
|
|
2994
|
-
if (!shouldScrollToBottom.current && !isNearBottom.current)
|
|
2995
|
-
return;
|
|
2996
|
-
scheduleScrollToBottom();
|
|
2997
|
-
});
|
|
2998
|
-
observer.observe(el, { childList: true, subtree: true, characterData: true });
|
|
2999
|
-
return () => observer.disconnect();
|
|
3000
|
-
}, []);
|
|
3001
|
-
const threadId = selectedThread?.id;
|
|
3002
|
-
useEffect5(() => {
|
|
3003
|
-
setAnimateNewParts(false);
|
|
3004
|
-
shouldScrollToBottom.current = true;
|
|
3005
|
-
queueMicrotask(() => setAnimateNewParts(true));
|
|
3006
|
-
}, [threadId]);
|
|
3007
|
-
const lastMessage = messages[messages.length - 1];
|
|
3008
|
-
const lastUserMessageId = lastMessage?.role === "user" ? lastMessage.id : undefined;
|
|
3009
|
-
useEffect5(() => {
|
|
3010
|
-
if (lastUserMessageId)
|
|
3011
|
-
shouldScrollToBottom.current = true;
|
|
3012
|
-
}, [lastUserMessageId]);
|
|
3013
|
-
useEffect5(() => {
|
|
3014
|
-
if (!shouldScrollToBottom.current && !isNearBottom.current)
|
|
3015
|
-
return;
|
|
3016
|
-
scheduleScrollToBottom();
|
|
3017
|
-
}, [messages]);
|
|
3018
|
-
function onScroll() {
|
|
3019
|
-
const el = containerRef.current;
|
|
3020
|
-
if (!el)
|
|
3021
|
-
return;
|
|
3022
|
-
isNearBottom.current = el.scrollHeight - el.scrollTop - el.clientHeight < 100;
|
|
3023
|
-
}
|
|
3024
|
-
return /* @__PURE__ */ jsxDEV24("div", {
|
|
3025
|
-
className: props.className,
|
|
3026
|
-
children: /* @__PURE__ */ jsxDEV24("div", {
|
|
3027
|
-
ref: containerRef,
|
|
3028
|
-
className: "cortex-message-list",
|
|
3029
|
-
onScroll,
|
|
3030
|
-
children: messages.map((message) => /* @__PURE__ */ jsxDEV24(Message, {
|
|
3031
|
-
message,
|
|
3032
|
-
debugMode: props.debugMode,
|
|
3033
|
-
animate: animateNewParts
|
|
3034
|
-
}, message.id, false, undefined, this))
|
|
3035
|
-
}, undefined, false, undefined, this)
|
|
3036
|
-
}, undefined, false, undefined, this);
|
|
3037
|
-
}
|
|
3038
|
-
|
|
3039
|
-
// src/components/ThreadList.tsx
|
|
3040
|
-
import { jsxDEV as jsxDEV25, Fragment as Fragment2 } from "react/jsx-dev-runtime";
|
|
3041
|
-
var BUBBLE_PATH = "M13.5 7.6c0 2.4-2.5 4.4-5.5 4.4-.6 0-1.2-.08-1.7-.23L3 13l.8-2.3C3 9.8 2.5 8.7 2.5 7.6 2.5 5.2 5 3.2 8 3.2s5.5 2 5.5 4.4Z";
|
|
3042
|
-
function ThreadList(props) {
|
|
3043
|
-
const { config, t, threads, selectedThread, deleteThread } = useCortex();
|
|
3044
|
-
const locale = config.locale ?? "en";
|
|
3045
|
-
return /* @__PURE__ */ jsxDEV25("div", {
|
|
3046
|
-
className: props.className,
|
|
3047
|
-
children: [
|
|
3048
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3049
|
-
className: "cortex-widget__threads-header",
|
|
3050
|
-
children: [
|
|
3051
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3052
|
-
children: [
|
|
3053
|
-
/* @__PURE__ */ jsxDEV25("h2", {
|
|
3054
|
-
className: "cortex-widget__threads-title",
|
|
3055
|
-
children: t("translate_threads")
|
|
3056
|
-
}, undefined, false, undefined, this),
|
|
3057
|
-
/* @__PURE__ */ jsxDEV25("p", {
|
|
3058
|
-
className: "cortex-widget__threads-count",
|
|
3059
|
-
children: t(threads?.length === 1 ? "translate_one_conversation" : "translate_n_conversations", {
|
|
3060
|
-
count: threads?.length ?? 0
|
|
3061
|
-
})
|
|
3062
|
-
}, undefined, false, undefined, this)
|
|
3063
|
-
]
|
|
3064
|
-
}, undefined, true, undefined, this),
|
|
3065
|
-
/* @__PURE__ */ jsxDEV25("button", {
|
|
3066
|
-
onClick: () => props.onNewChatRequested(),
|
|
3067
|
-
className: "cortex-widget__new-chat-btn",
|
|
3068
|
-
children: [
|
|
3069
|
-
/* @__PURE__ */ jsxDEV25("svg", {
|
|
3070
|
-
width: "12",
|
|
3071
|
-
height: "12",
|
|
3072
|
-
viewBox: "0 0 16 16",
|
|
3073
|
-
fill: "none",
|
|
3074
|
-
children: /* @__PURE__ */ jsxDEV25("path", {
|
|
3075
|
-
d: "M8 3v10M3 8h10",
|
|
3076
|
-
stroke: "currentColor",
|
|
3077
|
-
strokeWidth: "1.5",
|
|
3078
|
-
strokeLinecap: "round"
|
|
3079
|
-
}, undefined, false, undefined, this)
|
|
3080
|
-
}, undefined, false, undefined, this),
|
|
3081
|
-
t("translate_new")
|
|
3082
|
-
]
|
|
3083
|
-
}, undefined, true, undefined, this)
|
|
3084
|
-
]
|
|
3085
|
-
}, undefined, true, undefined, this),
|
|
3086
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3087
|
-
className: "cortex-widget__threads-list",
|
|
3088
|
-
children: threads === undefined ? [1, 2, 3, 4].map((i) => /* @__PURE__ */ jsxDEV25("div", {
|
|
3089
|
-
className: "cortex-widget__thread-skeleton",
|
|
3090
|
-
children: [
|
|
3091
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3092
|
-
className: "cortex-skeleton cortex-widget__thread-skeleton-icon"
|
|
3093
|
-
}, undefined, false, undefined, this),
|
|
3094
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3095
|
-
className: "cortex-widget__thread-skeleton-lines",
|
|
3096
|
-
children: /* @__PURE__ */ jsxDEV25("div", {
|
|
3097
|
-
className: "cortex-skeleton cortex-widget__thread-skeleton-line",
|
|
3098
|
-
style: { width: `${40 + i * 12}%` }
|
|
3099
|
-
}, undefined, false, undefined, this)
|
|
3100
|
-
}, undefined, false, undefined, this)
|
|
3101
|
-
]
|
|
3102
|
-
}, i, true, undefined, this)) : /* @__PURE__ */ jsxDEV25(Fragment2, {
|
|
3103
|
-
children: [
|
|
3104
|
-
threads.map((thread) => {
|
|
3105
|
-
const isActive = thread.id === selectedThread?.id;
|
|
3106
|
-
const time = relativeTimeLabel(thread.updatedAt, locale);
|
|
3107
|
-
return /* @__PURE__ */ jsxDEV25("button", {
|
|
3108
|
-
onClick: () => props.onThreadSelected(thread),
|
|
3109
|
-
className: cx("cortex-widget__thread-item", isActive && "cortex-widget__thread-item--active"),
|
|
3110
|
-
children: [
|
|
3111
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3112
|
-
className: cx("cortex-widget__thread-icon", isActive && "cortex-widget__thread-icon--active"),
|
|
3113
|
-
children: /* @__PURE__ */ jsxDEV25("svg", {
|
|
3114
|
-
width: "14",
|
|
3115
|
-
height: "14",
|
|
3116
|
-
viewBox: "0 0 16 16",
|
|
3117
|
-
fill: "none",
|
|
3118
|
-
children: /* @__PURE__ */ jsxDEV25("path", {
|
|
3119
|
-
d: BUBBLE_PATH,
|
|
3120
|
-
stroke: "currentColor",
|
|
3121
|
-
strokeWidth: "1.3",
|
|
3122
|
-
strokeLinecap: "round",
|
|
3123
|
-
strokeLinejoin: "round"
|
|
3124
|
-
}, undefined, false, undefined, this)
|
|
3125
|
-
}, undefined, false, undefined, this)
|
|
3126
|
-
}, undefined, false, undefined, this),
|
|
3127
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3128
|
-
className: "cortex-widget__thread-info",
|
|
3129
|
-
children: [
|
|
3130
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3131
|
-
className: "cortex-widget__thread-title-row",
|
|
3132
|
-
children: [
|
|
3133
|
-
/* @__PURE__ */ jsxDEV25("p", {
|
|
3134
|
-
className: cx("cortex-widget__thread-title", isActive && "cortex-widget__thread-title--active"),
|
|
3135
|
-
children: thread.title ?? t("translate_untitled")
|
|
3136
|
-
}, undefined, false, undefined, this),
|
|
3137
|
-
thread.isRunning && /* @__PURE__ */ jsxDEV25("span", {
|
|
3138
|
-
className: cx("cortex-widget__thread-running", isActive && "cortex-widget__thread-running--active"),
|
|
3139
|
-
children: [
|
|
3140
|
-
/* @__PURE__ */ jsxDEV25("span", {
|
|
3141
|
-
className: "cortex-widget__thread-running-dot"
|
|
3142
|
-
}, undefined, false, undefined, this),
|
|
3143
|
-
t("translate_running")
|
|
3144
|
-
]
|
|
3145
|
-
}, undefined, true, undefined, this)
|
|
3146
|
-
]
|
|
3147
|
-
}, undefined, true, undefined, this),
|
|
3148
|
-
time && /* @__PURE__ */ jsxDEV25("p", {
|
|
3149
|
-
className: "cortex-widget__thread-time",
|
|
3150
|
-
children: time
|
|
3151
|
-
}, undefined, false, undefined, this)
|
|
3152
|
-
]
|
|
3153
|
-
}, undefined, true, undefined, this),
|
|
3154
|
-
/* @__PURE__ */ jsxDEV25("span", {
|
|
3155
|
-
role: "button",
|
|
3156
|
-
tabIndex: 0,
|
|
3157
|
-
onClick: (event) => {
|
|
3158
|
-
event.stopPropagation();
|
|
3159
|
-
deleteThread(thread.id);
|
|
3160
|
-
},
|
|
3161
|
-
onKeyDown: (event) => {
|
|
3162
|
-
if (event.key !== "Enter" && event.key !== " ")
|
|
3163
|
-
return;
|
|
3164
|
-
event.preventDefault();
|
|
3165
|
-
event.stopPropagation();
|
|
3166
|
-
deleteThread(thread.id);
|
|
3167
|
-
},
|
|
3168
|
-
className: cx("cortex-widget__thread-delete", isActive && "cortex-widget__thread-delete--active"),
|
|
3169
|
-
children: /* @__PURE__ */ jsxDEV25("svg", {
|
|
3170
|
-
width: "12",
|
|
3171
|
-
height: "12",
|
|
3172
|
-
viewBox: "0 0 16 16",
|
|
3173
|
-
fill: "none",
|
|
3174
|
-
children: /* @__PURE__ */ jsxDEV25("path", {
|
|
3175
|
-
d: "M4 4l8 8M12 4l-8 8",
|
|
3176
|
-
stroke: "currentColor",
|
|
3177
|
-
strokeWidth: "1.3",
|
|
3178
|
-
strokeLinecap: "round"
|
|
3179
|
-
}, undefined, false, undefined, this)
|
|
3180
|
-
}, undefined, false, undefined, this)
|
|
3181
|
-
}, undefined, false, undefined, this),
|
|
3182
|
-
/* @__PURE__ */ jsxDEV25("svg", {
|
|
3183
|
-
className: cx("cortex-widget__thread-arrow", isActive && "cortex-widget__thread-arrow--active"),
|
|
3184
|
-
width: "10",
|
|
3185
|
-
height: "10",
|
|
3186
|
-
viewBox: "0 0 16 16",
|
|
3187
|
-
fill: "none",
|
|
3188
|
-
children: /* @__PURE__ */ jsxDEV25("path", {
|
|
3189
|
-
d: "M6 4l4 4-4 4",
|
|
3190
|
-
stroke: "currentColor",
|
|
3191
|
-
strokeWidth: "1.5",
|
|
3192
|
-
strokeLinecap: "round",
|
|
3193
|
-
strokeLinejoin: "round"
|
|
3194
|
-
}, undefined, false, undefined, this)
|
|
3195
|
-
}, undefined, false, undefined, this)
|
|
3196
|
-
]
|
|
3197
|
-
}, thread.id, true, undefined, this);
|
|
3198
|
-
}),
|
|
3199
|
-
!threads.length && /* @__PURE__ */ jsxDEV25("div", {
|
|
3200
|
-
className: "cortex-widget__threads-empty",
|
|
3201
|
-
children: [
|
|
3202
|
-
/* @__PURE__ */ jsxDEV25("div", {
|
|
3203
|
-
className: "cortex-widget__threads-empty-icon",
|
|
3204
|
-
children: /* @__PURE__ */ jsxDEV25("svg", {
|
|
3205
|
-
width: "18",
|
|
3206
|
-
height: "18",
|
|
3207
|
-
viewBox: "0 0 16 16",
|
|
3208
|
-
fill: "none",
|
|
3209
|
-
className: "cortex-widget__threads-empty-svg",
|
|
3210
|
-
children: /* @__PURE__ */ jsxDEV25("path", {
|
|
3211
|
-
d: BUBBLE_PATH,
|
|
3212
|
-
stroke: "currentColor",
|
|
3213
|
-
strokeWidth: "1.3",
|
|
3214
|
-
strokeLinecap: "round",
|
|
3215
|
-
strokeLinejoin: "round"
|
|
3216
|
-
}, undefined, false, undefined, this)
|
|
3217
|
-
}, undefined, false, undefined, this)
|
|
3218
|
-
}, undefined, false, undefined, this),
|
|
3219
|
-
/* @__PURE__ */ jsxDEV25("p", {
|
|
3220
|
-
className: "cortex-widget__threads-empty-title",
|
|
3221
|
-
children: t("translate_no_threads_yet")
|
|
3222
|
-
}, undefined, false, undefined, this),
|
|
3223
|
-
/* @__PURE__ */ jsxDEV25("p", {
|
|
3224
|
-
className: "cortex-widget__threads-empty-subtitle",
|
|
3225
|
-
children: t("translate_start_a_new_conversation")
|
|
3226
|
-
}, undefined, false, undefined, this),
|
|
3227
|
-
/* @__PURE__ */ jsxDEV25("button", {
|
|
3228
|
-
onClick: () => props.onNewChatRequested(),
|
|
3229
|
-
className: "cortex-widget__new-chat-btn cortex-widget__new-chat-btn--empty-state",
|
|
3230
|
-
children: t("translate_new_chat")
|
|
3231
|
-
}, undefined, false, undefined, this)
|
|
3232
|
-
]
|
|
3233
|
-
}, undefined, true, undefined, this)
|
|
3234
|
-
]
|
|
3235
|
-
}, undefined, true, undefined, this)
|
|
3236
|
-
}, undefined, false, undefined, this)
|
|
3237
|
-
]
|
|
3238
|
-
}, undefined, true, undefined, this);
|
|
3239
|
-
}
|
|
3240
|
-
|
|
3241
|
-
// src/components/CortexChatWidget.tsx
|
|
3242
|
-
import { jsxDEV as jsxDEV26 } from "react/jsx-dev-runtime";
|
|
3243
|
-
var initialSessionUi = {
|
|
3244
|
-
messages: [],
|
|
3245
|
-
isAgentWorking: false,
|
|
3246
|
-
isLoadingMessages: false,
|
|
3247
|
-
hasPendingToolCalls: false,
|
|
3248
|
-
messageMetadata: new Map
|
|
3249
|
-
};
|
|
3250
|
-
function CortexChatWidget({
|
|
3251
|
-
config,
|
|
3252
|
-
className
|
|
3253
|
-
}) {
|
|
3254
|
-
const configRef = useRef8(config);
|
|
3255
|
-
configRef.current = config;
|
|
3256
|
-
const [threads, setThreads] = useState9();
|
|
3257
|
-
const [session, setSession] = useState9();
|
|
3258
|
-
const [sessionUi, setSessionUi] = useState9(initialSessionUi);
|
|
3259
|
-
const [debugMode, setDebugMode] = useState9(false);
|
|
3260
|
-
const [screen, setScreen] = useState9("threads");
|
|
3261
|
-
const [sidebarOpen, setSidebarOpen] = useState9(false);
|
|
3262
|
-
const sessionRef = useRef8(undefined);
|
|
3263
|
-
const pendingSendRef = useRef8([]);
|
|
3264
|
-
const pendingThreadCreation = useRef8(undefined);
|
|
3265
|
-
const composerRef = useRef8(null);
|
|
3266
|
-
const api = useMemo3(() => createCortexApiClient(() => configRef.current.transport), []);
|
|
3267
|
-
const selectedThread = useMemo3(() => {
|
|
3268
|
-
const snapshot = session?.thread;
|
|
3269
|
-
if (!snapshot)
|
|
3270
|
-
return;
|
|
3271
|
-
return threads?.find((thread) => thread.id === snapshot.id) ?? snapshot;
|
|
3272
|
-
}, [threads, session]);
|
|
3273
|
-
const selectedThreadRef = useRef8(selectedThread);
|
|
3274
|
-
selectedThreadRef.current = selectedThread;
|
|
3275
|
-
const sessionUiRef = useRef8(sessionUi);
|
|
3276
|
-
sessionUiRef.current = sessionUi;
|
|
3277
|
-
const patchUi = useCallback((patch) => {
|
|
3278
|
-
setSessionUi((previous) => ({
|
|
3279
|
-
...previous,
|
|
3280
|
-
...typeof patch === "function" ? patch(previous) : patch
|
|
3281
|
-
}));
|
|
3282
|
-
}, []);
|
|
3283
|
-
const setRunning = useCallback((threadId, isRunning) => {
|
|
3284
|
-
setThreads((current) => {
|
|
3285
|
-
const thread = current?.find((candidate) => candidate.id === threadId);
|
|
3286
|
-
return thread ? upsertThread(current ?? [], { ...thread, isRunning }) : current;
|
|
3287
|
-
});
|
|
3288
|
-
}, []);
|
|
3289
|
-
const selectThread = useCallback((thread, options) => {
|
|
3290
|
-
if (selectedThreadRef.current?.id === thread.id && sessionRef.current)
|
|
3291
|
-
return;
|
|
3292
|
-
const previous = selectedThreadRef.current;
|
|
3293
|
-
selectedThreadRef.current = thread;
|
|
3294
|
-
setSessionUi(initialSessionUi);
|
|
3295
|
-
setSession({ thread, mode: options?.skipLoadingMessages ? "skip" : "load", epoch: 0 });
|
|
3296
|
-
if (previous && previous.id !== thread.id) {
|
|
3297
|
-
configRef.current.hooks?.onThreadDeselected?.(previous);
|
|
3298
|
-
}
|
|
3299
|
-
configRef.current.hooks?.onThreadSelected?.(thread);
|
|
3300
|
-
}, []);
|
|
3301
|
-
const deselectThread = useCallback(() => {
|
|
3302
|
-
const previous = selectedThreadRef.current;
|
|
3303
|
-
if (!previous && !sessionRef.current)
|
|
3304
|
-
return;
|
|
3305
|
-
selectedThreadRef.current = undefined;
|
|
3306
|
-
setSession(undefined);
|
|
3307
|
-
setSessionUi(initialSessionUi);
|
|
3308
|
-
if (previous) {
|
|
3309
|
-
configRef.current.hooks?.onThreadDeselected?.(previous);
|
|
3310
|
-
}
|
|
3311
|
-
}, []);
|
|
3312
|
-
const remountSession = useCallback((thread) => {
|
|
3313
|
-
patchUi({ hasPendingToolCalls: false, messageMetadata: new Map });
|
|
3314
|
-
setSession((current) => ({ thread, mode: "reload", epoch: (current?.epoch ?? 0) + 1 }));
|
|
3315
|
-
}, [patchUi]);
|
|
3316
|
-
const ensureThread = useCallback((prompt) => {
|
|
3317
|
-
const selected = selectedThreadRef.current;
|
|
3318
|
-
if (selected)
|
|
3319
|
-
return Promise.resolve(selected.id);
|
|
3320
|
-
pendingThreadCreation.current ??= api.createThread(prompt).then((thread) => {
|
|
3321
|
-
pendingThreadCreation.current = undefined;
|
|
3322
|
-
setThreads((current) => upsertThread(current ?? [], thread));
|
|
3323
|
-
selectThread(thread, { skipLoadingMessages: true });
|
|
3324
|
-
return thread.id;
|
|
3325
|
-
}, (error) => {
|
|
3326
|
-
pendingThreadCreation.current = undefined;
|
|
3327
|
-
throw error;
|
|
3328
|
-
});
|
|
3329
|
-
return pendingThreadCreation.current;
|
|
3330
|
-
}, [api, selectThread]);
|
|
3331
|
-
const queueStore = useMemo3(() => createAttachmentQueue({ api, ensureThread: () => ensureThread() }), [api, ensureThread]);
|
|
3332
|
-
const queueItems = useSyncExternalStore(queueStore.subscribe, queueStore.getState, queueStore.getState);
|
|
3333
|
-
const send = useCallback(async (prompt, attachments = []) => {
|
|
3334
|
-
if (sessionUiRef.current.isAgentWorking || sessionUiRef.current.hasPendingToolCalls)
|
|
3335
|
-
return;
|
|
3336
|
-
const handle = sessionRef.current;
|
|
3337
|
-
if (handle) {
|
|
3338
|
-
await handle.send(prompt, attachments);
|
|
3339
|
-
return;
|
|
3340
|
-
}
|
|
3341
|
-
pendingSendRef.current.push({ prompt, attachments });
|
|
3342
|
-
try {
|
|
3343
|
-
await ensureThread(prompt);
|
|
3344
|
-
} catch (error) {
|
|
3345
|
-
pendingSendRef.current = [];
|
|
3346
|
-
throw error;
|
|
3347
|
-
}
|
|
3348
|
-
}, [ensureThread]);
|
|
3349
|
-
const abort = useCallback(async () => {
|
|
3350
|
-
await sessionRef.current?.abort();
|
|
3351
|
-
}, []);
|
|
3352
|
-
const addToolResult = useCallback((toolCallId, toolName, output) => {
|
|
3353
|
-
sessionRef.current?.addToolResult(toolCallId, toolName, output);
|
|
3354
|
-
}, []);
|
|
3355
|
-
const deleteThread = useCallback(async (threadId) => {
|
|
3356
|
-
if (selectedThreadRef.current?.id === threadId)
|
|
3357
|
-
deselectThread();
|
|
3358
|
-
await api.deleteThread(threadId);
|
|
3359
|
-
setThreads((current) => current ? removeThread(current, threadId) : current);
|
|
3360
|
-
}, [api, deselectThread]);
|
|
3361
|
-
const onTurnFinished = useCallback(() => {
|
|
3362
|
-
queueStore.discardConsumed();
|
|
3363
|
-
setTimeout(() => composerRef.current?.focusInput());
|
|
3364
|
-
}, [queueStore]);
|
|
3365
|
-
const onSendFailed = useCallback(() => {
|
|
3366
|
-
queueStore.restoreConsumed(selectedThreadRef.current?.id);
|
|
3367
|
-
}, [queueStore]);
|
|
3368
|
-
const reloadThreads = useCallback(async () => {
|
|
3369
|
-
const listed = sortThreads(await api.listThreads());
|
|
3370
|
-
setThreads(listed);
|
|
3371
|
-
return listed;
|
|
3372
|
-
}, [api]);
|
|
3373
|
-
const handleWsEvent = useCallback((event) => {
|
|
3374
|
-
setThreads((current) => {
|
|
3375
|
-
const next = applyWsEvent(current ?? [], event);
|
|
3376
|
-
return current || next.length ? next : current;
|
|
3377
|
-
});
|
|
3378
|
-
const selectedId = selectedThreadRef.current?.id;
|
|
3379
|
-
switch (event.type) {
|
|
3380
|
-
case "thread:deleted":
|
|
3381
|
-
if (selectedId === event.payload.threadId)
|
|
3382
|
-
deselectThread();
|
|
3383
|
-
break;
|
|
3384
|
-
case "thread:run-started":
|
|
3385
|
-
if (selectedId === event.payload.thread.id) {
|
|
3386
|
-
sessionRef.current?.reattach(event.payload.thread);
|
|
3387
|
-
}
|
|
3388
|
-
break;
|
|
3389
|
-
case "thread:messages-updated":
|
|
3390
|
-
sessionRef.current?.refreshMessages(event.payload.threadId);
|
|
3391
|
-
break;
|
|
3392
|
-
}
|
|
3393
|
-
}, [deselectThread]);
|
|
3394
|
-
useEffect6(() => {
|
|
3395
|
-
reloadThreads();
|
|
3396
|
-
let openedOnce = false;
|
|
3397
|
-
const socket = createCortexSocket({
|
|
3398
|
-
wsUrl: () => configRef.current.wsUrl,
|
|
3399
|
-
transport: {
|
|
3400
|
-
baseUrl: () => {
|
|
3401
|
-
const baseUrl = configRef.current.transport.baseUrl;
|
|
3402
|
-
return typeof baseUrl === "string" ? baseUrl : baseUrl();
|
|
3403
|
-
},
|
|
3404
|
-
getHeaders: () => configRef.current.transport.getHeaders()
|
|
3405
|
-
},
|
|
3406
|
-
onEvent: handleWsEvent,
|
|
3407
|
-
onOpen: () => {
|
|
3408
|
-
if (!openedOnce) {
|
|
3409
|
-
openedOnce = true;
|
|
3410
|
-
return;
|
|
3411
|
-
}
|
|
3412
|
-
reloadThreads().then((listed) => {
|
|
3413
|
-
const selected = selectedThreadRef.current;
|
|
3414
|
-
if (!selected)
|
|
3415
|
-
return;
|
|
3416
|
-
sessionRef.current?.reattach(listed.find((thread) => thread.id === selected.id) ?? selected);
|
|
3417
|
-
});
|
|
3418
|
-
}
|
|
3419
|
-
});
|
|
3420
|
-
return () => {
|
|
3421
|
-
socket.close();
|
|
3422
|
-
};
|
|
3423
|
-
}, [handleWsEvent, reloadThreads]);
|
|
3424
|
-
const previousThreadId = useRef8(undefined);
|
|
3425
|
-
const selectedThreadId = selectedThread?.id;
|
|
3426
|
-
useEffect6(() => {
|
|
3427
|
-
if (selectedThreadId === previousThreadId.current)
|
|
3428
|
-
return;
|
|
3429
|
-
queueStore.clear(previousThreadId.current);
|
|
3430
|
-
previousThreadId.current = selectedThreadId;
|
|
3431
|
-
}, [selectedThreadId, queueStore]);
|
|
3432
|
-
const locale = config.locale ?? "en";
|
|
3433
|
-
const t = useCallback((key, params) => translate(locale, key, params), [locale]);
|
|
3434
|
-
const viewMode = config.viewMode ?? "helper";
|
|
3435
|
-
const contextValue = {
|
|
3436
|
-
config,
|
|
3437
|
-
t,
|
|
3438
|
-
api,
|
|
3439
|
-
debugMode,
|
|
3440
|
-
threads,
|
|
3441
|
-
selectedThread,
|
|
3442
|
-
deleteThread,
|
|
3443
|
-
...sessionUi,
|
|
3444
|
-
send,
|
|
3445
|
-
abort,
|
|
3446
|
-
addToolResult,
|
|
3447
|
-
queue: {
|
|
3448
|
-
items: queueItems,
|
|
3449
|
-
...attachmentQueueFlags(queueItems),
|
|
3450
|
-
accept: queueStore.accept,
|
|
3451
|
-
remove: queueStore.remove,
|
|
3452
|
-
consumeReady: queueStore.consumeReady
|
|
3453
|
-
}
|
|
3454
|
-
};
|
|
3455
|
-
function openThread(thread) {
|
|
3456
|
-
selectThread(thread);
|
|
3457
|
-
setScreen("chat");
|
|
3458
|
-
setSidebarOpen(false);
|
|
3459
|
-
}
|
|
3460
|
-
function newChat() {
|
|
3461
|
-
deselectThread();
|
|
3462
|
-
setScreen("chat");
|
|
3463
|
-
setSidebarOpen(false);
|
|
3464
|
-
}
|
|
3465
|
-
function goBack() {
|
|
3466
|
-
deselectThread();
|
|
3467
|
-
setScreen("threads");
|
|
3468
|
-
}
|
|
3469
|
-
return /* @__PURE__ */ jsxDEV26(CortexContext.Provider, {
|
|
3470
|
-
value: contextValue,
|
|
3471
|
-
children: /* @__PURE__ */ jsxDEV26("div", {
|
|
3472
|
-
className: cx("cortex-widget", className),
|
|
3473
|
-
"data-cortex-theme": config.theme,
|
|
3474
|
-
children: [
|
|
3475
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3476
|
-
className: cx("cortex-widget__container", viewMode === "full" && "cortex-widget__container--full", sidebarOpen && "cortex-widget__container--sidebar-open"),
|
|
3477
|
-
onDragOver: (event) => event.preventDefault(),
|
|
3478
|
-
onDrop: (event) => event.preventDefault(),
|
|
3479
|
-
children: [
|
|
3480
|
-
/* @__PURE__ */ jsxDEV26(ThreadList, {
|
|
3481
|
-
className: cx("cortex-widget__screen", screen === "threads" && "cortex-widget__screen--active", screen !== "threads" && "cortex-widget__screen--left"),
|
|
3482
|
-
onThreadSelected: openThread,
|
|
3483
|
-
onNewChatRequested: newChat
|
|
3484
|
-
}, undefined, false, undefined, this),
|
|
3485
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3486
|
-
className: cx("cortex-widget__screen", screen === "chat" && "cortex-widget__screen--active", screen !== "chat" && "cortex-widget__screen--right"),
|
|
3487
|
-
children: [
|
|
3488
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3489
|
-
className: "cortex-widget__chat-header",
|
|
3490
|
-
children: [
|
|
3491
|
-
/* @__PURE__ */ jsxDEV26("button", {
|
|
3492
|
-
onClick: () => setSidebarOpen((open) => !open),
|
|
3493
|
-
className: "cortex-widget__sidebar-toggle-btn",
|
|
3494
|
-
children: /* @__PURE__ */ jsxDEV26("svg", {
|
|
3495
|
-
width: "16",
|
|
3496
|
-
height: "16",
|
|
3497
|
-
viewBox: "0 0 16 16",
|
|
3498
|
-
fill: "none",
|
|
3499
|
-
children: /* @__PURE__ */ jsxDEV26("path", {
|
|
3500
|
-
d: "M2.5 4h11M2.5 8h11M2.5 12h11",
|
|
3501
|
-
stroke: "currentColor",
|
|
3502
|
-
strokeWidth: "1.4",
|
|
3503
|
-
strokeLinecap: "round"
|
|
3504
|
-
}, undefined, false, undefined, this)
|
|
3505
|
-
}, undefined, false, undefined, this)
|
|
3506
|
-
}, undefined, false, undefined, this),
|
|
3507
|
-
/* @__PURE__ */ jsxDEV26("button", {
|
|
3508
|
-
onClick: goBack,
|
|
3509
|
-
className: "cortex-widget__back-btn",
|
|
3510
|
-
children: /* @__PURE__ */ jsxDEV26("svg", {
|
|
3511
|
-
width: "14",
|
|
3512
|
-
height: "14",
|
|
3513
|
-
viewBox: "0 0 16 16",
|
|
3514
|
-
fill: "none",
|
|
3515
|
-
className: "cortex-widget__back-icon",
|
|
3516
|
-
children: /* @__PURE__ */ jsxDEV26("path", {
|
|
3517
|
-
d: "M10 3L5 8l5 5",
|
|
3518
|
-
stroke: "currentColor",
|
|
3519
|
-
strokeWidth: "1.5",
|
|
3520
|
-
strokeLinecap: "round",
|
|
3521
|
-
strokeLinejoin: "round"
|
|
3522
|
-
}, undefined, false, undefined, this)
|
|
3523
|
-
}, undefined, false, undefined, this)
|
|
3524
|
-
}, undefined, false, undefined, this),
|
|
3525
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3526
|
-
className: "cortex-widget__chat-title-wrap",
|
|
3527
|
-
children: /* @__PURE__ */ jsxDEV26("p", {
|
|
3528
|
-
className: "cortex-widget__chat-title",
|
|
3529
|
-
children: selectedThread?.title ?? t("translate_new_chat")
|
|
3530
|
-
}, undefined, false, undefined, this)
|
|
3531
|
-
}, undefined, false, undefined, this),
|
|
3532
|
-
config.showDebugButton && /* @__PURE__ */ jsxDEV26("button", {
|
|
3533
|
-
onClick: () => setDebugMode((mode) => !mode),
|
|
3534
|
-
className: cx("cortex-widget__debug-btn", debugMode ? "cortex-widget__debug-btn--on" : "cortex-widget__debug-btn--off"),
|
|
3535
|
-
children: debugMode ? t("translate_debug") : t("translate_normal")
|
|
3536
|
-
}, undefined, false, undefined, this)
|
|
3537
|
-
]
|
|
3538
|
-
}, undefined, true, undefined, this),
|
|
3539
|
-
sessionUi.isLoadingMessages && !sessionUi.isAgentWorking ? /* @__PURE__ */ jsxDEV26("div", {
|
|
3540
|
-
className: "cortex-widget__messages-skeleton",
|
|
3541
|
-
children: [
|
|
3542
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3543
|
-
className: "cortex-widget__msg-skel cortex-widget__msg-skel--user",
|
|
3544
|
-
children: /* @__PURE__ */ jsxDEV26("div", {
|
|
3545
|
-
className: "cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user",
|
|
3546
|
-
children: [
|
|
3547
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3548
|
-
className: "cortex-skeleton cortex-widget__msg-skel-line",
|
|
3549
|
-
style: { width: "13rem" }
|
|
3550
|
-
}, undefined, false, undefined, this),
|
|
3551
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3552
|
-
className: "cortex-skeleton cortex-widget__msg-skel-line",
|
|
3553
|
-
style: { width: "9rem" }
|
|
3554
|
-
}, undefined, false, undefined, this)
|
|
3555
|
-
]
|
|
3556
|
-
}, undefined, true, undefined, this)
|
|
3557
|
-
}, undefined, false, undefined, this),
|
|
3558
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3559
|
-
className: "cortex-widget__msg-skel cortex-widget__msg-skel--assistant",
|
|
3560
|
-
children: /* @__PURE__ */ jsxDEV26("div", {
|
|
3561
|
-
className: "cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant",
|
|
3562
|
-
children: [
|
|
3563
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3564
|
-
className: "cortex-skeleton cortex-widget__msg-skel-line",
|
|
3565
|
-
style: { width: "16rem" }
|
|
3566
|
-
}, undefined, false, undefined, this),
|
|
3567
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3568
|
-
className: "cortex-skeleton cortex-widget__msg-skel-line",
|
|
3569
|
-
style: { width: "18rem" }
|
|
3570
|
-
}, undefined, false, undefined, this),
|
|
3571
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3572
|
-
className: "cortex-skeleton cortex-widget__msg-skel-line",
|
|
3573
|
-
style: { width: "12rem" }
|
|
3574
|
-
}, undefined, false, undefined, this)
|
|
3575
|
-
]
|
|
3576
|
-
}, undefined, true, undefined, this)
|
|
3577
|
-
}, undefined, false, undefined, this),
|
|
3578
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3579
|
-
className: "cortex-widget__msg-skel cortex-widget__msg-skel--user",
|
|
3580
|
-
children: /* @__PURE__ */ jsxDEV26("div", {
|
|
3581
|
-
className: "cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user",
|
|
3582
|
-
children: /* @__PURE__ */ jsxDEV26("div", {
|
|
3583
|
-
className: "cortex-skeleton cortex-widget__msg-skel-line",
|
|
3584
|
-
style: { width: "11rem" }
|
|
3585
|
-
}, undefined, false, undefined, this)
|
|
3586
|
-
}, undefined, false, undefined, this)
|
|
3587
|
-
}, undefined, false, undefined, this),
|
|
3588
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3589
|
-
className: "cortex-widget__msg-skel cortex-widget__msg-skel--assistant",
|
|
3590
|
-
children: /* @__PURE__ */ jsxDEV26("div", {
|
|
3591
|
-
className: "cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant",
|
|
3592
|
-
children: [
|
|
3593
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3594
|
-
className: "cortex-skeleton cortex-widget__msg-skel-line",
|
|
3595
|
-
style: { width: "14rem" }
|
|
3596
|
-
}, undefined, false, undefined, this),
|
|
3597
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3598
|
-
className: "cortex-skeleton cortex-widget__msg-skel-line",
|
|
3599
|
-
style: { width: "15rem" }
|
|
3600
|
-
}, undefined, false, undefined, this)
|
|
3601
|
-
]
|
|
3602
|
-
}, undefined, true, undefined, this)
|
|
3603
|
-
}, undefined, false, undefined, this)
|
|
3604
|
-
]
|
|
3605
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV26(MessageList, {
|
|
3606
|
-
className: "cortex-widget__messages",
|
|
3607
|
-
debugMode
|
|
3608
|
-
}, undefined, false, undefined, this),
|
|
3609
|
-
sessionUi.isAgentWorking && !sessionUi.hasPendingToolCalls && /* @__PURE__ */ jsxDEV26("div", {
|
|
3610
|
-
className: "cortex-widget__working",
|
|
3611
|
-
children: [
|
|
3612
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3613
|
-
className: "cortex-widget__working-dots",
|
|
3614
|
-
children: [
|
|
3615
|
-
/* @__PURE__ */ jsxDEV26("span", {
|
|
3616
|
-
className: "cortex-working-dot"
|
|
3617
|
-
}, undefined, false, undefined, this),
|
|
3618
|
-
/* @__PURE__ */ jsxDEV26("span", {
|
|
3619
|
-
className: "cortex-working-dot"
|
|
3620
|
-
}, undefined, false, undefined, this),
|
|
3621
|
-
/* @__PURE__ */ jsxDEV26("span", {
|
|
3622
|
-
className: "cortex-working-dot"
|
|
3623
|
-
}, undefined, false, undefined, this)
|
|
3624
|
-
]
|
|
3625
|
-
}, undefined, true, undefined, this),
|
|
3626
|
-
/* @__PURE__ */ jsxDEV26("span", {
|
|
3627
|
-
className: "cortex-widget__working-text",
|
|
3628
|
-
children: t("translate_thinking")
|
|
3629
|
-
}, undefined, false, undefined, this)
|
|
3630
|
-
]
|
|
3631
|
-
}, undefined, true, undefined, this),
|
|
3632
|
-
!sessionUi.hasPendingToolCalls && /* @__PURE__ */ jsxDEV26(ChatComposer, {
|
|
3633
|
-
ref: composerRef
|
|
3634
|
-
}, undefined, false, undefined, this)
|
|
3635
|
-
]
|
|
3636
|
-
}, undefined, true, undefined, this),
|
|
3637
|
-
/* @__PURE__ */ jsxDEV26("div", {
|
|
3638
|
-
className: "cortex-widget__sidebar-backdrop",
|
|
3639
|
-
onClick: () => setSidebarOpen(false)
|
|
3640
|
-
}, undefined, false, undefined, this)
|
|
3641
|
-
]
|
|
3642
|
-
}, undefined, true, undefined, this),
|
|
3643
|
-
session && /* @__PURE__ */ jsxDEV26(ChatSession, {
|
|
3644
|
-
thread: session.thread,
|
|
3645
|
-
mode: session.mode,
|
|
3646
|
-
api,
|
|
3647
|
-
configRef,
|
|
3648
|
-
sessionRef,
|
|
3649
|
-
pendingSendRef,
|
|
3650
|
-
patchUi,
|
|
3651
|
-
setRunning,
|
|
3652
|
-
remount: remountSession,
|
|
3653
|
-
onTurnFinished,
|
|
3654
|
-
onSendFailed
|
|
3655
|
-
}, `${session.thread.id}:${session.epoch}`, false, undefined, this)
|
|
3656
|
-
]
|
|
3657
|
-
}, undefined, true, undefined, this)
|
|
3658
|
-
}, undefined, false, undefined, this);
|
|
3659
|
-
}
|
|
3660
|
-
export {
|
|
3661
|
-
CortexChatWidget
|
|
3662
|
-
};
|
|
1
|
+
import{useCallback as T,useEffect as D0,useMemo as D1,useRef as k_,useState as F_,useSyncExternalStore as n2}from"react";function P_(_){return Promise.resolve(_.getHeaders())}function w1(_,N){let k=_.baseUrl;return(typeof k==="string"?k:k()).replace(/\/$/,"")+N}function n0(_){let N=_?.match(/filename\*\s*=\s*[^']*'[^']*'([^;\r\n]+)/i)?.[1]?.trim().replace(/^"|"$/g,"");if(N)try{return decodeURIComponent(N)}catch{}return _?.match(/filename\s*=\s*"?([^";\r\n]+)"?/i)?.[1]}function h_(_){function N(){return P_(_())}function k(Z){return w1(_(),Z)}async function L(Z,J){let X=new Headers(await N());if(new Headers(J?.headers).forEach(function(K,z){X.set(z,K)}),J?.body instanceof FormData)X.delete("Content-Type");else if(!X.has("Content-Type"))X.set("Content-Type","application/json");let G=await fetch(k(Z),{...J,headers:X});if(!G.ok)throw Error(`HTTP ${G.status}: ${G.statusText}`);let $=await G.text();return $?JSON.parse($):void 0}return{listThreads(){return L("/threads")},createThread(Z){return L("/threads",{method:"POST",body:JSON.stringify({prompt:Z})})},deleteThread(Z){return L(`/threads/${Z}`,{method:"DELETE"})},listMessages(Z){return L(`/threads/${Z}/messages`)},listLlmRequests(Z){return L(`/messages/${Z}/llm-requests`)},abortStream(Z){return L(`/chat/${Z}/abort`,{method:"POST"})},async uploadAttachment(Z,J){let X=new FormData;return X.append("file",J),await L(`/threads/${Z}/files`,{method:"POST",body:X})},deleteAttachment(Z){return L(`/files/${Z}`,{method:"DELETE"})},async downloadAttachment(Z){let J=await fetch(k(`/files/${Z}`),{headers:await N()});if(!J.ok)throw Error(`HTTP ${J.status}: ${J.statusText}`);return{blob:await J.blob(),name:n0(J.headers.get("Content-Disposition"))??Z}},resolveHeaders:N,resolveUrl:k}}var c0=new Set(["complete","error"]);function A_(_){return c0.has(_)}function O_(_){return(b_(_)?.parts??[]).filter((k)=>k.type==="tool-call"&&!A_(k.state))}function b_(_){for(let N=_.length-1;N>=0;N-=1){let k=_[N];if(k?.role==="assistant")return k}return}var C0={complete:"success",error:"error","approval-requested":"approval","approval-responded":"approval","awaiting-input":"pending","input-streaming":"pending","input-complete":"pending"},S0={"awaiting-input":"translate_calling","input-streaming":"translate_calling","input-complete":"translate_input_ready","approval-requested":"translate_needs_approval","approval-responded":"translate_responded",complete:"translate_completed",error:"translate_error"};function j_(_){let{state:N,approval:k}=_;return{modifier:C0[N],labelKey:N==="approval-responded"&&k?.approved?"translate_approved":S0[N],pulse:N==="awaiting-input"||N==="input-streaming"?"default":N==="approval-requested"?"violet":void 0}}function i_(_){let N=_.output;if(N===void 0||N===null)return"";if(typeof N==="string")return N;return JSON.stringify(N,null,2)}var P1={code:"javascript",query:"cypher"};function a_(_){let N=_&&typeof _==="object"?_:null,k=N?Object.entries(P1).flatMap(([Z,J])=>{let X=N[Z];return typeof X==="string"?[{key:Z,lang:J,value:X.replace(/\\n/g,`
|
|
2
|
+
`)}]:[]}):[],L=_;if(N){let Z=Object.fromEntries(Object.entries(N).filter(([J])=>!Object.hasOwn(P1,J)));L=Object.keys(Z).length>0?Z:null}return{codeSnippets:k,remainingInput:L,remainingInputText:L?JSON.stringify(L,null,2):""}}var A1=10,I0={"awaiting-input":"starting","input-streaming":"starting","input-complete":"processing","approval-requested":"processing","approval-responded":"processing",complete:"complete",error:"error"};function g0(_){let N=0;for(let k=0;k<_.length;k++)N=N*31+_.charCodeAt(k)|0;return Math.abs(N)%A1}function x_(_){let N=I0[_.state]??"processing",k=_.name==="readAttachment"?"attachment":"tool",L=k==="tool"?`_${g0(_.id)}`:"";return{state:N,active:N==="starting"||N==="processing",titleKey:N==="error"?"translate_tool_error":`translate_${k}_${N==="complete"?"done":"status"}${L}`}}function L_(_){return Array.from({length:A1},(N,k)=>`translate_${_}_${k}`)}var b1=["queryGraph","executeCode"];function d_(_,N,k){if(_.type==="thinking")return!(k&&N);if(_.type!=="tool-call")return!1;return b1.includes(_.name)&&A_(_.state)}import{EventType as f0}from"@tanstack/ai";import{fetchServerSentEvents as U1}from"@tanstack/ai-client";function t_(_){return{id:_.id,role:_.role,parts:_.parts}}function v1(_){for(let N=_.length-1;N>=0;N-=1){let k=_[N],L="parts"in k&&k.parts.some((Z)=>Z.type==="tool-result");if(k.role==="user"||L)return _.slice(N,N+1)}return _.slice(-1)}function U_(_){return new Map(_.flatMap((N)=>N.metadata?[[N.id,N.metadata]]:[]))}function s_(_){let{api:N,thread:k}=_,L=async()=>({headers:await N.resolveHeaders()}),Z=U1(()=>N.resolveUrl("/chat"),L),J=function($,K,z,M){return Z.connect(v1($),K,z,M)},X=U1(()=>N.resolveUrl(`/chat/${k.id}/stream`),L),G=[];return{connect:J,async*joinRun($,K){yield{type:f0.MESSAGES_SNAPSHOT,timestamp:Date.now(),messages:G},yield*X.joinRun($,K)},hydrate:async()=>{let $=await p0(_);return G=$.messages,$}}}async function p0(_){let{api:N,thread:k,mode:L}=_,Z=k.isRunning?{runId:k.id}:null;if(L==="skip")return{messages:[],activeRun:Z,interrupts:null};if(L==="load")_.setLoadingMessages?.(!0);try{let J=await N.listMessages(k.id),X=J.map(t_);return _.onHydrated?.(J,X),{messages:X,activeRun:Z,interrupts:null}}finally{_.setLoadingMessages?.(!1)}}async function e_(_){try{let N=await _.api.listMessages(_.threadId);if(_.isStale?.())return;if(_.absorbMetadata(U_(N)),_.isStreaming())return;_.setMessages(N.map(t_))}catch{}}var _1=["image/png","image/jpeg","image/webp","application/pdf"];var R1=5;function n1(_,N){if(!_1.some((k)=>k===_))return"type";if(N>10485760)return"size";return"ok"}function N1(_){let{api:N}=_,k=new Set,L=new Set,Z=[],J=[];function X(){return Z}function G(F){return k.add(F),()=>{k.delete(F)}}function $(F){Z=F;for(let W of k)W()}function K(F,W){$(Z.map((V)=>V.localId===F?{...V,...W}:V))}function z(F){if(L.delete(F))return;K(F,{status:"error"})}function M(F){let W=[];for(let V of F){let S=n1(V.type,V.size)!=="ok"||Z.filter((O)=>O.status!=="error").length>=R1,c=crypto.randomUUID();if($([...Z,{localId:c,filename:V.name,status:S?"error":"uploading"}]),!S)W.push({localId:c,file:V})}if(!W.length)return;_.ensureThread().then((V)=>{for(let{localId:S,file:c}of W){if(L.delete(S))continue;K(S,{threadId:V}),N.uploadAttachment(V,c).then((O)=>{if(L.delete(S)){N.deleteAttachment(O.id).catch(()=>{});return}K(S,{status:"ready",attachmentId:O.id,summary:O})},()=>z(S))}},()=>{for(let{localId:V}of W)z(V)})}function B(F){let W=Z.find((V)=>V.localId===F);if(!W)return;if(W.status==="uploading"){L.add(F),$(Z.filter((V)=>V.localId!==F));return}if(W.attachmentId){K(F,{status:"deleting"}),N.deleteAttachment(W.attachmentId).then(()=>$(Z.filter((V)=>V.localId!==F)),()=>K(F,{status:"error"}));return}$(Z.filter((V)=>V.localId!==F))}function U(F){let W=[];for(let V of Z){if(V.threadId!==void 0&&V.threadId!==F){W.push(V);continue}if(V.status==="uploading")L.add(V.localId);else if(V.status==="ready"&&V.threadId===F&&V.attachmentId)N.deleteAttachment(V.attachmentId).catch(()=>{})}$(W)}function v(){let F=Z.flatMap((W)=>W.status==="ready"&&W.summary?[{...W,status:"ready",summary:W.summary}]:[]);return $(Z.filter((W)=>W.status!=="ready")),J=F,F}function q(F){let W=J;if(J=[],W.some((V)=>V.threadId!==F))return;$([...W.map((V)=>({...V,status:"error"})),...Z])}function C(){J=[]}return{getState:X,subscribe:G,accept:M,remove:B,clear:U,consumeReady:v,restoreConsumed:q,discardConsumed:C}}function k1(_){return{uploading:_.some((N)=>N.status==="uploading"),busy:_.some((N)=>N.status==="uploading"||N.status==="deleting"),hasReady:_.some((N)=>N.status==="ready")}}function m0(_){return Math.min(1000*2**(_-1),30000)}var T0=1e4;function L1(_){let N,k,L=0,Z=!1;function J(){let G=typeof _.wsUrl==="function"?_.wsUrl():_.wsUrl,$=l0(G,_.transport.baseUrl);P_(_.transport).then((K)=>{if(Z)return;N=new WebSocket(j0($,K)),N.addEventListener("open",()=>{let z=N;setTimeout(()=>{if(N===z&&!Z)L=0},T0),_.onOpen?.()}),N.addEventListener("message",(z)=>{let M=z.data;if(typeof M!=="string")return;let B;try{B=JSON.parse(M)}catch{return}_.onEvent(B)}),N.addEventListener("close",X)}).catch(X)}function X(){if(Z||k)return;L+=1,k=setTimeout(()=>{k=void 0,J()},m0(L))}return J(),{close(){Z=!0,clearTimeout(k),N?.close()}}}function l0(_,N){let k=_??o0(N);if(!_)return k;let L=u0(N);if(!L)return k;return r0(k,L)}function o0(_){let N=typeof _==="string"?_:_(),k=new URL(N,window.location.origin);return k.protocol=k.protocol==="https:"?"wss:":"ws:",k.pathname=k.pathname.replace(/\/$/,"")+"/ws",k.toString()}function u0(_){let N=typeof _==="string"?_:_(),L=new URL(N,window.location.origin).pathname.split("/").filter(Boolean),Z=L.lastIndexOf("agents");if(Z===-1)return;return L[Z+1]}function r0(_,N){let k=new URL(_,window.location.origin);if(k.searchParams.has("agentId")||h0(k))return k.toString();return k.searchParams.set("agentId",N),k.toString()}function h0(_){let N=_.pathname.split("/").filter(Boolean),k=N.lastIndexOf("agents");return k!==-1&&Boolean(N[k+1])}function j0(_,N){let k=N.Authorization??N.authorization;if(!k?.startsWith("Bearer "))return _;let L=new URL(_,window.location.origin);if(L.searchParams.has("token"))return L.toString();return L.searchParams.set("token",k.slice(7)),L.toString()}function v_(_){return[..._].sort((N,k)=>{let L=Date.parse(k.updatedAt)-Date.parse(N.updatedAt);if(L!==0)return L;return Date.parse(k.createdAt)-Date.parse(N.createdAt)})}function D_(_,N){let k=[..._],L=k.findIndex((Z)=>Z.id===N.id);if(L===-1)k.push(N);else k[L]={...k[L],...N};return v_(k)}function R_(_,N){return _.filter((k)=>k.id!==N)}function Z1(_,N){switch(N.type){case"thread:deleted":return R_(_,N.payload.threadId);case"thread:created":case"thread:title-updated":case"thread:run-started":case"thread:run-finished":case"thread:messages-updated":return D_(_,N.payload.thread);default:return _}}import{marked as i0}from"marked";import a0 from"dompurify";function J1(_){if(!_)return"";let N=i0.parse(_,{async:!1});return N=N.replace(/<table>/g,'<div style="overflow-x:auto"><table style="width:auto">').replace(/<\/table>/g,"</table></div>").replace(/<(t[hd])([\s>])/g,'<$1 style="padding:0.5rem 1rem"$2'),a0.sanitize(N)}import B_ from"highlight.js/lib/core";import x0 from"highlight.js/lib/languages/javascript";import d0 from"highlight.js/lib/languages/json";import t0 from"highlight.js/lib/languages/sql";var c1=!1;function s0(){if(c1)return;c1=!0,B_.registerLanguage("javascript",x0),B_.registerLanguage("json",d0),B_.registerLanguage("cypher",t0)}function $1(_,N){if(!_)return"";return s0(),B_.getLanguage(N)?B_.highlight(_,{language:N}).value:e0(_)}function e0(_){return _.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">")}var C1={translate_new:"جديد",translate_threads:"المحادثات",translate_n_conversations:"{{count}} محادثات",translate_one_conversation:"محادثة واحدة",translate_no_threads_yet:"لا توجد محادثات بعد",translate_start_a_new_conversation:"ابدأ محادثة جديدة",translate_untitled:"بدون عنوان",translate_new_chat:"محادثة جديدة",translate_normal:"عادي",translate_debug:"تصحيح",translate_type_a_message:"اكتب رسالة...",translate_thinking:"جارٍ معالجة الطلب...",translate_reasoned:"تم الاستنتاج",translate_knowledge_graph_query:"استعلام الرسم البياني المعرفي",translate_javascript_code_execution:"تنفيذ كود جافاسكريبت",translate_completed:"مكتمل",translate_attach_files:"إرفاق ملفات",translate_drop_files_here:"أفلت ملفاتك هنا...",translate_remove_attachment:"إزالة المرفق",translate_attachment_rejected:"لا يمكن إرفاق هذا الملف",translate_attachment_caption:"من فضلك اطّلع على الملفات المرفقة.",translate_download:"تنزيل",translate_tool_status_0:"جارٍ جلب البيانات…",translate_tool_status_1:"جارٍ تحليل المعلومات…",translate_tool_status_2:"جارٍ معالجة الطلب…",translate_tool_status_3:"جارٍ تجميع النتائج…",translate_tool_status_4:"جارٍ تحضير الرد…",translate_tool_status_5:"جارٍ البحث…",translate_tool_status_6:"جارٍ فحص السجلات…",translate_tool_status_7:"جارٍ مراجعة التفاصيل…",translate_tool_status_8:"جارٍ إجراء الحسابات…",translate_tool_status_9:"جارٍ سحب المعلومات…",translate_tool_done_0:"تم جلب البيانات بنجاح",translate_tool_done_1:"تم التحليل بنجاح",translate_tool_done_2:"تمت معالجة الطلب بنجاح",translate_tool_done_3:"تم تجميع النتائج بنجاح",translate_tool_done_4:"تم تحضير الرد بنجاح",translate_tool_done_5:"تم البحث بنجاح",translate_tool_done_6:"تم فحص السجلات بنجاح",translate_tool_done_7:"تمت المراجعة بنجاح",translate_tool_done_8:"تمت الحسابات بنجاح",translate_tool_done_9:"تم استرجاع المعلومات بنجاح",translate_tool_error:"حدث خطأ",translate_attachment_status:"جارٍ قراءة الملف المرفق…",translate_attachment_done:"تمت قراءة الملف المرفق",translate_graph_0:"جارٍ استكشاف الروابط...",translate_graph_1:"جارٍ رسم الخريطة...",translate_graph_2:"جارٍ اكتشاف العلاقات...",translate_graph_3:"جارٍ تتبع الروابط...",translate_graph_4:"جارٍ التنقل في المعرفة...",translate_graph_5:"جارٍ كشف الرؤى...",translate_graph_6:"جارٍ ربط النقاط...",translate_graph_7:"جارٍ تتبع المسار...",translate_graph_8:"جارٍ تجميع الأجزاء...",translate_graph_9:"جارٍ بناء الصورة...",translate_code_0:"جارٍ حساب الأرقام...",translate_code_1:"جارٍ معالجة البيانات...",translate_code_2:"جارٍ تنفيذ طلبك...",translate_code_3:"جارٍ تحليل الأرقام...",translate_code_4:"جارٍ تجميع كل شيء...",translate_code_5:"جارٍ تحليل النتائج...",translate_code_6:"جارٍ العمل خلف الكواليس...",translate_code_7:"جارٍ ترتيب التفاصيل...",translate_code_8:"جارٍ تحضير إجابتك...",translate_code_9:"أوشك على الانتهاء...",translate_reasoning_0:"جارٍ التفكير...",translate_reasoning_1:"جارٍ دراسة الخيارات...",translate_reasoning_2:"جارٍ تقييم الاحتمالات...",translate_reasoning_3:"جارٍ التأمل في هذا...",translate_reasoning_4:"جارٍ إيجاد الحل...",translate_reasoning_5:"جارٍ ترتيب الأفكار...",translate_reasoning_6:"جارٍ التمعن في الأمر...",translate_reasoning_7:"جارٍ إيجاد أفضل طريقة...",translate_reasoning_8:"جارٍ تنظيم أفكاري...",translate_reasoning_9:"أوشك على الانتهاء...",translate_running:"قيد التنفيذ",translate_aborted:"تم الإلغاء",translate_input:"المدخلات",translate_output:"المخرجات",translate_calling:"جارٍ الاستدعاء",translate_input_ready:"المدخلات جاهزة",translate_needs_approval:"بحاجة إلى موافقة",translate_approved:"تمت الموافقة",translate_responded:"تم الرد",translate_error:"خطأ",translate_approval_requested:"طلب موافقة",translate_approval_response:"رد الموافقة",translate_waiting_for_approval:"في انتظار الموافقة لتنفيذ هذه الأداة.",translate_tool_approved:"تمت الموافقة.",translate_tool_response_received:"تم استلام الرد.",translate_tokens:"رمز",translate_fresh:"جديد",translate_cache_read:"قراءة من الذاكرة",translate_cache_write:"كتابة في الذاكرة",translate_n_percent_cached:"{{percent}}٪ مخزّن مؤقتًا",translate_text:"نص",translate_reasoning:"الاستنتاج",translate_read:"قراءة",translate_write:"كتابة",translate_total:"الإجمالي",translate_request:"الطلب",translate_response:"الرد",translate_step_n:"الخطوة {{number}}",translate_inspect_llm_requests:"فحص طلبات النموذج",translate_loading:"جارٍ التحميل…",translate_no_llm_requests:"لا توجد طلبات نموذج مسجّلة لهذه الرسالة.",translate_unhandled_type:"نوع غير مدعوم:"};var S1={translate_new:"New",translate_threads:"Threads",translate_n_conversations:"{{count}} conversations",translate_one_conversation:"1 conversation",translate_no_threads_yet:"No threads yet",translate_start_a_new_conversation:"Start a new conversation",translate_untitled:"Untitled",translate_new_chat:"New Chat",translate_normal:"Normal",translate_debug:"Debug",translate_type_a_message:"Type a message...",translate_thinking:"Thinking things through...",translate_reasoned:"Reasoned",translate_knowledge_graph_query:"Knowledge Graph Query",translate_javascript_code_execution:"JavaScript Code Execution",translate_completed:"Completed",translate_attach_files:"Attach files",translate_drop_files_here:"Drop your files here...",translate_remove_attachment:"Remove attachment",translate_attachment_rejected:"This file cannot be attached",translate_attachment_caption:"Please take a look at the attached files.",translate_download:"Download",translate_tool_status_0:"Fetching data...",translate_tool_status_1:"Analyzing information...",translate_tool_status_2:"Processing request...",translate_tool_status_3:"Gathering results...",translate_tool_status_4:"Preparing response...",translate_tool_status_5:"Looking things up...",translate_tool_status_6:"Checking records...",translate_tool_status_7:"Reviewing details...",translate_tool_status_8:"Running calculations...",translate_tool_status_9:"Pulling information...",translate_tool_done_0:"Data fetched successfully",translate_tool_done_1:"Analysis completed successfully",translate_tool_done_2:"Request processed successfully",translate_tool_done_3:"Results gathered successfully",translate_tool_done_4:"Response prepared successfully",translate_tool_done_5:"Lookup completed successfully",translate_tool_done_6:"Records checked successfully",translate_tool_done_7:"Review completed successfully",translate_tool_done_8:"Calculations completed successfully",translate_tool_done_9:"Information retrieved successfully",translate_tool_error:"Something went wrong",translate_attachment_status:"Reading the attached file...",translate_attachment_done:"Finished reading the file",translate_graph_0:"Exploring connections...",translate_graph_1:"Mapping out the links...",translate_graph_2:"Discovering relationships...",translate_graph_3:"Tracing the connections...",translate_graph_4:"Navigating the knowledge...",translate_graph_5:"Uncovering insights...",translate_graph_6:"Connecting the dots...",translate_graph_7:"Following the trail...",translate_graph_8:"Piecing things together...",translate_graph_9:"Building the picture...",translate_code_0:"Running the numbers...",translate_code_1:"Working through the data...",translate_code_2:"Processing your request...",translate_code_3:"Crunching the figures...",translate_code_4:"Putting it all together...",translate_code_5:"Analyzing the results...",translate_code_6:"Working behind the scenes...",translate_code_7:"Sorting through the details...",translate_code_8:"Preparing your answer...",translate_code_9:"Almost ready...",translate_reasoning_0:"Thinking it through...",translate_reasoning_1:"Considering the options...",translate_reasoning_2:"Weighing the possibilities...",translate_reasoning_3:"Reflecting on this...",translate_reasoning_4:"Working it out...",translate_reasoning_5:"Putting thoughts together...",translate_reasoning_6:"Mulling it over...",translate_reasoning_7:"Finding the best approach...",translate_reasoning_8:"Organizing my thoughts...",translate_reasoning_9:"Almost there...",translate_running:"Running",translate_aborted:"Aborted",translate_input:"Input",translate_output:"Output",translate_calling:"Calling",translate_input_ready:"Input ready",translate_needs_approval:"Needs approval",translate_approved:"Approved",translate_responded:"Responded",translate_error:"Error",translate_approval_requested:"Approval requested",translate_approval_response:"Approval response",translate_waiting_for_approval:"Waiting for approval to execute this tool.",translate_tool_approved:"Approved.",translate_tool_response_received:"Response received.",translate_tokens:"tokens",translate_fresh:"Fresh",translate_cache_read:"Cache read",translate_cache_write:"Cache write",translate_n_percent_cached:"{{percent}}% cached",translate_text:"Text",translate_reasoning:"Reasoning",translate_read:"Read",translate_write:"Write",translate_total:"Total",translate_request:"Request",translate_response:"Response",translate_step_n:"Step {{number}}",translate_inspect_llm_requests:"Inspect LLM requests",translate_loading:"loading…",translate_no_llm_requests:"No LLM requests recorded for this message.",translate_unhandled_type:"Unhandled type:"};var n_={en:S1,ar:C1};function X1(_,N,k){let Z=(n_[_]??n_.en)?.[N]??n_.en?.[N]??N;if(!k)return Z;return Z.replace(/\{\{\s*(\w+)\s*\}\}/g,(J,X)=>(X in k)?String(k[X]):J)}function X_(_){if(typeof _==="string"){let N=_.trim();if(!(N.startsWith("{")&&N.endsWith("}")||N.startsWith("[")&&N.endsWith("]")))return _;try{return X_(JSON.parse(N))}catch{return _}}if(Array.isArray(_))return _.map((N)=>X_(N));if(_!==null&&typeof _==="object"){let N={};for(let[k,L]of Object.entries(_))N[k]=X_(L);return N}return _}function G1(_,N){if(Array.isArray(_)){let k=_;return{kind:"container",open:"[",close:"]",summary:I1(k.length,"item","items"),entries:k.map((L,Z)=>({key:null,value:L,path:`${N}[${Z}]`}))}}if(_!==null&&typeof _==="object"){let k=Object.entries(_);return{kind:"container",open:"{",close:"}",summary:I1(k.length,"property","properties"),entries:k.map(([L,Z])=>({key:L,value:Z,path:`${N}.${L}`}))}}return{kind:"primitive",text:k2(_),className:L2(_)}}function I1(_,N,k){return`${_} ${_===1?N:k}`}function k2(_){if(_===null||_===void 0)return"null";if(typeof _==="string")return JSON.stringify(_);if(typeof _==="number"||typeof _==="boolean")return String(_);return JSON.stringify(_)??"null"}function L2(_){if(_===null||_===void 0)return"jt-null";if(typeof _==="string")return"jt-string";if(typeof _==="number")return"jt-number";if(typeof _==="boolean")return"jt-boolean";return""}function c_(_){if(!_)return null;try{return JSON.parse(_)}catch{return _}}function C_(_){if(!_)return"";try{return JSON.stringify(JSON.parse(_),null,2)}catch{return _}}var W1=[["year",31536000000],["month",2592000000],["week",604800000],["day",86400000],["hour",3600000],["minute",60000],["second",1000]];function V1(_,N,k=Date.now()){let L=Date.parse(_);if(Number.isNaN(L))return"";let Z=L-k,[J,X]=W1.find(([,G])=>Math.abs(Z)>=G)??W1[W1.length-1];return new Intl.RelativeTimeFormat(N,{numeric:"auto"}).format(Math.round(Z/X),J)}function Y1(_,N){let k=URL.createObjectURL(_),L=document.createElement("a");L.href=k,L.download=N,L.click(),URL.revokeObjectURL(k)}class Z_{onUpdate;fullText="";displayedLength=0;animationFrameId=null;isDone=!1;static DRAIN_FRACTION=0.03;static MIN_CHARS_PER_FRAME=1;static DONE_DRAIN_FRACTION=0.1;constructor(_){this.onUpdate=_}seed(_){this.fullText=_,this.displayedLength=_.length,this.onUpdate(_)}update(_,N){if(this.fullText=_,this.isDone=N,this.displayedLength=Math.min(this.displayedLength,this.fullText.length),N&&this.displayedLength>=this.fullText.length){this.onUpdate(this.fullText),this.stopAnimation();return}if(!this.animationFrameId)this.scheduleFrame()}destroy(){this.stopAnimation()}scheduleFrame(){this.animationFrameId=requestAnimationFrame(()=>this.tick())}tick(){let _=this.fullText.length-this.displayedLength;if(_<=0){this.animationFrameId=null;return}let N=this.isDone?Z_.DONE_DRAIN_FRACTION:Z_.DRAIN_FRACTION,k=Math.max(Z_.MIN_CHARS_PER_FRAME,Math.ceil(_*N));if(this.displayedLength=Math.min(this.fullText.length,this.displayedLength+k),this.onUpdate(this.fullText.substring(0,this.displayedLength)),this.displayedLength<this.fullText.length)this.scheduleFrame();else this.animationFrameId=null}stopAnimation(){if(this.animationFrameId)cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null}}function y_(_){if(_.input.total<=0)return null;return Math.round(_.input.cacheRead/_.input.total*100)}import{useEffect as S_,useLayoutEffect as g1,useMemo as Z2,useRef as i}from"react";import{useChat as J2}from"@tanstack/ai-react";function f1(_){let{thread:N,api:k,patchUi:L}=_,Z=i(!0),J=i(!1),X=i(!1),G=i(!1),$=i(!1),K=i(new Set),z=i(Promise.resolve()),M=Z2(()=>s_({api:k,thread:{id:N.id,isRunning:N.isRunning},mode:_.mode,onHydrated:(H,R)=>{if(!Z.current)return;L({messageMetadata:U_(H),hasPendingToolCalls:O_(R).length>0})},setLoadingMessages:(H)=>{if(Z.current)L({isLoadingMessages:H})}}),[]),B=J2({threadId:N.id,persistence:!0,connection:M,onChunk:()=>{if(!Z.current)return;X.current=!0},onError:()=>{if(!Z.current)return;if(L({hasPendingToolCalls:!1}),X.current)_.onTurnFinished();else _.onSendFailed()}}),U=i(B);U.current=B;let v=i(B.isLoading);v.current=B.isLoading;function q(){let H=O_(U.current.messages);return L({hasPendingToolCalls:H.length>0}),H}async function C(H,R){let I=R({toolCallId:H.id,toolName:H.name,input:H.input},{threadId:N.id});if(I===null||I===void 0)return;let g=await Promise.resolve(I);if(g===null||g===void 0)return;if(!Z.current)return;await U.current.addToolResult({toolCallId:H.id,tool:H.name,output:g}),q()}function F(){let H=q(),R=_.configRef.current.hooks?.onToolCall;if(!R)return H.length>0;for(let I of H){if(I.state!=="input-complete")continue;if(K.current.has(I.id))continue;K.current.add(I.id),C(I,R)}return H.length>0}async function W(H){if(!Z.current||H!==N.id)return;await e_({api:k,threadId:H,isStale:()=>!Z.current,isStreaming:()=>v.current,absorbMetadata:(R)=>L({messageMetadata:R}),setMessages:(R)=>{U.current.setMessages(R),L({hasPendingToolCalls:O_(R).length>0})}})}function V(H){return z.current=z.current.then(()=>W(H)),z.current}async function S(){if(G.current){G.current=!1;return}if(J.current&&F())return;await V(N.id)}async function c(H,R){_.setRunning(N.id,!0),J.current=!0,X.current=!1;let I={id:crypto.randomUUID(),role:"user",parts:[{type:"text",content:H}]};if(R.length)L((g)=>({messageMetadata:new Map(g.messageMetadata).set(I.id,{attachments:R})}));await U.current.append(I)}async function O(){if(!v.current)return;let{aborted:H}=await k.abortStream(N.id).catch(()=>({aborted:!1}));if(!Z.current)return;if(H)G.current=!0,_.setRunning(N.id,!1);U.current.stop(),L({hasPendingToolCalls:!1})}function u(H,R,I){U.current.addToolResult({toolCallId:H,tool:R,output:I}).then(()=>q())}function H_(H){if(v.current)return;if(H.isRunning){_.remount(H);return}V(H.id)}S_(()=>{return Z.current=!0,()=>{Z.current=!1}},[]);let x=i(void 0);return x.current={threadId:N.id,send:c,abort:O,addToolResult:u,reattach:H_,refreshMessages:(H)=>{V(H)}},g1(()=>{_.sessionRef.current=x.current}),g1(()=>{return()=>{if(_.sessionRef.current===x.current)_.sessionRef.current=void 0}},[]),S_(()=>{if(!_.pendingSendRef.current.length)return;let H=setTimeout(()=>{let R=_.pendingSendRef.current;_.pendingSendRef.current=[],(async()=>{for(let{prompt:I,attachments:g}of R)await c(I,g)})()});return()=>clearTimeout(H)},[]),S_(()=>{L({messages:B.messages})},[B.messages]),S_(()=>{if(L({isAgentWorking:B.isLoading}),B.isLoading){$.current=!0;return}if(!$.current)return;$.current=!1,_.onTurnFinished(),S()},[B.isLoading]),null}import{createContext as $2,useContext as X2}from"react";var K1=$2(void 0);function D(){let _=X2(K1);if(!_)throw Error("useCortex must be used inside <CortexChatWidget>");return _}function Q(..._){return _.filter(Boolean).join(" ")}import{forwardRef as G2,useEffect as W2,useImperativeHandle as V2,useRef as z1,useState as m1}from"react";import{jsx as d,jsxs as Q1}from"react/jsx-runtime";function p1(){let{queue:_,t:N}=D();if(!_.items.length)return null;return d("div",{className:"cortex-attachment-queue",children:_.items.map((k)=>Q1("div",{className:Q("cortex-attachment-chip",k.status==="error"&&"cortex-attachment-chip--error"),title:k.status==="error"?N("translate_attachment_rejected"):"",children:[k.status==="uploading"||k.status==="deleting"?Q1("svg",{className:"cortex-attachment-chip__spinner",viewBox:"0 0 16 16",fill:"none",children:[d("circle",{cx:"8",cy:"8",r:"6",stroke:"currentColor",strokeWidth:"2",className:"cortex-attachment-chip__spinner-track"}),d("path",{d:"M14 8a6 6 0 0 0-6-6",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]}):Q1("svg",{viewBox:"0 0 16 16",className:"cortex-attachment-chip__icon",fill:"none",children:[d("path",{d:"M4 1.5h5.172a2 2 0 0 1 1.414.586l2.328 2.328a2 2 0 0 1 .586 1.414V12.5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2Z",stroke:"currentColor",strokeWidth:"1.25"}),d("path",{d:"M9.5 1.5v2a2 2 0 0 0 2 2h2",stroke:"currentColor",strokeWidth:"1.25",strokeLinecap:"round"})]}),d("span",{className:"cortex-attachment-chip__name",children:k.filename}),d("button",{type:"button",onClick:()=>_.remove(k.localId),className:"cortex-attachment-chip__remove",disabled:k.status==="deleting","aria-label":N("translate_remove_attachment"),children:d("svg",{viewBox:"0 0 16 16",fill:"none",children:d("path",{d:"M4.5 4.5l7 7m0-7l-7 7",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})})})]},k.localId))})}import{jsx as r,jsxs as I_}from"react/jsx-runtime";var Y2=_1.join(","),T1=G2(function(N,k){let{t:L,queue:Z,isAgentWorking:J,send:X,abort:G}=D(),[$,K]=m1(""),[z,M]=m1(!1),B=z1(null),U=z1(null);V2(k,()=>({focusInput:()=>B.current?.focus()}));let v=z1(J);W2(()=>{if(v.current&&!J)B.current?.focus();v.current=J},[J]);let q=!Z.busy&&(Boolean($.trim())||Z.hasReady);function C(){if(J||!q)return;let O="translate_attachment_caption",u=L(O),H_=u!==O?u:"Please take a look at the attached files.",x=$.trim()||H_,H=Z.consumeReady();K(""),X(x,H.map((R)=>R.summary))}function F(O){if(O.key==="Enter"&&!O.shiftKey)O.preventDefault(),C()}function W(O){O.preventDefault(),M(!0)}function V(O){if(!O.currentTarget.contains(O.relatedTarget))M(!1)}function S(O){O.preventDefault(),M(!1),Z.accept([...O.dataTransfer.files])}function c(O){let u=O.clipboardData.files;if(!u.length)return;O.preventDefault(),Z.accept([...u])}return I_("div",{className:"cortex-widget__input-area",onDragOver:W,onDragLeave:V,onDrop:S,children:[r(p1,{}),I_("div",{className:Q("cortex-widget__input-box",J&&"cortex-widget__input-box--disabled",!J&&"cortex-widget__input-box--enabled",z&&"cortex-widget__input-box--dragging"),children:[r("textarea",{ref:B,onKeyDown:F,onPaste:c,value:$,onChange:(O)=>K(O.target.value),placeholder:z?L("translate_drop_files_here"):J?"":L("translate_type_a_message"),disabled:J,rows:1,className:Q("cortex-widget__textarea",J&&"cortex-widget__textarea--disabled")}),J?I_("button",{onClick:()=>void G(),className:"cortex-stop-btn",children:[r("span",{className:"cortex-stop-btn__ring"}),r("svg",{width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",className:"cortex-stop-btn__icon",children:r("rect",{x:"1",y:"1",width:"10",height:"10",rx:"2.5",fill:"currentColor"})})]}):I_("div",{className:"cortex-widget__input-actions",children:[r("button",{type:"button",onClick:()=>U.current?.click(),className:"cortex-widget__attach-btn","aria-label":L("translate_attach_files"),children:r("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:r("path",{d:"M10.5 5.5 6.2 9.8a1.4 1.4 0 0 0 2 2l4.6-4.6a2.8 2.8 0 0 0-4-4L4.2 7.8a4.2 4.2 0 0 0 6 6l4-4",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round",strokeLinejoin:"round"})})}),r("input",{ref:U,type:"file",multiple:!0,accept:Y2,onChange:(O)=>{Z.accept([...O.target.files??[]]),O.target.value=""},className:"cortex-widget__file-input"}),r("button",{onClick:C,className:Q("cortex-widget__send-btn",!q&&"cortex-widget__send-btn--empty",q&&"cortex-widget__send-btn--ready"),disabled:!q,children:r("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",className:"cortex-widget__send-icon",children:r("path",{d:"M3 8h10M9 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})]})]})]})});import{useEffect as m_,useRef as T_,useState as v2}from"react";import{jsx as g_,jsxs as l1}from"react/jsx-runtime";function o1(){let{t:_}=D();return l1("div",{className:"cortex-aborted-flag",children:[g_("span",{className:"cortex-aborted-flag__line"}),l1("span",{className:"cortex-aborted-flag__label",children:[g_("svg",{className:"cortex-aborted-flag__icon",width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:g_("path",{d:"M6 1.5v5M6 8.75v.5",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round"})}),_("translate_aborted")]}),g_("span",{className:"cortex-aborted-flag__line"})]})}import{jsx as G_,jsxs as u1}from"react/jsx-runtime";function r1(_){let{api:N,t:k}=D();async function L(Z){let{blob:J,name:X}=await N.downloadAttachment(Z);Y1(J,X)}return G_("div",{className:"cortex-message-attachments",children:_.attachments.map((Z)=>u1("button",{type:"button",onClick:()=>void L(Z.id),className:"cortex-message-attachment","aria-label":`${k("translate_download")}: ${Z.filename}`,children:[u1("svg",{viewBox:"0 0 16 16",className:"cortex-message-attachment__icon",fill:"none",children:[G_("path",{d:"M4 1.5h5.172a2 2 0 0 1 1.414.586l2.328 2.328a2 2 0 0 1 .586 1.414V12.5a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-9a2 2 0 0 1 2-2Z",stroke:"currentColor",strokeWidth:"1.25"}),G_("path",{d:"M9.5 1.5v2a2 2 0 0 0 2 2h2",stroke:"currentColor",strokeWidth:"1.25",strokeLinecap:"round"})]}),G_("span",{className:"cortex-message-attachment__name",children:Z.filename}),G_("svg",{viewBox:"0 0 16 16",className:"cortex-message-attachment__dl-icon",fill:"none",children:G_("path",{d:"M8 3v7m0 0L5.5 7.5M8 10l2.5-2.5M3 13h10",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]},Z.id))})}import{useRef as q2,useState as E_}from"react";import{useRef as K2,useState as Q2}from"react";import{jsx as W_,jsxs as z2}from"react/jsx-runtime";function e({value:_,className:N}){let[k,L]=Q2(!1),Z=K2(null);async function J(X){X.stopPropagation(),X.preventDefault();try{if(await navigator.clipboard.writeText(_),L(!0),Z.current)clearTimeout(Z.current);Z.current=setTimeout(()=>L(!1),1500)}catch{}}return W_("span",{className:Q("cortex-copy-btn",N),children:W_("button",{className:Q("cortex-copy-btn__button",k&&"cortex-copy-btn__button--copied"),onClick:(X)=>void J(X),"aria-label":k?"Copied":"Copy to clipboard",type:"button",children:k?W_("svg",{className:"cortex-copy-btn__icon cortex-copy-btn__icon--check",width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",children:W_("path",{d:"M5 13l4 4L19 7",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round"})}):z2("svg",{className:"cortex-copy-btn__icon",width:"13",height:"13",viewBox:"0 0 24 24",fill:"none",children:[W_("rect",{x:"9",y:"9",width:"12",height:"12",rx:"2",stroke:"currentColor",strokeWidth:"2"}),W_("path",{d:"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})]})})})}import{useMemo as F2,useState as H2}from"react";import{jsx as o,jsxs as J_,Fragment as f_}from"react/jsx-runtime";function $_({data:_,expandDepth:N=1,className:k}){let L=F2(()=>X_(_),[_]),[Z,J]=H2({});function X($,K){return Z[$]??K>=N}function G($,K){J((z)=>({...z,[$]:!X($,K)}))}return o("div",{className:Q("cortex-json-tree",k),children:o(h1,{value:L,path:"$",depth:0,isCollapsed:X,toggle:G})})}function h1({value:_,path:N,depth:k,isCollapsed:L,toggle:Z}){let J=G1(_,N);if(J.kind==="primitive")return o("span",{className:J.className,children:J.text});if(J.entries.length===0)return J_("span",{className:"jt-bracket",children:[J.open,J.close]});let X=L(N,k);function G($){Z(N,k),$.stopPropagation()}return J_(f_,{children:[J_("span",{className:"jt-toggle",onClick:G,role:"button",children:[o("span",{className:Q("jt-arrow",X&&"jt-arrow--collapsed"),children:"▾"}),o("span",{className:"jt-bracket",children:J.open})]}),X?J_(f_,{children:[o("span",{className:"jt-collapsed-hint",onClick:G,role:"button",children:J.summary}),o("span",{className:"jt-bracket",children:J.close})]}):J_(f_,{children:[o("div",{className:"jt-indent",children:J.entries.map(($,K)=>J_("div",{className:"jt-line",children:[$.key!==null&&J_(f_,{children:[o("span",{className:"jt-key",children:`"${$.key}"`}),o("span",{className:"jt-colon",children:": "})]}),o(h1,{value:$.value,path:$.path,depth:k+1,isCollapsed:L,toggle:Z}),K<J.entries.length-1&&o("span",{className:"jt-comma",children:","})]},$.path))}),o("span",{className:"jt-bracket",children:J.close})]})]})}function b(_){return _.toLocaleString("en-US")}import{jsx as V_,jsxs as Y_}from"react/jsx-runtime";function j1({usage:_}){let{t:N}=D();return Y_("div",{className:"cortex-llm-inspector__usage-rows",children:[Y_("div",{className:"cortex-llm-inspector__usage-row",children:[V_("span",{className:"cortex-llm-inspector__usage-lbl",children:N("translate_input")}),V_("span",{className:"cortex-llm-inspector__usage-val",children:b(_.input.total)}),Y_("span",{className:"cortex-llm-inspector__usage-detail",children:[N("translate_fresh")," ",b(_.input.noCache)," · ",N("translate_read")," ",b(_.input.cacheRead)," · ",N("translate_write")," ",b(_.input.cacheWrite)]})]}),Y_("div",{className:"cortex-llm-inspector__usage-row",children:[V_("span",{className:"cortex-llm-inspector__usage-lbl",children:N("translate_output")}),V_("span",{className:"cortex-llm-inspector__usage-val",children:b(_.output.total)}),Y_("span",{className:"cortex-llm-inspector__usage-detail",children:[N("translate_text")," ",b(_.output.text)," · ",N("translate_reasoning")," ",b(_.output.reasoning)]})]}),Y_("div",{className:"cortex-llm-inspector__usage-row cortex-llm-inspector__usage-row--total",children:[V_("span",{className:"cortex-llm-inspector__usage-lbl",children:N("translate_total")}),V_("span",{className:"cortex-llm-inspector__usage-val",children:b(_.total)})]})]})}import{jsx as F1,jsxs as p_}from"react/jsx-runtime";function i1({usage:_}){let N=y_(_);return F1("span",{children:p_("span",{className:"cortex-llm-inspector__step-metrics",children:[p_("span",{className:"cortex-llm-inspector__metric",children:[F1("span",{className:"cortex-llm-inspector__dot cortex-llm-inspector__dot--input"}),b(_.input.total)]}),p_("span",{className:"cortex-llm-inspector__metric",children:[F1("span",{className:"cortex-llm-inspector__dot cortex-llm-inspector__dot--output"}),b(_.output.total)]}),N!==null?p_("span",{className:"cortex-llm-inspector__cache-pct",children:[N,"%"]}):null]})})}import{jsx as n,jsxs as __}from"react/jsx-runtime";function a1({messageId:_}){let{t:N,api:k}=D(),[L,Z]=E_(!1),[J,X]=E_(!1),[G,$]=E_([]),[K,z]=E_(null),[M,B]=E_({}),U=q2(!1);async function v(){if(!U.current){X(!0);try{$(await k.listLlmRequests(_))}finally{X(!1),U.current=!0}}Z((W)=>!W)}function q(W){z((V)=>V===W?null:W)}function C(W){return M[W]??"prompt"}function F(W,V){B((S)=>({...S,[W]:V}))}return __("div",{className:Q("cortex-llm-inspector",L&&"cortex-llm-inspector--open"),children:[__("button",{className:"cortex-llm-inspector__trigger",onClick:()=>void v(),children:[n("svg",{className:"cortex-llm-inspector__icon",width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",children:n("path",{d:"M6 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8ZM0 6a6 6 0 1 1 10.89 3.477l4.817 4.816a1 1 0 0 1-1.414 1.414l-4.816-4.816A6 6 0 0 1 0 6Z",fill:"currentColor"})}),n("span",{children:N("translate_inspect_llm_requests")}),J?n("span",{className:"cortex-llm-inspector__loading",children:N("translate_loading")}):G.length>0?n("span",{className:"cortex-llm-inspector__badge",children:G.length}):null,n("svg",{className:"cortex-llm-inspector__chevron",width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:n("path",{d:"M3 4.5L6 7.5L9 4.5",stroke:"currentColor",strokeWidth:"1.25",strokeLinecap:"round",strokeLinejoin:"round"})})]}),n("div",{className:"cortex-llm-inspector__panel-wrapper",children:n("div",{className:"cortex-llm-inspector__panel-inner",children:__("div",{className:"cortex-llm-inspector__panel",children:[G.length===0&&!J?n("div",{className:"cortex-llm-inspector__empty",children:N("translate_no_llm_requests")}):null,G.map((W,V)=>__("div",{className:Q("cortex-llm-inspector__step",K===W.id&&"cortex-llm-inspector__step--expanded"),children:[__("button",{className:"cortex-llm-inspector__step-header",onClick:()=>q(W.id),children:[n("span",{className:"cortex-llm-inspector__step-label",children:N("translate_step_n",{number:V+1})}),W.tokenUsage?n(i1,{usage:W.tokenUsage}):null,n("svg",{className:"cortex-llm-inspector__step-chevron",width:"10",height:"10",viewBox:"0 0 12 12",fill:"none",children:n("path",{d:"M3 4.5L6 7.5L9 4.5",stroke:"currentColor",strokeWidth:"1.25",strokeLinecap:"round",strokeLinejoin:"round"})})]}),n("div",{className:"cortex-llm-inspector__step-body-wrapper",children:n("div",{className:"cortex-llm-inspector__step-body-inner",children:__("div",{className:"cortex-llm-inspector__step-body",children:[W.tokenUsage?n(j1,{usage:W.tokenUsage}):null,__("div",{className:"cortex-llm-inspector__tabs",children:[n("button",{className:Q("cortex-llm-inspector__tab",C(W.id)==="prompt"&&"cortex-llm-inspector__tab--active"),onClick:()=>F(W.id,"prompt"),children:N("translate_request")}),n("button",{className:Q("cortex-llm-inspector__tab",C(W.id)==="response"&&"cortex-llm-inspector__tab--active"),onClick:()=>F(W.id,"response"),children:N("translate_response")})]}),__("div",{className:"cortex-llm-inspector__json-pane",children:[n(e,{className:"cortex-llm-inspector__json-copy",value:C(W.id)==="prompt"?C_(W.prompt):C_(W.output)}),C(W.id)==="prompt"?n($_,{data:c_(W.prompt),expandDepth:2}):n($_,{data:c_(W.output),expandDepth:2})]})]})})})]},W.id))]})})})]})}import{useEffect as O2,useRef as D2,useState as x1}from"react";import{jsx as M_,jsxs as d1}from"react/jsx-runtime";function K_({labels:_,className:N}){let{t:k}=D(),[L,Z]=x1(0),[J,X]=x1("idle"),G=D2(_.length);return G.current=_.length,O2(()=>{let $,K;function z(){$=setTimeout(()=>{X("exiting"),$=setTimeout(()=>{Z((M)=>(M+1)%G.current),X("enter-start"),K=requestAnimationFrame(()=>{X("entering"),$=setTimeout(()=>{X("idle"),z()},300)})},300)},2000)}return z(),()=>{if($)clearTimeout($);if(K)cancelAnimationFrame(K)}},[]),d1("div",{className:Q("cortex-subtle-activity",N),children:[d1("div",{className:"cortex-subtle-activity__dots",children:[M_("span",{className:"cortex-subtle-activity__dot"}),M_("span",{className:"cortex-subtle-activity__dot cortex-subtle-activity__dot--d1"}),M_("span",{className:"cortex-subtle-activity__dot cortex-subtle-activity__dot--d2"})]}),M_("div",{className:"cortex-subtle-activity__label-mask",children:M_("span",{className:Q("cortex-subtle-activity__label",`cortex-subtle-activity__label--${J}`),children:k(_[L])})})]})}import{jsx as t1}from"react/jsx-runtime";var B2=L_("reasoning");function s1(){return t1("div",{className:"cortex-reasoning-animated",children:t1(K_,{labels:B2})})}import{jsx as h,jsxs as w_}from"react/jsx-runtime";function e1(_){let{reasoningPart:N,streaming:k=!1}=_,{t:L}=D();return w_("details",{className:"cortex-reasoning-details",children:[w_("summary",{className:"cortex-reasoning-details__summary",children:[w_("div",{className:"cortex-reasoning-details__header",children:[h("span",{className:"cortex-reasoning-details__icon",children:w_("svg",{width:"14",height:"14",viewBox:"0 0 20 20",fill:"none","aria-hidden":"true",children:[h("path",{d:"M10 2C6.686 2 4 4.686 4 8c0 1.655.672 3.154 1.757 4.243.362.363.576.858.576 1.371V14.5a1 1 0 0 0 1 1h5.334a1 1 0 0 0 1-1v-.886c0-.513.214-1.008.576-1.371A5.978 5.978 0 0 0 16 8c0-3.314-2.686-6-6-6Z",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",strokeLinejoin:"round"}),h("path",{d:"M7.5 17.5h5M8.5 8a2 2 0 0 1 2-2",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round",strokeLinejoin:"round"})]})}),h("div",{className:"cortex-reasoning-details__title-group",children:w_("div",{className:"cortex-reasoning-details__title-row",children:[h("div",{className:"cortex-reasoning-details__title",children:L("translate_reasoning")}),h("span",{className:Q("cortex-reasoning-details__badge",k?"cortex-reasoning-details__badge--streaming":"cortex-reasoning-details__badge--done"),children:k?"Streaming":"Done"})]})})]}),h("span",{className:"cortex-reasoning-details__chevron","aria-hidden":"true",children:h("svg",{width:"14",height:"14",viewBox:"0 0 20 20",fill:"none",children:h("path",{d:"m5.75 8.25 4.25 4.25 4.25-4.25",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})})]}),h("div",{className:"cortex-reasoning-details__body",children:h("div",{className:"cortex-reasoning-details__content",children:h("pre",{className:"cortex-reasoning-details__pre",children:N.content.trim()?N.content:"No reasoning provided."})})})]})}import{useEffect as _0,useRef as H1,useState as y2}from"react";import{jsx as N0}from"react/jsx-runtime";function k0(_){let{role:N,textPart:k,streaming:L=!1}=_,Z=N==="assistant"&&L?"":k.content,[J,X]=y2(Z),G=H1(Z),$=H1(null),K=H1(!0);return _0(()=>{function z(M){G.current=M,X(M)}if(N!=="assistant"||!L){$.current?.destroy(),$.current=null,z(k.content),K.current=!1;return}if(!$.current)$.current=new Z_(z),$.current.seed(G.current);if(K.current){K.current=!1,$.current.seed(k.content);return}$.current.update(k.content,!1)},[N,L,k]),_0(()=>()=>{$.current?.destroy(),$.current=null},[]),N0("div",{className:Q("cortex-text-part",N==="assistant"&&"cortex-text-part--assistant",N==="user"&&"cortex-text-part--user"),children:N0("div",{className:Q("cortex-text-bubble",N==="assistant"&&"cortex-text-bubble--assistant",N==="user"&&"cortex-text-bubble--user"),dangerouslySetInnerHTML:{__html:J1(J)}})})}import{jsx as m,jsxs as N_}from"react/jsx-runtime";function L0({toolCallPart:_}){let{t:N}=D(),{state:k,approval:L}=_,Z=_.output,J=i_(_);function X(){if(k==="complete")return N_("div",{className:"dbg-tool__section dbg-tool__section--success",children:[N_("div",{className:"dbg-tool__section-bar",children:[m("span",{className:"dbg-tool__section-label dbg-tool__section-label--success",children:N("translate_output")}),m("span",{className:"dbg-tool__section-lang",children:"json"}),m(e,{value:J})]}),m("div",{dir:"ltr",className:"dbg-tool__tree",children:m($_,{data:Z,expandDepth:2})})]});if(k==="error")return N_("div",{className:"dbg-tool__section dbg-tool__section--error",children:[N_("div",{className:"dbg-tool__section-bar",children:[m("span",{className:"dbg-tool__section-label dbg-tool__section-label--error",children:N("translate_error")}),m(e,{value:J})]}),m("pre",{dir:"ltr",className:"dbg-tool__error-pre",children:J})]});if(k==="approval-requested")return N_("div",{className:"dbg-tool__section dbg-tool__section--approval",children:[N_("div",{className:"dbg-tool__section-bar",children:[m("span",{className:"dbg-tool__section-label dbg-tool__section-label--approval",children:N("translate_approval_requested")}),m("span",{className:"dbg-tool__section-lang",children:L?.id})]}),m("div",{className:"dbg-tool__message dbg-tool__message--approval",children:N("translate_waiting_for_approval")})]});if(k==="approval-responded")return N_("div",{className:"dbg-tool__section dbg-tool__section--approval",children:[N_("div",{className:"dbg-tool__section-bar",children:[m("span",{className:"dbg-tool__section-label dbg-tool__section-label--approval",children:N("translate_approval_response")}),m("span",{className:"dbg-tool__section-lang",children:L?.id})]}),m("div",{className:"dbg-tool__message dbg-tool__message--approval",children:N(L?.approved?"translate_tool_approved":"translate_tool_response_received")})]});return null}return m("div",{children:X()})}import{jsx as Z0,jsxs as E2}from"react/jsx-runtime";function J0({toolCallPart:_}){let{t:N}=D(),k=j_(_);return Z0("span",{children:E2("span",{className:Q("dbg-tool__state",k.modifier&&`dbg-tool__state--${k.modifier}`),children:[k.pulse&&Z0("span",{className:Q("dbg-tool__pulse",k.pulse==="violet"&&"dbg-tool__pulse--violet")}),N(k.labelKey)]})})}import{jsx as p,jsxs as t}from"react/jsx-runtime";function $0({toolCallPart:_}){let{t:N}=D(),{codeSnippets:k,remainingInput:L,remainingInputText:Z}=a_(_.input);return t("details",{className:"dbg-tool","data-state":_.state,children:[p("summary",{className:"dbg-tool__summary",children:t("div",{className:"dbg-tool__header",children:[t("div",{className:"dbg-tool__meta",children:[p("div",{className:"dbg-tool__title-row",children:p("span",{className:"dbg-tool__name",title:_.name,children:_.name})}),p("div",{className:"dbg-tool__id-row",children:p("span",{className:"dbg-tool__id",children:_.id})})]}),t("div",{className:"dbg-tool__actions",children:[p(J0,{toolCallPart:_}),p("svg",{className:"dbg-tool__chevron",width:"14",height:"14",viewBox:"0 0 20 20",fill:"none",children:p("path",{d:"m5.75 8.25 4.25 4.25 4.25-4.25",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]})]})}),t("div",{className:"dbg-tool__body",children:[k.map((J)=>t("div",{className:"dbg-tool__section",children:[t("div",{className:"dbg-tool__section-bar",children:[p("span",{className:"dbg-tool__section-label",children:J.key}),p("span",{className:"dbg-tool__section-lang",children:J.lang}),p(e,{value:J.value})]}),p("pre",{dir:"ltr",className:"dbg-tool__pre",children:p("code",{className:"hljs",dangerouslySetInnerHTML:{__html:$1(J.value,J.lang)}})})]},J.key)),!!L&&t("div",{className:"dbg-tool__section",children:[t("div",{className:"dbg-tool__section-bar",children:[p("span",{className:"dbg-tool__section-label",children:N("translate_input")}),p("span",{className:"dbg-tool__section-lang",children:"json"}),p(e,{value:Z})]}),p("div",{dir:"ltr",className:"dbg-tool__tree",children:p($_,{data:L,expandDepth:2})})]}),p(L0,{toolCallPart:_})]})]})}import{jsx as s,jsxs as X0}from"react/jsx-runtime";function G0({message:_,toolCallPart:N}){let{config:k,t:L,addToolResult:Z}=D(),J=k.toolComponents?.[N.name];if(J)return s("div",{className:"cortex-tool-call-animated",children:s(J,{toolCallPart:N,message:_,setOutput:(K)=>Z(N.id,N.name,K)})});let{state:X,active:G,titleKey:$}=x_(N);return s("div",{className:"cortex-tool-call-animated",children:X0("div",{className:"cortex-tool-pill",children:[X0("span",{className:"cortex-tool-pill__icon",children:[s("span",{className:Q("cortex-tool-pill__spinner",G&&"cortex-tool-pill__spinner--visible")}),s("svg",{className:Q("cortex-tool-pill__svg","cortex-tool-pill__svg--check",X==="complete"&&"cortex-tool-pill__svg--visible"),viewBox:"0 0 20 20",fill:"none",children:s("path",{d:"M5.5 10.5 L8.5 13.5 L14.5 7",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})}),s("svg",{className:Q("cortex-tool-pill__svg","cortex-tool-pill__svg--error",X==="error"&&"cortex-tool-pill__svg--visible"),viewBox:"0 0 20 20",fill:"none",children:s("path",{d:"M6.5 6.5 L13.5 13.5 M13.5 6.5 L6.5 13.5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round"})})]}),s("span",{className:Q("cortex-tool-pill__title",X==="error"&&"cortex-tool-pill__title--error"),children:L($)})]})})}import{jsx as w2}from"react/jsx-runtime";var M2=L_("code");function W0(){return w2(K_,{labels:M2})}import{jsx as A2}from"react/jsx-runtime";var P2=L_("graph");function V0(){return A2(K_,{labels:P2})}import{jsx as q1}from"react/jsx-runtime";function Y0({message:_,toolCallPart:N}){if(N.name==="queryGraph")return q1(V0,{});if(N.name==="executeCode")return q1(W0,{});return q1(G0,{toolCallPart:N,message:_})}import{jsx as Q_,jsxs as b2}from"react/jsx-runtime";function K0(_){let{message:N,part:k,debugMode:L=!1,animate:Z=!1,streaming:J=!1}=_,{t:X}=D();function G(){switch(k.type){case"text":return Q_(k0,{textPart:k,role:N.role,streaming:J});case"thinking":return L?Q_(e1,{reasoningPart:k,streaming:J}):Q_(s1,{});case"tool-call":return L?Q_($0,{toolCallPart:k}):Q_(Y0,{toolCallPart:k,message:N});default:return b2("p",{className:"cortex-unhandled-type",children:[X("translate_unhandled_type")," ",k.type]})}}return Q_("div",{className:Q("cortex-message-part",Z&&"cortex-message-part--animated"),children:G()})}import{useState as U2}from"react";import{jsx as P,jsxs as f}from"react/jsx-runtime";function Q0({usage:_,modelId:N}){let{t:k}=D(),[L,Z]=U2(!1),J=y_(_)??0;return f("div",{className:Q("cortex-token-usage",L&&"cortex-token-usage--expanded"),children:[f("button",{className:"cortex-token-usage__summary",onClick:()=>Z((X)=>!X),children:[f("span",{className:"cortex-token-usage__total",children:[P("span",{className:"cortex-token-usage__total-number",children:b(_.total)}),P("span",{className:"cortex-token-usage__total-label",children:k("translate_tokens")})]}),N?P("span",{className:"cortex-token-usage__model",children:N}):null,f("span",{className:"cortex-token-usage__pills",children:[f("span",{className:"cortex-token-usage__pill",children:[P("span",{className:"cortex-token-usage__dot cortex-token-usage__dot--input"}),b(_.input.total)]}),f("span",{className:"cortex-token-usage__pill",children:[P("span",{className:"cortex-token-usage__dot cortex-token-usage__dot--output"}),b(_.output.total)]})]}),J>0?f("span",{className:"cortex-token-usage__cache-badge",children:[J,"%"]}):null,P("svg",{className:"cortex-token-usage__chevron",width:"12",height:"12",viewBox:"0 0 12 12",fill:"none",children:P("path",{d:"M3 4.5L6 7.5L9 4.5",stroke:"currentColor",strokeWidth:"1.25",strokeLinecap:"round",strokeLinejoin:"round"})})]}),P("div",{className:"cortex-token-usage__details",children:P("div",{className:"cortex-token-usage__details-inner",children:f("div",{className:"cortex-token-usage__columns",children:[f("div",{className:"cortex-token-usage__col",children:[f("div",{className:"cortex-token-usage__col-header",children:[P("span",{className:"cortex-token-usage__dot cortex-token-usage__dot--input"}),P("span",{className:"cortex-token-usage__col-label",children:k("translate_input")}),P("span",{className:"cortex-token-usage__col-total",children:b(_.input.total)})]}),f("div",{className:"cortex-token-usage__rows",children:[_.input.noCache?f("div",{className:"cortex-token-usage__row",children:[P("span",{className:"cortex-token-usage__row-label",children:k("translate_fresh")}),P("span",{className:"cortex-token-usage__row-value",children:b(_.input.noCache)})]}):null,_.input.cacheRead?f("div",{className:"cortex-token-usage__row",children:[P("span",{className:"cortex-token-usage__row-label",children:k("translate_cache_read")}),P("span",{className:"cortex-token-usage__row-value",children:b(_.input.cacheRead)})]}):null,_.input.cacheWrite?f("div",{className:"cortex-token-usage__row",children:[P("span",{className:"cortex-token-usage__row-label",children:k("translate_cache_write")}),P("span",{className:"cortex-token-usage__row-value",children:b(_.input.cacheWrite)})]}):null]}),J>0?f("div",{className:"cortex-token-usage__cache-bar-row",children:[P("div",{className:"cortex-token-usage__cache-bar",children:P("div",{className:"cortex-token-usage__cache-fill",style:{width:`${J}%`}})}),P("span",{className:"cortex-token-usage__cache-label",children:k("translate_n_percent_cached",{percent:J})})]}):null]}),f("div",{className:"cortex-token-usage__col",children:[f("div",{className:"cortex-token-usage__col-header",children:[P("span",{className:"cortex-token-usage__dot cortex-token-usage__dot--output"}),P("span",{className:"cortex-token-usage__col-label",children:k("translate_output")}),P("span",{className:"cortex-token-usage__col-total",children:b(_.output.total)})]}),f("div",{className:"cortex-token-usage__rows",children:[_.output.text?f("div",{className:"cortex-token-usage__row",children:[P("span",{className:"cortex-token-usage__row-label",children:k("translate_text")}),P("span",{className:"cortex-token-usage__row-value",children:b(_.output.text)})]}):null,_.output.reasoning?f("div",{className:"cortex-token-usage__row",children:[P("span",{className:"cortex-token-usage__row-label",children:k("translate_reasoning")}),P("span",{className:"cortex-token-usage__row-value",children:b(_.output.reasoning)})]}):null]})]})]})})})]})}import{jsx as z_,jsxs as z0}from"react/jsx-runtime";function F0(_){let{message:N,debugMode:k=!1,animate:L=!1}=_,{messages:Z,isAgentWorking:J,messageMetadata:X}=D(),G=J&&b_(Z)?.id===N.id,$=N.role==="assistant",K=N.parts,z=K.filter((F,W)=>{if(F.type==="tool-result")return!1;return k||!d_(F,W===K.length-1,G)}),M=G?z.length-1:-1,B=X.get(N.id),U=Boolean(B?.isAborted),v=B?.tokenUsage,q=N.role==="user"?B?.attachments??[]:[],C=k&&!G&&(Boolean(v)||$);return z_("div",{className:"cortex-message",children:z.length>0&&z0("div",{className:"cortex-message-parts",children:[z.map((F,W)=>z_(K0,{part:F,message:N,debugMode:k,animate:L,streaming:W===M},W)),q.length>0&&z_(r1,{attachments:q}),U&&z_(o1,{}),C&&z0("div",{className:"cortex-message-debug-zone",children:[v&&z_(Q0,{usage:v,modelId:B?.modelId}),$&&z_(a1,{messageId:N.id})]})]})})}import{jsx as O1}from"react/jsx-runtime";function H0(_){let{messages:N,selectedThread:k}=D(),L=T_(null),Z=T_(!0),J=T_(!0),X=T_(!1),[G,$]=v2(!1);function K(){let q=L.current;if(q)q.scrollTop=q.scrollHeight}function z(){if(X.current)return;X.current=!0,queueMicrotask(()=>{X.current=!1,K(),Z.current=!1})}m_(()=>{let q=L.current;if(z(),$(!0),!q||typeof MutationObserver>"u")return;let C=new MutationObserver(()=>{if(!Z.current&&!J.current)return;z()});return C.observe(q,{childList:!0,subtree:!0,characterData:!0}),()=>C.disconnect()},[]);let M=k?.id;m_(()=>{$(!1),Z.current=!0,queueMicrotask(()=>$(!0))},[M]);let B=N[N.length-1],U=B?.role==="user"?B.id:void 0;m_(()=>{if(U)Z.current=!0},[U]),m_(()=>{if(!Z.current&&!J.current)return;z()},[N]);function v(){let q=L.current;if(!q)return;J.current=q.scrollHeight-q.scrollTop-q.clientHeight<100}return O1("div",{className:_.className,children:O1("div",{ref:L,className:"cortex-message-list",onScroll:v,children:N.map((q)=>O1(F0,{message:q,debugMode:_.debugMode,animate:G},q.id))})})}import{jsx as A,jsxs as j,Fragment as R2}from"react/jsx-runtime";var q0="M13.5 7.6c0 2.4-2.5 4.4-5.5 4.4-.6 0-1.2-.08-1.7-.23L3 13l.8-2.3C3 9.8 2.5 8.7 2.5 7.6 2.5 5.2 5 3.2 8 3.2s5.5 2 5.5 4.4Z";function O0(_){let{config:N,t:k,threads:L,selectedThread:Z,deleteThread:J}=D(),X=N.locale??"en";return j("div",{className:_.className,children:[j("div",{className:"cortex-widget__threads-header",children:[j("div",{children:[A("h2",{className:"cortex-widget__threads-title",children:k("translate_threads")}),A("p",{className:"cortex-widget__threads-count",children:k(L?.length===1?"translate_one_conversation":"translate_n_conversations",{count:L?.length??0})})]}),j("button",{onClick:()=>_.onNewChatRequested(),className:"cortex-widget__new-chat-btn",children:[A("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:A("path",{d:"M8 3v10M3 8h10",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round"})}),k("translate_new")]})]}),A("div",{className:"cortex-widget__threads-list",children:L===void 0?[1,2,3,4].map((G)=>j("div",{className:"cortex-widget__thread-skeleton",children:[A("div",{className:"cortex-skeleton cortex-widget__thread-skeleton-icon"}),A("div",{className:"cortex-widget__thread-skeleton-lines",children:A("div",{className:"cortex-skeleton cortex-widget__thread-skeleton-line",style:{width:`${40+G*12}%`}})})]},G)):j(R2,{children:[L.map((G)=>{let $=G.id===Z?.id,K=V1(G.updatedAt,X);return j("button",{onClick:()=>_.onThreadSelected(G),className:Q("cortex-widget__thread-item",$&&"cortex-widget__thread-item--active"),children:[A("div",{className:Q("cortex-widget__thread-icon",$&&"cortex-widget__thread-icon--active"),children:A("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",children:A("path",{d:q0,stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round",strokeLinejoin:"round"})})}),j("div",{className:"cortex-widget__thread-info",children:[j("div",{className:"cortex-widget__thread-title-row",children:[A("p",{className:Q("cortex-widget__thread-title",$&&"cortex-widget__thread-title--active"),children:G.title??k("translate_untitled")}),G.isRunning&&j("span",{className:Q("cortex-widget__thread-running",$&&"cortex-widget__thread-running--active"),children:[A("span",{className:"cortex-widget__thread-running-dot"}),k("translate_running")]})]}),K&&A("p",{className:"cortex-widget__thread-time",children:K})]}),A("span",{role:"button",tabIndex:0,onClick:(z)=>{z.stopPropagation(),J(G.id)},onKeyDown:(z)=>{if(z.key!=="Enter"&&z.key!==" ")return;z.preventDefault(),z.stopPropagation(),J(G.id)},className:Q("cortex-widget__thread-delete",$&&"cortex-widget__thread-delete--active"),children:A("svg",{width:"12",height:"12",viewBox:"0 0 16 16",fill:"none",children:A("path",{d:"M4 4l8 8M12 4l-8 8",stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round"})})}),A("svg",{className:Q("cortex-widget__thread-arrow",$&&"cortex-widget__thread-arrow--active"),width:"10",height:"10",viewBox:"0 0 16 16",fill:"none",children:A("path",{d:"M6 4l4 4-4 4",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})]},G.id)}),!L.length&&j("div",{className:"cortex-widget__threads-empty",children:[A("div",{className:"cortex-widget__threads-empty-icon",children:A("svg",{width:"18",height:"18",viewBox:"0 0 16 16",fill:"none",className:"cortex-widget__threads-empty-svg",children:A("path",{d:q0,stroke:"currentColor",strokeWidth:"1.3",strokeLinecap:"round",strokeLinejoin:"round"})})}),A("p",{className:"cortex-widget__threads-empty-title",children:k("translate_no_threads_yet")}),A("p",{className:"cortex-widget__threads-empty-subtitle",children:k("translate_start_a_new_conversation")}),A("button",{onClick:()=>_.onNewChatRequested(),className:"cortex-widget__new-chat-btn cortex-widget__new-chat-btn--empty-state",children:k("translate_new_chat")})]})]})})]})}import{jsx as y,jsxs as a}from"react/jsx-runtime";var B1={messages:[],isAgentWorking:!1,isLoadingMessages:!1,hasPendingToolCalls:!1,messageMetadata:new Map};function c2({config:_,className:N}){let k=k_(_);k.current=_;let[L,Z]=F_(),[J,X]=F_(),[G,$]=F_(B1),[K,z]=F_(!1),[M,B]=F_("threads"),[U,v]=F_(!1),q=k_(void 0),C=k_([]),F=k_(void 0),W=k_(null),V=D1(()=>h_(()=>k.current.transport),[]),S=D1(()=>{let Y=J?.thread;if(!Y)return;return L?.find((E)=>E.id===Y.id)??Y},[L,J]),c=k_(S);c.current=S;let O=k_(G);O.current=G;let u=T((Y)=>{$((E)=>({...E,...typeof Y==="function"?Y(E):Y}))},[]),H_=T((Y,E)=>{Z((w)=>{let l=w?.find((r_)=>r_.id===Y);return l?D_(w??[],{...l,isRunning:E}):w})},[]),x=T((Y,E)=>{if(c.current?.id===Y.id&&q.current)return;let w=c.current;if(c.current=Y,$(B1),X({thread:Y,mode:E?.skipLoadingMessages?"skip":"load",epoch:0}),w&&w.id!==Y.id)k.current.hooks?.onThreadDeselected?.(w);k.current.hooks?.onThreadSelected?.(Y)},[]),H=T(()=>{let Y=c.current;if(!Y&&!q.current)return;if(c.current=void 0,X(void 0),$(B1),Y)k.current.hooks?.onThreadDeselected?.(Y)},[]),R=T((Y)=>{u({hasPendingToolCalls:!1,messageMetadata:new Map}),X((E)=>({thread:Y,mode:"reload",epoch:(E?.epoch??0)+1}))},[u]),I=T((Y)=>{let E=c.current;if(E)return Promise.resolve(E.id);return F.current??=V.createThread(Y).then((w)=>{return F.current=void 0,Z((l)=>D_(l??[],w)),x(w,{skipLoadingMessages:!0}),w.id},(w)=>{throw F.current=void 0,w}),F.current},[V,x]),g=D1(()=>N1({api:V,ensureThread:()=>I()}),[V,I]),y1=n2(g.subscribe,g.getState,g.getState),B0=T(async(Y,E=[])=>{if(O.current.isAgentWorking||O.current.hasPendingToolCalls)return;let w=q.current;if(w){await w.send(Y,E);return}C.current.push({prompt:Y,attachments:E});try{await I(Y)}catch(l){throw C.current=[],l}},[I]),y0=T(async()=>{await q.current?.abort()},[]),E0=T((Y,E,w)=>{q.current?.addToolResult(Y,E,w)},[]),M0=T(async(Y)=>{if(c.current?.id===Y)H();await V.deleteThread(Y),Z((E)=>E?R_(E,Y):E)},[V,H]),w0=T(()=>{g.discardConsumed(),setTimeout(()=>W.current?.focusInput())},[g]),P0=T(()=>{g.restoreConsumed(c.current?.id)},[g]),l_=T(async()=>{let Y=v_(await V.listThreads());return Z(Y),Y},[V]),E1=T((Y)=>{Z((w)=>{let l=Z1(w??[],Y);return w||l.length?l:w});let E=c.current?.id;switch(Y.type){case"thread:deleted":if(E===Y.payload.threadId)H();break;case"thread:run-started":if(E===Y.payload.thread.id)q.current?.reattach(Y.payload.thread);break;case"thread:messages-updated":q.current?.refreshMessages(Y.payload.threadId);break}},[H]);D0(()=>{l_();let Y=!1,E=L1({wsUrl:()=>k.current.wsUrl,transport:{baseUrl:()=>{let w=k.current.transport.baseUrl;return typeof w==="string"?w:w()},getHeaders:()=>k.current.transport.getHeaders()},onEvent:E1,onOpen:()=>{if(!Y){Y=!0;return}l_().then((w)=>{let l=c.current;if(!l)return;q.current?.reattach(w.find((r_)=>r_.id===l.id)??l)})}});return()=>{E.close()}},[E1,l_]);let o_=k_(void 0),u_=S?.id;D0(()=>{if(u_===o_.current)return;g.clear(o_.current),o_.current=u_},[u_,g]);let M1=_.locale??"en",q_=T((Y,E)=>X1(M1,Y,E),[M1]),A0=_.viewMode??"helper",b0={config:_,t:q_,api:V,debugMode:K,threads:L,selectedThread:S,deleteThread:M0,...G,send:B0,abort:y0,addToolResult:E0,queue:{items:y1,...k1(y1),accept:g.accept,remove:g.remove,consumeReady:g.consumeReady}};function U0(Y){x(Y),B("chat"),v(!1)}function v0(){H(),B("chat"),v(!1)}function R0(){H(),B("threads")}return y(K1.Provider,{value:b0,children:a("div",{className:Q("cortex-widget",N),"data-cortex-theme":_.theme,children:[a("div",{className:Q("cortex-widget__container",A0==="full"&&"cortex-widget__container--full",U&&"cortex-widget__container--sidebar-open"),onDragOver:(Y)=>Y.preventDefault(),onDrop:(Y)=>Y.preventDefault(),children:[y(O0,{className:Q("cortex-widget__screen",M==="threads"&&"cortex-widget__screen--active",M!=="threads"&&"cortex-widget__screen--left"),onThreadSelected:U0,onNewChatRequested:v0}),a("div",{className:Q("cortex-widget__screen",M==="chat"&&"cortex-widget__screen--active",M!=="chat"&&"cortex-widget__screen--right"),children:[a("div",{className:"cortex-widget__chat-header",children:[y("button",{onClick:()=>v((Y)=>!Y),className:"cortex-widget__sidebar-toggle-btn",children:y("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",children:y("path",{d:"M2.5 4h11M2.5 8h11M2.5 12h11",stroke:"currentColor",strokeWidth:"1.4",strokeLinecap:"round"})})}),y("button",{onClick:R0,className:"cortex-widget__back-btn",children:y("svg",{width:"14",height:"14",viewBox:"0 0 16 16",fill:"none",className:"cortex-widget__back-icon",children:y("path",{d:"M10 3L5 8l5 5",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round"})})}),y("div",{className:"cortex-widget__chat-title-wrap",children:y("p",{className:"cortex-widget__chat-title",children:S?.title??q_("translate_new_chat")})}),_.showDebugButton&&y("button",{onClick:()=>z((Y)=>!Y),className:Q("cortex-widget__debug-btn",K?"cortex-widget__debug-btn--on":"cortex-widget__debug-btn--off"),children:K?q_("translate_debug"):q_("translate_normal")})]}),G.isLoadingMessages&&!G.isAgentWorking?a("div",{className:"cortex-widget__messages-skeleton",children:[y("div",{className:"cortex-widget__msg-skel cortex-widget__msg-skel--user",children:a("div",{className:"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user",children:[y("div",{className:"cortex-skeleton cortex-widget__msg-skel-line",style:{width:"13rem"}}),y("div",{className:"cortex-skeleton cortex-widget__msg-skel-line",style:{width:"9rem"}})]})}),y("div",{className:"cortex-widget__msg-skel cortex-widget__msg-skel--assistant",children:a("div",{className:"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant",children:[y("div",{className:"cortex-skeleton cortex-widget__msg-skel-line",style:{width:"16rem"}}),y("div",{className:"cortex-skeleton cortex-widget__msg-skel-line",style:{width:"18rem"}}),y("div",{className:"cortex-skeleton cortex-widget__msg-skel-line",style:{width:"12rem"}})]})}),y("div",{className:"cortex-widget__msg-skel cortex-widget__msg-skel--user",children:y("div",{className:"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--user",children:y("div",{className:"cortex-skeleton cortex-widget__msg-skel-line",style:{width:"11rem"}})})}),y("div",{className:"cortex-widget__msg-skel cortex-widget__msg-skel--assistant",children:a("div",{className:"cortex-widget__msg-skel-bubble cortex-widget__msg-skel-bubble--assistant",children:[y("div",{className:"cortex-skeleton cortex-widget__msg-skel-line",style:{width:"14rem"}}),y("div",{className:"cortex-skeleton cortex-widget__msg-skel-line",style:{width:"15rem"}})]})})]}):y(H0,{className:"cortex-widget__messages",debugMode:K}),G.isAgentWorking&&!G.hasPendingToolCalls&&a("div",{className:"cortex-widget__working",children:[a("div",{className:"cortex-widget__working-dots",children:[y("span",{className:"cortex-working-dot"}),y("span",{className:"cortex-working-dot"}),y("span",{className:"cortex-working-dot"})]}),y("span",{className:"cortex-widget__working-text",children:q_("translate_thinking")})]}),!G.hasPendingToolCalls&&y(T1,{ref:W})]}),y("div",{className:"cortex-widget__sidebar-backdrop",onClick:()=>v(!1)})]}),J&&y(f1,{thread:J.thread,mode:J.mode,api:V,configRef:k,sessionRef:q,pendingSendRef:C,patchUi:u,setRunning:H_,remount:R,onTurnFinished:w0,onSendFailed:P0},`${J.thread.id}:${J.epoch}`)]})})}export{c2 as CortexChatWidget};
|