680 lines
38 KiB
HTML
680 lines
38 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>GenericAgent</title>
|
||
<link rel="stylesheet" href="assets/fonts/fonts.css?v=2">
|
||
<link rel="stylesheet" href="styles.css?v=181">
|
||
<!-- 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">
|
||
<!-- Flatpickr: 日期选择器 -->
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.css" crossorigin="anonymous">
|
||
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/flatpickr.min.js" crossorigin="anonymous"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/flatpickr@4.6.13/dist/l10n/zh.js" crossorigin="anonymous"></script>
|
||
<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-text">
|
||
<div class="brand-name ga-wordmark">Generic Agent</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">
|
||
<span class="ic" data-ga-icon="chatTeardropText"></span>
|
||
<span data-i18n="nav.chat"></span>
|
||
</a>
|
||
<a class="nav-item" data-page="collab">
|
||
<span class="ic" data-ga-icon="gitFork"></span>
|
||
<span data-i18n="nav.collab"></span>
|
||
<span id="collab-badge" class="collab-nav-badge" hidden></span>
|
||
</a>
|
||
<a class="nav-item" data-page="services">
|
||
<span class="ic" data-ga-icon="broadcast"></span>
|
||
<span data-i18n="nav.services"></span>
|
||
</a>
|
||
<a class="nav-item" data-page="token">
|
||
<span class="ic" data-ga-icon="coins"></span>
|
||
<span data-i18n="nav.token"></span>
|
||
</a>
|
||
</nav>
|
||
|
||
<!-- 快速接入官方模型(DeepSeek / 通义千问):填好 API Key 即可使用 -->
|
||
<div class="provider-quickstart" id="provider-quickstart">
|
||
<div class="pq-head" id="pq-toggle" role="button" tabindex="0" aria-expanded="true">
|
||
<span class="fr-l">
|
||
<span class="ic" data-ga-icon="lightning"></span>
|
||
<span class="pq-title" data-i18n="pq.title"></span>
|
||
</span>
|
||
<span class="pq-collapse chev" data-ga-icon="caretRight" aria-hidden="true"></span>
|
||
</div>
|
||
<div class="pq-body">
|
||
<button type="button" class="pq-btn" data-provider="deepseek">
|
||
<span class="pq-logo" style="background:rgba(77,107,254,.12)" aria-hidden="true"><svg viewBox="0 0 24 24" fill="#4D6BFE" xmlns="http://www.w3.org/2000/svg"><path d="M23.748 4.651c-.254-.124-.364.113-.512.233-.051.04-.094.09-.137.137-.372.397-.806.657-1.373.626-.829-.046-1.537.214-2.163.848-.133-.782-.575-1.248-1.247-1.548-.352-.155-.708-.311-.955-.65-.172-.24-.219-.509-.305-.774-.055-.16-.11-.323-.293-.35-.2-.031-.278.136-.356.276-.313.572-.434 1.202-.422 1.84.027 1.436.633 2.58 1.838 3.393.137.094.172.187.129.323-.082.28-.18.553-.266.833-.055.179-.137.218-.328.14a5.5 5.5 0 0 1-1.737-1.179c-.857-.828-1.631-1.743-2.597-2.46a12 12 0 0 0-.689-.47c-.985-.957.13-1.743.387-1.836.27-.098.094-.433-.778-.428-.872.003-1.67.295-2.687.685a3 3 0 0 1-.465.136 9.6 9.6 0 0 0-2.883-.101c-1.885.21-3.39 1.1-4.497 2.622C.082 8.776-.231 10.854.152 13.02c.403 2.284 1.568 4.175 3.36 5.653 1.857 1.533 3.997 2.284 6.438 2.14 1.482-.085 3.132-.284 4.994-1.86.47.234.962.328 1.78.398.629.058 1.235-.031 1.705-.129.735-.155.684-.836.418-.961-2.155-1.004-1.682-.595-2.112-.926 1.095-1.295 2.768-3.598 3.284-6.733.05-.346.115-.834.108-1.114-.004-.171.035-.238.23-.257a4.2 4.2 0 0 0 1.545-.475c1.397-.763 1.96-2.016 2.093-3.517.02-.23-.004-.467-.247-.588M11.58 18.168c-2.088-1.642-3.101-2.183-3.52-2.16-.39.024-.32.472-.234.763.09.288.207.487.371.74.114.167.192.416-.113.603-.673.416-1.842-.14-1.897-.168-1.361-.801-2.5-1.86-3.301-3.306-.775-1.393-1.225-2.888-1.299-4.482-.02-.385.094-.522.477-.592a4.7 4.7 0 0 1 1.53-.038c2.131.311 3.946 1.264 5.467 2.774.868.86 1.525 1.887 2.202 2.89.72 1.066 1.494 2.082 2.48 2.915.348.291.626.513.892.677-.802.09-2.14.109-3.055-.615zm1.001-6.44a.306.306 0 0 1 .415-.287.3.3 0 0 1 .113.074.3.3 0 0 1 .086.214c0 .17-.136.307-.308.307a.303.303 0 0 1-.306-.307m3.11 1.596c-.2.081-.4.151-.591.16a1.25 1.25 0 0 1-.798-.254c-.274-.23-.47-.358-.551-.758a1.7 1.7 0 0 1 .015-.588c.07-.327-.007-.537-.238-.727-.188-.156-.426-.199-.689-.199a.6.6 0 0 1-.254-.078.253.253 0 0 1-.114-.358 1 1 0 0 1 .192-.21c.356-.202.767-.136 1.146.016.352.144.618.408 1.001.782.392.451.462.576.685.915.176.264.336.536.446.848.066.194-.02.353-.25.45"/></svg></span>
|
||
<span class="pq-btn-text">
|
||
<span class="pq-btn-name">DeepSeek</span>
|
||
<span class="pq-btn-desc" data-i18n="pq.deepseekDesc"></span>
|
||
</span>
|
||
<span class="pq-arrow" data-ga-icon="caretRight"></span>
|
||
</button>
|
||
<button type="button" class="pq-btn" data-provider="qwen">
|
||
<span class="pq-logo" style="background:rgba(97,92,237,.12)" aria-hidden="true"><svg viewBox="0 0 24 24" fill="#615CED" xmlns="http://www.w3.org/2000/svg"><path d="M23.919 14.545 20.817 9.17l1.47-2.544a.56.56 0 0 0 0-.566l-1.633-2.83a.57.57 0 0 0-.49-.283h-6.207L12.487.402a.57.57 0 0 0-.49-.284H8.732a.56.56 0 0 0-.49.284L5.139 5.775h-2.94a.56.56 0 0 0-.49.284L.077 8.887a.56.56 0 0 0 0 .567L3.18 14.83l-1.47 2.545a.56.56 0 0 0 0 .566l1.634 2.83a.57.57 0 0 0 .49.283h6.205l1.47 2.545a.57.57 0 0 0 .49.284h3.266a.57.57 0 0 0 .49-.284l3.104-5.375h2.94a.57.57 0 0 0 .49-.283l1.634-2.828a.55.55 0 0 0-.004-.568M8.733.686l1.634 2.828-1.634 2.828H21.8L20.164 9.17H7.425L5.63 6.06Zm1.306 19.801-6.205-.002 1.634-2.83h3.265L2.201 6.344h3.267q3.182 5.517 6.367 11.032zm10.124-5.66L18.53 12l-6.532 11.315-1.634-2.83c2.129-3.673 4.25-7.351 6.373-11.028h3.592l3.102 5.374z"/></svg></span>
|
||
<span class="pq-btn-text">
|
||
<span class="pq-btn-name">通义千问</span>
|
||
<span class="pq-btn-desc" data-i18n="pq.qwenDesc"></span>
|
||
</span>
|
||
<span class="pq-arrow" data-ga-icon="caretRight"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="sidebar-foot">
|
||
<a class="foot-row" id="settings-btn">
|
||
<span class="fr-l">
|
||
<span class="ic" data-ga-icon="gear"></span>
|
||
<span data-i18n="foot.settings"></span>
|
||
</span>
|
||
<span class="chev" data-ga-icon="caretRight"></span>
|
||
</a>
|
||
<div class="foot-ver" data-i18n="foot.ver"></div>
|
||
</div>
|
||
</aside>
|
||
<div class="sb-resize" id="sb-resize"></div>
|
||
|
||
<!-- 中间主区 -->
|
||
<main class="main">
|
||
|
||
<div id="pages">
|
||
|
||
<!-- 聊天 -->
|
||
<section class="page active page--chat-ui" data-page="chat">
|
||
<div class="page-top">
|
||
<button type="button" class="pt-icon pt-sb-toggle" aria-label="toggle sidebar">
|
||
<span data-ga-icon="caretLeft"></span>
|
||
</button>
|
||
<button class="run-state" id="run-toggle" type="button">
|
||
<i class="dot"></i> <span class="rs-label"></span>
|
||
</button>
|
||
<button type="button" class="pt-icon pt-rp-toggle" aria-label="toggle conversations">
|
||
<span data-ga-icon="caretRight"></span>
|
||
</button>
|
||
</div>
|
||
<div class="chat-shell">
|
||
<div class="chat-panel">
|
||
<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="session-loading" id="session-loading" hidden aria-live="polite">
|
||
<span class="ga-spin" aria-hidden="true"></span>
|
||
<span data-i18n="chat.sessionLoading"></span>
|
||
</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-anchor" id="chat-composer-anchor">
|
||
<div class="composer" id="chat-composer" data-composer-ctx="chat">
|
||
<div class="composer-slot">
|
||
<div class="plan-card" id="plan-bar" hidden aria-live="polite"></div>
|
||
<div class="composer-inset">
|
||
<div class="thumb-strip" id="thumb-strip" hidden></div>
|
||
<div class="input" id="chat-input" contenteditable="true" role="textbox" aria-multiline="true" data-i18n-ph="composer.placeholder"></div>
|
||
<div class="composer-bot">
|
||
<div class="composer-plus-wrap">
|
||
<button type="button" class="ic-btn composer-plus" id="chat-plus-btn" aria-haspopup="menu" aria-expanded="false" data-i18n-title="collab.plusMenu" title="">
|
||
<span data-ga-icon="plus"></span>
|
||
</button>
|
||
<div class="ga-menu composer-menu" id="chat-menu" hidden role="menu">
|
||
<button type="button" class="ga-menu-item" data-composer-action="upload" role="menuitem">
|
||
<span data-ga-icon="paperclip"></span>
|
||
<span data-i18n="upload.button"></span>
|
||
</button>
|
||
<button type="button" class="ga-menu-item" data-composer-action="preset" role="menuitem">
|
||
<span data-ga-icon="lightning"></span>
|
||
<span data-i18n="modal.preset"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<span class="spacer"></span>
|
||
<button type="button" class="chip" id="model-chip" data-i18n-title="model.menuLabel" title=""><span class="model-name"></span> <span class="chip-ic" data-ga-icon="caretDown"></span></button>
|
||
<button type="button" class="send" id="send-btn" aria-label="send">
|
||
<span data-ga-icon="paperPlaneTilt"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="ga-menu" id="model-menu" hidden></div>
|
||
<input type="file" id="chat-file-input" multiple hidden>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 后台服务:消息通道 + 状态面板 -->
|
||
<section class="page" data-page="services">
|
||
<div class="page-top">
|
||
<button type="button" class="pt-icon pt-sb-toggle" aria-label="toggle sidebar">
|
||
<span data-ga-icon="caretLeft"></span>
|
||
</button>
|
||
<span class="pt-spacer"></span>
|
||
<button type="button" class="pt-icon pt-rp-toggle" aria-label="toggle conversations">
|
||
<span data-ga-icon="caretRight"></span>
|
||
</button>
|
||
</div>
|
||
<div class="page-pad">
|
||
<div class="page-title" data-i18n="page.services.title"></div>
|
||
<div class="svc-tabs" id="svc-tabs">
|
||
<button type="button" class="svc-tab active" data-tab="channels" data-i18n="page.channels.title"></button>
|
||
<button type="button" class="svc-tab" data-tab="status" data-i18n="page.status.title"></button>
|
||
</div>
|
||
<div class="svc-panel active" data-svc-panel="channels">
|
||
<div class="list" id="chan-list"></div>
|
||
<div class="list-empty" id="chan-empty" hidden data-i18n="ch.empty"></div>
|
||
</div>
|
||
<div class="svc-panel" data-svc-panel="status">
|
||
<div class="list" id="status-list"></div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- 指挥家 Conductor(对话区结构复用 page--chat-ui / chat-shell) -->
|
||
<section class="page page--chat-ui" data-page="collab">
|
||
<div class="page-top">
|
||
<button type="button" class="pt-icon pt-sb-toggle" aria-label="toggle sidebar">
|
||
<span data-ga-icon="caretLeft"></span>
|
||
</button>
|
||
<div class="page-top-center">
|
||
<button class="run-state" id="collab-run-toggle" type="button">
|
||
<i class="dot"></i> <span class="rs-label"></span>
|
||
</button>
|
||
<button type="button" class="pt-icon collab-retry-btn" id="collab-retry" hidden data-i18n-aria-label="collab.retry" aria-label="retry">
|
||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="23 4 23 10 17 10"/><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"/></svg>
|
||
</button>
|
||
</div>
|
||
<button type="button" class="pt-icon pt-rp-toggle" aria-label="toggle conversations">
|
||
<span data-ga-icon="caretRight"></span>
|
||
</button>
|
||
</div>
|
||
<div class="chat-shell">
|
||
<div class="chat-panel">
|
||
<div class="msg-area collab-msgs" id="collab-msgs">
|
||
<div class="collab-scroll">
|
||
<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"><span data-ga-icon="chatTeardropText"></span></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"><span data-ga-icon="gridFour"></span></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"><span data-ga-icon="listChecks"></span></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"><span data-ga-icon="pencilSimple"></span></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="collab-overlay">
|
||
<div class="collab-rail" id="collab-rail" hidden>
|
||
<button type="button" class="collab-rail-handle" id="collab-rail-toggle" data-i18n-title="collab.showProgressTitle" title="">
|
||
<span class="collab-rail-grip" aria-hidden="true"></span>
|
||
<svg class="collab-rail-chev" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor" aria-hidden="true"><path d="M181.66,133.66l-80,80a8,8,0,0,1-11.32-11.32L164.69,128,90.34,53.66a8,8,0,0,1,11.32-11.32l80,80A8,8,0,0,1,181.66,133.66Z"/></svg>
|
||
<span class="collab-rail-badge collab-rail-run" id="collab-rail-run" hidden>
|
||
<span class="collab-rail-spin" aria-hidden="true"></span>
|
||
<span class="n" id="collab-rail-run-n">0</span>
|
||
</span>
|
||
<span class="collab-rail-badge collab-rail-done" id="collab-rail-done" hidden>
|
||
<span class="collab-rail-dot" aria-hidden="true"></span>
|
||
<span class="n" id="collab-rail-done-n">0</span>
|
||
</span>
|
||
<span class="collab-rail-badge collab-rail-issue" id="collab-rail-issue" hidden>
|
||
<span class="collab-rail-dot collab-rail-dot--danger" aria-hidden="true"></span>
|
||
<span class="n" id="collab-rail-issue-n">0</span>
|
||
</span>
|
||
</button>
|
||
</div>
|
||
<aside class="collab-prog-panel" id="collab-prog-panel">
|
||
<div class="collab-prog-panel-head">
|
||
<span data-i18n="collab.progressTitle"></span>
|
||
<button type="button" class="ic-btn collab-prog-close" id="collab-prog-close" aria-label="close">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor" aria-hidden="true"><path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"/></svg>
|
||
</button>
|
||
</div>
|
||
<div class="collab-prog-stats" id="collab-progress-stats" hidden></div>
|
||
<div class="collab-progress-empty" id="collab-progress-empty" data-i18n="collab.progressEmpty"></div>
|
||
<div id="collab-workers"></div>
|
||
</aside>
|
||
</div>
|
||
</div>
|
||
<div class="collab-quick" id="collab-quick">
|
||
<button type="button" class="pill" data-prompt-key="collab.chipProgress" data-i18n="collab.chipProgress"></button>
|
||
<button type="button" class="pill" data-prompt-key="collab.chipPause" data-i18n="collab.chipPause"></button>
|
||
<button type="button" class="pill" data-prompt-key="collab.chipSummary" data-i18n="collab.chipSummary"></button>
|
||
</div>
|
||
<div class="composer-anchor" id="cdb-composer-anchor">
|
||
<div class="composer" id="cdb-composer" data-composer-ctx="collab">
|
||
<div class="composer-slot">
|
||
<div class="composer-inset">
|
||
<div class="thumb-strip" id="cdb-thumb-strip" hidden></div>
|
||
<div class="input" id="cdb-input" contenteditable="true" role="textbox" aria-multiline="true" data-i18n-ph="collab.placeholder"></div>
|
||
<div class="composer-bot">
|
||
<div class="composer-plus-wrap">
|
||
<button type="button" class="ic-btn composer-plus" id="cdb-plus-btn" aria-haspopup="menu" aria-expanded="false" data-i18n-title="collab.plusMenu" title="">
|
||
<span data-ga-icon="plus"></span>
|
||
</button>
|
||
<div class="ga-menu composer-menu" id="cdb-menu" hidden role="menu">
|
||
<button type="button" class="ga-menu-item" data-composer-action="upload" role="menuitem">
|
||
<span data-ga-icon="paperclip"></span>
|
||
<span data-i18n="upload.button"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<span class="spacer"></span>
|
||
<button type="button" class="chip" id="cdb-model-chip" data-i18n-title="model.menuLabel" title="">
|
||
<span class="model-name"></span>
|
||
<span class="chip-ic" data-ga-icon="caretDown"></span>
|
||
</button>
|
||
<button type="button" class="send" id="cdb-send" aria-label="send">
|
||
<span data-ga-icon="paperPlaneTilt"></span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="ga-menu" id="cdb-model-menu" hidden></div>
|
||
<input type="file" id="cdb-file-input" multiple hidden>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- Token 统计 -->
|
||
<section class="page" data-page="token">
|
||
<div class="page-top">
|
||
<button type="button" class="pt-icon pt-sb-toggle" aria-label="toggle sidebar">
|
||
<span data-ga-icon="caretLeft"></span>
|
||
</button>
|
||
<span class="pt-spacer"></span>
|
||
<button type="button" class="pt-icon pt-rp-toggle" aria-label="toggle conversations">
|
||
<span data-ga-icon="caretRight"></span>
|
||
</button>
|
||
</div>
|
||
<div class="page-pad">
|
||
<div class="page-title" data-i18n="page.token.title"></div>
|
||
<div class="tok-tabs" id="tok-tabs">
|
||
<button class="tok-tab active" data-tab="chat" data-i18n="tok.tabAll"></button>
|
||
<button class="tok-tab" data-tab="conductor" data-i18n="tok.tabConductor"></button>
|
||
</div>
|
||
<div class="tok-filter">
|
||
<label data-i18n="tok.from"></label>
|
||
<input type="text" id="tok-since" class="tok-date" readonly>
|
||
<label data-i18n="tok.to"></label>
|
||
<input type="text" id="tok-until" class="tok-date" readonly>
|
||
<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>
|
||
|
||
<!-- ④ 右侧会话面板 -->
|
||
<div class="rp-resize" id="rp-resize"></div>
|
||
<aside class="rightpanel" id="rightpanel">
|
||
<div class="rp-head">
|
||
<div class="search">
|
||
<span class="search-ic" data-ga-icon="magnifyingGlass"></span>
|
||
<input data-i18n-ph="search.placeholder" placeholder="" maxlength="50">
|
||
</div>
|
||
</div>
|
||
<button type="button" class="new-conv">
|
||
<span data-ga-icon="plus"></span>
|
||
<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">
|
||
<span data-ga-icon="pushPinSimple"></span>
|
||
<span data-i18n="ctx.pin"></span>
|
||
</div>
|
||
<div class="ctx-item" data-act="rename">
|
||
<span data-ga-icon="pencilSimple"></span>
|
||
<span data-i18n="ctx.rename"></span>
|
||
</div>
|
||
<div class="ctx-item danger" data-act="del">
|
||
<span data-ga-icon="trash"></span>
|
||
<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="">
|
||
<span data-ga-icon="x"></span>
|
||
</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="">
|
||
<span data-ga-icon="x"></span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body model-form-body">
|
||
<div class="model-guide" id="model-guide" hidden>
|
||
<div class="model-guide-head">
|
||
<span class="model-guide-logo" id="model-guide-logo" aria-hidden="true"></span>
|
||
<span class="model-guide-name" id="model-guide-name"></span>
|
||
</div>
|
||
<ol class="model-guide-steps">
|
||
<li data-i18n="guide.step1"></li>
|
||
<li data-i18n="guide.step2"></li>
|
||
<li data-i18n="guide.step3"></li>
|
||
</ol>
|
||
<div class="model-guide-link-row">
|
||
<a class="model-guide-link" id="model-guide-link" href="#" target="_blank" rel="noopener noreferrer"></a>
|
||
<button type="button" class="model-guide-copy" id="model-guide-copy" data-i18n-title="guide.copy" title="" aria-label="copy">
|
||
<span data-ga-icon="copy"></span>
|
||
</button>
|
||
</div>
|
||
<p class="model-guide-tip" data-i18n="guide.prefillTip"></p>
|
||
</div>
|
||
<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" maxlength="50"><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" maxlength="200"></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" maxlength="200"></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>
|
||
<div class="model-form-field"><span class="field-label"><span data-i18n="model.stream"></span></span>
|
||
<div class="seg-group" role="radiogroup">
|
||
<label class="seg-opt"><input type="radio" name="stream" value="true" checked><span data-i18n="model.streamOn"></span></label>
|
||
<label class="seg-opt"><input type="radio" name="stream" value="false"><span data-i18n="model.streamOff"></span></label>
|
||
</div>
|
||
</div>
|
||
<label><span data-i18n="model.name"></span><input name="name" data-i18n-ph="model.namePh" data-optional-ph maxlength="50"></label>
|
||
<div class="model-form-row">
|
||
<label class="model-form-mini"><span data-i18n="model.retries"></span><input name="max_retries" type="text" inputmode="numeric" pattern="[0-9]*" min="1" max="20" value="5"></label>
|
||
<label class="model-form-mini"><span data-i18n="model.connTimeout"></span><input name="connect_timeout" type="text" inputmode="numeric" pattern="[0-9]*" min="1" max="300" value="15"></label>
|
||
<label class="model-form-mini"><span data-i18n="model.readTimeout"></span><input name="read_timeout" type="text" inputmode="numeric" pattern="[0-9]*" min="5" max="3600" 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="confirm-modal" hidden>
|
||
<div class="modal-backdrop" data-close></div>
|
||
<div class="modal-card confirm-card" role="dialog" aria-modal="true" aria-labelledby="confirm-title">
|
||
<div class="modal-head">
|
||
<div class="modal-title" id="confirm-title"></div>
|
||
<button class="modal-x" data-close data-i18n-title="common.close" title="">
|
||
<span data-ga-icon="x"></span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body confirm-body">
|
||
<div class="confirm-message" id="confirm-message"></div>
|
||
<div class="confirm-actions">
|
||
<button type="button" class="set-btn ghost" id="confirm-cancel"></button>
|
||
<button type="button" class="set-btn primary" id="confirm-ok"></button>
|
||
</div>
|
||
</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="">
|
||
<span data-ga-icon="x"></span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body cp-body">
|
||
<input class="cp-input" id="cp-title" type="text" data-i18n-ph="customPreset.titlePh" placeholder="" maxlength="50">
|
||
<textarea class="cp-textarea" id="cp-prompt" rows="6" data-i18n-ph="customPreset.promptPh" placeholder="" maxlength="10000"></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="">
|
||
<span data-ga-icon="x"></span>
|
||
</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="">
|
||
<span data-ga-icon="x"></span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body modal-body-inset chan-config-body">
|
||
<textarea id="chan-config-editor" class="mykey-editor" spellcheck="false" maxlength="1000000"></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="">
|
||
<span data-ga-icon="x"></span>
|
||
</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.lang"></div>
|
||
<div class="model-list lang-list" id="lang-list"></div>
|
||
</div>
|
||
<div class="set-block">
|
||
<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">
|
||
<span data-ga-icon="plus"></span>
|
||
<span data-i18n="set.addModel"></span>
|
||
</button>
|
||
</div>
|
||
<div class="set-block">
|
||
<div class="set-sec-t" data-i18n="set.features"></div>
|
||
<button class="set-btn" id="import-mykey-btn" type="button">
|
||
<span data-ga-icon="fileText"></span>
|
||
<span data-i18n="set.importMykey"></span>
|
||
</button>
|
||
<input type="file" id="import-mykey-input" accept=".py,text/plain" hidden>
|
||
<button class="set-btn set-btn-follow" id="export-mykey-btn" type="button">
|
||
<span data-ga-icon="folderSimple"></span>
|
||
<span data-i18n="set.exportMykey"></span>
|
||
</button>
|
||
<button class="set-btn set-btn-follow" id="settings-services-btn" type="button">
|
||
<span data-ga-icon="broadcast"></span>
|
||
<span data-i18n="set.serviceManager"></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="phosphor-icons.js?v=2"></script>
|
||
<script src="app.js?v=208"></script>
|
||
</body>
|
||
</html>
|