coding-tool-x 3.6.1 → 3.6.2
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/dist/web/assets/{Analytics-DvWZOZ13.js → Analytics-DLEiiIbw.js} +1 -1
- package/dist/web/assets/{ConfigTemplates-DiuKu3LA.js → ConfigTemplates-BxEw8kS_.js} +1 -1
- package/dist/web/assets/{Home-DeGTc9uf.js → Home-Bk6Bsjmm.js} +1 -1
- package/dist/web/assets/{PluginManager-CljkN0Rb.js → PluginManager-PCYV0eXK.js} +1 -1
- package/dist/web/assets/{ProjectList-CFQJaSQ8.js → ProjectList-AU3SqUA9.js} +1 -1
- package/dist/web/assets/{SessionList-Fq4uQSQp.js → SessionList-DIXB0QPe.js} +1 -1
- package/dist/web/assets/{SkillManager-DLhg11LF.js → SkillManager-DfNofdEQ.js} +1 -1
- package/dist/web/assets/{WorkspaceManager-DXB4kE9p.js → WorkspaceManager-DPCSLn59.js} +1 -1
- package/dist/web/assets/index-C2yKfEbU.js +2 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/src/config/default.js +3 -0
- package/src/config/model-metadata.json +77 -34
- package/src/server/codex-proxy-server.js +4 -10
- package/src/server/gemini-proxy-server.js +9 -12
- package/src/server/opencode-proxy-server.js +4 -10
- package/src/server/services/gemini-sessions.js +5 -2
- package/src/server/services/model-detector.js +7 -0
- package/src/server/utils/pricing.js +26 -1
- package/dist/web/assets/index-CLra7uzu.js +0 -2
package/dist/web/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<link rel="icon" href="/favicon.ico">
|
|
6
6
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7
7
|
<title>coding-tool-x · AI 编程工作台</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/assets/index-C2yKfEbU.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/assets/markdown-BNJfEgCA.js">
|
|
10
10
|
<link rel="modulepreload" crossorigin href="/assets/vue-vendor-B5RqjEjQ.js">
|
|
11
11
|
<link rel="modulepreload" crossorigin href="/assets/naive-ui-DM897mIP.js">
|
package/package.json
CHANGED
package/src/config/default.js
CHANGED
|
@@ -46,6 +46,7 @@ const DEFAULT_CONFIG = {
|
|
|
46
46
|
mode: 'auto',
|
|
47
47
|
input: 2.5,
|
|
48
48
|
output: 15,
|
|
49
|
+
cacheRead: 0.25,
|
|
49
50
|
models: {
|
|
50
51
|
'gpt-5-codex': { mode: 'auto' },
|
|
51
52
|
'gpt-4o-mini': { mode: 'auto' }
|
|
@@ -55,6 +56,7 @@ const DEFAULT_CONFIG = {
|
|
|
55
56
|
mode: 'auto',
|
|
56
57
|
input: 1.25,
|
|
57
58
|
output: 10,
|
|
59
|
+
cacheRead: 0.125,
|
|
58
60
|
models: {
|
|
59
61
|
'gemini-2.5-pro': { mode: 'auto' },
|
|
60
62
|
'gemini-2.5-flash': { mode: 'auto' }
|
|
@@ -64,6 +66,7 @@ const DEFAULT_CONFIG = {
|
|
|
64
66
|
mode: 'auto',
|
|
65
67
|
input: 2.5,
|
|
66
68
|
output: 15,
|
|
69
|
+
cacheRead: 0.25,
|
|
67
70
|
models: {}
|
|
68
71
|
}
|
|
69
72
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"lastUpdated": "2026-
|
|
2
|
+
"lastUpdated": "2026-05-10",
|
|
3
3
|
"defaultModels": {
|
|
4
4
|
"claude": [
|
|
5
|
+
"claude-opus-4-7",
|
|
5
6
|
"claude-opus-4-6",
|
|
6
7
|
"claude-sonnet-4-6",
|
|
7
8
|
"claude-opus-4-5-20251101",
|
|
@@ -9,8 +10,11 @@
|
|
|
9
10
|
"claude-haiku-4-5-20251001"
|
|
10
11
|
],
|
|
11
12
|
"codex": [
|
|
13
|
+
"gpt-5.5",
|
|
12
14
|
"gpt-5.4",
|
|
15
|
+
"gpt-5.4-mini",
|
|
13
16
|
"gpt-5.3-codex",
|
|
17
|
+
"gpt-5.3-codex-spark",
|
|
14
18
|
"gpt-5.2-codex",
|
|
15
19
|
"gpt-5.1-codex-max",
|
|
16
20
|
"gpt-5.1-codex",
|
|
@@ -21,6 +25,8 @@
|
|
|
21
25
|
"gpt-5"
|
|
22
26
|
],
|
|
23
27
|
"gemini": [
|
|
28
|
+
"gemini-3.1-pro-preview",
|
|
29
|
+
"gemini-3.1-flash-preview",
|
|
24
30
|
"gemini-3-pro-preview",
|
|
25
31
|
"gemini-3-flash-preview",
|
|
26
32
|
"gemini-2.5-pro",
|
|
@@ -34,17 +40,26 @@
|
|
|
34
40
|
"gemini": "gemini-2.5-pro"
|
|
35
41
|
},
|
|
36
42
|
"aliases": {
|
|
43
|
+
"claude-opus-4-7": "claude-opus-4-7",
|
|
44
|
+
"claude-opus-4.7": "claude-opus-4-7",
|
|
37
45
|
"claude-opus-4-6": "claude-opus-4-6",
|
|
38
46
|
"claude-sonnet-4-6": "claude-sonnet-4-6",
|
|
39
47
|
"claude-opus-4-5": "claude-opus-4-5-20251101",
|
|
40
48
|
"claude-sonnet-4-5": "claude-sonnet-4-5-20250929",
|
|
41
49
|
"claude-haiku-4-5": "claude-haiku-4-5-20251001",
|
|
42
|
-
"gemini-3.1-pro": "gemini-3-pro-preview"
|
|
50
|
+
"gemini-3.1-pro": "gemini-3.1-pro-preview",
|
|
51
|
+
"gemini-3.1-pro-high": "gemini-3.1-pro-high",
|
|
52
|
+
"gemini-3.1-pro-low": "gemini-3.1-pro-low",
|
|
53
|
+
"gemini-3.1-flash": "gemini-3.1-flash-preview"
|
|
43
54
|
},
|
|
44
55
|
"models": {
|
|
56
|
+
"claude-opus-4-7": {
|
|
57
|
+
"limit": { "context": 1000000, "output": 128000 },
|
|
58
|
+
"pricing": { "input": 5, "output": 25, "cacheCreation": 6.25, "cacheRead": 0.5 }
|
|
59
|
+
},
|
|
45
60
|
"claude-opus-4-6": {
|
|
46
|
-
"limit": { "context":
|
|
47
|
-
"pricing": { "input":
|
|
61
|
+
"limit": { "context": 1000000, "output": 128000 },
|
|
62
|
+
"pricing": { "input": 5, "output": 25, "cacheCreation": 6.25, "cacheRead": 0.5 }
|
|
48
63
|
},
|
|
49
64
|
"claude-sonnet-4-6": {
|
|
50
65
|
"limit": { "context": 200000, "output": 64000 },
|
|
@@ -63,64 +78,92 @@
|
|
|
63
78
|
"pricing": { "input": 1, "output": 5, "cacheCreation": 1.25, "cacheRead": 0.1 }
|
|
64
79
|
},
|
|
65
80
|
"gpt-5": {
|
|
66
|
-
"limit": { "context":
|
|
67
|
-
"pricing": { "input": 1.25, "output": 10 }
|
|
81
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
82
|
+
"pricing": { "input": 1.25, "output": 10, "cacheRead": 0.125 }
|
|
68
83
|
},
|
|
69
84
|
"gpt-5.1": {
|
|
70
|
-
"limit": { "context":
|
|
71
|
-
"pricing": { "input": 1.25, "output": 10 }
|
|
85
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
86
|
+
"pricing": { "input": 1.25, "output": 10, "cacheRead": 0.125 }
|
|
72
87
|
},
|
|
73
88
|
"gpt-5.2": {
|
|
74
|
-
"limit": { "context":
|
|
75
|
-
"pricing": { "input": 1.75, "output": 14 }
|
|
89
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
90
|
+
"pricing": { "input": 1.75, "output": 14, "cacheRead": 0.175 }
|
|
91
|
+
},
|
|
92
|
+
"gpt-5.5": {
|
|
93
|
+
"limit": { "context": 1050000, "output": 128000 },
|
|
94
|
+
"pricing": { "input": 5, "output": 30, "cacheRead": 0.5 }
|
|
76
95
|
},
|
|
77
96
|
"gpt-5.4": {
|
|
78
|
-
"limit": { "context":
|
|
79
|
-
"pricing": { "input": 2.5, "output": 15 }
|
|
97
|
+
"limit": { "context": 1050000, "output": 128000 },
|
|
98
|
+
"pricing": { "input": 2.5, "output": 15, "cacheRead": 0.25 }
|
|
99
|
+
},
|
|
100
|
+
"gpt-5.4-mini": {
|
|
101
|
+
"limit": { "context": 400000, "output": 128000 },
|
|
102
|
+
"pricing": { "input": 0.75, "output": 4.5, "cacheRead": 0.075 }
|
|
80
103
|
},
|
|
81
104
|
"gpt-5-codex": {
|
|
82
|
-
"limit": { "context":
|
|
83
|
-
"pricing": { "input": 1.25, "output": 10 }
|
|
105
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
106
|
+
"pricing": { "input": 1.25, "output": 10, "cacheRead": 0.125 }
|
|
84
107
|
},
|
|
85
108
|
"gpt-5.1-codex": {
|
|
86
|
-
"limit": { "context":
|
|
87
|
-
"pricing": { "input": 1.25, "output": 10 }
|
|
109
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
110
|
+
"pricing": { "input": 1.25, "output": 10, "cacheRead": 0.125 }
|
|
88
111
|
},
|
|
89
112
|
"gpt-5.1-codex-mini": {
|
|
90
|
-
"limit": { "context":
|
|
91
|
-
"pricing": { "input": 0.25, "output": 2 }
|
|
113
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
114
|
+
"pricing": { "input": 0.25, "output": 2, "cacheRead": 0.025 }
|
|
92
115
|
},
|
|
93
116
|
"gpt-5.1-codex-max": {
|
|
94
|
-
"limit": { "context":
|
|
95
|
-
"pricing": { "input": 1.25, "output": 10 }
|
|
117
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
118
|
+
"pricing": { "input": 1.25, "output": 10, "cacheRead": 0.125 }
|
|
96
119
|
},
|
|
97
120
|
"gpt-5.2-codex": {
|
|
98
|
-
"limit": { "context":
|
|
99
|
-
"pricing": { "input": 1.75, "output": 14 }
|
|
121
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
122
|
+
"pricing": { "input": 1.75, "output": 14, "cacheRead": 0.175 }
|
|
100
123
|
},
|
|
101
124
|
"gpt-5.3-codex": {
|
|
102
|
-
"limit": { "context":
|
|
103
|
-
"pricing": { "input": 1.75, "output": 14 }
|
|
125
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
126
|
+
"pricing": { "input": 1.75, "output": 14, "cacheRead": 0.175 }
|
|
127
|
+
},
|
|
128
|
+
"gpt-5.3-codex-spark": {
|
|
129
|
+
"limit": { "context": 272000, "output": 128000 },
|
|
130
|
+
"pricing": { "input": 1.25, "output": 10, "cacheRead": 0.125 }
|
|
131
|
+
},
|
|
132
|
+
"gemini-3.1-pro-preview": {
|
|
133
|
+
"limit": { "context": 1048576, "output": 65536 },
|
|
134
|
+
"pricing": { "input": 2, "output": 12, "cacheRead": 0.2 }
|
|
135
|
+
},
|
|
136
|
+
"gemini-3.1-pro-high": {
|
|
137
|
+
"limit": { "context": 1048576, "output": 65536 },
|
|
138
|
+
"pricing": { "input": 2, "output": 12, "cacheRead": 0.2 }
|
|
139
|
+
},
|
|
140
|
+
"gemini-3.1-pro-low": {
|
|
141
|
+
"limit": { "context": 1048576, "output": 65536 },
|
|
142
|
+
"pricing": { "input": 2, "output": 12, "cacheRead": 0.2 }
|
|
143
|
+
},
|
|
144
|
+
"gemini-3.1-flash-preview": {
|
|
145
|
+
"limit": { "context": 1048576, "output": 65535 },
|
|
146
|
+
"pricing": { "input": 0.5, "output": 3, "cacheRead": 0.05 }
|
|
104
147
|
},
|
|
105
148
|
"gemini-3-pro-preview": {
|
|
106
|
-
"limit": { "context":
|
|
107
|
-
"pricing": { "input": 2, "output": 12 }
|
|
149
|
+
"limit": { "context": 1048576, "output": 65535 },
|
|
150
|
+
"pricing": { "input": 2, "output": 12, "cacheRead": 0.2 }
|
|
108
151
|
},
|
|
109
152
|
"gemini-3-flash-preview": {
|
|
110
|
-
"limit": { "context": 1048576, "output":
|
|
111
|
-
"pricing": { "input": 0.5, "output": 3 }
|
|
153
|
+
"limit": { "context": 1048576, "output": 65535 },
|
|
154
|
+
"pricing": { "input": 0.5, "output": 3, "cacheRead": 0.05 }
|
|
112
155
|
},
|
|
113
156
|
"gemini-2.5-pro": {
|
|
114
|
-
"limit": { "context": 1048576, "output":
|
|
115
|
-
"pricing": { "input": 1.25, "output": 10 }
|
|
157
|
+
"limit": { "context": 1048576, "output": 65535 },
|
|
158
|
+
"pricing": { "input": 1.25, "output": 10, "cacheRead": 0.125 }
|
|
116
159
|
},
|
|
117
160
|
"gemini-2.5-flash": {
|
|
118
|
-
"limit": { "context": 1048576, "output":
|
|
119
|
-
"pricing": { "input": 0.3, "output": 2.5 }
|
|
161
|
+
"limit": { "context": 1048576, "output": 65535 },
|
|
162
|
+
"pricing": { "input": 0.3, "output": 2.5, "cacheRead": 0.03 }
|
|
120
163
|
},
|
|
121
164
|
"gemini-2.5-flash-lite": {
|
|
122
|
-
"limit": { "context": 1048576, "output":
|
|
123
|
-
"pricing": { "input": 0.1, "output": 0.4 }
|
|
165
|
+
"limit": { "context": 1048576, "output": 65535 },
|
|
166
|
+
"pricing": { "input": 0.1, "output": 0.4, "cacheRead": 0.01 }
|
|
124
167
|
}
|
|
125
168
|
}
|
|
126
169
|
}
|
|
@@ -7,7 +7,7 @@ const { allocateChannel, releaseChannel, getSchedulerState } = require('./servic
|
|
|
7
7
|
const { recordSuccess, recordFailure } = require('./services/channel-health');
|
|
8
8
|
const { loadConfig } = require('../config/loader');
|
|
9
9
|
const DEFAULT_CONFIG = require('../config/default');
|
|
10
|
-
const { resolveModelPricing } = require('./utils/pricing');
|
|
10
|
+
const { resolveModelPricing, calculateTokenCost } = require('./utils/pricing');
|
|
11
11
|
const { recordRequest: recordCodexRequest } = require('./services/codex-statistics-service');
|
|
12
12
|
const { saveProxyStartTime, clearProxyStartTime, getProxyStartTime, getProxyRuntime } = require('./services/proxy-runtime');
|
|
13
13
|
const { createDecodedStream } = require('./services/response-decoder');
|
|
@@ -52,7 +52,6 @@ const PRICING = {
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
const CODEX_BASE_PRICING = DEFAULT_CONFIG.pricing.codex;
|
|
55
|
-
const ONE_MILLION = 1000000;
|
|
56
55
|
|
|
57
56
|
// detectModelTier, redirectModel, resolveTargetUrl imported from services/base/proxy-utils
|
|
58
57
|
|
|
@@ -90,13 +89,7 @@ function calculateCost(model, tokens) {
|
|
|
90
89
|
}
|
|
91
90
|
|
|
92
91
|
const pricing = resolveModelPricing('codex', model, fallbackPricing, CODEX_BASE_PRICING);
|
|
93
|
-
|
|
94
|
-
const outputRate = typeof pricing.output === 'number' ? pricing.output : CODEX_BASE_PRICING.output;
|
|
95
|
-
|
|
96
|
-
return (
|
|
97
|
-
(tokens.input || 0) * inputRate / ONE_MILLION +
|
|
98
|
-
(tokens.output || 0) * outputRate / ONE_MILLION
|
|
99
|
-
);
|
|
92
|
+
return calculateTokenCost(pricing, tokens, CODEX_BASE_PRICING);
|
|
100
93
|
}
|
|
101
94
|
|
|
102
95
|
const jsonBodyParser = express.json({
|
|
@@ -598,5 +591,6 @@ module.exports = {
|
|
|
598
591
|
startCodexProxyServer,
|
|
599
592
|
stopCodexProxyServer,
|
|
600
593
|
getCodexProxyStatus,
|
|
601
|
-
clearCodexRedirectCache
|
|
594
|
+
clearCodexRedirectCache,
|
|
595
|
+
calculateCost
|
|
602
596
|
};
|
|
@@ -7,7 +7,7 @@ const { allocateChannel, releaseChannel, getSchedulerState } = require('./servic
|
|
|
7
7
|
const { recordSuccess, recordFailure } = require('./services/channel-health');
|
|
8
8
|
const { loadConfig } = require('../config/loader');
|
|
9
9
|
const DEFAULT_CONFIG = require('../config/default');
|
|
10
|
-
const { resolveModelPricing } = require('./utils/pricing');
|
|
10
|
+
const { resolveModelPricing, calculateTokenCost } = require('./utils/pricing');
|
|
11
11
|
const { recordRequest: recordGeminiRequest } = require('./services/gemini-statistics-service');
|
|
12
12
|
const { saveProxyStartTime, clearProxyStartTime, getProxyStartTime, getProxyRuntime } = require('./services/proxy-runtime');
|
|
13
13
|
const { createDecodedStream } = require('./services/response-decoder');
|
|
@@ -32,8 +32,9 @@ const printedGeminiRedirectCache = new Map();
|
|
|
32
32
|
// Gemini 模型定价(每百万 tokens 的价格,单位:美元)
|
|
33
33
|
// 作为 model-metadata 未覆盖时的兜底值
|
|
34
34
|
const PRICING = {
|
|
35
|
-
'gemini-2.5-pro': { input: 1.25, output:
|
|
36
|
-
'gemini-2.5-flash': { input: 0.
|
|
35
|
+
'gemini-2.5-pro': { input: 1.25, output: 10, cacheRead: 0.125 },
|
|
36
|
+
'gemini-2.5-flash': { input: 0.3, output: 2.5, cacheRead: 0.03 },
|
|
37
|
+
'gemini-2.5-flash-lite': { input: 0.1, output: 0.4, cacheRead: 0.01 },
|
|
37
38
|
'gemini-2.0-flash-exp': { input: 0, output: 0 }, // 实验性免费
|
|
38
39
|
'gemini-2.0-flash-thinking-exp-1219': { input: 0, output: 0 }, // 实验性免费
|
|
39
40
|
'gemini-1.5-pro': { input: 1.25, output: 5 },
|
|
@@ -46,7 +47,6 @@ const PRICING = {
|
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
const GEMINI_BASE_PRICING = DEFAULT_CONFIG.pricing.gemini;
|
|
49
|
-
const ONE_MILLION = 1000000;
|
|
50
50
|
|
|
51
51
|
// resolveGeminiTarget replaced by resolveTargetUrl from proxy-utils
|
|
52
52
|
const resolveGeminiTarget = resolveTargetUrl;
|
|
@@ -68,6 +68,8 @@ function calculateCost(model, tokens) {
|
|
|
68
68
|
const modelLower = String(model || '').toLowerCase();
|
|
69
69
|
if (modelLower.includes('gemini-2.5-pro')) {
|
|
70
70
|
fallbackPricing = PRICING['gemini-2.5-pro'];
|
|
71
|
+
} else if (modelLower.includes('gemini-2.5-flash-lite')) {
|
|
72
|
+
fallbackPricing = PRICING['gemini-2.5-flash-lite'];
|
|
71
73
|
} else if (modelLower.includes('gemini-2.5-flash')) {
|
|
72
74
|
fallbackPricing = PRICING['gemini-2.5-flash'];
|
|
73
75
|
} else if (modelLower.includes('gemini-2.0-flash-thinking')) {
|
|
@@ -88,13 +90,7 @@ function calculateCost(model, tokens) {
|
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
const pricing = resolveModelPricing('gemini', model, fallbackPricing, GEMINI_BASE_PRICING);
|
|
91
|
-
|
|
92
|
-
const outputRate = typeof pricing.output === 'number' ? pricing.output : GEMINI_BASE_PRICING.output;
|
|
93
|
-
|
|
94
|
-
return (
|
|
95
|
-
(tokens.input || 0) * inputRate / ONE_MILLION +
|
|
96
|
-
(tokens.output || 0) * outputRate / ONE_MILLION
|
|
97
|
-
);
|
|
93
|
+
return calculateTokenCost(pricing, tokens, GEMINI_BASE_PRICING);
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
// 启动 Gemini 代理服务器
|
|
@@ -571,5 +567,6 @@ module.exports = {
|
|
|
571
567
|
startGeminiProxyServer,
|
|
572
568
|
stopGeminiProxyServer,
|
|
573
569
|
getGeminiProxyStatus,
|
|
574
|
-
clearGeminiRedirectCache
|
|
570
|
+
clearGeminiRedirectCache,
|
|
571
|
+
calculateCost
|
|
575
572
|
};
|
|
@@ -14,7 +14,7 @@ const { recordSuccess, recordFailure } = require('./services/channel-health');
|
|
|
14
14
|
const { loadConfig } = require('../config/loader');
|
|
15
15
|
const DEFAULT_CONFIG = require('../config/default');
|
|
16
16
|
const { PATHS, ensureStorageDirMigrated } = require('../config/paths');
|
|
17
|
-
const { resolveModelPricing } = require('./utils/pricing');
|
|
17
|
+
const { resolveModelPricing, calculateTokenCost } = require('./utils/pricing');
|
|
18
18
|
const { recordRequest: recordOpenCodeRequest } = require('./services/opencode-statistics-service');
|
|
19
19
|
const { saveProxyStartTime, clearProxyStartTime, getProxyStartTime, getProxyRuntime } = require('./services/proxy-runtime');
|
|
20
20
|
const { getEnabledChannels, getEffectiveApiKey } = require('./services/opencode-channels');
|
|
@@ -58,7 +58,6 @@ const PRICING = {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
const OPENCODE_BASE_PRICING = DEFAULT_CONFIG.pricing.opencode || DEFAULT_CONFIG.pricing.codex;
|
|
61
|
-
const ONE_MILLION = 1000000;
|
|
62
61
|
const CLAUDE_CODE_USER_AGENT = 'claude-cli/2.1.59 (external, cli)';
|
|
63
62
|
const CLAUDE_MESSAGES_BETA_FLAGS = Object.freeze([
|
|
64
63
|
'claude-code-20250219',
|
|
@@ -133,13 +132,7 @@ function calculateCost(model, tokens) {
|
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
const pricing = resolveModelPricing('opencode', model, fallbackPricing, OPENCODE_BASE_PRICING);
|
|
136
|
-
|
|
137
|
-
const outputRate = typeof pricing.output === 'number' ? pricing.output : OPENCODE_BASE_PRICING.output;
|
|
138
|
-
|
|
139
|
-
return (
|
|
140
|
-
(tokens.input || 0) * inputRate / ONE_MILLION +
|
|
141
|
-
(tokens.output || 0) * outputRate / ONE_MILLION
|
|
142
|
-
);
|
|
135
|
+
return calculateTokenCost(pricing, tokens, OPENCODE_BASE_PRICING);
|
|
143
136
|
}
|
|
144
137
|
|
|
145
138
|
const jsonBodyParser = express.json({
|
|
@@ -4741,5 +4734,6 @@ module.exports = {
|
|
|
4741
4734
|
stopOpenCodeProxyServer,
|
|
4742
4735
|
getOpenCodeProxyStatus,
|
|
4743
4736
|
clearOpenCodeRedirectCache,
|
|
4744
|
-
collectProxyModelList
|
|
4737
|
+
collectProxyModelList,
|
|
4738
|
+
calculateCost
|
|
4745
4739
|
};
|
|
@@ -3,6 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
const { HOME_DIR } = require('../../config/paths');
|
|
5
5
|
const { getGeminiDir } = require('./gemini-config');
|
|
6
|
+
const { resolveModelPricing } = require('../utils/pricing');
|
|
6
7
|
|
|
7
8
|
// 路径映射缓存
|
|
8
9
|
let pathMappingCache = null;
|
|
@@ -228,8 +229,10 @@ function readSessionMeta(filePath) {
|
|
|
228
229
|
model = msg.model;
|
|
229
230
|
const inputTokens = msg.tokens.input || 0;
|
|
230
231
|
const outputTokens = msg.tokens.output || 0;
|
|
231
|
-
|
|
232
|
-
|
|
232
|
+
const pricing = resolveModelPricing('gemini', msg.model);
|
|
233
|
+
const inputRate = typeof pricing.input === 'number' ? pricing.input : 1.25;
|
|
234
|
+
const outputRate = typeof pricing.output === 'number' ? pricing.output : 10;
|
|
235
|
+
totalCost += (inputTokens * inputRate / 1000000) + (outputTokens * outputRate / 1000000);
|
|
233
236
|
}
|
|
234
237
|
}
|
|
235
238
|
});
|
|
@@ -16,6 +16,7 @@ const { PATHS } = require('../../config/paths');
|
|
|
16
16
|
// 内置模型优先级(当配置缺失时兜底)
|
|
17
17
|
const MODEL_PRIORITY = {
|
|
18
18
|
claude: [
|
|
19
|
+
'claude-opus-4-7',
|
|
19
20
|
'claude-opus-4-6',
|
|
20
21
|
'claude-sonnet-4-6',
|
|
21
22
|
'claude-opus-4-5-20251101',
|
|
@@ -23,7 +24,11 @@ const MODEL_PRIORITY = {
|
|
|
23
24
|
'claude-haiku-4-5-20251001'
|
|
24
25
|
],
|
|
25
26
|
codex: [
|
|
27
|
+
'gpt-5.5',
|
|
26
28
|
'gpt-5.4',
|
|
29
|
+
'gpt-5.4-mini',
|
|
30
|
+
'gpt-5.3-codex',
|
|
31
|
+
'gpt-5.3-codex-spark',
|
|
27
32
|
'gpt-5.2-codex',
|
|
28
33
|
'gpt-5.1-codex-max',
|
|
29
34
|
'gpt-5.1-codex',
|
|
@@ -34,6 +39,8 @@ const MODEL_PRIORITY = {
|
|
|
34
39
|
'gpt-5'
|
|
35
40
|
],
|
|
36
41
|
gemini: [
|
|
42
|
+
'gemini-3.1-pro-preview',
|
|
43
|
+
'gemini-3.1-flash-preview',
|
|
37
44
|
'gemini-3-pro-preview',
|
|
38
45
|
'gemini-3-flash-preview',
|
|
39
46
|
'gemini-2.5-pro',
|
|
@@ -67,7 +67,32 @@ function resolveModelPricing(_toolKey, model, fallbackPricing = {}, defaultPrici
|
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
function getRate(pricing, defaultPricing, key) {
|
|
71
|
+
if (typeof pricing?.[key] === 'number') return pricing[key];
|
|
72
|
+
if (typeof defaultPricing?.[key] === 'number') return defaultPricing[key];
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function calculateTokenCost(pricing = {}, tokens = {}, defaultPricing = {}) {
|
|
77
|
+
const inputRate = getRate(pricing, defaultPricing, 'input');
|
|
78
|
+
const outputRate = getRate(pricing, defaultPricing, 'output');
|
|
79
|
+
const cacheCreationRate = getRate(pricing, defaultPricing, 'cacheCreation');
|
|
80
|
+
const cacheReadRate = getRate(pricing, defaultPricing, 'cacheRead');
|
|
81
|
+
const inputTokens = Number(tokens.input || 0);
|
|
82
|
+
const outputTokens = Number(tokens.output || 0);
|
|
83
|
+
const cacheCreationTokens = Number(tokens.cacheCreation || 0);
|
|
84
|
+
const cacheReadTokens = Number(tokens.cacheRead || tokens.cached || 0);
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
inputTokens * inputRate / 1000000 +
|
|
88
|
+
outputTokens * outputRate / 1000000 +
|
|
89
|
+
cacheCreationTokens * cacheCreationRate / 1000000 +
|
|
90
|
+
cacheReadTokens * cacheReadRate / 1000000
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
70
94
|
module.exports = {
|
|
71
95
|
resolvePricing,
|
|
72
|
-
resolveModelPricing
|
|
96
|
+
resolveModelPricing,
|
|
97
|
+
calculateTokenCost
|
|
73
98
|
};
|