@personaai/react 0.5.4 → 0.7.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/README.md +34 -9
- package/dist/index.cjs +473 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +67 -2
- package/dist/index.d.ts +67 -2
- package/dist/index.js +471 -31
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1165,6 +1165,21 @@ function useThreads(autoFetch = true) {
|
|
|
1165
1165
|
(threadId, title) => updateThread(threadId, { title }),
|
|
1166
1166
|
[updateThread]
|
|
1167
1167
|
);
|
|
1168
|
+
const resetThread = useCallback3(
|
|
1169
|
+
async (threadId) => {
|
|
1170
|
+
const res = await fetchWithAuth(`/threads/${threadId}/reset`, {
|
|
1171
|
+
method: "POST"
|
|
1172
|
+
});
|
|
1173
|
+
if (!res.ok) throw new Error(`Failed to reset thread: ${res.statusText}`);
|
|
1174
|
+
const data = await res.json();
|
|
1175
|
+
const reset = data?.data ?? data;
|
|
1176
|
+
setThreads(
|
|
1177
|
+
(prev) => prev.map((t) => t._id === threadId ? { ...t, ...reset } : t)
|
|
1178
|
+
);
|
|
1179
|
+
return reset;
|
|
1180
|
+
},
|
|
1181
|
+
[fetchWithAuth]
|
|
1182
|
+
);
|
|
1168
1183
|
const getThread = useCallback3(
|
|
1169
1184
|
async (threadId) => {
|
|
1170
1185
|
const res = await fetchWithAuth(`/threads/${threadId}`);
|
|
@@ -1190,19 +1205,443 @@ function useThreads(autoFetch = true) {
|
|
|
1190
1205
|
deleteAllThreads,
|
|
1191
1206
|
updateThread,
|
|
1192
1207
|
renameThread,
|
|
1208
|
+
resetThread,
|
|
1193
1209
|
getThread
|
|
1194
1210
|
};
|
|
1195
1211
|
}
|
|
1196
1212
|
|
|
1213
|
+
// src/hooks/useVoice.ts
|
|
1214
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
|
|
1215
|
+
|
|
1216
|
+
// src/hooks/voiceWorklets.ts
|
|
1217
|
+
var RECORDER_WORKLET_SOURCE = `
|
|
1218
|
+
class PCMRecorderProcessor extends AudioWorkletProcessor {
|
|
1219
|
+
constructor() {
|
|
1220
|
+
super();
|
|
1221
|
+
this._buffer = [];
|
|
1222
|
+
this._chunkSamples = 320; // 20ms @ 16kHz
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
process(inputs) {
|
|
1226
|
+
const input = inputs[0];
|
|
1227
|
+
const channel = input && input[0];
|
|
1228
|
+
if (channel) {
|
|
1229
|
+
for (let i = 0; i < channel.length; i++) {
|
|
1230
|
+
this._buffer.push(channel[i]);
|
|
1231
|
+
}
|
|
1232
|
+
while (this._buffer.length >= this._chunkSamples) {
|
|
1233
|
+
const chunk = this._buffer.splice(0, this._chunkSamples);
|
|
1234
|
+
const int16 = new Int16Array(chunk.length);
|
|
1235
|
+
for (let i = 0; i < chunk.length; i++) {
|
|
1236
|
+
const s = Math.max(-1, Math.min(1, chunk[i]));
|
|
1237
|
+
int16[i] = s < 0 ? s * 0x8000 : s * 0x7fff;
|
|
1238
|
+
}
|
|
1239
|
+
this.port.postMessage(int16.buffer, [int16.buffer]);
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
return true;
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
registerProcessor('pcm-recorder-processor', PCMRecorderProcessor);
|
|
1247
|
+
`;
|
|
1248
|
+
var PLAYER_WORKLET_SOURCE = `
|
|
1249
|
+
class PCMPlayerProcessor extends AudioWorkletProcessor {
|
|
1250
|
+
constructor() {
|
|
1251
|
+
super();
|
|
1252
|
+
this._queue = [];
|
|
1253
|
+
this._readOffset = 0;
|
|
1254
|
+
this.port.onmessage = (event) => {
|
|
1255
|
+
const msg = event.data;
|
|
1256
|
+
if (msg && msg.type === 'flush') {
|
|
1257
|
+
this._queue = [];
|
|
1258
|
+
this._readOffset = 0;
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
const int16 = new Int16Array(msg);
|
|
1262
|
+
const float32 = new Float32Array(int16.length);
|
|
1263
|
+
for (let i = 0; i < int16.length; i++) {
|
|
1264
|
+
float32[i] = int16[i] / 0x8000;
|
|
1265
|
+
}
|
|
1266
|
+
this._queue.push(float32);
|
|
1267
|
+
};
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
process(_inputs, outputs) {
|
|
1271
|
+
const output = outputs[0][0];
|
|
1272
|
+
let outIdx = 0;
|
|
1273
|
+
while (outIdx < output.length) {
|
|
1274
|
+
if (this._queue.length === 0) {
|
|
1275
|
+
output[outIdx++] = 0;
|
|
1276
|
+
continue;
|
|
1277
|
+
}
|
|
1278
|
+
const current = this._queue[0];
|
|
1279
|
+
const remaining = current.length - this._readOffset;
|
|
1280
|
+
const toCopy = Math.min(remaining, output.length - outIdx);
|
|
1281
|
+
output.set(current.subarray(this._readOffset, this._readOffset + toCopy), outIdx);
|
|
1282
|
+
outIdx += toCopy;
|
|
1283
|
+
this._readOffset += toCopy;
|
|
1284
|
+
if (this._readOffset >= current.length) {
|
|
1285
|
+
this._queue.shift();
|
|
1286
|
+
this._readOffset = 0;
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
return true;
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
registerProcessor('pcm-player-processor', PCMPlayerProcessor);
|
|
1294
|
+
`;
|
|
1295
|
+
function toModuleUrl(source) {
|
|
1296
|
+
const blob = new Blob([source], { type: "application/javascript" });
|
|
1297
|
+
return URL.createObjectURL(blob);
|
|
1298
|
+
}
|
|
1299
|
+
function recorderWorkletUrl() {
|
|
1300
|
+
return toModuleUrl(RECORDER_WORKLET_SOURCE);
|
|
1301
|
+
}
|
|
1302
|
+
function playerWorkletUrl() {
|
|
1303
|
+
return toModuleUrl(PLAYER_WORKLET_SOURCE);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
// src/hooks/useVoice.ts
|
|
1307
|
+
function useVoice(options = {}) {
|
|
1308
|
+
const { defaultAgentId, fetchWithAuth, logger } = usePersonaContext();
|
|
1309
|
+
const voiceLogger = useMemo3(() => logger.child("voice"), [logger]);
|
|
1310
|
+
const agentId = options.agentId || defaultAgentId;
|
|
1311
|
+
const [state, setState] = useState4("idle");
|
|
1312
|
+
const [isMuted, setIsMuted] = useState4(false);
|
|
1313
|
+
const [transcript, setTranscript] = useState4(
|
|
1314
|
+
[]
|
|
1315
|
+
);
|
|
1316
|
+
const [partial, setPartial] = useState4(
|
|
1317
|
+
null
|
|
1318
|
+
);
|
|
1319
|
+
const [toolCalls, setToolCalls] = useState4([]);
|
|
1320
|
+
const [error, setError] = useState4(null);
|
|
1321
|
+
const [endReason, setEndReason] = useState4(
|
|
1322
|
+
null
|
|
1323
|
+
);
|
|
1324
|
+
const wsRef = useRef2(null);
|
|
1325
|
+
const streamRef = useRef2(null);
|
|
1326
|
+
const inputCtxRef = useRef2(null);
|
|
1327
|
+
const outputCtxRef = useRef2(null);
|
|
1328
|
+
const recorderNodeRef = useRef2(null);
|
|
1329
|
+
const playerNodeRef = useRef2(null);
|
|
1330
|
+
const acceptedTurnSeqRef = useRef2(0);
|
|
1331
|
+
const mountedRef = useRef2(true);
|
|
1332
|
+
useEffect4(() => {
|
|
1333
|
+
mountedRef.current = true;
|
|
1334
|
+
return () => {
|
|
1335
|
+
mountedRef.current = false;
|
|
1336
|
+
};
|
|
1337
|
+
}, []);
|
|
1338
|
+
const teardownAudio = useCallback4(() => {
|
|
1339
|
+
try {
|
|
1340
|
+
streamRef.current?.getTracks().forEach((track) => track.stop());
|
|
1341
|
+
} catch {
|
|
1342
|
+
}
|
|
1343
|
+
streamRef.current = null;
|
|
1344
|
+
try {
|
|
1345
|
+
recorderNodeRef.current?.disconnect();
|
|
1346
|
+
} catch {
|
|
1347
|
+
}
|
|
1348
|
+
recorderNodeRef.current = null;
|
|
1349
|
+
try {
|
|
1350
|
+
playerNodeRef.current?.disconnect();
|
|
1351
|
+
} catch {
|
|
1352
|
+
}
|
|
1353
|
+
playerNodeRef.current = null;
|
|
1354
|
+
try {
|
|
1355
|
+
void inputCtxRef.current?.close();
|
|
1356
|
+
} catch {
|
|
1357
|
+
}
|
|
1358
|
+
inputCtxRef.current = null;
|
|
1359
|
+
try {
|
|
1360
|
+
void outputCtxRef.current?.close();
|
|
1361
|
+
} catch {
|
|
1362
|
+
}
|
|
1363
|
+
outputCtxRef.current = null;
|
|
1364
|
+
}, []);
|
|
1365
|
+
const stop = useCallback4(() => {
|
|
1366
|
+
voiceLogger.debug("stop() called");
|
|
1367
|
+
try {
|
|
1368
|
+
wsRef.current?.close(1e3, "client_stop");
|
|
1369
|
+
} catch {
|
|
1370
|
+
}
|
|
1371
|
+
wsRef.current = null;
|
|
1372
|
+
teardownAudio();
|
|
1373
|
+
if (mountedRef.current) setState("idle");
|
|
1374
|
+
}, [teardownAudio, voiceLogger]);
|
|
1375
|
+
useEffect4(() => stop, [stop]);
|
|
1376
|
+
const startCapture = useCallback4(async (inputSampleRate) => {
|
|
1377
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
1378
|
+
audio: {
|
|
1379
|
+
echoCancellation: true,
|
|
1380
|
+
noiseSuppression: true,
|
|
1381
|
+
autoGainControl: true,
|
|
1382
|
+
channelCount: 1
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1385
|
+
streamRef.current = stream;
|
|
1386
|
+
const inputCtx = new AudioContext({ sampleRate: inputSampleRate });
|
|
1387
|
+
inputCtxRef.current = inputCtx;
|
|
1388
|
+
await inputCtx.audioWorklet.addModule(recorderWorkletUrl());
|
|
1389
|
+
const source = inputCtx.createMediaStreamSource(stream);
|
|
1390
|
+
const recorderNode = new AudioWorkletNode(
|
|
1391
|
+
inputCtx,
|
|
1392
|
+
"pcm-recorder-processor"
|
|
1393
|
+
);
|
|
1394
|
+
recorderNode.port.onmessage = (event) => {
|
|
1395
|
+
if (wsRef.current?.readyState === WebSocket.OPEN) {
|
|
1396
|
+
wsRef.current.send(event.data);
|
|
1397
|
+
}
|
|
1398
|
+
};
|
|
1399
|
+
recorderNodeRef.current = recorderNode;
|
|
1400
|
+
source.connect(recorderNode);
|
|
1401
|
+
}, []);
|
|
1402
|
+
const setupPlayback = useCallback4(async (outputSampleRate) => {
|
|
1403
|
+
const outputCtx = new AudioContext({ sampleRate: outputSampleRate });
|
|
1404
|
+
outputCtxRef.current = outputCtx;
|
|
1405
|
+
await outputCtx.audioWorklet.addModule(playerWorkletUrl());
|
|
1406
|
+
const playerNode = new AudioWorkletNode(outputCtx, "pcm-player-processor");
|
|
1407
|
+
playerNode.connect(outputCtx.destination);
|
|
1408
|
+
playerNodeRef.current = playerNode;
|
|
1409
|
+
}, []);
|
|
1410
|
+
const upsertToolCall = useCallback4(
|
|
1411
|
+
(id, patch) => {
|
|
1412
|
+
setToolCalls((prev) => {
|
|
1413
|
+
const idx = prev.findIndex((t) => t.id === id);
|
|
1414
|
+
if (idx === -1)
|
|
1415
|
+
return [...prev, { id, status: "running", ...patch }];
|
|
1416
|
+
const next = [...prev];
|
|
1417
|
+
next[idx] = { ...next[idx], ...patch };
|
|
1418
|
+
return next;
|
|
1419
|
+
});
|
|
1420
|
+
},
|
|
1421
|
+
[]
|
|
1422
|
+
);
|
|
1423
|
+
const handleTranscript = useCallback4(
|
|
1424
|
+
(value) => {
|
|
1425
|
+
const { speaker, text, isFinal } = value;
|
|
1426
|
+
if (isFinal) {
|
|
1427
|
+
setPartial((prev) => prev?.speaker === speaker ? null : prev);
|
|
1428
|
+
setTranscript((prev) => [
|
|
1429
|
+
...prev,
|
|
1430
|
+
{ id: `${speaker}-${prev.length}`, speaker, text }
|
|
1431
|
+
]);
|
|
1432
|
+
} else {
|
|
1433
|
+
setPartial({ id: "partial", speaker, text });
|
|
1434
|
+
}
|
|
1435
|
+
},
|
|
1436
|
+
[]
|
|
1437
|
+
);
|
|
1438
|
+
const handleCustomEvent = useCallback4(
|
|
1439
|
+
(name, value) => {
|
|
1440
|
+
switch (name) {
|
|
1441
|
+
case "voice_session_ready":
|
|
1442
|
+
voiceLogger.debug("voice_session_ready", value);
|
|
1443
|
+
Promise.all([
|
|
1444
|
+
setupPlayback(value.outputSampleRate),
|
|
1445
|
+
startCapture(value.inputSampleRate)
|
|
1446
|
+
]).then(() => {
|
|
1447
|
+
if (mountedRef.current) setState("listening");
|
|
1448
|
+
}).catch((err) => {
|
|
1449
|
+
voiceLogger.error("audio graph setup failed", {
|
|
1450
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1451
|
+
});
|
|
1452
|
+
if (mountedRef.current) {
|
|
1453
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1454
|
+
setState("error");
|
|
1455
|
+
}
|
|
1456
|
+
});
|
|
1457
|
+
break;
|
|
1458
|
+
case "voice_activity":
|
|
1459
|
+
if (value.speaker === "user" && value.state === "start") {
|
|
1460
|
+
setState("listening");
|
|
1461
|
+
} else if (value.speaker === "user" && value.state === "end") {
|
|
1462
|
+
setState("thinking");
|
|
1463
|
+
} else if (value.speaker === "agent" && value.state === "start") {
|
|
1464
|
+
setState("speaking");
|
|
1465
|
+
} else if (value.speaker === "agent" && value.state === "end") {
|
|
1466
|
+
setState("listening");
|
|
1467
|
+
}
|
|
1468
|
+
break;
|
|
1469
|
+
case "voice_transcript":
|
|
1470
|
+
handleTranscript(
|
|
1471
|
+
value
|
|
1472
|
+
);
|
|
1473
|
+
break;
|
|
1474
|
+
case "voice_interrupted":
|
|
1475
|
+
acceptedTurnSeqRef.current = value.turnSeq;
|
|
1476
|
+
playerNodeRef.current?.port.postMessage({ type: "flush" });
|
|
1477
|
+
break;
|
|
1478
|
+
case "voice_session_resumed":
|
|
1479
|
+
voiceLogger.info("session transparently resumed");
|
|
1480
|
+
break;
|
|
1481
|
+
case "voice_session_ended":
|
|
1482
|
+
voiceLogger.info("session ended", { reason: value.reason });
|
|
1483
|
+
setState("ended");
|
|
1484
|
+
setEndReason(value.reason ?? null);
|
|
1485
|
+
teardownAudio();
|
|
1486
|
+
try {
|
|
1487
|
+
wsRef.current?.close();
|
|
1488
|
+
} catch {
|
|
1489
|
+
}
|
|
1490
|
+
wsRef.current = null;
|
|
1491
|
+
break;
|
|
1492
|
+
default:
|
|
1493
|
+
break;
|
|
1494
|
+
}
|
|
1495
|
+
},
|
|
1496
|
+
[handleTranscript, setupPlayback, startCapture, teardownAudio, voiceLogger]
|
|
1497
|
+
);
|
|
1498
|
+
const handleMessage = useCallback4(
|
|
1499
|
+
(event) => {
|
|
1500
|
+
if (typeof event.data !== "string") {
|
|
1501
|
+
const buf = event.data;
|
|
1502
|
+
const view = new DataView(buf);
|
|
1503
|
+
const turnSeq = view.getUint32(0, true);
|
|
1504
|
+
if (turnSeq >= acceptedTurnSeqRef.current) {
|
|
1505
|
+
acceptedTurnSeqRef.current = turnSeq;
|
|
1506
|
+
const pcmBytes = buf.slice(4);
|
|
1507
|
+
playerNodeRef.current?.port.postMessage(pcmBytes, [pcmBytes]);
|
|
1508
|
+
}
|
|
1509
|
+
return;
|
|
1510
|
+
}
|
|
1511
|
+
let msg;
|
|
1512
|
+
try {
|
|
1513
|
+
msg = JSON.parse(event.data);
|
|
1514
|
+
} catch {
|
|
1515
|
+
return;
|
|
1516
|
+
}
|
|
1517
|
+
switch (msg.type) {
|
|
1518
|
+
case "CUSTOM":
|
|
1519
|
+
handleCustomEvent(
|
|
1520
|
+
msg.name,
|
|
1521
|
+
msg.value
|
|
1522
|
+
);
|
|
1523
|
+
break;
|
|
1524
|
+
case "TOOL_CALL_CHUNK":
|
|
1525
|
+
upsertToolCall(msg.toolCallId, {
|
|
1526
|
+
name: msg.toolCallName,
|
|
1527
|
+
status: "running"
|
|
1528
|
+
});
|
|
1529
|
+
break;
|
|
1530
|
+
case "TOOL_CALL_RESULT": {
|
|
1531
|
+
let parsed = null;
|
|
1532
|
+
try {
|
|
1533
|
+
parsed = JSON.parse(msg.content);
|
|
1534
|
+
} catch {
|
|
1535
|
+
parsed = { output: msg.content };
|
|
1536
|
+
}
|
|
1537
|
+
upsertToolCall(msg.toolCallId, {
|
|
1538
|
+
status: parsed?.error ? "error" : "done",
|
|
1539
|
+
summary: parsed?.error || (typeof parsed?.output === "string" ? parsed.output : JSON.stringify(parsed?.output ?? ""))
|
|
1540
|
+
});
|
|
1541
|
+
break;
|
|
1542
|
+
}
|
|
1543
|
+
case "RUN_ERROR":
|
|
1544
|
+
voiceLogger.warn("RUN_ERROR", { message: msg.message });
|
|
1545
|
+
setError(new Error(msg.message || "The agent run failed."));
|
|
1546
|
+
setState("error");
|
|
1547
|
+
break;
|
|
1548
|
+
default:
|
|
1549
|
+
break;
|
|
1550
|
+
}
|
|
1551
|
+
},
|
|
1552
|
+
[handleCustomEvent, upsertToolCall, voiceLogger]
|
|
1553
|
+
);
|
|
1554
|
+
const start = useCallback4(async () => {
|
|
1555
|
+
if (!agentId) {
|
|
1556
|
+
const err = new Error(
|
|
1557
|
+
"useVoice: no agentId provided and no defaultAgentId set on PersonaProvider"
|
|
1558
|
+
);
|
|
1559
|
+
setError(err);
|
|
1560
|
+
setState("error");
|
|
1561
|
+
return;
|
|
1562
|
+
}
|
|
1563
|
+
setError(null);
|
|
1564
|
+
setEndReason(null);
|
|
1565
|
+
setTranscript([]);
|
|
1566
|
+
setPartial(null);
|
|
1567
|
+
setToolCalls([]);
|
|
1568
|
+
acceptedTurnSeqRef.current = 0;
|
|
1569
|
+
setState("connecting");
|
|
1570
|
+
voiceLogger.debug("start() called", { agentId });
|
|
1571
|
+
try {
|
|
1572
|
+
const res = await fetchWithAuth("/voice/sessions", {
|
|
1573
|
+
method: "POST",
|
|
1574
|
+
headers: { "Content-Type": "application/json" },
|
|
1575
|
+
body: JSON.stringify({ agentId })
|
|
1576
|
+
});
|
|
1577
|
+
if (!res.ok) {
|
|
1578
|
+
throw new Error(`Failed to start voice session: ${res.statusText}`);
|
|
1579
|
+
}
|
|
1580
|
+
const data = await res.json();
|
|
1581
|
+
const ticket = data?.data ?? data;
|
|
1582
|
+
if (!ticket?.wsUrl) {
|
|
1583
|
+
throw new Error("Server did not return a voice session URL.");
|
|
1584
|
+
}
|
|
1585
|
+
const ws = new WebSocket(ticket.wsUrl);
|
|
1586
|
+
ws.binaryType = "arraybuffer";
|
|
1587
|
+
wsRef.current = ws;
|
|
1588
|
+
ws.onmessage = handleMessage;
|
|
1589
|
+
ws.onerror = () => {
|
|
1590
|
+
voiceLogger.warn("WebSocket error");
|
|
1591
|
+
if (mountedRef.current) {
|
|
1592
|
+
setError(new Error("Voice connection error."));
|
|
1593
|
+
setState("error");
|
|
1594
|
+
}
|
|
1595
|
+
};
|
|
1596
|
+
ws.onclose = () => {
|
|
1597
|
+
if (mountedRef.current && wsRef.current === ws) {
|
|
1598
|
+
setState((prev) => prev === "error" ? prev : "idle");
|
|
1599
|
+
}
|
|
1600
|
+
};
|
|
1601
|
+
} catch (err) {
|
|
1602
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1603
|
+
voiceLogger.error("start() failed", { error: errorObj.message });
|
|
1604
|
+
if (mountedRef.current) {
|
|
1605
|
+
setError(errorObj);
|
|
1606
|
+
setState("error");
|
|
1607
|
+
}
|
|
1608
|
+
teardownAudio();
|
|
1609
|
+
}
|
|
1610
|
+
}, [agentId, fetchWithAuth, handleMessage, teardownAudio, voiceLogger]);
|
|
1611
|
+
const mute = useCallback4((muted) => {
|
|
1612
|
+
setIsMuted(muted);
|
|
1613
|
+
streamRef.current?.getAudioTracks().forEach((track) => {
|
|
1614
|
+
track.enabled = !muted;
|
|
1615
|
+
});
|
|
1616
|
+
}, []);
|
|
1617
|
+
const sendText = useCallback4((text) => {
|
|
1618
|
+
if (!text?.trim() || wsRef.current?.readyState !== WebSocket.OPEN) return;
|
|
1619
|
+
wsRef.current.send(JSON.stringify({ type: "voice.text", text }));
|
|
1620
|
+
}, []);
|
|
1621
|
+
return {
|
|
1622
|
+
state,
|
|
1623
|
+
isMuted,
|
|
1624
|
+
transcript,
|
|
1625
|
+
partial,
|
|
1626
|
+
toolCalls,
|
|
1627
|
+
error,
|
|
1628
|
+
endReason,
|
|
1629
|
+
start,
|
|
1630
|
+
stop,
|
|
1631
|
+
mute,
|
|
1632
|
+
sendText
|
|
1633
|
+
};
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1197
1636
|
// src/hooks/useFiles.ts
|
|
1198
|
-
import { useCallback as
|
|
1637
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useState as useState5 } from "react";
|
|
1199
1638
|
function useFiles(autoFetch = true) {
|
|
1200
1639
|
const { fetchWithAuth } = usePersonaContext();
|
|
1201
|
-
const [files, setFiles] =
|
|
1202
|
-
const [isLoading, setIsLoading] =
|
|
1203
|
-
const [isUploading, setIsUploading] =
|
|
1204
|
-
const [error, setError] =
|
|
1205
|
-
const fetchFiles =
|
|
1640
|
+
const [files, setFiles] = useState5([]);
|
|
1641
|
+
const [isLoading, setIsLoading] = useState5(false);
|
|
1642
|
+
const [isUploading, setIsUploading] = useState5(false);
|
|
1643
|
+
const [error, setError] = useState5(null);
|
|
1644
|
+
const fetchFiles = useCallback5(async () => {
|
|
1206
1645
|
setIsLoading(true);
|
|
1207
1646
|
setError(null);
|
|
1208
1647
|
try {
|
|
@@ -1220,7 +1659,7 @@ function useFiles(autoFetch = true) {
|
|
|
1220
1659
|
setIsLoading(false);
|
|
1221
1660
|
}
|
|
1222
1661
|
}, [fetchWithAuth]);
|
|
1223
|
-
const uploadFile =
|
|
1662
|
+
const uploadFile = useCallback5(
|
|
1224
1663
|
async (fileOrFormData) => {
|
|
1225
1664
|
setIsUploading(true);
|
|
1226
1665
|
setError(null);
|
|
@@ -1253,7 +1692,7 @@ function useFiles(autoFetch = true) {
|
|
|
1253
1692
|
},
|
|
1254
1693
|
[fetchWithAuth, fetchFiles]
|
|
1255
1694
|
);
|
|
1256
|
-
const deleteFile =
|
|
1695
|
+
const deleteFile = useCallback5(
|
|
1257
1696
|
async (fileId) => {
|
|
1258
1697
|
const res = await fetchWithAuth(`/files/${fileId}`, { method: "DELETE" });
|
|
1259
1698
|
if (!res.ok) throw new Error(`Failed to delete file: ${res.statusText}`);
|
|
@@ -1261,7 +1700,7 @@ function useFiles(autoFetch = true) {
|
|
|
1261
1700
|
},
|
|
1262
1701
|
[fetchWithAuth]
|
|
1263
1702
|
);
|
|
1264
|
-
const bulkDeleteFiles =
|
|
1703
|
+
const bulkDeleteFiles = useCallback5(
|
|
1265
1704
|
async (fileIds) => {
|
|
1266
1705
|
const res = await fetchWithAuth("/files/bulk-delete", {
|
|
1267
1706
|
method: "POST",
|
|
@@ -1276,10 +1715,10 @@ function useFiles(autoFetch = true) {
|
|
|
1276
1715
|
},
|
|
1277
1716
|
[fetchWithAuth]
|
|
1278
1717
|
);
|
|
1279
|
-
const getDownloadUrl =
|
|
1718
|
+
const getDownloadUrl = useCallback5((fileId) => {
|
|
1280
1719
|
return `/files/${fileId}`;
|
|
1281
1720
|
}, []);
|
|
1282
|
-
|
|
1721
|
+
useEffect5(() => {
|
|
1283
1722
|
if (autoFetch) {
|
|
1284
1723
|
void fetchFiles();
|
|
1285
1724
|
}
|
|
@@ -1298,13 +1737,13 @@ function useFiles(autoFetch = true) {
|
|
|
1298
1737
|
}
|
|
1299
1738
|
|
|
1300
1739
|
// src/hooks/useAgents.ts
|
|
1301
|
-
import { useCallback as
|
|
1740
|
+
import { useCallback as useCallback6, useEffect as useEffect6, useState as useState6 } from "react";
|
|
1302
1741
|
function useAgents(autoFetch = true) {
|
|
1303
1742
|
const { fetchWithAuth } = usePersonaContext();
|
|
1304
|
-
const [agents, setAgents] =
|
|
1305
|
-
const [isLoading, setIsLoading] =
|
|
1306
|
-
const [error, setError] =
|
|
1307
|
-
const fetchAgents =
|
|
1743
|
+
const [agents, setAgents] = useState6([]);
|
|
1744
|
+
const [isLoading, setIsLoading] = useState6(false);
|
|
1745
|
+
const [error, setError] = useState6(null);
|
|
1746
|
+
const fetchAgents = useCallback6(async () => {
|
|
1308
1747
|
setIsLoading(true);
|
|
1309
1748
|
setError(null);
|
|
1310
1749
|
try {
|
|
@@ -1322,7 +1761,7 @@ function useAgents(autoFetch = true) {
|
|
|
1322
1761
|
setIsLoading(false);
|
|
1323
1762
|
}
|
|
1324
1763
|
}, [fetchWithAuth]);
|
|
1325
|
-
|
|
1764
|
+
useEffect6(() => {
|
|
1326
1765
|
if (autoFetch) {
|
|
1327
1766
|
void fetchAgents();
|
|
1328
1767
|
}
|
|
@@ -1336,13 +1775,13 @@ function useAgents(autoFetch = true) {
|
|
|
1336
1775
|
}
|
|
1337
1776
|
|
|
1338
1777
|
// src/hooks/useConnection.ts
|
|
1339
|
-
import { useCallback as
|
|
1778
|
+
import { useCallback as useCallback7, useEffect as useEffect7, useState as useState7 } from "react";
|
|
1340
1779
|
function useConnection(autoCheck = true) {
|
|
1341
1780
|
const { fetchWithAuth } = usePersonaContext();
|
|
1342
|
-
const [health, setHealth] =
|
|
1343
|
-
const [isConnected, setIsConnected] =
|
|
1344
|
-
const [isLoading, setIsLoading] =
|
|
1345
|
-
const checkHealth =
|
|
1781
|
+
const [health, setHealth] = useState7(null);
|
|
1782
|
+
const [isConnected, setIsConnected] = useState7(false);
|
|
1783
|
+
const [isLoading, setIsLoading] = useState7(false);
|
|
1784
|
+
const checkHealth = useCallback7(async () => {
|
|
1346
1785
|
setIsLoading(true);
|
|
1347
1786
|
try {
|
|
1348
1787
|
const res = await fetchWithAuth("/health");
|
|
@@ -1361,7 +1800,7 @@ function useConnection(autoCheck = true) {
|
|
|
1361
1800
|
setIsLoading(false);
|
|
1362
1801
|
}
|
|
1363
1802
|
}, [fetchWithAuth]);
|
|
1364
|
-
|
|
1803
|
+
useEffect7(() => {
|
|
1365
1804
|
if (autoCheck) {
|
|
1366
1805
|
void checkHealth();
|
|
1367
1806
|
}
|
|
@@ -1375,15 +1814,15 @@ function useConnection(autoCheck = true) {
|
|
|
1375
1814
|
}
|
|
1376
1815
|
|
|
1377
1816
|
// src/hooks/useMcpConnections.ts
|
|
1378
|
-
import { useCallback as
|
|
1817
|
+
import { useCallback as useCallback8, useEffect as useEffect8, useState as useState8 } from "react";
|
|
1379
1818
|
function useMcpConnections(options = {}) {
|
|
1380
1819
|
const { defaultAgentId, fetchWithAuth } = usePersonaContext();
|
|
1381
1820
|
const agentId = options.agentId ?? defaultAgentId;
|
|
1382
1821
|
const autoFetch = options.autoFetch ?? true;
|
|
1383
|
-
const [connections, setConnections] =
|
|
1384
|
-
const [isLoading, setIsLoading] =
|
|
1385
|
-
const [error, setError] =
|
|
1386
|
-
const fetchConnections =
|
|
1822
|
+
const [connections, setConnections] = useState8([]);
|
|
1823
|
+
const [isLoading, setIsLoading] = useState8(false);
|
|
1824
|
+
const [error, setError] = useState8(null);
|
|
1825
|
+
const fetchConnections = useCallback8(async () => {
|
|
1387
1826
|
if (!agentId) return [];
|
|
1388
1827
|
setIsLoading(true);
|
|
1389
1828
|
setError(null);
|
|
@@ -1407,7 +1846,7 @@ function useMcpConnections(options = {}) {
|
|
|
1407
1846
|
setIsLoading(false);
|
|
1408
1847
|
}
|
|
1409
1848
|
}, [agentId, fetchWithAuth, options.returnTo]);
|
|
1410
|
-
|
|
1849
|
+
useEffect8(() => {
|
|
1411
1850
|
if (autoFetch) void fetchConnections();
|
|
1412
1851
|
}, [autoFetch, fetchConnections]);
|
|
1413
1852
|
return {
|
|
@@ -1428,7 +1867,7 @@ import {
|
|
|
1428
1867
|
getLogLevel,
|
|
1429
1868
|
isLevelEnabled
|
|
1430
1869
|
} from "@personaai/logger";
|
|
1431
|
-
var VERSION = "0.
|
|
1870
|
+
var VERSION = "0.7.0";
|
|
1432
1871
|
export {
|
|
1433
1872
|
PersonaProvider,
|
|
1434
1873
|
VERSION,
|
|
@@ -1446,6 +1885,7 @@ export {
|
|
|
1446
1885
|
useMcpConnections,
|
|
1447
1886
|
useMemory,
|
|
1448
1887
|
usePersonaContext,
|
|
1449
|
-
useThreads
|
|
1888
|
+
useThreads,
|
|
1889
|
+
useVoice
|
|
1450
1890
|
};
|
|
1451
1891
|
//# sourceMappingURL=index.js.map
|