@symerian/symi 2.0.10 → 2.0.12
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/{audio-preflight-B8ffbICW.js → audio-preflight-Cq4C-m27.js} +4 -4
- package/dist/{audio-preflight-DRQD_nt1.js → audio-preflight-DbUFnPX1.js} +4 -4
- package/dist/build-info.json +3 -3
- package/dist/bundled/boot-md/handler.js +6 -6
- package/dist/bundled/session-memory/handler.js +6 -6
- package/dist/canvas-host/a2ui/.bundle.hash +1 -1
- package/dist/{chrome-LmEyZdbC.js → chrome-BATLK3yK.js} +7 -7
- package/dist/{chrome-B_zrSLce.js → chrome-h6BnL8Lp.js} +7 -7
- package/dist/control-ui/css/style.css +199 -0
- package/dist/control-ui/index.html +19 -0
- package/dist/control-ui/js/app.js +34 -0
- package/dist/control-ui/js/render.js +217 -1
- package/dist/control-ui/vendor/highlight.min.js +2518 -0
- package/dist/control-ui/vendor/marked.min.js +69 -0
- package/dist/daemon-cli.js +6 -6
- package/dist/{deliver-CkjSfucB.js → deliver-CZF9f8aC.js} +1 -1
- package/dist/{deliver-B3UoBZdC.js → deliver-DD3gs9SF.js} +1 -1
- package/dist/extensionAPI.js +6 -6
- package/dist/{image-CSeAnozE.js → image-DOnOTocl.js} +1 -1
- package/dist/{image-RFofsrof.js → image-RLbZ3RUn.js} +1 -1
- package/dist/llm-slug-generator.js +6 -6
- package/dist/{pi-embedded-9wEA_0mu.js → pi-embedded-BvCoZBNg.js} +16 -16
- package/dist/{pi-embedded-BjzaB3CT.js → pi-embedded-ZzUH4ioO.js} +16 -16
- package/dist/{pi-embedded-helpers-BmYZe8o8.js → pi-embedded-helpers--yFTAWwW.js} +4 -4
- package/dist/{pi-embedded-helpers-kB5lBgXk.js → pi-embedded-helpers-x8rJur4F.js} +4 -4
- package/dist/{pw-ai-CAkn033M.js → pw-ai-CCt1nIO-.js} +1 -1
- package/dist/{pw-ai-s-d46DCX.js → pw-ai-C_C5as1t.js} +1 -1
- package/dist/{runner-DOvsNiYz.js → runner-DjHRFXSI.js} +1 -1
- package/dist/{runner-CJJY2r19.js → runner-uDZlTCm2.js} +1 -1
- package/dist/{web-BKQnrqo-.js → web-0bP0TLM2.js} +6 -6
- package/dist/{web-CAnxcgBD.js → web-G0LUda_q.js} +6 -6
- package/package.json +1 -1
|
@@ -497,6 +497,216 @@ function formatTime(ts) {
|
|
|
497
497
|
// Expose renderBlock for use in app.js streaming finalization
|
|
498
498
|
window.renderBlock = renderBlock;
|
|
499
499
|
|
|
500
|
+
// ── Reasoning Panel — append a block ─────────────────────────────────
|
|
501
|
+
window.appendToReasoningPanel = function (block) {
|
|
502
|
+
const feed = document.getElementById("reasoning-feed");
|
|
503
|
+
if (!feed) {
|
|
504
|
+
return;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Remove empty-state placeholder on first real entry
|
|
508
|
+
const empty = document.getElementById("reasoning-empty");
|
|
509
|
+
if (empty) {
|
|
510
|
+
empty.remove();
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
const entry = document.createElement("div");
|
|
514
|
+
entry.className = "reasoning-entry";
|
|
515
|
+
|
|
516
|
+
switch (block.type) {
|
|
517
|
+
// ── Thinking block ──────────────────────────────────────────────
|
|
518
|
+
case "thinking": {
|
|
519
|
+
const text = (block.thinking ?? "").trim();
|
|
520
|
+
if (!text) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
entry.innerHTML = `
|
|
524
|
+
<div class="reasoning-entry-header">
|
|
525
|
+
<span class="reasoning-entry-badge badge-think">◈ THINK</span>
|
|
526
|
+
<span class="reasoning-entry-name">${escHtml(String(text).split("\n")[0].slice(0, 60))}${text.length > 60 ? "…" : ""}</span>
|
|
527
|
+
</div>
|
|
528
|
+
<div class="reasoning-think-body">${escHtml(text)}</div>
|
|
529
|
+
`;
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
// ── Tool call ───────────────────────────────────────────────────
|
|
534
|
+
case "tool_use": {
|
|
535
|
+
const name = block.name ?? "tool";
|
|
536
|
+
const inputJson = block.input ? JSON.stringify(block.input, null, 2) : "{}";
|
|
537
|
+
// One-line preview: first key=value pair
|
|
538
|
+
let preview = "";
|
|
539
|
+
try {
|
|
540
|
+
const keys = Object.keys(block.input ?? {});
|
|
541
|
+
if (keys.length) {
|
|
542
|
+
const val = String(block.input[keys[0]]).slice(0, 50);
|
|
543
|
+
preview = `${keys[0]}: ${val}${val.length >= 50 ? "…" : ""}`;
|
|
544
|
+
}
|
|
545
|
+
} catch {
|
|
546
|
+
/* ignore */
|
|
547
|
+
}
|
|
548
|
+
entry.innerHTML = `
|
|
549
|
+
<div class="reasoning-entry-header">
|
|
550
|
+
<span class="reasoning-entry-badge badge-tool">${escHtml(toolIcon(name))} TOOL</span>
|
|
551
|
+
<span class="reasoning-entry-name">${escHtml(formatToolName(name))}</span>
|
|
552
|
+
</div>
|
|
553
|
+
${preview ? `<div class="reasoning-tool-preview">${escHtml(preview)}</div>` : ""}
|
|
554
|
+
<div class="reasoning-tool-detail">${escHtml(inputJson)}</div>
|
|
555
|
+
`;
|
|
556
|
+
// Toggle expand on click
|
|
557
|
+
entry.style.cursor = "pointer";
|
|
558
|
+
entry.addEventListener("click", () => entry.classList.toggle("expanded"));
|
|
559
|
+
break;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// ── Tool result ─────────────────────────────────────────────────
|
|
563
|
+
case "tool_result": {
|
|
564
|
+
const content = Array.isArray(block.content)
|
|
565
|
+
? block.content.map((b) => b.text ?? "").join("\n")
|
|
566
|
+
: String(block.content ?? "");
|
|
567
|
+
const chars = content.length;
|
|
568
|
+
const isError = block.is_error === true;
|
|
569
|
+
entry.innerHTML = `
|
|
570
|
+
<div class="reasoning-entry-header">
|
|
571
|
+
<span class="reasoning-entry-badge badge-result">${isError ? "⚠ ERROR" : "↩ RESULT"}</span>
|
|
572
|
+
<span class="reasoning-entry-name">${chars} chars</span>
|
|
573
|
+
</div>
|
|
574
|
+
<div class="reasoning-result-meta">${escHtml(content.slice(0, 80))}${chars > 80 ? "…" : ""}</div>
|
|
575
|
+
`;
|
|
576
|
+
break;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
default:
|
|
580
|
+
return; // unknown block — skip
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
feed.appendChild(entry);
|
|
584
|
+
feed.scrollTop = feed.scrollHeight;
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
// ── Reasoning Panel — run separator ──────────────────────────────────
|
|
588
|
+
window.injectReasoningRunSeparator = function () {
|
|
589
|
+
const feed = document.getElementById("reasoning-feed");
|
|
590
|
+
if (!feed) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const empty = document.getElementById("reasoning-empty");
|
|
594
|
+
if (empty) {
|
|
595
|
+
empty.remove();
|
|
596
|
+
}
|
|
597
|
+
const now = new Date();
|
|
598
|
+
const hhmm = now.toLocaleTimeString("en-US", {
|
|
599
|
+
hour: "2-digit",
|
|
600
|
+
minute: "2-digit",
|
|
601
|
+
hour12: false,
|
|
602
|
+
});
|
|
603
|
+
const sep = document.createElement("div");
|
|
604
|
+
sep.className = "reasoning-run-sep";
|
|
605
|
+
sep.innerHTML = `<span class="reasoning-run-sep-label">RUN · ${hhmm}</span>`;
|
|
606
|
+
feed.appendChild(sep);
|
|
607
|
+
feed.scrollTop = feed.scrollHeight;
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
// ── Reasoning Panel — clear ───────────────────────────────────────────
|
|
611
|
+
window.clearReasoningPanel = function () {
|
|
612
|
+
const feed = document.getElementById("reasoning-feed");
|
|
613
|
+
if (!feed) {
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
feed.innerHTML = `
|
|
617
|
+
<div class="reasoning-empty" id="reasoning-empty">
|
|
618
|
+
<div class="reasoning-empty-icon">
|
|
619
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
|
|
620
|
+
<circle cx="12" cy="12" r="3"/>
|
|
621
|
+
<path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M4.93 19.07l1.41-1.41M17.66 6.34l1.41-1.41"/>
|
|
622
|
+
</svg>
|
|
623
|
+
</div>
|
|
624
|
+
<div class="reasoning-empty-text">No reasoning yet</div>
|
|
625
|
+
</div>`;
|
|
626
|
+
};
|
|
627
|
+
|
|
628
|
+
// ── Reasoning Panel — live thinking update (streaming) ───────────────
|
|
629
|
+
// Called repeatedly during a run to accumulate thinking text in real-time.
|
|
630
|
+
// Creates a single "live" entry and updates it in-place until finalized.
|
|
631
|
+
let _liveThinkEntry = null;
|
|
632
|
+
let _liveThinkBody = null;
|
|
633
|
+
let _liveThinkBuffer = "";
|
|
634
|
+
|
|
635
|
+
window.openLiveThinking = function () {
|
|
636
|
+
const feed = document.getElementById("reasoning-feed");
|
|
637
|
+
if (!feed) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
const empty = document.getElementById("reasoning-empty");
|
|
641
|
+
if (empty) {
|
|
642
|
+
empty.remove();
|
|
643
|
+
}
|
|
644
|
+
_liveThinkBuffer = "";
|
|
645
|
+
const entry = document.createElement("div");
|
|
646
|
+
entry.className = "reasoning-entry";
|
|
647
|
+
entry.id = "reasoning-live-think";
|
|
648
|
+
entry.innerHTML = `
|
|
649
|
+
<div class="reasoning-entry-header">
|
|
650
|
+
<span class="reasoning-entry-badge badge-think">◈ THINK</span>
|
|
651
|
+
<span class="reasoning-entry-name" id="reasoning-live-name">…</span>
|
|
652
|
+
</div>
|
|
653
|
+
<div class="reasoning-think-body" id="reasoning-live-body"></div>
|
|
654
|
+
`;
|
|
655
|
+
feed.appendChild(entry);
|
|
656
|
+
_liveThinkEntry = entry;
|
|
657
|
+
_liveThinkBody = entry.querySelector("#reasoning-live-body");
|
|
658
|
+
feed.scrollTop = feed.scrollHeight;
|
|
659
|
+
};
|
|
660
|
+
|
|
661
|
+
window.updateLiveThinking = function (text) {
|
|
662
|
+
if (!_liveThinkBody) {
|
|
663
|
+
window.openLiveThinking();
|
|
664
|
+
}
|
|
665
|
+
_liveThinkBuffer += text;
|
|
666
|
+
if (_liveThinkBody) {
|
|
667
|
+
_liveThinkBody.textContent = _liveThinkBuffer;
|
|
668
|
+
const feed = document.getElementById("reasoning-feed");
|
|
669
|
+
if (feed) {
|
|
670
|
+
feed.scrollTop = feed.scrollHeight;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
// Update name preview
|
|
674
|
+
const nameEl = _liveThinkEntry?.querySelector("#reasoning-live-name");
|
|
675
|
+
if (nameEl) {
|
|
676
|
+
const firstLine = _liveThinkBuffer.split("\n")[0].slice(0, 60);
|
|
677
|
+
nameEl.textContent = firstLine + (_liveThinkBuffer.length > 60 ? "…" : "");
|
|
678
|
+
}
|
|
679
|
+
};
|
|
680
|
+
|
|
681
|
+
window.closeLiveThinking = function () {
|
|
682
|
+
if (_liveThinkEntry) {
|
|
683
|
+
_liveThinkEntry.removeAttribute("id");
|
|
684
|
+
_liveThinkEntry = null;
|
|
685
|
+
_liveThinkBody = null;
|
|
686
|
+
_liveThinkBuffer = "";
|
|
687
|
+
}
|
|
688
|
+
};
|
|
689
|
+
|
|
690
|
+
// ── Extract thinking text from a content array (for streaming deltas) ─
|
|
691
|
+
window.extractThinkingText = function (content) {
|
|
692
|
+
if (!content) {
|
|
693
|
+
return "";
|
|
694
|
+
}
|
|
695
|
+
if (typeof content === "string") {
|
|
696
|
+
return "";
|
|
697
|
+
}
|
|
698
|
+
if (Array.isArray(content)) {
|
|
699
|
+
return content
|
|
700
|
+
.filter((b) => b?.type === "thinking")
|
|
701
|
+
.map((b) => b.thinking ?? "")
|
|
702
|
+
.join("");
|
|
703
|
+
}
|
|
704
|
+
if (content?.content) {
|
|
705
|
+
return window.extractThinkingText(content.content);
|
|
706
|
+
}
|
|
707
|
+
return "";
|
|
708
|
+
};
|
|
709
|
+
|
|
500
710
|
// ── Main render function — builds a full message element ──────────────
|
|
501
711
|
window.renderMessage = function (message) {
|
|
502
712
|
const { role, content, timestamp } = message;
|
|
@@ -523,9 +733,15 @@ window.renderMessage = function (message) {
|
|
|
523
733
|
bubble.appendChild(copyBtn);
|
|
524
734
|
}
|
|
525
735
|
|
|
526
|
-
// Render each content block
|
|
736
|
+
// Render each content block — route reasoning/tool blocks to the side panel
|
|
737
|
+
const REASONING_TYPES = new Set(["thinking", "tool_use", "tool_result"]);
|
|
527
738
|
const blocks = Array.isArray(content) ? content : [{ type: "text", text: extractText(content) }];
|
|
528
739
|
for (const block of blocks) {
|
|
740
|
+
if (!isUser && REASONING_TYPES.has(block.type)) {
|
|
741
|
+
// Route to Reasoning Panel — keep response bubble clean
|
|
742
|
+
window.appendToReasoningPanel(block);
|
|
743
|
+
continue;
|
|
744
|
+
}
|
|
529
745
|
const el = renderBlock(block);
|
|
530
746
|
if (el.childNodes.length || el.innerHTML) {
|
|
531
747
|
bubble.appendChild(el);
|