nothumanallowed 13.5.6 → 13.5.8
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/package.json +1 -1
- package/src/commands/ui.mjs +5 -2
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +248 -121
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.8",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/commands/ui.mjs
CHANGED
|
@@ -3790,8 +3790,11 @@ ${writtenSoFar ? `## REPORT WRITTEN SO FAR (for consistency):\n${writtenSoFar.sl
|
|
|
3790
3790
|
}
|
|
3791
3791
|
|
|
3792
3792
|
// Estimate token usage (aprox: 1 token ≈ 4 chars)
|
|
3793
|
-
|
|
3794
|
-
const
|
|
3793
|
+
// Include context + toolData in input estimate since they're sent in the prompt
|
|
3794
|
+
const contextLen = (context || '').length;
|
|
3795
|
+
const toolDataLen = (toolData || '').length;
|
|
3796
|
+
const inTokens = Math.ceil((sysPrompt.length + userMsg.length + contextLen + toolDataLen) / 4);
|
|
3797
|
+
const outTokens = Math.ceil(fullOutputClean.length / 4);
|
|
3795
3798
|
clearInterval(keepalive);
|
|
3796
3799
|
sendEvent({ usage: { input: inTokens, output: outTokens } });
|
|
3797
3800
|
sendEvent({ done: true });
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '13.5.
|
|
8
|
+
export const VERSION = '13.5.8';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -3626,70 +3626,127 @@ function officeRoomDecor() {
|
|
|
3626
3626
|
// Characters are positioned with position:absolute, scale by row for depth.
|
|
3627
3627
|
var ISO_TILE_W = 72;
|
|
3628
3628
|
var ISO_TILE_H = 36;
|
|
3629
|
-
var ISO_ORIGIN_X =
|
|
3630
|
-
var ISO_ORIGIN_Y =
|
|
3629
|
+
var ISO_ORIGIN_X = 300;
|
|
3630
|
+
var ISO_ORIGIN_Y = 60;
|
|
3631
3631
|
function isoProject(col, row) {
|
|
3632
3632
|
return {
|
|
3633
3633
|
x: ISO_ORIGIN_X + (col - row) * (ISO_TILE_W / 2),
|
|
3634
3634
|
y: ISO_ORIGIN_Y + (col + row) * (ISO_TILE_H / 2)
|
|
3635
3635
|
};
|
|
3636
3636
|
}
|
|
3637
|
-
|
|
3637
|
+
|
|
3638
|
+
// Full bright office scene SVG background
|
|
3638
3639
|
function isoFloorSvg(cols, rows) {
|
|
3639
|
-
var w =
|
|
3640
|
+
var w = 640; var h = 320;
|
|
3640
3641
|
var out = \x27<svg viewBox="0 0 \x27+w+\x27 \x27+h+\x27" width="\x27+w+\x27" height="\x27+h+\x27" xmlns="http://www.w3.org/2000/svg" style="position:absolute;top:0;left:0;pointer-events:none;z-index:0">\x27;
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
out += \x27<polygon points="
|
|
3644
|
-
|
|
3645
|
-
out += \x27<line x1="0" y1="
|
|
3646
|
-
out += \x27<line x1="
|
|
3647
|
-
// Wall
|
|
3648
|
-
out += \x27<
|
|
3649
|
-
|
|
3650
|
-
//
|
|
3651
|
-
|
|
3652
|
-
out += \x27<polygon points="
|
|
3653
|
-
|
|
3654
|
-
out += \x27<
|
|
3655
|
-
out += \x27<polygon points="
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
out += \x27<
|
|
3659
|
-
out += \x27<
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3642
|
+
|
|
3643
|
+
// ── BACK WALL (white/cream) ──────────────────────────────────────────
|
|
3644
|
+
out += \x27<polygon points="0,100 320,20 320,120 0,200" fill="#f5f3ee"/>\x27;
|
|
3645
|
+
out += \x27<polygon points="320,20 640,100 640,200 320,120" fill="#edeae3"/>\x27;
|
|
3646
|
+
out += \x27<line x1="0" y1="100" x2="320" y2="20" stroke="#ccc" stroke-width="1.5"/>\x27;
|
|
3647
|
+
out += \x27<line x1="320" y1="20" x2="640" y2="100" stroke="#bbb" stroke-width="1.5"/>\x27;
|
|
3648
|
+
// Wall corner vertical line
|
|
3649
|
+
out += \x27<line x1="320" y1="20" x2="320" y2="120" stroke="#c8c4bc" stroke-width="1"/>\x27;
|
|
3650
|
+
|
|
3651
|
+
// ── WINDOWS — 3 centered on left wall ────────────────────────────────
|
|
3652
|
+
// Win L1
|
|
3653
|
+
out += \x27<polygon points="30,122 90,102 90,155 30,175" fill="#d0eeff" stroke="#aac8e8" stroke-width="1"/>\x27;
|
|
3654
|
+
out += \x27<line x1="60,112" y1="60" x2="60" y2="130" stroke="#aac8e8" stroke-width=".8"/>\x27;
|
|
3655
|
+
out += \x27<line x1="30,148" y1="148" x2="90" y2="128" stroke="#aac8e8" stroke-width=".8"/>\x27;
|
|
3656
|
+
out += \x27<polygon points="30,122 90,102 90,108 30,128" fill="#b8ddf8" opacity=".4"/>\x27;
|
|
3657
|
+
out += \x27<polygon points="30,122 90,102 90,155 30,175" fill="rgba(200,230,255,.12)"/>\x27;
|
|
3658
|
+
// Win L2 (center-left)
|
|
3659
|
+
out += \x27<polygon points="110,102 175,80 175,132 110,154" fill="#d0eeff" stroke="#aac8e8" stroke-width="1"/>\x27;
|
|
3660
|
+
out += \x27<polygon points="110,102 175,80 175,88 110,110" fill="#b8ddf8" opacity=".4"/>\x27;
|
|
3661
|
+
out += \x27<line x1="142" y1="91" x2="142" y2="143" stroke="#aac8e8" stroke-width=".8"/>\x27;
|
|
3662
|
+
out += \x27<line x1="110" y1="128" x2="175" y2="106" stroke="#aac8e8" stroke-width=".8"/>\x27;
|
|
3663
|
+
out += \x27<polygon points="110,102 175,80 175,132 110,154" fill="rgba(200,230,255,.10)"/>\x27;
|
|
3664
|
+
// Win L3 (center)
|
|
3665
|
+
out += \x27<polygon points="195,88 255,68 255,118 195,138" fill="#d0eeff" stroke="#aac8e8" stroke-width="1"/>\x27;
|
|
3666
|
+
out += \x27<polygon points="195,88 255,68 255,76 195,96" fill="#b8ddf8" opacity=".4"/>\x27;
|
|
3667
|
+
out += \x27<line x1="225" y1="78" x2="225" y2="128" stroke="#aac8e8" stroke-width=".8"/>\x27;
|
|
3668
|
+
out += \x27<line x1="195" y1="113" x2="255" y2="93" stroke="#aac8e8" stroke-width=".8"/>\x27;
|
|
3669
|
+
// Sunlight shafts from windows
|
|
3670
|
+
out += \x27<polygon points="50,155 90,140 120,260 80,275" fill="rgba(255,250,220,.06)"/>\x27;
|
|
3671
|
+
out += \x27<polygon points="130,132 175,116 200,260 155,275" fill="rgba(255,250,220,.05)"/>\x27;
|
|
3672
|
+
out += \x27<polygon points="210,116 255,100 270,260 225,275" fill="rgba(255,250,220,.04)"/>\x27;
|
|
3673
|
+
|
|
3674
|
+
// ── ART on left wall ────────────────────────────────────────────────
|
|
3675
|
+
// Frame 1 (small painting near top-right of left wall)
|
|
3676
|
+
out += \x27<polygon points="275,72 310,60 310,90 275,102" fill="#e8e4dc" stroke="#bbb" stroke-width="1"/>\x27;
|
|
3677
|
+
out += \x27<polygon points="278,74 307,63 307,88 278,99" fill="#7a9ed4"/>\x27;
|
|
3678
|
+
out += \x27<polygon points="285,77 303,70 303,84 285,91" fill="#a8c4e8"/>\x27;
|
|
3679
|
+
out += \x27<ellipse cx="294" cy="80" rx="5" ry="4" fill="#fff" opacity=".5"/>\x27;
|
|
3680
|
+
|
|
3681
|
+
// ── PLANT (bottom-left corner) ───────────────────────────────────────
|
|
3682
|
+
out += \x27<ellipse cx="30" cy="188" rx="10" ry="5" fill="#2d4a1e" opacity=".7"/>\x27;
|
|
3683
|
+
out += \x27<rect x="25" y="178" width="10" height="10" rx="2" fill="#5a3a1a"/>\x27;
|
|
3684
|
+
out += \x27<path d="M30 178 C25 165 18 155 22 148 C26 142 30 148 30 178" fill="#3a7a1e"/>\x27;
|
|
3685
|
+
out += \x27<path d="M30 178 C35 162 42 155 38 148 C34 142 30 150 30 178" fill="#4a8a26"/>\x27;
|
|
3686
|
+
out += \x27<path d="M30 175 C22 168 16 160 18 153" stroke="#3a7a1e" stroke-width="2" fill="none" stroke-linecap="round"/>\x27;
|
|
3687
|
+
out += \x27<path d="M30 170 C38 165 44 158 42 151" stroke="#4a8a26" stroke-width="2" fill="none" stroke-linecap="round"/>\x27;
|
|
3688
|
+
|
|
3689
|
+
// ── CEILING CHANDELIER with glow ─────────────────────────────────────
|
|
3690
|
+
out += \x27<line x1="320" y1="0" x2="320" y2="18" stroke="#999" stroke-width="2"/>\x27;
|
|
3691
|
+
// Chandelier body
|
|
3692
|
+
out += \x27<ellipse cx="320" cy="18" rx="24" ry="7" fill="#d4c88a" stroke="#b8a860" stroke-width="1.5"/>\x27;
|
|
3693
|
+
out += \x27<ellipse cx="320" cy="22" rx="20" ry="5" fill="#e8d898"/>\x27;
|
|
3694
|
+
// Bulbs hanging down
|
|
3695
|
+
out += \x27<circle cx="305" cy="28" r="5" fill="#fffbe8" filter="url(#glow)"/>\x27;
|
|
3696
|
+
out += \x27<circle cx="320" cy="26" r="6" fill="#fffbe8" filter="url(#glow)"/>\x27;
|
|
3697
|
+
out += \x27<circle cx="335" cy="28" r="5" fill="#fffbe8" filter="url(#glow)"/>\x27;
|
|
3698
|
+
out += \x27<line x1="305" y1="22" x2="305" y2="28" stroke="#aaa" stroke-width=".8"/>\x27;
|
|
3699
|
+
out += \x27<line x1="320" y1="22" x2="320" y2="26" stroke="#aaa" stroke-width=".8"/>\x27;
|
|
3700
|
+
out += \x27<line x1="335" y1="22" x2="335" y2="28" stroke="#aaa" stroke-width=".8"/>\x27;
|
|
3701
|
+
// Light cone glow on floor/walls
|
|
3702
|
+
out += \x27<radialGradient id="chandelierGlow" cx="50%" cy="0%" r="60%"><stop offset="0%" stop-color="rgba(255,245,180,.22)"/><stop offset="100%" stop-color="rgba(255,245,180,0)"/></radialGradient>\x27;
|
|
3703
|
+
out += \x27<filter id="glow"><feGaussianBlur stdDeviation="3" result="blur"/><feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge></filter>\x27;
|
|
3704
|
+
out += \x27<ellipse cx="320" cy="180" rx="200" ry="120" fill="url(#chandelierGlow)"/>\x27;
|
|
3705
|
+
|
|
3706
|
+
// ── PARQUET FLOOR — long narrow planks ───────────────────────────────
|
|
3707
|
+
// Draw rectangular plank tiles in iso projection
|
|
3708
|
+
var PLANK_W = ISO_TILE_W; var PLANK_H = ISO_TILE_H;
|
|
3709
|
+
var plankColors = [\x27#b5854a\x27,\x27#a8783c\x27,\x27#bf9055\x27,\x27#c49a60\x27,\x27#a07234\x27];
|
|
3710
|
+
for (var r2 = 0; r2 < rows; r2++) {
|
|
3711
|
+
for (var c2 = 0; c2 < cols; c2++) {
|
|
3712
|
+
var pp = isoProject(c2, r2);
|
|
3713
|
+
var ptx = pp.x; var pty = pp.y + 110;
|
|
3714
|
+
var pIdx = (r2 * 3 + c2) % plankColors.length;
|
|
3715
|
+
var pFill = plankColors[pIdx];
|
|
3716
|
+
var ppts = ptx+\x27,\x27+pty+\x27 \x27+(ptx+PLANK_W/2)+\x27,\x27+(pty+PLANK_H/2)+\x27 \x27+ptx+\x27,\x27+(pty+PLANK_H)+\x27 \x27+(ptx-PLANK_W/2)+\x27,\x27+(pty+PLANK_H/2);
|
|
3717
|
+
out += \x27<polygon points="\x27+ppts+\x27" fill="\x27+pFill+\x27" stroke="#8a6028" stroke-width=".7" opacity=".95"/>\x27;
|
|
3718
|
+
// Plank grain lines (long horizontal across plank)
|
|
3719
|
+
out += \x27<line x1="\x27+(ptx-PLANK_W/2+4)+\x27" y1="\x27+(pty+PLANK_H/2)+\x27" x2="\x27+(ptx+PLANK_W/2-4)+\x27" y2="\x27+(pty+PLANK_H/2)+\x27" stroke="rgba(0,0,0,.06)" stroke-width=".5"/>\x27;
|
|
3671
3720
|
}
|
|
3672
3721
|
}
|
|
3722
|
+
// Floor highlight (lamp reflection)
|
|
3723
|
+
out += \x27<ellipse cx="320" cy="220" rx="90" ry="30" fill="rgba(255,250,200,.08)"/>\x27;
|
|
3724
|
+
|
|
3673
3725
|
out += \x27</svg>\x27;
|
|
3674
3726
|
return out;
|
|
3675
3727
|
}
|
|
3676
|
-
// Small isometric desk object at iso position
|
|
3728
|
+
// Small isometric desk object at iso position — bright wood
|
|
3677
3729
|
function isoDeskSvg(x, y, accentColor) {
|
|
3678
|
-
var ac = accentColor || \x27#
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3730
|
+
var ac = accentColor || \x27#888\x27;
|
|
3731
|
+
var doneDesk = ac === \x27#22c55e\x27;
|
|
3732
|
+
return \x27<svg viewBox="0 0 72 44" width="72" height="44" xmlns="http://www.w3.org/2000/svg" style="position:absolute;left:\x27+(x-36)+\x27px;top:\x27+(y+8)+\x27px;z-index:\x27+(Math.round(y))+\x27;pointer-events:none">\x27+
|
|
3733
|
+
// Desk top face — warm wood
|
|
3734
|
+
\x27<polygon points="36,4 62,18 36,32 10,18" fill="#d4a855" stroke="#b8893a" stroke-width="1"/>\x27+
|
|
3735
|
+
\x27<polygon points="36,4 62,18 36,32 10,18" fill="rgba(255,255,255,.08)"/>\x27+
|
|
3736
|
+
// Grain lines on top
|
|
3737
|
+
\x27<line x1="22" y1="18" x2="50" y2="10" stroke="rgba(0,0,0,.1)" stroke-width=".8"/>\x27+
|
|
3738
|
+
\x27<line x1="22" y1="22" x2="50" y2="14" stroke="rgba(0,0,0,.07)" stroke-width=".8"/>\x27+
|
|
3682
3739
|
// Desk right face
|
|
3683
|
-
\x27<polygon points="
|
|
3740
|
+
\x27<polygon points="62,18 62,36 36,50 36,32" fill="#a8783c" stroke="#8a5c28" stroke-width=".8"/>\x27+
|
|
3684
3741
|
// Desk left face
|
|
3685
|
-
\x27<polygon points="
|
|
3686
|
-
// Monitor on desk
|
|
3687
|
-
\x27<polygon points="
|
|
3688
|
-
\x27<polygon points="
|
|
3689
|
-
// Screen lines
|
|
3690
|
-
\x27<line x1="
|
|
3691
|
-
\x27<line x1="
|
|
3692
|
-
\x27<line x1="
|
|
3742
|
+
\x27<polygon points="10,18 36,32 36,50 10,36" fill="#c49050" stroke="#9e7234" stroke-width=".8"/>\x27+
|
|
3743
|
+
// Monitor on desk — light screen
|
|
3744
|
+
\x27<polygon points="28,10 44,16 44,26 28,20" fill="#1e2840" stroke="\x27+ac+\x27" stroke-width="1.2"/>\x27+
|
|
3745
|
+
\x27<polygon points="29,11 43,17 43,25 29,19" fill="\x27+(doneDesk?\x27#0d2010\x27:\x27#0d1a2e\x27)+\x27"/>\x27+
|
|
3746
|
+
// Screen glow lines
|
|
3747
|
+
\x27<line x1="31" y1="14" x2="41" y2="18" stroke="\x27+ac+\x27" stroke-width=".9" opacity=".8"/>\x27+
|
|
3748
|
+
\x27<line x1="31" y1="17" x2="40" y2="20" stroke="\x27+ac+\x27" stroke-width=".9" opacity=".5"/>\x27+
|
|
3749
|
+
\x27<line x1="31" y1="20" x2="39" y2="23" stroke="\x27+ac+\x27" stroke-width=".9" opacity=".3"/>\x27+
|
|
3693
3750
|
\x27</svg>\x27;
|
|
3694
3751
|
}
|
|
3695
3752
|
// Isometric JRPG sprite character — top-down 3/4 perspective, Pokemon-style
|
|
@@ -3835,10 +3892,8 @@ function renderStudioNodes() {
|
|
|
3835
3892
|
|
|
3836
3893
|
// ── ISO scene dimensions ───────────────────────────────────────────────────
|
|
3837
3894
|
var ISO_COLS = Math.max(nodes.length, 1);
|
|
3838
|
-
var SCENE_W =
|
|
3895
|
+
var SCENE_W = 640; var SCENE_H = 420;
|
|
3839
3896
|
|
|
3840
|
-
// Distribute agents along row=1 of the iso grid, spaced evenly
|
|
3841
|
-
// Orchestrator walks on row=0 (further back = smaller)
|
|
3842
3897
|
var agentsHtml = \x27\x27;
|
|
3843
3898
|
nodes.forEach(function(n, idx) {
|
|
3844
3899
|
var isActive = n.status === \x27running\x27;
|
|
@@ -3846,39 +3901,34 @@ function renderStudioNodes() {
|
|
|
3846
3901
|
var isErr = n.status === \x27error\x27;
|
|
3847
3902
|
var lbl = n.label || n.agent;
|
|
3848
3903
|
var pal = agentPalette(lbl);
|
|
3849
|
-
var accentColor = isActive ? \x27#6366f1\x27 : (isDone ? \x27#22c55e\x27 : (isErr ? \x27#ef4444\x27 : \x27#
|
|
3904
|
+
var accentColor = isActive ? \x27#6366f1\x27 : (isDone ? \x27#22c55e\x27 : (isErr ? \x27#ef4444\x27 : \x27#999\x27));
|
|
3850
3905
|
|
|
3851
|
-
//
|
|
3852
|
-
var
|
|
3853
|
-
col = (
|
|
3854
|
-
var row =
|
|
3906
|
+
// Spread agents evenly across front rows
|
|
3907
|
+
var colStep = ISO_COLS > 1 ? 5 / (ISO_COLS - 1) : 2;
|
|
3908
|
+
var col = (ISO_COLS === 1) ? 2.5 : idx * colStep;
|
|
3909
|
+
var row = 3.5;
|
|
3855
3910
|
var pos = isoProject(col, row);
|
|
3856
|
-
var px = pos.x; var py = pos.y +
|
|
3857
|
-
|
|
3858
|
-
var charScale = 0.9 + row * 0.08;
|
|
3911
|
+
var px = pos.x; var py = pos.y + 80;
|
|
3912
|
+
var charScale = 1.1;
|
|
3859
3913
|
var zIdx = Math.round(py + 100);
|
|
3860
3914
|
|
|
3861
|
-
//
|
|
3862
|
-
var bubbleText = \x27\x27;
|
|
3863
|
-
var bubbleColor = \x27#6366f1\x27;
|
|
3864
|
-
if (isActive) { bubbleText = \x27...lavora\x27; bubbleColor = \x27#6366f1\x27; }
|
|
3865
|
-
else if (isDone) { bubbleText = \x27\u2714 fatto\x27; bubbleColor = \x27#22c55e\x27; }
|
|
3866
|
-
else if (isErr) { bubbleText = \x27\u2715 errore\x27; bubbleColor = \x27#ef4444\x27; }
|
|
3867
|
-
else { bubbleText = \x27in attesa\x27; bubbleColor = \x27#4a4a6a\x27; }
|
|
3868
|
-
|
|
3915
|
+
// Bubble: only show when active (live text) or done (checkmark)
|
|
3916
|
+
var bubbleText = isActive ? \x27...lavora\x27 : (isDone ? \x27\u2714 fatto\x27 : (isErr ? \x27\u2715 errore\x27 : \x27\x27));
|
|
3917
|
+
var bubbleColor = isActive ? \x27#6366f1\x27 : (isDone ? \x27#22c55e\x27 : \x27#ef4444\x27);
|
|
3869
3918
|
var charSvg = isoCharSvg({skin: pal.skin, shirt: pal.shirt, hair: pal.hair,
|
|
3870
3919
|
isActive: isActive, isDone: isDone, scale: charScale, accentColor: accentColor});
|
|
3920
|
+
var charW = Math.round(48 * charScale); var charH = Math.round(64 * charScale);
|
|
3871
3921
|
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
3922
|
+
agentsHtml += \x27<div class="iso-agent" data-agent-label="\x27+esc(lbl)+\x27" style="position:absolute;left:\x27+(px-charW/2)+\x27px;top:\x27+(py-charH)+\x27px;z-index:\x27+zIdx+\x27;display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer" onclick="studioScrollToAgent(this.getAttribute(String.fromCharCode(100,97,116,97,45,97,103,101,110,116,45,108,97,98,101,108)))">\x27;
|
|
3923
|
+
// Bubble — bigger, left-aligned (no mirror issue)
|
|
3924
|
+
if (bubbleText || isActive) {
|
|
3925
|
+
agentsHtml += \x27<div class="iso-bubble\x27+(isActive?\x27 iso-bubble--active\x27:\x27\x27)+\x27" id="isobubble_\x27+idx+\x27" style="border-color:\x27+bubbleColor+\x27;color:\x27+bubbleColor+\x27;min-width:80px;max-width:140px;font-size:10px;padding:4px 10px;text-align:left">\x27+esc(bubbleText)+\x27</div>\x27;
|
|
3926
|
+
} else {
|
|
3927
|
+
agentsHtml += \x27<div class="iso-bubble" id="isobubble_\x27+idx+\x27" style="visibility:hidden;min-width:80px"></div>\x27;
|
|
3928
|
+
}
|
|
3878
3929
|
agentsHtml += charSvg;
|
|
3879
|
-
|
|
3880
|
-
|
|
3881
|
-
// Iso desk below character
|
|
3930
|
+
agentsHtml += \x27<div class="iso-name" style="font-size:10px;font-weight:700;color:\x27+(isDone?\x27#22c55e\x27:(isActive?\x27#818cf8\x27:(isErr?\x27#ef4444\x27:\x27#555\x27)))+\x27;text-shadow:0 1px 3px rgba(255,255,255,.8)">\x27+esc(lbl)+\x27</div>\x27;
|
|
3931
|
+
// Desk — lighter wood color for bright office
|
|
3882
3932
|
agentsHtml += isoDeskSvg(px, py - charH/2, accentColor);
|
|
3883
3933
|
agentsHtml += \x27</div>\x27;
|
|
3884
3934
|
});
|
|
@@ -3886,17 +3936,16 @@ function renderStudioNodes() {
|
|
|
3886
3936
|
// ── Orchestrator ──────────────────────────────────────────────────────────
|
|
3887
3937
|
var orchHtml = \x27\x27;
|
|
3888
3938
|
if (showMaster) {
|
|
3889
|
-
var oPh = isoProject(ISO_COLS / 2
|
|
3890
|
-
var orchPhrase = [\x27Analizzo il progresso...\x27, \x27Verifico gli step...\x27, \x27Coordinamento...\x27, \x27Supervisione in corso\x27][Math.floor(Date.now()/3000)%4];
|
|
3939
|
+
var oPh = isoProject(ISO_COLS / 2 + 0.5, 1.2);
|
|
3891
3940
|
var orchDone = !hasActive && doneCount === totalCount;
|
|
3892
3941
|
var orchAnim = hasActive ? \x27prl-master-walk\x27 : (orchDone ? \x27prl-master-done\x27 : \x27\x27);
|
|
3893
3942
|
var orchStatus = hasActive
|
|
3894
|
-
? (\
|
|
3895
|
-
: (orchDone ? \
|
|
3896
|
-
orchHtml = \x27<div class="prl-master \x27+orchAnim+\x27" id="wfOrch" style="position:absolute;left:\x27+(oPh.x
|
|
3897
|
-
\x27<div class="iso-bubble iso-bubble--orch" id="wfOrchBubble" style="border-color:#
|
|
3943
|
+
? (\x27Step \x27+doneCount+\x27/\x27+totalCount)
|
|
3944
|
+
: (orchDone ? \x27Completato!\x27 : \x27Pianificazione\x27);
|
|
3945
|
+
orchHtml = \x27<div class="prl-master \x27+orchAnim+\x27" id="wfOrch" style="position:absolute;left:\x27+(oPh.x-28)+\x27px;top:\x27+(oPh.y+60)+\x27px;z-index:50;display:flex;flex-direction:column;align-items:center;gap:3px">\x27+
|
|
3946
|
+
\x27<div class="iso-bubble iso-bubble--orch" id="wfOrchBubble" style="border-color:#6366f1;color:#6366f1;max-width:140px;font-size:10px;padding:4px 10px">\x27+esc(orchStatus)+\x27</div>\x27+
|
|
3898
3947
|
isoOrchSvg(hasActive, doneCount / Math.max(totalCount,1))+
|
|
3899
|
-
\x27<div class="prl-master-label" style="color:#
|
|
3948
|
+
\x27<div class="prl-master-label" style="color:#6366f1;font-size:9px;font-weight:700;text-shadow:0 1px 3px rgba(255,255,255,.8)">Orchestratore</div>\x27+
|
|
3900
3949
|
\x27</div>\x27;
|
|
3901
3950
|
}
|
|
3902
3951
|
|
|
@@ -3908,11 +3957,13 @@ function renderStudioNodes() {
|
|
|
3908
3957
|
el.innerHTML =
|
|
3909
3958
|
\x27<div class="prl-wrap" style="border-color:\x27+phaseColor2+\x2744;padding-bottom:8px">\x27+
|
|
3910
3959
|
\x27<div class="prl-header"><span class="prl-phase-chip" style="--pc:\x27+phaseColor2+\x27">\x27+phaseLabel2+\x27</span></div>\x27+
|
|
3911
|
-
\x27<div
|
|
3912
|
-
|
|
3960
|
+
\x27<div style="display:flex;justify-content:center;width:100%;overflow-x:auto">\x27+
|
|
3961
|
+
\x27<div class="iso-scene" style="position:relative;width:\x27+SCENE_W+\x27px;min-width:\x27+SCENE_W+\x27px;height:\x27+SCENE_H+\x27px;overflow:hidden;border-radius:12px;background:#f0ede6">\x27+
|
|
3962
|
+
isoFloorSvg(ISO_COLS + 2, 5)+
|
|
3913
3963
|
agentsHtml+
|
|
3914
3964
|
orchHtml+
|
|
3915
3965
|
\x27</div>\x27+
|
|
3966
|
+
\x27</div>\x27+
|
|
3916
3967
|
\x27</div>\x27;
|
|
3917
3968
|
}
|
|
3918
3969
|
|
|
@@ -4440,7 +4491,7 @@ async function runStudio() {
|
|
|
4440
4491
|
nudge = document.createElement(\x27div\x27);
|
|
4441
4492
|
nudge.id = \x27studioParliamentNudge\x27;
|
|
4442
4493
|
nudge.style.cssText = \x27margin:8px 0;padding:8px 12px;background:#1a1a2e;border:1px solid #6366f1;border-radius:8px;font-size:11px;color:#a5b4fc;display:flex;align-items:center;gap:10px\x27;
|
|
4443
|
-
nudge.innerHTML = \x27&#
|
|
4494
|
+
nudge.innerHTML = \x27💼 <span><strong>Suggerimento:</strong> questo workflow ha \x27 + specialistAgents.length + \x27 agenti specialisti — attiva il <strong>Consiglio</strong> per un confronto critico tra le loro analisi.</span><button onclick="document.getElementById(\\\x27studioParliamentMode\\\x27).checked=true;studioState.parliamentMode=true;this.parentNode.remove()" style="margin-left:auto;background:#6366f1;border:none;border-radius:6px;color:#fff;padding:4px 10px;cursor:pointer;font-size:10px;white-space:nowrap">Attiva 💼</button>\x27;
|
|
4444
4495
|
var tokenBar = document.getElementById(\x27studioTokenBar\x27);
|
|
4445
4496
|
if (tokenBar && tokenBar.parentNode) tokenBar.parentNode.insertBefore(nudge, tokenBar.parentNode.firstChild);
|
|
4446
4497
|
}
|
|
@@ -4511,10 +4562,10 @@ async function runStudio() {
|
|
|
4511
4562
|
proposals.push({agent: \x27Context\x27, label: \x27Contesto workflow\x27, output: context});
|
|
4512
4563
|
}
|
|
4513
4564
|
if (proposals.length >= 2) {
|
|
4514
|
-
studioLog(\
|
|
4515
|
-
// Add
|
|
4565
|
+
studioLog(\x27Consiglio\x27, \x27💼\x27, \x27Avvio Consiglio — gli agenti si riuniscono per confrontare e raffinare i risultati...\x27, \x27system\x27);
|
|
4566
|
+
// Add Consiglio node to pipeline visual
|
|
4516
4567
|
var parlNodeIdx = studioState.nodes.length;
|
|
4517
|
-
studioState.nodes.push({icon:\x27&#
|
|
4568
|
+
studioState.nodes.push({icon:\x27💼\x27, agent:\x27Consiglio\x27, label:\x27Consiglio\x27, status:\x27running\x27, output:\x27\x27, _rendered:false});
|
|
4518
4569
|
renderStudioNodes();
|
|
4519
4570
|
|
|
4520
4571
|
// ── Parliament visual block ──────────────────────────────────────
|
|
@@ -4532,10 +4583,10 @@ async function runStudio() {
|
|
|
4532
4583
|
|
|
4533
4584
|
var phaseColor = {r1:\x27#6366f1\x27,r2:\x27#22d3ee\x27,r3:\x27#f59e0b\x27,done:\x27#22c55e\x27}[phase]||\x27#6366f1\x27;
|
|
4534
4585
|
var phaseLabel = {
|
|
4535
|
-
r1:\
|
|
4536
|
-
r2:\
|
|
4537
|
-
r3:\
|
|
4538
|
-
done:\
|
|
4586
|
+
r1:\x27Consiglio \u2014 Analisi individuale\x27,
|
|
4587
|
+
r2:\x27Consiglio \u2014 Confronto e raffinamento\x27,
|
|
4588
|
+
r3:\x27Consiglio \u2014 Sintesi finale HERALD\x27,
|
|
4589
|
+
done:\x27Consiglio concluso \u2014 consenso raggiunto\x27
|
|
4539
4590
|
}[phase]||\x27\x27;
|
|
4540
4591
|
var n = proposals.length;
|
|
4541
4592
|
var doneCount = Object.keys(parlDoneAgents).length;
|
|
@@ -4646,7 +4697,7 @@ async function runStudio() {
|
|
|
4646
4697
|
var orchHtml = \x27<div class="br-orch" id="brOrch">\x27+
|
|
4647
4698
|
\x27<div class="br-orch-speech" id="brOrchSpeech"></div>\x27+
|
|
4648
4699
|
orchSvg+
|
|
4649
|
-
\x27<div class="br-orch-label">
|
|
4700
|
+
\x27<div class="br-orch-label">NHA Studio</div>\x27+
|
|
4650
4701
|
\x27</div>\x27;
|
|
4651
4702
|
|
|
4652
4703
|
// Phase indicator + progress
|
|
@@ -4685,17 +4736,17 @@ async function runStudio() {
|
|
|
4685
4736
|
if (convEl && convergence != null) {
|
|
4686
4737
|
convEl.style.display = \x27block\x27;
|
|
4687
4738
|
convEl.innerHTML = \x27<div class="br-conv-bar-outer"><div class="br-conv-bar-inner" style="width:\x27+Math.min(convergence,100)+\x27%"></div></div>\x27+
|
|
4688
|
-
\x27<div class="br-conv-text"><strong>\u2714 Convergenza \x27+convergence+\x27%</strong> \u2014 HERALD ha sintetizzato il
|
|
4739
|
+
\x27<div class="br-conv-text"><strong>\u2714 Convergenza: \x27+convergence+\x27%</strong> \u2014 Il Consiglio ha raggiunto il consenso. HERALD ha sintetizzato il risultato finale.</div>\x27;
|
|
4689
4740
|
}
|
|
4690
4741
|
|
|
4691
4742
|
// Orchestrator speech bubble
|
|
4692
4743
|
var orchSpeech = document.getElementById(\x27brOrchSpeech\x27);
|
|
4693
4744
|
if (orchSpeech) {
|
|
4694
4745
|
var orchSpeeches = {
|
|
4695
|
-
r1: [\
|
|
4696
|
-
r2: [\
|
|
4697
|
-
r3: [\
|
|
4698
|
-
done: [\
|
|
4746
|
+
r1: [\x27Analisi in corso...\x27,\x27Ogni team al lavoro\x27,\x27Raccolta dati\x27,\x27Prima bozza...\x27],
|
|
4747
|
+
r2: [\x27Confronto in corso\x27,\x27Cross-review...\x27,\x27Raffinamento\x27,\x27Scambio idee\x27],
|
|
4748
|
+
r3: [\x27Sintesi finale\x27,\x27Convergenza...\x27,\x27Accordo in vista\x27],
|
|
4749
|
+
done: [\x27Consiglio concluso\x27,\x27Consenso raggiunto\x27,\x27Report pronto\x27]
|
|
4699
4750
|
};
|
|
4700
4751
|
var spArr = orchSpeeches[phase] || orchSpeeches.r1;
|
|
4701
4752
|
if (phase === \x27done\x27) {
|
|
@@ -4716,6 +4767,42 @@ async function runStudio() {
|
|
|
4716
4767
|
orchEl.style.setProperty(\x27--oc\x27, phaseColor);
|
|
4717
4768
|
}
|
|
4718
4769
|
|
|
4770
|
+
// Draw attention line from orchestrator to active agent seat
|
|
4771
|
+
var orchEl2 = document.getElementById(\x27brOrch\x27);
|
|
4772
|
+
var brRoom2 = orchEl2 ? orchEl2.closest(\x27.br-room\x27) : null;
|
|
4773
|
+
if (brRoom2) {
|
|
4774
|
+
var existLine = brRoom2.querySelector(\x27.br-attention-line\x27);
|
|
4775
|
+
if (existLine) existLine.parentNode.removeChild(existLine);
|
|
4776
|
+
if (activeLabel && phase !== \x27done\x27) {
|
|
4777
|
+
var aLblSafe = activeLabel.replace(/[^a-zA-Z0-9_-]/g,\x27_\x27);
|
|
4778
|
+
var activeSeatEl = document.getElementById(\x27brseat_\x27+aLblSafe);
|
|
4779
|
+
if (activeSeatEl && orchEl2) {
|
|
4780
|
+
var roomRect = brRoom2.getBoundingClientRect();
|
|
4781
|
+
var orchRect = orchEl2.getBoundingClientRect();
|
|
4782
|
+
var seatRect = activeSeatEl.getBoundingClientRect();
|
|
4783
|
+
var x1 = orchRect.left + orchRect.width/2 - roomRect.left;
|
|
4784
|
+
var y1 = orchRect.top + orchRect.height/2 - roomRect.top;
|
|
4785
|
+
var x2 = seatRect.left + seatRect.width/2 - roomRect.left;
|
|
4786
|
+
var y2 = seatRect.top + seatRect.height/2 - roomRect.top;
|
|
4787
|
+
var lineSvg = document.createElementNS(\x27http://www.w3.org/2000/svg\x27, \x27svg\x27);
|
|
4788
|
+
lineSvg.setAttribute(\x27class\x27, \x27br-attention-line\x27);
|
|
4789
|
+
lineSvg.style.cssText = \x27position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:10;overflow:visible\x27;
|
|
4790
|
+
var lineEl = document.createElementNS(\x27http://www.w3.org/2000/svg\x27, \x27line\x27);
|
|
4791
|
+
lineEl.setAttribute(\x27x1\x27, String(Math.round(x1)));
|
|
4792
|
+
lineEl.setAttribute(\x27y1\x27, String(Math.round(y1)));
|
|
4793
|
+
lineEl.setAttribute(\x27x2\x27, String(Math.round(x2)));
|
|
4794
|
+
lineEl.setAttribute(\x27y2\x27, String(Math.round(y2)));
|
|
4795
|
+
lineEl.setAttribute(\x27stroke\x27, \x27#6366f1\x27);
|
|
4796
|
+
lineEl.setAttribute(\x27stroke-width\x27, \x272\x27);
|
|
4797
|
+
lineEl.setAttribute(\x27stroke-dasharray\x27, \x276 4\x27);
|
|
4798
|
+
lineEl.setAttribute(\x27opacity\x27, \x27.6\x27);
|
|
4799
|
+
lineEl.style.animation = \x27brDashFlow 1s linear infinite\x27;
|
|
4800
|
+
lineSvg.appendChild(lineEl);
|
|
4801
|
+
brRoom2.appendChild(lineSvg);
|
|
4802
|
+
}
|
|
4803
|
+
}
|
|
4804
|
+
}
|
|
4805
|
+
|
|
4719
4806
|
// Update each agent seat state
|
|
4720
4807
|
proposals.forEach(function(prop) {
|
|
4721
4808
|
var lbl = prop.label || prop.agent;
|
|
@@ -5198,7 +5285,7 @@ async function runStudio() {
|
|
|
5198
5285
|
if (r2StartM) {
|
|
5199
5286
|
var r2Label = r2StartM[1];
|
|
5200
5287
|
parlActiveAgent = r2Label;
|
|
5201
|
-
studioLog(r2Label, \x27&#
|
|
5288
|
+
studioLog(r2Label, \x27💼\x27, \x27\x27, \x27agent\x27, false);
|
|
5202
5289
|
var delEnts2 = document.querySelectorAll(\x27.studio-log-entry\x27);
|
|
5203
5290
|
var delL2 = delEnts2[delEnts2.length - 1];
|
|
5204
5291
|
if (delL2) {
|
|
@@ -5232,10 +5319,25 @@ async function runStudio() {
|
|
|
5232
5319
|
var delEntries = document.querySelectorAll(\x27.studio-log-entry\x27);
|
|
5233
5320
|
var delLast = delEntries[delEntries.length - 1];
|
|
5234
5321
|
if (delLast) { var delTb = delLast.querySelector(\x27.studio-log-entry__text\x27); if (delTb) delTb.textContent = dev.token.replace(new RegExp(\x27[\\r\\n]+\x27,\x27g\x27),\x27 \x27); }
|
|
5322
|
+
// Mirror live token to the active agent boardroom bubble
|
|
5323
|
+
if (parlActiveAgent) {
|
|
5324
|
+
var brSafe2 = parlActiveAgent.replace(new RegExp(\x27[^a-zA-Z0-9_-]\x27,\x27g\x27),\x27_\x27);
|
|
5325
|
+
var brLiveBubble = document.getElementById(\x27brbubble_\x27+brSafe2);
|
|
5326
|
+
if (brLiveBubble) {
|
|
5327
|
+
var rawTok = dev.token.replace(new RegExp(\x27[\\r\\n]+\x27,\x27g\x27),\x27 \x27);
|
|
5328
|
+
var safeTok = rawTok.replace(/&/g,\x27&\x27).replace(/</g,\x27<\x27).replace(/>/g,\x27>\x27);
|
|
5329
|
+
var truncTok = rawTok.length > 60 ? rawTok.slice(-60) : rawTok;
|
|
5330
|
+
var safeTrunc = truncTok.replace(/&/g,\x27&\x27).replace(/</g,\x27<\x27).replace(/>/g,\x27>\x27);
|
|
5331
|
+
brLiveBubble.style.display = \x27\x27;
|
|
5332
|
+
brLiveBubble.innerHTML = safeTrunc + \x27<span style="display:inline-block;width:2px;height:8px;background:var(--green);margin-left:1px;vertical-align:text-bottom;animation:streamBlink .7s step-end infinite">​</span>\x27;
|
|
5333
|
+
brLiveBubble.style.borderColor = \x27#6366f1\x27;
|
|
5334
|
+
brLiveBubble.style.color = \x27#a5b4fc\x27;
|
|
5335
|
+
}
|
|
5336
|
+
}
|
|
5235
5337
|
}
|
|
5236
5338
|
} else if (dev.deliberation_r2) {
|
|
5237
5339
|
var r2d = dev.deliberation_r2;
|
|
5238
|
-
studioLog(r2d.label || r2d.agent, \x27&#
|
|
5340
|
+
studioLog(r2d.label || r2d.agent, \x27💼\x27, \x27[Consiglio R2] \x27 + (r2d.output || \x27\x27), \x27agent\x27, true);
|
|
5239
5341
|
var ni2 = studioState.nodes.findIndex(function(x){return x.agent===r2d.agent;});
|
|
5240
5342
|
if (ni2 >= 0) { studioState.nodes[ni2].output = r2d.output; studioState.nodes[ni2].status = \x27done\x27; }
|
|
5241
5343
|
studioAddTokens(0, Math.ceil((r2d.output||'').length / 4));
|
|
@@ -5252,12 +5354,12 @@ async function runStudio() {
|
|
|
5252
5354
|
context = dev.deliberation_r3.output || context;
|
|
5253
5355
|
} else if (dev.deliberation_done) {
|
|
5254
5356
|
var r2Conv = Math.round((dev.r2_convergence || 0) * 100);
|
|
5255
|
-
studioLog(\
|
|
5357
|
+
studioLog(\x27Consiglio\x27, \x27💼\x27, \x27Consiglio concluso — convergenza R2: \x27 + r2Conv + \x27%\x27, \x27system\x27);
|
|
5256
5358
|
if (dev.mediation) { context = dev.mediation; }
|
|
5257
5359
|
renderParlBlock(\x27done\x27, null, r2Conv);
|
|
5258
5360
|
if (studioState.nodes[parlNodeIdx]) {
|
|
5259
5361
|
studioState.nodes[parlNodeIdx].status = \x27done\x27;
|
|
5260
|
-
studioState.nodes[parlNodeIdx].label = \
|
|
5362
|
+
studioState.nodes[parlNodeIdx].label = \x27Consiglio (\x27 + r2Conv + \x27%)\x27;
|
|
5261
5363
|
renderStudioNodes();
|
|
5262
5364
|
}
|
|
5263
5365
|
delDone = true;
|
|
@@ -5270,7 +5372,7 @@ async function runStudio() {
|
|
|
5270
5372
|
}
|
|
5271
5373
|
} catch(e3) {
|
|
5272
5374
|
if (e3.name !== \x27AbortError\x27) {
|
|
5273
|
-
studioLog(\
|
|
5375
|
+
studioLog(\x27Consiglio\x27, \x27💼\x27, \x27Consiglio non disponibile: \x27 + (e3.message || String(e3)), \x27error\x27);
|
|
5274
5376
|
// Do NOT hide the parliament block if it already has content — user is watching it
|
|
5275
5377
|
}
|
|
5276
5378
|
}
|
|
@@ -5341,7 +5443,9 @@ function saveStudioSession(task, nodes, log, result) {
|
|
|
5341
5443
|
var sessions = JSON.parse(localStorage.getItem('nha_studio_sessions') || '[]');
|
|
5342
5444
|
// Save parliament block HTML if present (static snapshot — animations not needed on restore)
|
|
5343
5445
|
var parlEl = document.getElementById('studioParliamentBlock');
|
|
5344
|
-
var
|
|
5446
|
+
var parlRaw = (parlEl && parlEl.style.display !== 'none') ? parlEl.innerHTML : null;
|
|
5447
|
+
// Limit parlHtml to 30KB to avoid localStorage quota issues
|
|
5448
|
+
var parlHtml = parlRaw ? (parlRaw.length > 30000 ? parlRaw.slice(0, 30000) : parlRaw) : null;
|
|
5345
5449
|
sessions.unshift({
|
|
5346
5450
|
id: Date.now(),
|
|
5347
5451
|
task: task,
|
|
@@ -5352,8 +5456,14 @@ function saveStudioSession(task, nodes, log, result) {
|
|
|
5352
5456
|
log: log.map(function(e){return {agent:e.agent,icon:e.icon,text:e.text,type:e.type,time:e.time};}),
|
|
5353
5457
|
ts: new Date().toLocaleString()
|
|
5354
5458
|
});
|
|
5355
|
-
sessions = sessions.slice(0,
|
|
5356
|
-
|
|
5459
|
+
sessions = sessions.slice(0, 10); // keep last 10 (save space)
|
|
5460
|
+
try {
|
|
5461
|
+
localStorage.setItem('nha_studio_sessions', JSON.stringify(sessions));
|
|
5462
|
+
} catch(qe) {
|
|
5463
|
+
// Quota exceeded: save without canvas/parlHtml
|
|
5464
|
+
sessions[0].canvas = null; sessions[0].parlHtml = null;
|
|
5465
|
+
try { localStorage.setItem('nha_studio_sessions', JSON.stringify(sessions)); } catch(e2) {}
|
|
5466
|
+
}
|
|
5357
5467
|
} catch(e) {}
|
|
5358
5468
|
}
|
|
5359
5469
|
|
|
@@ -5403,6 +5513,10 @@ function restoreStudioSession(idx) {
|
|
|
5403
5513
|
if (s.parlHtml) {
|
|
5404
5514
|
parlEl.innerHTML = s.parlHtml;
|
|
5405
5515
|
parlEl.style.display = 'block';
|
|
5516
|
+
// Scroll into view after DOM settles
|
|
5517
|
+
setTimeout(function() {
|
|
5518
|
+
if (parlEl) parlEl.scrollIntoView({behavior: 'smooth', block: 'start'});
|
|
5519
|
+
}, 150);
|
|
5406
5520
|
} else {
|
|
5407
5521
|
parlEl.style.display = 'none';
|
|
5408
5522
|
}
|
|
@@ -5546,13 +5660,16 @@ function runStudioStep(idx, node, task, context, stepDef, signal) {
|
|
|
5546
5660
|
if (tb) {
|
|
5547
5661
|
if (isStatus) {
|
|
5548
5662
|
var st = ev.token.replace(new RegExp(\x27[\\\\r\\\\n]+\x27,\x27g\x27), \x27 \x27);
|
|
5549
|
-
//
|
|
5550
|
-
var
|
|
5663
|
+
// Strip surrounding brackets for display
|
|
5664
|
+
var stLabel = st.replace(new RegExp(\x27^\\\\[\x27), \x27\x27).replace(new RegExp(\x27\\\\]\\\\s*$\x27), \x27\x27).trim();
|
|
5665
|
+
// Special chip for Searching
|
|
5666
|
+
var srchM = st.match(new RegExp(\x27^\\\\[Searching:\\\\s*"([^"]+)"\\\\]\\\\s*$\x27));
|
|
5551
5667
|
if (srchM) {
|
|
5552
5668
|
var qEsc = srchM[1].replace(/&/g,\x27&\x27).replace(/</g,\x27<\x27).replace(/>/g,\x27>\x27);
|
|
5553
|
-
tb.innerHTML = \x27<span
|
|
5669
|
+
tb.innerHTML = \x27<span class="iso-status-chip"><span class="iso-status-dot"></span>🔍 <span style="color:var(--dim)">Cercando</span> <strong style="color:#a5b4fc">\x27+qEsc+\x27</strong></span>\x27;
|
|
5554
5670
|
} else {
|
|
5555
|
-
|
|
5671
|
+
var stEsc = stLabel.replace(/&/g,\x27&\x27).replace(/</g,\x27<\x27).replace(/>/g,\x27>\x27);
|
|
5672
|
+
tb.innerHTML = \x27<span class="iso-status-chip"><span class="iso-status-dot"></span>\x27+stEsc+\x27</span>\x27;
|
|
5556
5673
|
}
|
|
5557
5674
|
} else {
|
|
5558
5675
|
// Word-by-word streaming: APPEND new chars, never overwrite
|
|
@@ -5639,9 +5756,14 @@ function runStudioStep(idx, node, task, context, stepDef, signal) {
|
|
|
5639
5756
|
}
|
|
5640
5757
|
}
|
|
5641
5758
|
if (ev.usage) {
|
|
5759
|
+
// Backend sends accurate usage at end: add input, replace out estimate with real value
|
|
5642
5760
|
var uIn = ev.usage.input||0; var uOut = ev.usage.output||0;
|
|
5643
|
-
|
|
5644
|
-
|
|
5761
|
+
// Correct output: remove per-token estimate already added, replace with real count
|
|
5762
|
+
var outDiff = uOut - stepTokensOut;
|
|
5763
|
+
studioTokens.out = Math.max(0, studioTokens.out + outDiff);
|
|
5764
|
+
stepTokensIn += uIn; stepTokensOut = uOut;
|
|
5765
|
+
studioTokens.in += uIn;
|
|
5766
|
+
studioUpdateTokenBar();
|
|
5645
5767
|
} else if (ev.token && !isStatus) {
|
|
5646
5768
|
var est = Math.ceil(ev.token.length/4);
|
|
5647
5769
|
stepTokensOut += est; studioTokens.out += est; studioUpdateTokenBar();
|
|
@@ -5779,7 +5901,7 @@ function renderStudio(el) {
|
|
|
5779
5901
|
'</div>' +
|
|
5780
5902
|
'<label style="display:flex;align-items:center;gap:8px;margin-top:8px;cursor:pointer;user-select:none">' +
|
|
5781
5903
|
'<input type="checkbox" id="studioParliamentMode" style="width:15px;height:15px;accent-color:var(--green3)" ' + (studioState.parliamentMode ? \x27checked\x27 : \x27\x27) + ' onchange="studioState.parliamentMode=this.checked">' +
|
|
5782
|
-
'<span style="font-size:12px;color:var(--dim)">&#
|
|
5904
|
+
'<span style="font-size:12px;color:var(--dim)">💼 <strong style="color:var(--green)">Consiglio</strong> — gli agenti si confrontano dopo aver lavorato in autonomia (2x token)</span>' +
|
|
5783
5905
|
'</label>' +
|
|
5784
5906
|
'</div>' +
|
|
5785
5907
|
|
|
@@ -5805,7 +5927,6 @@ function renderStudio(el) {
|
|
|
5805
5927
|
'<div class="studio-log" id="studioLog" style="display:none"></div>' +
|
|
5806
5928
|
'<div id="studioParliamentBlock" style="display:none;margin-bottom:12px"></div>' +
|
|
5807
5929
|
'<div id="studioResult"></div>' +
|
|
5808
|
-
'<div id="studioSessionsBar" style="margin-top:16px;display:none"></div>' +
|
|
5809
5930
|
'</div>' +
|
|
5810
5931
|
|
|
5811
5932
|
// ── AGENT SIDEBAR ──
|
|
@@ -5818,6 +5939,7 @@ function renderStudio(el) {
|
|
|
5818
5939
|
'<div style="font-size:9px;color:var(--dim);margin-bottom:8px">Click to add to pipeline</div>' +
|
|
5819
5940
|
'<div id="sideToolsList">'+toolsHtml+'</div>' +
|
|
5820
5941
|
'<div id="sideAgentsList" style="display:none">'+specialistHtml+'</div>' +
|
|
5942
|
+
'<div id="studioSessionsBar" style="margin-top:16px;display:none"></div>' +
|
|
5821
5943
|
'</div>' +
|
|
5822
5944
|
'</div>';
|
|
5823
5945
|
|
|
@@ -6313,10 +6435,10 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
6313
6435
|
.studio-header{margin-bottom:20px}
|
|
6314
6436
|
.studio-header h2{font-size:15px;color:var(--green);margin-bottom:4px}
|
|
6315
6437
|
.studio-header p{font-size:11px;color:var(--dim);line-height:1.5}
|
|
6316
|
-
.studio-input-row{display:flex;gap:8px;margin-bottom:
|
|
6317
|
-
.studio-input-row textarea{flex:1;resize:
|
|
6438
|
+
.studio-input-row{display:flex;gap:8px;margin-bottom:16px;align-items:flex-start}
|
|
6439
|
+
.studio-input-row textarea{flex:1;resize:vertical;min-height:90px;max-height:200px;padding:10px 14px;font-size:13px;border-radius:var(--r);border:1px solid var(--border2);line-height:1.5}
|
|
6318
6440
|
.studio-input-row textarea:focus{border-color:var(--green3)}
|
|
6319
|
-
.studio-run-btn{background:var(--green3);color:var(--bg);padding:0
|
|
6441
|
+
.studio-run-btn{background:var(--green3);color:var(--bg);padding:0 16px;border-radius:var(--r);font-weight:600;font-size:12px;white-space:nowrap;align-self:stretch;min-width:80px;letter-spacing:.2px}
|
|
6320
6442
|
.studio-run-btn:disabled{opacity:.4}
|
|
6321
6443
|
.studio-canvas{position:relative;width:100%;min-height:220px;background:var(--bg2);border:1px solid var(--border);border-radius:8px;margin-bottom:20px;overflow:hidden}
|
|
6322
6444
|
.studio-canvas__empty{display:flex;align-items:center;justify-content:center;height:180px;color:var(--dim);font-size:11px;flex-direction:column;gap:8px}
|
|
@@ -6424,6 +6546,7 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
6424
6546
|
.br-conv-bar-outer{height:4px;background:#1a2e1a;border-radius:4px;overflow:hidden;margin-bottom:6px}
|
|
6425
6547
|
.br-conv-bar-inner{height:100%;background:linear-gradient(90deg,#22c55e,#4ade80);border-radius:4px;transition:width .8s ease}
|
|
6426
6548
|
.br-conv-text{font-size:9px;color:#86efac;line-height:1.55}
|
|
6549
|
+
@keyframes brDashFlow{0%{stroke-dashoffset:20}100%{stroke-dashoffset:0}}
|
|
6427
6550
|
/* Keep old prl-* classes for workflow (not touched) */
|
|
6428
6551
|
.prl-wrap{background:#0b0918;border:1.5px solid #6366f1;border-radius:14px;padding:14px 16px 12px;margin-bottom:16px;animation:stNodeIn .35s ease forwards;overflow:hidden}
|
|
6429
6552
|
@keyframes parlPulse{0%,100%{border-color:#6366f1;box-shadow:none}50%{border-color:#818cf8;box-shadow:0 0 20px rgba(99,102,241,.3)}}
|
|
@@ -6472,7 +6595,11 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
6472
6595
|
/* Plant right */
|
|
6473
6596
|
.prl-office-plant2{position:absolute;bottom:14px;right:8px;width:22px;height:42px;z-index:2;pointer-events:none}
|
|
6474
6597
|
/* ── ISOMETRIC JRPG SCENE ── */
|
|
6475
|
-
.iso-scene{background:#
|
|
6598
|
+
.iso-scene{background:#f0ede6;cursor:default;max-width:100%;overflow-x:auto;box-shadow:0 4px 24px rgba(0,0,0,.18)}
|
|
6599
|
+
/* Animated status chip for [bracket tokens] */
|
|
6600
|
+
.iso-status-chip{display:inline-flex;align-items:center;gap:6px;background:rgba(99,102,241,.1);border:1px solid rgba(99,102,241,.3);border-radius:20px;padding:3px 10px;font-size:11px;font-family:var(--mono);color:#818cf8;animation:statusPulse 2s ease-in-out infinite}
|
|
6601
|
+
@keyframes statusPulse{0%,100%{opacity:.7;border-color:rgba(99,102,241,.3)}50%{opacity:1;border-color:rgba(99,102,241,.7);box-shadow:0 0 8px rgba(99,102,241,.3)}}
|
|
6602
|
+
.iso-status-dot{width:6px;height:6px;border-radius:50%;background:#6366f1;animation:dotBounce 1s ease-in-out infinite}
|
|
6476
6603
|
.iso-agent{transition:filter .3s}
|
|
6477
6604
|
.iso-agent:hover{filter:brightness(1.15)}
|
|
6478
6605
|
/* Thought bubble / speech bubble above character */
|
|
@@ -6542,7 +6669,7 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
6542
6669
|
.prl-conv-bar-inner{height:100%;background:linear-gradient(90deg,#22c55e,#4ade80);border-radius:4px;transition:width .8s ease}
|
|
6543
6670
|
.prl-conv-text{font-size:9px;color:#86efac;line-height:1.55}
|
|
6544
6671
|
.studio-log{background:var(--bg2);border:1px solid var(--border);border-radius:10px;padding:16px;max-height:380px;overflow-y:auto;font-size:11.5px;line-height:1.65}
|
|
6545
|
-
.studio-log-entry{margin-bottom:
|
|
6672
|
+
.studio-log-entry{margin-bottom:10px;padding:14px 16px;border-radius:10px;background:var(--bg3);border:1px solid var(--border);min-height:80px}
|
|
6546
6673
|
.studio-log-entry:last-child{margin-bottom:0}
|
|
6547
6674
|
.studio-log-entry__header{display:flex;align-items:center;gap:8px;margin-bottom:6px}
|
|
6548
6675
|
.studio-log-entry__icon{font-size:15px}
|
|
@@ -6556,7 +6683,7 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
6556
6683
|
.studio-result__body{font-size:13px;color:var(--text);word-wrap:break-word;line-height:1.7}
|
|
6557
6684
|
.studio-example-btn{display:inline-block;padding:5px 12px;border:1px solid var(--border2);border-radius:20px;font-size:10px;color:var(--dim);cursor:pointer;background:none;margin:0 4px 6px 0;transition:all .15s}
|
|
6558
6685
|
.studio-example-btn:hover{border-color:var(--green3);color:var(--green);background:var(--greendim)}
|
|
6559
|
-
.studio-tools-panel{width:220px;flex-shrink:0;border:1px solid var(--border);border-radius:10px;padding:12px;background:var(--bg2);max-height:
|
|
6686
|
+
.studio-tools-panel{width:220px;flex-shrink:0;border:1px solid var(--border);border-radius:10px;padding:12px;background:var(--bg2);max-height:calc(100vh - 120px);overflow-y:auto;position:sticky;top:16px}
|
|
6560
6687
|
.studio-tool-item{display:flex;align-items:flex-start;gap:8px;padding:8px;border-radius:6px;cursor:pointer;transition:background .15s;margin-bottom:4px}
|
|
6561
6688
|
.studio-tool-item:hover{background:var(--bg3);border-radius:6px}
|
|
6562
6689
|
.studio-tool-icon{font-size:16px;flex-shrink:0;margin-top:1px}
|