diff --git a/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json b/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json index 717af1d..73628fe 100644 --- a/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json +++ b/.astra/tests/stress/.astra/cache/259a37934ead3910a8722b82054d46d2ca2057b05c488be1dcf439166ac5a9a1.json @@ -1,5 +1,5 @@ { "result": "Final report with inconsistencies. This should be long enough to pass validation.", - "createdAt": 1778687752353, + "createdAt": 1778688210543, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json b/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json index dfd6dde..267646d 100644 --- a/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json +++ b/.astra/tests/stress/.astra/cache/65775be352df43297b63c7af59c9f4f39d2bc368f77456c37b5eef9a94a66b5c.json @@ -1,5 +1,5 @@ { "result": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.", - "createdAt": 1778687752352, + "createdAt": 1778688210537, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json b/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json index b82653e..26028ad 100644 --- a/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json +++ b/.astra/tests/stress/.astra/cache/6894d26c5b0a55d25d756a473225c7a44d7661af673b24e3f49551a7a2e50280.json @@ -1,5 +1,5 @@ { "result": "Detailed Execution Plan: 1. Research 2. Analyze 3. Write report with high quality.", - "createdAt": 1778687752351, + "createdAt": 1778688210532, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json b/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json index 5fb06c8..1cb6fce 100644 --- a/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json +++ b/.astra/tests/stress/.astra/cache/88cb61499f88ed38165b64bd3e8adc543795e4b427b64540a49c9ab27c7fe213.json @@ -1,5 +1,5 @@ { - "result": "---\nid: stress_conflict_1778687752337\ndate: 2026-05-13T15:55:52.353Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\nFinal report with inconsistencies. This should be long enough to pass validation.\n\nFinal report with inconsistencies. This should be long enough to pass validation.\n\n---\n## 💡 Astra의 선제적 제안 (Proactive Next Actions)\nFinal report with inconsistencies. This should be long enough to pass validation.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `60/100` | ⚠️ Medium |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[PLANNER]** 전략 수립 중... (13ms)\n- **[RESEARCHER]** 핵심 정보 수집 및 분석 중... (2ms)\n- **[WRITER]** 최종 리포트 작성 및 편집 중... (1ms)\n", - "createdAt": 1778687752353, + "result": "---\nid: stress_conflict_1778688210519\ndate: 2026-05-13T16:03:30.549Z\ntype: knowledge_artifact\nstandard: P-Reinforce v3.0\ntags: [automated, connect_ai, brain_sync]\n---\n\n## 📌 Brief Summary\nFinal report with inconsistencies. This should be long enough to pass validation.\n\nFinal report with inconsistencies. This should be long enough to pass validation.\n\n---\n## 💡 Astra의 선제적 제안 (Proactive Next Actions)\nFinal report with inconsistencies. This should be long enough to pass validation.\n---\n## 🛡️ Reliability & Audit Summary\n> [!NOTE]\n> 이 문서는 ConnectAI의 **Intelligent Resilience** 엔진에 의해 검증 및 정제되었습니다.\n\n| Metric | Value | Status |\n| :--- | :--- | :--- |\n| **Conflict Risk** | `60/100` | ⚠️ Medium |\n| **Fallbacks Used** | `0` | ✅ None |\n| **Auto Retries** | `0` | ✅ Stable |\n| **Deduplication** | `0` | Standard |\n| **Processing Time** | `0.0s` | ✅ Fast |\n\n### 🔍 Decision Audit Trail\n- **[PLANNER]** 전략 수립 중... (10ms)\n- **[RESEARCHER]** 핵심 정보 수집 및 분석 중... (3ms)\n- **[WRITER]** 최종 리포트 작성 및 편집 중... (9ms)\n", + "createdAt": 1778688210549, "modelVersion": "unknown" } \ No newline at end of file diff --git a/.astra/tests/stress/.astra/missions/stress_conflict_1778687752337.json b/.astra/tests/stress/.astra/missions/stress_conflict_1778688210519.json similarity index 78% rename from .astra/tests/stress/.astra/missions/stress_conflict_1778687752337.json rename to .astra/tests/stress/.astra/missions/stress_conflict_1778688210519.json index ba380df..98f5c81 100644 --- a/.astra/tests/stress/.astra/missions/stress_conflict_1778687752337.json +++ b/.astra/tests/stress/.astra/missions/stress_conflict_1778688210519.json @@ -1,8 +1,8 @@ { - "missionId": "stress_conflict_1778687752337", + "missionId": "stress_conflict_1778688210519", "status": "completed", - "startTime": "2026-05-13T15:55:52.337Z", - "totalElapsedMs": 16, + "startTime": "2026-05-13T16:03:30.519Z", + "totalElapsedMs": 30, "results": { "planner": "Detailed Execution Plan: 1. Research 2. Analyze 3. Write report with high quality.", "researcher": "[CONFLICT WARNING] 성능이 200% 증가했습니다. vs 그러나 동시에 50% 감소했습니다. 최적화와 성능 저하가 동시에 발견됨.", @@ -16,30 +16,30 @@ { "from": "idle", "to": "planner", - "durationMs": 13, + "durationMs": 10, "message": "전략 수립 중...", - "ts": "2026-05-13T15:55:52.350Z" + "ts": "2026-05-13T16:03:30.529Z" }, { "from": "planner", "to": "researcher", - "durationMs": 2, + "durationMs": 3, "message": "핵심 정보 수집 및 분석 중...", - "ts": "2026-05-13T15:55:52.352Z" + "ts": "2026-05-13T16:03:30.532Z" }, { "from": "researcher", "to": "writer", - "durationMs": 1, + "durationMs": 9, "message": "최종 리포트 작성 및 편집 중...", - "ts": "2026-05-13T15:55:52.353Z" + "ts": "2026-05-13T16:03:30.541Z" }, { "from": "writer", "to": "completed", - "durationMs": 0, + "durationMs": 8, "message": "미션 완료", - "ts": "2026-05-13T15:55:52.353Z" + "ts": "2026-05-13T16:03:30.549Z" } ], "resilienceMetrics": { diff --git a/media/sidebar.css b/media/sidebar.css index 6655e81..9840602 100644 --- a/media/sidebar.css +++ b/media/sidebar.css @@ -333,23 +333,56 @@ /* Agent cards inside the manage overlay. */ .company-agent-list { display: flex; flex-direction: column; gap: 6px; padding: 0; } + /* + * Agent card layout, rebuilt 2026-05-14 to fix overflow: + * - Card itself stacks its rows VERTICALLY (`flex-direction: column`). + * The old version was a horizontal flex container, which caused + * the head row, mix row, and editor row to compete for the same + * horizontal space — content spilled past the overlay's right edge. + * - The head row uses `flex-wrap: wrap` so when the sidebar is too + * narrow to fit emoji + body + 3 controls in one line, the + * controls drop to a second row instead of clipping the tagline. + * - The mix row likewise wraps; slider takes priority and the + * hint/checkbox fall to the next line when there's no room. + * - `overflow: hidden` on the card itself prevents any one-pixel + * overflow from leaking past the rounded border. + */ .company-agent-card { - display: flex; align-items: center; gap: 10px; + display: flex; + flex-direction: column; + gap: 6px; padding: 8px 10px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; list-style: none; + overflow: hidden; } .company-agent-card[data-active="false"] { opacity: 0.55; } .company-agent-card[data-locked="true"] .company-agent-toggle { cursor: not-allowed; opacity: 0.4; } + + .company-agent-head { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; /* controls drop to row 2 when narrow */ + row-gap: 6px; + width: 100%; + min-width: 0; + } + .company-agent-emoji { font-size: 18px; flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 6px; background: var(--bg-secondary); } - .company-agent-body { flex: 1; min-width: 0; line-height: 1.35; } + .company-agent-body { + flex: 1 1 180px; /* prefer ≥180px, shrink down to its content */ + min-width: 0; + line-height: 1.35; + overflow: hidden; + } .company-agent-name { color: var(--text-bright); font-weight: 600; font-size: 12px; display: flex; gap: 6px; align-items: baseline; flex-wrap: wrap; @@ -361,12 +394,16 @@ margin-top: 1px; } .company-agent-controls { - display: flex; align-items: center; gap: 6px; flex-shrink: 0; + display: flex; align-items: center; gap: 6px; + flex-shrink: 0; + margin-left: auto; /* push to the right of the head row */ + max-width: 100%; } .company-agent-toggle { background: transparent; border: 1px solid var(--border); color: var(--text-dim); font-size: 10px; font-weight: 600; padding: 3px 8px; border-radius: 999px; cursor: pointer; + flex-shrink: 0; } .company-agent-card[data-active="true"] .company-agent-toggle { border-color: var(--accent); color: var(--accent); @@ -375,7 +412,8 @@ background: var(--input-bg); border: 1px solid var(--border); color: var(--text-primary); font-size: 10px; padding: 3px 6px; border-radius: 6px; - max-width: 150px; min-width: 0; + width: 120px; min-width: 0; /* fixed width keeps row predictable */ + max-width: 100%; cursor: pointer; } .company-agent-model option { color: var(--text-primary); background: var(--bg); } @@ -391,25 +429,37 @@ background: var(--accent-glow); } - /* Per-agent Knowledge Mix slider row — sits between the controls - row and the (collapsed) prompt editor. Indent matches the - prompt-editor indent (38px) so the emoji stays as the visual - "ruler" for everything that follows. */ + /* Per-agent Knowledge Mix slider. Wraps so the slider always has + breathing room — hint + checkbox flow to next line when needed. */ .company-agent-mix-row { display: flex; align-items: center; gap: 8px; - margin: 6px 0 0 38px; + flex-wrap: wrap; + row-gap: 4px; + margin: 0; /* gap on parent handles the spacing */ font-size: 10px; color: var(--text-dim); } .company-agent-mix-label { flex-shrink: 0; } .company-agent-mix-slider { - flex: 1; min-width: 0; + flex: 1 1 120px; /* slider is the row's hero */ + min-width: 80px; accent-color: var(--accent); cursor: pointer; } .company-agent-mix-slider:disabled { opacity: 0.5; cursor: not-allowed; } .company-agent-mix-hint { flex-shrink: 0; font-size: 9.5px; color: var(--text-dim); - min-width: 165px; text-align: right; + white-space: nowrap; + } + .company-agent-mix-source { + font-size: 9px; color: var(--text-dim); + padding: 1px 6px; + border: 1px solid var(--border); + border-radius: 8px; + text-transform: uppercase; letter-spacing: 0.04em; + } + .company-agent-mix-source.override { + color: var(--accent); border-color: var(--accent); + background: var(--accent-glow); } .company-agent-mix-cbwrap { display: inline-flex; align-items: center; gap: 3px; @@ -423,7 +473,7 @@ Reset / Save / Cancel — empty save clears that field's override. */ .company-agent-editor { display: none; - margin: 6px 0 0 38px; /* indent under the emoji */ + margin: 0; padding: 8px; background: var(--bg-secondary); border: 1px dashed var(--border); diff --git a/media/sidebar.js b/media/sidebar.js index cace912..7775ae8 100644 --- a/media/sidebar.js +++ b/media/sidebar.js @@ -1547,11 +1547,10 @@ li.dataset.agentId = a.id; // ── Row 1: emoji + name/tagline + controls ── + // CSS handles layout via `.company-agent-head` (flex-wrap, + // gap, etc.) so we don't repeat inline styles here. const row = document.createElement('div'); - row.style.display = 'flex'; - row.style.alignItems = 'center'; - row.style.gap = '10px'; - row.style.width = '100%'; + row.className = 'company-agent-head'; const emoji = document.createElement('span'); emoji.className = 'company-agent-emoji'; @@ -1650,24 +1649,37 @@ row.className = 'company-agent-mix-row'; const usingOverride = a.knowledgeMixOverride !== null && a.knowledgeMixOverride !== undefined; const effective = a.effectiveKnowledgeMixWeight; + + // Tight label — "Mix" alone keeps the row narrow. The 🎚 emoji + // signals what it controls without needing the full word. const label = document.createElement('span'); label.className = 'company-agent-mix-label'; - label.textContent = '🎚 Knowledge Mix'; + label.textContent = '🎚 Mix'; + + // Source badge ("GLOBAL" / "OVERRIDE") visually communicates + // *which knob* the value is coming from — clearer than packing + // it into the hint text. + const sourceBadge = document.createElement('span'); + sourceBadge.className = 'company-agent-mix-source' + (usingOverride ? ' override' : ''); + sourceBadge.textContent = usingOverride ? 'override' : 'global'; + const slider = document.createElement('input'); slider.type = 'range'; slider.min = '0'; slider.max = '100'; slider.step = '5'; slider.value = String(effective); slider.disabled = !usingOverride; slider.className = 'company-agent-mix-slider'; + + // Compact hint: "Brain 55%" only — the model% is just 100 - + // brain%, so showing both was redundant noise. Stays narrow + // enough not to push the checkbox off the row. const hint = document.createElement('span'); hint.className = 'company-agent-mix-hint'; const renderHint = () => { const w = parseInt(slider.value, 10) || 50; - const tag = usingOverride - ? `override · Model ${100 - w}% / Brain ${w}%` - : `global · Model ${100 - effective}% / Brain ${effective}%`; - hint.textContent = tag; + hint.textContent = `Brain ${w}%`; }; + const cb = document.createElement('input'); cb.type = 'checkbox'; cb.checked = !usingOverride; cb.className = 'company-agent-mix-cb'; @@ -1677,6 +1689,9 @@ // Reset to global. slider.disabled = true; slider.value = String(globalWeight ?? 50); + sourceBadge.textContent = 'global'; + sourceBadge.classList.remove('override'); + renderHint(); vscode.postMessage({ type: 'setCompanyAgentKnowledgeMix', agentId: a.id, value: null, @@ -1684,6 +1699,8 @@ } else { // Take ownership at the current displayed value. slider.disabled = false; + sourceBadge.textContent = 'override'; + sourceBadge.classList.add('override'); const w = parseInt(slider.value, 10) || 50; vscode.postMessage({ type: 'setCompanyAgentKnowledgeMix', @@ -1704,8 +1721,9 @@ const cbWrap = document.createElement('label'); cbWrap.className = 'company-agent-mix-cbwrap'; cbWrap.appendChild(cb); - cbWrap.appendChild(document.createTextNode(' use global')); + cbWrap.appendChild(document.createTextNode(' global')); row.appendChild(label); + row.appendChild(sourceBadge); row.appendChild(slider); row.appendChild(hint); row.appendChild(cbWrap);