codeep 2.11.2 → 2.13.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/dist/api/index.js +3 -1
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.js +1 -0
- package/dist/config/providers.d.ts +64 -0
- package/dist/config/providers.js +373 -2
- package/dist/renderer/App.js +11 -1
- package/dist/renderer/commands.js +55 -4
- package/dist/renderer/components/Settings.js +13 -0
- package/dist/renderer/components/Status.d.ts +3 -0
- package/dist/renderer/main.js +7 -1
- package/dist/utils/agentChat.js +24 -6
- package/dist/utils/commandIndex.d.ts +16 -0
- package/dist/utils/commandIndex.js +29 -0
- package/dist/utils/mcpMarketplace.d.ts +3 -1
- package/dist/utils/mcpMarketplace.js +22 -6
- package/dist/utils/tokenTracker.js +37 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/api/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import * as http from 'node:http';
|
|
|
2
2
|
import * as https from 'node:https';
|
|
3
3
|
import { config, getApiKey, resolveBaseUrl } from '../config/index.js';
|
|
4
4
|
import { withRetry, isNetworkError } from '../utils/retry.js';
|
|
5
|
-
import { getProvider, getProviderBaseUrl, getProviderAuthHeader, usesMaxCompletionTokens, requiresDefaultTemperature, modelRejectsSamplingParams } from '../config/providers.js';
|
|
5
|
+
import { getProvider, getProviderBaseUrl, getProviderAuthHeader, usesMaxCompletionTokens, requiresDefaultTemperature, modelRejectsSamplingParams, reasoningParamsFor } from '../config/providers.js';
|
|
6
6
|
import { logApiRequest, logApiResponse } from '../utils/logger.js';
|
|
7
7
|
import { loadProjectIntelligence, generateContextFromIntelligence } from '../utils/projectIntelligence.js';
|
|
8
8
|
import { loadProjectRules } from '../utils/agent.js';
|
|
@@ -390,6 +390,7 @@ async function chatOpenAI(message, history, model, apiKey, onChunk, abortSignal)
|
|
|
390
390
|
...(stream ? { stream_options: { include_usage: true } } : {}),
|
|
391
391
|
...(omitTemperature ? {} : { temperature }),
|
|
392
392
|
...(useCompletionTokens ? { max_completion_tokens: maxTokens } : { max_tokens: maxTokens }),
|
|
393
|
+
...reasoningParamsFor(providerId, model, config.get('reasoningEffort')),
|
|
393
394
|
...(providerId === 'openrouter' ? { usage: { include: true } } : {}),
|
|
394
395
|
...(openRouterProvider ? { provider: openRouterProvider } : {}),
|
|
395
396
|
});
|
|
@@ -658,6 +659,7 @@ async function chatAnthropic(message, history, model, apiKey, onChunk, abortSign
|
|
|
658
659
|
// Fable 5 / Opus 4.7+ reject temperature with a 400 — omit it there
|
|
659
660
|
// (omission means API default on every Claude model).
|
|
660
661
|
...(modelRejectsSamplingParams(model) ? {} : { temperature }),
|
|
662
|
+
...reasoningParamsFor(providerId, model, config.get('reasoningEffort')),
|
|
661
663
|
stream,
|
|
662
664
|
...cachedSystem,
|
|
663
665
|
}),
|
package/dist/config/index.d.ts
CHANGED
|
@@ -52,6 +52,11 @@ interface ConfigSchema {
|
|
|
52
52
|
migrationVersion: number;
|
|
53
53
|
temperature: number;
|
|
54
54
|
maxTokens: number;
|
|
55
|
+
/** Thinking / reasoning-effort tier sent with each request. 'auto' (default)
|
|
56
|
+
* omits the param so each model uses its own default; low/medium/high/max are
|
|
57
|
+
* clamped per provider+model by reasoningParamsFor() (config/providers.ts).
|
|
58
|
+
* Only applied for models that expose a graded knob — set via `/thinking`. */
|
|
59
|
+
reasoningEffort: 'auto' | 'low' | 'medium' | 'high' | 'max';
|
|
55
60
|
apiTimeout: number;
|
|
56
61
|
rateLimitApi: number;
|
|
57
62
|
rateLimitCommands: number;
|
package/dist/config/index.js
CHANGED
|
@@ -26,6 +26,10 @@ export interface ProviderConfig {
|
|
|
26
26
|
maxOutputTokens?: number;
|
|
27
27
|
useMaxCompletionTokens?: boolean;
|
|
28
28
|
requiresDefaultTemperature?: boolean;
|
|
29
|
+
/** Provider's OpenAI-compatible endpoint rejects `tools` together with
|
|
30
|
+
* `stream: true` (Alibaba/Qwen DashScope). When true, agent turns that send
|
|
31
|
+
* tools are issued non-streamed (we buffer the full response). */
|
|
32
|
+
noStreamWithTools?: boolean;
|
|
29
33
|
envKey?: string;
|
|
30
34
|
subscribeUrl?: string;
|
|
31
35
|
noApiKey?: boolean;
|
|
@@ -68,9 +72,69 @@ export declare function usesMaxCompletionTokens(providerId: string): boolean;
|
|
|
68
72
|
* (e.g. OpenAI GPT-5+ only accepts the default of 1).
|
|
69
73
|
*/
|
|
70
74
|
export declare function requiresDefaultTemperature(providerId: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Returns true if the provider's OpenAI-compatible endpoint rejects `tools`
|
|
77
|
+
* together with `stream: true` (Alibaba/Qwen) — callers must issue tool-bearing
|
|
78
|
+
* agent turns non-streamed.
|
|
79
|
+
*/
|
|
80
|
+
export declare function providerNoStreamWithTools(providerId: string): boolean;
|
|
71
81
|
export declare function modelRejectsSamplingParams(model: string): boolean;
|
|
72
82
|
/**
|
|
73
83
|
* Returns the effective max output tokens for a provider, capped by the provider's limit.
|
|
74
84
|
* Falls back to the requested value if no provider limit is set.
|
|
75
85
|
*/
|
|
76
86
|
export declare function getEffectiveMaxTokens(providerId: string, requested: number): number;
|
|
87
|
+
/**
|
|
88
|
+
* Unified, user-facing thinking-effort tiers (the `/thinking` setting).
|
|
89
|
+
*
|
|
90
|
+
* 'auto' — omit the param entirely → each provider's own default.
|
|
91
|
+
* low / medium / high / max — four explicit depth tiers.
|
|
92
|
+
*
|
|
93
|
+
* The four tiers are CONCEPTUAL. `reasoningParamsFor()` clamps each one to the
|
|
94
|
+
* nearest level the active provider+model actually accepts, so we never send a
|
|
95
|
+
* value that would 400 (e.g. Gemini rejects "medium"; OpenAI has no "max").
|
|
96
|
+
* The control is a pure DEPTH knob on models that already think — it never
|
|
97
|
+
* toggles thinking on/off, which keeps us clear of the reasoning_content-replay
|
|
98
|
+
* contract that DeepSeek/GLM impose when thinking mode is flipped.
|
|
99
|
+
*/
|
|
100
|
+
export type ReasoningTier = 'auto' | 'low' | 'medium' | 'high' | 'max';
|
|
101
|
+
export declare const REASONING_TIERS: ReasoningTier[];
|
|
102
|
+
/**
|
|
103
|
+
* Canonicalize a model id for capability matching: lowercase, drop any
|
|
104
|
+
* `vendor/` namespace (OpenRouter sends `anthropic/claude-opus-4.8`), and
|
|
105
|
+
* normalize `.` version separators to `-` (`glm-5.2` → `glm-5-2`,
|
|
106
|
+
* `claude-opus-4.8` → `claude-opus-4-8`). Mirrors macOS `ModelTuning.canonicalModelID`.
|
|
107
|
+
*/
|
|
108
|
+
export declare function canonicalModelId(model: string): string;
|
|
109
|
+
/**
|
|
110
|
+
* Does this provider+model expose a GRADED thinking-effort control we can drive?
|
|
111
|
+
* Used to gate the `/thinking` UI — hidden entirely for models without one.
|
|
112
|
+
* Keep in lockstep with macOS `ModelTuning.reasoningEffortSupported`.
|
|
113
|
+
*/
|
|
114
|
+
export declare function modelSupportsReasoningEffort(providerId: string, model: string): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Build the request-body fields that carry the chosen effort tier for the
|
|
117
|
+
* active provider+model+protocol. Returns `{}` for 'auto', unsupported
|
|
118
|
+
* models, or providers without a graded knob — so callers can spread it
|
|
119
|
+
* unconditionally. Keep in lockstep with macOS `ModelTuning.reasoningParams`.
|
|
120
|
+
*/
|
|
121
|
+
export declare function reasoningParamsFor(providerId: string, model: string, tier: ReasoningTier): Record<string, unknown>;
|
|
122
|
+
/**
|
|
123
|
+
* The DISTINCT tiers a given provider+model actually exposes — used to build a
|
|
124
|
+
* per-model picker that only offers levels the model can tell apart (e.g.
|
|
125
|
+
* GLM-5.2/DeepSeek grade only high|max; Gemini via the OpenAI-compat layer only
|
|
126
|
+
* low|high). Always leads with 'auto'. `[]` for models with no graded knob.
|
|
127
|
+
*
|
|
128
|
+
* Kept in lockstep with `reasoningParamsFor` (the providers-test asserts every
|
|
129
|
+
* listed tier yields a DISTINCT param, so this can't silently drift). Mirrors
|
|
130
|
+
* macOS `ModelTuning.availableReasoningTiers`.
|
|
131
|
+
*/
|
|
132
|
+
export declare function availableReasoningTiers(providerId: string, model: string): ReasoningTier[];
|
|
133
|
+
/**
|
|
134
|
+
* Map a (possibly out-of-range) tier to the tier this model actually distinguishes,
|
|
135
|
+
* for display — the chip + the checked menu row. The effort setting is global, so
|
|
136
|
+
* a tier picked on Opus ('low') may not exist on GLM-5.2; we show the level GLM
|
|
137
|
+
* will really run (its 'low' clamps to 'high'). Picks the available tier whose
|
|
138
|
+
* effective param equals the requested one. 'auto' (or unsupported) → 'auto'.
|
|
139
|
+
*/
|
|
140
|
+
export declare function resolveReasoningTier(providerId: string, model: string, tier: ReasoningTier): ReasoningTier;
|
package/dist/config/providers.js
CHANGED
|
@@ -203,6 +203,196 @@ export const PROVIDERS = {
|
|
|
203
203
|
groupLabel: 'DeepSeek',
|
|
204
204
|
hint: 'Pay-per-use via DeepSeek API key (platform.deepseek.com).',
|
|
205
205
|
},
|
|
206
|
+
// ── Kimi (Moonshot AI) ────────────────────────────────────────────
|
|
207
|
+
// Subscription (Kimi Code) mirrors the Z.AI GLM-Coding-Plan shape: a
|
|
208
|
+
// dedicated coding base URL + a separate key, model id ALWAYS
|
|
209
|
+
// `kimi-for-coding` (a backend alias). OpenAI-compatible is the
|
|
210
|
+
// battle-tested path so we don't expose the Anthropic surface here.
|
|
211
|
+
'kimi': {
|
|
212
|
+
name: 'Kimi (Moonshot) — Coding Plan',
|
|
213
|
+
description: 'Kimi Code subscription',
|
|
214
|
+
protocols: {
|
|
215
|
+
openai: { baseUrl: 'https://api.kimi.com/coding/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
216
|
+
},
|
|
217
|
+
models: [
|
|
218
|
+
{ id: 'kimi-for-coding', name: 'Kimi Code', description: 'Subscription alias — auto-maps to the latest Kimi coding model (K2.7 Code)' },
|
|
219
|
+
],
|
|
220
|
+
defaultModel: 'kimi-for-coding',
|
|
221
|
+
defaultProtocol: 'openai',
|
|
222
|
+
maxOutputTokens: 32_768,
|
|
223
|
+
envKey: 'KIMI_CODE_API_KEY',
|
|
224
|
+
subscribeUrl: 'https://www.kimi.com/code',
|
|
225
|
+
groupLabel: 'Kimi — Subscription (Kimi Code)',
|
|
226
|
+
hint: 'Uses your Kimi Code subscription — no per-token charges. Key from kimi.com/code/console.',
|
|
227
|
+
},
|
|
228
|
+
'kimi-api': {
|
|
229
|
+
name: 'Kimi (Moonshot) API (pay-per-use)',
|
|
230
|
+
description: 'Moonshot AI Kimi models via API key',
|
|
231
|
+
protocols: {
|
|
232
|
+
openai: { baseUrl: 'https://api.moonshot.ai/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
233
|
+
},
|
|
234
|
+
models: [
|
|
235
|
+
{ id: 'kimi-k2.7-code', name: 'Kimi K2.7 Code', description: 'Flagship agentic coding model (256K context)' },
|
|
236
|
+
{ id: 'kimi-k2.7-code-highspeed', name: 'Kimi K2.7 Code (High-Speed)', description: 'Throughput-tuned K2.7 Code for latency-sensitive loops' },
|
|
237
|
+
{ id: 'kimi-k2.6', name: 'Kimi K2.6', description: 'Previous-gen multimodal reasoning model' },
|
|
238
|
+
{ id: 'kimi-k2.5', name: 'Kimi K2.5', description: 'Older general-purpose model (cheaper)' },
|
|
239
|
+
],
|
|
240
|
+
defaultModel: 'kimi-k2.7-code',
|
|
241
|
+
defaultProtocol: 'openai',
|
|
242
|
+
maxOutputTokens: 32_768,
|
|
243
|
+
envKey: 'MOONSHOT_API_KEY',
|
|
244
|
+
subscribeUrl: 'https://platform.kimi.ai/console/api-keys',
|
|
245
|
+
groupLabel: 'Kimi — API (pay-per-use)',
|
|
246
|
+
hint: 'Pay-per-use via Moonshot API key (platform.kimi.ai).',
|
|
247
|
+
},
|
|
248
|
+
'kimi-cn': {
|
|
249
|
+
name: 'Kimi China (Moonshot)',
|
|
250
|
+
description: 'Moonshot AI Kimi models (China)',
|
|
251
|
+
protocols: {
|
|
252
|
+
openai: { baseUrl: 'https://api.moonshot.cn/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
253
|
+
},
|
|
254
|
+
models: [
|
|
255
|
+
{ id: 'kimi-k2.7-code', name: 'Kimi K2.7 Code', description: 'Flagship agentic coding model (256K context)' },
|
|
256
|
+
{ id: 'kimi-k2.7-code-highspeed', name: 'Kimi K2.7 Code (High-Speed)', description: 'Throughput-tuned K2.7 Code' },
|
|
257
|
+
{ id: 'kimi-k2.6', name: 'Kimi K2.6', description: 'Previous-gen multimodal reasoning model' },
|
|
258
|
+
{ id: 'kimi-k2.5', name: 'Kimi K2.5', description: 'Older general-purpose model' },
|
|
259
|
+
],
|
|
260
|
+
defaultModel: 'kimi-k2.7-code',
|
|
261
|
+
defaultProtocol: 'openai',
|
|
262
|
+
maxOutputTokens: 32_768,
|
|
263
|
+
envKey: 'MOONSHOT_CN_API_KEY',
|
|
264
|
+
subscribeUrl: 'https://platform.moonshot.cn/console/api-keys',
|
|
265
|
+
groupLabel: 'Kimi China — API (pay-per-use)',
|
|
266
|
+
hint: 'Pay-per-use via Moonshot China API key (platform.moonshot.cn).',
|
|
267
|
+
},
|
|
268
|
+
// ── Grok (xAI) ────────────────────────────────────────────────────
|
|
269
|
+
// Pay-per-use today (console.x.ai key). The SuperGrok / X Premium+
|
|
270
|
+
// subscription is OAuth-based — added separately. Reasoning models
|
|
271
|
+
// require max_completion_tokens (like GPT-5), so useMaxCompletionTokens.
|
|
272
|
+
'grok': {
|
|
273
|
+
name: 'Grok (xAI)',
|
|
274
|
+
description: 'xAI Grok models',
|
|
275
|
+
protocols: {
|
|
276
|
+
openai: { baseUrl: 'https://api.x.ai/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
277
|
+
},
|
|
278
|
+
models: [
|
|
279
|
+
{ id: 'grok-build-0.1', name: 'Grok Build 0.1', description: 'Agentic coding model — fast, 256K context' },
|
|
280
|
+
{ id: 'grok-4.3', name: 'Grok 4.3', description: 'Flagship — highest quality, 1M context' },
|
|
281
|
+
{ id: 'grok-code-fast-1', name: 'Grok Code Fast 1', description: 'Low-cost speed-first coder (alias of Build 0.1)' },
|
|
282
|
+
{ id: 'grok-4-fast-reasoning', name: 'Grok 4 Fast (reasoning)', description: 'Cheap reasoning model, very large context' },
|
|
283
|
+
],
|
|
284
|
+
defaultModel: 'grok-build-0.1',
|
|
285
|
+
defaultProtocol: 'openai',
|
|
286
|
+
useMaxCompletionTokens: true, // reasoning models reject max_tokens
|
|
287
|
+
envKey: 'XAI_API_KEY',
|
|
288
|
+
subscribeUrl: 'https://console.x.ai',
|
|
289
|
+
groupLabel: 'xAI Grok',
|
|
290
|
+
hint: 'Pay-per-use via xAI API key (console.x.ai).',
|
|
291
|
+
},
|
|
292
|
+
// ── Qwen (Alibaba Model Studio / DashScope) ───────────────────────
|
|
293
|
+
// Coding Plan subscription = dedicated base URL + sk-sp- key (mirrors
|
|
294
|
+
// Z.AI). Qwen's OpenAI-compatible surface CANNOT combine tools with
|
|
295
|
+
// streaming, so all Qwen entries set noStreamWithTools.
|
|
296
|
+
'qwen': {
|
|
297
|
+
name: 'Qwen (Alibaba) — Coding Plan',
|
|
298
|
+
description: 'Qwen Coding Plan subscription',
|
|
299
|
+
protocols: {
|
|
300
|
+
openai: { baseUrl: 'https://coding-intl.dashscope.aliyuncs.com/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
301
|
+
},
|
|
302
|
+
models: [
|
|
303
|
+
{ id: 'qwen3-coder-plus', name: 'Qwen3-Coder Plus', description: 'Flagship coding model — best quality' },
|
|
304
|
+
{ id: 'qwen3-coder-next', name: 'Qwen3-Coder Next', description: 'Balanced quality/speed/cost' },
|
|
305
|
+
{ id: 'qwen3-max', name: 'Qwen3-Max', description: 'Flagship general model (code + reasoning)' },
|
|
306
|
+
],
|
|
307
|
+
defaultModel: 'qwen3-coder-plus',
|
|
308
|
+
defaultProtocol: 'openai',
|
|
309
|
+
maxOutputTokens: 65_536,
|
|
310
|
+
noStreamWithTools: true,
|
|
311
|
+
envKey: 'BAILIAN_CODING_PLAN_API_KEY',
|
|
312
|
+
subscribeUrl: 'https://www.alibabacloud.com/help/en/model-studio/qwen-code-coding-plan',
|
|
313
|
+
groupLabel: 'Qwen — Subscription (Coding Plan)',
|
|
314
|
+
hint: 'Uses your Qwen Coding Plan — no per-token charges. sk-sp-… key from Model Studio. Interactive coding use only.',
|
|
315
|
+
},
|
|
316
|
+
'qwen-api': {
|
|
317
|
+
name: 'Qwen (Alibaba) API (pay-per-use)',
|
|
318
|
+
description: 'Alibaba Model Studio Qwen models via API key',
|
|
319
|
+
protocols: {
|
|
320
|
+
openai: { baseUrl: 'https://dashscope-intl.aliyuncs.com/compatible-mode/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
321
|
+
},
|
|
322
|
+
models: [
|
|
323
|
+
{ id: 'qwen3-coder-plus', name: 'Qwen3-Coder Plus', description: 'Flagship coding model (256K, up to 1M)' },
|
|
324
|
+
{ id: 'qwen3-coder-next', name: 'Qwen3-Coder Next', description: 'Balanced quality/speed/cost' },
|
|
325
|
+
{ id: 'qwen3-coder-flash', name: 'Qwen3-Coder Flash', description: 'Fast/cheap coder' },
|
|
326
|
+
{ id: 'qwen3-max', name: 'Qwen3-Max', description: 'Flagship general model' },
|
|
327
|
+
],
|
|
328
|
+
defaultModel: 'qwen3-coder-plus',
|
|
329
|
+
defaultProtocol: 'openai',
|
|
330
|
+
maxOutputTokens: 65_536,
|
|
331
|
+
noStreamWithTools: true,
|
|
332
|
+
envKey: 'DASHSCOPE_API_KEY',
|
|
333
|
+
subscribeUrl: 'https://modelstudio.console.alibabacloud.com/',
|
|
334
|
+
groupLabel: 'Qwen — API (pay-per-use)',
|
|
335
|
+
hint: 'Pay-per-use via Alibaba Model Studio key (DASHSCOPE_API_KEY).',
|
|
336
|
+
},
|
|
337
|
+
'qwen-cn': {
|
|
338
|
+
name: 'Qwen China — Coding Plan',
|
|
339
|
+
description: 'Qwen Coding Plan subscription (China)',
|
|
340
|
+
protocols: {
|
|
341
|
+
openai: { baseUrl: 'https://coding.dashscope.aliyuncs.com/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
342
|
+
},
|
|
343
|
+
models: [
|
|
344
|
+
{ id: 'qwen3-coder-plus', name: 'Qwen3-Coder Plus', description: 'Flagship coding model — best quality' },
|
|
345
|
+
{ id: 'qwen3-coder-next', name: 'Qwen3-Coder Next', description: 'Balanced quality/speed/cost' },
|
|
346
|
+
{ id: 'qwen3-max', name: 'Qwen3-Max', description: 'Flagship general model' },
|
|
347
|
+
],
|
|
348
|
+
defaultModel: 'qwen3-coder-plus',
|
|
349
|
+
defaultProtocol: 'openai',
|
|
350
|
+
maxOutputTokens: 65_536,
|
|
351
|
+
noStreamWithTools: true,
|
|
352
|
+
envKey: 'BAILIAN_CODING_PLAN_CN_API_KEY',
|
|
353
|
+
subscribeUrl: 'https://bailian.console.aliyun.com/',
|
|
354
|
+
groupLabel: 'Qwen China — Subscription (Coding Plan)',
|
|
355
|
+
hint: 'Uses your Qwen Coding Plan (China). sk-sp-… key from Bailian.',
|
|
356
|
+
},
|
|
357
|
+
'qwen-cn-api': {
|
|
358
|
+
name: 'Qwen China API (pay-per-use)',
|
|
359
|
+
description: 'Alibaba Model Studio Qwen models via API key (China)',
|
|
360
|
+
protocols: {
|
|
361
|
+
openai: { baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
362
|
+
},
|
|
363
|
+
models: [
|
|
364
|
+
{ id: 'qwen3-coder-plus', name: 'Qwen3-Coder Plus', description: 'Flagship coding model' },
|
|
365
|
+
{ id: 'qwen3-coder-next', name: 'Qwen3-Coder Next', description: 'Balanced quality/speed/cost' },
|
|
366
|
+
{ id: 'qwen3-coder-flash', name: 'Qwen3-Coder Flash', description: 'Fast/cheap coder' },
|
|
367
|
+
{ id: 'qwen3-max', name: 'Qwen3-Max', description: 'Flagship general model' },
|
|
368
|
+
],
|
|
369
|
+
defaultModel: 'qwen3-coder-plus',
|
|
370
|
+
defaultProtocol: 'openai',
|
|
371
|
+
maxOutputTokens: 65_536,
|
|
372
|
+
noStreamWithTools: true,
|
|
373
|
+
envKey: 'DASHSCOPE_CN_API_KEY',
|
|
374
|
+
subscribeUrl: 'https://bailian.console.aliyun.com/',
|
|
375
|
+
groupLabel: 'Qwen China — API (pay-per-use)',
|
|
376
|
+
hint: 'Pay-per-use via Alibaba Model Studio China key.',
|
|
377
|
+
},
|
|
378
|
+
'modelscope': {
|
|
379
|
+
name: 'ModelScope (free Qwen)',
|
|
380
|
+
description: 'Free Qwen3-Coder inference via ModelScope',
|
|
381
|
+
protocols: {
|
|
382
|
+
openai: { baseUrl: 'https://api-inference.modelscope.cn/v1', authHeader: 'Bearer', supportsNativeTools: true },
|
|
383
|
+
},
|
|
384
|
+
models: [
|
|
385
|
+
{ id: 'Qwen/Qwen3-Coder-480B-A35B-Instruct', name: 'Qwen3-Coder 480B', description: 'Open MoE coder — free tier (~2000 req/day)' },
|
|
386
|
+
],
|
|
387
|
+
defaultModel: 'Qwen/Qwen3-Coder-480B-A35B-Instruct',
|
|
388
|
+
defaultProtocol: 'openai',
|
|
389
|
+
maxOutputTokens: 65_536,
|
|
390
|
+
noStreamWithTools: true,
|
|
391
|
+
envKey: 'MODELSCOPE_API_KEY',
|
|
392
|
+
subscribeUrl: 'https://modelscope.cn/my/myaccesstoken',
|
|
393
|
+
groupLabel: 'ModelScope — Free (Qwen)',
|
|
394
|
+
hint: 'Free tier (~2000 req/day) via ModelScope token (modelscope.cn). Needs a bound Aliyun account.',
|
|
395
|
+
},
|
|
206
396
|
'openai': {
|
|
207
397
|
name: 'OpenAI',
|
|
208
398
|
description: 'GPT and o-series models',
|
|
@@ -361,14 +551,24 @@ const DISPLAY_ORDER = [
|
|
|
361
551
|
'openrouter', // 100+ models, one key — surfaced high on purpose for 2.0.0.
|
|
362
552
|
'z.ai',
|
|
363
553
|
'z.ai-api',
|
|
554
|
+
'kimi',
|
|
555
|
+
'kimi-api',
|
|
556
|
+
'qwen',
|
|
557
|
+
'qwen-api',
|
|
558
|
+
'grok',
|
|
364
559
|
'deepseek',
|
|
365
560
|
'google',
|
|
366
561
|
'minimax',
|
|
367
562
|
'minimax-api',
|
|
563
|
+
'modelscope',
|
|
368
564
|
'ollama',
|
|
369
565
|
'custom',
|
|
566
|
+
// Regional + parameter-variant entries trail.
|
|
370
567
|
'z.ai-cn',
|
|
371
568
|
'z.ai-cn-api',
|
|
569
|
+
'kimi-cn',
|
|
570
|
+
'qwen-cn',
|
|
571
|
+
'qwen-cn-api',
|
|
372
572
|
'minimax-cn',
|
|
373
573
|
];
|
|
374
574
|
export function getProviderList() {
|
|
@@ -441,14 +641,26 @@ export function usesMaxCompletionTokens(providerId) {
|
|
|
441
641
|
export function requiresDefaultTemperature(providerId) {
|
|
442
642
|
return PROVIDERS[providerId]?.requiresDefaultTemperature ?? false;
|
|
443
643
|
}
|
|
644
|
+
/**
|
|
645
|
+
* Returns true if the provider's OpenAI-compatible endpoint rejects `tools`
|
|
646
|
+
* together with `stream: true` (Alibaba/Qwen) — callers must issue tool-bearing
|
|
647
|
+
* agent turns non-streamed.
|
|
648
|
+
*/
|
|
649
|
+
export function providerNoStreamWithTools(providerId) {
|
|
650
|
+
return PROVIDERS[providerId]?.noStreamWithTools ?? false;
|
|
651
|
+
}
|
|
444
652
|
/**
|
|
445
653
|
* Models that reject sampling parameters (temperature/top_p/top_k) with a 400.
|
|
446
654
|
* Anthropic removed them on Fable 5 and Opus 4.7+; older Claude models still
|
|
447
655
|
* accept them, so this must be a MODEL-level check, not a provider-level one
|
|
448
656
|
* (requiresDefaultTemperature can't express it). Omitting the field is always
|
|
449
|
-
* safe — the API treats omission as default.
|
|
657
|
+
* safe — the API treats omission as default. Kimi K2.x code/thinking models
|
|
658
|
+
* fix temperature internally and 400 on any custom value, so they're here too.
|
|
450
659
|
*/
|
|
451
|
-
const SAMPLING_PARAMS_REJECTED = [
|
|
660
|
+
const SAMPLING_PARAMS_REJECTED = [
|
|
661
|
+
'claude-fable-5', 'claude-opus-4-8', 'claude-opus-4-7',
|
|
662
|
+
'kimi-k2.7-code', 'kimi-for-coding',
|
|
663
|
+
];
|
|
452
664
|
export function modelRejectsSamplingParams(model) {
|
|
453
665
|
return SAMPLING_PARAMS_REJECTED.some(id => model === id || model.startsWith(`${id}-`));
|
|
454
666
|
}
|
|
@@ -462,3 +674,162 @@ export function getEffectiveMaxTokens(providerId, requested) {
|
|
|
462
674
|
return requested;
|
|
463
675
|
return Math.min(requested, provider.maxOutputTokens);
|
|
464
676
|
}
|
|
677
|
+
export const REASONING_TIERS = ['auto', 'low', 'medium', 'high', 'max'];
|
|
678
|
+
/**
|
|
679
|
+
* Canonicalize a model id for capability matching: lowercase, drop any
|
|
680
|
+
* `vendor/` namespace (OpenRouter sends `anthropic/claude-opus-4.8`), and
|
|
681
|
+
* normalize `.` version separators to `-` (`glm-5.2` → `glm-5-2`,
|
|
682
|
+
* `claude-opus-4.8` → `claude-opus-4-8`). Mirrors macOS `ModelTuning.canonicalModelID`.
|
|
683
|
+
*/
|
|
684
|
+
export function canonicalModelId(model) {
|
|
685
|
+
let id = model.toLowerCase();
|
|
686
|
+
const slash = id.lastIndexOf('/');
|
|
687
|
+
if (slash !== -1)
|
|
688
|
+
id = id.slice(slash + 1);
|
|
689
|
+
return id.replace(/\./g, '-');
|
|
690
|
+
}
|
|
691
|
+
/** True when `id` equals `prefix` or starts with `prefix-` (catches dated variants). */
|
|
692
|
+
function idMatches(id, prefix) {
|
|
693
|
+
return id === prefix || id.startsWith(`${prefix}-`);
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Does this provider+model expose a GRADED thinking-effort control we can drive?
|
|
697
|
+
* Used to gate the `/thinking` UI — hidden entirely for models without one.
|
|
698
|
+
* Keep in lockstep with macOS `ModelTuning.reasoningEffortSupported`.
|
|
699
|
+
*/
|
|
700
|
+
export function modelSupportsReasoningEffort(providerId, model) {
|
|
701
|
+
const id = canonicalModelId(model);
|
|
702
|
+
switch (providerId) {
|
|
703
|
+
case 'anthropic':
|
|
704
|
+
// Effort is GA on Opus 4.5+, Sonnet 4.6, Fable 5 — NOT Haiku or Sonnet 4.5.
|
|
705
|
+
if (idMatches(id, 'claude-haiku-4-5') || idMatches(id, 'claude-sonnet-4-5'))
|
|
706
|
+
return false;
|
|
707
|
+
return /^claude-(opus-4-([5-9]|\d\d)|sonnet-4-6|fable-5)/.test(id);
|
|
708
|
+
case 'openai':
|
|
709
|
+
// GPT-5.x are reasoning models — reasoning_effort across the family (incl. mini).
|
|
710
|
+
return id.startsWith('gpt-5');
|
|
711
|
+
case 'google':
|
|
712
|
+
// Gemini 3.x thinking_level via the OpenAI-compat reasoning_effort mapping.
|
|
713
|
+
return id.startsWith('gemini-3');
|
|
714
|
+
case 'deepseek':
|
|
715
|
+
return id.startsWith('deepseek-v4');
|
|
716
|
+
case 'z.ai':
|
|
717
|
+
case 'z.ai-api':
|
|
718
|
+
case 'z.ai-cn':
|
|
719
|
+
case 'z.ai-cn-api':
|
|
720
|
+
// GLM-5.2 added graded High/Max effort. glm-5-turbo is a plain thinking
|
|
721
|
+
// toggle (no graded levels) so it stays out.
|
|
722
|
+
return idMatches(id, 'glm-5-2');
|
|
723
|
+
case 'grok':
|
|
724
|
+
// Grok reasoning models accept reasoning_effort (none/low/medium/high).
|
|
725
|
+
// Explicit *-non-reasoning variants don't think → excluded.
|
|
726
|
+
return id.startsWith('grok') && !id.includes('non-reasoning');
|
|
727
|
+
// Kimi (thinking on/off, not graded) and Qwen coders (non-thinking) have
|
|
728
|
+
// no graded knob → fall through to default false.
|
|
729
|
+
case 'openrouter':
|
|
730
|
+
// OpenRouter normalizes a unified `reasoning` field and silently ignores
|
|
731
|
+
// it for non-reasoning models, so the control is always safe to expose.
|
|
732
|
+
return true;
|
|
733
|
+
default:
|
|
734
|
+
// minimax (toggle only), ollama, custom — no graded depth knob.
|
|
735
|
+
return false;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Build the request-body fields that carry the chosen effort tier for the
|
|
740
|
+
* active provider+model+protocol. Returns `{}` for 'auto', unsupported
|
|
741
|
+
* models, or providers without a graded knob — so callers can spread it
|
|
742
|
+
* unconditionally. Keep in lockstep with macOS `ModelTuning.reasoningParams`.
|
|
743
|
+
*/
|
|
744
|
+
export function reasoningParamsFor(providerId, model, tier) {
|
|
745
|
+
// 'auto', or any unexpected value from an older/garbled config, → no param.
|
|
746
|
+
// (Guards against ever emitting e.g. `effort: undefined`, which could 400.)
|
|
747
|
+
if (tier === 'auto' || !REASONING_TIERS.includes(tier))
|
|
748
|
+
return {};
|
|
749
|
+
if (!modelSupportsReasoningEffort(providerId, model))
|
|
750
|
+
return {};
|
|
751
|
+
switch (providerId) {
|
|
752
|
+
case 'anthropic':
|
|
753
|
+
// low / medium / high / max — all valid on the capable Claude models.
|
|
754
|
+
return { output_config: { effort: tier } };
|
|
755
|
+
case 'openai':
|
|
756
|
+
// none/low/medium/high/xhigh — no "max"; map our Max → xhigh (the ceiling).
|
|
757
|
+
return { reasoning_effort: tier === 'max' ? 'xhigh' : tier };
|
|
758
|
+
case 'google':
|
|
759
|
+
// Gemini 3 (OpenAI-compat) accepts ONLY low/high — "medium" 400s.
|
|
760
|
+
return { reasoning_effort: tier === 'low' ? 'low' : 'high' };
|
|
761
|
+
case 'deepseek':
|
|
762
|
+
case 'z.ai':
|
|
763
|
+
case 'z.ai-api':
|
|
764
|
+
case 'z.ai-cn':
|
|
765
|
+
case 'z.ai-cn-api':
|
|
766
|
+
// Graded thinking depth: high (default) or max. Lower tiers collapse to high.
|
|
767
|
+
return { reasoning_effort: tier === 'max' ? 'max' : 'high' };
|
|
768
|
+
case 'grok':
|
|
769
|
+
// none/low/medium/high — no "max"; map our Max → high (the ceiling).
|
|
770
|
+
return { reasoning_effort: tier === 'max' ? 'high' : tier };
|
|
771
|
+
case 'openrouter':
|
|
772
|
+
// Unified reasoning object; no "max" effort → cap at high.
|
|
773
|
+
return { reasoning: { effort: tier === 'max' ? 'high' : tier } };
|
|
774
|
+
default:
|
|
775
|
+
return {};
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* The DISTINCT tiers a given provider+model actually exposes — used to build a
|
|
780
|
+
* per-model picker that only offers levels the model can tell apart (e.g.
|
|
781
|
+
* GLM-5.2/DeepSeek grade only high|max; Gemini via the OpenAI-compat layer only
|
|
782
|
+
* low|high). Always leads with 'auto'. `[]` for models with no graded knob.
|
|
783
|
+
*
|
|
784
|
+
* Kept in lockstep with `reasoningParamsFor` (the providers-test asserts every
|
|
785
|
+
* listed tier yields a DISTINCT param, so this can't silently drift). Mirrors
|
|
786
|
+
* macOS `ModelTuning.availableReasoningTiers`.
|
|
787
|
+
*/
|
|
788
|
+
export function availableReasoningTiers(providerId, model) {
|
|
789
|
+
if (!modelSupportsReasoningEffort(providerId, model))
|
|
790
|
+
return [];
|
|
791
|
+
switch (providerId) {
|
|
792
|
+
case 'anthropic':
|
|
793
|
+
case 'openai':
|
|
794
|
+
return ['auto', 'low', 'medium', 'high', 'max'];
|
|
795
|
+
case 'google':
|
|
796
|
+
// OpenAI-compat layer accepts only low/high — "medium" 400s.
|
|
797
|
+
return ['auto', 'low', 'high'];
|
|
798
|
+
case 'deepseek':
|
|
799
|
+
case 'z.ai':
|
|
800
|
+
case 'z.ai-api':
|
|
801
|
+
case 'z.ai-cn':
|
|
802
|
+
case 'z.ai-cn-api':
|
|
803
|
+
return ['auto', 'high', 'max'];
|
|
804
|
+
case 'grok':
|
|
805
|
+
return ['auto', 'low', 'medium', 'high'];
|
|
806
|
+
case 'openrouter':
|
|
807
|
+
return ['auto', 'low', 'medium', 'high'];
|
|
808
|
+
default:
|
|
809
|
+
return [];
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Map a (possibly out-of-range) tier to the tier this model actually distinguishes,
|
|
814
|
+
* for display — the chip + the checked menu row. The effort setting is global, so
|
|
815
|
+
* a tier picked on Opus ('low') may not exist on GLM-5.2; we show the level GLM
|
|
816
|
+
* will really run (its 'low' clamps to 'high'). Picks the available tier whose
|
|
817
|
+
* effective param equals the requested one. 'auto' (or unsupported) → 'auto'.
|
|
818
|
+
*/
|
|
819
|
+
export function resolveReasoningTier(providerId, model, tier) {
|
|
820
|
+
if (tier === 'auto')
|
|
821
|
+
return 'auto';
|
|
822
|
+
const avail = availableReasoningTiers(providerId, model);
|
|
823
|
+
if (avail.length === 0)
|
|
824
|
+
return 'auto';
|
|
825
|
+
if (avail.includes(tier))
|
|
826
|
+
return tier;
|
|
827
|
+
const target = JSON.stringify(reasoningParamsFor(providerId, model, tier));
|
|
828
|
+
for (const t of avail) {
|
|
829
|
+
if (t === 'auto')
|
|
830
|
+
continue;
|
|
831
|
+
if (JSON.stringify(reasoningParamsFor(providerId, model, t)) === target)
|
|
832
|
+
return t;
|
|
833
|
+
}
|
|
834
|
+
return 'auto';
|
|
835
|
+
}
|
package/dist/renderer/App.js
CHANGED
|
@@ -66,7 +66,7 @@ const COMMAND_DESCRIPTIONS = {
|
|
|
66
66
|
'drop': 'Remove file from context',
|
|
67
67
|
'multiline': 'Toggle multi-line input',
|
|
68
68
|
'test': 'Generate/run tests',
|
|
69
|
-
'docs': '
|
|
69
|
+
'docs': 'Open web docs for a command (e.g. /docs personality)',
|
|
70
70
|
'refactor': 'Improve code quality',
|
|
71
71
|
'fix': 'Debug and fix issues',
|
|
72
72
|
'explain': 'Explain code',
|
|
@@ -123,6 +123,8 @@ const COMMAND_DESCRIPTIONS = {
|
|
|
123
123
|
'sync': 'Sync learning preferences and profiles to codeep.dev',
|
|
124
124
|
'telemetry': 'Show or toggle automatic cloud telemetry (on/off)',
|
|
125
125
|
'keysync': 'Show or toggle syncing API keys to codeep.dev (on/off)',
|
|
126
|
+
'thinking': 'Set the thinking/reasoning-effort tier (auto/low/medium/high/max) for models that support it',
|
|
127
|
+
'effort': 'Alias for /thinking — set the reasoning-effort tier',
|
|
126
128
|
// 2.0 — surfaced for `/` autocomplete; documented in /help too.
|
|
127
129
|
'compact': 'Summarize older messages to free up context',
|
|
128
130
|
'commands': 'List custom slash commands in .codeep/commands/*.md',
|
|
@@ -2312,6 +2314,14 @@ export class App {
|
|
|
2312
2314
|
this.screen.write(leftX - 1, y, '·', fg.gray);
|
|
2313
2315
|
leftX += 1;
|
|
2314
2316
|
}
|
|
2317
|
+
// Thinking-effort tier, right beside the model (the CLI twin of the Mac
|
|
2318
|
+
// app's effort chip). Only present when set + supported — see getStatus.
|
|
2319
|
+
if (status.reasoningEffort) {
|
|
2320
|
+
this.screen.write(leftX, y, fg.yellow + status.reasoningEffort + style.reset);
|
|
2321
|
+
leftX += status.reasoningEffort.length + 2;
|
|
2322
|
+
this.screen.write(leftX - 1, y, '·', fg.gray);
|
|
2323
|
+
leftX += 1;
|
|
2324
|
+
}
|
|
2315
2325
|
this.screen.write(leftX, y, msgCount, fg.gray);
|
|
2316
2326
|
leftX += msgCount.length;
|
|
2317
2327
|
if (tokenStr) {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { config, getCurrentProvider, getModelsForCurrentProvider, PROTOCOLS, LANGUAGES, setProvider, setApiKey, clearApiKey, getApiKey, isTelemetryEnabled, telemetryForcedOffByEnv, isKeySyncEnabled, keySyncForcedOffByEnv, saveSession, startNewSession, loadSession, listSessionsWithInfo, deleteSession, renameSession, setProjectPermission, saveProfile, loadProfile, applyProfile, listProfiles, deleteProfile, initializeAsProject, isManuallyInitializedProject, } from '../config/index.js';
|
|
9
9
|
import { getProjectContext } from '../utils/project.js';
|
|
10
10
|
import { getCurrentVersion } from '../utils/update.js';
|
|
11
|
-
import { getProviderList, getProvider } from '../config/providers.js';
|
|
11
|
+
import { getProviderList, getProvider, modelSupportsReasoningEffort, reasoningParamsFor, availableReasoningTiers, resolveReasoningTier, REASONING_TIERS } from '../config/providers.js';
|
|
12
12
|
import { setProjectContext } from '../api/index.js';
|
|
13
13
|
import { runSkill, runCommandChain } from './agentExecution.js';
|
|
14
14
|
import { loadProjectIntelligence, saveProjectIntelligence } from '../utils/projectIntelligence.js';
|
|
@@ -303,6 +303,57 @@ export async function handleCommand(command, args, ctx) {
|
|
|
303
303
|
ctx.app.addMessage({ role: 'system', content: kLines.join('\n') });
|
|
304
304
|
break;
|
|
305
305
|
}
|
|
306
|
+
case 'effort':
|
|
307
|
+
case 'thinking': {
|
|
308
|
+
const providerId = config.get('provider');
|
|
309
|
+
const model = config.get('model');
|
|
310
|
+
const supported = modelSupportsReasoningEffort(providerId, model);
|
|
311
|
+
// Tiers THIS model actually distinguishes (e.g. GLM-5.2 → auto/high/max).
|
|
312
|
+
const available = availableReasoningTiers(providerId, model);
|
|
313
|
+
const sub = args[0]?.toLowerCase();
|
|
314
|
+
if (sub && REASONING_TIERS.includes(sub)) {
|
|
315
|
+
config.set('reasoningEffort', sub);
|
|
316
|
+
if (sub === 'auto') {
|
|
317
|
+
ctx.app.notify('Thinking effort: auto — each model uses its own default.');
|
|
318
|
+
}
|
|
319
|
+
else if (!supported) {
|
|
320
|
+
ctx.app.notify(`Thinking effort set to "${sub}", but ${model} has no graded thinking control — it will be ignored until you switch to a model that does (e.g. Opus 4.8, GPT-5.x, Gemini 3, DeepSeek V4, GLM-5.2).`);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
// Tell the user what THIS model will actually run (the tier may
|
|
324
|
+
// collapse onto a level the model distinguishes, e.g. low→high on GLM).
|
|
325
|
+
const resolved = resolveReasoningTier(providerId, model, sub);
|
|
326
|
+
const note = resolved === sub ? '' : ` (${model} runs this as "${resolved}")`;
|
|
327
|
+
ctx.app.notify(`Thinking effort: ${sub}${note} — sending ${JSON.stringify(reasoningParamsFor(providerId, model, sub))}.`);
|
|
328
|
+
}
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
if (sub && sub !== 'status') {
|
|
332
|
+
const offer = available.length > 0 ? available : REASONING_TIERS;
|
|
333
|
+
ctx.app.notify(`Usage: /thinking ${offer.join(' · /thinking ')}`);
|
|
334
|
+
break;
|
|
335
|
+
}
|
|
336
|
+
const tier = (config.get('reasoningEffort') ?? 'auto');
|
|
337
|
+
const resolved = resolveReasoningTier(providerId, model, tier);
|
|
338
|
+
const tLines = ['## Thinking effort', ''];
|
|
339
|
+
tLines.push(`**Tier** ${tier}${resolved !== tier && tier !== 'auto' ? ` → ${resolved} on this model` : ''}`);
|
|
340
|
+
tLines.push(`**Model** ${model} (${providerId})`);
|
|
341
|
+
if (!supported) {
|
|
342
|
+
tLines.push('**Effective** not sent — this model has no graded thinking control');
|
|
343
|
+
}
|
|
344
|
+
else if (tier === 'auto') {
|
|
345
|
+
tLines.push('**Effective** model default (no param sent)');
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
tLines.push(`**Effective** ${JSON.stringify(reasoningParamsFor(providerId, model, tier))}`);
|
|
349
|
+
}
|
|
350
|
+
if (supported)
|
|
351
|
+
tLines.push(`**Available** ${available.join(' · ')}`);
|
|
352
|
+
tLines.push('');
|
|
353
|
+
tLines.push('Sets how hard the model reasons. Each model offers only the levels it distinguishes (GLM-5.2 / DeepSeek → high · max; Gemini → low · high; Opus/Sonnet & GPT-5.x → the full set). The setting is global and clamps to the active model, so it never sends a value the API rejects. `/effort` is an alias.');
|
|
354
|
+
ctx.app.addMessage({ role: 'system', content: tLines.join('\n') });
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
306
357
|
case 'grant': {
|
|
307
358
|
setProjectPermission(ctx.projectPath, true, true);
|
|
308
359
|
ctx.setHasWriteAccess(true);
|
|
@@ -341,10 +392,12 @@ export async function handleCommand(command, args, ctx) {
|
|
|
341
392
|
runAgentTask(args.join(' '), true, ctx, () => null, () => { });
|
|
342
393
|
break;
|
|
343
394
|
}
|
|
395
|
+
case 'd':
|
|
344
396
|
case 'docs': {
|
|
345
397
|
// Open per-command web docs in the system browser. Lets the inline
|
|
346
398
|
// /help stay terse (single-line entries) while users who want the
|
|
347
|
-
// long story get one keystroke away from a real page.
|
|
399
|
+
// long story get one keystroke away from a real page. `/d` is the
|
|
400
|
+
// short alias.
|
|
348
401
|
const cmd = (args[0] ?? '').toLowerCase().replace(/^\//, '');
|
|
349
402
|
const KNOWN = {
|
|
350
403
|
personality: 'https://codeep.dev/docs/agent#personalities',
|
|
@@ -1504,8 +1557,6 @@ Format: use headers per category, only include categories where you found issues
|
|
|
1504
1557
|
case 'commit':
|
|
1505
1558
|
case 't':
|
|
1506
1559
|
case 'test':
|
|
1507
|
-
case 'd':
|
|
1508
|
-
case 'docs':
|
|
1509
1560
|
case 'r':
|
|
1510
1561
|
case 'refactor':
|
|
1511
1562
|
case 'f':
|
|
@@ -26,6 +26,19 @@ export const SETTINGS = [
|
|
|
26
26
|
max: 32768,
|
|
27
27
|
step: 256,
|
|
28
28
|
},
|
|
29
|
+
{
|
|
30
|
+
key: 'reasoningEffort',
|
|
31
|
+
label: 'Thinking Effort',
|
|
32
|
+
getValue: () => config.get('reasoningEffort') ?? 'auto',
|
|
33
|
+
type: 'select',
|
|
34
|
+
options: [
|
|
35
|
+
{ value: 'auto', label: 'Auto (model default)' },
|
|
36
|
+
{ value: 'low', label: 'Low' },
|
|
37
|
+
{ value: 'medium', label: 'Medium' },
|
|
38
|
+
{ value: 'high', label: 'High' },
|
|
39
|
+
{ value: 'max', label: 'Max' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
29
42
|
{
|
|
30
43
|
key: 'apiTimeout',
|
|
31
44
|
label: 'API Timeout (ms)',
|
|
@@ -7,6 +7,9 @@ export interface StatusInfo {
|
|
|
7
7
|
provider: string;
|
|
8
8
|
model: string;
|
|
9
9
|
agentMode: string;
|
|
10
|
+
/** Thinking-effort tier to show beside the model (e.g. "max") — only set
|
|
11
|
+
* when non-auto AND the active model supports a graded knob; undefined hides it. */
|
|
12
|
+
reasoningEffort?: string;
|
|
10
13
|
projectPath: string;
|
|
11
14
|
hasWriteAccess: boolean;
|
|
12
15
|
sessionId: string;
|
package/dist/renderer/main.js
CHANGED
|
@@ -15,7 +15,7 @@ import { getZaiVisionConfig, getMinimaxMcpConfig, callZaiVisionApi, callMinimaxA
|
|
|
15
15
|
import { config, loadApiKey, loadAllApiKeys, getCurrentProvider, autoSaveSession, startNewSession, getCurrentSessionId, loadSession, listSessionsWithInfo, deleteSession, hasReadPermission, hasWritePermission, setProjectPermission, initializeAsProject, isManuallyInitializedProject, setApiKey, setProvider, getGithubId, } from '../config/index.js';
|
|
16
16
|
import { isProjectDirectory, getProjectContext, } from '../utils/project.js';
|
|
17
17
|
import { getCurrentVersion, checkForUpdates, getUpdateInstructions } from '../utils/update.js';
|
|
18
|
-
import { getProviderList, isNoApiKeyProvider } from '../config/providers.js';
|
|
18
|
+
import { getProviderList, isNoApiKeyProvider, resolveReasoningTier } from '../config/providers.js';
|
|
19
19
|
import { getSessionStats, getCostBreakdown } from '../utils/tokenTracker.js';
|
|
20
20
|
import { isGitRepository } from '../utils/git.js';
|
|
21
21
|
import { reportStats, syncSession, generateProjectId } from '../utils/codeepCloud.js';
|
|
@@ -73,11 +73,17 @@ function getStatus() {
|
|
|
73
73
|
const providers = getProviderList();
|
|
74
74
|
const providerInfo = providers.find(p => p.id === provider.id);
|
|
75
75
|
const stats = getSessionStats();
|
|
76
|
+
// Show the thinking-effort tier beside the model. Resolve the (global) tier
|
|
77
|
+
// to what THIS model actually runs — e.g. a global 'low' shows as 'high' on
|
|
78
|
+
// GLM-5.2, which only grades high|max. 'auto'/unsupported → hidden.
|
|
79
|
+
const resolved = resolveReasoningTier(provider.id, config.get('model'), config.get('reasoningEffort'));
|
|
80
|
+
const reasoningEffort = resolved !== 'auto' ? resolved : undefined;
|
|
76
81
|
return {
|
|
77
82
|
version: getCurrentVersion(),
|
|
78
83
|
provider: providerInfo?.name || 'Unknown',
|
|
79
84
|
model: config.get('model'),
|
|
80
85
|
agentMode: config.get('agentMode') || 'off',
|
|
86
|
+
reasoningEffort,
|
|
81
87
|
projectPath,
|
|
82
88
|
hasWriteAccess,
|
|
83
89
|
sessionId,
|
package/dist/utils/agentChat.js
CHANGED
|
@@ -16,8 +16,9 @@ import { join } from 'path';
|
|
|
16
16
|
import { createHash } from 'crypto';
|
|
17
17
|
import { config, getApiKey, resolveBaseUrl } from '../config/index.js';
|
|
18
18
|
import { loadProjectIntelligence, generateContextFromIntelligence } from './projectIntelligence.js';
|
|
19
|
+
import { formatCommandIndex } from './commandIndex.js';
|
|
19
20
|
import { syncProgress, generateProjectId } from './codeepCloud.js';
|
|
20
|
-
import { getProviderAuthHeader, supportsNativeTools, getEffectiveMaxTokens, usesMaxCompletionTokens, requiresDefaultTemperature, modelRejectsSamplingParams, isNoApiKeyProvider } from '../config/providers.js';
|
|
21
|
+
import { getProviderAuthHeader, supportsNativeTools, getEffectiveMaxTokens, usesMaxCompletionTokens, requiresDefaultTemperature, modelRejectsSamplingParams, isNoApiKeyProvider, reasoningParamsFor, providerNoStreamWithTools } from '../config/providers.js';
|
|
21
22
|
import { recordTokenUsage, extractOpenAIUsage, extractAnthropicUsage } from './tokenTracker.js';
|
|
22
23
|
import { parseOpenAIToolCalls, parseAnthropicToolCalls, parseToolCalls } from './toolParsing.js';
|
|
23
24
|
import { formatToolDefinitions, getOpenAITools, getAnthropicTools } from './tools.js';
|
|
@@ -281,6 +282,16 @@ export function getAgentSystemPrompt(projectContext) {
|
|
|
281
282
|
- Keep working until the task is actually finished. If you still have work to do, CALL A TOOL — don't just narrate. If you're done, reply with a short summary and no tool calls.
|
|
282
283
|
- Don't ask permission for routine work; the user already launched the agent.
|
|
283
284
|
|
|
285
|
+
## About Codeep
|
|
286
|
+
Codeep is an open-source, terminal-native AI coding agent — also a native macOS app and a VS Code / Zed extension (over ACP). Beyond the file/command tools above, the user can extend you through Codeep features:
|
|
287
|
+
- Skills — reusable workflow bundles (browse/add/run with \`/skills\`)
|
|
288
|
+
- MCP — connect external tools & data, e.g. Postgres, GitHub, a browser, the iOS simulator (\`/mcp\`)
|
|
289
|
+
- Sub-agents — delegate focused subtasks (\`/agents\`)
|
|
290
|
+
- Personalities — change your working style (\`/personality\`)
|
|
291
|
+
- A dashboard at codeep.dev for synced sessions, usage & cost
|
|
292
|
+
When the user asks what you can do, or a task maps to one of these, point them at the right slash-command:
|
|
293
|
+
${formatCommandIndex()}
|
|
294
|
+
|
|
284
295
|
## Codeep App Storage (your own metadata)
|
|
285
296
|
This project uses Codeep. The following paths are Codeep's internal state — **read** them if you need context about prior sessions, but do not edit them manually during a task:
|
|
286
297
|
- \`${root}/.codeep/intelligence.json\` — cached project analysis (structure, frameworks, CI/CD, conventions). Refresh via \`/scan\`.
|
|
@@ -356,10 +367,15 @@ additionalTools) {
|
|
|
356
367
|
try {
|
|
357
368
|
let endpoint;
|
|
358
369
|
let body;
|
|
359
|
-
|
|
370
|
+
// Qwen/DashScope reject `tools` + `stream:true` together; this path always
|
|
371
|
+
// sends tools, so force a non-streamed request there (the non-streaming
|
|
372
|
+
// branch below still emits the content via onChunk). Other providers stream.
|
|
373
|
+
const useStreaming = Boolean(onChunk) && !providerNoStreamWithTools(providerId);
|
|
360
374
|
// Provider-level guard (OpenAI GPT-5+) OR model-level guard — Anthropic's
|
|
361
375
|
// Fable 5 / Opus 4.7+ reject temperature with a 400; omission is safe.
|
|
362
376
|
const tempParam = (requiresDefaultTemperature(providerId) || modelRejectsSamplingParams(model)) ? {} : { temperature: config.get('temperature') };
|
|
377
|
+
// Thinking-effort tier → provider-shaped param ({} for 'auto'/unsupported).
|
|
378
|
+
const reasoningParam = reasoningParamsFor(providerId, model, config.get('reasoningEffort'));
|
|
363
379
|
if (protocol === 'openai') {
|
|
364
380
|
const maxTok = getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384));
|
|
365
381
|
const tokParam = usesMaxCompletionTokens(providerId) ? { max_completion_tokens: maxTok } : { max_tokens: maxTok };
|
|
@@ -410,7 +426,7 @@ additionalTools) {
|
|
|
410
426
|
body = {
|
|
411
427
|
model, messages: [{ role: 'system', content: systemPrompt }, ...messages],
|
|
412
428
|
tools: getOpenAITools(additionalTools), tool_choice: 'auto', stream: useStreaming,
|
|
413
|
-
...tempParam, ...tokParam,
|
|
429
|
+
...tempParam, ...tokParam, ...reasoningParam,
|
|
414
430
|
...(useStreaming && providerId === 'openai' ? { stream_options: { include_usage: true } } : {}),
|
|
415
431
|
...openRouterExtras,
|
|
416
432
|
};
|
|
@@ -436,7 +452,7 @@ additionalTools) {
|
|
|
436
452
|
system: [{ type: 'text', text: systemPrompt, cache_control: { type: 'ephemeral' } }],
|
|
437
453
|
messages,
|
|
438
454
|
tools: cachedTools, stream: useStreaming,
|
|
439
|
-
...tempParam, max_tokens: getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384)),
|
|
455
|
+
...tempParam, ...reasoningParam, max_tokens: getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384)),
|
|
440
456
|
};
|
|
441
457
|
}
|
|
442
458
|
const response = await fetch(endpoint, {
|
|
@@ -554,13 +570,15 @@ export async function agentChatFallback(messages, systemPrompt, onChunk, abortSi
|
|
|
554
570
|
// Provider-level guard (OpenAI GPT-5+) OR model-level guard — Anthropic's
|
|
555
571
|
// Fable 5 / Opus 4.7+ reject temperature with a 400; omission is safe.
|
|
556
572
|
const tempParam = (requiresDefaultTemperature(providerId) || modelRejectsSamplingParams(model)) ? {} : { temperature: config.get('temperature') };
|
|
573
|
+
// Thinking-effort tier → provider-shaped param ({} for 'auto'/unsupported).
|
|
574
|
+
const reasoningParam = reasoningParamsFor(providerId, model, config.get('reasoningEffort'));
|
|
557
575
|
if (protocol === 'openai') {
|
|
558
576
|
const maxTok = getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384));
|
|
559
577
|
const tokParam = usesMaxCompletionTokens(providerId) ? { max_completion_tokens: maxTok } : { max_tokens: maxTok };
|
|
560
578
|
endpoint = `${baseUrl}/chat/completions`;
|
|
561
579
|
body = {
|
|
562
580
|
model, messages: [{ role: 'system', content: fallbackPrompt }, ...messages],
|
|
563
|
-
stream: Boolean(onChunk), ...tempParam, ...tokParam,
|
|
581
|
+
stream: Boolean(onChunk), ...tempParam, ...tokParam, ...reasoningParam,
|
|
564
582
|
};
|
|
565
583
|
}
|
|
566
584
|
else {
|
|
@@ -577,7 +595,7 @@ export async function agentChatFallback(messages, systemPrompt, onChunk, abortSi
|
|
|
577
595
|
{ role: 'assistant', content: 'Understood. I will use the tools as specified.' },
|
|
578
596
|
...messages,
|
|
579
597
|
],
|
|
580
|
-
stream: Boolean(onChunk), ...tempParam,
|
|
598
|
+
stream: Boolean(onChunk), ...tempParam, ...reasoningParam,
|
|
581
599
|
max_tokens: getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384)),
|
|
582
600
|
};
|
|
583
601
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curated, agent-facing index of the most useful Codeep slash-commands.
|
|
3
|
+
*
|
|
4
|
+
* Injected into the agent's system prompt (see `getAgentSystemPrompt`) so the
|
|
5
|
+
* model knows these exist and can point the user at the right one. Deliberately
|
|
6
|
+
* a CURATED subset — not the full ~60-command registry in
|
|
7
|
+
* `renderer/commands.ts` — to keep the prompt small; every entry here must be
|
|
8
|
+
* a real command. Single source for this list so it doesn't drift across the
|
|
9
|
+
* places that describe Codeep to the model.
|
|
10
|
+
*/
|
|
11
|
+
export declare const COMMAND_INDEX: {
|
|
12
|
+
cmd: string;
|
|
13
|
+
desc: string;
|
|
14
|
+
}[];
|
|
15
|
+
/** Render the index as Markdown bullets for the system prompt. */
|
|
16
|
+
export declare function formatCommandIndex(): string;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Curated, agent-facing index of the most useful Codeep slash-commands.
|
|
3
|
+
*
|
|
4
|
+
* Injected into the agent's system prompt (see `getAgentSystemPrompt`) so the
|
|
5
|
+
* model knows these exist and can point the user at the right one. Deliberately
|
|
6
|
+
* a CURATED subset — not the full ~60-command registry in
|
|
7
|
+
* `renderer/commands.ts` — to keep the prompt small; every entry here must be
|
|
8
|
+
* a real command. Single source for this list so it doesn't drift across the
|
|
9
|
+
* places that describe Codeep to the model.
|
|
10
|
+
*/
|
|
11
|
+
export const COMMAND_INDEX = [
|
|
12
|
+
{ cmd: '/scan', desc: 'analyze the project (structure, frameworks, conventions) into .codeep/intelligence.json' },
|
|
13
|
+
{ cmd: '/plan', desc: 'plan a task before executing it (plan mode)' },
|
|
14
|
+
{ cmd: '/skills', desc: 'browse, add, or run reusable skill bundles' },
|
|
15
|
+
{ cmd: '/mcp', desc: 'connect external tools & data via MCP servers (Postgres, GitHub, a browser, the iOS simulator…)' },
|
|
16
|
+
{ cmd: '/agents', desc: 'manage sub-agents you can delegate focused subtasks to' },
|
|
17
|
+
{ cmd: '/personality', desc: 'switch the agent persona / working style' },
|
|
18
|
+
{ cmd: '/review', desc: 'code-review the current changes' },
|
|
19
|
+
{ cmd: '/commit', desc: 'write a commit message from the current diff' },
|
|
20
|
+
{ cmd: '/pr', desc: 'open a pull request' },
|
|
21
|
+
{ cmd: '/checkpoint', desc: 'save a restore point (/rewind rolls back to it)' },
|
|
22
|
+
{ cmd: '/memory', desc: 'add or list project memory notes the agent remembers' },
|
|
23
|
+
{ cmd: '/cost', desc: 'show token usage and estimated cost for the session' },
|
|
24
|
+
{ cmd: '/settings', desc: 'change models, providers, confirmation policy, and limits' },
|
|
25
|
+
];
|
|
26
|
+
/** Render the index as Markdown bullets for the system prompt. */
|
|
27
|
+
export function formatCommandIndex() {
|
|
28
|
+
return COMMAND_INDEX.map(c => `- \`${c.cmd}\` — ${c.desc}`).join('\n');
|
|
29
|
+
}
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* - Each entry's `args` should be the **invocation-without-runtime-args**
|
|
10
10
|
* so `/mcp install` can prompt for the things that vary per user
|
|
11
11
|
* (paths, tokens, etc.) via `argHints`.
|
|
12
|
-
* - Prefer official `@modelcontextprotocol/*` packages
|
|
12
|
+
* - Prefer official `@modelcontextprotocol/*` packages; well-maintained
|
|
13
|
+
* third-party servers are fine when they're the de-facto standard for
|
|
14
|
+
* their niche (e.g. Playwright for browsers, the iOS-simulator servers).
|
|
13
15
|
*/
|
|
14
16
|
import type { McpServer } from '../acp/protocol.js';
|
|
15
17
|
export interface MarketplaceEntry {
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
* - Each entry's `args` should be the **invocation-without-runtime-args**
|
|
10
10
|
* so `/mcp install` can prompt for the things that vary per user
|
|
11
11
|
* (paths, tokens, etc.) via `argHints`.
|
|
12
|
-
* - Prefer official `@modelcontextprotocol/*` packages
|
|
12
|
+
* - Prefer official `@modelcontextprotocol/*` packages; well-maintained
|
|
13
|
+
* third-party servers are fine when they're the de-facto standard for
|
|
14
|
+
* their niche (e.g. Playwright for browsers, the iOS-simulator servers).
|
|
13
15
|
*/
|
|
14
16
|
export const MCP_MARKETPLACE = [
|
|
15
17
|
{
|
|
@@ -116,11 +118,25 @@ export const MCP_MARKETPLACE = [
|
|
|
116
118
|
url: 'https://github.com/modelcontextprotocol/servers/tree/main/src/time',
|
|
117
119
|
},
|
|
118
120
|
{
|
|
119
|
-
id: '
|
|
120
|
-
name: '
|
|
121
|
-
description: '
|
|
122
|
-
server: { command: 'npx', args: ['-y', '@
|
|
123
|
-
url: 'https://github.com/
|
|
121
|
+
id: 'playwright',
|
|
122
|
+
name: 'Playwright (browser)',
|
|
123
|
+
description: 'Drive a real browser — navigate, click, fill, screenshot, and scrape — via Microsoft Playwright. The de-facto browser-automation MCP (supersedes Puppeteer).',
|
|
124
|
+
server: { command: 'npx', args: ['-y', '@playwright/mcp@latest'] },
|
|
125
|
+
url: 'https://github.com/microsoft/playwright-mcp',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
id: 'ios-simulator',
|
|
129
|
+
name: 'iOS Simulator',
|
|
130
|
+
description: 'Drive the iOS Simulator — tap, type, swipe, screenshot, record, install & launch apps. macOS only; needs Xcode + idb (`brew install facebook/fb/idb-companion`).',
|
|
131
|
+
server: { command: 'npx', args: ['-y', 'ios-simulator-mcp'] },
|
|
132
|
+
url: 'https://github.com/joshuayoes/ios-simulator-mcp',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: 'mobile',
|
|
136
|
+
name: 'Mobile (iOS + Android)',
|
|
137
|
+
description: 'UI automation for end-to-end mobile testing across iOS simulators/devices and Android. macOS needs Xcode command-line tools.',
|
|
138
|
+
server: { command: 'npx', args: ['-y', '@mobilenext/mobile-mcp@latest'] },
|
|
139
|
+
url: 'https://github.com/mobile-next/mobile-mcp',
|
|
124
140
|
},
|
|
125
141
|
];
|
|
126
142
|
export function findMarketplaceEntry(id) {
|
|
@@ -26,6 +26,23 @@ const MODEL_CONTEXT_WINDOWS = {
|
|
|
26
26
|
'gemini-3-flash-preview': 1_000_000,
|
|
27
27
|
// MiniMax
|
|
28
28
|
'MiniMax-M3': 524_288,
|
|
29
|
+
// Kimi (Moonshot) — 256K across the K2.x line
|
|
30
|
+
'kimi-k2.7-code': 262_144,
|
|
31
|
+
'kimi-k2.7-code-highspeed': 262_144,
|
|
32
|
+
'kimi-k2.6': 262_144,
|
|
33
|
+
'kimi-k2.5': 262_144,
|
|
34
|
+
'kimi-for-coding': 262_144,
|
|
35
|
+
// Grok (xAI)
|
|
36
|
+
'grok-build-0.1': 256_000,
|
|
37
|
+
'grok-4.3': 1_000_000,
|
|
38
|
+
'grok-code-fast-1': 256_000,
|
|
39
|
+
'grok-4-fast-reasoning': 2_000_000,
|
|
40
|
+
// Qwen (Alibaba) — 256K native (1M with extrapolation)
|
|
41
|
+
'qwen3-coder-plus': 262_144,
|
|
42
|
+
'qwen3-coder-next': 262_144,
|
|
43
|
+
'qwen3-coder-flash': 262_144,
|
|
44
|
+
'qwen3-max': 262_144,
|
|
45
|
+
'Qwen/Qwen3-Coder-480B-A35B-Instruct': 262_144,
|
|
29
46
|
};
|
|
30
47
|
const DEFAULT_CONTEXT_WINDOW = 128_000;
|
|
31
48
|
/**
|
|
@@ -62,6 +79,26 @@ const MODEL_PRICING = {
|
|
|
62
79
|
'gemini-3-flash-preview': { inputPer1M: 0.50, outputPer1M: 3.00 },
|
|
63
80
|
// MiniMax
|
|
64
81
|
'MiniMax-M3': { inputPer1M: 0.60, outputPer1M: 2.40 },
|
|
82
|
+
// Kimi (Moonshot) — pay-per-use cache-miss rates; `kimi-for-coding` is the
|
|
83
|
+
// subscription alias (flat-fee in reality, priced notionally like K2.7 Code).
|
|
84
|
+
'kimi-k2.7-code': { inputPer1M: 0.60, outputPer1M: 2.50 },
|
|
85
|
+
'kimi-k2.7-code-highspeed': { inputPer1M: 0.60, outputPer1M: 2.50 },
|
|
86
|
+
'kimi-k2.6': { inputPer1M: 0.55, outputPer1M: 2.20 },
|
|
87
|
+
'kimi-k2.5': { inputPer1M: 0.40, outputPer1M: 1.90 },
|
|
88
|
+
'kimi-for-coding': { inputPer1M: 0.60, outputPer1M: 2.50 },
|
|
89
|
+
// Grok (xAI)
|
|
90
|
+
'grok-build-0.1': { inputPer1M: 1.00, outputPer1M: 2.00 },
|
|
91
|
+
'grok-4.3': { inputPer1M: 1.25, outputPer1M: 2.50 },
|
|
92
|
+
'grok-code-fast-1': { inputPer1M: 0.20, outputPer1M: 1.50 },
|
|
93
|
+
'grok-4-fast-reasoning': { inputPer1M: 0.20, outputPer1M: 0.50 },
|
|
94
|
+
// Qwen (Alibaba) — qwen3-coder-* 0–256K tier; the Coding Plan is flat-fee so
|
|
95
|
+
// this only affects the pay-per-use estimate.
|
|
96
|
+
'qwen3-coder-plus': { inputPer1M: 0.28, outputPer1M: 1.65 },
|
|
97
|
+
'qwen3-coder-next': { inputPer1M: 0.28, outputPer1M: 1.65 },
|
|
98
|
+
'qwen3-coder-flash': { inputPer1M: 0.10, outputPer1M: 0.50 },
|
|
99
|
+
'qwen3-max': { inputPer1M: 1.20, outputPer1M: 6.00 },
|
|
100
|
+
// ModelScope free tier — no per-token charge.
|
|
101
|
+
'Qwen/Qwen3-Coder-480B-A35B-Instruct': { inputPer1M: 0, outputPer1M: 0 },
|
|
65
102
|
};
|
|
66
103
|
export function getPricingTable() {
|
|
67
104
|
return Object.entries(MODEL_PRICING).map(([model, p]) => ({ model, ...p }));
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "2.
|
|
1
|
+
export declare const VERSION = "2.13.0";
|
package/dist/version.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
// AUTO-GENERATED by scripts/gen-version.js — do not edit by hand.
|
|
2
2
|
// Baked from package.json at build time so the bun-compiled binary reports
|
|
3
3
|
// the right version (it has no package.json on disk to read at runtime).
|
|
4
|
-
export const VERSION = '2.
|
|
4
|
+
export const VERSION = '2.13.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "AI-powered coding assistant built for the terminal. Multiple LLM providers, project-aware context, and a seamless development workflow.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|