515 lines
31 KiB
HTML
515 lines
31 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>GenericAgent</title>
|
||
<link rel="stylesheet" href="styles.css?v=72">
|
||
<!-- KaTeX: LaTeX 公式渲染 -->
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" crossorigin="anonymous">
|
||
<!-- highlight.js: 代码高亮 -->
|
||
<link id="hljs-theme" rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github.min.css" crossorigin="anonymous">
|
||
<!-- DEV 脚手架(标注模式):删本行 + 下方 annot.js 一行即可彻底移除 -->
|
||
<link rel="stylesheet" href="annot.css">
|
||
<script>
|
||
(function(){
|
||
var t=localStorage.getItem('ga_theme'); if(t) document.documentElement.dataset.theme=t;
|
||
var l=localStorage.getItem('ga_lang'); if(l==='en') document.documentElement.lang='en';
|
||
var legacy=localStorage.getItem('ga_style');
|
||
var app=localStorage.getItem('ga_appearance');
|
||
if(!app&&legacy){
|
||
if(legacy==='dark') app='dark';
|
||
else{ app='light'; if(legacy==='classic') localStorage.setItem('ga_plain','1'); }
|
||
localStorage.setItem('ga_appearance',app);
|
||
localStorage.removeItem('ga_style');
|
||
}
|
||
app=app||'light';
|
||
document.documentElement.dataset.appearance=app;
|
||
if(app==='light'&&localStorage.getItem('ga_plain')==='1') document.documentElement.dataset.plain='1';
|
||
var LEGACY_FONT={sm:12,md:14,lg:16};
|
||
function chatFontPx(v){
|
||
if(v&&LEGACY_FONT[v]) return LEGACY_FONT[v];
|
||
var n=parseInt(v,10); if(!isNaN(n)&&n>=10&&n<=20) return n;
|
||
return 14;
|
||
}
|
||
var fs=localStorage.getItem('ga_font_size');
|
||
var cfp=chatFontPx(fs);
|
||
document.documentElement.dataset.chatFont=String(cfp);
|
||
document.documentElement.style.setProperty('--chat-font',cfp+'px');
|
||
var hljs=document.getElementById('hljs-theme');
|
||
if(hljs&&app==='dark') hljs.href='https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/github-dark.min.css';
|
||
try{ var sraw=localStorage.getItem('ga_sessions'); if(sraw && JSON.parse(sraw).length) document.documentElement.dataset.bootHasSessions='1'; }catch(_){}
|
||
})();
|
||
</script>
|
||
</head>
|
||
<body>
|
||
|
||
<div id="app">
|
||
|
||
<div class="body">
|
||
|
||
<!-- ① 左侧边栏 -->
|
||
<aside class="sidebar">
|
||
<div class="brand">
|
||
<div class="brand-logo">GA</div>
|
||
<div class="brand-text">
|
||
<div class="brand-name">GenericAgent</div>
|
||
<div class="brand-sub" data-i18n="brand.sub"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<nav class="nav" id="nav">
|
||
<a class="nav-item active" data-page="chat">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.4 8.4 0 0 1-8.5 8.5 8.4 8.4 0 0 1-3.8-.9L3 21l1.9-5.7A8.4 8.4 0 0 1 3.5 11.5 8.5 8.5 0 0 1 12 3a8.5 8.5 0 0 1 9 8.5z"/></svg>
|
||
<span data-i18n="nav.chat"></span>
|
||
</a>
|
||
<a class="nav-item" data-page="channels">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 3 21 3 21 8"/><line x1="4" y1="20" x2="21" y2="3"/><polyline points="21 16 21 21 16 21"/><line x1="15" y1="15" x2="21" y2="21"/><line x1="4" y1="4" x2="9" y2="9"/></svg>
|
||
<span data-i18n="nav.channels"></span>
|
||
</a>
|
||
<a class="nav-item" data-page="status">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="20" x2="6" y2="10"/><line x1="12" y1="20" x2="12" y2="4"/><line x1="18" y1="20" x2="18" y2="14"/></svg>
|
||
<span data-i18n="nav.status"></span>
|
||
</a>
|
||
<a class="nav-item" data-page="collab">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
|
||
<span data-i18n="nav.collab"></span>
|
||
<span id="collab-badge" class="collab-nav-badge" hidden></span>
|
||
</a>
|
||
<a class="nav-item" data-page="token">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v10M9.5 9.6c0-1 1.1-1.7 2.5-1.7s2.5.7 2.5 1.7-1.1 1.5-2.5 1.5-2.5.7-2.5 1.7 1.1 1.8 2.5 1.8 2.5-.7 2.5-1.7"/></svg>
|
||
<span data-i18n="nav.token"></span>
|
||
</a>
|
||
</nav>
|
||
|
||
<div class="sidebar-foot">
|
||
<a class="foot-row" id="settings-btn">
|
||
<span class="fr-l">
|
||
<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg>
|
||
<span data-i18n="foot.settings"></span>
|
||
</span>
|
||
<svg class="chev" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
|
||
</a>
|
||
<div class="foot-ver" data-i18n="foot.ver"></div>
|
||
</div>
|
||
</aside>
|
||
<div class="sb-resize" id="sb-resize"></div>
|
||
<button class="sb-toggle" id="sb-toggle" aria-label="toggle sidebar">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg>
|
||
</button>
|
||
|
||
<!-- 中间主区 -->
|
||
<main class="main">
|
||
|
||
<div class="topbar">
|
||
<div class="tb-left">
|
||
<button class="run-state" id="run-toggle"
|
||
>
|
||
<i class="dot"></i> <span class="rs-label"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div id="pages">
|
||
|
||
<!-- 聊天 -->
|
||
<section class="page active" data-page="chat"
|
||
>
|
||
<div class="msg-area">
|
||
<div class="chat-start">
|
||
<div class="feature-head">
|
||
<div class="page-title" data-i18n="chat.startTitle"></div>
|
||
<div class="page-sub" data-i18n="chat.startSub"></div>
|
||
</div>
|
||
<div class="feature-grid"></div>
|
||
</div>
|
||
<div class="msg-loading" id="msg-loading" hidden aria-live="polite">
|
||
<span class="ga-spin" aria-hidden="true"></span>
|
||
<span data-i18n="chat.interrupting"></span>
|
||
</div>
|
||
</div>
|
||
<div class="composer">
|
||
<div class="composer-top">
|
||
<button class="ic-btn" id="upload-btn" data-i18n-title="upload.button" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05 12 20.5a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>
|
||
</button>
|
||
<button class="ic-btn" id="preset-btn">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 10 14 9 22 21 10 14 10 13 2"/></svg>
|
||
</button>
|
||
</div>
|
||
<textarea class="input" data-i18n-ph="composer.placeholder" placeholder=""></textarea>
|
||
<input type="file" id="img-input" multiple hidden>
|
||
<div class="thumb-strip" id="thumb-strip" hidden></div>
|
||
<div class="composer-bot">
|
||
<div class="cb-left">
|
||
<button class="chip" id="model-chip" data-i18n-title="model.menuLabel" title=""><span class="model-name"></span> <svg class="chip-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></button>
|
||
<button class="chip sm" id="plan-chip"><span data-i18n="chip.plan"></span></button>
|
||
<button class="chip sm" id="auto-chip">
|
||
<svg class="chip-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 10 14 9 22 21 10 14 10 13 2"/></svg>
|
||
<span data-i18n="chip.auto"></span>
|
||
</button>
|
||
</div>
|
||
<button class="send" id="send-btn" type="button">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="ga-menu" id="model-menu" hidden></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 消息通道 -->
|
||
<section class="page" data-page="channels">
|
||
<div class="page-pad">
|
||
<div class="page-title" data-i18n="page.channels.title"></div>
|
||
<div class="list" id="chan-list"></div>
|
||
<div class="list-empty" id="chan-empty" hidden data-i18n="ch.empty"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 状态面板 -->
|
||
<section class="page" data-page="status">
|
||
<div class="page-pad">
|
||
<div class="page-title" data-i18n="page.status.title"></div>
|
||
<div class="list" id="status-list"></div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Conductor -->
|
||
<section class="page" data-page="collab">
|
||
<div class="collab-offline" id="collab-offline" hidden>
|
||
<span data-i18n="collab.offline"></span>
|
||
<button type="button" class="chip sm" id="collab-retry" data-i18n="collab.retry"></button>
|
||
</div>
|
||
<div class="collab-reconnect" id="collab-reconnect" hidden data-i18n="collab.reconnect"></div>
|
||
<div class="collab-sticky" id="collab-sticky" hidden></div>
|
||
<div class="collab-body" id="collab-body">
|
||
<aside class="collab-progress">
|
||
<div class="collab-progress-stats" id="collab-progress-stats" hidden></div>
|
||
<div class="collab-progress-head" data-i18n="collab.progressTitle"></div>
|
||
<div class="collab-progress-empty" id="collab-progress-empty" data-i18n="collab.progressEmpty"></div>
|
||
<div id="collab-workers"></div>
|
||
</aside>
|
||
<div class="collab-chat">
|
||
<div class="collab-chat-head" id="collab-chat-head" hidden>
|
||
<span data-i18n="collab.chatTitle"></span>
|
||
<button type="button" class="ic-btn collab-progress-toggle" id="collab-progress-toggle" hidden data-i18n-title="collab.showProgressTitle" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="3" width="7" height="18" rx="1"/><rect x="14" y="3" width="7" height="18" rx="1"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="msg-area collab-msgs" id="collab-msgs">
|
||
<div class="collab-guide" id="collab-welcome" hidden>
|
||
<div class="feature-head">
|
||
<div class="page-title" data-i18n="collab.guideTitle"></div>
|
||
<p class="page-sub" data-i18n="collab.guideWhen"></p>
|
||
</div>
|
||
<div class="collab-guide-steps">
|
||
<div class="collab-guide-step">
|
||
<span class="collab-guide-ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg></span>
|
||
<span class="collab-guide-txt"><span class="collab-guide-label" data-i18n="collab.guideStep1t"></span><span class="collab-guide-desc" data-i18n="collab.guideStep1d"></span></span>
|
||
</div>
|
||
<div class="collab-guide-step">
|
||
<span class="collab-guide-ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></svg></span>
|
||
<span class="collab-guide-txt"><span class="collab-guide-label" data-i18n="collab.guideStep2t"></span><span class="collab-guide-desc" data-i18n="collab.guideStep2d"></span></span>
|
||
</div>
|
||
<div class="collab-guide-step">
|
||
<span class="collab-guide-ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><path d="M9 15l2 2 4-4"/></svg></span>
|
||
<span class="collab-guide-txt"><span class="collab-guide-label" data-i18n="collab.guideStep3t"></span><span class="collab-guide-desc" data-i18n="collab.guideStep3d"></span></span>
|
||
</div>
|
||
<div class="collab-guide-step">
|
||
<span class="collab-guide-ic" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"/><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"/></svg></span>
|
||
<span class="collab-guide-txt"><span class="collab-guide-label" data-i18n="collab.guideStep4t"></span><span class="collab-guide-desc" data-i18n="collab.guideStep4d"></span></span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="msgs" id="collab-msg-list" hidden></div>
|
||
</div>
|
||
<div class="composer collab-composer">
|
||
<div class="composer-top">
|
||
<button class="ic-btn" id="collab-upload-btn" type="button" data-i18n-title="upload.button" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05 12 20.5a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>
|
||
</button>
|
||
<div class="collab-chips" id="collab-chips"></div>
|
||
</div>
|
||
<textarea class="input" id="collab-input" data-i18n-ph="collab.placeholder" rows="1"></textarea>
|
||
<input type="file" id="collab-img-input" multiple hidden>
|
||
<div class="thumb-strip" id="collab-thumb-strip" hidden></div>
|
||
<div class="composer-bot">
|
||
<div class="cb-left"></div>
|
||
<button class="send" id="collab-send" type="button" aria-label="send">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Token 统计 -->
|
||
<section class="page" data-page="token">
|
||
<div class="page-pad">
|
||
<div class="page-title" data-i18n="page.token.title"></div>
|
||
<div class="tok-filter">
|
||
<label data-i18n="tok.from"></label>
|
||
<input type="datetime-local" id="tok-since">
|
||
<label data-i18n="tok.to"></label>
|
||
<input type="datetime-local" id="tok-until">
|
||
<button class="tok-reset" id="tok-reset" data-i18n="tok.reset"></button>
|
||
</div>
|
||
<div class="stat-row">
|
||
<div class="stat"><div class="s-n" id="tok-total-n">0</div><div class="s-l" data-i18n="tok.total"></div></div>
|
||
<div class="stat"><div class="s-n" id="tok-cost-n">¥ 0</div><div class="s-l" data-i18n="tok.cost"></div></div>
|
||
<div class="stat"><div class="s-n" id="tok-today-n">0</div><div class="s-l" data-i18n="tok.today"></div></div>
|
||
</div>
|
||
<table class="tok-table" id="tok-table">
|
||
<thead><tr>
|
||
<th data-i18n="tok.colSession"></th>
|
||
<th data-i18n="tok.colIn"></th>
|
||
<th data-i18n="tok.colOut"></th>
|
||
<th data-i18n="tok.colCacheW"></th>
|
||
<th data-i18n="tok.colCache"></th>
|
||
<th data-i18n="tok.cost"></th>
|
||
</tr></thead>
|
||
<tbody id="tok-tbody"></tbody>
|
||
</table>
|
||
<div class="tok-pager" id="tok-pager"></div>
|
||
</div>
|
||
</section>
|
||
|
||
</div>
|
||
</main>
|
||
|
||
<!-- ④ 右侧会话面板 -->
|
||
<button class="rp-toggle" id="rp-toggle" aria-label="toggle panel">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
|
||
</button>
|
||
<div class="rp-resize" id="rp-resize"></div>
|
||
<aside class="rightpanel" id="rightpanel">
|
||
<div class="search">
|
||
<svg class="search-ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
|
||
<input data-i18n-ph="search.placeholder" placeholder="">
|
||
</div>
|
||
<button class="new-conv">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||
<span data-i18n="conv.new"></span>
|
||
</button>
|
||
<div class="conv-list"></div>
|
||
|
||
<!-- 会话操作菜单 -->
|
||
<div class="ctx-menu" id="conv-menu" hidden>
|
||
<div class="ctx-item" data-act="pin">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="17" x2="12" y2="22"/><path d="M9 4h6l-1 6 3 3v2H7v-2l3-3-1-6z"/></svg>
|
||
<span data-i18n="ctx.pin"></span>
|
||
</div>
|
||
<div class="ctx-item danger" data-act="del">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 6 5 6 21 6"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
|
||
<span data-i18n="ctx.del"></span>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
|
||
</div>
|
||
|
||
<!-- 预设功能 弹窗 -->
|
||
<div class="modal" id="preset-modal" hidden>
|
||
<div class="modal-backdrop" data-close></div>
|
||
<div class="modal-card" role="dialog">
|
||
<div class="modal-head">
|
||
<div class="modal-title" data-i18n="modal.preset"></div>
|
||
<button id="preset-restore-btn" class="preset-restore" type="button" data-i18n="builtinPreset.restoreBtn" hidden></button>
|
||
<button class="modal-x" data-close data-i18n-title="common.close" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body preset-pop">
|
||
<div class="feature-grid"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 添加模型 弹窗(模板,未实现)-->
|
||
<div class="modal" id="add-model-modal" hidden>
|
||
<div class="modal-backdrop" data-close></div>
|
||
<div class="modal-card" role="dialog">
|
||
<div class="modal-head">
|
||
<div class="modal-title" id="model-form-title" data-i18n="modal.addModel"></div>
|
||
<button class="modal-x" data-close data-i18n-title="common.close" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body model-form-body">
|
||
<form id="add-model-form" class="model-form" autocomplete="off">
|
||
<label><span class="field-label"><span data-i18n="model.model"></span><span class="field-req" aria-hidden="true">*</span></span><input name="model" required data-i18n-ph="model.modelPh"><span class="field-hint" data-i18n="model.modelHint"></span></label>
|
||
<label id="model-apikey-label"><span class="field-label"><span data-i18n="model.apikey"></span><span class="field-req" aria-hidden="true">*</span></span><input name="apikey" type="password" data-i18n-ph="model.apikeyPh" id="model-apikey-input"></label>
|
||
<label><span class="field-label"><span data-i18n="model.apibase"></span><span class="field-req" aria-hidden="true">*</span></span><input name="apibase" required data-i18n-ph="model.apibasePh"></label>
|
||
<div class="model-form-field"><span class="field-label"><span data-i18n="model.protocol"></span><span class="field-req" aria-hidden="true">*</span></span>
|
||
<div class="seg-group" role="radiogroup">
|
||
<label class="seg-opt"><input type="radio" name="protocol" value="oai" required><span data-i18n="model.protocolOai"></span></label>
|
||
<label class="seg-opt"><input type="radio" name="protocol" value="claude" required><span data-i18n="model.protocolClaude"></span></label>
|
||
</div>
|
||
</div>
|
||
<label><span data-i18n="model.name"></span><input name="name" data-i18n-ph="model.namePh" data-optional-ph></label>
|
||
<div class="model-form-row">
|
||
<label class="model-form-mini"><span data-i18n="model.retries"></span><input name="max_retries" type="number" min="1" value="5"></label>
|
||
<label class="model-form-mini"><span data-i18n="model.connTimeout"></span><input name="connect_timeout" type="number" min="1" value="15"></label>
|
||
<label class="model-form-mini"><span data-i18n="model.readTimeout"></span><input name="read_timeout" type="number" min="5" value="300"></label>
|
||
</div>
|
||
<p class="model-form-err" id="add-model-err" hidden></p>
|
||
<div class="model-form-actions">
|
||
<button type="button" class="set-btn ghost" data-close data-i18n="common.cancel"></button>
|
||
<button type="submit" class="set-btn primary"><span data-i18n="model.save"></span></button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 自定义预设 弹窗 -->
|
||
<div class="modal" id="custom-preset-modal" hidden>
|
||
<div class="modal-backdrop" data-close></div>
|
||
<div class="modal-card" role="dialog">
|
||
<div class="modal-head">
|
||
<div class="modal-title" data-i18n="modal.customPreset"></div>
|
||
<button class="modal-x" data-close data-i18n-title="common.close" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body cp-body">
|
||
<input class="cp-input" id="cp-title" type="text" data-i18n-ph="customPreset.titlePh" placeholder="">
|
||
<textarea class="cp-textarea" id="cp-prompt" rows="6" data-i18n-ph="customPreset.promptPh" placeholder=""></textarea>
|
||
<div class="cp-error" id="cp-error" hidden></div>
|
||
<div class="cp-actions">
|
||
<button class="cp-btn" data-close data-i18n="common.cancel" type="button"></button>
|
||
<button class="cp-btn cp-btn-primary" id="cp-save" data-i18n="common.save" type="button"></button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 渠道日志 弹窗 -->
|
||
<div class="modal" id="chan-log-modal" hidden>
|
||
<div class="modal-backdrop" data-close></div>
|
||
<div class="modal-card modal-card-wide modal-card-inset" role="dialog">
|
||
<div class="modal-head">
|
||
<div class="modal-title" id="chan-log-title" data-i18n="modal.channelLogs"></div>
|
||
<button class="modal-x" data-close data-i18n-title="common.close" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body modal-body-inset">
|
||
<pre class="chan-log-pre" id="chan-log-pre"></pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- mykey 配置 弹窗 -->
|
||
<div class="modal" id="chan-config-modal" hidden>
|
||
<div class="modal-backdrop" data-close></div>
|
||
<div class="modal-card modal-card-wide modal-card-inset" role="dialog">
|
||
<div class="modal-head">
|
||
<div class="modal-title" id="chan-config-title" data-i18n="modal.mykeyConfig"></div>
|
||
<button class="modal-x" data-close data-i18n-title="common.close" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body modal-body-inset chan-config-body">
|
||
<textarea id="chan-config-editor" class="mykey-editor" spellcheck="false"></textarea>
|
||
<div class="chan-config-foot">
|
||
<button type="button" class="chan-config-save" id="chan-config-save" data-i18n="common.save"></button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 配置 弹窗 -->
|
||
<div class="modal" id="settings-modal" hidden>
|
||
<div class="modal-backdrop" data-close></div>
|
||
<div class="modal-card" role="dialog">
|
||
<div class="modal-head">
|
||
<div class="modal-title" data-i18n="modal.settings"></div>
|
||
<button class="modal-x" data-close data-i18n-title="common.close" title="">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body set-body">
|
||
<div class="set-block">
|
||
<div class="set-sec-t" data-i18n="set.appearance"></div>
|
||
<div class="appear-cards" id="appearance-seg" role="radiogroup">
|
||
<button class="appear-card sel" type="button" data-appearance="light" role="radio" aria-checked="true">
|
||
<span class="appear-preview appear-preview-light" aria-hidden="true"></span>
|
||
<span class="appear-name" data-i18n="appearance.light"></span>
|
||
</button>
|
||
<button class="appear-card" type="button" data-appearance="dark" role="radio" aria-checked="false">
|
||
<span class="appear-preview appear-preview-dark" aria-hidden="true"></span>
|
||
<span class="appear-name" data-i18n="appearance.dark"></span>
|
||
</button>
|
||
</div>
|
||
<div class="set-toggle-row" id="plain-ui-row" hidden>
|
||
<span class="set-toggle-label" data-i18n="set.plainUi"></span>
|
||
<button class="set-switch" type="button" id="plain-ui-switch" role="switch" aria-checked="false">
|
||
<span class="set-switch-knob" aria-hidden="true"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="set-block">
|
||
<div class="set-sec-t" id="chat-font-label" data-i18n="set.fontSize"></div>
|
||
<div class="chat-font-panel">
|
||
<div class="chat-font-stepper" id="chat-font-stepper" role="slider"
|
||
aria-valuemin="10" aria-valuemax="20" aria-valuenow="14"
|
||
aria-valuetext="14px" aria-labelledby="chat-font-label" tabindex="0">
|
||
<div class="chat-font-segments" id="chat-font-segments"></div>
|
||
</div>
|
||
<span class="chat-font-value" id="chat-font-value" aria-hidden="true">14px</span>
|
||
<div class="chat-font-scale" aria-hidden="true">
|
||
<span class="chat-font-scale-min">10</span>
|
||
<span class="chat-font-scale-max">20</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="set-block">
|
||
<div class="set-sec-t" data-i18n="set.theme"></div>
|
||
<div class="color-grid" id="theme-swatches">
|
||
<span class="swatch sel" data-theme="1" role="button" tabindex="0" aria-label="1"></span>
|
||
<span class="swatch" data-theme="2" role="button" tabindex="0" aria-label="2"></span>
|
||
<span class="swatch" data-theme="3" role="button" tabindex="0" aria-label="3"></span>
|
||
<span class="swatch" data-theme="4" role="button" tabindex="0" aria-label="4"></span>
|
||
<span class="swatch" data-theme="5" role="button" tabindex="0" aria-label="5"></span>
|
||
<span class="swatch" data-theme="6" role="button" tabindex="0" aria-label="6"></span>
|
||
<span class="swatch" data-theme="7" role="button" tabindex="0" aria-label="7"></span>
|
||
<span class="swatch" data-theme="8" role="button" tabindex="0" aria-label="8"></span>
|
||
</div>
|
||
</div>
|
||
<div class="set-block">
|
||
<div class="set-sec-t" data-i18n="set.lang"></div>
|
||
<div class="model-list lang-list" id="lang-list"></div>
|
||
</div>
|
||
<div>
|
||
<div class="set-sec-t" data-i18n="set.model"></div>
|
||
<div class="model-list" id="model-list"></div>
|
||
<button class="set-btn" id="add-model-btn" type="button">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||
<span data-i18n="set.addModel"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 图片预览 lightbox -->
|
||
<div class="lightbox" id="lightbox" hidden>
|
||
<div class="lightbox-backdrop" data-close></div>
|
||
<button class="lightbox-x" data-close data-i18n-title="lightbox.closeTitle" title="">×</button>
|
||
<img class="lightbox-img" id="lightbox-img" alt="">
|
||
</div>
|
||
|
||
<div id="toast-root" class="toast-root" aria-live="polite"></div>
|
||
|
||
<script src="vendor/marked.min.js"></script>
|
||
<!-- KaTeX JS -->
|
||
<script src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" crossorigin="anonymous"></script>
|
||
<!-- highlight.js -->
|
||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js" crossorigin="anonymous"></script>
|
||
<script src="app.js?v=43"></script>
|
||
<script src="annot.js"></script><!-- DEV 脚手架,可删 -->
|
||
</body>
|
||
</html>
|