-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpricing.html
More file actions
244 lines (237 loc) · 11.9 KB
/
Copy pathpricing.html
File metadata and controls
244 lines (237 loc) · 11.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>价格配置 - OpenClaw Usage</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="/src/style.css" />
<script>
(function () {
try {
var m = localStorage.getItem('openclaw-theme') || 'system';
var dark = m === 'dark' || (m === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);
document.documentElement.classList.add(dark ? 'theme-dark' : 'theme-light');
document.documentElement.dataset.themeMode = m;
document.documentElement.style.colorScheme = dark ? 'dark' : 'light';
} catch (e) {
document.documentElement.classList.add('theme-light');
}
})();
</script>
<script src="/src/theme.js"></script>
</head>
<body data-i18n-title-key="pricing.pageTitle">
<div class="pricing-page">
<!-- 返回链接 -->
<a href="/" class="back-link">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M19 12H5M12 19l-7-7 7-7"/>
</svg>
<span data-i18n="pricing.backToDashboard">返回仪表盘</span>
</a>
<!-- 页面头部 -->
<div class="pricing-header">
<div>
<h1 class="pricing-title-row">
<span class="pricing-title-text">💰 价格配置</span>
<label
class="pricing-enable-integrated"
title="关闭后仪表盘与统计使用会话中的 OpenClaw 账面成本;下方配置仍可编辑,仅表示当前未生效"
>
<span class="pricing-enable-integrated-track">
<input
type="checkbox"
id="custom-pricing-enabled"
class="pricing-enable-integrated-input"
checked
aria-label="启用自定义单价"
/>
<span class="pricing-enable-integrated-word">启用</span>
<span class="pricing-enable-integrated-rail" aria-hidden="true">
<span class="pricing-enable-integrated-knob"></span>
</span>
</span>
</label>
<div class="tooltip-wrapper">
<button
type="button"
class="help-icon"
id="pricing-help-copy-btn"
title="悬停查看说明;点击复制全部说明到剪贴板"
aria-label="价格说明,悬停查看,点击复制"
>
?
</button>
<div class="tooltip-popup glass-card">
<div id="pricing-help-copy-content">
<h4>📝 说明</h4>
<ul>
<li>单价按<strong>每百万 tokens</strong>的美元计价(与下方数值列一致)</li>
<li>关闭「启用」或关闭某一行的「启用」后,该范围使用会话中的 OpenClaw 账面成本</li>
<li>开启「启用」且开启对应行时,使用自定义单价重算成本(理论价)</li>
<li>下方「内置价格」「缺少价格」参考表来自 <code>models.json</code>(<code>$OPENCLAW_CONFIG_DIR</code> 或默认 <code>~/.openclaw</code> 下 <code>agents/main/agent/models.json</code>)中的模型条目;<strong>实际在 OpenClaw 里能选择的模型</strong>取决于 <code>openclaw.json</code> 中 <code>agents.defaults.models</code> 的配置,与参考表并非一一对应</li>
<li>Cache Read/Write 留空表示不设单独缓存价:<strong>统一按 Input 原价计算</strong>(读取与写入都用 Input 单价)</li>
<li>修改后会自动保存到配置文件并失效聚合缓存,重新计算成本</li>
<li>支持<strong>通配符</strong>(如 <code>*/claude-*</code>)与<strong>正则</strong>(如 <code>/claude.*/i</code>)规则,按声明顺序匹配完整 <code>provider/model</code>;<strong>精确规则优先</strong></li>
</ul>
</div>
</div>
</div>
</h1>
</div>
<div class="actions">
<div class="locale-switch" role="group" aria-label="语言" data-i18n-attr="aria-label:common.languageGroup">
<button type="button" data-locale-control="zh-CN" title="中文" aria-label="中文">中</button>
<button type="button" data-locale-control="en-US" title="English" aria-label="English">EN</button>
</div>
<div class="theme-switch" role="group" aria-label="主题">
<button type="button" data-theme-control="light" title="浅色">🌞</button>
<button type="button" data-theme-control="dark" title="深色">🌙</button>
<button type="button" data-theme-control="system" title="跟随系统">💻</button>
</div>
<button id="reset-pricing-btn" class="btn-secondary" data-i18n="pricing.reset">重置</button>
</div>
</div>
<div id="pricing-config-stack" class="pricing-config-stack">
<!-- 已配置价格 -->
<div class="glass-card">
<h3 style="margin-bottom: 15px;">已配置价格</h3>
<table id="pricing-table">
<colgroup>
<col class="pricing-col-enable" />
<col class="pricing-col-model" />
<col class="pricing-col-match" />
<col class="pricing-col-num" />
<col class="pricing-col-num" />
<col class="pricing-col-cache" />
<col class="pricing-col-cache" />
<col class="pricing-col-action" />
</colgroup>
<thead>
<tr>
<th class="col-center">启用</th>
<th>Provider/Model</th>
<th class="col-center">类型</th>
<th class="col-numeric">Input</th>
<th class="col-numeric">Output</th>
<th class="col-numeric">Cache Read</th>
<th class="col-numeric">Cache Write</th>
<th class="col-center">操作</th>
</tr>
</thead>
<tbody id="pricing-tbody"></tbody>
</table>
</div>
<!-- 添加新价格 -->
<div id="add-pricing-section" class="glass-card" style="margin-top: 20px;">
<h3 style="margin-bottom: 15px;">添加新价格</h3>
<div class="pricing-add-row">
<div class="pricing-add-combobox-wrap">
<input
type="text"
id="new-model-input"
class="pricing-add-combobox"
list="new-model-datalist"
placeholder="选择或输入 provider/model(通配符/正则下可填模式)"
autocomplete="off"
aria-label="模型或匹配模式"
/>
<button type="button" id="new-model-clear" class="pricing-input-clear" aria-label="清空" hidden>
×
</button>
</div>
<datalist id="new-model-datalist"></datalist>
<select id="new-match-type" title="精确:与会话键完全一致;通配符/正则:匹配整串 provider/model">
<option value="exact">精确</option>
<option value="wildcard">通配符</option>
<option value="regex">正则</option>
</select>
<input type="number" id="new-input-price" placeholder="Input" step="0.01" />
<input type="number" id="new-output-price" placeholder="Output" step="0.01" />
<input type="number" id="new-cache-read-price" class="pricing-input--cache" placeholder="留空按 Input 原价" title="留空时按该行 Input 单价计算 Cache Read 费用" step="0.01" />
<input type="number" id="new-cache-write-price" class="pricing-input--cache" placeholder="留空按 Input 原价" title="留空时按该行 Input 单价计算 Cache Write 费用" step="0.01" />
<button id="add-pricing-btn" class="btn-primary" type="button">添加</button>
<p id="new-pattern-hint" class="pricing-pattern-hint pricing-add-hint-full" hidden>
通配符:<code>*</code> 任意长度,<code>?</code> 单字符。正则:须以 <code>/</code> 开头,可为 <code>/pattern/flags</code>。
</p>
<p id="new-pattern-error" class="pricing-pattern-error pricing-add-hint-full" role="alert" hidden></p>
</div>
</div>
<!-- OpenClaw 内置价格参考(models.json 中有单价条目) -->
<div class="glass-card pricing-collapsible-card" style="margin-top: 20px;">
<button
type="button"
class="pricing-collapse-toggle"
id="openclaw-ref-collapse-toggle"
aria-expanded="false"
aria-controls="openclaw-ref-panel"
>
<span class="pricing-collapse-chevron" aria-hidden="true"></span>
<span class="pricing-collapse-heading">OpenClaw 内置价格(参考)</span>
</button>
<div id="openclaw-ref-panel" class="pricing-collapse-panel" hidden>
<p class="subtitle" style="margin-bottom: 15px;">
读取自 <code>$OPENCLAW_CONFIG_DIR/agents/main/agent/models.json</code>(未设置环境变量时默认为 <code>~/.openclaw/...</code>)中已声明有效 input/output 单价的模型。「已覆盖」表示上方自定义表中已有匹配该 <code>provider/model</code> 的规则(含通配符/正则)。<strong>实际在 OpenClaw 里能选择的模型</strong>取决于 <code>openclaw.json</code> 内 <code>agents.defaults.models</code> 的配置。
</p>
<div style="overflow-x: auto;">
<table id="openclaw-ref-table">
<thead>
<tr>
<th>Provider / Model</th>
<th>Input</th>
<th>Output</th>
<th>Cache Read</th>
<th>Cache Write</th>
<th>Context</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody id="openclaw-ref-tbody"></tbody>
</table>
</div>
<div id="openclaw-ref-pagination" class="table-pagination" aria-label="参考表分页"></div>
</div>
</div>
<!-- 缺少价格的模型(与上表同一 models.json,无有效单价) -->
<div class="glass-card pricing-collapsible-card" style="margin-top: 20px;">
<button
type="button"
class="pricing-collapse-toggle"
id="unpriced-models-collapse-toggle"
aria-expanded="false"
aria-controls="unpriced-models-panel"
>
<span class="pricing-collapse-chevron" aria-hidden="true"></span>
<span class="pricing-collapse-heading">缺少价格的模型(参考)</span>
</button>
<div id="unpriced-models-panel" class="pricing-collapse-panel" hidden>
<p class="subtitle" style="margin-bottom: 15px;">
与「内置价格」同一文件:列出其中尚未声明有效 input/output 单价的模型(两表互为补集)。「已覆盖」表示上方自定义表中已有匹配该 <code>provider/model</code> 的规则。<strong>实际在 OpenClaw 里能选择的模型</strong>取决于 <code>openclaw.json</code> 内 <code>agents.defaults.models</code> 的配置。
</p>
<div style="overflow-x: auto;">
<table id="unpriced-models-table">
<thead>
<tr>
<th>Provider / Model</th>
<th>名称</th>
<th>Context</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody id="unpriced-models-tbody"></tbody>
</table>
</div>
<div id="unpriced-models-pagination" class="table-pagination" aria-label="缺少价格表分页"></div>
</div>
</div>
</div>
</div>
<div id="pricing-toast" class="pricing-toast" role="status" aria-live="polite" hidden></div>
<script type="module" src="/src/pricing.js"></script>
</body>
</html>