@personaai/react 0.6.0 → 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/dist/index.js CHANGED
@@ -1210,15 +1210,438 @@ function useThreads(autoFetch = true) {
1210
1210
  };
1211
1211
  }
1212
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
+
1213
1636
  // src/hooks/useFiles.ts
1214
- import { useCallback as useCallback4, useEffect as useEffect4, useState as useState4 } from "react";
1637
+ import { useCallback as useCallback5, useEffect as useEffect5, useState as useState5 } from "react";
1215
1638
  function useFiles(autoFetch = true) {
1216
1639
  const { fetchWithAuth } = usePersonaContext();
1217
- const [files, setFiles] = useState4([]);
1218
- const [isLoading, setIsLoading] = useState4(false);
1219
- const [isUploading, setIsUploading] = useState4(false);
1220
- const [error, setError] = useState4(null);
1221
- const fetchFiles = useCallback4(async () => {
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 () => {
1222
1645
  setIsLoading(true);
1223
1646
  setError(null);
1224
1647
  try {
@@ -1236,7 +1659,7 @@ function useFiles(autoFetch = true) {
1236
1659
  setIsLoading(false);
1237
1660
  }
1238
1661
  }, [fetchWithAuth]);
1239
- const uploadFile = useCallback4(
1662
+ const uploadFile = useCallback5(
1240
1663
  async (fileOrFormData) => {
1241
1664
  setIsUploading(true);
1242
1665
  setError(null);
@@ -1269,7 +1692,7 @@ function useFiles(autoFetch = true) {
1269
1692
  },
1270
1693
  [fetchWithAuth, fetchFiles]
1271
1694
  );
1272
- const deleteFile = useCallback4(
1695
+ const deleteFile = useCallback5(
1273
1696
  async (fileId) => {
1274
1697
  const res = await fetchWithAuth(`/files/${fileId}`, { method: "DELETE" });
1275
1698
  if (!res.ok) throw new Error(`Failed to delete file: ${res.statusText}`);
@@ -1277,7 +1700,7 @@ function useFiles(autoFetch = true) {
1277
1700
  },
1278
1701
  [fetchWithAuth]
1279
1702
  );
1280
- const bulkDeleteFiles = useCallback4(
1703
+ const bulkDeleteFiles = useCallback5(
1281
1704
  async (fileIds) => {
1282
1705
  const res = await fetchWithAuth("/files/bulk-delete", {
1283
1706
  method: "POST",
@@ -1292,10 +1715,10 @@ function useFiles(autoFetch = true) {
1292
1715
  },
1293
1716
  [fetchWithAuth]
1294
1717
  );
1295
- const getDownloadUrl = useCallback4((fileId) => {
1718
+ const getDownloadUrl = useCallback5((fileId) => {
1296
1719
  return `/files/${fileId}`;
1297
1720
  }, []);
1298
- useEffect4(() => {
1721
+ useEffect5(() => {
1299
1722
  if (autoFetch) {
1300
1723
  void fetchFiles();
1301
1724
  }
@@ -1314,13 +1737,13 @@ function useFiles(autoFetch = true) {
1314
1737
  }
1315
1738
 
1316
1739
  // src/hooks/useAgents.ts
1317
- import { useCallback as useCallback5, useEffect as useEffect5, useState as useState5 } from "react";
1740
+ import { useCallback as useCallback6, useEffect as useEffect6, useState as useState6 } from "react";
1318
1741
  function useAgents(autoFetch = true) {
1319
1742
  const { fetchWithAuth } = usePersonaContext();
1320
- const [agents, setAgents] = useState5([]);
1321
- const [isLoading, setIsLoading] = useState5(false);
1322
- const [error, setError] = useState5(null);
1323
- const fetchAgents = useCallback5(async () => {
1743
+ const [agents, setAgents] = useState6([]);
1744
+ const [isLoading, setIsLoading] = useState6(false);
1745
+ const [error, setError] = useState6(null);
1746
+ const fetchAgents = useCallback6(async () => {
1324
1747
  setIsLoading(true);
1325
1748
  setError(null);
1326
1749
  try {
@@ -1338,7 +1761,7 @@ function useAgents(autoFetch = true) {
1338
1761
  setIsLoading(false);
1339
1762
  }
1340
1763
  }, [fetchWithAuth]);
1341
- useEffect5(() => {
1764
+ useEffect6(() => {
1342
1765
  if (autoFetch) {
1343
1766
  void fetchAgents();
1344
1767
  }
@@ -1352,13 +1775,13 @@ function useAgents(autoFetch = true) {
1352
1775
  }
1353
1776
 
1354
1777
  // src/hooks/useConnection.ts
1355
- import { useCallback as useCallback6, useEffect as useEffect6, useState as useState6 } from "react";
1778
+ import { useCallback as useCallback7, useEffect as useEffect7, useState as useState7 } from "react";
1356
1779
  function useConnection(autoCheck = true) {
1357
1780
  const { fetchWithAuth } = usePersonaContext();
1358
- const [health, setHealth] = useState6(null);
1359
- const [isConnected, setIsConnected] = useState6(false);
1360
- const [isLoading, setIsLoading] = useState6(false);
1361
- const checkHealth = useCallback6(async () => {
1781
+ const [health, setHealth] = useState7(null);
1782
+ const [isConnected, setIsConnected] = useState7(false);
1783
+ const [isLoading, setIsLoading] = useState7(false);
1784
+ const checkHealth = useCallback7(async () => {
1362
1785
  setIsLoading(true);
1363
1786
  try {
1364
1787
  const res = await fetchWithAuth("/health");
@@ -1377,7 +1800,7 @@ function useConnection(autoCheck = true) {
1377
1800
  setIsLoading(false);
1378
1801
  }
1379
1802
  }, [fetchWithAuth]);
1380
- useEffect6(() => {
1803
+ useEffect7(() => {
1381
1804
  if (autoCheck) {
1382
1805
  void checkHealth();
1383
1806
  }
@@ -1391,15 +1814,15 @@ function useConnection(autoCheck = true) {
1391
1814
  }
1392
1815
 
1393
1816
  // src/hooks/useMcpConnections.ts
1394
- import { useCallback as useCallback7, useEffect as useEffect7, useState as useState7 } from "react";
1817
+ import { useCallback as useCallback8, useEffect as useEffect8, useState as useState8 } from "react";
1395
1818
  function useMcpConnections(options = {}) {
1396
1819
  const { defaultAgentId, fetchWithAuth } = usePersonaContext();
1397
1820
  const agentId = options.agentId ?? defaultAgentId;
1398
1821
  const autoFetch = options.autoFetch ?? true;
1399
- const [connections, setConnections] = useState7([]);
1400
- const [isLoading, setIsLoading] = useState7(false);
1401
- const [error, setError] = useState7(null);
1402
- const fetchConnections = useCallback7(async () => {
1822
+ const [connections, setConnections] = useState8([]);
1823
+ const [isLoading, setIsLoading] = useState8(false);
1824
+ const [error, setError] = useState8(null);
1825
+ const fetchConnections = useCallback8(async () => {
1403
1826
  if (!agentId) return [];
1404
1827
  setIsLoading(true);
1405
1828
  setError(null);
@@ -1423,7 +1846,7 @@ function useMcpConnections(options = {}) {
1423
1846
  setIsLoading(false);
1424
1847
  }
1425
1848
  }, [agentId, fetchWithAuth, options.returnTo]);
1426
- useEffect7(() => {
1849
+ useEffect8(() => {
1427
1850
  if (autoFetch) void fetchConnections();
1428
1851
  }, [autoFetch, fetchConnections]);
1429
1852
  return {
@@ -1444,7 +1867,7 @@ import {
1444
1867
  getLogLevel,
1445
1868
  isLevelEnabled
1446
1869
  } from "@personaai/logger";
1447
- var VERSION = "0.6.0";
1870
+ var VERSION = "0.7.0";
1448
1871
  export {
1449
1872
  PersonaProvider,
1450
1873
  VERSION,
@@ -1462,6 +1885,7 @@ export {
1462
1885
  useMcpConnections,
1463
1886
  useMemory,
1464
1887
  usePersonaContext,
1465
- useThreads
1888
+ useThreads,
1889
+ useVoice
1466
1890
  };
1467
1891
  //# sourceMappingURL=index.js.map