llm-api-gateway-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +10 -0
- package/README.md +1127 -0
- package/cli-agent.js +666 -0
- package/cli-anthropic.js +236 -0
- package/cli-claude-code.js +317 -0
- package/cli-openai.js +212 -0
- package/completions/_llm-api-gateway-cli +65 -0
- package/completions/llm-api-gateway-cli.bash +64 -0
- package/completions/llm-api-gateway-cli.fish +43 -0
- package/images/chat.png +0 -0
- package/images/settings.png +0 -0
- package/images/task.png +0 -0
- package/lib/agent.js +607 -0
- package/lib/commands.js +468 -0
- package/lib/common.js +196 -0
- package/lib/config.js +70 -0
- package/lib/configcmd.js +230 -0
- package/lib/hub.js +1494 -0
- package/lib/jsonstore.js +49 -0
- package/lib/mcp.js +375 -0
- package/lib/memory.js +109 -0
- package/lib/plandoc.js +178 -0
- package/lib/pricing.js +52 -0
- package/lib/runner.js +234 -0
- package/lib/runstore.js +96 -0
- package/lib/secrets.js +198 -0
- package/lib/sessionstore.js +269 -0
- package/lib/settings.js +517 -0
- package/lib/tasksession.js +594 -0
- package/lib/taskstore.js +740 -0
- package/lib/tools.js +927 -0
- package/package.json +55 -0
- package/public/app.js +1055 -0
- package/public/index.html +167 -0
- package/public/manual.css +215 -0
- package/public/manual.html +381 -0
- package/public/manual.js +186 -0
- package/public/models.js +121 -0
- package/public/render.js +250 -0
- package/public/styles.css +955 -0
- package/public/task-slash.js +493 -0
- package/public/task.css +739 -0
- package/public/task.html +220 -0
- package/public/task.js +3127 -0
- package/public/theme.js +91 -0
- package/public/tint.js +261 -0
- package/scripts/install.ps1 +537 -0
- package/scripts/install.sh +510 -0
- package/server.js +14 -0
- package/task-server.js +15 -0
package/public/task.html
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>LLM API Gateway · 任务模式</title>
|
|
7
|
+
<link rel="stylesheet" href="/styles.css" />
|
|
8
|
+
<link rel="stylesheet" href="/task.css" />
|
|
9
|
+
<script>
|
|
10
|
+
// 防闪白:必须在首次绘制前把主题定下来,所以内联在这里(逻辑与 /theme.js 一致)
|
|
11
|
+
(() => {
|
|
12
|
+
try {
|
|
13
|
+
let t = localStorage.getItem('lgw.theme');
|
|
14
|
+
if (t !== 'dark' && t !== 'light') {
|
|
15
|
+
t = window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
|
|
16
|
+
}
|
|
17
|
+
document.documentElement.setAttribute('data-theme', t);
|
|
18
|
+
document.documentElement.style.colorScheme = t;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
21
|
+
}
|
|
22
|
+
})();
|
|
23
|
+
</script>
|
|
24
|
+
<!-- 外部集成:地址上带 ?bg=<底色> 时按底色推导整套配色。必须是阻塞脚本(排在 theme.js 之前),
|
|
25
|
+
否则会先按默认配色画一帧再变色 —— 这就是所谓的闪一下 -->
|
|
26
|
+
<script src="/tint.js"></script>
|
|
27
|
+
<script src="/theme.js" defer></script>
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<div class="app">
|
|
31
|
+
<aside class="sidebar" id="sidebar">
|
|
32
|
+
<div class="sidebar-head">
|
|
33
|
+
<button class="btn primary block" id="btn-new-task" type="button">+ 新任务</button>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="session-list" id="task-list"></div>
|
|
36
|
+
<div class="sidebar-foot">
|
|
37
|
+
<span id="tasks-count">任务 0 / 20</span>
|
|
38
|
+
<span class="foot-sep">·</span>
|
|
39
|
+
<span id="tasks-retention">滑动保留 15 天</span>
|
|
40
|
+
<button class="btn ghost tiny" id="btn-prune" type="button" title="立即清理已过期或超量的任务">清理</button>
|
|
41
|
+
</div>
|
|
42
|
+
<div class="store-line" id="store-path" title="">存储未连接</div>
|
|
43
|
+
</aside>
|
|
44
|
+
|
|
45
|
+
<main class="main">
|
|
46
|
+
<header class="topbar">
|
|
47
|
+
<button class="btn ghost icon-only" id="btn-toggle-sidebar" type="button" title="任务列表">☰</button>
|
|
48
|
+
<div class="brand">
|
|
49
|
+
<span class="dot" id="status-dot"></span>
|
|
50
|
+
<h1>LLM API Gateway</h1>
|
|
51
|
+
</div>
|
|
52
|
+
<button class="workdir-chip" id="workdir-chip" type="button" title="点击更换工作目录">
|
|
53
|
+
<span class="wd-label">工作目录</span>
|
|
54
|
+
<code id="workdir-path">未选择</code>
|
|
55
|
+
</button>
|
|
56
|
+
<div class="topbar-actions">
|
|
57
|
+
<a class="btn ghost chat-entry" id="btn-open-chat" href="/" target="_blank" rel="noopener"
|
|
58
|
+
title="回到聊天模式:不碰文件系统,纯对话">
|
|
59
|
+
<span>聊天</span>
|
|
60
|
+
<span class="ext-mark" aria-hidden="true">↗</span>
|
|
61
|
+
</a>
|
|
62
|
+
<a class="btn ghost" id="btn-open-manual" href="/manual" target="_blank" rel="noopener"
|
|
63
|
+
title="操作手册:任务页操作流程 + 三端斜杠指令对照(输入 / 也能弹指令面板)">
|
|
64
|
+
手册
|
|
65
|
+
</a>
|
|
66
|
+
<div class="theme-switch" role="group" aria-label="主题">
|
|
67
|
+
<button class="theme-btn" type="button" data-theme-option="system" title="跟随系统" aria-label="跟随系统">◐</button>
|
|
68
|
+
<button class="theme-btn" type="button" data-theme-option="light" title="白天" aria-label="白天">☀</button>
|
|
69
|
+
<button class="theme-btn" type="button" data-theme-option="dark" title="黑夜" aria-label="黑夜">☾</button>
|
|
70
|
+
</div>
|
|
71
|
+
<button class="btn ghost" id="btn-settings" type="button">设置</button>
|
|
72
|
+
</div>
|
|
73
|
+
</header>
|
|
74
|
+
|
|
75
|
+
<section class="messages" id="messages">
|
|
76
|
+
<div class="empty" id="empty-hint">
|
|
77
|
+
<h2 id="empty-title">先选择一个工作目录</h2>
|
|
78
|
+
<p id="empty-desc">
|
|
79
|
+
任务模式下模型会通过工具<b>真正读写</b>你选定的目录:可列目录、读文件、搜索内容;
|
|
80
|
+
写入文件前会先征求你的批准。所有操作都被限制在该目录之内。
|
|
81
|
+
</p>
|
|
82
|
+
<div class="chips">
|
|
83
|
+
<button class="chip" id="chip-pick" type="button">选择工作目录</button>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</section>
|
|
87
|
+
|
|
88
|
+
<footer class="composer">
|
|
89
|
+
<div class="composer-box" id="composer-box">
|
|
90
|
+
<div class="mode-bar">
|
|
91
|
+
<span class="mode-label">模式</span>
|
|
92
|
+
<div class="mode-switch" id="mode-switch" role="group" aria-label="审批模式">
|
|
93
|
+
<button class="mode-btn" type="button" data-mode="manual"
|
|
94
|
+
title="每次写入都要你在界面上点确认">手动</button>
|
|
95
|
+
<button class="mode-btn" type="button" data-mode="auto"
|
|
96
|
+
title="写入直接执行,不再打断你;界面仍逐条显示改了什么">自动</button>
|
|
97
|
+
<button class="mode-btn" type="button" data-mode="plan"
|
|
98
|
+
title="只给模型只读工具,先出计划、不动文件;确认后再执行">计划</button>
|
|
99
|
+
</div>
|
|
100
|
+
<span class="mode-note" id="mode-note"></span>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="slash-menu" id="slash-menu" hidden role="listbox" aria-label="斜杠指令候选"></div>
|
|
103
|
+
<textarea id="input" rows="1" placeholder="先选择工作目录后再输入任务" autocomplete="off" disabled></textarea>
|
|
104
|
+
<div class="composer-bar">
|
|
105
|
+
<span class="hint" id="status">等待选择工作目录</span>
|
|
106
|
+
<div class="composer-buttons">
|
|
107
|
+
<button class="btn" id="btn-stop" type="button" hidden>停止</button>
|
|
108
|
+
<button class="btn primary" id="btn-send" type="button" disabled>执行</button>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
</footer>
|
|
113
|
+
</main>
|
|
114
|
+
|
|
115
|
+
<aside class="settings" id="settings">
|
|
116
|
+
<div class="settings-head">
|
|
117
|
+
<h2>设置</h2>
|
|
118
|
+
<button class="btn ghost" id="btn-settings-close" type="button">关闭</button>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<label class="field">
|
|
122
|
+
<span>模型</span>
|
|
123
|
+
<select id="set-model" title="只能从网关拉到的模型列表里选;列表不对就点「刷新模型」"></select>
|
|
124
|
+
<small id="models-hint">模型列表由网关 /v1/models 提供,只能选、不能填</small>
|
|
125
|
+
</label>
|
|
126
|
+
|
|
127
|
+
<label class="field">
|
|
128
|
+
<span>附加要求(拼在系统提示词之后)</span>
|
|
129
|
+
<textarea id="set-system" rows="3" placeholder="例如:只改 src/ 下的代码,不要动配置"></textarea>
|
|
130
|
+
</label>
|
|
131
|
+
|
|
132
|
+
<div class="row">
|
|
133
|
+
<label class="field">
|
|
134
|
+
<span>温度</span>
|
|
135
|
+
<input id="set-temperature" type="number" min="0" max="2" step="0.1" />
|
|
136
|
+
</label>
|
|
137
|
+
<label class="field">
|
|
138
|
+
<span>最大 tokens</span>
|
|
139
|
+
<input id="set-max-tokens" type="number" min="0" step="256" placeholder="0 = 不限制" />
|
|
140
|
+
</label>
|
|
141
|
+
</div>
|
|
142
|
+
|
|
143
|
+
<label class="check" title="思考模型(如 deepseek-v4-*)会先输出思维链;关闭后只显示正文">
|
|
144
|
+
<input id="set-show-reasoning" type="checkbox" />
|
|
145
|
+
<span>显示思考过程</span>
|
|
146
|
+
</label>
|
|
147
|
+
|
|
148
|
+
<div class="settings-actions">
|
|
149
|
+
<button class="btn ghost" id="btn-refresh-models" type="button">刷新模型</button>
|
|
150
|
+
<button class="btn ghost" id="btn-reset" type="button">恢复默认</button>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<!-- 其他配置:按服务端白名单(/api/settings 的 rows)渲染,页面不抄第二份。
|
|
154
|
+
默认展开(这些项以前在页面上根本没地方改);连不上服务端时整组隐藏 ——
|
|
155
|
+
它们本来就住在磁盘上,浏览器里没有可兜底的副本。 -->
|
|
156
|
+
<details class="settings-group" id="config-extra-group" open hidden>
|
|
157
|
+
<summary>
|
|
158
|
+
<span>其他配置</span>
|
|
159
|
+
<small>改完即时生效;标「重启生效」的要重启服务</small>
|
|
160
|
+
</summary>
|
|
161
|
+
<div id="config-extra"></div>
|
|
162
|
+
</details>
|
|
163
|
+
|
|
164
|
+
<div class="info">
|
|
165
|
+
<div class="info-row"><span>网关地址</span><code id="info-base">—</code></div>
|
|
166
|
+
<div class="info-row"><span>密钥</span><code id="info-key">—</code></div>
|
|
167
|
+
<div class="info-row"><span>可用工具</span><code id="info-tools">—</code></div>
|
|
168
|
+
<div class="info-row"><span>累计用量</span><code id="info-usage">—</code></div>
|
|
169
|
+
<div class="info-row"><span>轮次上限</span><code id="info-limit">—</code></div>
|
|
170
|
+
<div class="info-row"><span>本地任务</span><code id="info-tasks">—</code></div>
|
|
171
|
+
<div class="info-row"><span>保留策略</span><code id="info-retention">—</code></div>
|
|
172
|
+
<div class="info-row"><span>占用空间</span><code id="info-store-size">—</code></div>
|
|
173
|
+
<div class="info-row info-row-wide">
|
|
174
|
+
<span>存储位置</span>
|
|
175
|
+
<code id="info-store" class="path-code" title="">—</code>
|
|
176
|
+
</div>
|
|
177
|
+
</div>
|
|
178
|
+
<p class="settings-note">
|
|
179
|
+
任务记录存放在上面这个磁盘目录里(服务端直写,不经过浏览器),所以换浏览器、
|
|
180
|
+
清缓存都不会丢,单条任务的工具输出也不再受浏览器存储 5MB 的限制。
|
|
181
|
+
用 <code>--store <目录></code> 可以改到别处。
|
|
182
|
+
</p>
|
|
183
|
+
</aside>
|
|
184
|
+
</div>
|
|
185
|
+
|
|
186
|
+
<!-- 工作目录选择器 -->
|
|
187
|
+
<div class="modal" id="dir-modal" hidden>
|
|
188
|
+
<div class="modal-card">
|
|
189
|
+
<div class="modal-head">
|
|
190
|
+
<h2>选择工作目录</h2>
|
|
191
|
+
<span class="modal-sub">模型只能读写你选定的这个目录</span>
|
|
192
|
+
</div>
|
|
193
|
+
|
|
194
|
+
<div class="modal-path">
|
|
195
|
+
<button class="btn ghost tiny" id="dir-up" type="button">↑ 上级</button>
|
|
196
|
+
<input id="dir-path-input" spellcheck="false" placeholder="也可以直接粘贴一个绝对路径" />
|
|
197
|
+
<button class="btn ghost tiny" id="dir-go" type="button">前往</button>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<div class="modal-body">
|
|
201
|
+
<div class="dir-roots" id="dir-roots"></div>
|
|
202
|
+
<div class="dir-list" id="dir-list"></div>
|
|
203
|
+
</div>
|
|
204
|
+
|
|
205
|
+
<div class="modal-foot">
|
|
206
|
+
<span class="modal-note" id="dir-note">双击目录进入,选中后点「选为工作目录」</span>
|
|
207
|
+
<div class="modal-actions">
|
|
208
|
+
<button class="btn ghost" id="dir-cancel" type="button">取消</button>
|
|
209
|
+
<button class="btn primary" id="dir-confirm" type="button">选为工作目录</button>
|
|
210
|
+
</div>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
|
|
215
|
+
<script src="/render.js"></script>
|
|
216
|
+
<script src="/models.js"></script>
|
|
217
|
+
<script src="/task-slash.js"></script>
|
|
218
|
+
<script src="/task.js"></script>
|
|
219
|
+
</body>
|
|
220
|
+
</html>
|