451 lines
26 KiB
HTML
451 lines
26 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
<title>Astra</title>
|
|
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
<link rel="stylesheet" href="__STYLES_URI__">
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<div class="header-top">
|
|
<div class="brand"><div class="logo">✦</div> Astra</div>
|
|
<div class="header-actions">
|
|
<button class="icon-btn" id="newChatBtn" data-tooltip="New Chat">New</button>
|
|
<button class="icon-btn toggle-chip active" id="brainTraceBtn" data-tooltip="Second Brain Trace Mode">Trace</button>
|
|
<button class="icon-btn toggle-chip" id="internetBtn" data-tooltip="Internet Access">Web</button>
|
|
<!--
|
|
Corp toggle — replaces the old pill-shaped chip that lived
|
|
in the records-line. Same rounded-rectangle style as the
|
|
other header buttons. Clicking toggles 1인 기업 모드 on/off;
|
|
the adjacent ▾ opens the manage overlay (agents · models ·
|
|
prompt edits · Knowledge Mix sliders).
|
|
-->
|
|
<button class="icon-btn toggle-chip" id="companyChip" data-tooltip="1인 기업 모드 토글">Corp</button>
|
|
<button class="icon-btn" id="companyManageBtn" data-tooltip="회사 관리 (에이전트·모델·prompt·Knowledge Mix)">▾</button>
|
|
<div class="hdr-dropdown" data-dd>
|
|
<button class="icon-btn" id="toolsMenuBtn" data-dd-trigger data-tooltip="Tools">Tools ▾</button>
|
|
<div class="hdr-menu" id="toolsMenu" data-dd-menu>
|
|
<div class="hdr-menu-label">Tools</div>
|
|
<button class="hdr-menu-item toggle-item" id="brainTraceDebugBtn" data-tooltip="Second Brain Debug JSON">Debug Trace JSON</button>
|
|
<button class="hdr-menu-item" id="saveWikiRawBtn" data-tooltip="Save Wiki Raw">Save Wiki Raw</button>
|
|
<button class="hdr-menu-item" id="brainBtn" data-tooltip="Sync Knowledge (commit + push)">Sync Knowledge</button>
|
|
</div>
|
|
</div>
|
|
<button class="icon-btn" id="historyBtn" data-tooltip="View History">History</button>
|
|
<button class="icon-btn" id="settingsBtn" data-tooltip="Settings">Set</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="readyBar" class="ready-bar" title="현재 준비 상태 — 엔진 / 모델 / 컨텍스트 창 / 메모리">
|
|
<span class="rb-dot" id="rbDot"></span>
|
|
<span class="rb-content" id="rbContent">준비 상태 확인 중…</span>
|
|
<span id="statusDot" class="status-dot" hidden></span><span id="engineStatusText" hidden></span>
|
|
</div>
|
|
|
|
<div class="context-bar">
|
|
<div class="context-summary" id="contextSummary">
|
|
<span class="cb-seg"><span class="cb-key">Brain</span> <span id="ctxBrainName" class="cb-val">—</span></span>
|
|
<span class="cb-sep">·</span>
|
|
<span class="cb-seg"><span class="cb-key">Agent</span> <span id="ctxAgentName" class="cb-val">—</span></span>
|
|
<span class="cb-sep">·</span>
|
|
<span class="cb-seg"><span class="cb-key">Project</span> <span id="ctxProjectName" class="cb-val">—</span></span>
|
|
</div>
|
|
<div class="hdr-dropdown context-edit-dd" data-dd>
|
|
<button class="icon-btn" id="contextEditBtn" data-dd-trigger data-tooltip="Model / Brain / Agent / Knowledge Map / Project">Edit ▾</button>
|
|
<div class="hdr-menu hdr-menu-wide" id="contextEditMenu" data-dd-menu>
|
|
<div class="hdr-menu-label">Model</div>
|
|
<div class="select-wrap"><select id="modelSel" title="Select Model"></select></div>
|
|
|
|
<div class="hdr-menu-label">
|
|
Knowledge Mix
|
|
<span class="hdr-menu-hint" id="knowledgeMixHint">Model 50% · Brain 50%</span>
|
|
</div>
|
|
<div class="knowledge-mix-control" title="Slide left for more model knowledge, right for more Second Brain reliance">
|
|
<span class="km-end-label">Model</span>
|
|
<input type="range" id="knowledgeMixSlider" min="0" max="100" step="5" value="50" class="km-slider">
|
|
<span class="km-end-label">Brain</span>
|
|
</div>
|
|
|
|
<div class="hdr-menu-label">Brain</div>
|
|
<div class="control-row">
|
|
<div class="select-wrap"><select id="brainSel" title="Select Brain"></select></div>
|
|
<div class="tool-group" aria-label="Brain actions">
|
|
<button class="icon-btn" id="addBrainBtn" data-tooltip="Add Brain">Add</button>
|
|
<button class="icon-btn" id="editBrainBtn" data-tooltip="Edit Brain">Edit</button>
|
|
<button class="icon-btn" id="deleteBrainBtn" data-tooltip="Delete Brain">Del</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="hdr-menu-label">Agent</div>
|
|
<div class="control-row">
|
|
<div class="select-wrap"><select id="agentSel" title="Select Agentic Skill"></select></div>
|
|
<div class="tool-group" aria-label="Agent actions">
|
|
<button class="icon-btn" id="addAgentBtn" data-tooltip="Create Agent">Add</button>
|
|
<button class="icon-btn" id="editAgentBtn" data-tooltip="Edit Agent Skill">Edit</button>
|
|
<button class="icon-btn" id="deleteAgentBtn" data-tooltip="Delete Agent Skill">Del</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="hdr-menu-label">Agent ↔ Knowledge</div>
|
|
<div class="control-row">
|
|
<div class="select-wrap"><select id="knowledgeScopeSel" title="Knowledge folders mapped to this agent"></select></div>
|
|
<div class="tool-group" aria-label="Knowledge map actions">
|
|
<button class="icon-btn" id="editKnowledgeMapBtn" data-tooltip="Edit Agent ↔ Knowledge Map">Map</button>
|
|
<button class="icon-btn" id="reloadKnowledgeMapBtn" data-tooltip="Reload Knowledge Map">Rld</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="hdr-menu-label">Project (Chronicle)</div>
|
|
<div class="control-row">
|
|
<div class="select-wrap"><select id="designerSel" title="Select Designer Project"></select></div>
|
|
<div class="tool-group" aria-label="Designer actions">
|
|
<button class="icon-btn" id="addDesignerBtn" data-tooltip="Create Designer Project">Add</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="records-line">
|
|
<div class="rl-summary">
|
|
<span class="status-dot ready"></span>
|
|
<span id="chronicleAutoStatus" title="Project records are saved automatically after meaningful project turns.">Auto Records</span>
|
|
<span class="rl-latest" id="recordsLatest"></span>
|
|
</div>
|
|
<!-- (Removed) Corp chip moved to the header toolbar above —
|
|
see #companyChip / #companyManageBtn alongside New/Trace/Web. -->
|
|
<div class="hdr-dropdown" data-dd>
|
|
<button class="icon-btn" id="recordsMenuBtn" data-dd-trigger data-tooltip="Chronicle records">Records ▾</button>
|
|
<div class="hdr-menu hdr-menu-wide" id="recordsMenu" data-dd-menu>
|
|
<div class="hdr-menu-label">Chronicle Records</div>
|
|
<div class="select-wrap"><select id="chronicleRecordSel" title="Select Chronicle Record"></select></div>
|
|
<button class="hdr-menu-item" id="openChronicleRecordBtn" data-tooltip="Open Selected Record">Open Selected Record</button>
|
|
<button class="hdr-menu-item" id="refreshChronicleRecordsBtn" data-tooltip="Refresh Records">Refresh Records</button>
|
|
<button class="hdr-menu-item" id="openDesignerBtn" data-tooltip="Open Record Folder">Open Record Folder</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!--
|
|
Company manage overlay. Uses the same overlay framework as the agent
|
|
knowledge map modal (`.history-overlay` / `.visible`) so styling and
|
|
keyboard dismissal stay consistent.
|
|
-->
|
|
<div id="companyOverlay" class="history-overlay">
|
|
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:14px;">
|
|
<div>
|
|
<h2 style="color:var(--text-bright); margin:0;">🏢 1인 기업 모드</h2>
|
|
<p style="margin:4px 0 0; font-size:11px; color:var(--text-dim);">
|
|
CEO가 사용자의 요청을 분석하고 활성화된 specialist에게 순차 dispatch합니다.
|
|
동시에 메모리에 올라가는 모델은 항상 1개입니다.
|
|
</p>
|
|
</div>
|
|
<button class="icon-btn" id="closeCompanyOverlayBtn">✕</button>
|
|
</div>
|
|
|
|
<div class="map-section">
|
|
<div class="map-section-head">
|
|
<div>
|
|
<div class="map-section-title">회사 정보</div>
|
|
<div class="map-section-hint">CEO와 보고서에 사용되는 회사명. 한국어/영어 모두 가능.</div>
|
|
</div>
|
|
</div>
|
|
<div class="control-row" style="margin-top:8px;">
|
|
<input id="companyNameInput" type="text" class="company-name-input" placeholder="회사명 (예: My Company)" />
|
|
<button class="secondary-btn" id="saveCompanyNameBtn">저장</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="map-section">
|
|
<div class="map-section-head">
|
|
<div>
|
|
<div class="map-section-title">활성 에이전트 + 모델</div>
|
|
<div class="map-section-hint">CEO는 항상 활성. 각 에이전트별로 모델을 따로 지정할 수 있습니다 — 다른 모델을 쓸 때만 LM Studio가 swap합니다.</div>
|
|
</div>
|
|
<div class="map-btn-group">
|
|
<button class="secondary-btn" id="addCompanyAgentBtn" title="새 사용자 에이전트 추가">+ Agent</button>
|
|
</div>
|
|
</div>
|
|
<ul id="companyAgentList" class="map-list company-agent-list"></ul>
|
|
</div>
|
|
|
|
<!-- Inline form for adding a new custom agent. Hidden by default; the
|
|
"+ Agent" button toggles `data-open` to show it. Kept in-overlay
|
|
(no separate modal) so the user can see existing agents while
|
|
editing — easier to spot id collisions. -->
|
|
<div id="addCompanyAgentForm" class="map-section company-agent-add-form" data-open="false">
|
|
<div class="map-section-title" style="margin-bottom:8px;">새 에이전트 추가</div>
|
|
<div class="company-agent-add-grid">
|
|
<label class="field-label">ID (소문자/숫자/-/_, 예: marketer)
|
|
<input type="text" id="newAgentId" placeholder="marketer" />
|
|
</label>
|
|
<label class="field-label">이름
|
|
<input type="text" id="newAgentName" placeholder="현수" />
|
|
</label>
|
|
<label class="field-label">역할
|
|
<input type="text" id="newAgentRole" placeholder="Marketing Lead" />
|
|
</label>
|
|
<label class="field-label">이모지
|
|
<input type="text" id="newAgentEmoji" placeholder="📣" maxlength="4" />
|
|
</label>
|
|
<label class="field-label">색상 (#hex)
|
|
<input type="text" id="newAgentColor" placeholder="#3B82F6" />
|
|
</label>
|
|
<label class="field-label" style="grid-column:1/-1;">직군 (담당 역할 분류)
|
|
<select id="newAgentRoleCategory"></select>
|
|
</label>
|
|
<label class="field-label" style="grid-column:1/-1;">한 줄 태그라인
|
|
<input type="text" id="newAgentTagline" placeholder="브랜드 메시지·캠페인을 설계합니다" />
|
|
</label>
|
|
<label class="field-label" style="grid-column:1/-1;">전문 분야 (CEO가 매칭에 사용)
|
|
<textarea id="newAgentSpecialty" rows="2" placeholder="캠페인 기획, 메시지 설계, 채널 분석"></textarea>
|
|
</label>
|
|
<label class="field-label" style="grid-column:1/-1;">페르소나 (선택)
|
|
<textarea id="newAgentPersona" rows="2" placeholder="데이터 기반·간결한 톤. 가설 검증 사이클을 좋아함."></textarea>
|
|
</label>
|
|
</div>
|
|
<div class="editor-actions" style="margin-top:10px;">
|
|
<button id="cancelAddAgentBtn">Cancel</button>
|
|
<button class="primary" id="saveAddAgentBtn">추가</button>
|
|
</div>
|
|
<div id="addAgentError" class="map-status" style="color:var(--error); margin-top:6px;"></div>
|
|
</div>
|
|
|
|
<!-- Work Pipeline editor. The active pipeline (if any) drives the
|
|
dispatcher instead of the CEO planner. Empty list / "기본 (CEO
|
|
자유 분배)" → legacy planner behaviour. -->
|
|
<div class="map-section">
|
|
<div class="map-section-head">
|
|
<div>
|
|
<div class="map-section-title">워크 파이프라인</div>
|
|
<div class="map-section-hint">CEO 자유 분배 대신 사용자가 정한 stage 순서대로 dispatch합니다. loop-back 정규식이 매칭되면 이전 stage로 되돌아갑니다 (최대 maxIterations 회).</div>
|
|
</div>
|
|
<div class="map-btn-group">
|
|
<button class="secondary-btn" id="addCompanyPipelineBtn" title="새 파이프라인 추가">+ Pipeline</button>
|
|
</div>
|
|
</div>
|
|
<div class="control-row" style="margin-top:8px; gap:8px; align-items:center;">
|
|
<label style="font-size:10px; color:var(--text-dim);">활성:</label>
|
|
<select id="activePipelineSel" style="flex:1; padding:4px 8px; background:var(--bg); color:var(--text-primary); border:1px solid var(--border); border-radius:6px; font-size:11px;">
|
|
<option value="">기본 (CEO 자유 분배)</option>
|
|
</select>
|
|
</div>
|
|
<ul id="companyPipelineList" class="map-list" style="margin-top:8px;"></ul>
|
|
</div>
|
|
|
|
<!-- Pipeline editor: hidden until "+ Pipeline" or "Edit" is clicked.
|
|
MVP is a JSON textarea so we don't have to ship a stage-list
|
|
reorder widget yet. -->
|
|
<div id="pipelineEditForm" class="map-section company-agent-add-form" data-open="false">
|
|
<div class="map-section-title" style="margin-bottom:8px;">파이프라인 편집</div>
|
|
<div class="company-agent-add-grid">
|
|
<label class="field-label">ID
|
|
<input type="text" id="pipelineEditId" placeholder="product-dev-v1" />
|
|
</label>
|
|
<label class="field-label">이름
|
|
<input type="text" id="pipelineEditName" placeholder="제품 개발 v1" />
|
|
</label>
|
|
<label class="field-label" style="grid-column:1/-1;">Stages (JSON 배열)
|
|
<textarea id="pipelineEditStages" rows="14" style="font-family:monospace; font-size:11px;"></textarea>
|
|
</label>
|
|
</div>
|
|
<div class="map-section-hint" style="margin-top:6px;">
|
|
예시:
|
|
<code style="font-size:10px;">[{"id":"plan","label":"기획","agentId":"writer","instructionTemplate":"{{userPrompt}} 에 대한 기획서 작성"},{"id":"dev","label":"개발","agentId":"developer","instructionTemplate":"다음 기획대로 구현: {{stage.plan}}","loopBackPattern":"버그|오류|fail","loopBackTo":"plan","maxIterations":3}]</code>
|
|
</div>
|
|
<div class="editor-actions" style="margin-top:10px;">
|
|
<button id="cancelPipelineEditBtn">Cancel</button>
|
|
<button class="primary" id="savePipelineEditBtn">저장</button>
|
|
</div>
|
|
<div id="pipelineEditError" class="map-status" style="color:var(--error); margin-top:6px;"></div>
|
|
</div>
|
|
|
|
<div class="map-footer">
|
|
<button class="secondary-btn" id="openCompanySessionsBtn" title="이번 회사가 만든 세션 폴더 열기">세션 폴더 열기</button>
|
|
<div style="flex:1"></div>
|
|
<button class="send-btn" id="closeCompanyOverlayBtn2">닫기</button>
|
|
</div>
|
|
<div id="companyStatus" class="map-status"></div>
|
|
</div>
|
|
|
|
<div id="historyOverlay" class="history-overlay">
|
|
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">
|
|
<h2 style="color:var(--text-bright);">Chat History</h2>
|
|
<button class="icon-btn" id="closeHistoryBtn">✕</button>
|
|
</div>
|
|
<div id="historyList" style="flex:1; overflow-y:auto;"></div>
|
|
</div>
|
|
|
|
<div id="agentMapOverlay" class="history-overlay">
|
|
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:14px;">
|
|
<div>
|
|
<h2 style="color:var(--text-bright); margin:0;">Agent Mapping</h2>
|
|
<p style="margin:4px 0 0; font-size:11px; color:var(--text-dim);">
|
|
선택한 에이전트에 <strong>지식 폴더</strong>와 <strong>외부 스킬 폴더/파일</strong>을 연결합니다.
|
|
</p>
|
|
</div>
|
|
<button class="icon-btn" id="closeAgentMapBtn">✕</button>
|
|
</div>
|
|
|
|
<div class="map-agent-row">
|
|
<div class="field-label">Agent</div>
|
|
<div id="agentMapAgentName" class="map-agent-name">(선택된 에이전트가 없습니다)</div>
|
|
</div>
|
|
|
|
<div class="map-section">
|
|
<div class="map-section-head">
|
|
<div>
|
|
<div class="map-section-title">🤖 Model for this agent</div>
|
|
<div class="map-section-hint">이 에이전트를 선택했을 때 사용할 모델을 지정합니다. <strong>Use current model</strong>을 선택하면 상단에서 고른 기본 모델을 그대로 사용합니다.</div>
|
|
</div>
|
|
</div>
|
|
<div class="select-wrap" style="margin-top:8px;">
|
|
<select id="agentMapModelSel" title="Model override for this agent"></select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="map-section">
|
|
<div class="map-section-head">
|
|
<div>
|
|
<div class="map-section-title">🎚 Knowledge Mix for this agent</div>
|
|
<div class="map-section-hint">에이전트별 의존도. <strong>Use global setting</strong>을 켜두면 상단 슬라이더 값을 그대로 따릅니다.</div>
|
|
</div>
|
|
</div>
|
|
<label class="map-checkbox-row" style="margin-top:8px;">
|
|
<input type="checkbox" id="agentMapMixUseGlobal" checked>
|
|
<span>Use global setting</span>
|
|
</label>
|
|
<div class="knowledge-mix-control map-mix-control" style="margin-top:6px;">
|
|
<span class="km-end-label">Model</span>
|
|
<input type="range" id="agentMapMixSlider" min="0" max="100" step="5" value="50" class="km-slider" disabled>
|
|
<span class="km-end-label">Brain</span>
|
|
</div>
|
|
<div class="map-section-hint" id="agentMapMixHint" style="margin-top:4px;">Model 50% · Brain 50%</div>
|
|
</div>
|
|
|
|
<div class="map-section">
|
|
<div class="map-section-head">
|
|
<div>
|
|
<div class="map-section-title">📚 Knowledge Folders</div>
|
|
<div class="map-section-hint">Brain 안에서 검색(RAG)에 사용할 폴더입니다. 폴더가 Brain 외부면 자동으로 제외됩니다.</div>
|
|
</div>
|
|
<button class="secondary-btn" id="addKnowledgeFolderBtn">+ 폴더 추가</button>
|
|
</div>
|
|
<ul id="knowledgeFolderList" class="map-list"></ul>
|
|
</div>
|
|
|
|
<div class="map-section">
|
|
<div class="map-section-head">
|
|
<div>
|
|
<div class="map-section-title">🛠 External Skills</div>
|
|
<div class="map-section-hint">.md 스킬 파일이 들어 있는 폴더 또는 개별 .md 파일을 연결하세요. 채팅 시 항상 함께 로드됩니다.</div>
|
|
</div>
|
|
<div class="map-btn-group">
|
|
<button class="secondary-btn" id="addSkillFolderBtn">+ 폴더 추가</button>
|
|
<button class="secondary-btn" id="addSkillFileBtn">+ 파일 추가</button>
|
|
</div>
|
|
</div>
|
|
<ul id="skillFolderList" class="map-list"></ul>
|
|
</div>
|
|
|
|
<div class="map-footer">
|
|
<button class="secondary-btn" id="editAgentMapJsonBtn" title="고급 사용자용: JSON으로 직접 편집">JSON 편집</button>
|
|
<div style="flex:1"></div>
|
|
<button class="secondary-btn" id="cancelAgentMapBtn">취소</button>
|
|
<button class="send-btn" id="saveAgentMapBtn">저장</button>
|
|
</div>
|
|
|
|
<div id="agentMapStatus" class="map-status"></div>
|
|
</div>
|
|
|
|
<div class="thinking-bar" id="thinkingBar"></div>
|
|
|
|
<div id="stepper" class="stepper-container">
|
|
<div class="steps">
|
|
<div class="step" id="step-analyze"><div class="step-dot"></div><div class="step-label">Analyze</div></div>
|
|
<div class="step" id="step-plan"><div class="step-dot"></div><div class="step-label">Plan</div></div>
|
|
<div class="step" id="step-execute"><div class="step-dot"></div><div class="step-label">Execute</div></div>
|
|
<div class="step" id="step-verify"><div class="step-dot"></div><div class="step-label">Verify</div></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="chat" id="chat">
|
|
<div class="welcome">
|
|
<div class="welcome-logo">✦</div>
|
|
<div class="welcome-title">Welcome to Astra</div>
|
|
<p>Your premium local AI assistant.<br>Ready to analyze projects and build reports.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="input-wrap">
|
|
<!--
|
|
Project Architecture chip. Hidden by default; the JS handler flips
|
|
`data-active` when the extension host sends an `architectureStatus`
|
|
message with active=true. Click "Open" / "Refresh" / "Detach" to
|
|
route back to the chatHandlers cases.
|
|
-->
|
|
<!--
|
|
Three-state chip:
|
|
data-state="hidden" → completely collapsed
|
|
data-state="active" → full info + Open / Refresh / Detach
|
|
data-state="inactive" → project name + Attach (or Re-attach) only
|
|
JS switches the state attribute on every `architectureStatus`
|
|
event so the user always has a one-click path back into project
|
|
mode after a Detach.
|
|
-->
|
|
<div id="archChip" class="arch-chip" data-state="hidden">
|
|
<span class="arch-chip-icon">📋</span>
|
|
<div class="arch-chip-info">
|
|
<div class="arch-chip-title" id="archChipTitle">—</div>
|
|
<div class="arch-chip-meta" id="archChipMeta">—</div>
|
|
</div>
|
|
<div class="arch-chip-actions" id="archChipActions">
|
|
<!-- active state buttons -->
|
|
<button class="arch-chip-btn arch-chip-active-only" id="archOpenBtn" title="Architecture 문서 열기">Open</button>
|
|
<button class="arch-chip-btn arch-chip-active-only" id="archRefreshBtn" title="지금 다시 스캔">Refresh</button>
|
|
<button class="arch-chip-btn arch-chip-active-only" id="archDetachBtn" title="자동 첨부 끄기">Detach</button>
|
|
<!-- inactive state button -->
|
|
<button class="arch-chip-btn arch-chip-inactive-only" id="archAttachBtn" title="이 프로젝트에 architecture 자동 첨부 켜기">Attach</button>
|
|
</div>
|
|
</div>
|
|
<div id="agentConfigPanel" class="panel">
|
|
<div class="field-label">Agent Persona/Instructions</div>
|
|
<textarea id="agentPrompt" rows="5" placeholder="Agent Persona & Instructions..."></textarea>
|
|
|
|
<div class="field-label">Negative Prompt (Strict Rules)</div>
|
|
<textarea id="negativePrompt" rows="2" placeholder="What NOT to do..."></textarea>
|
|
|
|
<button id="updateAgentBtn" class="secondary-btn">Update Agent Skill</button>
|
|
</div>
|
|
<div class="input-box">
|
|
<div id="attachPreview" class="attachment-preview"></div>
|
|
<textarea id="input" rows="1" placeholder="Ask Astra..."></textarea>
|
|
<div class="input-footer">
|
|
<div class="footer-left">
|
|
<button class="icon-btn" id="attachBtn" title="Attach Files">📎</button>
|
|
<span class="model-pill" title="Switch model for this conversation">
|
|
<span class="model-prefix">Model:</span>
|
|
<select id="modelInlineSel" class="model-inline-sel" title="Switch model"></select>
|
|
</span>
|
|
<span id="statusLabel" class="status-label"></span>
|
|
<span id="ctxBadge" class="ctx-badge" title="직전 요청에 실제로 들어간 컨텍스트 추정치"></span>
|
|
</div>
|
|
<div class="footer-right">
|
|
<button id="cancelBtn" class="cancel-btn" title="Clear draft" style="display:none;">✕ Clear</button>
|
|
<button id="stopBtn" class="stop-btn" title="Stop generation" style="display:none;">■ Stop</button>
|
|
<button id="sendBtn" class="send-btn">Send</button>
|
|
</div>
|
|
</div>
|
|
<div id="toastNotif" class="toast-notif"></div>
|
|
</div>
|
|
</div>
|
|
<input type="file" id="fileInput" multiple hidden accept="image/*,.txt,.md,.pdf,.csv,.json,.js,.ts,.py,.java,.rs,.go">
|
|
</div>
|
|
|
|
<script src="__SCRIPT_URI__"></script>
|
|
</body>
|
|
</html>
|