@lokutor/sdk 1.1.40 → 1.1.42

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -389,6 +389,10 @@ declare class VoiceAgentClient {
389
389
  * Update tool definitions mid-conversation
390
390
  */
391
391
  updateTools(tools: ToolDefinition[]): void;
392
+ /**
393
+ * Submit a tool execution result back to the agent
394
+ */
395
+ submitToolResult(callID: string, result: string | object): void;
392
396
  /**
393
397
  * Get full conversation transcript
394
398
  */
package/dist/index.d.ts CHANGED
@@ -389,6 +389,10 @@ declare class VoiceAgentClient {
389
389
  * Update tool definitions mid-conversation
390
390
  */
391
391
  updateTools(tools: ToolDefinition[]): void;
392
+ /**
393
+ * Submit a tool execution result back to the agent
394
+ */
395
+ submitToolResult(callID: string, result: string | object): void;
392
396
  /**
393
397
  * Get full conversation transcript
394
398
  */
package/dist/index.js CHANGED
@@ -1222,6 +1222,24 @@ var VoiceAgentClient = class {
1222
1222
  console.log(`\u2699\uFE0F Updated ${tools.length} tool(s)`);
1223
1223
  }
1224
1224
  }
1225
+ /**
1226
+ * Submit a tool execution result back to the agent
1227
+ */
1228
+ submitToolResult(callID, result) {
1229
+ const resultStr = typeof result === "string" ? result : JSON.stringify(result);
1230
+ if (this.ws && this.ws.readyState === WebSocket.OPEN && this.isConnected) {
1231
+ this.ws.send(JSON.stringify({
1232
+ type: "tool_result",
1233
+ data: {
1234
+ call_id: callID,
1235
+ result: resultStr
1236
+ }
1237
+ }));
1238
+ console.log(`\u2713 Submitted tool result for call ${callID}`);
1239
+ } else {
1240
+ console.warn("Not connected - cannot submit tool result");
1241
+ }
1242
+ }
1225
1243
  /**
1226
1244
  * Get full conversation transcript
1227
1245
  */
@@ -1362,7 +1380,7 @@ var PANEL_CSS = (
1362
1380
  position: relative;
1363
1381
  width: 100%;
1364
1382
  aspect-ratio: 16 / 9;
1365
- max-height: clamp(400px, 50vh, 800px);
1383
+ max-height: clamp(200px, 50vh, 800px);
1366
1384
  display: flex;
1367
1385
  flex-direction: column;
1368
1386
  align-items: center;
@@ -1371,8 +1389,9 @@ var PANEL_CSS = (
1371
1389
  margin: 0;
1372
1390
  background: var(--cv-bg, #0a0a0a);
1373
1391
  box-shadow: inset 0 10px 40px rgba(0, 0, 0, 0.1), inset 0 0 100px rgba(0, 0, 0, 0.05);
1374
- border-radius: clamp(20px, 5vw, 40px);
1392
+ border-radius: clamp(12px, 4vw, 40px);
1375
1393
  overflow: hidden;
1394
+ container-type: size;
1376
1395
  }
1377
1396
  .cv-curtain {
1378
1397
  position: absolute;
@@ -1574,29 +1593,73 @@ var PANEL_CSS = (
1574
1593
  .cv-error.is-visible { display: flex; }
1575
1594
  .cv-error-icon { color: var(--cv-accent); flex-shrink: 0; }
1576
1595
 
1577
- @media (max-width: 768px) {
1578
- .cv-panel { max-height: 600px; border-radius: 24px; }
1579
- .cv-curtain-content { padding: clamp(0.75rem, 3vw, 1.5rem); gap: clamp(0.5rem, 2vw, 1rem); }
1580
- .cv-curtain-title { font-size: clamp(1rem, 5vw, 1.8rem); }
1581
- .cv-curtain-desc { font-size: clamp(0.65rem, 2.5vw, 0.95rem); max-width: 90vw; }
1582
- .cv-curtain-btn { padding: clamp(0.45rem, 1.5vw, 0.75rem) clamp(1rem, 3vw, 2rem); font-size: clamp(0.65rem, 1.5vw, 0.9rem); }
1583
- .cv-visualizer-wrap { width: clamp(100px, 45vw, 220px); height: clamp(100px, 45vw, 220px); }
1584
- .cv-title { font-size: clamp(0.9rem, 2vw, 1.5rem); gap: clamp(0.5rem, 1vw, 0.75rem); }
1585
- .cv-controls { gap: clamp(1rem, 2vw, 1.5rem); padding-bottom: clamp(1rem, 2vw, 1.5rem); }
1586
- .cv-pill { padding: clamp(0.2rem, 1vw, 0.4rem) clamp(0.5rem, 1.5vw, 0.75rem); font-size: clamp(0.65rem, 1.5vw, 0.75rem); }
1587
- .cv-btn { padding: clamp(0.25rem, 1vw, 0.35rem) clamp(0.5rem, 1.5vw, 0.75rem); font-size: clamp(0.65rem, 1.5vw, 0.75rem); }
1588
- .cv-error { padding: clamp(0.5rem, 1.5vw, 0.75rem) clamp(1rem, 2vw, 1.5rem); font-size: clamp(0.75rem, 1.5vw, 0.875rem); }
1596
+ /* === COMPACT MODE: < 300px width === */
1597
+ @container (max-width: 299px) {
1598
+ .cv-curtain-content { padding: 0.5rem; gap: 0.3rem; }
1599
+ .cv-curtain-title { font-size: 0.8rem; }
1600
+ .cv-curtain-desc { display: none; }
1601
+ .cv-curtain-btn { padding: 0.3rem 0.6rem; font-size: 0.6rem; gap: 0.3rem; }
1602
+ .cv-curtain-btn svg { display: none; }
1603
+ .cv-visualizer-wrap { width: 60px; height: 60px; }
1604
+ .cv-header { padding-top: 0.75rem; }
1605
+ .cv-title { font-size: 0.7rem; gap: 0.3rem; }
1606
+ .cv-title .cv-timer { display: none; }
1607
+ .cv-controls { gap: 0.6rem; padding-bottom: 0.6rem; }
1608
+ .cv-pill { padding: 0.15rem 0.4rem; gap: 0.3rem; }
1609
+ .cv-btn { padding: 0.2rem 0.4rem; font-size: 0.6rem; gap: 0; }
1610
+ .cv-btn span { display: none; }
1611
+ .cv-btn svg { width: 16px; height: 16px; }
1612
+ .cv-error { padding: 0.4rem 0.8rem; font-size: 0.65rem; bottom: 0.5rem; }
1589
1613
  }
1590
-
1591
- @media (max-width: 480px) {
1592
- .cv-panel { aspect-ratio: 3 / 4; max-height: 500px; border-radius: 20px; }
1593
- .cv-curtain-content { padding: clamp(0.5rem, 2vw, 1rem); gap: clamp(0.4rem, 1.5vw, 0.75rem); }
1594
- .cv-curtain-title { font-size: clamp(0.9rem, 4.5vw, 1.4rem); }
1595
- .cv-curtain-desc { font-size: clamp(0.6rem, 2vw, 0.8rem); }
1596
- .cv-curtain-btn { padding: clamp(0.4rem, 1.2vw, 0.6rem) clamp(0.8rem, 2.5vw, 1.5rem); font-size: clamp(0.6rem, 1.2vw, 0.8rem); }
1597
- .cv-visualizer-wrap { width: clamp(80px, 40vw, 180px); height: clamp(80px, 40vw, 180px); }
1598
- .cv-header { padding-top: clamp(1rem, 2vw, 1.5rem); }
1599
- .cv-controls { gap: clamp(0.8rem, 1.5vw, 1.2rem); padding-bottom: clamp(0.8rem, 1.5vw, 1.2rem); }
1614
+
1615
+ /* === SMALL MODE: 300px - 480px width === */
1616
+ @container (min-width: 300px) and (max-width: 480px) {
1617
+ .cv-curtain-content { padding: 0.75rem; gap: 0.5rem; }
1618
+ .cv-curtain-title { font-size: clamp(0.9rem, 3cqw, 1.2rem); }
1619
+ .cv-curtain-desc { font-size: clamp(0.6rem, 2cqw, 0.8rem); }
1620
+ .cv-curtain-btn { padding: clamp(0.3rem, 1cqw, 0.5rem) clamp(0.6rem, 2cqw, 1rem); font-size: clamp(0.6rem, 1.5cqw, 0.8rem); }
1621
+ .cv-visualizer-wrap { width: clamp(80px, 35cqw, 140px); height: clamp(80px, 35cqw, 140px); }
1622
+ .cv-header { padding-top: 0.8rem; }
1623
+ .cv-title { font-size: clamp(0.7rem, 2.5cqw, 1rem); gap: 0.4rem; }
1624
+ .cv-title .cv-timer { font-size: 0.65em; }
1625
+ .cv-controls { gap: clamp(0.6rem, 1.5cqw, 1rem); padding-bottom: clamp(0.6rem, 1.5cqw, 1rem); }
1626
+ .cv-pill { padding: clamp(0.15rem, 0.5cqw, 0.25rem) clamp(0.35rem, 1cqw, 0.6rem); font-size: 0.65rem; gap: 0.3rem; }
1627
+ .cv-btn { padding: clamp(0.2rem, 0.5cqw, 0.3rem) clamp(0.35rem, 1cqw, 0.6rem); font-size: clamp(0.6rem, 1.2cqw, 0.7rem); }
1628
+ .cv-btn span:last-child { display: none; }
1629
+ .cv-error { padding: clamp(0.4rem, 1cqw, 0.6rem) clamp(0.8rem, 1.5cqw, 1.2rem); font-size: 0.7rem; }
1630
+ }
1631
+
1632
+ /* === MEDIUM MODE: 480px - 768px width === */
1633
+ @container (min-width: 480px) and (max-width: 768px) {
1634
+ .cv-panel { max-height: 600px; aspect-ratio: 3 / 4; }
1635
+ .cv-curtain-content { padding: clamp(0.75rem, 2cqw, 1.25rem); gap: clamp(0.5rem, 1.5cqw, 1rem); }
1636
+ .cv-curtain-title { font-size: clamp(1rem, 4cqw, 1.6rem); }
1637
+ .cv-curtain-desc { font-size: clamp(0.7rem, 2.5cqw, 1rem); }
1638
+ .cv-curtain-btn { padding: clamp(0.45rem, 1.5cqw, 0.7rem) clamp(1rem, 2cqw, 1.5rem); font-size: clamp(0.7rem, 1.5cqw, 0.9rem); }
1639
+ .cv-visualizer-wrap { width: clamp(100px, 40cqw, 200px); height: clamp(100px, 40cqw, 200px); }
1640
+ .cv-header { padding-top: clamp(1rem, 1.5cqw, 1.5rem); }
1641
+ .cv-title { font-size: clamp(0.9rem, 3cqw, 1.3rem); gap: clamp(0.4rem, 1cqw, 0.75rem); }
1642
+ .cv-title .cv-timer { font-size: 0.85em; }
1643
+ .cv-controls { gap: clamp(0.8rem, 1.5cqw, 1.2rem); padding-bottom: clamp(0.8rem, 1.5cqw, 1.2rem); }
1644
+ .cv-pill { padding: clamp(0.2rem, 0.75cqw, 0.3rem) clamp(0.5rem, 1.2cqw, 0.75rem); font-size: 0.7rem; }
1645
+ .cv-btn { padding: clamp(0.25rem, 0.75cqw, 0.35rem) clamp(0.5rem, 1.2cqw, 0.75rem); font-size: clamp(0.65rem, 1.2cqw, 0.8rem); }
1646
+ .cv-error { padding: clamp(0.5rem, 1.2cqw, 0.75rem) clamp(1rem, 1.5cqw, 1.5rem); font-size: clamp(0.7rem, 1.2cqw, 0.85rem); }
1647
+ }
1648
+
1649
+ /* === LARGE MODE: > 768px width === */
1650
+ @container (min-width: 768px) {
1651
+ .cv-curtain-content { padding: clamp(1rem, 2.5cqw, 2rem); gap: clamp(0.75rem, 2cqw, 1.5rem); }
1652
+ .cv-curtain-title { font-size: clamp(1.2rem, 5cqw, 2.5rem); }
1653
+ .cv-curtain-desc { font-size: clamp(0.8rem, 2.5cqw, 1.2rem); max-width: 500px; }
1654
+ .cv-curtain-btn { padding: clamp(0.6rem, 2cqw, 1rem) clamp(1.5rem, 3cqw, 2.5rem); font-size: clamp(0.8rem, 1.5cqw, 1.1rem); }
1655
+ .cv-visualizer-wrap { width: clamp(140px, 45cqw, 300px); height: clamp(140px, 45cqw, 300px); }
1656
+ .cv-header { padding-top: clamp(1.5rem, 2cqw, 2rem); }
1657
+ .cv-title { font-size: clamp(1rem, 3cqw, 1.8rem); gap: clamp(0.75rem, 1.5cqw, 1.2rem); }
1658
+ .cv-title .cv-timer { font-size: 0.9em; }
1659
+ .cv-controls { gap: clamp(1.2rem, 2cqw, 1.8rem); padding-bottom: clamp(1.2rem, 2cqw, 1.8rem); }
1660
+ .cv-pill { padding: clamp(0.3rem, 0.8cqw, 0.4rem) clamp(0.75rem, 1.2cqw, 1rem); font-size: 0.85rem; gap: 0.75rem; }
1661
+ .cv-btn { padding: clamp(0.35rem, 0.8cqw, 0.4rem) clamp(0.75rem, 1.2cqw, 1rem); font-size: clamp(0.75rem, 1.2cqw, 0.9rem); }
1662
+ .cv-error { padding: clamp(0.75rem, 1.5cqw, 1rem) clamp(1.5rem, 2cqw, 2rem); font-size: clamp(0.85rem, 1cqw, 1rem); }
1600
1663
  }
1601
1664
  `
1602
1665
  );
package/dist/index.mjs CHANGED
@@ -1175,6 +1175,24 @@ var VoiceAgentClient = class {
1175
1175
  console.log(`\u2699\uFE0F Updated ${tools.length} tool(s)`);
1176
1176
  }
1177
1177
  }
1178
+ /**
1179
+ * Submit a tool execution result back to the agent
1180
+ */
1181
+ submitToolResult(callID, result) {
1182
+ const resultStr = typeof result === "string" ? result : JSON.stringify(result);
1183
+ if (this.ws && this.ws.readyState === WebSocket.OPEN && this.isConnected) {
1184
+ this.ws.send(JSON.stringify({
1185
+ type: "tool_result",
1186
+ data: {
1187
+ call_id: callID,
1188
+ result: resultStr
1189
+ }
1190
+ }));
1191
+ console.log(`\u2713 Submitted tool result for call ${callID}`);
1192
+ } else {
1193
+ console.warn("Not connected - cannot submit tool result");
1194
+ }
1195
+ }
1178
1196
  /**
1179
1197
  * Get full conversation transcript
1180
1198
  */
@@ -1315,7 +1333,7 @@ var PANEL_CSS = (
1315
1333
  position: relative;
1316
1334
  width: 100%;
1317
1335
  aspect-ratio: 16 / 9;
1318
- max-height: clamp(400px, 50vh, 800px);
1336
+ max-height: clamp(200px, 50vh, 800px);
1319
1337
  display: flex;
1320
1338
  flex-direction: column;
1321
1339
  align-items: center;
@@ -1324,8 +1342,9 @@ var PANEL_CSS = (
1324
1342
  margin: 0;
1325
1343
  background: var(--cv-bg, #0a0a0a);
1326
1344
  box-shadow: inset 0 10px 40px rgba(0, 0, 0, 0.1), inset 0 0 100px rgba(0, 0, 0, 0.05);
1327
- border-radius: clamp(20px, 5vw, 40px);
1345
+ border-radius: clamp(12px, 4vw, 40px);
1328
1346
  overflow: hidden;
1347
+ container-type: size;
1329
1348
  }
1330
1349
  .cv-curtain {
1331
1350
  position: absolute;
@@ -1527,29 +1546,73 @@ var PANEL_CSS = (
1527
1546
  .cv-error.is-visible { display: flex; }
1528
1547
  .cv-error-icon { color: var(--cv-accent); flex-shrink: 0; }
1529
1548
 
1530
- @media (max-width: 768px) {
1531
- .cv-panel { max-height: 600px; border-radius: 24px; }
1532
- .cv-curtain-content { padding: clamp(0.75rem, 3vw, 1.5rem); gap: clamp(0.5rem, 2vw, 1rem); }
1533
- .cv-curtain-title { font-size: clamp(1rem, 5vw, 1.8rem); }
1534
- .cv-curtain-desc { font-size: clamp(0.65rem, 2.5vw, 0.95rem); max-width: 90vw; }
1535
- .cv-curtain-btn { padding: clamp(0.45rem, 1.5vw, 0.75rem) clamp(1rem, 3vw, 2rem); font-size: clamp(0.65rem, 1.5vw, 0.9rem); }
1536
- .cv-visualizer-wrap { width: clamp(100px, 45vw, 220px); height: clamp(100px, 45vw, 220px); }
1537
- .cv-title { font-size: clamp(0.9rem, 2vw, 1.5rem); gap: clamp(0.5rem, 1vw, 0.75rem); }
1538
- .cv-controls { gap: clamp(1rem, 2vw, 1.5rem); padding-bottom: clamp(1rem, 2vw, 1.5rem); }
1539
- .cv-pill { padding: clamp(0.2rem, 1vw, 0.4rem) clamp(0.5rem, 1.5vw, 0.75rem); font-size: clamp(0.65rem, 1.5vw, 0.75rem); }
1540
- .cv-btn { padding: clamp(0.25rem, 1vw, 0.35rem) clamp(0.5rem, 1.5vw, 0.75rem); font-size: clamp(0.65rem, 1.5vw, 0.75rem); }
1541
- .cv-error { padding: clamp(0.5rem, 1.5vw, 0.75rem) clamp(1rem, 2vw, 1.5rem); font-size: clamp(0.75rem, 1.5vw, 0.875rem); }
1549
+ /* === COMPACT MODE: < 300px width === */
1550
+ @container (max-width: 299px) {
1551
+ .cv-curtain-content { padding: 0.5rem; gap: 0.3rem; }
1552
+ .cv-curtain-title { font-size: 0.8rem; }
1553
+ .cv-curtain-desc { display: none; }
1554
+ .cv-curtain-btn { padding: 0.3rem 0.6rem; font-size: 0.6rem; gap: 0.3rem; }
1555
+ .cv-curtain-btn svg { display: none; }
1556
+ .cv-visualizer-wrap { width: 60px; height: 60px; }
1557
+ .cv-header { padding-top: 0.75rem; }
1558
+ .cv-title { font-size: 0.7rem; gap: 0.3rem; }
1559
+ .cv-title .cv-timer { display: none; }
1560
+ .cv-controls { gap: 0.6rem; padding-bottom: 0.6rem; }
1561
+ .cv-pill { padding: 0.15rem 0.4rem; gap: 0.3rem; }
1562
+ .cv-btn { padding: 0.2rem 0.4rem; font-size: 0.6rem; gap: 0; }
1563
+ .cv-btn span { display: none; }
1564
+ .cv-btn svg { width: 16px; height: 16px; }
1565
+ .cv-error { padding: 0.4rem 0.8rem; font-size: 0.65rem; bottom: 0.5rem; }
1542
1566
  }
1543
-
1544
- @media (max-width: 480px) {
1545
- .cv-panel { aspect-ratio: 3 / 4; max-height: 500px; border-radius: 20px; }
1546
- .cv-curtain-content { padding: clamp(0.5rem, 2vw, 1rem); gap: clamp(0.4rem, 1.5vw, 0.75rem); }
1547
- .cv-curtain-title { font-size: clamp(0.9rem, 4.5vw, 1.4rem); }
1548
- .cv-curtain-desc { font-size: clamp(0.6rem, 2vw, 0.8rem); }
1549
- .cv-curtain-btn { padding: clamp(0.4rem, 1.2vw, 0.6rem) clamp(0.8rem, 2.5vw, 1.5rem); font-size: clamp(0.6rem, 1.2vw, 0.8rem); }
1550
- .cv-visualizer-wrap { width: clamp(80px, 40vw, 180px); height: clamp(80px, 40vw, 180px); }
1551
- .cv-header { padding-top: clamp(1rem, 2vw, 1.5rem); }
1552
- .cv-controls { gap: clamp(0.8rem, 1.5vw, 1.2rem); padding-bottom: clamp(0.8rem, 1.5vw, 1.2rem); }
1567
+
1568
+ /* === SMALL MODE: 300px - 480px width === */
1569
+ @container (min-width: 300px) and (max-width: 480px) {
1570
+ .cv-curtain-content { padding: 0.75rem; gap: 0.5rem; }
1571
+ .cv-curtain-title { font-size: clamp(0.9rem, 3cqw, 1.2rem); }
1572
+ .cv-curtain-desc { font-size: clamp(0.6rem, 2cqw, 0.8rem); }
1573
+ .cv-curtain-btn { padding: clamp(0.3rem, 1cqw, 0.5rem) clamp(0.6rem, 2cqw, 1rem); font-size: clamp(0.6rem, 1.5cqw, 0.8rem); }
1574
+ .cv-visualizer-wrap { width: clamp(80px, 35cqw, 140px); height: clamp(80px, 35cqw, 140px); }
1575
+ .cv-header { padding-top: 0.8rem; }
1576
+ .cv-title { font-size: clamp(0.7rem, 2.5cqw, 1rem); gap: 0.4rem; }
1577
+ .cv-title .cv-timer { font-size: 0.65em; }
1578
+ .cv-controls { gap: clamp(0.6rem, 1.5cqw, 1rem); padding-bottom: clamp(0.6rem, 1.5cqw, 1rem); }
1579
+ .cv-pill { padding: clamp(0.15rem, 0.5cqw, 0.25rem) clamp(0.35rem, 1cqw, 0.6rem); font-size: 0.65rem; gap: 0.3rem; }
1580
+ .cv-btn { padding: clamp(0.2rem, 0.5cqw, 0.3rem) clamp(0.35rem, 1cqw, 0.6rem); font-size: clamp(0.6rem, 1.2cqw, 0.7rem); }
1581
+ .cv-btn span:last-child { display: none; }
1582
+ .cv-error { padding: clamp(0.4rem, 1cqw, 0.6rem) clamp(0.8rem, 1.5cqw, 1.2rem); font-size: 0.7rem; }
1583
+ }
1584
+
1585
+ /* === MEDIUM MODE: 480px - 768px width === */
1586
+ @container (min-width: 480px) and (max-width: 768px) {
1587
+ .cv-panel { max-height: 600px; aspect-ratio: 3 / 4; }
1588
+ .cv-curtain-content { padding: clamp(0.75rem, 2cqw, 1.25rem); gap: clamp(0.5rem, 1.5cqw, 1rem); }
1589
+ .cv-curtain-title { font-size: clamp(1rem, 4cqw, 1.6rem); }
1590
+ .cv-curtain-desc { font-size: clamp(0.7rem, 2.5cqw, 1rem); }
1591
+ .cv-curtain-btn { padding: clamp(0.45rem, 1.5cqw, 0.7rem) clamp(1rem, 2cqw, 1.5rem); font-size: clamp(0.7rem, 1.5cqw, 0.9rem); }
1592
+ .cv-visualizer-wrap { width: clamp(100px, 40cqw, 200px); height: clamp(100px, 40cqw, 200px); }
1593
+ .cv-header { padding-top: clamp(1rem, 1.5cqw, 1.5rem); }
1594
+ .cv-title { font-size: clamp(0.9rem, 3cqw, 1.3rem); gap: clamp(0.4rem, 1cqw, 0.75rem); }
1595
+ .cv-title .cv-timer { font-size: 0.85em; }
1596
+ .cv-controls { gap: clamp(0.8rem, 1.5cqw, 1.2rem); padding-bottom: clamp(0.8rem, 1.5cqw, 1.2rem); }
1597
+ .cv-pill { padding: clamp(0.2rem, 0.75cqw, 0.3rem) clamp(0.5rem, 1.2cqw, 0.75rem); font-size: 0.7rem; }
1598
+ .cv-btn { padding: clamp(0.25rem, 0.75cqw, 0.35rem) clamp(0.5rem, 1.2cqw, 0.75rem); font-size: clamp(0.65rem, 1.2cqw, 0.8rem); }
1599
+ .cv-error { padding: clamp(0.5rem, 1.2cqw, 0.75rem) clamp(1rem, 1.5cqw, 1.5rem); font-size: clamp(0.7rem, 1.2cqw, 0.85rem); }
1600
+ }
1601
+
1602
+ /* === LARGE MODE: > 768px width === */
1603
+ @container (min-width: 768px) {
1604
+ .cv-curtain-content { padding: clamp(1rem, 2.5cqw, 2rem); gap: clamp(0.75rem, 2cqw, 1.5rem); }
1605
+ .cv-curtain-title { font-size: clamp(1.2rem, 5cqw, 2.5rem); }
1606
+ .cv-curtain-desc { font-size: clamp(0.8rem, 2.5cqw, 1.2rem); max-width: 500px; }
1607
+ .cv-curtain-btn { padding: clamp(0.6rem, 2cqw, 1rem) clamp(1.5rem, 3cqw, 2.5rem); font-size: clamp(0.8rem, 1.5cqw, 1.1rem); }
1608
+ .cv-visualizer-wrap { width: clamp(140px, 45cqw, 300px); height: clamp(140px, 45cqw, 300px); }
1609
+ .cv-header { padding-top: clamp(1.5rem, 2cqw, 2rem); }
1610
+ .cv-title { font-size: clamp(1rem, 3cqw, 1.8rem); gap: clamp(0.75rem, 1.5cqw, 1.2rem); }
1611
+ .cv-title .cv-timer { font-size: 0.9em; }
1612
+ .cv-controls { gap: clamp(1.2rem, 2cqw, 1.8rem); padding-bottom: clamp(1.2rem, 2cqw, 1.8rem); }
1613
+ .cv-pill { padding: clamp(0.3rem, 0.8cqw, 0.4rem) clamp(0.75rem, 1.2cqw, 1rem); font-size: 0.85rem; gap: 0.75rem; }
1614
+ .cv-btn { padding: clamp(0.35rem, 0.8cqw, 0.4rem) clamp(0.75rem, 1.2cqw, 1rem); font-size: clamp(0.75rem, 1.2cqw, 0.9rem); }
1615
+ .cv-error { padding: clamp(0.75rem, 1.5cqw, 1rem) clamp(1.5rem, 2cqw, 2rem); font-size: clamp(0.85rem, 1cqw, 1rem); }
1553
1616
  }
1554
1617
  `
1555
1618
  );
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lokutor/sdk",
3
3
 
4
- "version": "1.1.40",
4
+ "version": "1.1.42",
5
5
  "description": "JavaScript/TypeScript SDK for Lokutor Real-time Voice AI",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
package/src/client.ts CHANGED
@@ -778,6 +778,25 @@ export class VoiceAgentClient {
778
778
  }
779
779
  }
780
780
 
781
+ /**
782
+ * Submit a tool execution result back to the agent
783
+ */
784
+ public submitToolResult(callID: string, result: string | object) {
785
+ const resultStr = typeof result === 'string' ? result : JSON.stringify(result);
786
+ if (this.ws && this.ws.readyState === WebSocket.OPEN && this.isConnected) {
787
+ this.ws.send(JSON.stringify({
788
+ type: 'tool_result',
789
+ data: {
790
+ call_id: callID,
791
+ result: resultStr
792
+ }
793
+ }));
794
+ console.log(`✓ Submitted tool result for call ${callID}`);
795
+ } else {
796
+ console.warn('Not connected - cannot submit tool result');
797
+ }
798
+ }
799
+
781
800
  /**
782
801
  * Get full conversation transcript
783
802
  */
@@ -3,7 +3,7 @@ const PANEL_CSS = /*css*/ `
3
3
  position: relative;
4
4
  width: 100%;
5
5
  aspect-ratio: 16 / 9;
6
- max-height: clamp(400px, 50vh, 800px);
6
+ max-height: clamp(200px, 50vh, 800px);
7
7
  display: flex;
8
8
  flex-direction: column;
9
9
  align-items: center;
@@ -12,8 +12,9 @@ const PANEL_CSS = /*css*/ `
12
12
  margin: 0;
13
13
  background: var(--cv-bg, #0a0a0a);
14
14
  box-shadow: inset 0 10px 40px rgba(0, 0, 0, 0.1), inset 0 0 100px rgba(0, 0, 0, 0.05);
15
- border-radius: clamp(20px, 5vw, 40px);
15
+ border-radius: clamp(12px, 4vw, 40px);
16
16
  overflow: hidden;
17
+ container-type: size;
17
18
  }
18
19
  .cv-curtain {
19
20
  position: absolute;
@@ -215,29 +216,73 @@ const PANEL_CSS = /*css*/ `
215
216
  .cv-error.is-visible { display: flex; }
216
217
  .cv-error-icon { color: var(--cv-accent); flex-shrink: 0; }
217
218
 
218
- @media (max-width: 768px) {
219
- .cv-panel { max-height: 600px; border-radius: 24px; }
220
- .cv-curtain-content { padding: clamp(0.75rem, 3vw, 1.5rem); gap: clamp(0.5rem, 2vw, 1rem); }
221
- .cv-curtain-title { font-size: clamp(1rem, 5vw, 1.8rem); }
222
- .cv-curtain-desc { font-size: clamp(0.65rem, 2.5vw, 0.95rem); max-width: 90vw; }
223
- .cv-curtain-btn { padding: clamp(0.45rem, 1.5vw, 0.75rem) clamp(1rem, 3vw, 2rem); font-size: clamp(0.65rem, 1.5vw, 0.9rem); }
224
- .cv-visualizer-wrap { width: clamp(100px, 45vw, 220px); height: clamp(100px, 45vw, 220px); }
225
- .cv-title { font-size: clamp(0.9rem, 2vw, 1.5rem); gap: clamp(0.5rem, 1vw, 0.75rem); }
226
- .cv-controls { gap: clamp(1rem, 2vw, 1.5rem); padding-bottom: clamp(1rem, 2vw, 1.5rem); }
227
- .cv-pill { padding: clamp(0.2rem, 1vw, 0.4rem) clamp(0.5rem, 1.5vw, 0.75rem); font-size: clamp(0.65rem, 1.5vw, 0.75rem); }
228
- .cv-btn { padding: clamp(0.25rem, 1vw, 0.35rem) clamp(0.5rem, 1.5vw, 0.75rem); font-size: clamp(0.65rem, 1.5vw, 0.75rem); }
229
- .cv-error { padding: clamp(0.5rem, 1.5vw, 0.75rem) clamp(1rem, 2vw, 1.5rem); font-size: clamp(0.75rem, 1.5vw, 0.875rem); }
230
- }
231
-
232
- @media (max-width: 480px) {
233
- .cv-panel { aspect-ratio: 3 / 4; max-height: 500px; border-radius: 20px; }
234
- .cv-curtain-content { padding: clamp(0.5rem, 2vw, 1rem); gap: clamp(0.4rem, 1.5vw, 0.75rem); }
235
- .cv-curtain-title { font-size: clamp(0.9rem, 4.5vw, 1.4rem); }
236
- .cv-curtain-desc { font-size: clamp(0.6rem, 2vw, 0.8rem); }
237
- .cv-curtain-btn { padding: clamp(0.4rem, 1.2vw, 0.6rem) clamp(0.8rem, 2.5vw, 1.5rem); font-size: clamp(0.6rem, 1.2vw, 0.8rem); }
238
- .cv-visualizer-wrap { width: clamp(80px, 40vw, 180px); height: clamp(80px, 40vw, 180px); }
239
- .cv-header { padding-top: clamp(1rem, 2vw, 1.5rem); }
240
- .cv-controls { gap: clamp(0.8rem, 1.5vw, 1.2rem); padding-bottom: clamp(0.8rem, 1.5vw, 1.2rem); }
219
+ /* === COMPACT MODE: < 300px width === */
220
+ @container (max-width: 299px) {
221
+ .cv-curtain-content { padding: 0.5rem; gap: 0.3rem; }
222
+ .cv-curtain-title { font-size: 0.8rem; }
223
+ .cv-curtain-desc { display: none; }
224
+ .cv-curtain-btn { padding: 0.3rem 0.6rem; font-size: 0.6rem; gap: 0.3rem; }
225
+ .cv-curtain-btn svg { display: none; }
226
+ .cv-visualizer-wrap { width: 60px; height: 60px; }
227
+ .cv-header { padding-top: 0.75rem; }
228
+ .cv-title { font-size: 0.7rem; gap: 0.3rem; }
229
+ .cv-title .cv-timer { display: none; }
230
+ .cv-controls { gap: 0.6rem; padding-bottom: 0.6rem; }
231
+ .cv-pill { padding: 0.15rem 0.4rem; gap: 0.3rem; }
232
+ .cv-btn { padding: 0.2rem 0.4rem; font-size: 0.6rem; gap: 0; }
233
+ .cv-btn span { display: none; }
234
+ .cv-btn svg { width: 16px; height: 16px; }
235
+ .cv-error { padding: 0.4rem 0.8rem; font-size: 0.65rem; bottom: 0.5rem; }
236
+ }
237
+
238
+ /* === SMALL MODE: 300px - 480px width === */
239
+ @container (min-width: 300px) and (max-width: 480px) {
240
+ .cv-curtain-content { padding: 0.75rem; gap: 0.5rem; }
241
+ .cv-curtain-title { font-size: clamp(0.9rem, 3cqw, 1.2rem); }
242
+ .cv-curtain-desc { font-size: clamp(0.6rem, 2cqw, 0.8rem); }
243
+ .cv-curtain-btn { padding: clamp(0.3rem, 1cqw, 0.5rem) clamp(0.6rem, 2cqw, 1rem); font-size: clamp(0.6rem, 1.5cqw, 0.8rem); }
244
+ .cv-visualizer-wrap { width: clamp(80px, 35cqw, 140px); height: clamp(80px, 35cqw, 140px); }
245
+ .cv-header { padding-top: 0.8rem; }
246
+ .cv-title { font-size: clamp(0.7rem, 2.5cqw, 1rem); gap: 0.4rem; }
247
+ .cv-title .cv-timer { font-size: 0.65em; }
248
+ .cv-controls { gap: clamp(0.6rem, 1.5cqw, 1rem); padding-bottom: clamp(0.6rem, 1.5cqw, 1rem); }
249
+ .cv-pill { padding: clamp(0.15rem, 0.5cqw, 0.25rem) clamp(0.35rem, 1cqw, 0.6rem); font-size: 0.65rem; gap: 0.3rem; }
250
+ .cv-btn { padding: clamp(0.2rem, 0.5cqw, 0.3rem) clamp(0.35rem, 1cqw, 0.6rem); font-size: clamp(0.6rem, 1.2cqw, 0.7rem); }
251
+ .cv-btn span:last-child { display: none; }
252
+ .cv-error { padding: clamp(0.4rem, 1cqw, 0.6rem) clamp(0.8rem, 1.5cqw, 1.2rem); font-size: 0.7rem; }
253
+ }
254
+
255
+ /* === MEDIUM MODE: 480px - 768px width === */
256
+ @container (min-width: 480px) and (max-width: 768px) {
257
+ .cv-panel { max-height: 600px; aspect-ratio: 3 / 4; }
258
+ .cv-curtain-content { padding: clamp(0.75rem, 2cqw, 1.25rem); gap: clamp(0.5rem, 1.5cqw, 1rem); }
259
+ .cv-curtain-title { font-size: clamp(1rem, 4cqw, 1.6rem); }
260
+ .cv-curtain-desc { font-size: clamp(0.7rem, 2.5cqw, 1rem); }
261
+ .cv-curtain-btn { padding: clamp(0.45rem, 1.5cqw, 0.7rem) clamp(1rem, 2cqw, 1.5rem); font-size: clamp(0.7rem, 1.5cqw, 0.9rem); }
262
+ .cv-visualizer-wrap { width: clamp(100px, 40cqw, 200px); height: clamp(100px, 40cqw, 200px); }
263
+ .cv-header { padding-top: clamp(1rem, 1.5cqw, 1.5rem); }
264
+ .cv-title { font-size: clamp(0.9rem, 3cqw, 1.3rem); gap: clamp(0.4rem, 1cqw, 0.75rem); }
265
+ .cv-title .cv-timer { font-size: 0.85em; }
266
+ .cv-controls { gap: clamp(0.8rem, 1.5cqw, 1.2rem); padding-bottom: clamp(0.8rem, 1.5cqw, 1.2rem); }
267
+ .cv-pill { padding: clamp(0.2rem, 0.75cqw, 0.3rem) clamp(0.5rem, 1.2cqw, 0.75rem); font-size: 0.7rem; }
268
+ .cv-btn { padding: clamp(0.25rem, 0.75cqw, 0.35rem) clamp(0.5rem, 1.2cqw, 0.75rem); font-size: clamp(0.65rem, 1.2cqw, 0.8rem); }
269
+ .cv-error { padding: clamp(0.5rem, 1.2cqw, 0.75rem) clamp(1rem, 1.5cqw, 1.5rem); font-size: clamp(0.7rem, 1.2cqw, 0.85rem); }
270
+ }
271
+
272
+ /* === LARGE MODE: > 768px width === */
273
+ @container (min-width: 768px) {
274
+ .cv-curtain-content { padding: clamp(1rem, 2.5cqw, 2rem); gap: clamp(0.75rem, 2cqw, 1.5rem); }
275
+ .cv-curtain-title { font-size: clamp(1.2rem, 5cqw, 2.5rem); }
276
+ .cv-curtain-desc { font-size: clamp(0.8rem, 2.5cqw, 1.2rem); max-width: 500px; }
277
+ .cv-curtain-btn { padding: clamp(0.6rem, 2cqw, 1rem) clamp(1.5rem, 3cqw, 2.5rem); font-size: clamp(0.8rem, 1.5cqw, 1.1rem); }
278
+ .cv-visualizer-wrap { width: clamp(140px, 45cqw, 300px); height: clamp(140px, 45cqw, 300px); }
279
+ .cv-header { padding-top: clamp(1.5rem, 2cqw, 2rem); }
280
+ .cv-title { font-size: clamp(1rem, 3cqw, 1.8rem); gap: clamp(0.75rem, 1.5cqw, 1.2rem); }
281
+ .cv-title .cv-timer { font-size: 0.9em; }
282
+ .cv-controls { gap: clamp(1.2rem, 2cqw, 1.8rem); padding-bottom: clamp(1.2rem, 2cqw, 1.8rem); }
283
+ .cv-pill { padding: clamp(0.3rem, 0.8cqw, 0.4rem) clamp(0.75rem, 1.2cqw, 1rem); font-size: 0.85rem; gap: 0.75rem; }
284
+ .cv-btn { padding: clamp(0.35rem, 0.8cqw, 0.4rem) clamp(0.75rem, 1.2cqw, 1rem); font-size: clamp(0.75rem, 1.2cqw, 0.9rem); }
285
+ .cv-error { padding: clamp(0.75rem, 1.5cqw, 1rem) clamp(1.5rem, 2cqw, 2rem); font-size: clamp(0.85rem, 1cqw, 1rem); }
241
286
  }
242
287
  `;
243
288