@symerian/symi 3.4.30 → 3.4.31
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/{agent-O3PihJOY.js → agent-ZFfYdexc.js} +10 -10
- package/dist/{agents-C2MpIr16.js → agents-C8naPegc.js} +5 -5
- package/dist/{audit-yf3H4Y1h.js → audit-DOfexJi4.js} +8 -8
- package/dist/{auth-choice-CyBcsQ9T.js → auth-choice-DxH-c3vK.js} +4 -4
- package/dist/{banner-D7__HlM-.js → banner-D7zYLyA8.js} +1 -1
- package/dist/{browser-cli-B_6WWHm_.js → browser-cli-MYIql1Ic.js} +3 -3
- package/dist/build-info.json +1 -1
- package/dist/bundled/boot-md/handler.js +4 -4
- package/dist/bundled/session-memory/handler.js +4 -4
- package/dist/{call-IfleM0ap.js → call-D9U2Sfhp.js} +1 -1
- package/dist/{channel-options-B5974x-7.js → channel-options-9PzSNQLG.js} +1 -1
- package/dist/{channels-cli-C6Nv9mzy.js → channels-cli-C3XnNkE5.js} +30 -30
- package/dist/{chrome-DT1fIVG1.js → chrome-B4P7ycw5.js} +7 -7
- package/dist/{chrome-DJCkCRLf.js → chrome-ClVIwINy.js} +1 -1
- package/dist/{cli-DZoms4qg.js → cli-DhTdzhjk.js} +26 -26
- package/dist/{command-registry--D98SJ6k.js → command-registry-BOwku-e8.js} +11 -11
- package/dist/{completion-cli-CHYvpIPw.js → completion-cli-KZYbGY4H.js} +2 -2
- package/dist/{config-BTSBEAnk.js → config-Byd2Y9rr.js} +5 -5
- package/dist/{config-cli-DstpcB33.js → config-cli-CJ1CRfG8.js} +5 -5
- package/dist/{config-guard-CCJrDmON.js → config-guard-zt0zhFHl.js} +2 -2
- package/dist/{config-validation-YCrMlM9Z.js → config-validation-CRazk6Kd.js} +1 -1
- package/dist/{configure-B-UvSZZ7.js → configure-CFY_XEps.js} +10 -10
- package/dist/{control-service-CwRG4M_O.js → control-service-DN6-IdFk.js} +4 -4
- package/dist/{cron-cli-DUETe3Of.js → cron-cli-fmiz43Pz.js} +3 -3
- package/dist/{daemon-cli-Dy5eY4M7.js → daemon-cli-BilAL40g.js} +6 -6
- package/dist/{daemon-runtime-ChztAKDA.js → daemon-runtime-D4KHzQq2.js} +1 -1
- package/dist/{deliver-59sRVaYQ.js → deliver-BkCYBlzi.js} +4 -4
- package/dist/{deliver-BHmK4isn.js → deliver-CnsfN7km.js} +1 -1
- package/dist/{devices-cli-BCZ2HHjT.js → devices-cli-D7HdOwRI.js} +2 -2
- package/dist/{directory-cli-BVGd0l0T.js → directory-cli-ed6QacBC.js} +1 -1
- package/dist/{dns-cli-DH-ksmiI.js → dns-cli-RPa1dGTQ.js} +1 -1
- package/dist/{docs-cli-BuX8FDdh.js → docs-cli-ZTdS_Gak.js} +2 -2
- package/dist/{doctor-completion-C4Sf8CFV.js → doctor-completion-DpGX8dau.js} +1 -1
- package/dist/{doctor-config-flow-BhmF6EAq.js → doctor-config-flow-CIrG_yW_.js} +4 -4
- package/dist/entry.js +3 -3
- package/dist/{exec-approvals-cli-CyXTXgft.js → exec-approvals-cli-65pcsa1y.js} +6 -6
- package/dist/{frontmatter-BH3ExkUY.js → frontmatter-B4levtVg.js} +2 -2
- package/dist/{gateway-cli-fT43bqlv.js → gateway-cli-CTi7Wl2k.js} +50 -50
- package/dist/{gateway-rpc-BEqCo2JK.js → gateway-rpc-2VPLhMhx.js} +1 -1
- package/dist/{glass-ui-ws-BfMKuf9v.js → glass-ui-ws-Bah_A-jn.js} +38 -38
- package/dist/{gmail-setup-utils-Cz9Tb30q.js → gmail-setup-utils-C9WBC6Cd.js} +1 -1
- package/dist/{health-DDxrkioj.js → health-B5rRzhyV.js} +3 -3
- package/dist/{hooks-cli-Btgk__9z.js → hooks-cli-CSDCGO-W.js} +29 -29
- package/dist/{hooks-status-BaV4_YaJ.js → hooks-status-OorbLcc2.js} +2 -2
- package/dist/index.js +0 -0
- package/dist/{lifecycle-core-B0tG8ERp.js → lifecycle-core-BRc-XqTk.js} +2 -2
- package/dist/llm-slug-generator.js +4 -4
- package/dist/{logs-cli-CUhZrDw7.js → logs-cli-D5phVUOT.js} +3 -3
- package/dist/{manager-BeNnzSJv.js → manager-BfhHvsI9.js} +1 -1
- package/dist/{manager-Di9qtuZF.js → manager-DzBH9uQG.js} +1 -1
- package/dist/{memory-BDeydRz3.js → memory-BCj0cj5v.js} +3 -3
- package/dist/{memory-cli-D4hZiGr5.js → memory-cli-9WUMBHol.js} +3 -3
- package/dist/{model-catalog-DPnCNs5N.js → model-catalog-CD2kTz4V.js} +2 -2
- package/dist/{model-picker-DuPommMc.js → model-picker-CVd5UuXV.js} +2 -2
- package/dist/{models-cli-CL5K06Wu.js → models-cli-rd4eX_6P.js} +30 -30
- package/dist/{models-config-CPlvO1b0.js → models-config-oxaGiRUT.js} +1 -1
- package/dist/{models-B0wNKA18.js → models-sbKIrJBG.js} +9 -9
- package/dist/{node-cli-CWWMajKF.js → node-cli-ClLXSdFL.js} +9 -9
- package/dist/{nodes-cli-YmE7S-JB.js → nodes-cli-DY38p5In.js} +3 -3
- package/dist/{onboard-HqUZVKyD.js → onboard-BAyp_UFm.js} +7 -7
- package/dist/{onboard-channels-BbF5-N3g.js → onboard-channels-CUpkV_IJ.js} +1 -1
- package/dist/{onboard-custom-63SI3jrk.js → onboard-custom-BMgLK-vo.js} +2 -2
- package/dist/{onboard-helpers-Cb3WFLl9.js → onboard-helpers-DIQjpQ-s.js} +2 -2
- package/dist/{onboard-hooks-DXXg3YH9.js → onboard-hooks-KZKmj5Dk.js} +3 -3
- package/dist/{onboard-remote-CqtCrqtm.js → onboard-remote-C-_NUgBl.js} +1 -1
- package/dist/{onboard-skills-CS3l5fhH.js → onboard-skills-CwvicFTi.js} +3 -3
- package/dist/{onboarding-Be_HJIFA.js → onboarding-BxCNNo75.js} +11 -11
- package/dist/{onboarding.finalize-dsCUTKCQ.js → onboarding.finalize-DgMPXTtO.js} +18 -18
- package/dist/{onboarding.gateway-config-Ctd1_QW4.js → onboarding.gateway-config-BAaWvPSX.js} +4 -4
- package/dist/{outbound-send-deps-DPsU_Xdy.js → outbound-send-deps-qhFaNYAY.js} +1 -1
- package/dist/{pairing-cli-PtlNv7Gr.js → pairing-cli-CFkiSx8t.js} +1 -1
- package/dist/{pi-embedded-helpers-CVKIHnFv.js → pi-embedded-helpers-CRG5LMS7.js} +1 -1
- package/dist/{pi-tools.policy-8_wTu7v2.js → pi-tools.policy-De6xHjVL.js} +2 -2
- package/dist/{plugin-registry-BG51uZOA.js → plugin-registry-BNe5jtPK.js} +2 -2
- package/dist/plugin-sdk/index.js +6 -6
- package/dist/{plugins-cli-B-zVOiQN.js → plugins-cli-CWj33_Hj.js} +27 -27
- package/dist/{program-BOh0XGsA.js → program-Z2OLlhsB.js} +33 -33
- package/dist/{prompt-select-styled-Bj-hrPCx.js → prompt-select-styled-BNwbBBcH.js} +16 -16
- package/dist/{provider-auth-helpers-BK6NFk2Q.js → provider-auth-helpers-5qb15Hje.js} +2 -2
- package/dist/{push-apns-CMxk3Hxf.js → push-apns-D6qV5P4h.js} +1 -1
- package/dist/{pw-ai-C5MJKzUM.js → pw-ai-BsEf8C15.js} +1 -1
- package/dist/{pw-ai-CE2TBGif.js → pw-ai-C7mvVllB.js} +2 -2
- package/dist/{qr-cli-BeHlC33g.js → qr-cli-oENcXq8d.js} +1 -1
- package/dist/{redact-identifier-B1VHIbnd.js → redact-identifier-ZE8OIUof.js} +1 -1
- package/dist/{register.agent-COv5OPLQ.js → register.agent-DpiHPMca.js} +36 -36
- package/dist/{register.configure-RhKVlfWH.js → register.configure-DRFaroYF.js} +40 -40
- package/dist/{register.maintenance-BAK-DiQY.js → register.maintenance-BGNNTt_1.js} +38 -38
- package/dist/{register.message-CCBmn5ja.js → register.message-R4AIHhlU.js} +28 -28
- package/dist/{register.onboard-B3jO_Goy.js → register.onboard-Cl-_Suyv.js} +13 -13
- package/dist/{register.setup-CYSISTDO.js → register.setup-Dt98v2V3.js} +15 -15
- package/dist/{register.status-health-sessions-CGbg9k6d.js → register.status-health-sessions-DiX5lVyr.js} +23 -23
- package/dist/{register.subclis-loifbhVx.js → register.subclis-DVObuR_P.js} +28 -28
- package/dist/{replies-Dj640LxQ.js → replies-VTJu1jUK.js} +1 -1
- package/dist/{routes-B5y-oAKp.js → routes-DOFg6X5M.js} +3 -3
- package/dist/{rpc-qWm1bRo5.js → rpc-BIHKXdlN.js} +1 -1
- package/dist/{run-main-B7Ria3zD.js → run-main-NAgYKzSu.js} +44 -44
- package/dist/{sandbox-BJgHc4Vu.js → sandbox-EB7cFSML.js} +6 -6
- package/dist/{sandbox-cli-CSudrHYL.js → sandbox-cli-D4dy6sUK.js} +8 -8
- package/dist/{security-cli-B2lCR2xX.js → security-cli-DwCKOrFm.js} +11 -11
- package/dist/{send-CY9na-Jw.js → send-CkRtuQbr.js} +1 -1
- package/dist/{server-context-DdWWaDf6.js → server-context-ww1jytet.js} +5 -5
- package/dist/{server-methods-Dk_EnINI.js → server-methods-BDiZyPvS.js} +23 -23
- package/dist/{server-node-events-BHegSgG9.js → server-node-events-9cY40B4m.js} +29 -29
- package/dist/{session-utils-CAVPV2Hh.js → session-utils-CStjqGE6.js} +3 -3
- package/dist/{sessions-BDM9kNY0.js → sessions-BSRHJH8T.js} +3 -3
- package/dist/{sessions-CqLQkkWg.js → sessions-CInbrqsF.js} +1 -1
- package/dist/{shared-CpwtQRJB.js → shared-DEAo94kI.js} +1 -1
- package/dist/{skill-commands-CRQniaHy.js → skill-commands-BkKfrbHt.js} +2 -2
- package/dist/{skills-CTcjFd_F.js → skills-CFLijAZ-.js} +1 -1
- package/dist/{skills-cli-9Mlb7VRg.js → skills-cli-BbagnO6p.js} +5 -5
- package/dist/{skills-install-D5ikt72d.js → skills-install-dLRO1KGp.js} +2 -2
- package/dist/{skills-remote-BASG1Doo.js → skills-remote-DQVB-3Pj.js} +1 -1
- package/dist/{skills-status-1iVfuVIG.js → skills-status-HWybfj0K.js} +2 -2
- package/dist/{status-Bci6O3aA.js → status-BSrVEUoJ.js} +2 -2
- package/dist/{status-D5RhVO0A.js → status-FIp7UKru.js} +12 -12
- package/dist/{status.update-D5CachQ_.js → status.update-Cm8Fm8QD.js} +1 -1
- package/dist/{subagent-registry-CsXaK_sy.js → subagent-registry-DqryocLT.js} +31 -31
- package/dist/{synthesis-dplLmFIP.js → synthesis-CS-lrEGy.js} +4 -4
- package/dist/{synthesis-BoZf8BeO.js → synthesis-DKhH0YwU.js} +26 -26
- package/dist/{system-cli-D5FffFX5.js → system-cli-DYSI6cIB.js} +3 -3
- package/dist/{systemd-hints-CufcSfMk.js → systemd-hints-EIfW5y8K.js} +1 -1
- package/dist/{tui-DZ8gksSZ.js → tui-C20rHOeB.js} +4 -4
- package/dist/{tui-cli-CyBJYh9u.js → tui-cli-JwlzHCza.js} +11 -11
- package/dist/{unified-runner-BFLLzEHE.js → unified-runner-AM9tFC5q.js} +10 -10
- package/dist/{update-cli-yW6Xl6fs.js → update-cli-BYfA3RPc.js} +41 -41
- package/dist/{update-runner-CIgLduhH.js → update-runner-CBG8p9iG.js} +1 -1
- package/dist/{webhooks-cli-4bmyKzwb.js → webhooks-cli-MuG_QGLp.js} +4 -4
- package/dist/{with-timeout-bWr6yBeX.js → with-timeout-BvxaeAo6.js} +1 -1
- package/dist/{workspace-DxscDsm6.js → workspace-D0d7Gi4-.js} +1 -1
- package/extensions/memory-core/node_modules/.bin/symi +0 -0
- package/extensions/msteams/node_modules/.bin/symi +0 -0
- package/extensions/outlook/node_modules/.bin/symi +0 -0
- package/extensions/slack/node_modules/.bin/symi +0 -0
- package/package.json +108 -79
- package/dist/control-ui/css/revert-red-theme.md +0 -141
- package/dist/control-ui/css/style.css +0 -5843
- package/dist/control-ui/css/style.css.backup-2026-03-03-162525 +0 -3546
- package/dist/control-ui/css/style.css.backup-before-red-2026-03-03-162525 +0 -3546
- package/dist/control-ui/css/style.css.backup-before-red-theme-2026-03-03-162530 +0 -3546
- package/dist/control-ui/css/style.css.pre-2row +0 -2165
- package/dist/control-ui/css/style.css.pre-brand +0 -1776
- package/dist/control-ui/css/style.css.pre-history +0 -1974
- package/dist/control-ui/css/style.css.pre-nav +0 -2264
- package/dist/control-ui/css/style.css.pre-newsession +0 -1898
- package/dist/control-ui/css/style.css.pre-queue +0 -2195
- package/dist/control-ui/css/style.css.pre-red-prompt +0 -2524
- package/dist/control-ui/css/style.css.pre-stop +0 -2239
- package/dist/control-ui/css/style.css.pre-textarea +0 -2184
- package/dist/control-ui/css/style.css.pre-watchdog +0 -1848
- package/dist/control-ui/css/style.css.red-theme +0 -2999
- package/dist/control-ui/index.html +0 -1042
- package/dist/control-ui/js/app.js +0 -1304
- package/dist/control-ui/js/app.js.pre-2row +0 -463
- package/dist/control-ui/js/app.js.pre-heartbeat-filter +0 -595
- package/dist/control-ui/js/app.js.pre-newsession +0 -408
- package/dist/control-ui/js/app.js.pre-queue +0 -476
- package/dist/control-ui/js/app.js.pre-stop +0 -564
- package/dist/control-ui/js/app.js.pre-textarea +0 -467
- package/dist/control-ui/js/app.js.pre-watchdog +0 -293
- package/dist/control-ui/js/connections.js +0 -438
- package/dist/control-ui/js/gateway.js +0 -233
- package/dist/control-ui/js/gateway.js.pre-stop +0 -110
- package/dist/control-ui/js/history.js +0 -732
- package/dist/control-ui/js/logs.js +0 -238
- package/dist/control-ui/js/menu.js +0 -230
- package/dist/control-ui/js/menu.js.pre-nav +0 -66
- package/dist/control-ui/js/metrics.js +0 -53
- package/dist/control-ui/js/models.js +0 -138
- package/dist/control-ui/js/render.js +0 -882
- package/dist/control-ui/js/render.test.js +0 -112
- package/dist/control-ui/js/scheduling.js +0 -461
- package/dist/control-ui/js/settings.js +0 -909
- package/dist/control-ui/js/slash-autocomplete.js +0 -168
- package/dist/control-ui/js/subagents.js +0 -560
- package/dist/control-ui/js/utils.js +0 -29
- package/dist/control-ui/vendor/highlight.min.js +0 -2518
- package/dist/control-ui/vendor/marked.min.js +0 -69
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
// ── Symi UI — Live Gateway App ────────────────────────────────────────
|
|
2
|
-
|
|
3
|
-
const responseArea = document.getElementById('response-area');
|
|
4
|
-
const promptInput = document.getElementById('prompt-input');
|
|
5
|
-
const sendBtn = document.getElementById('send-btn');
|
|
6
|
-
|
|
7
|
-
let isStreaming = false;
|
|
8
|
-
let currentRunId = null;
|
|
9
|
-
let streamBubble = null;
|
|
10
|
-
let streamContent = null;
|
|
11
|
-
let streamStart = 0;
|
|
12
|
-
|
|
13
|
-
// ── Utility ───────────────────────────────────────────────────────
|
|
14
|
-
const sleep = ms => new Promise(r => setTimeout(r, ms));
|
|
15
|
-
function escapeHtml(t) {
|
|
16
|
-
return t.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// ── Status indicator (top-right of response area) ─────────────────
|
|
20
|
-
const statusEl = document.createElement('div');
|
|
21
|
-
statusEl.className = 'conn-status';
|
|
22
|
-
statusEl.innerHTML = '<span class="conn-dot dot-yellow pulse"></span><span class="conn-label">connecting…</span>';
|
|
23
|
-
responseArea.before(statusEl);
|
|
24
|
-
|
|
25
|
-
function setStatus(state) { // 'connecting' | 'online' | 'offline'
|
|
26
|
-
const dot = statusEl.querySelector('.conn-dot');
|
|
27
|
-
const label = statusEl.querySelector('.conn-label');
|
|
28
|
-
dot.className = `conn-dot ${state === 'online' ? 'dot-green pulse' : state === 'offline' ? 'dot-red' : 'dot-yellow pulse'}`;
|
|
29
|
-
label.textContent = state === 'online' ? 'live' : state === 'offline' ? 'disconnected' : 'connecting…';
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// ── Render helpers ─────────────────────────────────────────────────
|
|
33
|
-
function addUserMessage(text) {
|
|
34
|
-
const msg = document.createElement('div');
|
|
35
|
-
msg.className = 'message user-msg';
|
|
36
|
-
msg.innerHTML = `<div class="bubble">${escapeHtml(text)}</div><div class="message-clearfix"></div>`;
|
|
37
|
-
responseArea.appendChild(msg);
|
|
38
|
-
msg.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// ── Thinking bubble ────────────────────────────────────────────────
|
|
42
|
-
function createThinkingBubble() {
|
|
43
|
-
const msg = document.createElement('div');
|
|
44
|
-
msg.className = 'message symi-msg thinking-msg';
|
|
45
|
-
msg.innerHTML = `
|
|
46
|
-
<div class="bubble thinking-bubble">
|
|
47
|
-
<div class="think-header">
|
|
48
|
-
<span class="think-badge">◈ PROCESSING</span>
|
|
49
|
-
<span class="think-dots"><span>.</span><span>.</span><span>.</span></span>
|
|
50
|
-
</div>
|
|
51
|
-
<div class="think-bar-wrap"><div class="think-bar"></div></div>
|
|
52
|
-
</div>
|
|
53
|
-
<div class="message-clearfix"></div>
|
|
54
|
-
`;
|
|
55
|
-
responseArea.appendChild(msg);
|
|
56
|
-
msg.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
|
57
|
-
return msg;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// ── Stream bubble lifecycle ────────────────────────────────────────
|
|
61
|
-
function openStreamBubble() {
|
|
62
|
-
streamStart = Date.now();
|
|
63
|
-
const msg = document.createElement('div');
|
|
64
|
-
msg.className = 'message symi-msg stream-msg';
|
|
65
|
-
msg.innerHTML = `<div class="bubble stream-bubble streaming"><div class="bubble-content"></div></div><div class="message-clearfix"></div>`;
|
|
66
|
-
responseArea.appendChild(msg);
|
|
67
|
-
streamBubble = msg.querySelector('.stream-bubble');
|
|
68
|
-
streamContent = msg.querySelector('.bubble-content');
|
|
69
|
-
msg.scrollIntoView({ behavior: 'smooth', block: 'end' });
|
|
70
|
-
return msg;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function updateStream(text) {
|
|
74
|
-
if (!streamContent) return;
|
|
75
|
-
streamContent.textContent = text;
|
|
76
|
-
responseArea.scrollTop = responseArea.scrollHeight;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function closeStreamBubble(model = 'claude-sonnet-4-6') {
|
|
80
|
-
if (!streamBubble) return;
|
|
81
|
-
streamBubble.classList.remove('streaming');
|
|
82
|
-
streamBubble.classList.add('done');
|
|
83
|
-
|
|
84
|
-
// Apply full markdown rendering to the final text
|
|
85
|
-
const rawText = streamContent?.textContent ?? '';
|
|
86
|
-
if (streamContent && rawText) {
|
|
87
|
-
streamContent.innerHTML = '';
|
|
88
|
-
const textBlock = renderBlock({ type: 'text', text: rawText });
|
|
89
|
-
streamContent.appendChild(textBlock);
|
|
90
|
-
window.applyHighlighting(streamContent);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
const elapsed = Date.now() - streamStart;
|
|
94
|
-
const chars = Math.round(rawText.length / 4);
|
|
95
|
-
|
|
96
|
-
// Add copy button
|
|
97
|
-
const copyBtn = document.createElement('button');
|
|
98
|
-
copyBtn.className = 'msg-copy-btn msg-copy-visible';
|
|
99
|
-
copyBtn.title = 'Copy';
|
|
100
|
-
copyBtn.onclick = function() { window.copyMessage(this); };
|
|
101
|
-
copyBtn.innerHTML = `<svg width="12" height="12" viewBox="0 0 24 24" fill="none">
|
|
102
|
-
<rect x="9" y="9" width="13" height="13" rx="2" stroke="currentColor" stroke-width="2"/>
|
|
103
|
-
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" stroke="currentColor" stroke-width="2"/>
|
|
104
|
-
</svg>`;
|
|
105
|
-
streamBubble.appendChild(copyBtn);
|
|
106
|
-
|
|
107
|
-
const footer = document.createElement('div');
|
|
108
|
-
footer.className = 'telemetry';
|
|
109
|
-
footer.innerHTML = `
|
|
110
|
-
<span class="tele-item">✦ ${model}</span>
|
|
111
|
-
<span class="tele-sep">·</span>
|
|
112
|
-
<span class="tele-item">${chars} tokens</span>
|
|
113
|
-
<span class="tele-sep">·</span>
|
|
114
|
-
<span class="tele-item">${elapsed}ms</span>
|
|
115
|
-
`;
|
|
116
|
-
streamBubble.appendChild(footer);
|
|
117
|
-
requestAnimationFrame(() => {
|
|
118
|
-
footer.classList.add('tele-visible');
|
|
119
|
-
// Scroll to bottom immediately after markdown + footer are in the DOM
|
|
120
|
-
responseArea.scrollTop = responseArea.scrollHeight;
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
// Second scroll after the fit-content width transition finishes (0.3s)
|
|
124
|
-
setTimeout(() => { responseArea.scrollTop = responseArea.scrollHeight; }, 350);
|
|
125
|
-
|
|
126
|
-
streamBubble = null;
|
|
127
|
-
streamContent = null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// ── Render history (on first connect) ─────────────────────────────
|
|
131
|
-
function renderHistory(messages) {
|
|
132
|
-
responseArea.innerHTML = '';
|
|
133
|
-
for (const m of messages) {
|
|
134
|
-
if (!m || !m.role) continue;
|
|
135
|
-
const hasContent = Array.isArray(m.content)
|
|
136
|
-
? m.content.some(b => (b.text ?? b.thinking ?? b.name ?? '').trim())
|
|
137
|
-
: extractText(m.content).trim();
|
|
138
|
-
if (!hasContent) continue;
|
|
139
|
-
|
|
140
|
-
const el = window.renderMessage(m);
|
|
141
|
-
responseArea.appendChild(el);
|
|
142
|
-
window.applyHighlighting(el);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// Scroll to very bottom after history renders
|
|
146
|
-
requestAnimationFrame(() => { responseArea.scrollTop = responseArea.scrollHeight; });
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// ── Gateway event handler ──────────────────────────────────────────
|
|
150
|
-
let thinkingEl = null;
|
|
151
|
-
|
|
152
|
-
function handleGatewayEvent(event) {
|
|
153
|
-
if (event.event !== 'chat') return;
|
|
154
|
-
const p = event.payload;
|
|
155
|
-
if (!p || p.sessionKey !== window.SESSION_KEY) return;
|
|
156
|
-
|
|
157
|
-
if (p.state === 'delta') {
|
|
158
|
-
// First delta — remove thinking bubble, open stream bubble
|
|
159
|
-
if (thinkingEl) { thinkingEl.remove(); thinkingEl = null; }
|
|
160
|
-
if (!streamBubble) {
|
|
161
|
-
openStreamBubble();
|
|
162
|
-
setAgentStatus('streaming');
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const text = extractText(p.message);
|
|
166
|
-
if (text) updateStream(text);
|
|
167
|
-
|
|
168
|
-
} else if (p.state === 'final') {
|
|
169
|
-
closeStreamBubble();
|
|
170
|
-
setAgentStatus('done');
|
|
171
|
-
isStreaming = false;
|
|
172
|
-
currentRunId = null;
|
|
173
|
-
enableInput();
|
|
174
|
-
|
|
175
|
-
} else if (p.state === 'aborted' || p.state === 'error') {
|
|
176
|
-
if (streamBubble) closeStreamBubble();
|
|
177
|
-
if (thinkingEl) { thinkingEl.remove(); thinkingEl = null; }
|
|
178
|
-
setAgentStatus('idle');
|
|
179
|
-
isStreaming = false;
|
|
180
|
-
currentRunId = null;
|
|
181
|
-
enableInput();
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// ── Agent Status Orb ───────────────────────────────────────────────
|
|
186
|
-
const asoPanel = document.getElementById('agent-status-panel');
|
|
187
|
-
const asoLabel = document.getElementById('aso-label');
|
|
188
|
-
const asoSub = document.getElementById('aso-sub');
|
|
189
|
-
let asoDoneTimer = null;
|
|
190
|
-
|
|
191
|
-
const ASO_STATES = {
|
|
192
|
-
idle: { state: 'idle', label: 'STANDBY', sub: 'Awaiting your prompt' },
|
|
193
|
-
waiting: { state: 'waiting', label: 'WAITING', sub: 'Sending to Symi\u2026' },
|
|
194
|
-
thinking: { state: 'thinking', label: 'PROCESSING', sub: 'Reasoning through request' },
|
|
195
|
-
streaming: { state: 'streaming', label: 'RESPONDING', sub: 'Generating response' },
|
|
196
|
-
done: { state: 'done', label: 'COMPLETE', sub: 'Response ready' },
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
function setAgentStatus(key) {
|
|
200
|
-
if (!asoPanel) return;
|
|
201
|
-
if (asoDoneTimer) { clearTimeout(asoDoneTimer); asoDoneTimer = null; }
|
|
202
|
-
const s = ASO_STATES[key] || ASO_STATES.idle;
|
|
203
|
-
asoPanel.dataset.state = s.state;
|
|
204
|
-
if (asoLabel) asoLabel.textContent = s.label;
|
|
205
|
-
if (asoSub) asoSub.textContent = s.sub;
|
|
206
|
-
if (key === 'done') {
|
|
207
|
-
asoDoneTimer = setTimeout(() => setAgentStatus('idle'), 3000);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// ── Input state ────────────────────────────────────────────────────
|
|
212
|
-
function disableInput() {
|
|
213
|
-
promptInput.disabled = true;
|
|
214
|
-
sendBtn.disabled = true;
|
|
215
|
-
sendBtn.classList.add('btn-loading');
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function enableInput() {
|
|
219
|
-
promptInput.disabled = false;
|
|
220
|
-
sendBtn.disabled = false;
|
|
221
|
-
sendBtn.classList.remove('btn-loading');
|
|
222
|
-
promptInput.focus();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// ── Send handler ───────────────────────────────────────────────────
|
|
226
|
-
async function handleSend() {
|
|
227
|
-
if (isStreaming || !gateway.connected) return;
|
|
228
|
-
const text = promptInput.value.trim();
|
|
229
|
-
if (!text) return;
|
|
230
|
-
|
|
231
|
-
isStreaming = true;
|
|
232
|
-
promptInput.value = '';
|
|
233
|
-
disableInput();
|
|
234
|
-
|
|
235
|
-
addUserMessage(text);
|
|
236
|
-
await sleep(200);
|
|
237
|
-
|
|
238
|
-
setAgentStatus('waiting');
|
|
239
|
-
thinkingEl = createThinkingBubble();
|
|
240
|
-
setAgentStatus('thinking');
|
|
241
|
-
|
|
242
|
-
try {
|
|
243
|
-
await gateway.send(text);
|
|
244
|
-
// Response will arrive via chat events
|
|
245
|
-
} catch (err) {
|
|
246
|
-
if (thinkingEl) { thinkingEl.remove(); thinkingEl = null; }
|
|
247
|
-
setAgentStatus('idle');
|
|
248
|
-
const errMsg = document.createElement('div');
|
|
249
|
-
errMsg.className = 'message symi-msg';
|
|
250
|
-
errMsg.innerHTML = `<div class="bubble stream-bubble done"><div class="bubble-content" style="color:var(--accent-pink)">Error: ${escapeHtml(err.message)}</div></div><div class="message-clearfix"></div>`;
|
|
251
|
-
responseArea.appendChild(errMsg);
|
|
252
|
-
isStreaming = false;
|
|
253
|
-
enableInput();
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
sendBtn.addEventListener('click', handleSend);
|
|
258
|
-
promptInput.addEventListener('keydown', e => {
|
|
259
|
-
if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSend(); }
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
// Clicking anywhere on the prompt bar (padding, icon, gaps) focuses the input
|
|
263
|
-
document.getElementById('prompt-bar').addEventListener('click', e => {
|
|
264
|
-
if (e.target !== sendBtn && !sendBtn.contains(e.target)) {
|
|
265
|
-
promptInput.focus();
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
// ── Gateway setup ──────────────────────────────────────────────────
|
|
270
|
-
const gateway = new SymiGateway();
|
|
271
|
-
|
|
272
|
-
gateway.addEventListener('connect', () => {
|
|
273
|
-
setStatus('online');
|
|
274
|
-
enableInput();
|
|
275
|
-
// History arrives via separate 'history' event pushed by the server
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
gateway.addEventListener('history', (e) => {
|
|
279
|
-
const msgs = Array.isArray(e.detail?.messages) ? e.detail.messages : [];
|
|
280
|
-
renderHistory(msgs);
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
gateway.addEventListener('disconnect', () => {
|
|
284
|
-
setStatus('offline');
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
gateway.addEventListener('event', (e) => {
|
|
288
|
-
handleGatewayEvent(e.detail);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
// Start connecting
|
|
292
|
-
disableInput();
|
|
293
|
-
gateway.start();
|