coding-tool-x 3.5.8 → 3.5.10

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.
Files changed (91) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +4 -25
  3. package/bin/ctx.js +1 -6
  4. package/dist/web/assets/{Analytics-BzoNzfbi.js → Analytics-DPb1zErn.js} +2 -2
  5. package/dist/web/assets/Analytics-RNn1BUbG.css +1 -0
  6. package/dist/web/assets/{ConfigTemplates-O4ikBt1o.js → ConfigTemplates-Bki2k4Lo.js} +1 -1
  7. package/dist/web/assets/{Home-BQjsnblU.js → Home-BKYHKSax.js} +1 -1
  8. package/dist/web/assets/Home-BQxQ1LhR.css +1 -0
  9. package/dist/web/assets/{PluginManager-DS_DJnVc.js → PluginManager-jgeQOE24.js} +1 -1
  10. package/dist/web/assets/ProjectList-CF67RzP_.js +1 -0
  11. package/dist/web/assets/ProjectList-DL4JK6ci.css +1 -0
  12. package/dist/web/assets/SessionList-DhHsY5q9.js +1 -0
  13. package/dist/web/assets/SessionList-lz23U6ZJ.css +1 -0
  14. package/dist/web/assets/{SkillManager-DpNE02r0.js → SkillManager-CtEz5gGp.js} +1 -1
  15. package/dist/web/assets/{WorkspaceManager-DMY7_SHh.js → WorkspaceManager-D3B0Y5XE.js} +1 -1
  16. package/dist/web/assets/icons-lKCTySl7.js +1 -0
  17. package/dist/web/assets/index-BS7aplYp.css +1 -0
  18. package/dist/web/assets/index-BnyNm74G.js +2 -0
  19. package/dist/web/assets/{markdown-DyTJGI4N.js → markdown-BNJfEgCA.js} +1 -1
  20. package/dist/web/assets/{naive-ui-Cg4_ZeoT.js → naive-ui-DM897mIP.js} +1 -1
  21. package/dist/web/assets/vendors-DQA4Hw9v.js +7 -0
  22. package/dist/web/assets/vue-vendor-B5RqjEjQ.js +45 -0
  23. package/dist/web/index.html +8 -8
  24. package/package.json +1 -2
  25. package/src/commands/daemon.js +5 -33
  26. package/src/commands/export-config.js +6 -6
  27. package/src/commands/stats.js +4 -41
  28. package/src/commands/ui.js +3 -12
  29. package/src/config/channel-preset-websites.js +114 -0
  30. package/src/config/default.js +9 -5
  31. package/src/config/loader.js +2 -2
  32. package/src/config/model-metadata.json +16 -20
  33. package/src/config/paths.js +33 -166
  34. package/src/index.js +34 -125
  35. package/src/server/api/agents.js +2 -52
  36. package/src/server/api/codex-proxy.js +4 -2
  37. package/src/server/api/codex-sessions.js +88 -9
  38. package/src/server/api/commands.js +2 -38
  39. package/src/server/api/dashboard.js +1 -25
  40. package/src/server/api/gemini-proxy.js +4 -2
  41. package/src/server/api/gemini-sessions.js +86 -9
  42. package/src/server/api/hooks.js +1 -17
  43. package/src/server/api/opencode-proxy.js +7 -2
  44. package/src/server/api/opencode-sessions.js +82 -7
  45. package/src/server/api/plugins.js +34 -128
  46. package/src/server/api/proxy.js +5 -3
  47. package/src/server/api/sessions.js +180 -24
  48. package/src/server/api/workspaces.js +0 -14
  49. package/src/server/index.js +9 -31
  50. package/src/server/services/agents-service.js +62 -269
  51. package/src/server/services/base/base-channel-service.js +3 -1
  52. package/src/server/services/channels.js +5 -0
  53. package/src/server/services/codex-channels.js +2 -0
  54. package/src/server/services/codex-sessions.js +78 -108
  55. package/src/server/services/commands-service.js +81 -281
  56. package/src/server/services/config-export-service.js +7 -7
  57. package/src/server/services/config-registry-service.js +9 -8
  58. package/src/server/services/config-sync-manager.js +41 -61
  59. package/src/server/services/config-sync-service.js +3 -3
  60. package/src/server/services/gemini-channels.js +17 -6
  61. package/src/server/services/gemini-config.js +4 -3
  62. package/src/server/services/gemini-sessions.js +51 -26
  63. package/src/server/services/gemini-settings-manager.js +3 -2
  64. package/src/server/services/mcp-service.js +14 -9
  65. package/src/server/services/native-oauth-adapters.js +3 -3
  66. package/src/server/services/network-access.js +2 -61
  67. package/src/server/services/notification-hooks.js +19 -184
  68. package/src/server/services/opencode-channels.js +9 -0
  69. package/src/server/services/opencode-sessions.js +4 -4
  70. package/src/server/services/opencode-settings-manager.js +3 -3
  71. package/src/server/services/plugins-service.js +62 -996
  72. package/src/server/services/prompts-service.js +9 -5
  73. package/src/server/services/sessions.js +128 -99
  74. package/src/server/services/skill-service.js +18 -155
  75. package/src/server/websocket-server.js +4 -35
  76. package/dist/web/assets/Analytics-vQS5IWvs.css +0 -1
  77. package/dist/web/assets/Home-qzk118Of.css +0 -1
  78. package/dist/web/assets/ProjectList-CqYDtsHx.js +0 -1
  79. package/dist/web/assets/ProjectList-GCC2QOmq.css +0 -1
  80. package/dist/web/assets/SessionList-CfPtcq6Y.css +0 -1
  81. package/dist/web/assets/SessionList-DMlLtMCz.js +0 -1
  82. package/dist/web/assets/icons-CEq2hYB-.js +0 -1
  83. package/dist/web/assets/index-Clf0l3wc.js +0 -2
  84. package/dist/web/assets/index-Dih_bOsv.css +0 -1
  85. package/dist/web/assets/vendors-Bsp-dq2d.js +0 -7
  86. package/dist/web/assets/vue-vendor-BxIT0uQq.js +0 -45
  87. package/docs/Caddyfile.example +0 -19
  88. package/docs/reverse-proxy-https.md +0 -57
  89. package/src/server/services/https-cert.js +0 -171
  90. package/src/server/services/session-launch-command.js +0 -81
  91. package/src/server/services/web-ui-runtime.js +0 -54
@@ -9,9 +9,6 @@ const TOOL_ENDPOINTS = {
9
9
  gemini: '/api/gemini/statistics',
10
10
  opencode: '/api/opencode/statistics'
11
11
  };
12
- const SHARED_TOOL_TYPE_BY_CLI = {
13
- claude: 'claude-code'
14
- };
15
12
 
16
13
  /**
17
14
  * HTTP 请求辅助函数
@@ -157,34 +154,6 @@ function extractSummary(stats) {
157
154
  return summary;
158
155
  }
159
156
 
160
- function extractToolSummary(stats, toolType) {
161
- const sharedToolType = SHARED_TOOL_TYPE_BY_CLI[toolType];
162
- if (!sharedToolType) {
163
- return extractSummary(stats);
164
- }
165
-
166
- // `/api/statistics/*` is shared across tools, so Claude must be scoped explicitly.
167
- const toolStats = stats?.byToolType?.[sharedToolType] || {};
168
- return extractSummary({
169
- summary: {
170
- requests: normalizeNumber(toolStats.requests),
171
- tokens: normalizeNumber(toolStats.tokens?.total),
172
- cost: normalizeNumber(toolStats.cost),
173
- inputTokens: normalizeNumber(toolStats.tokens?.input),
174
- outputTokens: normalizeNumber(toolStats.tokens?.output),
175
- cacheCreation: normalizeNumber(toolStats.tokens?.cacheCreation),
176
- cacheRead: normalizeNumber(toolStats.tokens?.cacheRead),
177
- reasoningTokens: normalizeNumber(toolStats.tokens?.reasoning),
178
- cachedTokens: normalizeNumber(toolStats.tokens?.cached)
179
- },
180
- global: {
181
- totalRequests: normalizeNumber(toolStats.requests),
182
- totalTokens: normalizeNumber(toolStats.tokens?.total),
183
- totalCost: normalizeNumber(toolStats.cost)
184
- }
185
- });
186
- }
187
-
188
157
  function mergeSummaries(target, source) {
189
158
  target.requests += normalizeNumber(source.requests);
190
159
  target.tokens += normalizeNumber(source.tokens);
@@ -212,12 +181,12 @@ async function fetchToolStats(toolType, timeRange) {
212
181
 
213
182
  if (timeRange === 'today') {
214
183
  const response = await httpRequest('GET', `${endpointBase}/today`);
215
- return extractToolSummary(response.data, toolType);
184
+ return extractSummary(response.data);
216
185
  }
217
186
 
218
187
  if (timeRange === 'all') {
219
188
  const response = await httpRequest('GET', `${endpointBase}/summary`);
220
- return extractToolSummary(response.data, toolType);
189
+ return extractSummary(response.data);
221
190
  }
222
191
 
223
192
  const days = getRangeDays(timeRange);
@@ -225,7 +194,7 @@ async function fetchToolStats(toolType, timeRange) {
225
194
  for (let i = 0; i < days; i++) {
226
195
  const date = getDateString(i);
227
196
  const response = await httpRequest('GET', `${endpointBase}/daily/${date}`);
228
- const dailySummary = extractToolSummary(response.data, toolType);
197
+ const dailySummary = extractSummary(response.data);
229
198
  mergeSummaries(merged, dailySummary);
230
199
  }
231
200
  return merged;
@@ -425,11 +394,5 @@ async function handleStatsExport(type = null, format = 'json') {
425
394
 
426
395
  module.exports = {
427
396
  handleStats,
428
- handleStatsExport,
429
- _test: {
430
- extractSummary,
431
- extractToolSummary,
432
- fetchToolStats,
433
- fetchOverallStats
434
- }
397
+ handleStatsExport
435
398
  };
@@ -3,7 +3,6 @@ const { startServer } = require('../server');
3
3
  const open = require('open');
4
4
  const { getProxyStatus } = require('../server/proxy-server');
5
5
  const { loadConfig } = require('../config/loader');
6
- const { isHttpsEnabled, getWebUiBaseUrl } = require('../server/services/web-ui-runtime');
7
6
 
8
7
  async function handleUI() {
9
8
  // 检查是否为 daemon 模式(PM2 启动)
@@ -12,8 +11,6 @@ async function handleUI() {
12
11
  // 检查是否启用 LAN 访问 (--host 标志)
13
12
  const enableHost = process.argv.includes('--host');
14
13
  const host = enableHost ? '0.0.0.0' : '127.0.0.1';
15
- const httpsEnabled = isHttpsEnabled();
16
- process.env.CC_TOOL_WEB_UI_PROTOCOL = httpsEnabled ? 'https' : 'http';
17
14
 
18
15
  if (!isDaemon) {
19
16
  console.clear();
@@ -21,21 +18,15 @@ async function handleUI() {
21
18
  if (enableHost) {
22
19
  console.log(chalk.yellow('[WARN] LAN 访问已启用 (--host)\n'));
23
20
  }
24
- if (httpsEnabled) {
25
- console.log(chalk.yellow('[LOCK] 已启用原生 HTTPS (--https)\n'));
26
- }
27
21
  }
28
22
 
29
23
  // 从配置加载端口
30
24
  const config = loadConfig();
31
25
  const port = config.ports?.webUI || 19999;
32
- const url = getWebUiBaseUrl(port, {
33
- https: httpsEnabled,
34
- hostname: httpsEnabled ? '127.0.0.1' : 'localhost'
35
- });
26
+ const url = `http://localhost:${port}`;
36
27
 
37
28
  try {
38
- await startServer(port, host, { https: httpsEnabled });
29
+ await startServer(port, host);
39
30
 
40
31
  // 自动打开浏览器(仅非 daemon 模式)
41
32
  if (!isDaemon) {
@@ -96,7 +87,7 @@ async function handleUI() {
96
87
  console.log(chalk.gray('按 Ctrl+C 停止服务器'));
97
88
  } else {
98
89
  // Daemon 模式:保持运行
99
- console.log(chalk.green(`[OK] Coding-Tool 服务已在后台启动 (${httpsEnabled ? 'HTTPS' : 'HTTP'}, 端口: ${port})`));
90
+ console.log(chalk.green(`[OK] Coding-Tool 服务已在后台启动 (端口: ${port})`));
100
91
  }
101
92
 
102
93
  } catch (error) {
@@ -0,0 +1,114 @@
1
+ const PRESET_WEBSITE_SOURCES = {
2
+ claude: [
3
+ { presetId: 'official', baseUrl: 'https://api.anthropic.com', websiteUrl: 'https://www.anthropic.com' },
4
+ { presetId: 'deepseek', baseUrl: 'https://api.deepseek.com/anthropic', websiteUrl: 'https://platform.deepseek.com' },
5
+ { presetId: 'zhipu', baseUrl: 'https://open.bigmodel.cn/api/anthropic', websiteUrl: 'https://open.bigmodel.cn' },
6
+ { presetId: 'kimi', baseUrl: 'https://api.moonshot.cn/anthropic', websiteUrl: 'https://platform.moonshot.cn' },
7
+ { presetId: 'minimax', baseUrl: 'https://api.minimaxi.com/anthropic', websiteUrl: 'https://platform.minimaxi.com' },
8
+ { presetId: 'qwen', baseUrl: 'https://dashscope.aliyuncs.com/api/v2/apps/claude-code-proxy', websiteUrl: 'https://bailian.console.aliyun.com' },
9
+ { presetId: 'doubao', baseUrl: 'https://ark.cn-beijing.volces.com/api/coding', websiteUrl: 'https://www.volcengine.com/product/doubao' }
10
+ ],
11
+ codex: [
12
+ { presetId: 'openai', baseUrl: 'https://api.openai.com/v1', websiteUrl: 'https://platform.openai.com' }
13
+ ],
14
+ gemini: [
15
+ { presetId: 'google', baseUrl: 'https://generativelanguage.googleapis.com/v1beta', websiteUrl: 'https://ai.google.dev' }
16
+ ],
17
+ opencode: [
18
+ { presetId: 'openrouter', baseUrl: 'https://openrouter.ai/api/v1', websiteUrl: 'https://openrouter.ai' },
19
+ { presetId: 'openai_api', baseUrl: 'https://api.openai.com/v1', websiteUrl: 'https://platform.openai.com' },
20
+ { presetId: 'anthropic_api', baseUrl: 'https://api.anthropic.com/v1', websiteUrl: 'https://console.anthropic.com' },
21
+ { presetId: 'deepseek', baseUrl: 'https://api.deepseek.com/v1', websiteUrl: 'https://platform.deepseek.com' },
22
+ { presetId: 'groq', baseUrl: 'https://api.groq.com/openai/v1', websiteUrl: 'https://console.groq.com' },
23
+ { presetId: 'together', baseUrl: 'https://api.together.xyz/v1', websiteUrl: 'https://www.together.ai' }
24
+ ]
25
+ };
26
+
27
+ function normalizeNonEmptyString(value) {
28
+ if (typeof value !== 'string') return '';
29
+ const trimmed = value.trim();
30
+ return trimmed || '';
31
+ }
32
+
33
+ function normalizePresetId(value) {
34
+ return normalizeNonEmptyString(value).toLowerCase();
35
+ }
36
+
37
+ function normalizeBaseUrl(value) {
38
+ const raw = normalizeNonEmptyString(value);
39
+ if (!raw) return '';
40
+
41
+ try {
42
+ const parsed = new URL(raw);
43
+ const pathname = parsed.pathname.replace(/\/+$/, '');
44
+ return `${parsed.protocol.toLowerCase()}//${parsed.host.toLowerCase()}${pathname}`;
45
+ } catch (_) {
46
+ return raw.replace(/\/+$/, '').toLowerCase();
47
+ }
48
+ }
49
+
50
+ function buildPresetWebsiteLookup() {
51
+ const lookup = {};
52
+
53
+ for (const [platform, entries] of Object.entries(PRESET_WEBSITE_SOURCES)) {
54
+ const byPresetId = {};
55
+ const byBaseUrl = {};
56
+
57
+ for (const entry of entries) {
58
+ const websiteUrl = normalizeNonEmptyString(entry.websiteUrl);
59
+ if (!websiteUrl) continue;
60
+
61
+ const presetId = normalizePresetId(entry.presetId);
62
+ if (presetId) {
63
+ byPresetId[presetId] = websiteUrl;
64
+ }
65
+
66
+ const baseUrl = normalizeBaseUrl(entry.baseUrl);
67
+ if (baseUrl) {
68
+ byBaseUrl[baseUrl] = websiteUrl;
69
+ }
70
+ }
71
+
72
+ lookup[platform] = { byPresetId, byBaseUrl };
73
+ }
74
+
75
+ return lookup;
76
+ }
77
+
78
+ const PRESET_WEBSITE_LOOKUP = buildPresetWebsiteLookup();
79
+
80
+ function resolveChannelWebsiteUrl(platform, channel = {}) {
81
+ const existingWebsiteUrl = normalizeNonEmptyString(channel.websiteUrl);
82
+ if (existingWebsiteUrl) {
83
+ return existingWebsiteUrl;
84
+ }
85
+
86
+ const platformKey = normalizePresetId(platform);
87
+ const lookup = PRESET_WEBSITE_LOOKUP[platformKey];
88
+ if (!lookup) {
89
+ return '';
90
+ }
91
+
92
+ const presetId = normalizePresetId(channel.presetId);
93
+ if (presetId && lookup.byPresetId[presetId]) {
94
+ return lookup.byPresetId[presetId];
95
+ }
96
+
97
+ const baseUrl = normalizeBaseUrl(channel.baseUrl);
98
+ if (baseUrl && lookup.byBaseUrl[baseUrl]) {
99
+ return lookup.byBaseUrl[baseUrl];
100
+ }
101
+
102
+ return '';
103
+ }
104
+
105
+ module.exports = {
106
+ PRESET_WEBSITE_SOURCES,
107
+ resolveChannelWebsiteUrl,
108
+ _test: {
109
+ PRESET_WEBSITE_LOOKUP,
110
+ normalizeBaseUrl,
111
+ normalizeNonEmptyString,
112
+ normalizePresetId
113
+ }
114
+ };
@@ -1,9 +1,13 @@
1
1
  // 默认配置
2
- const { NATIVE_PATHS } = require('./paths');
2
+ const path = require('path');
3
+ const os = require('os');
4
+ const { resolvePreferredHomeDir } = require('../utils/home-dir');
3
5
  const modelMetadataConfig = require('./model-metadata.json');
4
6
 
7
+ const HOME_DIR = resolvePreferredHomeDir(process.platform, process.env, os.homedir());
8
+
5
9
  const DEFAULT_CONFIG = {
6
- projectsDir: NATIVE_PATHS.claude.projects,
10
+ projectsDir: path.join(HOME_DIR, '.claude', 'projects'),
7
11
  defaultProject: null,
8
12
  maxDisplaySessions: 100,
9
13
  pageSize: 15,
@@ -41,7 +45,7 @@ const DEFAULT_CONFIG = {
41
45
  codex: {
42
46
  mode: 'auto',
43
47
  input: 2.5,
44
- output: 10,
48
+ output: 15,
45
49
  models: {
46
50
  'gpt-5-codex': { mode: 'auto' },
47
51
  'gpt-4o-mini': { mode: 'auto' }
@@ -50,7 +54,7 @@ const DEFAULT_CONFIG = {
50
54
  gemini: {
51
55
  mode: 'auto',
52
56
  input: 1.25,
53
- output: 5,
57
+ output: 10,
54
58
  models: {
55
59
  'gemini-2.5-pro': { mode: 'auto' },
56
60
  'gemini-2.5-flash': { mode: 'auto' }
@@ -59,7 +63,7 @@ const DEFAULT_CONFIG = {
59
63
  opencode: {
60
64
  mode: 'auto',
61
65
  input: 2.5,
62
- output: 10,
66
+ output: 15,
63
67
  models: {}
64
68
  }
65
69
  }
@@ -3,7 +3,7 @@ const fs = require('fs');
3
3
  const path = require('path');
4
4
  const os = require('os');
5
5
  const DEFAULT_CONFIG = require('./default');
6
- const { PATHS, ensureStorageDirMigrated, joinNativeBasePath } = require('./paths');
6
+ const { PATHS, ensureStorageDirMigrated } = require('./paths');
7
7
  const { resolvePreferredHomeDir } = require('../utils/home-dir');
8
8
  const eventBus = require('../plugins/event-bus');
9
9
 
@@ -11,7 +11,7 @@ const HOME_DIR = resolvePreferredHomeDir(process.platform, process.env, os.homed
11
11
 
12
12
  const LEGACY_CONFIG_FILES = [
13
13
  path.join(__dirname, '../../config.json'),
14
- joinNativeBasePath(HOME_DIR, '.claude', 'config.json')
14
+ path.join(HOME_DIR, '.claude', 'config.json')
15
15
  ];
16
16
 
17
17
  function getConfigFilePath() {
@@ -1,5 +1,5 @@
1
1
  {
2
- "lastUpdated": "2026-03-06",
2
+ "lastUpdated": "2026-04-19",
3
3
  "defaultModels": {
4
4
  "claude": [
5
5
  "claude-opus-4-6",
@@ -21,7 +21,6 @@
21
21
  "gpt-5"
22
22
  ],
23
23
  "gemini": [
24
- "gemini-3.1-pro",
25
24
  "gemini-3-pro-preview",
26
25
  "gemini-3-flash-preview",
27
26
  "gemini-2.5-pro",
@@ -39,7 +38,8 @@
39
38
  "claude-sonnet-4-6": "claude-sonnet-4-6",
40
39
  "claude-opus-4-5": "claude-opus-4-5-20251101",
41
40
  "claude-sonnet-4-5": "claude-sonnet-4-5-20250929",
42
- "claude-haiku-4-5": "claude-haiku-4-5-20251001"
41
+ "claude-haiku-4-5": "claude-haiku-4-5-20251001",
42
+ "gemini-3.1-pro": "gemini-3-pro-preview"
43
43
  },
44
44
  "models": {
45
45
  "claude-opus-4-6": {
@@ -64,55 +64,51 @@
64
64
  },
65
65
  "gpt-5": {
66
66
  "limit": { "context": 1000000, "output": 32768 },
67
- "pricing": { "input": 2, "output": 8 }
67
+ "pricing": { "input": 1.25, "output": 10 }
68
68
  },
69
69
  "gpt-5.1": {
70
70
  "limit": { "context": 1000000, "output": 32768 },
71
- "pricing": { "input": 2, "output": 8 }
71
+ "pricing": { "input": 1.25, "output": 10 }
72
72
  },
73
73
  "gpt-5.2": {
74
74
  "limit": { "context": 1000000, "output": 32768 },
75
- "pricing": { "input": 2, "output": 8 }
75
+ "pricing": { "input": 1.75, "output": 14 }
76
76
  },
77
77
  "gpt-5.4": {
78
78
  "limit": { "context": 1000000, "output": 32768 },
79
- "pricing": { "input": 2, "output": 8 }
79
+ "pricing": { "input": 2.5, "output": 15 }
80
80
  },
81
81
  "gpt-5-codex": {
82
82
  "limit": { "context": 1000000, "output": 32768 },
83
- "pricing": { "input": 2, "output": 8 }
83
+ "pricing": { "input": 1.25, "output": 10 }
84
84
  },
85
85
  "gpt-5.1-codex": {
86
86
  "limit": { "context": 1000000, "output": 32768 },
87
- "pricing": { "input": 2, "output": 8 }
87
+ "pricing": { "input": 1.25, "output": 10 }
88
88
  },
89
89
  "gpt-5.1-codex-mini": {
90
90
  "limit": { "context": 1000000, "output": 32768 },
91
- "pricing": { "input": 1.5, "output": 6 }
91
+ "pricing": { "input": 0.25, "output": 2 }
92
92
  },
93
93
  "gpt-5.1-codex-max": {
94
94
  "limit": { "context": 1000000, "output": 32768 },
95
- "pricing": { "input": 3, "output": 12 }
95
+ "pricing": { "input": 1.25, "output": 10 }
96
96
  },
97
97
  "gpt-5.2-codex": {
98
98
  "limit": { "context": 1000000, "output": 32768 },
99
- "pricing": { "input": 2, "output": 8 }
99
+ "pricing": { "input": 1.75, "output": 14 }
100
100
  },
101
101
  "gpt-5.3-codex": {
102
102
  "limit": { "context": 1000000, "output": 32768 },
103
- "pricing": { "input": 2, "output": 8 }
104
- },
105
- "gemini-3.1-pro": {
106
- "limit": { "context": 2097152, "output": 65536 },
107
- "pricing": { "input": 2.5, "output": 15 }
103
+ "pricing": { "input": 1.75, "output": 14 }
108
104
  },
109
105
  "gemini-3-pro-preview": {
110
106
  "limit": { "context": 2097152, "output": 65536 },
111
- "pricing": { "input": 2.5, "output": 15 }
107
+ "pricing": { "input": 2, "output": 12 }
112
108
  },
113
109
  "gemini-3-flash-preview": {
114
110
  "limit": { "context": 1048576, "output": 65536 },
115
- "pricing": { "input": 0.3, "output": 1.2 }
111
+ "pricing": { "input": 0.5, "output": 3 }
116
112
  },
117
113
  "gemini-2.5-pro": {
118
114
  "limit": { "context": 1048576, "output": 65536 },
@@ -120,7 +116,7 @@
120
116
  },
121
117
  "gemini-2.5-flash": {
122
118
  "limit": { "context": 1048576, "output": 65536 },
123
- "pricing": { "input": 0.15, "output": 0.6 }
119
+ "pricing": { "input": 0.3, "output": 2.5 }
124
120
  },
125
121
  "gemini-2.5-flash-lite": {
126
122
  "limit": { "context": 1048576, "output": 65536 },