@personaai/react 0.9.0 → 0.11.0

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.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ ARCHITECT_AGENT_ID: () => ARCHITECT_AGENT_ID,
23
24
  PersonaProvider: () => PersonaProvider,
24
25
  VERSION: () => VERSION,
25
26
  createLogger: () => import_logger2.createLogger,
@@ -30,6 +31,7 @@ __export(index_exports, {
30
31
  setLogLevel: () => import_logger2.setLogLevel,
31
32
  supportsStreamingFetch: () => supportsStreamingFetch,
32
33
  useAgents: () => useAgents,
34
+ useArchitectChat: () => useArchitectChat,
33
35
  useChat: () => useChat,
34
36
  useConnection: () => useConnection,
35
37
  useFiles: () => useFiles,
@@ -37,6 +39,8 @@ __export(index_exports, {
37
39
  useMcpConnections: () => useMcpConnections,
38
40
  useMemory: () => useMemory,
39
41
  usePersonaContext: () => usePersonaContext,
42
+ useRcpSources: () => useRcpSources,
43
+ useSkills: () => useSkills,
40
44
  useThreads: () => useThreads,
41
45
  useVoice: () => useVoice,
42
46
  useWorkflow: () => useWorkflow,
@@ -334,7 +338,7 @@ async function openSSEStream(opts) {
334
338
  };
335
339
  }
336
340
 
337
- // src/hooks/useChat.ts
341
+ // src/hooks/streamEventHelpers.ts
338
342
  function isErrorToolContent(content) {
339
343
  if (typeof content !== "string" || !content.trim().startsWith("{"))
340
344
  return false;
@@ -380,6 +384,38 @@ function parsePresentedFile(content) {
380
384
  return null;
381
385
  }
382
386
  }
387
+ function normalizeWorkspaceFiles(raw) {
388
+ const normalized = {};
389
+ for (const [path, file] of Object.entries(raw || {})) {
390
+ normalized[path] = {
391
+ content: file.content,
392
+ size: file.size,
393
+ createdAt: file.created_at,
394
+ modifiedAt: file.modified_at
395
+ };
396
+ }
397
+ return normalized;
398
+ }
399
+ function normalizePendingInterrupt(pending) {
400
+ if (!pending || typeof pending !== "object") return null;
401
+ const p = pending;
402
+ if (p.kind === "hitl") {
403
+ return {
404
+ kind: "hitl",
405
+ actionRequests: p.value?.actionRequests ?? [],
406
+ reviewConfigs: p.value?.reviewConfigs ?? []
407
+ };
408
+ }
409
+ if (p.kind === "clarification") {
410
+ return {
411
+ kind: "clarification",
412
+ questions: p.value?.questions ?? []
413
+ };
414
+ }
415
+ return null;
416
+ }
417
+
418
+ // src/hooks/useChat.ts
383
419
  function parseSandboxCommand(tc) {
384
420
  let command = tc.args ?? "";
385
421
  try {
@@ -411,36 +447,6 @@ function parseSandboxCommand(tc) {
411
447
  seq: tc.seq
412
448
  };
413
449
  }
414
- function normalizeWorkspaceFiles(raw) {
415
- const normalized = {};
416
- for (const [path, file] of Object.entries(raw || {})) {
417
- normalized[path] = {
418
- content: file.content,
419
- size: file.size,
420
- createdAt: file.created_at,
421
- modifiedAt: file.modified_at
422
- };
423
- }
424
- return normalized;
425
- }
426
- function normalizePendingInterrupt(pending) {
427
- if (!pending || typeof pending !== "object") return null;
428
- const p = pending;
429
- if (p.kind === "hitl") {
430
- return {
431
- kind: "hitl",
432
- actionRequests: p.value?.actionRequests ?? [],
433
- reviewConfigs: p.value?.reviewConfigs ?? []
434
- };
435
- }
436
- if (p.kind === "clarification") {
437
- return {
438
- kind: "clarification",
439
- questions: p.value?.questions ?? []
440
- };
441
- }
442
- return null;
443
- }
444
450
  function useChat(options = {}) {
445
451
  const { defaultAgentId, fetchWithAuth, baseUrl, getAuthToken, logger } = usePersonaContext();
446
452
  const chatLogger = (0, import_react2.useMemo)(() => logger.child("chat"), [logger]);
@@ -1154,104 +1160,656 @@ function useChat(options = {}) {
1154
1160
  };
1155
1161
  }
1156
1162
 
1157
- // src/hooks/useMemory.ts
1163
+ // src/hooks/useArchitectChat.ts
1158
1164
  var import_react3 = require("react");
1159
- function useMemory(autoFetch = true) {
1160
- const { fetchWithAuth } = usePersonaContext();
1161
- const [memory, setMemory] = (0, import_react3.useState)({
1162
- userFiles: [],
1163
- agentMemories: []
1164
- });
1165
- const [isLoading, setIsLoading] = (0, import_react3.useState)(false);
1165
+ var ARCHITECT_AGENT_ID = "000000000000000000000002";
1166
+ function useArchitectChat(options = {}) {
1167
+ const { fetchWithAuth, baseUrl, getAuthToken, logger } = usePersonaContext();
1168
+ const chatLogger = (0, import_react3.useMemo)(() => logger.child("architect"), [logger]);
1169
+ const threadId = options.threadId;
1170
+ const [internalThreadId, setInternalThreadId] = (0, import_react3.useState)(void 0);
1171
+ const effectiveThreadId = threadId ?? internalThreadId;
1172
+ (0, import_react3.useEffect)(() => {
1173
+ if (threadId !== void 0) setInternalThreadId(threadId);
1174
+ }, [threadId]);
1175
+ const didLogInitRef = (0, import_react3.useRef)(false);
1176
+ if (!didLogInitRef.current) {
1177
+ didLogInitRef.current = true;
1178
+ chatLogger.debug("useArchitectChat init", {
1179
+ threadId,
1180
+ hasInitialMessages: !!options.initialMessages?.length
1181
+ });
1182
+ chatLogger.trace("useArchitectChat options", {
1183
+ threadId,
1184
+ initialMessageCount: options.initialMessages?.length ?? 0
1185
+ });
1186
+ }
1187
+ const [messages, setMessages] = (0, import_react3.useState)(
1188
+ options.initialMessages || []
1189
+ );
1190
+ const [input, setInput] = (0, import_react3.useState)("");
1191
+ const [isStreaming, setIsStreaming] = (0, import_react3.useState)(false);
1192
+ const [isLoadingHistory, setIsLoadingHistory] = (0, import_react3.useState)(false);
1166
1193
  const [error, setError] = (0, import_react3.useState)(null);
1167
- const fetchMemory = (0, import_react3.useCallback)(async () => {
1168
- setIsLoading(true);
1194
+ const [interrupt, setInterrupt] = (0, import_react3.useState)(null);
1195
+ const [files, setFiles] = (0, import_react3.useState)({});
1196
+ const [todos, setTodos] = (0, import_react3.useState)([]);
1197
+ const [presentedFile, setPresentedFile] = (0, import_react3.useState)(null);
1198
+ const abortControllerRef = (0, import_react3.useRef)(null);
1199
+ const loadedThreadIdRef = (0, import_react3.useRef)(void 0);
1200
+ const stop = (0, import_react3.useCallback)(() => {
1201
+ if (abortControllerRef.current) {
1202
+ chatLogger.info("stop streaming", {});
1203
+ chatLogger.debug("abort controller", {
1204
+ hasController: !!abortControllerRef.current
1205
+ });
1206
+ abortControllerRef.current.abort();
1207
+ abortControllerRef.current = null;
1208
+ setIsStreaming(false);
1209
+ chatLogger.debug("streaming stopped");
1210
+ } else {
1211
+ chatLogger.trace("stop called \u2014 no active stream");
1212
+ }
1213
+ }, [chatLogger]);
1214
+ const clear = (0, import_react3.useCallback)(() => {
1215
+ chatLogger.info("clear chat", { messageCount: messages.length });
1216
+ chatLogger.debug("clear", { messageCount: messages.length });
1217
+ stop();
1218
+ setMessages([]);
1169
1219
  setError(null);
1170
- try {
1171
- const res = await fetchWithAuth("/memory");
1172
- if (!res.ok) {
1173
- throw new Error(`Failed to fetch memory: ${res.statusText}`);
1220
+ setInterrupt(null);
1221
+ setFiles({});
1222
+ setTodos([]);
1223
+ setPresentedFile(null);
1224
+ loadedThreadIdRef.current = void 0;
1225
+ }, [stop, chatLogger, messages.length]);
1226
+ const startNewChat = (0, import_react3.useCallback)(() => {
1227
+ chatLogger.info("startNewChat \u2014 entering ephemeral mode");
1228
+ stop();
1229
+ setMessages([]);
1230
+ setError(null);
1231
+ setInterrupt(null);
1232
+ setFiles({});
1233
+ setTodos([]);
1234
+ setPresentedFile(null);
1235
+ setInput("");
1236
+ loadedThreadIdRef.current = void 0;
1237
+ setInternalThreadId(void 0);
1238
+ }, [stop, chatLogger]);
1239
+ const loadThreadMessages = (0, import_react3.useCallback)(
1240
+ async (id) => {
1241
+ chatLogger.debug("loadThreadMessages start", { threadId: id });
1242
+ chatLogger.trace("loadThreadMessages", { threadId: id });
1243
+ setIsLoadingHistory(true);
1244
+ setError(null);
1245
+ try {
1246
+ const res = await fetchWithAuth(`/threads/${id}/messages`);
1247
+ if (!res.ok)
1248
+ throw new Error(`Failed to load thread history: ${res.statusText}`);
1249
+ const body = await res.json();
1250
+ const data = body?.data ?? body;
1251
+ const raw = data?.messages ?? [];
1252
+ const subagentTraces = data?.subagentTraces ?? {};
1253
+ const loaded = raw.map((m, i) => ({
1254
+ id: m.id || `history-${id}-${i}`,
1255
+ role: m.role,
1256
+ content: m.content,
1257
+ createdAt: /* @__PURE__ */ new Date(),
1258
+ toolCalls: m.toolCalls?.map((tc) => {
1259
+ const trace = subagentTraces[tc.toolCallId];
1260
+ return Array.isArray(trace) && trace.length > 0 ? {
1261
+ ...tc,
1262
+ subagentActivity: persistedTraceToActivityEntries(trace)
1263
+ } : tc;
1264
+ })
1265
+ }));
1266
+ setMessages(loaded);
1267
+ setInterrupt(normalizePendingInterrupt(data?.pendingInterrupt));
1268
+ setFiles(normalizeWorkspaceFiles(data?.state?.files ?? {}));
1269
+ setTodos(data?.state?.todos ?? []);
1270
+ loadedThreadIdRef.current = id;
1271
+ chatLogger.info("loadThreadMessages succeeded", {
1272
+ threadId: id,
1273
+ messageCount: loaded.length
1274
+ });
1275
+ chatLogger.debug("loadThreadMessages completed", {
1276
+ threadId: id,
1277
+ messageCount: loaded.length
1278
+ });
1279
+ return loaded;
1280
+ } catch (err) {
1281
+ const errorObj = err instanceof Error ? err : new Error(String(err));
1282
+ chatLogger.warn("loadThreadMessages failed", {
1283
+ threadId: id,
1284
+ error: errorObj.message
1285
+ });
1286
+ chatLogger.error("loadThreadMessages error", {
1287
+ threadId: id,
1288
+ error: errorObj.message
1289
+ });
1290
+ setError(errorObj);
1291
+ if (loadedThreadIdRef.current === id) loadedThreadIdRef.current = void 0;
1292
+ return [];
1293
+ } finally {
1294
+ setIsLoadingHistory(false);
1295
+ chatLogger.trace("loadThreadMessages end", { threadId: id });
1174
1296
  }
1175
- const data = await res.json();
1176
- setMemory(data);
1177
- return data;
1178
- } catch (err) {
1179
- const errorObj = err instanceof Error ? err : new Error(String(err));
1180
- setError(errorObj);
1181
- return { userFiles: [], agentMemories: [] };
1182
- } finally {
1183
- setIsLoading(false);
1184
- }
1185
- }, [fetchWithAuth]);
1186
- const getFile = (0, import_react3.useCallback)(
1187
- async (params) => {
1188
- const query = new URLSearchParams({ path: params.path });
1189
- if (params.scope) query.set("scope", params.scope);
1190
- if (params.agentId) query.set("agentId", params.agentId);
1191
- const res = await fetchWithAuth(`/memory/file?${query.toString()}`);
1192
- if (!res.ok)
1193
- throw new Error(`Failed to get memory file: ${res.statusText}`);
1194
- return await res.json();
1195
- },
1196
- [fetchWithAuth]
1197
- );
1198
- const writeFile = (0, import_react3.useCallback)(
1199
- async (params) => {
1200
- const res = await fetchWithAuth("/memory/file", {
1201
- method: "PUT",
1202
- headers: { "Content-Type": "application/json" },
1203
- body: JSON.stringify(params)
1204
- });
1205
- if (!res.ok)
1206
- throw new Error(`Failed to write memory file: ${res.statusText}`);
1207
- const updated = await res.json();
1208
- void fetchMemory();
1209
- return updated;
1210
- },
1211
- [fetchWithAuth, fetchMemory]
1212
- );
1213
- const deleteFile = (0, import_react3.useCallback)(
1214
- async (params) => {
1215
- const query = new URLSearchParams({ path: params.path });
1216
- if (params.scope) query.set("scope", params.scope);
1217
- if (params.agentId) query.set("agentId", params.agentId);
1218
- const res = await fetchWithAuth(`/memory/file?${query.toString()}`, {
1219
- method: "DELETE"
1220
- });
1221
- if (!res.ok)
1222
- throw new Error(`Failed to delete memory file: ${res.statusText}`);
1223
- void fetchMemory();
1224
1297
  },
1225
- [fetchWithAuth, fetchMemory]
1298
+ [fetchWithAuth, chatLogger]
1226
1299
  );
1227
1300
  (0, import_react3.useEffect)(() => {
1228
- if (autoFetch) {
1229
- void fetchMemory();
1301
+ if (!effectiveThreadId || isStreaming) {
1302
+ chatLogger.trace("auto-load skipped", { threadId: effectiveThreadId, isStreaming });
1303
+ return;
1230
1304
  }
1231
- }, [autoFetch, fetchMemory]);
1232
- return {
1233
- memory,
1234
- isLoading,
1235
- error,
1236
- refetch: fetchMemory,
1237
- getFile,
1238
- writeFile,
1239
- deleteFile
1240
- };
1241
- }
1242
-
1243
- // src/hooks/useThreads.ts
1244
- var import_react4 = require("react");
1245
- function useThreads(autoFetch = true) {
1246
- const { fetchWithAuth, defaultAgentId } = usePersonaContext();
1247
- const [threads, setThreads] = (0, import_react4.useState)([]);
1248
- const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
1249
- const [error, setError] = (0, import_react4.useState)(null);
1250
- const fetchThreads = (0, import_react4.useCallback)(async () => {
1251
- setIsLoading(true);
1252
- setError(null);
1253
- try {
1254
- const res = await fetchWithAuth("/threads");
1305
+ if (loadedThreadIdRef.current === effectiveThreadId) {
1306
+ chatLogger.trace("auto-load already loaded", { threadId: effectiveThreadId });
1307
+ return;
1308
+ }
1309
+ if (messages.length > 0) {
1310
+ chatLogger.trace("auto-load has messages", {
1311
+ threadId: effectiveThreadId,
1312
+ count: messages.length
1313
+ });
1314
+ return;
1315
+ }
1316
+ chatLogger.info("auto-load thread history", { threadId: effectiveThreadId });
1317
+ chatLogger.debug("loadThreadMessages trigger", { threadId: effectiveThreadId });
1318
+ void loadThreadMessages(effectiveThreadId);
1319
+ }, [effectiveThreadId, isStreaming, messages.length, loadThreadMessages, chatLogger]);
1320
+ const doSend = (0, import_react3.useCallback)(
1321
+ async (prompt, baseMessages, overrideOptions) => {
1322
+ chatLogger.debug("sendMessage start", {
1323
+ promptPreview: prompt.slice(0, 100),
1324
+ threadId: effectiveThreadId ?? overrideOptions?.threadId,
1325
+ hasResume: !!overrideOptions?.resume,
1326
+ messageCount: baseMessages.length
1327
+ });
1328
+ chatLogger.trace("sendMessage details", {
1329
+ promptPreview: prompt.slice(0, 200),
1330
+ hasResume: !!overrideOptions?.resume
1331
+ });
1332
+ const userMessage = {
1333
+ id: `user-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
1334
+ role: "user",
1335
+ content: prompt,
1336
+ createdAt: /* @__PURE__ */ new Date()
1337
+ };
1338
+ const assistantMessageId = `assistant-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
1339
+ const placeholderAssistant = {
1340
+ id: assistantMessageId,
1341
+ role: "assistant",
1342
+ content: "",
1343
+ createdAt: /* @__PURE__ */ new Date(),
1344
+ isStreaming: true,
1345
+ toolCalls: []
1346
+ };
1347
+ const nextMessages = [...baseMessages, userMessage];
1348
+ setMessages([...nextMessages, placeholderAssistant]);
1349
+ setInput("");
1350
+ setIsStreaming(true);
1351
+ setError(null);
1352
+ setInterrupt(null);
1353
+ const controller = new AbortController();
1354
+ abortControllerRef.current = controller;
1355
+ const finalizeReasoning = () => {
1356
+ setMessages(
1357
+ (prev) => prev.map((m) => m.role === "reasoning" && m.isStreaming ? { ...m, isStreaming: false } : m)
1358
+ );
1359
+ };
1360
+ try {
1361
+ const payloadMessages = nextMessages.filter((m) => m.role !== "reasoning").map((m) => ({
1362
+ role: m.role === "assistant" ? "assistant" : "user",
1363
+ content: m.content
1364
+ }));
1365
+ let resolvedThreadId = await overrideOptions?.threadId ?? effectiveThreadId;
1366
+ if (!resolvedThreadId) {
1367
+ chatLogger.info("minting real thread for ephemeral architect chat", {});
1368
+ const createRes = await fetchWithAuth("/threads", {
1369
+ method: "POST",
1370
+ headers: { "Content-Type": "application/json" },
1371
+ body: JSON.stringify({ agentId: ARCHITECT_AGENT_ID })
1372
+ });
1373
+ if (!createRes.ok) throw new Error(`Failed to create thread: ${createRes.statusText}`);
1374
+ const createBody = await createRes.json();
1375
+ const created = createBody?.data ?? createBody;
1376
+ resolvedThreadId = created._id ?? created.id;
1377
+ if (!resolvedThreadId) throw new Error("Thread creation returned no id");
1378
+ setInternalThreadId(resolvedThreadId);
1379
+ loadedThreadIdRef.current = resolvedThreadId;
1380
+ options.onThreadCreated?.(resolvedThreadId);
1381
+ chatLogger.info("ephemeral architect chat minted", { threadId: resolvedThreadId });
1382
+ }
1383
+ chatLogger.trace("resolved threadId", { threadId: resolvedThreadId });
1384
+ const token = getAuthToken ? await getAuthToken() : null;
1385
+ chatLogger.debug("opening SSE stream", {
1386
+ hasToken: !!token,
1387
+ hasThreadId: !!resolvedThreadId
1388
+ });
1389
+ const stream = await openSSEStream({
1390
+ url: `${baseUrl}/architect`,
1391
+ headers: {
1392
+ "Content-Type": "application/json",
1393
+ ...token ? { Authorization: `Bearer ${token}` } : {}
1394
+ },
1395
+ body: JSON.stringify({
1396
+ messages: payloadMessages,
1397
+ threadId: resolvedThreadId,
1398
+ resume: overrideOptions?.resume
1399
+ }),
1400
+ signal: controller.signal
1401
+ });
1402
+ if (!stream.ok) {
1403
+ chatLogger.warn("SSE stream not ok", { status: stream.status, errorText: stream.errorText });
1404
+ chatLogger.error("architect stream failed", { status: stream.status, error: stream.errorText });
1405
+ throw new Error(`Architect error (${stream.status}): ${stream.errorText ?? "Stream failed"}`);
1406
+ }
1407
+ chatLogger.debug("SSE stream opened", { status: stream.status });
1408
+ chatLogger.info("architect stream started", { threadId: resolvedThreadId });
1409
+ const reader = stream.reader;
1410
+ let buffer = "";
1411
+ let accumulatedText = "";
1412
+ const toolCallsMap = /* @__PURE__ */ new Map();
1413
+ let streamSeq = 0;
1414
+ let activeReasoningId = null;
1415
+ const reasoningById = /* @__PURE__ */ new Map();
1416
+ const patchAssistant = (patch) => {
1417
+ setMessages(
1418
+ (prev) => prev.map(
1419
+ (msg) => msg.id === assistantMessageId ? { ...msg, toolCalls: Array.from(toolCallsMap.values()), ...patch } : msg
1420
+ )
1421
+ );
1422
+ };
1423
+ const insertReasoningMessage = (id, seq) => {
1424
+ const msg = { id, role: "reasoning", content: "", createdAt: /* @__PURE__ */ new Date(), isStreaming: true, seq };
1425
+ setMessages((prev) => {
1426
+ const idx = prev.findIndex((m) => m.id === assistantMessageId);
1427
+ if (idx === -1) return [...prev, msg];
1428
+ const next = [...prev];
1429
+ next.splice(idx, 0, msg);
1430
+ return next;
1431
+ });
1432
+ };
1433
+ while (true) {
1434
+ const { done, value } = await reader.read();
1435
+ if (done) break;
1436
+ buffer += value ?? "";
1437
+ const lines = buffer.split("\n");
1438
+ buffer = lines.pop() ?? "";
1439
+ for (const line of lines) {
1440
+ const trimmed = line.trim();
1441
+ if (!trimmed || !trimmed.startsWith("data:")) continue;
1442
+ const raw = trimmed.replace(/^data:\s*/, "");
1443
+ if (raw === "[DONE]") break;
1444
+ try {
1445
+ const event = JSON.parse(raw);
1446
+ chatLogger.trace("stream event", { type: event.type, event });
1447
+ options.onEvent?.(event);
1448
+ if (event.type === "TEXT_MESSAGE_CHUNK" && event.delta) {
1449
+ chatLogger.debug("text chunk", { deltaLength: event.delta.length });
1450
+ accumulatedText += event.delta;
1451
+ patchAssistant({ content: accumulatedText, isStreaming: true });
1452
+ } else if (event.type === "TOOL_CALL_CHUNK" && event.toolCallId) {
1453
+ chatLogger.debug("tool call chunk", { toolCallId: event.toolCallId, toolCallName: event.toolCallName });
1454
+ const existing = toolCallsMap.get(event.toolCallId);
1455
+ if (existing) {
1456
+ existing.args = (existing.args || "") + (event.delta || "");
1457
+ } else {
1458
+ toolCallsMap.set(event.toolCallId, {
1459
+ toolCallId: event.toolCallId,
1460
+ toolName: event.toolCallName || "",
1461
+ args: event.delta || "",
1462
+ seq: streamSeq++
1463
+ });
1464
+ }
1465
+ patchAssistant({});
1466
+ } else if (event.type === "TOOL_CALL_RESULT") {
1467
+ chatLogger.debug("tool call result", { toolCallId: event.toolCallId });
1468
+ const existing = toolCallsMap.get(event.toolCallId);
1469
+ if (existing) {
1470
+ existing.result = event.content;
1471
+ existing.isError = isErrorToolContent(event.content);
1472
+ if (existing.isError) chatLogger.warn("tool call error", { toolCallId: event.toolCallId });
1473
+ if (existing.toolName === "present_file" && !existing.isError) {
1474
+ const presented = parsePresentedFile(event.content);
1475
+ if (presented) {
1476
+ chatLogger.info("present_file", { path: presented.path });
1477
+ setPresentedFile(presented);
1478
+ }
1479
+ }
1480
+ patchAssistant({});
1481
+ }
1482
+ } else if (event.type === "STATE_SNAPSHOT") {
1483
+ chatLogger.debug("state snapshot", {
1484
+ fileCount: Object.keys(event.snapshot.files ?? {}).length,
1485
+ todoCount: event.snapshot.todos?.length ?? 0
1486
+ });
1487
+ setFiles(normalizeWorkspaceFiles(event.snapshot.files ?? {}));
1488
+ setTodos(event.snapshot.todos ?? []);
1489
+ } else if (event.type === "REASONING_MESSAGE_START" && event.messageId) {
1490
+ chatLogger.debug("reasoning start", { messageId: event.messageId });
1491
+ activeReasoningId = event.messageId;
1492
+ reasoningById.set(event.messageId, { content: "" });
1493
+ insertReasoningMessage(event.messageId, streamSeq++);
1494
+ } else if (event.type === "REASONING_MESSAGE_CONTENT") {
1495
+ let rid = event.messageId || activeReasoningId || "";
1496
+ if (!rid || !reasoningById.has(rid)) {
1497
+ rid = rid || `reasoning-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
1498
+ activeReasoningId = rid;
1499
+ reasoningById.set(rid, { content: "" });
1500
+ insertReasoningMessage(rid, streamSeq++);
1501
+ chatLogger.debug("reasoning lazy start", { messageId: rid });
1502
+ }
1503
+ const entry = reasoningById.get(rid);
1504
+ entry.content += event.delta;
1505
+ chatLogger.trace("reasoning content", { messageId: rid, deltaLength: event.delta?.length ?? 0 });
1506
+ setMessages((prev) => prev.map((m) => m.id === rid ? { ...m, content: entry.content, isStreaming: true } : m));
1507
+ } else if (event.type === "REASONING_END") {
1508
+ chatLogger.debug("reasoning end", { messageId: activeReasoningId });
1509
+ const rid = activeReasoningId;
1510
+ activeReasoningId = null;
1511
+ if (rid) {
1512
+ setMessages((prev) => prev.map((m) => m.id === rid ? { ...m, isStreaming: false } : m));
1513
+ }
1514
+ } else if (event.type === "CUSTOM") {
1515
+ chatLogger.debug("custom event", { name: event.name });
1516
+ if (event.name === "hitl_request") {
1517
+ const value2 = event.value;
1518
+ chatLogger.info("hitl interrupt", { actionCount: value2.actionRequests?.length ?? 0 });
1519
+ setInterrupt({ kind: "hitl", actionRequests: value2.actionRequests, reviewConfigs: value2.reviewConfigs });
1520
+ } else if (event.name === "clarification_request") {
1521
+ const value2 = event.value;
1522
+ chatLogger.info("clarification interrupt", { questionCount: value2.questions?.length ?? 0 });
1523
+ setInterrupt({ kind: "clarification", questions: value2.questions });
1524
+ } else if (event.name === "subagent_activity") {
1525
+ const { toolCallId, ...entry } = event.value;
1526
+ chatLogger.trace("subagent activity", { toolCallId, kind: entry.kind });
1527
+ const existing = toolCallsMap.get(toolCallId);
1528
+ if (existing) {
1529
+ existing.subagentActivity = [...existing.subagentActivity || [], entry];
1530
+ patchAssistant({});
1531
+ }
1532
+ } else if (event.name === "mcp_app") {
1533
+ const val = event.value;
1534
+ if (val?.toolCallId && val?.resourceUri && val?.mcpId) {
1535
+ const existing = toolCallsMap.get(val.toolCallId);
1536
+ if (existing) {
1537
+ existing.mcpApp = { resourceUri: val.resourceUri, mcpId: val.mcpId };
1538
+ patchAssistant({});
1539
+ }
1540
+ }
1541
+ }
1542
+ } else if (event.type === "title") {
1543
+ const title = event.title;
1544
+ if (typeof title === "string" && title.trim()) {
1545
+ chatLogger.info("auto title", { title });
1546
+ options.onTitle?.(title);
1547
+ }
1548
+ } else if (event.type === "RUN_ERROR") {
1549
+ chatLogger.warn("run error", { message: event.message, code: event.code });
1550
+ chatLogger.error("stream run error", { code: event.code, message: event.message });
1551
+ throw new Error(event.message || "Stream error from agent");
1552
+ } else {
1553
+ chatLogger.trace("unhandled event", { type: event.type });
1554
+ }
1555
+ } catch (e) {
1556
+ if (e instanceof Error && e.message.startsWith("Stream error")) throw e;
1557
+ chatLogger.warn("event parse error", { raw: raw.slice(0, 200), error: e instanceof Error ? e.message : String(e) });
1558
+ }
1559
+ }
1560
+ }
1561
+ const finalMessage = {
1562
+ id: assistantMessageId,
1563
+ role: "assistant",
1564
+ content: accumulatedText,
1565
+ createdAt: /* @__PURE__ */ new Date(),
1566
+ isStreaming: false,
1567
+ toolCalls: Array.from(toolCallsMap.values())
1568
+ };
1569
+ setMessages((prev) => prev.map((msg) => msg.id === assistantMessageId ? finalMessage : msg));
1570
+ chatLogger.info("sendMessage succeeded", { textLength: accumulatedText.length, toolCallCount: toolCallsMap.size });
1571
+ chatLogger.debug("sendMessage completed", { textLength: accumulatedText.length, eventCount: toolCallsMap.size + 1 });
1572
+ options.onFinish?.(finalMessage);
1573
+ return true;
1574
+ } catch (err) {
1575
+ if (controller.signal.aborted) {
1576
+ chatLogger.info("sendMessage aborted", {});
1577
+ chatLogger.debug("stream aborted", {});
1578
+ setMessages((prev) => prev.map((msg) => msg.id === assistantMessageId ? { ...msg, isStreaming: false } : msg));
1579
+ return false;
1580
+ }
1581
+ const errorObj = err instanceof Error ? err : new Error(String(err));
1582
+ chatLogger.warn("sendMessage failed", { error: errorObj.message });
1583
+ chatLogger.error("sendMessage error", { error: errorObj.message });
1584
+ setError(errorObj);
1585
+ options.onError?.(errorObj);
1586
+ setMessages(
1587
+ (prev) => prev.map(
1588
+ (msg) => msg.id === assistantMessageId ? { ...msg, content: msg.content || `\u26A0\uFE0F Error: ${errorObj.message || "Failed to get response."}`, isStreaming: false } : msg
1589
+ )
1590
+ );
1591
+ return false;
1592
+ } finally {
1593
+ setIsStreaming(false);
1594
+ abortControllerRef.current = null;
1595
+ finalizeReasoning();
1596
+ chatLogger.debug("sendMessage finally", { isStreaming: false });
1597
+ chatLogger.trace("sendMessage end", {});
1598
+ }
1599
+ },
1600
+ [baseUrl, getAuthToken, fetchWithAuth, options, chatLogger, effectiveThreadId]
1601
+ );
1602
+ const sendMessage = (0, import_react3.useCallback)(
1603
+ async (contentToSend, overrideOptions) => {
1604
+ const prompt = (contentToSend ?? input).trim();
1605
+ if (!prompt || isStreaming) {
1606
+ chatLogger.trace("sendMessage skipped", {
1607
+ hasPrompt: !!prompt,
1608
+ isStreaming
1609
+ });
1610
+ if (isStreaming) {
1611
+ chatLogger.warn("sendMessage dropped while streaming \u2014 caller should queue or disable send", {});
1612
+ }
1613
+ return false;
1614
+ }
1615
+ return doSend(prompt, messages, overrideOptions);
1616
+ },
1617
+ [input, isStreaming, messages, doSend, chatLogger]
1618
+ );
1619
+ const handleInputChange = (0, import_react3.useCallback)(
1620
+ (e) => {
1621
+ chatLogger.trace("handleInputChange", { length: e.target.value.length });
1622
+ setInput(e.target.value);
1623
+ },
1624
+ [chatLogger]
1625
+ );
1626
+ const handleSubmit = (0, import_react3.useCallback)(
1627
+ (e) => {
1628
+ if (e) e.preventDefault();
1629
+ chatLogger.debug("handleSubmit", {});
1630
+ void sendMessage();
1631
+ },
1632
+ [sendMessage, chatLogger]
1633
+ );
1634
+ const reload = (0, import_react3.useCallback)(async () => {
1635
+ if (messages.length === 0 || isStreaming) {
1636
+ chatLogger.trace("reload skipped", {
1637
+ messageCount: messages.length,
1638
+ isStreaming
1639
+ });
1640
+ return false;
1641
+ }
1642
+ let lastUserIndex = -1;
1643
+ for (let i = messages.length - 1; i >= 0; i--) {
1644
+ if (messages[i].role === "user") {
1645
+ lastUserIndex = i;
1646
+ break;
1647
+ }
1648
+ }
1649
+ if (lastUserIndex === -1) {
1650
+ chatLogger.warn("reload no user message", {});
1651
+ return false;
1652
+ }
1653
+ const lastUserMessage = messages[lastUserIndex];
1654
+ const truncated = messages.slice(0, lastUserIndex);
1655
+ chatLogger.info("reload", { messageId: lastUserMessage.id });
1656
+ chatLogger.debug("reload last user", {
1657
+ preview: lastUserMessage.content.slice(0, 100)
1658
+ });
1659
+ return doSend(lastUserMessage.content, truncated);
1660
+ }, [isStreaming, messages, doSend, chatLogger]);
1661
+ const resumeInterrupt = (0, import_react3.useCallback)(
1662
+ (resume, displayContent) => {
1663
+ chatLogger.info("resumeInterrupt", {
1664
+ kind: resume.decisions ? "hitl" : "clarification",
1665
+ preview: displayContent.slice(0, 50)
1666
+ });
1667
+ return sendMessage(displayContent, { resume });
1668
+ },
1669
+ [sendMessage, chatLogger]
1670
+ );
1671
+ const dismissPresentedFile = (0, import_react3.useCallback)(() => {
1672
+ chatLogger.debug("dismissPresentedFile", {});
1673
+ setPresentedFile(null);
1674
+ }, [chatLogger]);
1675
+ const openWorkspaceFile = (0, import_react3.useCallback)(
1676
+ (path) => {
1677
+ chatLogger.debug("openWorkspaceFile", { path });
1678
+ setPresentedFile({
1679
+ path,
1680
+ title: path.split("/").pop() || path,
1681
+ description: ""
1682
+ });
1683
+ },
1684
+ [chatLogger]
1685
+ );
1686
+ return {
1687
+ messages,
1688
+ input,
1689
+ setInput,
1690
+ handleInputChange,
1691
+ handleSubmit,
1692
+ sendMessage,
1693
+ isStreaming,
1694
+ isLoading: isStreaming,
1695
+ isLoadingHistory,
1696
+ error,
1697
+ interrupt,
1698
+ resumeInterrupt,
1699
+ files,
1700
+ todos,
1701
+ presentedFile,
1702
+ dismissPresentedFile,
1703
+ openWorkspaceFile,
1704
+ stop,
1705
+ reload,
1706
+ clear,
1707
+ startNewChat,
1708
+ currentThreadId: effectiveThreadId,
1709
+ isEphemeral: !effectiveThreadId,
1710
+ setMessages,
1711
+ loadThreadMessages
1712
+ };
1713
+ }
1714
+
1715
+ // src/hooks/useMemory.ts
1716
+ var import_react4 = require("react");
1717
+ function useMemory(autoFetch = true) {
1718
+ const { fetchWithAuth } = usePersonaContext();
1719
+ const [memory, setMemory] = (0, import_react4.useState)({
1720
+ userFiles: [],
1721
+ agentMemories: []
1722
+ });
1723
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
1724
+ const [error, setError] = (0, import_react4.useState)(null);
1725
+ const fetchMemory = (0, import_react4.useCallback)(async () => {
1726
+ setIsLoading(true);
1727
+ setError(null);
1728
+ try {
1729
+ const res = await fetchWithAuth("/memory");
1730
+ if (!res.ok) {
1731
+ throw new Error(`Failed to fetch memory: ${res.statusText}`);
1732
+ }
1733
+ const data = await res.json();
1734
+ setMemory(data);
1735
+ return data;
1736
+ } catch (err) {
1737
+ const errorObj = err instanceof Error ? err : new Error(String(err));
1738
+ setError(errorObj);
1739
+ return { userFiles: [], agentMemories: [] };
1740
+ } finally {
1741
+ setIsLoading(false);
1742
+ }
1743
+ }, [fetchWithAuth]);
1744
+ const getFile = (0, import_react4.useCallback)(
1745
+ async (params) => {
1746
+ const query = new URLSearchParams({ path: params.path });
1747
+ if (params.scope) query.set("scope", params.scope);
1748
+ if (params.agentId) query.set("agentId", params.agentId);
1749
+ const res = await fetchWithAuth(`/memory/file?${query.toString()}`);
1750
+ if (!res.ok)
1751
+ throw new Error(`Failed to get memory file: ${res.statusText}`);
1752
+ return await res.json();
1753
+ },
1754
+ [fetchWithAuth]
1755
+ );
1756
+ const writeFile = (0, import_react4.useCallback)(
1757
+ async (params) => {
1758
+ const res = await fetchWithAuth("/memory/file", {
1759
+ method: "PUT",
1760
+ headers: { "Content-Type": "application/json" },
1761
+ body: JSON.stringify(params)
1762
+ });
1763
+ if (!res.ok)
1764
+ throw new Error(`Failed to write memory file: ${res.statusText}`);
1765
+ const updated = await res.json();
1766
+ void fetchMemory();
1767
+ return updated;
1768
+ },
1769
+ [fetchWithAuth, fetchMemory]
1770
+ );
1771
+ const deleteFile = (0, import_react4.useCallback)(
1772
+ async (params) => {
1773
+ const query = new URLSearchParams({ path: params.path });
1774
+ if (params.scope) query.set("scope", params.scope);
1775
+ if (params.agentId) query.set("agentId", params.agentId);
1776
+ const res = await fetchWithAuth(`/memory/file?${query.toString()}`, {
1777
+ method: "DELETE"
1778
+ });
1779
+ if (!res.ok)
1780
+ throw new Error(`Failed to delete memory file: ${res.statusText}`);
1781
+ void fetchMemory();
1782
+ },
1783
+ [fetchWithAuth, fetchMemory]
1784
+ );
1785
+ (0, import_react4.useEffect)(() => {
1786
+ if (autoFetch) {
1787
+ void fetchMemory();
1788
+ }
1789
+ }, [autoFetch, fetchMemory]);
1790
+ return {
1791
+ memory,
1792
+ isLoading,
1793
+ error,
1794
+ refetch: fetchMemory,
1795
+ getFile,
1796
+ writeFile,
1797
+ deleteFile
1798
+ };
1799
+ }
1800
+
1801
+ // src/hooks/useThreads.ts
1802
+ var import_react5 = require("react");
1803
+ function useThreads(autoFetch = true) {
1804
+ const { fetchWithAuth, defaultAgentId } = usePersonaContext();
1805
+ const [threads, setThreads] = (0, import_react5.useState)([]);
1806
+ const [isLoading, setIsLoading] = (0, import_react5.useState)(false);
1807
+ const [error, setError] = (0, import_react5.useState)(null);
1808
+ const fetchThreads = (0, import_react5.useCallback)(async () => {
1809
+ setIsLoading(true);
1810
+ setError(null);
1811
+ try {
1812
+ const res = await fetchWithAuth("/threads");
1255
1813
  if (!res.ok) throw new Error(`Failed to list threads: ${res.statusText}`);
1256
1814
  const data = await res.json();
1257
1815
  const items = Array.isArray(data) ? data : data?.items || data?.threads || (Array.isArray(data?.data) ? data.data : void 0) || [];
@@ -1265,7 +1823,7 @@ function useThreads(autoFetch = true) {
1265
1823
  setIsLoading(false);
1266
1824
  }
1267
1825
  }, [fetchWithAuth]);
1268
- const createThread = (0, import_react4.useCallback)(
1826
+ const createThread = (0, import_react5.useCallback)(
1269
1827
  async (agentId) => {
1270
1828
  const targetAgentId = agentId || defaultAgentId;
1271
1829
  const res = await fetchWithAuth("/threads", {
@@ -1282,7 +1840,7 @@ function useThreads(autoFetch = true) {
1282
1840
  },
1283
1841
  [fetchWithAuth, defaultAgentId, fetchThreads]
1284
1842
  );
1285
- const deleteThread = (0, import_react4.useCallback)(
1843
+ const deleteThread = (0, import_react5.useCallback)(
1286
1844
  async (threadId) => {
1287
1845
  const res = await fetchWithAuth(`/threads/${threadId}`, {
1288
1846
  method: "DELETE"
@@ -1293,7 +1851,7 @@ function useThreads(autoFetch = true) {
1293
1851
  },
1294
1852
  [fetchWithAuth]
1295
1853
  );
1296
- const bulkDeleteThreads = (0, import_react4.useCallback)(
1854
+ const bulkDeleteThreads = (0, import_react5.useCallback)(
1297
1855
  async (threadIds) => {
1298
1856
  const res = await fetchWithAuth("/threads/bulk-delete", {
1299
1857
  method: "POST",
@@ -1310,13 +1868,13 @@ function useThreads(autoFetch = true) {
1310
1868
  },
1311
1869
  [fetchWithAuth]
1312
1870
  );
1313
- const deleteAllThreads = (0, import_react4.useCallback)(async () => {
1871
+ const deleteAllThreads = (0, import_react5.useCallback)(async () => {
1314
1872
  const ids = threads.map((t) => t._id);
1315
1873
  for (let i = 0; i < ids.length; i += 100) {
1316
1874
  await bulkDeleteThreads(ids.slice(i, i + 100));
1317
1875
  }
1318
1876
  }, [threads, bulkDeleteThreads]);
1319
- const updateThread = (0, import_react4.useCallback)(
1877
+ const updateThread = (0, import_react5.useCallback)(
1320
1878
  async (threadId, input) => {
1321
1879
  const res = await fetchWithAuth(`/threads/${threadId}`, {
1322
1880
  method: "PATCH",
@@ -1334,11 +1892,11 @@ function useThreads(autoFetch = true) {
1334
1892
  },
1335
1893
  [fetchWithAuth]
1336
1894
  );
1337
- const renameThread = (0, import_react4.useCallback)(
1895
+ const renameThread = (0, import_react5.useCallback)(
1338
1896
  (threadId, title) => updateThread(threadId, { title }),
1339
1897
  [updateThread]
1340
1898
  );
1341
- const resetThread = (0, import_react4.useCallback)(
1899
+ const resetThread = (0, import_react5.useCallback)(
1342
1900
  async (threadId) => {
1343
1901
  const res = await fetchWithAuth(`/threads/${threadId}/reset`, {
1344
1902
  method: "POST"
@@ -1353,7 +1911,7 @@ function useThreads(autoFetch = true) {
1353
1911
  },
1354
1912
  [fetchWithAuth]
1355
1913
  );
1356
- const getThread = (0, import_react4.useCallback)(
1914
+ const getThread = (0, import_react5.useCallback)(
1357
1915
  async (threadId) => {
1358
1916
  const res = await fetchWithAuth(`/threads/${threadId}`);
1359
1917
  if (!res.ok) throw new Error(`Failed to fetch thread: ${res.statusText}`);
@@ -1362,7 +1920,7 @@ function useThreads(autoFetch = true) {
1362
1920
  },
1363
1921
  [fetchWithAuth]
1364
1922
  );
1365
- (0, import_react4.useEffect)(() => {
1923
+ (0, import_react5.useEffect)(() => {
1366
1924
  if (autoFetch) {
1367
1925
  void fetchThreads();
1368
1926
  }
@@ -1384,7 +1942,7 @@ function useThreads(autoFetch = true) {
1384
1942
  }
1385
1943
 
1386
1944
  // src/hooks/useVoice.ts
1387
- var import_react5 = require("react");
1945
+ var import_react6 = require("react");
1388
1946
 
1389
1947
  // src/hooks/voiceWorklets.ts
1390
1948
  var RECORDER_WORKLET_SOURCE = `
@@ -1487,42 +2045,42 @@ function mergeTranscriptText(prev, next) {
1487
2045
  }
1488
2046
  function useVoice(options = {}) {
1489
2047
  const { defaultAgentId, fetchWithAuth, logger } = usePersonaContext();
1490
- const voiceLogger = (0, import_react5.useMemo)(() => logger.child("voice"), [logger]);
2048
+ const voiceLogger = (0, import_react6.useMemo)(() => logger.child("voice"), [logger]);
1491
2049
  const agentId = options.agentId || defaultAgentId;
1492
2050
  const threadId = options.threadId;
1493
2051
  const contextOverride = options.contextOverride;
1494
2052
  const context = options.context;
1495
- const [state, setState] = (0, import_react5.useState)("idle");
1496
- const [isMuted, setIsMuted] = (0, import_react5.useState)(false);
1497
- const [transcript, setTranscript] = (0, import_react5.useState)(
2053
+ const [state, setState] = (0, import_react6.useState)("idle");
2054
+ const [isMuted, setIsMuted] = (0, import_react6.useState)(false);
2055
+ const [transcript, setTranscript] = (0, import_react6.useState)(
1498
2056
  []
1499
2057
  );
1500
- const [partial, setPartial] = (0, import_react5.useState)(
2058
+ const [partial, setPartial] = (0, import_react6.useState)(
1501
2059
  null
1502
2060
  );
1503
- const [toolCalls, setToolCalls] = (0, import_react5.useState)([]);
1504
- const [error, setError] = (0, import_react5.useState)(null);
1505
- const [endReason, setEndReason] = (0, import_react5.useState)(
2061
+ const [toolCalls, setToolCalls] = (0, import_react6.useState)([]);
2062
+ const [error, setError] = (0, import_react6.useState)(null);
2063
+ const [endReason, setEndReason] = (0, import_react6.useState)(
1506
2064
  null
1507
2065
  );
1508
- const wsRef = (0, import_react5.useRef)(null);
1509
- const streamRef = (0, import_react5.useRef)(null);
1510
- const inputCtxRef = (0, import_react5.useRef)(null);
1511
- const outputCtxRef = (0, import_react5.useRef)(null);
1512
- const recorderNodeRef = (0, import_react5.useRef)(null);
1513
- const playerNodeRef = (0, import_react5.useRef)(null);
1514
- const acceptedTurnSeqRef = (0, import_react5.useRef)(0);
1515
- const mountedRef = (0, import_react5.useRef)(true);
1516
- const lastFinalTurnRef = (0, import_react5.useRef)(
2066
+ const wsRef = (0, import_react6.useRef)(null);
2067
+ const streamRef = (0, import_react6.useRef)(null);
2068
+ const inputCtxRef = (0, import_react6.useRef)(null);
2069
+ const outputCtxRef = (0, import_react6.useRef)(null);
2070
+ const recorderNodeRef = (0, import_react6.useRef)(null);
2071
+ const playerNodeRef = (0, import_react6.useRef)(null);
2072
+ const acceptedTurnSeqRef = (0, import_react6.useRef)(0);
2073
+ const mountedRef = (0, import_react6.useRef)(true);
2074
+ const lastFinalTurnRef = (0, import_react6.useRef)(
1517
2075
  null
1518
2076
  );
1519
- (0, import_react5.useEffect)(() => {
2077
+ (0, import_react6.useEffect)(() => {
1520
2078
  mountedRef.current = true;
1521
2079
  return () => {
1522
2080
  mountedRef.current = false;
1523
2081
  };
1524
2082
  }, []);
1525
- const teardownAudio = (0, import_react5.useCallback)(() => {
2083
+ const teardownAudio = (0, import_react6.useCallback)(() => {
1526
2084
  try {
1527
2085
  streamRef.current?.getTracks().forEach((track) => track.stop());
1528
2086
  } catch {
@@ -1549,7 +2107,7 @@ function useVoice(options = {}) {
1549
2107
  }
1550
2108
  outputCtxRef.current = null;
1551
2109
  }, []);
1552
- const stop = (0, import_react5.useCallback)(() => {
2110
+ const stop = (0, import_react6.useCallback)(() => {
1553
2111
  voiceLogger.debug("stop() called");
1554
2112
  try {
1555
2113
  wsRef.current?.close(1e3, "client_stop");
@@ -1559,8 +2117,8 @@ function useVoice(options = {}) {
1559
2117
  teardownAudio();
1560
2118
  if (mountedRef.current) setState("idle");
1561
2119
  }, [teardownAudio, voiceLogger]);
1562
- (0, import_react5.useEffect)(() => stop, [stop]);
1563
- const startCapture = (0, import_react5.useCallback)(async (inputSampleRate) => {
2120
+ (0, import_react6.useEffect)(() => stop, [stop]);
2121
+ const startCapture = (0, import_react6.useCallback)(async (inputSampleRate) => {
1564
2122
  const stream = await navigator.mediaDevices.getUserMedia({
1565
2123
  audio: {
1566
2124
  echoCancellation: true,
@@ -1586,7 +2144,7 @@ function useVoice(options = {}) {
1586
2144
  recorderNodeRef.current = recorderNode;
1587
2145
  source.connect(recorderNode);
1588
2146
  }, []);
1589
- const setupPlayback = (0, import_react5.useCallback)(async (outputSampleRate) => {
2147
+ const setupPlayback = (0, import_react6.useCallback)(async (outputSampleRate) => {
1590
2148
  const outputCtx = new AudioContext({ sampleRate: outputSampleRate });
1591
2149
  outputCtxRef.current = outputCtx;
1592
2150
  await outputCtx.audioWorklet.addModule(playerWorkletUrl());
@@ -1594,7 +2152,7 @@ function useVoice(options = {}) {
1594
2152
  playerNode.connect(outputCtx.destination);
1595
2153
  playerNodeRef.current = playerNode;
1596
2154
  }, []);
1597
- const upsertToolCall = (0, import_react5.useCallback)(
2155
+ const upsertToolCall = (0, import_react6.useCallback)(
1598
2156
  (id, patch) => {
1599
2157
  setToolCalls((prev) => {
1600
2158
  const idx = prev.findIndex((t) => t.id === id);
@@ -1606,7 +2164,7 @@ function useVoice(options = {}) {
1606
2164
  },
1607
2165
  []
1608
2166
  );
1609
- const handleTranscript = (0, import_react5.useCallback)((value) => {
2167
+ const handleTranscript = (0, import_react6.useCallback)((value) => {
1610
2168
  const { speaker, text, isFinal, turnSeq } = value;
1611
2169
  if (!isFinal) {
1612
2170
  setPartial({ id: "partial", speaker, text });
@@ -1629,7 +2187,7 @@ function useVoice(options = {}) {
1629
2187
  });
1630
2188
  lastFinalTurnRef.current = { speaker, turnSeq };
1631
2189
  }, []);
1632
- const handleCustomEvent = (0, import_react5.useCallback)(
2190
+ const handleCustomEvent = (0, import_react6.useCallback)(
1633
2191
  (name, value) => {
1634
2192
  switch (name) {
1635
2193
  case "voice_session_ready":
@@ -1687,7 +2245,7 @@ function useVoice(options = {}) {
1687
2245
  },
1688
2246
  [handleTranscript, setupPlayback, startCapture, teardownAudio, voiceLogger]
1689
2247
  );
1690
- const handleMessage = (0, import_react5.useCallback)(
2248
+ const handleMessage = (0, import_react6.useCallback)(
1691
2249
  (event) => {
1692
2250
  if (typeof event.data !== "string") {
1693
2251
  const buf = event.data;
@@ -1745,7 +2303,7 @@ function useVoice(options = {}) {
1745
2303
  },
1746
2304
  [handleCustomEvent, upsertToolCall, voiceLogger]
1747
2305
  );
1748
- const start = (0, import_react5.useCallback)(async () => {
2306
+ const start = (0, import_react6.useCallback)(async () => {
1749
2307
  if (!agentId) {
1750
2308
  const err = new Error(
1751
2309
  "useVoice: no agentId provided and no defaultAgentId set on PersonaProvider"
@@ -1812,17 +2370,17 @@ function useVoice(options = {}) {
1812
2370
  teardownAudio();
1813
2371
  }
1814
2372
  }, [agentId, threadId, contextOverride, context, fetchWithAuth, handleMessage, teardownAudio, voiceLogger]);
1815
- const mute = (0, import_react5.useCallback)((muted) => {
2373
+ const mute = (0, import_react6.useCallback)((muted) => {
1816
2374
  setIsMuted(muted);
1817
2375
  streamRef.current?.getAudioTracks().forEach((track) => {
1818
2376
  track.enabled = !muted;
1819
2377
  });
1820
2378
  }, []);
1821
- const sendText = (0, import_react5.useCallback)((text) => {
2379
+ const sendText = (0, import_react6.useCallback)((text) => {
1822
2380
  if (!text?.trim() || wsRef.current?.readyState !== WebSocket.OPEN) return;
1823
2381
  wsRef.current.send(JSON.stringify({ type: "voice.text", text }));
1824
2382
  }, []);
1825
- const updateContext = (0, import_react5.useCallback)((newContext) => {
2383
+ const updateContext = (0, import_react6.useCallback)((newContext) => {
1826
2384
  if (wsRef.current?.readyState !== WebSocket.OPEN) return;
1827
2385
  wsRef.current.send(JSON.stringify({ type: "voice.context", context: newContext }));
1828
2386
  }, []);
@@ -1843,14 +2401,14 @@ function useVoice(options = {}) {
1843
2401
  }
1844
2402
 
1845
2403
  // src/hooks/useFiles.ts
1846
- var import_react6 = require("react");
2404
+ var import_react7 = require("react");
1847
2405
  function useFiles(autoFetch = true) {
1848
2406
  const { fetchWithAuth } = usePersonaContext();
1849
- const [files, setFiles] = (0, import_react6.useState)([]);
1850
- const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
1851
- const [isUploading, setIsUploading] = (0, import_react6.useState)(false);
1852
- const [error, setError] = (0, import_react6.useState)(null);
1853
- const fetchFiles = (0, import_react6.useCallback)(async () => {
2407
+ const [files, setFiles] = (0, import_react7.useState)([]);
2408
+ const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
2409
+ const [isUploading, setIsUploading] = (0, import_react7.useState)(false);
2410
+ const [error, setError] = (0, import_react7.useState)(null);
2411
+ const fetchFiles = (0, import_react7.useCallback)(async () => {
1854
2412
  setIsLoading(true);
1855
2413
  setError(null);
1856
2414
  try {
@@ -1868,7 +2426,7 @@ function useFiles(autoFetch = true) {
1868
2426
  setIsLoading(false);
1869
2427
  }
1870
2428
  }, [fetchWithAuth]);
1871
- const uploadFile = (0, import_react6.useCallback)(
2429
+ const uploadFile = (0, import_react7.useCallback)(
1872
2430
  async (fileOrFormData) => {
1873
2431
  setIsUploading(true);
1874
2432
  setError(null);
@@ -1901,7 +2459,7 @@ function useFiles(autoFetch = true) {
1901
2459
  },
1902
2460
  [fetchWithAuth, fetchFiles]
1903
2461
  );
1904
- const deleteFile = (0, import_react6.useCallback)(
2462
+ const deleteFile = (0, import_react7.useCallback)(
1905
2463
  async (fileId) => {
1906
2464
  const res = await fetchWithAuth(`/files/${fileId}`, { method: "DELETE" });
1907
2465
  if (!res.ok) throw new Error(`Failed to delete file: ${res.statusText}`);
@@ -1909,7 +2467,7 @@ function useFiles(autoFetch = true) {
1909
2467
  },
1910
2468
  [fetchWithAuth]
1911
2469
  );
1912
- const bulkDeleteFiles = (0, import_react6.useCallback)(
2470
+ const bulkDeleteFiles = (0, import_react7.useCallback)(
1913
2471
  async (fileIds) => {
1914
2472
  const res = await fetchWithAuth("/files/bulk-delete", {
1915
2473
  method: "POST",
@@ -1924,10 +2482,10 @@ function useFiles(autoFetch = true) {
1924
2482
  },
1925
2483
  [fetchWithAuth]
1926
2484
  );
1927
- const getDownloadUrl = (0, import_react6.useCallback)((fileId) => {
2485
+ const getDownloadUrl = (0, import_react7.useCallback)((fileId) => {
1928
2486
  return `/files/${fileId}`;
1929
2487
  }, []);
1930
- (0, import_react6.useEffect)(() => {
2488
+ (0, import_react7.useEffect)(() => {
1931
2489
  if (autoFetch) {
1932
2490
  void fetchFiles();
1933
2491
  }
@@ -1946,21 +2504,39 @@ function useFiles(autoFetch = true) {
1946
2504
  }
1947
2505
 
1948
2506
  // src/hooks/useAgents.ts
1949
- var import_react7 = require("react");
1950
- function useAgents(autoFetch = true) {
2507
+ var import_react8 = require("react");
2508
+ function useAgents(options = true) {
2509
+ const opts = typeof options === "boolean" ? { autoFetch: options } : options;
2510
+ const { autoFetch = true, page, limit, search, category, scope } = opts;
1951
2511
  const { fetchWithAuth } = usePersonaContext();
1952
- const [agents, setAgents] = (0, import_react7.useState)([]);
1953
- const [isLoading, setIsLoading] = (0, import_react7.useState)(false);
1954
- const [error, setError] = (0, import_react7.useState)(null);
1955
- const fetchAgents = (0, import_react7.useCallback)(async () => {
2512
+ const [agents, setAgents] = (0, import_react8.useState)([]);
2513
+ const [pagination, setPagination] = (0, import_react8.useState)({
2514
+ total: 0,
2515
+ page: page ?? 1,
2516
+ limit: limit ?? 20,
2517
+ pages: 0
2518
+ });
2519
+ const [isLoading, setIsLoading] = (0, import_react8.useState)(false);
2520
+ const [error, setError] = (0, import_react8.useState)(null);
2521
+ const fetchAgents = (0, import_react8.useCallback)(async () => {
1956
2522
  setIsLoading(true);
1957
2523
  setError(null);
1958
2524
  try {
1959
- const res = await fetchWithAuth("/agents");
2525
+ const query = new URLSearchParams();
2526
+ if (page) query.set("page", String(page));
2527
+ if (limit) query.set("limit", String(limit));
2528
+ if (search) query.set("search", search);
2529
+ if (category) query.set("category", category);
2530
+ if (scope) query.set("scope", scope);
2531
+ const queryStr = query.toString() ? `?${query.toString()}` : "";
2532
+ const res = await fetchWithAuth(`/agents${queryStr}`);
1960
2533
  if (!res.ok) throw new Error(`Failed to list agents: ${res.statusText}`);
1961
2534
  const data = await res.json();
1962
- const items = Array.isArray(data) ? data : data?.items || data?.agents || [];
2535
+ const items = Array.isArray(data) ? data : data?.items ?? [];
1963
2536
  setAgents(items);
2537
+ setPagination(
2538
+ data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
2539
+ );
1964
2540
  return items;
1965
2541
  } catch (err) {
1966
2542
  const errorObj = err instanceof Error ? err : new Error(String(err));
@@ -1969,28 +2545,131 @@ function useAgents(autoFetch = true) {
1969
2545
  } finally {
1970
2546
  setIsLoading(false);
1971
2547
  }
1972
- }, [fetchWithAuth]);
1973
- (0, import_react7.useEffect)(() => {
1974
- if (autoFetch) {
1975
- void fetchAgents();
1976
- }
2548
+ }, [fetchWithAuth, page, limit, search, category, scope]);
2549
+ const getAgent = (0, import_react8.useCallback)(
2550
+ async (agentId) => {
2551
+ const res = await fetchWithAuth(`/agents/${agentId}`);
2552
+ if (!res.ok) throw new Error(`Failed to fetch agent: ${res.statusText}`);
2553
+ return res.json();
2554
+ },
2555
+ [fetchWithAuth]
2556
+ );
2557
+ const createAgent = (0, import_react8.useCallback)(
2558
+ async (input) => {
2559
+ setError(null);
2560
+ try {
2561
+ const res = await fetchWithAuth("/agents", {
2562
+ method: "POST",
2563
+ headers: { "Content-Type": "application/json" },
2564
+ body: JSON.stringify(input)
2565
+ });
2566
+ if (!res.ok) {
2567
+ const errText = await res.text().catch(() => res.statusText);
2568
+ throw new Error(`Failed to create agent (${res.status}): ${errText}`);
2569
+ }
2570
+ const created = await res.json();
2571
+ setAgents((prev) => [created, ...prev]);
2572
+ return created;
2573
+ } catch (err) {
2574
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2575
+ setError(errorObj);
2576
+ throw errorObj;
2577
+ }
2578
+ },
2579
+ [fetchWithAuth]
2580
+ );
2581
+ const updateAgent = (0, import_react8.useCallback)(
2582
+ async (agentId, input) => {
2583
+ setError(null);
2584
+ try {
2585
+ const res = await fetchWithAuth(`/agents/${agentId}`, {
2586
+ method: "PATCH",
2587
+ headers: { "Content-Type": "application/json" },
2588
+ body: JSON.stringify(input)
2589
+ });
2590
+ if (!res.ok) {
2591
+ const errText = await res.text().catch(() => res.statusText);
2592
+ throw new Error(`Failed to update agent (${res.status}): ${errText}`);
2593
+ }
2594
+ const updated = await res.json();
2595
+ setAgents((prev) => prev.map((a) => a._id === agentId ? updated : a));
2596
+ return updated;
2597
+ } catch (err) {
2598
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2599
+ setError(errorObj);
2600
+ throw errorObj;
2601
+ }
2602
+ },
2603
+ [fetchWithAuth]
2604
+ );
2605
+ const deleteAgent = (0, import_react8.useCallback)(
2606
+ async (agentId) => {
2607
+ setError(null);
2608
+ try {
2609
+ const res = await fetchWithAuth(`/agents/${agentId}`, { method: "DELETE" });
2610
+ if (!res.ok) {
2611
+ const errText = await res.text().catch(() => res.statusText);
2612
+ throw new Error(`Failed to delete agent (${res.status}): ${errText}`);
2613
+ }
2614
+ setAgents((prev) => prev.filter((a) => a._id !== agentId));
2615
+ } catch (err) {
2616
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2617
+ setError(errorObj);
2618
+ throw errorObj;
2619
+ }
2620
+ },
2621
+ [fetchWithAuth]
2622
+ );
2623
+ const bulkDeleteAgents = (0, import_react8.useCallback)(
2624
+ async (ids) => {
2625
+ setError(null);
2626
+ try {
2627
+ const res = await fetchWithAuth("/agents/bulk-delete", {
2628
+ method: "POST",
2629
+ headers: { "Content-Type": "application/json" },
2630
+ body: JSON.stringify({ ids })
2631
+ });
2632
+ if (!res.ok) {
2633
+ const errText = await res.text().catch(() => res.statusText);
2634
+ throw new Error(`Failed to bulk-delete agents (${res.status}): ${errText}`);
2635
+ }
2636
+ const result = await res.json();
2637
+ const deletedSet = new Set(result.deleted);
2638
+ setAgents((prev) => prev.filter((a) => !deletedSet.has(a._id)));
2639
+ return result;
2640
+ } catch (err) {
2641
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2642
+ setError(errorObj);
2643
+ throw errorObj;
2644
+ }
2645
+ },
2646
+ [fetchWithAuth]
2647
+ );
2648
+ (0, import_react8.useEffect)(() => {
2649
+ if (autoFetch) void fetchAgents();
1977
2650
  }, [autoFetch, fetchAgents]);
1978
2651
  return {
1979
2652
  agents,
2653
+ pagination,
1980
2654
  isLoading,
1981
2655
  error,
1982
- refetch: fetchAgents
2656
+ refetch: fetchAgents,
2657
+ getAgent,
2658
+ createAgent,
2659
+ updateAgent,
2660
+ deleteAgent,
2661
+ bulkDeleteAgents
1983
2662
  };
1984
2663
  }
1985
2664
 
1986
2665
  // src/hooks/useConnection.ts
1987
- var import_react8 = require("react");
2666
+ var import_react9 = require("react");
1988
2667
  function useConnection(autoCheck = true) {
1989
2668
  const { fetchWithAuth } = usePersonaContext();
1990
- const [health, setHealth] = (0, import_react8.useState)(null);
1991
- const [isConnected, setIsConnected] = (0, import_react8.useState)(false);
1992
- const [isLoading, setIsLoading] = (0, import_react8.useState)(false);
1993
- const checkHealth = (0, import_react8.useCallback)(async () => {
2669
+ const [health, setHealth] = (0, import_react9.useState)(null);
2670
+ const [isConnected, setIsConnected] = (0, import_react9.useState)(false);
2671
+ const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
2672
+ const checkHealth = (0, import_react9.useCallback)(async () => {
1994
2673
  setIsLoading(true);
1995
2674
  try {
1996
2675
  const res = await fetchWithAuth("/health");
@@ -2009,7 +2688,7 @@ function useConnection(autoCheck = true) {
2009
2688
  setIsLoading(false);
2010
2689
  }
2011
2690
  }, [fetchWithAuth]);
2012
- (0, import_react8.useEffect)(() => {
2691
+ (0, import_react9.useEffect)(() => {
2013
2692
  if (autoCheck) {
2014
2693
  void checkHealth();
2015
2694
  }
@@ -2023,15 +2702,15 @@ function useConnection(autoCheck = true) {
2023
2702
  }
2024
2703
 
2025
2704
  // src/hooks/useMcpConnections.ts
2026
- var import_react9 = require("react");
2705
+ var import_react10 = require("react");
2027
2706
  function useMcpConnections(options = {}) {
2028
2707
  const { defaultAgentId, fetchWithAuth } = usePersonaContext();
2029
2708
  const agentId = options.agentId ?? defaultAgentId;
2030
2709
  const autoFetch = options.autoFetch ?? true;
2031
- const [connections, setConnections] = (0, import_react9.useState)([]);
2032
- const [isLoading, setIsLoading] = (0, import_react9.useState)(false);
2033
- const [error, setError] = (0, import_react9.useState)(null);
2034
- const fetchConnections = (0, import_react9.useCallback)(async () => {
2710
+ const [connections, setConnections] = (0, import_react10.useState)([]);
2711
+ const [isLoading, setIsLoading] = (0, import_react10.useState)(false);
2712
+ const [error, setError] = (0, import_react10.useState)(null);
2713
+ const fetchConnections = (0, import_react10.useCallback)(async () => {
2035
2714
  if (!agentId) return [];
2036
2715
  setIsLoading(true);
2037
2716
  setError(null);
@@ -2055,7 +2734,34 @@ function useMcpConnections(options = {}) {
2055
2734
  setIsLoading(false);
2056
2735
  }
2057
2736
  }, [agentId, fetchWithAuth, options.returnTo]);
2058
- (0, import_react9.useEffect)(() => {
2737
+ const [isDisconnecting, setIsDisconnecting] = (0, import_react10.useState)(false);
2738
+ const disconnect = (0, import_react10.useCallback)(
2739
+ async (mcpId) => {
2740
+ setIsDisconnecting(true);
2741
+ setError(null);
2742
+ try {
2743
+ const res = await fetchWithAuth(`/mcps/${mcpId}/oauth/user/connection`, {
2744
+ method: "DELETE"
2745
+ });
2746
+ if (!res.ok)
2747
+ throw new Error(`Failed to disconnect MCP: ${res.statusText}`);
2748
+ setConnections(
2749
+ (prev) => prev.map(
2750
+ (c) => c.mcpId === mcpId ? { ...c, connected: false, authorizeUrl: null } : c
2751
+ )
2752
+ );
2753
+ void fetchConnections();
2754
+ } catch (err) {
2755
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2756
+ setError(errorObj);
2757
+ throw errorObj;
2758
+ } finally {
2759
+ setIsDisconnecting(false);
2760
+ }
2761
+ },
2762
+ [fetchWithAuth, fetchConnections]
2763
+ );
2764
+ (0, import_react10.useEffect)(() => {
2059
2765
  if (autoFetch) void fetchConnections();
2060
2766
  }, [autoFetch, fetchConnections]);
2061
2767
  return {
@@ -2064,16 +2770,18 @@ function useMcpConnections(options = {}) {
2064
2770
  unconnected: connections.filter((c) => !c.connected),
2065
2771
  isLoading,
2066
2772
  error,
2067
- refetch: fetchConnections
2773
+ refetch: fetchConnections,
2774
+ disconnect,
2775
+ isDisconnecting
2068
2776
  };
2069
2777
  }
2070
2778
 
2071
2779
  // src/hooks/useMcp.ts
2072
- var import_react10 = require("react");
2780
+ var import_react11 = require("react");
2073
2781
  function useMcp(options = {}) {
2074
2782
  const { fetchWithAuth } = usePersonaContext();
2075
2783
  const defaultMcpId = options.mcpId;
2076
- const readResource = (0, import_react10.useCallback)(
2784
+ const readResource = (0, import_react11.useCallback)(
2077
2785
  async (uri, mcpId) => {
2078
2786
  const id = mcpId ?? defaultMcpId;
2079
2787
  if (!id) throw new Error("MCP server ID is required to read resource");
@@ -2087,7 +2795,7 @@ function useMcp(options = {}) {
2087
2795
  },
2088
2796
  [fetchWithAuth, defaultMcpId]
2089
2797
  );
2090
- const callTool = (0, import_react10.useCallback)(
2798
+ const callTool = (0, import_react11.useCallback)(
2091
2799
  async (name, args, mcpId) => {
2092
2800
  const id = mcpId ?? defaultMcpId;
2093
2801
  if (!id) throw new Error("MCP server ID is required to call tool");
@@ -2109,22 +2817,378 @@ function useMcp(options = {}) {
2109
2817
  };
2110
2818
  }
2111
2819
 
2820
+ // src/hooks/useSkills.ts
2821
+ var import_react12 = require("react");
2822
+ function useSkills(options = {}) {
2823
+ const { autoFetch = true, page, limit, search, scope } = options;
2824
+ const { fetchWithAuth } = usePersonaContext();
2825
+ const [skills, setSkills] = (0, import_react12.useState)([]);
2826
+ const [pagination, setPagination] = (0, import_react12.useState)({
2827
+ total: 0,
2828
+ page: page ?? 1,
2829
+ limit: limit ?? 20,
2830
+ pages: 0
2831
+ });
2832
+ const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
2833
+ const [error, setError] = (0, import_react12.useState)(null);
2834
+ const fetchSkills = (0, import_react12.useCallback)(async () => {
2835
+ setIsLoading(true);
2836
+ setError(null);
2837
+ try {
2838
+ const query = new URLSearchParams();
2839
+ if (page) query.set("page", String(page));
2840
+ if (limit) query.set("limit", String(limit));
2841
+ if (search) query.set("search", search);
2842
+ if (scope) query.set("scope", scope);
2843
+ const queryStr = query.toString() ? `?${query.toString()}` : "";
2844
+ const res = await fetchWithAuth(`/skills${queryStr}`);
2845
+ if (!res.ok) throw new Error(`Failed to list skills: ${res.statusText}`);
2846
+ const data = await res.json();
2847
+ const items = Array.isArray(data) ? data : data?.items ?? [];
2848
+ setSkills(items);
2849
+ setPagination(
2850
+ data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
2851
+ );
2852
+ return items;
2853
+ } catch (err) {
2854
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2855
+ setError(errorObj);
2856
+ return [];
2857
+ } finally {
2858
+ setIsLoading(false);
2859
+ }
2860
+ }, [fetchWithAuth, page, limit, search, scope]);
2861
+ const getSkill = (0, import_react12.useCallback)(
2862
+ async (skillId) => {
2863
+ const res = await fetchWithAuth(`/skills/${skillId}`);
2864
+ if (!res.ok) throw new Error(`Failed to fetch skill: ${res.statusText}`);
2865
+ return res.json();
2866
+ },
2867
+ [fetchWithAuth]
2868
+ );
2869
+ const createSkill = (0, import_react12.useCallback)(
2870
+ async (input) => {
2871
+ setError(null);
2872
+ try {
2873
+ const res = await fetchWithAuth("/skills", {
2874
+ method: "POST",
2875
+ headers: { "Content-Type": "application/json" },
2876
+ body: JSON.stringify(input)
2877
+ });
2878
+ if (!res.ok) {
2879
+ const errText = await res.text().catch(() => res.statusText);
2880
+ throw new Error(`Failed to create skill (${res.status}): ${errText}`);
2881
+ }
2882
+ const created = await res.json();
2883
+ setSkills((prev) => [created, ...prev]);
2884
+ return created;
2885
+ } catch (err) {
2886
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2887
+ setError(errorObj);
2888
+ throw errorObj;
2889
+ }
2890
+ },
2891
+ [fetchWithAuth]
2892
+ );
2893
+ const updateSkill = (0, import_react12.useCallback)(
2894
+ async (skillId, input) => {
2895
+ setError(null);
2896
+ try {
2897
+ const res = await fetchWithAuth(`/skills/${skillId}`, {
2898
+ method: "PATCH",
2899
+ headers: { "Content-Type": "application/json" },
2900
+ body: JSON.stringify(input)
2901
+ });
2902
+ if (!res.ok) {
2903
+ const errText = await res.text().catch(() => res.statusText);
2904
+ throw new Error(`Failed to update skill (${res.status}): ${errText}`);
2905
+ }
2906
+ const updated = await res.json();
2907
+ setSkills((prev) => prev.map((s) => s._id === skillId ? updated : s));
2908
+ return updated;
2909
+ } catch (err) {
2910
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2911
+ setError(errorObj);
2912
+ throw errorObj;
2913
+ }
2914
+ },
2915
+ [fetchWithAuth]
2916
+ );
2917
+ const deleteSkill = (0, import_react12.useCallback)(
2918
+ async (skillId) => {
2919
+ setError(null);
2920
+ try {
2921
+ const res = await fetchWithAuth(`/skills/${skillId}`, { method: "DELETE" });
2922
+ if (!res.ok) {
2923
+ const errText = await res.text().catch(() => res.statusText);
2924
+ throw new Error(`Failed to delete skill (${res.status}): ${errText}`);
2925
+ }
2926
+ setSkills((prev) => prev.filter((s) => s._id !== skillId));
2927
+ } catch (err) {
2928
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2929
+ setError(errorObj);
2930
+ throw errorObj;
2931
+ }
2932
+ },
2933
+ [fetchWithAuth]
2934
+ );
2935
+ const bulkDeleteSkills = (0, import_react12.useCallback)(
2936
+ async (ids) => {
2937
+ setError(null);
2938
+ try {
2939
+ const res = await fetchWithAuth("/skills/bulk-delete", {
2940
+ method: "POST",
2941
+ headers: { "Content-Type": "application/json" },
2942
+ body: JSON.stringify({ ids })
2943
+ });
2944
+ if (!res.ok) {
2945
+ const errText = await res.text().catch(() => res.statusText);
2946
+ throw new Error(`Failed to bulk-delete skills (${res.status}): ${errText}`);
2947
+ }
2948
+ const result = await res.json();
2949
+ const deletedSet = new Set(result.deleted);
2950
+ setSkills((prev) => prev.filter((s) => !deletedSet.has(s._id)));
2951
+ return result;
2952
+ } catch (err) {
2953
+ const errorObj = err instanceof Error ? err : new Error(String(err));
2954
+ setError(errorObj);
2955
+ throw errorObj;
2956
+ }
2957
+ },
2958
+ [fetchWithAuth]
2959
+ );
2960
+ const getSkillUsage = (0, import_react12.useCallback)(
2961
+ async (skillId) => {
2962
+ const res = await fetchWithAuth(`/skills/${skillId}/usage`);
2963
+ if (!res.ok) throw new Error(`Failed to fetch skill usage: ${res.statusText}`);
2964
+ return res.json();
2965
+ },
2966
+ [fetchWithAuth]
2967
+ );
2968
+ (0, import_react12.useEffect)(() => {
2969
+ if (autoFetch) void fetchSkills();
2970
+ }, [autoFetch, fetchSkills]);
2971
+ return {
2972
+ skills,
2973
+ pagination,
2974
+ isLoading,
2975
+ error,
2976
+ refetch: fetchSkills,
2977
+ getSkill,
2978
+ createSkill,
2979
+ updateSkill,
2980
+ deleteSkill,
2981
+ bulkDeleteSkills,
2982
+ getSkillUsage
2983
+ };
2984
+ }
2985
+
2986
+ // src/hooks/useRcpSources.ts
2987
+ var import_react13 = require("react");
2988
+ function useRcpSources(options = {}) {
2989
+ const { autoFetch = true, page, limit, search } = options;
2990
+ const { fetchWithAuth } = usePersonaContext();
2991
+ const [rcpSources, setRcpSources] = (0, import_react13.useState)([]);
2992
+ const [pagination, setPagination] = (0, import_react13.useState)({
2993
+ total: 0,
2994
+ page: page ?? 1,
2995
+ limit: limit ?? 20,
2996
+ pages: 0
2997
+ });
2998
+ const [isLoading, setIsLoading] = (0, import_react13.useState)(false);
2999
+ const [error, setError] = (0, import_react13.useState)(null);
3000
+ const fetchRcpSources = (0, import_react13.useCallback)(async () => {
3001
+ setIsLoading(true);
3002
+ setError(null);
3003
+ try {
3004
+ const query = new URLSearchParams();
3005
+ if (page) query.set("page", String(page));
3006
+ if (limit) query.set("limit", String(limit));
3007
+ if (search) query.set("search", search);
3008
+ const queryStr = query.toString() ? `?${query.toString()}` : "";
3009
+ const res = await fetchWithAuth(`/rcp-sources${queryStr}`);
3010
+ if (!res.ok) throw new Error(`Failed to list RCP sources: ${res.statusText}`);
3011
+ const data = await res.json();
3012
+ const items = Array.isArray(data) ? data : data?.items ?? [];
3013
+ setRcpSources(items);
3014
+ setPagination(
3015
+ data?.pagination ?? { total: items.length, page: 1, limit: items.length, pages: 1 }
3016
+ );
3017
+ return items;
3018
+ } catch (err) {
3019
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3020
+ setError(errorObj);
3021
+ return [];
3022
+ } finally {
3023
+ setIsLoading(false);
3024
+ }
3025
+ }, [fetchWithAuth, page, limit, search]);
3026
+ const getRcpSource = (0, import_react13.useCallback)(
3027
+ async (sourceId) => {
3028
+ const res = await fetchWithAuth(`/rcp-sources/${sourceId}`);
3029
+ if (!res.ok) throw new Error(`Failed to fetch RCP source: ${res.statusText}`);
3030
+ return res.json();
3031
+ },
3032
+ [fetchWithAuth]
3033
+ );
3034
+ const createRcpSource = (0, import_react13.useCallback)(
3035
+ async (input) => {
3036
+ setError(null);
3037
+ try {
3038
+ const res = await fetchWithAuth("/rcp-sources", {
3039
+ method: "POST",
3040
+ headers: { "Content-Type": "application/json" },
3041
+ body: JSON.stringify(input)
3042
+ });
3043
+ if (!res.ok) {
3044
+ const errText = await res.text().catch(() => res.statusText);
3045
+ throw new Error(`Failed to create RCP source (${res.status}): ${errText}`);
3046
+ }
3047
+ const created = await res.json();
3048
+ setRcpSources((prev) => [created, ...prev]);
3049
+ return created;
3050
+ } catch (err) {
3051
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3052
+ setError(errorObj);
3053
+ throw errorObj;
3054
+ }
3055
+ },
3056
+ [fetchWithAuth]
3057
+ );
3058
+ const updateRcpSource = (0, import_react13.useCallback)(
3059
+ async (sourceId, input) => {
3060
+ setError(null);
3061
+ try {
3062
+ const res = await fetchWithAuth(`/rcp-sources/${sourceId}`, {
3063
+ method: "PATCH",
3064
+ headers: { "Content-Type": "application/json" },
3065
+ body: JSON.stringify(input)
3066
+ });
3067
+ if (!res.ok) {
3068
+ const errText = await res.text().catch(() => res.statusText);
3069
+ throw new Error(`Failed to update RCP source (${res.status}): ${errText}`);
3070
+ }
3071
+ const updated = await res.json();
3072
+ setRcpSources((prev) => prev.map((s) => s._id === sourceId ? updated : s));
3073
+ return updated;
3074
+ } catch (err) {
3075
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3076
+ setError(errorObj);
3077
+ throw errorObj;
3078
+ }
3079
+ },
3080
+ [fetchWithAuth]
3081
+ );
3082
+ const deleteRcpSource = (0, import_react13.useCallback)(
3083
+ async (sourceId) => {
3084
+ setError(null);
3085
+ try {
3086
+ const res = await fetchWithAuth(`/rcp-sources/${sourceId}`, { method: "DELETE" });
3087
+ if (!res.ok) {
3088
+ const errText = await res.text().catch(() => res.statusText);
3089
+ throw new Error(`Failed to delete RCP source (${res.status}): ${errText}`);
3090
+ }
3091
+ setRcpSources((prev) => prev.filter((s) => s._id !== sourceId));
3092
+ } catch (err) {
3093
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3094
+ setError(errorObj);
3095
+ throw errorObj;
3096
+ }
3097
+ },
3098
+ [fetchWithAuth]
3099
+ );
3100
+ const bulkDeleteRcpSources = (0, import_react13.useCallback)(
3101
+ async (ids) => {
3102
+ setError(null);
3103
+ try {
3104
+ const res = await fetchWithAuth("/rcp-sources/bulk-delete", {
3105
+ method: "POST",
3106
+ headers: { "Content-Type": "application/json" },
3107
+ body: JSON.stringify({ ids })
3108
+ });
3109
+ if (!res.ok) {
3110
+ const errText = await res.text().catch(() => res.statusText);
3111
+ throw new Error(`Failed to bulk-delete RCP sources (${res.status}): ${errText}`);
3112
+ }
3113
+ const result = await res.json();
3114
+ const deletedSet = new Set(result.deleted);
3115
+ setRcpSources((prev) => prev.filter((s) => !deletedSet.has(s._id)));
3116
+ return result;
3117
+ } catch (err) {
3118
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3119
+ setError(errorObj);
3120
+ throw errorObj;
3121
+ }
3122
+ },
3123
+ [fetchWithAuth]
3124
+ );
3125
+ const getRcpSourceUsage = (0, import_react13.useCallback)(
3126
+ async (sourceId) => {
3127
+ const res = await fetchWithAuth(`/rcp-sources/${sourceId}/usage`);
3128
+ if (!res.ok) throw new Error(`Failed to fetch RCP source usage: ${res.statusText}`);
3129
+ return res.json();
3130
+ },
3131
+ [fetchWithAuth]
3132
+ );
3133
+ const testRcpSourceConnection = (0, import_react13.useCallback)(
3134
+ async (sourceId) => {
3135
+ setError(null);
3136
+ try {
3137
+ const res = await fetchWithAuth(`/rcp-sources/${sourceId}/test`, { method: "POST" });
3138
+ if (!res.ok) {
3139
+ const errText = await res.text().catch(() => res.statusText);
3140
+ throw new Error(`Failed to test RCP source connection (${res.status}): ${errText}`);
3141
+ }
3142
+ const result = await res.json();
3143
+ setRcpSources(
3144
+ (prev) => prev.map(
3145
+ (s) => s._id === sourceId ? { ...s, tools: result.tools, lastTestedAt: (/* @__PURE__ */ new Date()).toISOString() } : s
3146
+ )
3147
+ );
3148
+ return result;
3149
+ } catch (err) {
3150
+ const errorObj = err instanceof Error ? err : new Error(String(err));
3151
+ setError(errorObj);
3152
+ throw errorObj;
3153
+ }
3154
+ },
3155
+ [fetchWithAuth]
3156
+ );
3157
+ (0, import_react13.useEffect)(() => {
3158
+ if (autoFetch) void fetchRcpSources();
3159
+ }, [autoFetch, fetchRcpSources]);
3160
+ return {
3161
+ rcpSources,
3162
+ pagination,
3163
+ isLoading,
3164
+ error,
3165
+ refetch: fetchRcpSources,
3166
+ getRcpSource,
3167
+ createRcpSource,
3168
+ updateRcpSource,
3169
+ deleteRcpSource,
3170
+ bulkDeleteRcpSources,
3171
+ getRcpSourceUsage,
3172
+ testRcpSourceConnection
3173
+ };
3174
+ }
3175
+
2112
3176
  // src/hooks/useWorkflows.ts
2113
- var import_react11 = require("react");
3177
+ var import_react14 = require("react");
2114
3178
  function useWorkflows(options) {
2115
3179
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
2116
3180
  const { autoFetch = true, search, status, page, limit } = opts;
2117
3181
  const { fetchWithAuth } = usePersonaContext();
2118
- const [workflows, setWorkflows] = (0, import_react11.useState)([]);
2119
- const [pagination, setPagination] = (0, import_react11.useState)({
3182
+ const [workflows, setWorkflows] = (0, import_react14.useState)([]);
3183
+ const [pagination, setPagination] = (0, import_react14.useState)({
2120
3184
  page: page ?? 1,
2121
3185
  limit: limit ?? 20,
2122
3186
  total: 0,
2123
3187
  totalPages: 0
2124
3188
  });
2125
- const [isLoading, setIsLoading] = (0, import_react11.useState)(false);
2126
- const [error, setError] = (0, import_react11.useState)(null);
2127
- const fetchWorkflows = (0, import_react11.useCallback)(async () => {
3189
+ const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
3190
+ const [error, setError] = (0, import_react14.useState)(null);
3191
+ const fetchWorkflows = (0, import_react14.useCallback)(async () => {
2128
3192
  setIsLoading(true);
2129
3193
  setError(null);
2130
3194
  try {
@@ -2146,7 +3210,10 @@ function useWorkflows(options) {
2146
3210
  page: data.pagination.page ?? 1,
2147
3211
  limit: data.pagination.limit ?? items.length,
2148
3212
  total: data.pagination.total ?? items.length,
2149
- totalPages: data.pagination.totalPages ?? 1
3213
+ // Backend's paginationEnvelope() names this field `pages`, not
3214
+ // `totalPages` — this used to always fall through to the `?? 1`
3215
+ // default.
3216
+ totalPages: data.pagination.pages ?? 1
2150
3217
  });
2151
3218
  } else {
2152
3219
  setPagination({
@@ -2165,7 +3232,7 @@ function useWorkflows(options) {
2165
3232
  setIsLoading(false);
2166
3233
  }
2167
3234
  }, [fetchWithAuth, search, status, page, limit]);
2168
- const createWorkflow = (0, import_react11.useCallback)(
3235
+ const createWorkflow = (0, import_react14.useCallback)(
2169
3236
  async (input) => {
2170
3237
  setError(null);
2171
3238
  try {
@@ -2189,7 +3256,7 @@ function useWorkflows(options) {
2189
3256
  },
2190
3257
  [fetchWithAuth]
2191
3258
  );
2192
- (0, import_react11.useEffect)(() => {
3259
+ (0, import_react14.useEffect)(() => {
2193
3260
  if (autoFetch) {
2194
3261
  void fetchWorkflows();
2195
3262
  }
@@ -2205,17 +3272,17 @@ function useWorkflows(options) {
2205
3272
  }
2206
3273
 
2207
3274
  // src/hooks/useWorkflow.ts
2208
- var import_react12 = require("react");
3275
+ var import_react15 = require("react");
2209
3276
  function useWorkflow(workflowId, options) {
2210
3277
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
2211
3278
  const { autoFetch = true } = opts;
2212
3279
  const { fetchWithAuth } = usePersonaContext();
2213
- const [workflow, setWorkflow] = (0, import_react12.useState)(null);
2214
- const [versions, setVersions] = (0, import_react12.useState)([]);
2215
- const [mermaid, setMermaid] = (0, import_react12.useState)(null);
2216
- const [isLoading, setIsLoading] = (0, import_react12.useState)(false);
2217
- const [error, setError] = (0, import_react12.useState)(null);
2218
- const fetchWorkflow = (0, import_react12.useCallback)(async () => {
3280
+ const [workflow, setWorkflow] = (0, import_react15.useState)(null);
3281
+ const [versions, setVersions] = (0, import_react15.useState)([]);
3282
+ const [mermaid, setMermaid] = (0, import_react15.useState)(null);
3283
+ const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
3284
+ const [error, setError] = (0, import_react15.useState)(null);
3285
+ const fetchWorkflow = (0, import_react15.useCallback)(async () => {
2219
3286
  if (!workflowId) return null;
2220
3287
  setIsLoading(true);
2221
3288
  setError(null);
@@ -2235,7 +3302,7 @@ function useWorkflow(workflowId, options) {
2235
3302
  setIsLoading(false);
2236
3303
  }
2237
3304
  }, [fetchWithAuth, workflowId]);
2238
- const fetchVersions = (0, import_react12.useCallback)(async () => {
3305
+ const fetchVersions = (0, import_react15.useCallback)(async () => {
2239
3306
  if (!workflowId) return [];
2240
3307
  try {
2241
3308
  const res = await fetchWithAuth(`/workflows/${workflowId}/versions`);
@@ -2248,7 +3315,7 @@ function useWorkflow(workflowId, options) {
2248
3315
  return [];
2249
3316
  }
2250
3317
  }, [fetchWithAuth, workflowId]);
2251
- const fetchMermaid = (0, import_react12.useCallback)(async () => {
3318
+ const fetchMermaid = (0, import_react15.useCallback)(async () => {
2252
3319
  if (!workflowId) return "";
2253
3320
  try {
2254
3321
  const res = await fetchWithAuth(`/workflows/${workflowId}/mermaid`);
@@ -2261,7 +3328,7 @@ function useWorkflow(workflowId, options) {
2261
3328
  return "";
2262
3329
  }
2263
3330
  }, [fetchWithAuth, workflowId]);
2264
- const saveDraft = (0, import_react12.useCallback)(
3331
+ const saveDraft = (0, import_react15.useCallback)(
2265
3332
  async (draft) => {
2266
3333
  if (!workflowId) throw new Error("Workflow ID is required");
2267
3334
  setError(null);
@@ -2280,7 +3347,7 @@ function useWorkflow(workflowId, options) {
2280
3347
  },
2281
3348
  [fetchWithAuth, workflowId]
2282
3349
  );
2283
- const publish = (0, import_react12.useCallback)(
3350
+ const publish = (0, import_react15.useCallback)(
2284
3351
  async (summary) => {
2285
3352
  if (!workflowId) throw new Error("Workflow ID is required");
2286
3353
  setError(null);
@@ -2300,7 +3367,7 @@ function useWorkflow(workflowId, options) {
2300
3367
  },
2301
3368
  [fetchWithAuth, workflowId, fetchWorkflow, fetchVersions]
2302
3369
  );
2303
- const deleteWorkflow = (0, import_react12.useCallback)(async () => {
3370
+ const deleteWorkflow = (0, import_react15.useCallback)(async () => {
2304
3371
  if (!workflowId) throw new Error("Workflow ID is required");
2305
3372
  setError(null);
2306
3373
  const res = await fetchWithAuth(`/workflows/${workflowId}`, {
@@ -2311,7 +3378,7 @@ function useWorkflow(workflowId, options) {
2311
3378
  }
2312
3379
  setWorkflow(null);
2313
3380
  }, [fetchWithAuth, workflowId]);
2314
- (0, import_react12.useEffect)(() => {
3381
+ (0, import_react15.useEffect)(() => {
2315
3382
  if (autoFetch && workflowId) {
2316
3383
  void fetchWorkflow();
2317
3384
  }
@@ -2332,25 +3399,25 @@ function useWorkflow(workflowId, options) {
2332
3399
  }
2333
3400
 
2334
3401
  // src/hooks/useWorkflowStream.ts
2335
- var import_react13 = require("react");
3402
+ var import_react16 = require("react");
2336
3403
  function useWorkflowStream(workflowId, options) {
2337
3404
  const { baseUrl, getAuthToken, fetchWithAuth, logger } = usePersonaContext();
2338
- const [status, setStatus] = (0, import_react13.useState)("idle");
2339
- const [runId, setRunId] = (0, import_react13.useState)(null);
2340
- const [activeNodeId, setActiveNodeId] = (0, import_react13.useState)(null);
2341
- const [nodeRuns, setNodeRuns] = (0, import_react13.useState)(
3405
+ const [status, setStatus] = (0, import_react16.useState)("idle");
3406
+ const [runId, setRunId] = (0, import_react16.useState)(null);
3407
+ const [activeNodeId, setActiveNodeId] = (0, import_react16.useState)(null);
3408
+ const [nodeRuns, setNodeRuns] = (0, import_react16.useState)(
2342
3409
  {}
2343
3410
  );
2344
- const [text, setText] = (0, import_react13.useState)("");
2345
- const [output, setOutput] = (0, import_react13.useState)(null);
2346
- const [error, setError] = (0, import_react13.useState)(null);
2347
- const [events, setEvents] = (0, import_react13.useState)([]);
2348
- const abortControllerRef = (0, import_react13.useRef)(null);
2349
- const currentRunIdRef = (0, import_react13.useRef)(null);
3411
+ const [text, setText] = (0, import_react16.useState)("");
3412
+ const [output, setOutput] = (0, import_react16.useState)(null);
3413
+ const [error, setError] = (0, import_react16.useState)(null);
3414
+ const [events, setEvents] = (0, import_react16.useState)([]);
3415
+ const abortControllerRef = (0, import_react16.useRef)(null);
3416
+ const currentRunIdRef = (0, import_react16.useRef)(null);
2350
3417
  currentRunIdRef.current = runId;
2351
- const optionsRef = (0, import_react13.useRef)(options);
3418
+ const optionsRef = (0, import_react16.useRef)(options);
2352
3419
  optionsRef.current = options;
2353
- const cancel = (0, import_react13.useCallback)(async () => {
3420
+ const cancel = (0, import_react16.useCallback)(async () => {
2354
3421
  if (abortControllerRef.current) {
2355
3422
  abortControllerRef.current.abort();
2356
3423
  abortControllerRef.current = null;
@@ -2371,7 +3438,7 @@ function useWorkflowStream(workflowId, options) {
2371
3438
  setStatus("cancelled");
2372
3439
  setActiveNodeId(null);
2373
3440
  }, [fetchWithAuth, logger]);
2374
- const reset = (0, import_react13.useCallback)(() => {
3441
+ const reset = (0, import_react16.useCallback)(() => {
2375
3442
  if (abortControllerRef.current) {
2376
3443
  abortControllerRef.current.abort();
2377
3444
  abortControllerRef.current = null;
@@ -2385,7 +3452,7 @@ function useWorkflowStream(workflowId, options) {
2385
3452
  setError(null);
2386
3453
  setEvents([]);
2387
3454
  }, []);
2388
- const processStream = (0, import_react13.useCallback)(
3455
+ const processStream = (0, import_react16.useCallback)(
2389
3456
  async (url, method, body, targetRunId) => {
2390
3457
  if (abortControllerRef.current) {
2391
3458
  abortControllerRef.current.abort();
@@ -2550,7 +3617,7 @@ function useWorkflowStream(workflowId, options) {
2550
3617
  },
2551
3618
  [getAuthToken]
2552
3619
  );
2553
- const start = (0, import_react13.useCallback)(
3620
+ const start = (0, import_react16.useCallback)(
2554
3621
  async (input, opts) => {
2555
3622
  const targetWfId = opts?.workflowId || workflowId;
2556
3623
  if (!targetWfId) {
@@ -2571,7 +3638,7 @@ function useWorkflowStream(workflowId, options) {
2571
3638
  },
2572
3639
  [workflowId, baseUrl, processStream]
2573
3640
  );
2574
- const resume = (0, import_react13.useCallback)(
3641
+ const resume = (0, import_react16.useCallback)(
2575
3642
  async (targetRunId, sinceSeq) => {
2576
3643
  if (!targetRunId) {
2577
3644
  throw new Error("Run ID is required to resume stream");
@@ -2584,7 +3651,7 @@ function useWorkflowStream(workflowId, options) {
2584
3651
  },
2585
3652
  [baseUrl, processStream]
2586
3653
  );
2587
- (0, import_react13.useEffect)(() => {
3654
+ (0, import_react16.useEffect)(() => {
2588
3655
  return () => {
2589
3656
  if (abortControllerRef.current) {
2590
3657
  abortControllerRef.current.abort();
@@ -2609,21 +3676,21 @@ function useWorkflowStream(workflowId, options) {
2609
3676
  }
2610
3677
 
2611
3678
  // src/hooks/useWorkflowRuns.ts
2612
- var import_react14 = require("react");
3679
+ var import_react17 = require("react");
2613
3680
  function useWorkflowRuns(workflowId, options) {
2614
3681
  const opts = typeof options === "boolean" ? { autoFetch: options } : options ?? {};
2615
3682
  const { autoFetch = true, page = 1, limit = 20 } = opts;
2616
3683
  const { fetchWithAuth } = usePersonaContext();
2617
- const [runs, setRuns] = (0, import_react14.useState)([]);
2618
- const [pagination, setPagination] = (0, import_react14.useState)({
3684
+ const [runs, setRuns] = (0, import_react17.useState)([]);
3685
+ const [pagination, setPagination] = (0, import_react17.useState)({
2619
3686
  page,
2620
3687
  limit,
2621
3688
  total: 0,
2622
3689
  totalPages: 0
2623
3690
  });
2624
- const [isLoading, setIsLoading] = (0, import_react14.useState)(false);
2625
- const [error, setError] = (0, import_react14.useState)(null);
2626
- const fetchRuns = (0, import_react14.useCallback)(async () => {
3691
+ const [isLoading, setIsLoading] = (0, import_react17.useState)(false);
3692
+ const [error, setError] = (0, import_react17.useState)(null);
3693
+ const fetchRuns = (0, import_react17.useCallback)(async () => {
2627
3694
  if (!workflowId) return [];
2628
3695
  setIsLoading(true);
2629
3696
  setError(null);
@@ -2653,7 +3720,7 @@ function useWorkflowRuns(workflowId, options) {
2653
3720
  setIsLoading(false);
2654
3721
  }
2655
3722
  }, [fetchWithAuth, workflowId, page, limit]);
2656
- const getRun = (0, import_react14.useCallback)(
3723
+ const getRun = (0, import_react17.useCallback)(
2657
3724
  async (runId) => {
2658
3725
  if (!runId) throw new Error("Run ID is required");
2659
3726
  const res = await fetchWithAuth(`/workflows/runs/${runId}`);
@@ -2664,7 +3731,7 @@ function useWorkflowRuns(workflowId, options) {
2664
3731
  },
2665
3732
  [fetchWithAuth]
2666
3733
  );
2667
- const cancelRun = (0, import_react14.useCallback)(
3734
+ const cancelRun = (0, import_react17.useCallback)(
2668
3735
  async (runId) => {
2669
3736
  if (!runId) throw new Error("Run ID is required");
2670
3737
  const res = await fetchWithAuth(`/workflows/runs/${runId}/cancel`, {
@@ -2679,7 +3746,7 @@ function useWorkflowRuns(workflowId, options) {
2679
3746
  },
2680
3747
  [fetchWithAuth]
2681
3748
  );
2682
- (0, import_react14.useEffect)(() => {
3749
+ (0, import_react17.useEffect)(() => {
2683
3750
  if (autoFetch && workflowId) {
2684
3751
  void fetchRuns();
2685
3752
  }
@@ -2697,9 +3764,10 @@ function useWorkflowRuns(workflowId, options) {
2697
3764
 
2698
3765
  // src/index.ts
2699
3766
  var import_logger2 = require("@personaai/logger");
2700
- var VERSION = "0.9.0";
3767
+ var VERSION = "0.10.0";
2701
3768
  // Annotate the CommonJS export names for ESM import in node:
2702
3769
  0 && (module.exports = {
3770
+ ARCHITECT_AGENT_ID,
2703
3771
  PersonaProvider,
2704
3772
  VERSION,
2705
3773
  createLogger,
@@ -2710,6 +3778,7 @@ var VERSION = "0.9.0";
2710
3778
  setLogLevel,
2711
3779
  supportsStreamingFetch,
2712
3780
  useAgents,
3781
+ useArchitectChat,
2713
3782
  useChat,
2714
3783
  useConnection,
2715
3784
  useFiles,
@@ -2717,6 +3786,8 @@ var VERSION = "0.9.0";
2717
3786
  useMcpConnections,
2718
3787
  useMemory,
2719
3788
  usePersonaContext,
3789
+ useRcpSources,
3790
+ useSkills,
2720
3791
  useThreads,
2721
3792
  useVoice,
2722
3793
  useWorkflow,