infinicode 2.8.67 → 2.8.69
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.
|
@@ -29,46 +29,39 @@ export const DASHBOARD_HTML = `<!doctype html>
|
|
|
29
29
|
<title>RoboPark Control</title>
|
|
30
30
|
<style>
|
|
31
31
|
/* ── premium tech glass theme ── dark is the committed default; light is a frosted toggle ── */
|
|
32
|
-
:root{
|
|
33
|
-
--bg:#
|
|
34
|
-
--grad: radial-gradient(
|
|
35
|
-
radial-gradient(
|
|
36
|
-
radial-gradient(
|
|
37
|
-
linear-gradient(
|
|
38
|
-
--panel: rgba(
|
|
39
|
-
--glass-border: rgba(255,
|
|
40
|
-
--border: rgba(255,
|
|
41
|
-
--ink:#
|
|
42
|
-
--gold:#
|
|
32
|
+
:root{
|
|
33
|
+
--bg:#050504;
|
|
34
|
+
--grad: radial-gradient(900px 520px at 7% -8%, rgba(255,198,79,0.18), transparent 64%),
|
|
35
|
+
radial-gradient(760px 520px at 98% 4%, rgba(161,105,16,0.16), transparent 62%),
|
|
36
|
+
radial-gradient(650px 520px at 62% 112%, rgba(255,211,123,0.08), transparent 68%),
|
|
37
|
+
linear-gradient(145deg,#030303 0%,#0b0905 46%,#050504 100%);
|
|
38
|
+
--panel: rgba(16,14,10,0.64); --panel-2: rgba(27,23,15,0.68); --panel-solid:#0d0b08;
|
|
39
|
+
--glass-border: rgba(255,224,151,0.14); --glass-hi: rgba(255,241,204,0.09);
|
|
40
|
+
--border: rgba(255,224,151,0.12); --border-strong: rgba(255,205,93,0.52);
|
|
41
|
+
--ink:#F6F0E3; --muted:#A99D87;
|
|
42
|
+
--gold:#C9962E; --gold-bright:#F6D77B; --gold-pale:#FFF0BE; --gold-deep:#78520F;
|
|
43
43
|
--ok:#6FE0A6; --ok-bg:rgba(28,64,50,0.55); --warn:#F2C14E; --warn-bg:rgba(64,50,20,0.5);
|
|
44
44
|
--bad:#FF7E6E; --bad-bg:rgba(64,24,20,0.55); --info:#78BBFF; --info-bg:rgba(20,44,66,0.55);
|
|
45
|
-
--shadow: 0
|
|
46
|
-
--mono:
|
|
47
|
-
--sans:
|
|
45
|
+
--shadow: 0 18px 55px rgba(0,0,0,0.56),0 2px 12px rgba(0,0,0,0.36);
|
|
46
|
+
--mono:"Cascadia Code","SFMono-Regular",Consolas,monospace;
|
|
47
|
+
--sans:"Trebuchet MS","Segoe UI",sans-serif;
|
|
48
|
+
--display:"Palatino Linotype","Book Antiqua",Palatino,serif;
|
|
48
49
|
}
|
|
49
50
|
@media (prefers-color-scheme:dark){:root{}}
|
|
50
51
|
:root[data-theme="dark"]{}
|
|
51
|
-
:root[data-theme="light"]{
|
|
52
|
-
--bg:#
|
|
53
|
-
--
|
|
54
|
-
|
|
55
|
-
linear-gradient(160deg,#F3EFFB 0%,#ECEAF7 50%,#F5F0E4 100%);
|
|
56
|
-
--panel: rgba(255,255,255,0.62); --panel-2: rgba(255,255,255,0.78); --panel-solid:#FBF7EE;
|
|
57
|
-
--glass-border: rgba(90,70,20,0.16); --glass-hi: rgba(255,255,255,0.7);
|
|
58
|
-
--border: rgba(90,70,20,0.16); --border-strong: rgba(185,120,22,0.55);
|
|
59
|
-
--ink:#241A08; --muted:#6E5A3E;
|
|
60
|
-
--gold:#8A5A0C; --gold-bright:#B9781A;
|
|
61
|
-
--ok:#1F7A4C; --ok-bg:rgba(180,220,190,0.6); --warn:#8A6410; --warn-bg:rgba(240,225,180,0.7);
|
|
62
|
-
--bad:#B5382E; --bad-bg:rgba(240,205,200,0.7); --info:#1F6F9E; --info-bg:rgba(200,225,240,0.7);
|
|
63
|
-
--shadow: 0 10px 30px rgba(60,40,10,0.14);
|
|
52
|
+
:root[data-theme="light"]{
|
|
53
|
+
--bg:#090806;--panel:rgba(24,20,13,.72);--panel-2:rgba(38,31,18,.76);--panel-solid:#100e09;
|
|
54
|
+
--ink:#FFF8E8;--muted:#B5A88F;--glass-border:rgba(255,224,151,.17);--glass-hi:rgba(255,244,214,.1);
|
|
55
|
+
--border:rgba(255,224,151,.14);--border-strong:rgba(255,205,93,.58);--gold:#D3A43D;--gold-bright:#FFE094;
|
|
64
56
|
}
|
|
65
57
|
*{box-sizing:border-box;margin:0;padding:0}
|
|
66
58
|
html,body{height:100%}
|
|
67
|
-
body{background:var(--bg);background-image:var(--grad);background-attachment:fixed;background-size:cover;
|
|
68
|
-
color:var(--ink);font-family:var(--sans);line-height:1.45;-webkit-font-smoothing:antialiased;}
|
|
59
|
+
body{background:var(--bg);background-image:var(--grad);background-attachment:fixed;background-size:cover;
|
|
60
|
+
color:var(--ink);font-family:var(--sans);line-height:1.45;-webkit-font-smoothing:antialiased;}
|
|
61
|
+
body:before{content:"";position:fixed;inset:0;pointer-events:none;z-index:-1;opacity:.22;background-image:linear-gradient(rgba(255,221,140,.025) 1px,transparent 1px),linear-gradient(90deg,rgba(255,221,140,.025) 1px,transparent 1px);background-size:42px 42px;mask-image:linear-gradient(to bottom,black,transparent 82%);}
|
|
69
62
|
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums;}
|
|
70
|
-
.glass{background:var(--panel);-webkit-backdrop-filter:blur(16px) saturate(1.3);backdrop-filter:blur(16px) saturate(1.3);
|
|
71
|
-
border:1px solid var(--glass-border);box-shadow:var(--shadow),inset 0 1px 0 var(--glass-hi);}
|
|
63
|
+
.glass{background:var(--panel);-webkit-backdrop-filter:blur(16px) saturate(1.3);backdrop-filter:blur(16px) saturate(1.3);
|
|
64
|
+
border:1px solid var(--glass-border);box-shadow:var(--shadow),inset 0 1px 0 var(--glass-hi),inset 0 -1px 0 rgba(0,0,0,.5);}
|
|
72
65
|
|
|
73
66
|
/* top bar */
|
|
74
67
|
header.bar{display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap;
|
|
@@ -80,7 +73,7 @@ header.bar{display:flex;align-items:center;justify-content:space-between;gap:1re
|
|
|
80
73
|
.livedot.stale{background:var(--muted);box-shadow:none;animation:none;}
|
|
81
74
|
@keyframes pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--ok) 55%,transparent),0 0 12px var(--ok)}70%{box-shadow:0 0 0 7px transparent,0 0 12px var(--ok)}100%{box-shadow:0 0 0 0 transparent,0 0 12px var(--ok)}}
|
|
82
75
|
@media (prefers-reduced-motion:reduce){.livedot{animation:none}}
|
|
83
|
-
.brand b{font-size:
|
|
76
|
+
.brand b{font-family:var(--display);font-size:1.08rem;letter-spacing:.015em;color:var(--gold-pale);text-shadow:0 0 24px rgba(246,215,123,.2);}
|
|
84
77
|
.brand .who{font-family:var(--mono);font-size:0.72rem;color:var(--muted);}
|
|
85
78
|
.chips{display:flex;gap:0.45rem;flex-wrap:wrap;align-items:center;}
|
|
86
79
|
.chip{font-family:var(--mono);font-size:0.68rem;padding:0.28em 0.62em;border-radius:100px;border:1px solid var(--glass-border);
|
|
@@ -532,21 +525,49 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
532
525
|
.rp-modal-body pre{background:var(--panel-solid);border:1px solid var(--glass-border);border-radius:8px;padding:0.5rem 0.7rem;
|
|
533
526
|
font-size:0.66rem;max-height:240px;overflow:auto;white-space:pre-wrap;word-break:break-word;color:var(--ink);}
|
|
534
527
|
|
|
535
|
-
.rp-call-shell{
|
|
536
|
-
.rp-call-
|
|
537
|
-
.rp-call-
|
|
538
|
-
.rp-call-
|
|
539
|
-
.rp-call-
|
|
540
|
-
.rp-call-
|
|
541
|
-
.rp-call-
|
|
542
|
-
.rp-call-
|
|
543
|
-
.rp-call-
|
|
544
|
-
.rp-call-
|
|
545
|
-
.rp-call-
|
|
546
|
-
.rp-
|
|
547
|
-
.rp-
|
|
548
|
-
.rp-
|
|
549
|
-
.rp-
|
|
528
|
+
.rp-call-shell{position:relative;min-height:720px;overflow:hidden;border:1px solid var(--glass-border);border-radius:24px;background:linear-gradient(145deg,rgba(18,15,9,.84),rgba(5,5,4,.9));box-shadow:0 30px 90px rgba(0,0,0,.7),inset 0 1px 0 rgba(255,238,194,.11);}
|
|
529
|
+
.rp-call-shell:before{content:"";position:absolute;width:520px;height:520px;border-radius:50%;left:18%;top:-340px;background:rgba(246,215,123,.15);filter:blur(75px);pointer-events:none;}
|
|
530
|
+
.rp-call-top{height:58px;padding:0 1.1rem;display:flex;align-items:center;gap:.75rem;border-bottom:1px solid var(--glass-border);background:rgba(8,7,5,.56);backdrop-filter:blur(24px);position:relative;z-index:3;}
|
|
531
|
+
.rp-call-top .eyebrow{font-family:var(--mono);font-size:.57rem;letter-spacing:.16em;color:var(--gold);text-transform:uppercase;}
|
|
532
|
+
.rp-call-top .title{font-family:var(--display);font-size:1.02rem;color:var(--gold-pale);letter-spacing:.03em;}
|
|
533
|
+
.rp-call-top .session{margin-left:auto;font-family:var(--mono);font-size:.58rem;color:var(--muted);max-width:32ch;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
|
|
534
|
+
.rp-call-grid{display:grid;grid-template-columns:280px minmax(380px,1fr) 330px;gap:1px;background:var(--glass-border);min-height:662px;position:relative;z-index:2;}
|
|
535
|
+
.rp-call-rail,.rp-call-stage,.rp-call-chat{background:rgba(8,7,5,.82);padding:1rem;min-width:0;}
|
|
536
|
+
.rp-call-rail{display:flex;flex-direction:column;gap:.8rem;}
|
|
537
|
+
.rp-call-card{border:1px solid var(--glass-border);border-radius:16px;background:linear-gradient(145deg,rgba(38,31,18,.58),rgba(13,11,8,.66));box-shadow:inset 0 1px 0 var(--glass-hi),0 12px 35px rgba(0,0,0,.25);padding:.8rem;}
|
|
538
|
+
.rp-call-character{position:relative;display:flex;align-items:center;gap:.75rem;padding:.75rem;border:1px solid rgba(246,215,123,.2);border-radius:15px;background:radial-gradient(circle at 12% 10%,rgba(246,215,123,.15),transparent 52%),rgba(16,14,10,.65);overflow:hidden;}
|
|
539
|
+
.rp-call-character img{width:76px;height:76px;object-fit:contain;filter:drop-shadow(0 10px 20px rgba(0,0,0,.48));}
|
|
540
|
+
.rp-call-character .name{font-family:var(--display);font-size:1.18rem;color:var(--gold-pale);font-weight:700;}
|
|
541
|
+
.rp-call-character .meta{font-size:.64rem;line-height:1.4;}
|
|
542
|
+
.rp-call-service-grid{display:grid;gap:.4rem;}
|
|
543
|
+
.rp-call-service{display:grid;grid-template-columns:29px 1fr auto;align-items:center;gap:.45rem;padding:.48rem;border:1px solid var(--glass-border);border-radius:10px;background:rgba(255,255,255,.018);}
|
|
544
|
+
.rp-call-service .ico{width:29px;height:29px;display:grid;place-items:center;border-radius:8px;background:rgba(246,215,123,.09);color:var(--gold-bright);font-size:.75rem;}
|
|
545
|
+
.rp-call-service b{display:block;font-size:.64rem;color:var(--ink);}.rp-call-service small{display:block;font-family:var(--mono);font-size:.52rem;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:130px;}
|
|
546
|
+
.rp-call-service .ready{font-family:var(--mono);font-size:.48rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ok);}
|
|
547
|
+
.rp-call-device{display:grid;gap:.22rem;margin-top:.45rem}.rp-call-device:first-child{margin-top:0}.rp-call-device label{font-family:var(--mono);font-size:.51rem;text-transform:uppercase;letter-spacing:.1em;color:var(--muted)}
|
|
548
|
+
.rp-call-device select{width:100%;min-width:0;font-family:var(--mono);font-size:.62rem;background:#0c0a07;border:1px solid var(--glass-border);color:var(--ink);border-radius:9px;padding:.42rem .5rem;}
|
|
549
|
+
.rp-call-stage{display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:hidden;}
|
|
550
|
+
.rp-call-stage:before{content:"";position:absolute;width:420px;height:420px;border:1px solid rgba(246,215,123,.08);border-radius:50%;box-shadow:0 0 0 42px rgba(246,215,123,.018),0 0 0 92px rgba(246,215,123,.012);}
|
|
551
|
+
.rp-call-visual{position:relative;width:min(330px,80%);aspect-ratio:1;border-radius:50%;display:grid;place-items:center;background:radial-gradient(circle,rgba(246,215,123,.14),rgba(10,8,5,.58) 52%,rgba(0,0,0,.82) 72%);border:1px solid rgba(246,215,123,.24);box-shadow:0 0 70px rgba(201,150,46,.13),inset 0 0 48px rgba(246,215,123,.06);z-index:1;transition:box-shadow .3s,border-color .3s;}
|
|
552
|
+
.rp-call-visual.speaking{box-shadow:0 0 95px rgba(246,215,123,.28),inset 0 0 55px rgba(246,215,123,.11);border-color:rgba(255,229,157,.55)}
|
|
553
|
+
.rp-call-avatar{position:absolute;width:58%;height:58%;object-fit:contain;filter:drop-shadow(0 18px 30px rgba(0,0,0,.65));opacity:.96;}
|
|
554
|
+
.rp-call-avatar:not([src]){display:none}
|
|
555
|
+
.rp-call-avatar-fallback{position:absolute;width:128px;height:128px;border-radius:50%;display:grid;place-items:center;font-family:var(--display);font-size:2.8rem;letter-spacing:.08em;color:var(--gold-pale);background:radial-gradient(circle at 32% 24%,rgba(255,234,174,.18),rgba(201,150,46,.07) 48%,rgba(0,0,0,.2));border:1px solid rgba(246,215,123,.2);box-shadow:inset 0 0 34px rgba(246,215,123,.06),0 18px 45px rgba(0,0,0,.42);}
|
|
556
|
+
.rp-call-avatar[src]{z-index:1}.rp-call-avatar[src]+.rp-call-avatar-fallback{display:none}
|
|
557
|
+
.rp-call-bars{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;gap:7px;opacity:.82}.rp-call-bars i{width:5px;height:16px;border-radius:8px;background:linear-gradient(var(--gold-pale),var(--gold));box-shadow:0 0 12px rgba(246,215,123,.35);transition:height .09s ease;}
|
|
558
|
+
.rp-call-ring{position:absolute;inset:-10px;border:1px solid rgba(246,215,123,.13);border-radius:50%;animation:rp-call-spin 18s linear infinite}.rp-call-ring:before,.rp-call-ring:after{content:"";position:absolute;width:7px;height:7px;border-radius:50%;background:var(--gold-bright);box-shadow:0 0 15px var(--gold-bright)}.rp-call-ring:before{left:15%;top:12%}.rp-call-ring:after{right:10%;bottom:18%}
|
|
559
|
+
@keyframes rp-call-spin{to{transform:rotate(360deg)}}
|
|
560
|
+
.rp-call-agent-state{position:relative;z-index:2;margin-top:1.15rem;text-align:center}.rp-call-agent-state strong{display:block;font-family:var(--display);font-size:1.35rem;color:var(--gold-pale);font-weight:500}.rp-call-agent-state span{font-family:var(--mono);font-size:.55rem;letter-spacing:.13em;color:var(--muted);text-transform:uppercase}
|
|
561
|
+
.rp-call-state{display:flex;align-items:center;justify-content:center;gap:.5rem;font-family:var(--mono);font-size:.62rem;padding:.55rem 0;position:relative;z-index:2;}
|
|
562
|
+
.rp-call-orb{width:8px;height:8px;border-radius:50%;background:var(--muted)}.rp-call-orb.live{background:var(--ok);box-shadow:0 0 12px var(--ok);animation:pulse 1.6s infinite}.rp-call-orb.busy{background:var(--gold-bright);box-shadow:0 0 12px var(--gold-bright);animation:pulse 1s infinite}
|
|
563
|
+
.rp-call-latency{position:relative;z-index:2;display:grid;grid-template-columns:repeat(3,1fr);gap:.4rem;width:min(420px,92%);margin-top:.65rem}.rp-call-latency div{padding:.48rem;border:1px solid var(--glass-border);border-radius:10px;background:rgba(0,0,0,.28);text-align:center}.rp-call-latency b{display:block;font-family:var(--mono);font-size:.72rem;color:var(--gold-bright)}.rp-call-latency span{font-family:var(--mono);font-size:.46rem;text-transform:uppercase;letter-spacing:.08em;color:var(--muted)}
|
|
564
|
+
.rp-call-media{position:absolute;right:1rem;top:1rem;width:128px;aspect-ratio:4/3;border:1px solid var(--glass-border);border-radius:12px;background:#050504;overflow:hidden;display:none;z-index:4;box-shadow:var(--shadow)}.rp-call-media.on{display:block}.rp-call-media video{width:100%;height:100%;object-fit:cover}.rp-call-media .tag{position:absolute;left:.35rem;bottom:.3rem;font-family:var(--mono);font-size:.46rem;color:var(--gold-pale);background:rgba(0,0,0,.7);padding:.12rem .3rem;border-radius:4px}
|
|
565
|
+
.rp-call-controls{position:relative;z-index:3;display:flex;align-items:center;justify-content:center;gap:.52rem;margin-top:1rem;flex-wrap:wrap}.rp-call-ctl{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;border:1px solid var(--glass-border);background:rgba(255,255,255,.035);color:var(--ink);cursor:pointer;font-size:1rem;transition:.18s}.rp-call-ctl:hover:not(:disabled){transform:translateY(-2px);border-color:var(--gold-bright);color:var(--gold-bright);box-shadow:0 7px 24px rgba(0,0,0,.38)}.rp-call-ctl.on{background:rgba(246,215,123,.12);border-color:rgba(246,215,123,.46);color:var(--gold-bright)}.rp-call-ctl.danger{background:rgba(255,78,63,.13);border-color:rgba(255,126,110,.35);color:var(--bad)}.rp-call-ctl:disabled{opacity:.32;cursor:not-allowed}.rp-call-start{width:auto;border-radius:100px;padding:0 1.15rem;font-family:var(--mono);font-size:.61rem;text-transform:uppercase;letter-spacing:.08em;background:linear-gradient(135deg,#ffe59a,#b77b16);color:#201401;border-color:#ffdc7d;font-weight:700}
|
|
566
|
+
.rp-call-chat{display:flex;flex-direction:column;min-height:0}.rp-call-chat-head{display:flex;align-items:center;gap:.45rem;padding-bottom:.65rem;border-bottom:1px solid var(--glass-border)}.rp-call-chat-head b{font-family:var(--display);font-size:.94rem;color:var(--gold-pale)}.rp-call-chat-head button{margin-left:auto;background:none;border:0;color:var(--muted);font-family:var(--mono);font-size:.55rem;cursor:pointer}.rp-call-chat-head button:hover{color:var(--gold-bright)}
|
|
567
|
+
.rp-call-transcript{height:500px;overflow-y:auto;display:flex;flex-direction:column;gap:.55rem;padding:.7rem .15rem;scrollbar-color:var(--gold-deep) transparent}.rp-call-transcript.collapsed{display:none}
|
|
568
|
+
.rp-turn{max-width:90%;border:1px solid var(--glass-border);border-radius:14px;padding:.6rem .7rem;font-size:.71rem;line-height:1.5;background:rgba(255,255,255,.025);box-shadow:0 8px 22px rgba(0,0,0,.2)}.rp-turn.user{align-self:flex-end;border-color:rgba(246,215,123,.22);background:linear-gradient(145deg,rgba(201,150,46,.13),rgba(255,255,255,.025));border-bottom-right-radius:4px}.rp-turn.assistant{align-self:flex-start;border-color:rgba(246,215,123,.38);border-bottom-left-radius:4px}.rp-turn .who{font-family:var(--mono);font-size:.5rem;text-transform:uppercase;letter-spacing:.1em;color:var(--gold);margin-bottom:.2rem}
|
|
569
|
+
.rp-call-compose{display:flex;gap:.4rem;margin-top:auto;padding-top:.65rem;border-top:1px solid var(--glass-border)}.rp-call-compose input{flex:1;min-width:0;background:#0c0a07;border:1px solid var(--glass-border);color:var(--ink);border-radius:11px;padding:.58rem .65rem;font-size:.7rem}.rp-call-compose input:focus{outline:none;border-color:var(--gold-bright);box-shadow:0 0 0 3px rgba(246,215,123,.08)}.rp-call-compose button{width:38px;border-radius:11px;border:1px solid rgba(246,215,123,.38);background:rgba(246,215,123,.1);color:var(--gold-bright);cursor:pointer}
|
|
570
|
+
.rp-call-event{min-height:42px;margin-top:.65rem;padding:.5rem .6rem;border:1px solid var(--glass-border);border-radius:10px;background:rgba(0,0,0,.22);font-family:var(--mono);font-size:.54rem;color:var(--muted);line-height:1.45}.rp-call-event b{color:var(--gold-bright)}
|
|
550
571
|
.rp-detail-hero{display:flex;align-items:center;gap:.8rem;padding:.6rem;border:1px solid var(--glass-border);border-radius:12px;background:var(--panel-2);margin-bottom:.8rem;}
|
|
551
572
|
.rp-detail-hero img{width:72px;height:72px;object-fit:contain;}
|
|
552
573
|
.rp-pipeline{display:flex;flex-direction:column;gap:.3rem;margin-top:.5rem;}
|
|
@@ -556,7 +577,8 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
556
577
|
.node .node-avatar{width:68px;height:68px;object-fit:contain;flex:none;filter:drop-shadow(0 7px 12px rgba(0,0,0,.3));}
|
|
557
578
|
.node .node-health{font-family:var(--mono);font-size:.61rem;line-height:1.45;color:var(--muted);}
|
|
558
579
|
.node .node-health b{color:var(--ink);}
|
|
559
|
-
@media(max-width:
|
|
580
|
+
@media(max-width:1150px){.rp-call-grid{grid-template-columns:250px minmax(360px,1fr)}.rp-call-chat{grid-column:1/-1;min-height:390px}.rp-call-transcript{height:280px}}
|
|
581
|
+
@media(max-width:760px){.rp-call-shell{border-radius:15px}.rp-call-grid{display:block}.rp-call-rail,.rp-call-stage,.rp-call-chat{border-bottom:1px solid var(--glass-border)}.rp-call-stage{min-height:590px}.rp-call-top .session{display:none}.rp-call-visual{width:min(285px,78vw)}.rp-call-transcript{height:320px}.rp-pipeline-row{grid-template-columns:62px 105px 58px 1fr}}
|
|
560
582
|
|
|
561
583
|
/* ── TTS voice picker (used inside the generic modal) ── */
|
|
562
584
|
.rp-voice-picker{display:flex;flex-direction:column;gap:0.6rem;min-height:320px;}
|
|
@@ -729,23 +751,64 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
729
751
|
<!-- ═══ History ═══ -->
|
|
730
752
|
<div class="rp-sub" id="rp-sub-voice">
|
|
731
753
|
<div class="rp-call-shell">
|
|
732
|
-
<div class="rp-call-
|
|
733
|
-
<div class="
|
|
734
|
-
<div class="
|
|
735
|
-
<div class="rp-field"><label>Character preset</label><select id="rp-call-character-select"><option value="">select character...</option></select></div>
|
|
736
|
-
<div class="rp-field" style="margin-top:.55rem"><label>Voice stack</label><select id="rp-call-stack-select"><option value="">character default</option></select></div>
|
|
737
|
-
<div class="rp-call-state"><span class="rp-call-orb" id="rp-call-orb"></span><span id="rp-call-status">ready to start</span></div>
|
|
738
|
-
<div class="rp-call-actions">
|
|
739
|
-
<button class="rp-btn primary" id="rp-call-start">Start voice call</button>
|
|
740
|
-
<button class="rp-btn" id="rp-call-mute" disabled>Mute microphone</button>
|
|
741
|
-
<button class="rp-btn danger" id="rp-call-end" disabled>End call</button>
|
|
742
|
-
</div>
|
|
743
|
-
<div class="pk-note" style="margin-top:.7rem">Uses your browser microphone. Agent audio plays here and every final transcript turn is saved to session history.</div>
|
|
754
|
+
<div class="rp-call-top">
|
|
755
|
+
<div><div class="eyebrow">RoboVoice operator channel</div><div class="title">Royal Voice Studio</div></div>
|
|
756
|
+
<div class="session" id="rp-call-session">No active session</div>
|
|
744
757
|
</div>
|
|
745
|
-
<div class="rp-call-
|
|
746
|
-
<
|
|
747
|
-
|
|
748
|
-
|
|
758
|
+
<div class="rp-call-grid">
|
|
759
|
+
<aside class="rp-call-rail">
|
|
760
|
+
<div class="rp-call-character" id="rp-call-character"><div><div class="name">Choose a character</div><div class="meta">Preset and voice stack are frozen into session history.</div></div></div>
|
|
761
|
+
<div class="rp-call-card">
|
|
762
|
+
<div class="rp-call-device"><label>Character preset</label><select id="rp-call-character-select"><option value="">select character...</option></select></div>
|
|
763
|
+
<div class="rp-call-device"><label>Voice stack</label><select id="rp-call-stack-select"><option value="">character default</option></select></div>
|
|
764
|
+
</div>
|
|
765
|
+
<div class="rp-call-card">
|
|
766
|
+
<div class="rp-section-h" style="margin:0 0 .5rem">Voice pipeline <span class="meta">selected stack</span></div>
|
|
767
|
+
<div class="rp-call-service-grid" id="rp-call-services">
|
|
768
|
+
<div class="rp-call-service"><span class="ico">STT</span><div><b>Speech recognition</b><small>choose a stack</small></div><span class="ready">standby</span></div>
|
|
769
|
+
<div class="rp-call-service"><span class="ico">LLM</span><div><b>Language model</b><small>choose a stack</small></div><span class="ready">standby</span></div>
|
|
770
|
+
<div class="rp-call-service"><span class="ico">TTS</span><div><b>Voice synthesis</b><small>choose a stack</small></div><span class="ready">standby</span></div>
|
|
771
|
+
</div>
|
|
772
|
+
</div>
|
|
773
|
+
<div class="rp-call-card">
|
|
774
|
+
<div class="rp-section-h" style="margin:0 0 .5rem">Browser devices <span class="meta" id="rp-call-device-status">permission on start</span></div>
|
|
775
|
+
<div class="rp-call-device"><label>Microphone</label><select id="rp-call-mic-device"><option value="">system default</option></select></div>
|
|
776
|
+
<div class="rp-call-device"><label>Camera</label><select id="rp-call-cam-device"><option value="">system default</option></select></div>
|
|
777
|
+
<div class="rp-call-device"><label>Speaker output</label><select id="rp-call-speaker-device"><option value="">system default</option></select></div>
|
|
778
|
+
<button class="rp-btn" id="rp-call-refresh-devices" style="width:100%;margin-top:.55rem">Refresh browser devices</button>
|
|
779
|
+
</div>
|
|
780
|
+
</aside>
|
|
781
|
+
<main class="rp-call-stage">
|
|
782
|
+
<div class="rp-call-media" id="rp-call-media"><video id="rp-call-video" autoplay muted playsinline></video><span class="tag" id="rp-call-media-tag">CAMERA</span></div>
|
|
783
|
+
<div class="rp-call-visual" id="rp-call-visual">
|
|
784
|
+
<div class="rp-call-ring"></div>
|
|
785
|
+
<img class="rp-call-avatar" id="rp-call-avatar" alt="" onerror="this.removeAttribute('src')">
|
|
786
|
+
<div class="rp-call-avatar-fallback" id="rp-call-avatar-fallback" aria-hidden="true">RP</div>
|
|
787
|
+
<div class="rp-call-bars" id="rp-call-bars"><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
|
|
788
|
+
</div>
|
|
789
|
+
<div class="rp-call-agent-state"><strong id="rp-call-agent-state">Ready when you are</strong><span id="rp-call-agent-detail">select character and begin</span></div>
|
|
790
|
+
<div class="rp-call-state"><span class="rp-call-orb" id="rp-call-orb"></span><span id="rp-call-status">ready to start</span><span class="mono" id="rp-call-timer">00:00</span></div>
|
|
791
|
+
<div class="rp-call-latency">
|
|
792
|
+
<div><b id="rp-call-lat-total">--</b><span>Total response</span></div>
|
|
793
|
+
<div><b id="rp-call-lat-stt">--</b><span>STT to LLM</span></div>
|
|
794
|
+
<div><b id="rp-call-lat-tts">--</b><span>LLM to TTS</span></div>
|
|
795
|
+
</div>
|
|
796
|
+
<div class="rp-call-controls">
|
|
797
|
+
<button class="rp-call-ctl rp-call-start" id="rp-call-start">Start call</button>
|
|
798
|
+
<button class="rp-call-ctl" id="rp-call-mute" title="Microphone" disabled>MIC</button>
|
|
799
|
+
<button class="rp-call-ctl" id="rp-call-camera" title="Camera" disabled>CAM</button>
|
|
800
|
+
<button class="rp-call-ctl" id="rp-call-screen" title="Share screen" disabled>SCR</button>
|
|
801
|
+
<button class="rp-call-ctl" id="rp-call-chat-toggle" title="Toggle transcript">TXT</button>
|
|
802
|
+
<button class="rp-call-ctl danger" id="rp-call-end" title="End call" disabled>END</button>
|
|
803
|
+
</div>
|
|
804
|
+
<div class="rp-call-event" id="rp-call-event"><b>System</b> Voice pipeline is standing by.</div>
|
|
805
|
+
</main>
|
|
806
|
+
<section class="rp-call-chat">
|
|
807
|
+
<div class="rp-call-chat-head"><b>Conversation</b><span class="chip" id="rp-call-message-count">0 messages</span><button id="rp-call-collapse">collapse transcript</button></div>
|
|
808
|
+
<div class="rp-call-transcript" id="rp-call-transcript"><div class="rp-tbl-empty">Your live transcript and typed messages appear here.</div></div>
|
|
809
|
+
<form class="rp-call-compose" id="rp-call-compose"><input id="rp-call-message" autocomplete="off" placeholder="Type a message to the character..." disabled><button type="submit" id="rp-call-send" disabled>SEND</button></form>
|
|
810
|
+
<div id="rp-call-audio" hidden></div>
|
|
811
|
+
</section>
|
|
749
812
|
</div>
|
|
750
813
|
</div>
|
|
751
814
|
</div>
|
|
@@ -2597,7 +2660,7 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
2597
2660
|
})();
|
|
2598
2661
|
|
|
2599
2662
|
// ── History sub-tab ──
|
|
2600
|
-
var rpVoiceCall={room:null,session:null,eventToken:null,muted:false,ending:false,seen:{}};
|
|
2663
|
+
var rpVoiceCall={room:null,LK:null,session:null,eventToken:null,muted:false,camera:false,screen:false,ending:false,seen:{},messages:0,timer:null,startedAt:0,audioContext:null,analyser:null,audioRaf:0,transcriptCollapsed:false};
|
|
2601
2664
|
function refreshVoiceCallOptions(){
|
|
2602
2665
|
var cs=$('rp-call-character-select'), ss=$('rp-call-stack-select');
|
|
2603
2666
|
if(!cs||!ss) return;
|
|
@@ -2605,19 +2668,35 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
2605
2668
|
cs.innerHTML='<option value="">select character...</option>'+(characterPresets||[]).map(function(c){return '<option value="'+esc(c.id)+'">'+esc(c.name||c.id)+'</option>';}).join('');
|
|
2606
2669
|
ss.innerHTML='<option value="">character default</option>'+(voiceStacks||[]).map(function(s){return '<option value="'+esc(s.id)+'">'+esc(s.name||s.id)+' - '+esc(s.stt_provider)+' / '+esc(s.llm_model)+' / '+esc(s.tts_provider)+'</option>';}).join('');
|
|
2607
2670
|
if(cv) cs.value=cv; if(sv) ss.value=sv;
|
|
2608
|
-
paintVoiceCallCharacter();
|
|
2671
|
+
paintVoiceCallCharacter(); paintVoiceCallStack();
|
|
2609
2672
|
}
|
|
2610
2673
|
function paintVoiceCallCharacter(){
|
|
2611
2674
|
var sel=$('rp-call-character-select'), box=$('rp-call-character'); if(!sel||!box) return;
|
|
2612
2675
|
var chosen=null; for(var i=0;i<characterPresets.length;i++) if(characterPresets[i].id===sel.value){chosen=characterPresets[i];break;}
|
|
2613
|
-
if(!chosen){ box.innerHTML='<div><div class="name">Choose a character</div><div class="meta">
|
|
2676
|
+
if(!chosen){ box.innerHTML='<div><div class="name">Choose a character</div><div class="meta">Preset and voice stack are frozen into session history.</div></div>'; $('rp-call-avatar').removeAttribute('src'); $('rp-call-avatar-fallback').textContent='RP'; return; }
|
|
2614
2677
|
var img=chosen.img||rpAvatarFor(chosen.id||chosen.name);
|
|
2615
2678
|
box.innerHTML=(img?'<img alt="'+esc(chosen.name)+'" src="'+esc(img+QS)+'">':'')+'<div><div class="name">'+esc(chosen.name||chosen.id)+'</div><div class="meta">'+esc(chosen.description||'Ready for an operator voice call')+'</div></div>';
|
|
2679
|
+
$('rp-call-avatar-fallback').textContent=String(chosen.name||chosen.id||'RP').slice(0,2).toUpperCase();
|
|
2680
|
+
if(img)$('rp-call-avatar').src=img+QS;else $('rp-call-avatar').removeAttribute('src');
|
|
2616
2681
|
var stack=$('rp-call-stack-select'); if(stack && !stack.value && chosen.voice_stack_id) stack.value=chosen.voice_stack_id;
|
|
2682
|
+
paintVoiceCallStack();
|
|
2683
|
+
}
|
|
2684
|
+
function selectedVoiceStack(){
|
|
2685
|
+
var sid=$('rp-call-stack-select').value, chosen=null;
|
|
2686
|
+
if(!sid){var cid=$('rp-call-character-select').value;for(var i=0;i<characterPresets.length;i++)if(characterPresets[i].id===cid){sid=characterPresets[i].voice_stack_id||'';break;}}
|
|
2687
|
+
for(var j=0;j<voiceStacks.length;j++)if(voiceStacks[j].id===sid){chosen=voiceStacks[j];break;} return chosen;
|
|
2688
|
+
}
|
|
2689
|
+
function paintVoiceCallStack(){
|
|
2690
|
+
var wrap=$('rp-call-services'); if(!wrap)return; var s=selectedVoiceStack();
|
|
2691
|
+
if(!s){wrap.innerHTML='<div class="rp-call-service"><span class="ico">STT</span><div><b>Speech recognition</b><small>choose a stack</small></div><span class="ready">standby</span></div><div class="rp-call-service"><span class="ico">LLM</span><div><b>Language model</b><small>choose a stack</small></div><span class="ready">standby</span></div><div class="rp-call-service"><span class="ico">TTS</span><div><b>Voice synthesis</b><small>choose a stack</small></div><span class="ready">standby</span></div>';return;}
|
|
2692
|
+
function svc(code,name,provider,model){return '<div class="rp-call-service"><span class="ico">'+code+'</span><div><b>'+esc(name)+'</b><small>'+esc((provider||'default')+' / '+(model||'default'))+'</small></div><span class="ready">ready</span></div>';}
|
|
2693
|
+
wrap.innerHTML=svc('STT','Speech recognition',s.stt_provider,s.stt_model)+svc('LLM','Language model',s.llm_provider,s.llm_model)+svc('TTS','Voice synthesis',s.tts_provider,s.tts_voice);
|
|
2617
2694
|
}
|
|
2618
2695
|
function setVoiceCallStatus(text,state){
|
|
2619
2696
|
var s=$('rp-call-status'), o=$('rp-call-orb'); if(s)s.textContent=text; if(o)o.className='rp-call-orb '+(state||'');
|
|
2620
2697
|
}
|
|
2698
|
+
function setVoiceAgentState(title,detail){if($('rp-call-agent-state'))$('rp-call-agent-state').textContent=title;if($('rp-call-agent-detail'))$('rp-call-agent-detail').textContent=detail||'';}
|
|
2699
|
+
function setVoiceEvent(title,detail){var e=$('rp-call-event');if(e)e.innerHTML='<b>'+esc(title)+'</b> '+esc(detail||'');}
|
|
2621
2700
|
function ensureVoiceLiveKit(){
|
|
2622
2701
|
if(window.LivekitClient) return Promise.resolve(window.LivekitClient);
|
|
2623
2702
|
return new Promise(function(resolve,reject){
|
|
@@ -2633,7 +2712,41 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
2633
2712
|
var div=document.createElement('div'); div.className='rp-turn '+role;
|
|
2634
2713
|
div.innerHTML='<div class="who">'+esc(role==='user'?'operator':'character')+'</div><div>'+esc(text)+'</div>';
|
|
2635
2714
|
wrap.appendChild(div); wrap.scrollTop=wrap.scrollHeight;
|
|
2715
|
+
rpVoiceCall.messages++; if($('rp-call-message-count'))$('rp-call-message-count').textContent=rpVoiceCall.messages+' message'+(rpVoiceCall.messages===1?'':'s');
|
|
2716
|
+
}
|
|
2717
|
+
function fillDeviceSelect(id,devices,kind){
|
|
2718
|
+
var sel=$(id);if(!sel)return;var current=sel.value,rows=devices.filter(function(d){return d.kind===kind;});
|
|
2719
|
+
sel.innerHTML='<option value="">system default</option>'+rows.map(function(d,i){return '<option value="'+esc(d.deviceId)+'">'+esc(d.label||kind+' '+(i+1))+'</option>';}).join('');if(current)sel.value=current;
|
|
2636
2720
|
}
|
|
2721
|
+
function refreshBrowserDevices(requestPermission){
|
|
2722
|
+
if(!navigator.mediaDevices||!navigator.mediaDevices.enumerateDevices){$('rp-call-device-status').textContent='unsupported';return Promise.resolve([]);}
|
|
2723
|
+
var permission=Promise.resolve();
|
|
2724
|
+
if(requestPermission)permission=navigator.mediaDevices.getUserMedia({audio:true}).then(function(stream){stream.getTracks().forEach(function(t){t.stop();});}).catch(function(e){setVoiceEvent('Microphone',e.message||'permission denied');});
|
|
2725
|
+
return permission.then(function(){return navigator.mediaDevices.enumerateDevices();}).then(function(devices){fillDeviceSelect('rp-call-mic-device',devices,'audioinput');fillDeviceSelect('rp-call-cam-device',devices,'videoinput');fillDeviceSelect('rp-call-speaker-device',devices,'audiooutput');$('rp-call-device-status').textContent=devices.length+' detected';return devices;});
|
|
2726
|
+
}
|
|
2727
|
+
function switchVoiceDevice(kind,id){if(!rpVoiceCall.room||!id)return Promise.resolve();return rpVoiceCall.room.switchActiveDevice(kind,id).catch(function(e){setVoiceEvent('Device switch failed',e.message);});}
|
|
2728
|
+
function applyVoiceOutputDevice(){var id=$('rp-call-speaker-device').value;if(!id)return;var els=$('rp-call-audio').querySelectorAll('audio');for(var i=0;i<els.length;i++)if(typeof els[i].setSinkId==='function')els[i].setSinkId(id).catch(function(){});}
|
|
2729
|
+
function startVoiceVisualizer(track){
|
|
2730
|
+
stopVoiceVisualizer();try{var C=window.AudioContext||window.webkitAudioContext;if(!C||!track||!track.mediaStreamTrack)return;var ctx=new C(),an=ctx.createAnalyser(),source=ctx.createMediaStreamSource(new MediaStream([track.mediaStreamTrack]));an.fftSize=128;source.connect(an);rpVoiceCall.audioContext=ctx;rpVoiceCall.analyser=an;var data=new Uint8Array(an.frequencyBinCount),bars=$('rp-call-bars').querySelectorAll('i');
|
|
2731
|
+
function draw(){an.getByteFrequencyData(data);var sum=0;for(var x=0;x<data.length;x++)sum+=data[x];var avg=sum/data.length;for(var i=0;i<bars.length;i++){var idx=Math.floor(i*data.length/bars.length);bars[i].style.height=(12+Math.min(70,data[idx]*.28))+'px';}$('rp-call-visual').classList.toggle('speaking',avg>10);rpVoiceCall.audioRaf=requestAnimationFrame(draw);}draw();
|
|
2732
|
+
}catch(_){}
|
|
2733
|
+
}
|
|
2734
|
+
function stopVoiceVisualizer(){if(rpVoiceCall.audioRaf)cancelAnimationFrame(rpVoiceCall.audioRaf);rpVoiceCall.audioRaf=0;if(rpVoiceCall.audioContext)try{rpVoiceCall.audioContext.close();}catch(_){}rpVoiceCall.audioContext=null;rpVoiceCall.analyser=null;var bars=$('rp-call-bars');if(bars)Array.prototype.forEach.call(bars.querySelectorAll('i'),function(b){b.style.height='16px';});}
|
|
2735
|
+
function updateVoiceTimer(){if(!rpVoiceCall.startedAt)return;var sec=Math.floor((Date.now()-rpVoiceCall.startedAt)/1000),m=Math.floor(sec/60),s=sec%60;$('rp-call-timer').textContent=(m<10?'0':'')+m+':'+(s<10?'0':'')+s;}
|
|
2736
|
+
function updateAgentFromParticipant(participant){if(!participant)return;var a=participant.attributes||{},state=a['lk.agent.state']||a['agent.state']||'';if(state==='speaking')setVoiceAgentState('Speaking','character audio is streaming');else if(state==='thinking')setVoiceAgentState('Thinking','language model is composing');else if(state==='listening')setVoiceAgentState('Listening','speak naturally');else if(state==='initializing')setVoiceAgentState('Preparing agent','loading voice pipeline');}
|
|
2737
|
+
function handleVoiceData(payload,participant,kind,topic){
|
|
2738
|
+
try{var msg=JSON.parse(new TextDecoder().decode(payload));
|
|
2739
|
+
if(topic==='response_latency'){var total=Number(msg.total_ms)||0;$('rp-call-lat-total').textContent=total?total+'ms':'--';$('rp-call-lat-stt').textContent=msg.stt_to_llm_ms!=null?Math.round(msg.stt_to_llm_ms)+'ms':'--';$('rp-call-lat-tts').textContent=msg.llm_to_tts_ms!=null?Math.round(msg.llm_to_tts_ms)+'ms':'--';setVoiceEvent('Response complete',total+'ms round trip');return;}
|
|
2740
|
+
if(topic==='wakeword_state'){setVoiceEvent('Wake word',msg.state==='active'?'active - listening now':'waiting for wake word');return;}
|
|
2741
|
+
if(topic==='model_loading_status'){if(msg.is_loading){setVoiceAgentState('Loading model','cold start in progress');setVoiceEvent('Model status','loading model into memory');}return;}
|
|
2742
|
+
if(topic==='tool_status'){var names=msg.tool_names||[];setVoiceEvent('Tool activity',names.length?names.join(', '):'tool cycle complete');return;}
|
|
2743
|
+
if(topic && topic!=='lk-chat-topic')return;var text=String(msg.message||msg.text||'').trim();if(!text)return;var role=msg.role==='user'?'user':'assistant',key=role+'|'+text;if(rpVoiceCall.seen[key])return;rpVoiceCall.seen[key]=1;appendVoiceTurn(role,text);saveVoiceTurn(role,text,Object.keys(rpVoiceCall.seen).length);
|
|
2744
|
+
}catch(_){}
|
|
2745
|
+
}
|
|
2746
|
+
function attachVoiceMedia(track,tag){var video=$('rp-call-video'),box=$('rp-call-media');try{track.attach(video);box.classList.add('on');$('rp-call-media-tag').textContent=tag;}catch(_){} }
|
|
2747
|
+
function toggleVoiceCamera(){if(!rpVoiceCall.room)return;var next=!rpVoiceCall.camera,opts=$('rp-call-cam-device').value?{deviceId:$('rp-call-cam-device').value}:undefined;$('rp-call-camera').disabled=true;rpVoiceCall.room.localParticipant.setCameraEnabled(next,opts).then(function(){rpVoiceCall.camera=next;$('rp-call-camera').classList.toggle('on',next);$('rp-call-camera').textContent=next?'CAM ON':'CAM';if(next){var pub=rpVoiceCall.room.localParticipant.getTrackPublication(rpVoiceCall.LK.Track.Source.Camera);if(pub&&pub.track)attachVoiceMedia(pub.track,'CAMERA');refreshBrowserDevices(false);}else if(!rpVoiceCall.screen){$('rp-call-media').classList.remove('on');$('rp-call-video').srcObject=null;}}).catch(function(e){setVoiceEvent('Camera',e.message);}).finally(function(){$('rp-call-camera').disabled=false;});}
|
|
2748
|
+
function toggleVoiceScreen(){if(!rpVoiceCall.room)return;var next=!rpVoiceCall.screen;$('rp-call-screen').disabled=true;rpVoiceCall.room.localParticipant.setScreenShareEnabled(next).then(function(){rpVoiceCall.screen=next;$('rp-call-screen').classList.toggle('on',next);$('rp-call-screen').textContent=next?'SCR ON':'SCR';if(next){var pub=rpVoiceCall.room.localParticipant.getTrackPublication(rpVoiceCall.LK.Track.Source.ScreenShare);if(pub&&pub.track)attachVoiceMedia(pub.track,'SCREEN');}else if(!rpVoiceCall.camera){$('rp-call-media').classList.remove('on');$('rp-call-video').srcObject=null;}}).catch(function(e){setVoiceEvent('Screen share',e.message);}).finally(function(){$('rp-call-screen').disabled=false;});}
|
|
2749
|
+
function sendVoiceMessage(text){if(!rpVoiceCall.room||!text)return Promise.resolve();var payload=new TextEncoder().encode(JSON.stringify({message:text,role:'user',timestamp:Date.now()}));return rpVoiceCall.room.localParticipant.publishData(payload,{reliable:true,topic:'lk-chat-topic'}).then(function(){var key='user|'+text;if(!rpVoiceCall.seen[key]){rpVoiceCall.seen[key]=1;appendVoiceTurn('user',text);saveVoiceTurn('user',text,Object.keys(rpVoiceCall.seen).length);}});}
|
|
2637
2750
|
function saveVoiceTurn(role,text,sequence){
|
|
2638
2751
|
if(!rpVoiceCall.session||!rpVoiceCall.eventToken)return;
|
|
2639
2752
|
fetch('/robopark/api/sessions/'+encodeURIComponent(rpVoiceCall.session)+'/transcript'+QS,{
|
|
@@ -2645,15 +2758,15 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
2645
2758
|
var cid=$('rp-call-character-select').value, sid=$('rp-call-stack-select').value;
|
|
2646
2759
|
if(!cid){setVoiceCallStatus('select a character first','');return;}
|
|
2647
2760
|
if(rpVoiceCall.room)return;
|
|
2648
|
-
setVoiceCallStatus('
|
|
2649
|
-
rpAction('POST','/robopark/api/sessions/voice-call',{character_preset_id:cid,voice_stack_id:sid||null,client_name:getOperatorName()||'RoboPark Operator'})
|
|
2761
|
+
setVoiceCallStatus('requesting microphone...','busy');setVoiceAgentState('Opening channel','requesting browser media permission'); $('rp-call-start').disabled=true;
|
|
2762
|
+
refreshBrowserDevices(true).then(function(){return rpAction('POST','/robopark/api/sessions/voice-call',{character_preset_id:cid,voice_stack_id:sid||null,client_name:getOperatorName()||'RoboPark Operator'});})
|
|
2650
2763
|
.then(function(call){
|
|
2651
2764
|
if(!call)throw new Error('scheduler returned no call');
|
|
2652
|
-
rpVoiceCall.session=call.session_id; rpVoiceCall.eventToken=call.event_token; rpVoiceCall.seen={};
|
|
2765
|
+
rpVoiceCall.session=call.session_id; rpVoiceCall.eventToken=call.event_token; rpVoiceCall.seen={};rpVoiceCall.messages=0;rpVoiceCall.ending=false;
|
|
2653
2766
|
$('rp-call-session').textContent=call.session_id; $('rp-call-transcript').innerHTML='<div class="rp-tbl-empty">Connecting to '+esc(call.character&&call.character.name||cid)+'...</div>';
|
|
2654
2767
|
return ensureVoiceLiveKit().then(function(LK){
|
|
2655
|
-
var room=new LK.Room({adaptiveStream:true,dynacast:true}); rpVoiceCall.room=room;
|
|
2656
|
-
room.on(LK.RoomEvent.TrackSubscribed,function(track){ if(track.kind==='audio'){var el=track.attach();el.autoplay=true;$('rp-call-audio').appendChild(el);} });
|
|
2768
|
+
var room=new LK.Room({adaptiveStream:true,dynacast:true}); rpVoiceCall.room=room;rpVoiceCall.LK=LK;
|
|
2769
|
+
room.on(LK.RoomEvent.TrackSubscribed,function(track){ if(track.kind==='audio'){var el=track.attach();el.autoplay=true;$('rp-call-audio').appendChild(el);applyVoiceOutputDevice();startVoiceVisualizer(track);setVoiceAgentState('Agent online','voice channel connected');} });
|
|
2657
2770
|
room.on(LK.RoomEvent.TranscriptionReceived,function(segments,participant){
|
|
2658
2771
|
for(var i=0;i<(segments||[]).length;i++){
|
|
2659
2772
|
var seg=segments[i], final=seg.final===true||seg.isFinal===true; if(!final||!String(seg.text||'').trim())continue;
|
|
@@ -2662,43 +2775,43 @@ button.act:disabled{opacity:0.5;cursor:default;}
|
|
|
2662
2775
|
appendVoiceTurn(role,String(seg.text)); saveVoiceTurn(role,String(seg.text),Object.keys(rpVoiceCall.seen).length);
|
|
2663
2776
|
}
|
|
2664
2777
|
});
|
|
2665
|
-
room.on(LK.RoomEvent.DataReceived,
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
var msg=JSON.parse(new TextDecoder().decode(payload));
|
|
2669
|
-
var text=String(msg.message||msg.text||'').trim(); if(!text)return;
|
|
2670
|
-
var role=msg.role==='user'?'user':'assistant';
|
|
2671
|
-
var key=role+'|'+text; if(rpVoiceCall.seen[key])return; rpVoiceCall.seen[key]=1;
|
|
2672
|
-
appendVoiceTurn(role,text); saveVoiceTurn(role,text,Object.keys(rpVoiceCall.seen).length);
|
|
2673
|
-
}catch(_){}
|
|
2674
|
-
});
|
|
2778
|
+
room.on(LK.RoomEvent.DataReceived,handleVoiceData);
|
|
2779
|
+
if(LK.RoomEvent.ParticipantAttributesChanged)room.on(LK.RoomEvent.ParticipantAttributesChanged,function(changed,p){updateAgentFromParticipant(p);});
|
|
2780
|
+
room.on(LK.RoomEvent.ParticipantConnected,function(p){updateAgentFromParticipant(p);setVoiceEvent('Agent connected',p.name||p.identity||'ROBOVOICE worker');});
|
|
2675
2781
|
room.on(LK.RoomEvent.Disconnected,function(){ if(!rpVoiceCall.ending) finishVoiceCall('connection_lost'); });
|
|
2676
|
-
return room.connect(call.server_url,call.token).then(function(){return room.localParticipant.setMicrophoneEnabled(true);});
|
|
2782
|
+
return room.connect(call.server_url,call.token).then(function(){var mic=$('rp-call-mic-device').value,opts=mic?{deviceId:mic}:undefined;return room.localParticipant.setMicrophoneEnabled(true,opts);});
|
|
2677
2783
|
}).then(function(){
|
|
2678
|
-
setVoiceCallStatus('
|
|
2784
|
+
setVoiceCallStatus('secure channel connected','live');setVoiceAgentState('Listening','speak naturally');setVoiceEvent('Connected','waiting for ROBOVOICE agent');rpVoiceCall.startedAt=Date.now();rpVoiceCall.timer=setInterval(updateVoiceTimer,1000);updateVoiceTimer();
|
|
2785
|
+
$('rp-call-mute').disabled=false;$('rp-call-camera').disabled=false;$('rp-call-screen').disabled=false;$('rp-call-end').disabled=false;$('rp-call-message').disabled=false;$('rp-call-send').disabled=false;
|
|
2679
2786
|
return fetch('/robopark/api/sessions/'+encodeURIComponent(rpVoiceCall.session)+'/joined'+QS,{method:'POST',headers:{'X-RoboPark-Session-Token':rpVoiceCall.eventToken}}).catch(function(){});
|
|
2680
2787
|
});
|
|
2681
2788
|
}).catch(function(e){
|
|
2682
|
-
setVoiceCallStatus('call failed
|
|
2789
|
+
setVoiceCallStatus('call failed','');setVoiceAgentState('Unable to connect',e&&e.message||String(e));setVoiceEvent('Call failed',e&&e.message||String(e)); $('rp-call-start').disabled=false;
|
|
2790
|
+
if(rpVoiceCall.session)rpAction('POST','/robopark/api/sessions/'+encodeURIComponent(rpVoiceCall.session)+'/end?reason=connection_failed');
|
|
2683
2791
|
if(rpVoiceCall.room){try{rpVoiceCall.room.disconnect();}catch(_){} rpVoiceCall.room=null;}
|
|
2684
2792
|
});
|
|
2685
2793
|
}
|
|
2686
2794
|
function toggleVoiceMute(){
|
|
2687
2795
|
if(!rpVoiceCall.room)return; rpVoiceCall.muted=!rpVoiceCall.muted;
|
|
2688
2796
|
rpVoiceCall.room.localParticipant.setMicrophoneEnabled(!rpVoiceCall.muted);
|
|
2689
|
-
$('rp-call-mute').textContent=rpVoiceCall.muted?'
|
|
2797
|
+
$('rp-call-mute').textContent=rpVoiceCall.muted?'MIC OFF':'MIC';$('rp-call-mute').classList.toggle('on',!rpVoiceCall.muted);setVoiceCallStatus(rpVoiceCall.muted?'microphone muted':'secure channel connected','live');
|
|
2690
2798
|
}
|
|
2691
2799
|
function finishVoiceCall(reason){
|
|
2692
2800
|
if(rpVoiceCall.ending)return; rpVoiceCall.ending=true; var session=rpVoiceCall.session, room=rpVoiceCall.room;
|
|
2693
|
-
rpVoiceCall.room=null;
|
|
2801
|
+
rpVoiceCall.room=null;if(rpVoiceCall.timer)clearInterval(rpVoiceCall.timer);rpVoiceCall.timer=null;stopVoiceVisualizer();if(room){try{room.disconnect();}catch(_){}}
|
|
2694
2802
|
if(session) rpAction('POST','/robopark/api/sessions/'+encodeURIComponent(session)+'/end?reason='+encodeURIComponent(reason||'operator'));
|
|
2695
|
-
setVoiceCallStatus('call ended','');
|
|
2696
|
-
$('rp-call-mute').textContent='Mute microphone'; rpVoiceCall.session=null; rpVoiceCall.eventToken=null; rpVoiceCall.muted=false; setTimeout(function(){rpVoiceCall.ending=false;},300);
|
|
2803
|
+
setVoiceCallStatus('call ended','');setVoiceAgentState('Call complete','session transcript saved');setVoiceEvent('Session closed',reason||'operator');$('rp-call-start').disabled=false;['rp-call-mute','rp-call-camera','rp-call-screen','rp-call-end'].forEach(function(id){$(id).disabled=true;$(id).classList.remove('on');});$('rp-call-message').disabled=true;$('rp-call-send').disabled=true;$('rp-call-media').classList.remove('on');$('rp-call-video').srcObject=null;$('rp-call-mute').textContent='MIC';$('rp-call-camera').textContent='CAM';$('rp-call-screen').textContent='SCR';$('rp-call-session').textContent='No active session';$('rp-call-timer').textContent='00:00';rpVoiceCall.session=null;rpVoiceCall.eventToken=null;rpVoiceCall.muted=false;rpVoiceCall.camera=false;rpVoiceCall.screen=false;rpVoiceCall.startedAt=0;setTimeout(function(){rpVoiceCall.ending=false;},300);
|
|
2697
2804
|
}
|
|
2698
2805
|
(function(){
|
|
2699
|
-
var cs=$('rp-call-character-select'),
|
|
2806
|
+
var cs=$('rp-call-character-select'),ss=$('rp-call-stack-select'),start=$('rp-call-start'),mute=$('rp-call-mute'),end=$('rp-call-end');
|
|
2700
2807
|
if(cs)cs.addEventListener('change',paintVoiceCallCharacter); if(start)start.addEventListener('click',startVoiceCall);
|
|
2701
|
-
if(mute)mute.addEventListener('click',toggleVoiceMute);
|
|
2808
|
+
if(ss)ss.addEventListener('change',paintVoiceCallStack);if(mute)mute.addEventListener('click',toggleVoiceMute);if(end)end.addEventListener('click',function(){finishVoiceCall('operator');});
|
|
2809
|
+
$('rp-call-camera').addEventListener('click',toggleVoiceCamera);$('rp-call-screen').addEventListener('click',toggleVoiceScreen);$('rp-call-refresh-devices').addEventListener('click',function(){refreshBrowserDevices(true);});
|
|
2810
|
+
$('rp-call-mic-device').addEventListener('change',function(){switchVoiceDevice('audioinput',this.value);});$('rp-call-cam-device').addEventListener('change',function(){switchVoiceDevice('videoinput',this.value);});$('rp-call-speaker-device').addEventListener('change',applyVoiceOutputDevice);
|
|
2811
|
+
function toggleTranscript(){rpVoiceCall.transcriptCollapsed=!rpVoiceCall.transcriptCollapsed;$('rp-call-transcript').classList.toggle('collapsed',rpVoiceCall.transcriptCollapsed);$('rp-call-collapse').textContent=rpVoiceCall.transcriptCollapsed?'expand transcript':'collapse transcript';}
|
|
2812
|
+
$('rp-call-chat-toggle').addEventListener('click',toggleTranscript);$('rp-call-collapse').addEventListener('click',toggleTranscript);
|
|
2813
|
+
$('rp-call-compose').addEventListener('submit',function(e){e.preventDefault();var input=$('rp-call-message'),text=input.value.trim();if(!text)return;$('rp-call-send').disabled=true;sendVoiceMessage(text).then(function(){input.value='';}).catch(function(err){setVoiceEvent('Message failed',err.message);}).finally(function(){$('rp-call-send').disabled=!rpVoiceCall.room;});});
|
|
2814
|
+
refreshBrowserDevices(false);
|
|
2702
2815
|
})();
|
|
2703
2816
|
|
|
2704
2817
|
var rpHistoryFilter = { robot: '', endReason: '', range: '7d', search: '' };
|
package/package.json
CHANGED