codeep 2.11.1 → 2.12.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/acp/session.js +9 -2
- 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 +54 -0
- package/dist/config/providers.js +148 -10
- 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 +20 -5
- 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 +0 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/acp/session.js
CHANGED
|
@@ -90,8 +90,15 @@ export async function runAgentSession(opts) {
|
|
|
90
90
|
const result = await runAgent(opts.prompt, projectContext, {
|
|
91
91
|
abortSignal: opts.abortSignal,
|
|
92
92
|
onChunk: (text) => { chunksEmitted++; opts.onChunk(text); },
|
|
93
|
-
onIteration: (_iteration,
|
|
94
|
-
//
|
|
93
|
+
onIteration: (_iteration, message) => {
|
|
94
|
+
// The bare iteration counter is internal noise, but transient notices —
|
|
95
|
+
// API retry/backoff ("retrying in Ns") and context warnings (⚠) — are
|
|
96
|
+
// exactly what the user needs to see when a request stalls, otherwise
|
|
97
|
+
// the editor just shows an endless "Thinking…" spinner. Surface those
|
|
98
|
+
// (and only those) as a thought.
|
|
99
|
+
if (opts.onThought && /retry|⚠/i.test(message)) {
|
|
100
|
+
opts.onThought(message);
|
|
101
|
+
}
|
|
95
102
|
},
|
|
96
103
|
onThinking: (text) => {
|
|
97
104
|
if (opts.onThought) {
|
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
|
@@ -74,3 +74,57 @@ export declare function modelRejectsSamplingParams(model: string): boolean;
|
|
|
74
74
|
* Falls back to the requested value if no provider limit is set.
|
|
75
75
|
*/
|
|
76
76
|
export declare function getEffectiveMaxTokens(providerId: string, requested: number): number;
|
|
77
|
+
/**
|
|
78
|
+
* Unified, user-facing thinking-effort tiers (the `/thinking` setting).
|
|
79
|
+
*
|
|
80
|
+
* 'auto' — omit the param entirely → each provider's own default.
|
|
81
|
+
* low / medium / high / max — four explicit depth tiers.
|
|
82
|
+
*
|
|
83
|
+
* The four tiers are CONCEPTUAL. `reasoningParamsFor()` clamps each one to the
|
|
84
|
+
* nearest level the active provider+model actually accepts, so we never send a
|
|
85
|
+
* value that would 400 (e.g. Gemini rejects "medium"; OpenAI has no "max").
|
|
86
|
+
* The control is a pure DEPTH knob on models that already think — it never
|
|
87
|
+
* toggles thinking on/off, which keeps us clear of the reasoning_content-replay
|
|
88
|
+
* contract that DeepSeek/GLM impose when thinking mode is flipped.
|
|
89
|
+
*/
|
|
90
|
+
export type ReasoningTier = 'auto' | 'low' | 'medium' | 'high' | 'max';
|
|
91
|
+
export declare const REASONING_TIERS: ReasoningTier[];
|
|
92
|
+
/**
|
|
93
|
+
* Canonicalize a model id for capability matching: lowercase, drop any
|
|
94
|
+
* `vendor/` namespace (OpenRouter sends `anthropic/claude-opus-4.8`), and
|
|
95
|
+
* normalize `.` version separators to `-` (`glm-5.2` → `glm-5-2`,
|
|
96
|
+
* `claude-opus-4.8` → `claude-opus-4-8`). Mirrors macOS `ModelTuning.canonicalModelID`.
|
|
97
|
+
*/
|
|
98
|
+
export declare function canonicalModelId(model: string): string;
|
|
99
|
+
/**
|
|
100
|
+
* Does this provider+model expose a GRADED thinking-effort control we can drive?
|
|
101
|
+
* Used to gate the `/thinking` UI — hidden entirely for models without one.
|
|
102
|
+
* Keep in lockstep with macOS `ModelTuning.reasoningEffortSupported`.
|
|
103
|
+
*/
|
|
104
|
+
export declare function modelSupportsReasoningEffort(providerId: string, model: string): boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Build the request-body fields that carry the chosen effort tier for the
|
|
107
|
+
* active provider+model+protocol. Returns `{}` for 'auto', unsupported
|
|
108
|
+
* models, or providers without a graded knob — so callers can spread it
|
|
109
|
+
* unconditionally. Keep in lockstep with macOS `ModelTuning.reasoningParams`.
|
|
110
|
+
*/
|
|
111
|
+
export declare function reasoningParamsFor(providerId: string, model: string, tier: ReasoningTier): Record<string, unknown>;
|
|
112
|
+
/**
|
|
113
|
+
* The DISTINCT tiers a given provider+model actually exposes — used to build a
|
|
114
|
+
* per-model picker that only offers levels the model can tell apart (e.g.
|
|
115
|
+
* GLM-5.2/DeepSeek grade only high|max; Gemini via the OpenAI-compat layer only
|
|
116
|
+
* low|high). Always leads with 'auto'. `[]` for models with no graded knob.
|
|
117
|
+
*
|
|
118
|
+
* Kept in lockstep with `reasoningParamsFor` (the providers-test asserts every
|
|
119
|
+
* listed tier yields a DISTINCT param, so this can't silently drift). Mirrors
|
|
120
|
+
* macOS `ModelTuning.availableReasoningTiers`.
|
|
121
|
+
*/
|
|
122
|
+
export declare function availableReasoningTiers(providerId: string, model: string): ReasoningTier[];
|
|
123
|
+
/**
|
|
124
|
+
* Map a (possibly out-of-range) tier to the tier this model actually distinguishes,
|
|
125
|
+
* for display — the chip + the checked menu row. The effort setting is global, so
|
|
126
|
+
* a tier picked on Opus ('low') may not exist on GLM-5.2; we show the level GLM
|
|
127
|
+
* will really run (its 'low' clamps to 'high'). Picks the available tier whose
|
|
128
|
+
* effective param equals the requested one. 'auto' (or unsupported) → 'auto'.
|
|
129
|
+
*/
|
|
130
|
+
export declare function resolveReasoningTier(providerId: string, model: string, tier: ReasoningTier): ReasoningTier;
|
package/dist/config/providers.js
CHANGED
|
@@ -19,9 +19,7 @@ export const PROVIDERS = {
|
|
|
19
19
|
},
|
|
20
20
|
models: [
|
|
21
21
|
{ id: 'glm-5.2', name: 'GLM-5.2', description: 'Latest GLM model, available to all users' },
|
|
22
|
-
{ id: 'glm-5.1', name: 'GLM-5.1', description: 'Previous GLM model, available to all users' },
|
|
23
22
|
{ id: 'glm-5-turbo', name: 'GLM-5 Turbo', description: 'Fast GLM-5 variant, available to all users' },
|
|
24
|
-
{ id: 'glm-5', name: 'GLM-5', description: 'Most capable GLM-5 model (Pro/Max plan only)' },
|
|
25
23
|
],
|
|
26
24
|
defaultModel: 'glm-5.2',
|
|
27
25
|
defaultProtocol: 'openai',
|
|
@@ -47,9 +45,7 @@ export const PROVIDERS = {
|
|
|
47
45
|
},
|
|
48
46
|
models: [
|
|
49
47
|
{ id: 'glm-5.2', name: 'GLM-5.2', description: 'Latest GLM model' },
|
|
50
|
-
{ id: 'glm-5.1', name: 'GLM-5.1', description: 'Previous GLM model' },
|
|
51
48
|
{ id: 'glm-5-turbo', name: 'GLM-5 Turbo', description: 'Fast GLM-5 variant' },
|
|
52
|
-
{ id: 'glm-5', name: 'GLM-5', description: 'Most capable GLM-5 model' },
|
|
53
49
|
],
|
|
54
50
|
defaultModel: 'glm-5.2',
|
|
55
51
|
defaultProtocol: 'openai',
|
|
@@ -75,9 +71,7 @@ export const PROVIDERS = {
|
|
|
75
71
|
},
|
|
76
72
|
models: [
|
|
77
73
|
{ id: 'glm-5.2', name: 'GLM-5.2', description: 'Latest GLM model, available to all users' },
|
|
78
|
-
{ id: 'glm-5.1', name: 'GLM-5.1', description: 'Previous GLM model, available to all users' },
|
|
79
74
|
{ id: 'glm-5-turbo', name: 'GLM-5 Turbo', description: 'Fast GLM-5 variant, available to all users' },
|
|
80
|
-
{ id: 'glm-5', name: 'GLM-5', description: 'Most capable GLM-5 model (Pro/Max plan only)' },
|
|
81
75
|
],
|
|
82
76
|
defaultModel: 'glm-5.2',
|
|
83
77
|
defaultProtocol: 'openai',
|
|
@@ -103,9 +97,7 @@ export const PROVIDERS = {
|
|
|
103
97
|
},
|
|
104
98
|
models: [
|
|
105
99
|
{ id: 'glm-5.2', name: 'GLM-5.2', description: 'Latest GLM model' },
|
|
106
|
-
{ id: 'glm-5.1', name: 'GLM-5.1', description: 'Previous GLM model' },
|
|
107
100
|
{ id: 'glm-5-turbo', name: 'GLM-5 Turbo', description: 'Fast GLM-5 variant' },
|
|
108
|
-
{ id: 'glm-5', name: 'GLM-5', description: 'Most capable GLM-5 model' },
|
|
109
101
|
],
|
|
110
102
|
defaultModel: 'glm-5.2',
|
|
111
103
|
defaultProtocol: 'openai',
|
|
@@ -225,7 +217,6 @@ export const PROVIDERS = {
|
|
|
225
217
|
{ id: 'gpt-5.5', name: 'GPT-5.5', description: 'Latest GPT model — best for coding' },
|
|
226
218
|
{ id: 'gpt-5.4', name: 'GPT-5.4', description: 'Previous generation GPT' },
|
|
227
219
|
{ id: 'gpt-5.4-mini', name: 'GPT-5.4 Mini', description: 'Faster and cheaper GPT-5.4' },
|
|
228
|
-
{ id: 'gpt-5.4-nano', name: 'GPT-5.4 Nano', description: 'Most affordable, great for simple tasks' },
|
|
229
220
|
],
|
|
230
221
|
defaultModel: 'gpt-5.5',
|
|
231
222
|
defaultProtocol: 'openai',
|
|
@@ -247,7 +238,6 @@ export const PROVIDERS = {
|
|
|
247
238
|
},
|
|
248
239
|
},
|
|
249
240
|
models: [
|
|
250
|
-
{ id: 'claude-fable-5', name: 'Claude Fable 5', description: 'Most powerful — new tier above Opus' },
|
|
251
241
|
{ id: 'claude-opus-4-8', name: 'Claude Opus 4.8', description: 'Most capable Opus model' },
|
|
252
242
|
{ id: 'claude-sonnet-4-6', name: 'Claude Sonnet', description: 'Best balance of speed and intelligence' },
|
|
253
243
|
{ id: 'claude-haiku-4-5-20251001', name: 'Claude Haiku', description: 'Fastest and most affordable' },
|
|
@@ -472,3 +462,151 @@ export function getEffectiveMaxTokens(providerId, requested) {
|
|
|
472
462
|
return requested;
|
|
473
463
|
return Math.min(requested, provider.maxOutputTokens);
|
|
474
464
|
}
|
|
465
|
+
export const REASONING_TIERS = ['auto', 'low', 'medium', 'high', 'max'];
|
|
466
|
+
/**
|
|
467
|
+
* Canonicalize a model id for capability matching: lowercase, drop any
|
|
468
|
+
* `vendor/` namespace (OpenRouter sends `anthropic/claude-opus-4.8`), and
|
|
469
|
+
* normalize `.` version separators to `-` (`glm-5.2` → `glm-5-2`,
|
|
470
|
+
* `claude-opus-4.8` → `claude-opus-4-8`). Mirrors macOS `ModelTuning.canonicalModelID`.
|
|
471
|
+
*/
|
|
472
|
+
export function canonicalModelId(model) {
|
|
473
|
+
let id = model.toLowerCase();
|
|
474
|
+
const slash = id.lastIndexOf('/');
|
|
475
|
+
if (slash !== -1)
|
|
476
|
+
id = id.slice(slash + 1);
|
|
477
|
+
return id.replace(/\./g, '-');
|
|
478
|
+
}
|
|
479
|
+
/** True when `id` equals `prefix` or starts with `prefix-` (catches dated variants). */
|
|
480
|
+
function idMatches(id, prefix) {
|
|
481
|
+
return id === prefix || id.startsWith(`${prefix}-`);
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Does this provider+model expose a GRADED thinking-effort control we can drive?
|
|
485
|
+
* Used to gate the `/thinking` UI — hidden entirely for models without one.
|
|
486
|
+
* Keep in lockstep with macOS `ModelTuning.reasoningEffortSupported`.
|
|
487
|
+
*/
|
|
488
|
+
export function modelSupportsReasoningEffort(providerId, model) {
|
|
489
|
+
const id = canonicalModelId(model);
|
|
490
|
+
switch (providerId) {
|
|
491
|
+
case 'anthropic':
|
|
492
|
+
// Effort is GA on Opus 4.5+, Sonnet 4.6, Fable 5 — NOT Haiku or Sonnet 4.5.
|
|
493
|
+
if (idMatches(id, 'claude-haiku-4-5') || idMatches(id, 'claude-sonnet-4-5'))
|
|
494
|
+
return false;
|
|
495
|
+
return /^claude-(opus-4-([5-9]|\d\d)|sonnet-4-6|fable-5)/.test(id);
|
|
496
|
+
case 'openai':
|
|
497
|
+
// GPT-5.x are reasoning models — reasoning_effort across the family (incl. mini).
|
|
498
|
+
return id.startsWith('gpt-5');
|
|
499
|
+
case 'google':
|
|
500
|
+
// Gemini 3.x thinking_level via the OpenAI-compat reasoning_effort mapping.
|
|
501
|
+
return id.startsWith('gemini-3');
|
|
502
|
+
case 'deepseek':
|
|
503
|
+
return id.startsWith('deepseek-v4');
|
|
504
|
+
case 'z.ai':
|
|
505
|
+
case 'z.ai-api':
|
|
506
|
+
case 'z.ai-cn':
|
|
507
|
+
case 'z.ai-cn-api':
|
|
508
|
+
// GLM-5.2 added graded High/Max effort. glm-5-turbo is a plain thinking
|
|
509
|
+
// toggle (no graded levels) so it stays out.
|
|
510
|
+
return idMatches(id, 'glm-5-2');
|
|
511
|
+
case 'openrouter':
|
|
512
|
+
// OpenRouter normalizes a unified `reasoning` field and silently ignores
|
|
513
|
+
// it for non-reasoning models, so the control is always safe to expose.
|
|
514
|
+
return true;
|
|
515
|
+
default:
|
|
516
|
+
// minimax (toggle only), ollama, custom — no graded depth knob.
|
|
517
|
+
return false;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
/**
|
|
521
|
+
* Build the request-body fields that carry the chosen effort tier for the
|
|
522
|
+
* active provider+model+protocol. Returns `{}` for 'auto', unsupported
|
|
523
|
+
* models, or providers without a graded knob — so callers can spread it
|
|
524
|
+
* unconditionally. Keep in lockstep with macOS `ModelTuning.reasoningParams`.
|
|
525
|
+
*/
|
|
526
|
+
export function reasoningParamsFor(providerId, model, tier) {
|
|
527
|
+
// 'auto', or any unexpected value from an older/garbled config, → no param.
|
|
528
|
+
// (Guards against ever emitting e.g. `effort: undefined`, which could 400.)
|
|
529
|
+
if (tier === 'auto' || !REASONING_TIERS.includes(tier))
|
|
530
|
+
return {};
|
|
531
|
+
if (!modelSupportsReasoningEffort(providerId, model))
|
|
532
|
+
return {};
|
|
533
|
+
switch (providerId) {
|
|
534
|
+
case 'anthropic':
|
|
535
|
+
// low / medium / high / max — all valid on the capable Claude models.
|
|
536
|
+
return { output_config: { effort: tier } };
|
|
537
|
+
case 'openai':
|
|
538
|
+
// none/low/medium/high/xhigh — no "max"; map our Max → xhigh (the ceiling).
|
|
539
|
+
return { reasoning_effort: tier === 'max' ? 'xhigh' : tier };
|
|
540
|
+
case 'google':
|
|
541
|
+
// Gemini 3 (OpenAI-compat) accepts ONLY low/high — "medium" 400s.
|
|
542
|
+
return { reasoning_effort: tier === 'low' ? 'low' : 'high' };
|
|
543
|
+
case 'deepseek':
|
|
544
|
+
case 'z.ai':
|
|
545
|
+
case 'z.ai-api':
|
|
546
|
+
case 'z.ai-cn':
|
|
547
|
+
case 'z.ai-cn-api':
|
|
548
|
+
// Graded thinking depth: high (default) or max. Lower tiers collapse to high.
|
|
549
|
+
return { reasoning_effort: tier === 'max' ? 'max' : 'high' };
|
|
550
|
+
case 'openrouter':
|
|
551
|
+
// Unified reasoning object; no "max" effort → cap at high.
|
|
552
|
+
return { reasoning: { effort: tier === 'max' ? 'high' : tier } };
|
|
553
|
+
default:
|
|
554
|
+
return {};
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* The DISTINCT tiers a given provider+model actually exposes — used to build a
|
|
559
|
+
* per-model picker that only offers levels the model can tell apart (e.g.
|
|
560
|
+
* GLM-5.2/DeepSeek grade only high|max; Gemini via the OpenAI-compat layer only
|
|
561
|
+
* low|high). Always leads with 'auto'. `[]` for models with no graded knob.
|
|
562
|
+
*
|
|
563
|
+
* Kept in lockstep with `reasoningParamsFor` (the providers-test asserts every
|
|
564
|
+
* listed tier yields a DISTINCT param, so this can't silently drift). Mirrors
|
|
565
|
+
* macOS `ModelTuning.availableReasoningTiers`.
|
|
566
|
+
*/
|
|
567
|
+
export function availableReasoningTiers(providerId, model) {
|
|
568
|
+
if (!modelSupportsReasoningEffort(providerId, model))
|
|
569
|
+
return [];
|
|
570
|
+
switch (providerId) {
|
|
571
|
+
case 'anthropic':
|
|
572
|
+
case 'openai':
|
|
573
|
+
return ['auto', 'low', 'medium', 'high', 'max'];
|
|
574
|
+
case 'google':
|
|
575
|
+
// OpenAI-compat layer accepts only low/high — "medium" 400s.
|
|
576
|
+
return ['auto', 'low', 'high'];
|
|
577
|
+
case 'deepseek':
|
|
578
|
+
case 'z.ai':
|
|
579
|
+
case 'z.ai-api':
|
|
580
|
+
case 'z.ai-cn':
|
|
581
|
+
case 'z.ai-cn-api':
|
|
582
|
+
return ['auto', 'high', 'max'];
|
|
583
|
+
case 'openrouter':
|
|
584
|
+
return ['auto', 'low', 'medium', 'high'];
|
|
585
|
+
default:
|
|
586
|
+
return [];
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Map a (possibly out-of-range) tier to the tier this model actually distinguishes,
|
|
591
|
+
* for display — the chip + the checked menu row. The effort setting is global, so
|
|
592
|
+
* a tier picked on Opus ('low') may not exist on GLM-5.2; we show the level GLM
|
|
593
|
+
* will really run (its 'low' clamps to 'high'). Picks the available tier whose
|
|
594
|
+
* effective param equals the requested one. 'auto' (or unsupported) → 'auto'.
|
|
595
|
+
*/
|
|
596
|
+
export function resolveReasoningTier(providerId, model, tier) {
|
|
597
|
+
if (tier === 'auto')
|
|
598
|
+
return 'auto';
|
|
599
|
+
const avail = availableReasoningTiers(providerId, model);
|
|
600
|
+
if (avail.length === 0)
|
|
601
|
+
return 'auto';
|
|
602
|
+
if (avail.includes(tier))
|
|
603
|
+
return tier;
|
|
604
|
+
const target = JSON.stringify(reasoningParamsFor(providerId, model, tier));
|
|
605
|
+
for (const t of avail) {
|
|
606
|
+
if (t === 'auto')
|
|
607
|
+
continue;
|
|
608
|
+
if (JSON.stringify(reasoningParamsFor(providerId, model, t)) === target)
|
|
609
|
+
return t;
|
|
610
|
+
}
|
|
611
|
+
return 'auto';
|
|
612
|
+
}
|
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 } 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\`.
|
|
@@ -360,6 +371,8 @@ additionalTools) {
|
|
|
360
371
|
// Provider-level guard (OpenAI GPT-5+) OR model-level guard — Anthropic's
|
|
361
372
|
// Fable 5 / Opus 4.7+ reject temperature with a 400; omission is safe.
|
|
362
373
|
const tempParam = (requiresDefaultTemperature(providerId) || modelRejectsSamplingParams(model)) ? {} : { temperature: config.get('temperature') };
|
|
374
|
+
// Thinking-effort tier → provider-shaped param ({} for 'auto'/unsupported).
|
|
375
|
+
const reasoningParam = reasoningParamsFor(providerId, model, config.get('reasoningEffort'));
|
|
363
376
|
if (protocol === 'openai') {
|
|
364
377
|
const maxTok = getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384));
|
|
365
378
|
const tokParam = usesMaxCompletionTokens(providerId) ? { max_completion_tokens: maxTok } : { max_tokens: maxTok };
|
|
@@ -410,7 +423,7 @@ additionalTools) {
|
|
|
410
423
|
body = {
|
|
411
424
|
model, messages: [{ role: 'system', content: systemPrompt }, ...messages],
|
|
412
425
|
tools: getOpenAITools(additionalTools), tool_choice: 'auto', stream: useStreaming,
|
|
413
|
-
...tempParam, ...tokParam,
|
|
426
|
+
...tempParam, ...tokParam, ...reasoningParam,
|
|
414
427
|
...(useStreaming && providerId === 'openai' ? { stream_options: { include_usage: true } } : {}),
|
|
415
428
|
...openRouterExtras,
|
|
416
429
|
};
|
|
@@ -436,7 +449,7 @@ additionalTools) {
|
|
|
436
449
|
system: [{ type: 'text', text: systemPrompt, cache_control: { type: 'ephemeral' } }],
|
|
437
450
|
messages,
|
|
438
451
|
tools: cachedTools, stream: useStreaming,
|
|
439
|
-
...tempParam, max_tokens: getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384)),
|
|
452
|
+
...tempParam, ...reasoningParam, max_tokens: getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384)),
|
|
440
453
|
};
|
|
441
454
|
}
|
|
442
455
|
const response = await fetch(endpoint, {
|
|
@@ -554,13 +567,15 @@ export async function agentChatFallback(messages, systemPrompt, onChunk, abortSi
|
|
|
554
567
|
// Provider-level guard (OpenAI GPT-5+) OR model-level guard — Anthropic's
|
|
555
568
|
// Fable 5 / Opus 4.7+ reject temperature with a 400; omission is safe.
|
|
556
569
|
const tempParam = (requiresDefaultTemperature(providerId) || modelRejectsSamplingParams(model)) ? {} : { temperature: config.get('temperature') };
|
|
570
|
+
// Thinking-effort tier → provider-shaped param ({} for 'auto'/unsupported).
|
|
571
|
+
const reasoningParam = reasoningParamsFor(providerId, model, config.get('reasoningEffort'));
|
|
557
572
|
if (protocol === 'openai') {
|
|
558
573
|
const maxTok = getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384));
|
|
559
574
|
const tokParam = usesMaxCompletionTokens(providerId) ? { max_completion_tokens: maxTok } : { max_tokens: maxTok };
|
|
560
575
|
endpoint = `${baseUrl}/chat/completions`;
|
|
561
576
|
body = {
|
|
562
577
|
model, messages: [{ role: 'system', content: fallbackPrompt }, ...messages],
|
|
563
|
-
stream: Boolean(onChunk), ...tempParam, ...tokParam,
|
|
578
|
+
stream: Boolean(onChunk), ...tempParam, ...tokParam, ...reasoningParam,
|
|
564
579
|
};
|
|
565
580
|
}
|
|
566
581
|
else {
|
|
@@ -577,7 +592,7 @@ export async function agentChatFallback(messages, systemPrompt, onChunk, abortSi
|
|
|
577
592
|
{ role: 'assistant', content: 'Understood. I will use the tools as specified.' },
|
|
578
593
|
...messages,
|
|
579
594
|
],
|
|
580
|
-
stream: Boolean(onChunk), ...tempParam,
|
|
595
|
+
stream: Boolean(onChunk), ...tempParam, ...reasoningParam,
|
|
581
596
|
max_tokens: getEffectiveMaxTokens(providerId, Math.max(config.get('maxTokens'), 16384)),
|
|
582
597
|
};
|
|
583
598
|
}
|
|
@@ -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) {
|
|
@@ -8,16 +8,12 @@
|
|
|
8
8
|
const MODEL_CONTEXT_WINDOWS = {
|
|
9
9
|
// Z.AI / ZhipuAI
|
|
10
10
|
'glm-5.2': 200_000,
|
|
11
|
-
'glm-5.1': 131_072,
|
|
12
|
-
'glm-5': 80_000,
|
|
13
11
|
'glm-5-turbo': 202_752,
|
|
14
12
|
// OpenAI
|
|
15
13
|
'gpt-5.5': 1_200_000,
|
|
16
14
|
'gpt-5.4': 1_050_000,
|
|
17
15
|
'gpt-5.4-mini': 400_000,
|
|
18
|
-
'gpt-5.4-nano': 400_000,
|
|
19
16
|
// Anthropic
|
|
20
|
-
'claude-fable-5': 1_000_000,
|
|
21
17
|
'claude-opus-4-8': 1_000_000,
|
|
22
18
|
'claude-sonnet-4-6': 1_000_000,
|
|
23
19
|
'claude-haiku-4-5-20251001': 200_000,
|
|
@@ -48,16 +44,12 @@ const MODEL_PRICING = {
|
|
|
48
44
|
// Note: on the GLM Coding Plan (the default `z.ai` provider) billing is a flat
|
|
49
45
|
// subscription, so this only affects the pay-per-use estimate.
|
|
50
46
|
'glm-5.2': { inputPer1M: 1.00, outputPer1M: 3.20 },
|
|
51
|
-
'glm-5.1': { inputPer1M: 1.00, outputPer1M: 3.20 },
|
|
52
|
-
'glm-5': { inputPer1M: 0.72, outputPer1M: 2.30 },
|
|
53
47
|
'glm-5-turbo': { inputPer1M: 1.20, outputPer1M: 4.00 },
|
|
54
48
|
// OpenAI
|
|
55
49
|
'gpt-5.5': { inputPer1M: 5.00, outputPer1M: 30.00 },
|
|
56
50
|
'gpt-5.4': { inputPer1M: 2.50, outputPer1M: 15.00 },
|
|
57
51
|
'gpt-5.4-mini': { inputPer1M: 0.75, outputPer1M: 4.50 },
|
|
58
|
-
'gpt-5.4-nano': { inputPer1M: 0.20, outputPer1M: 1.25 },
|
|
59
52
|
// Anthropic
|
|
60
|
-
'claude-fable-5': { inputPer1M: 10.00, outputPer1M: 50.00 },
|
|
61
53
|
'claude-opus-4-8': { inputPer1M: 5.00, outputPer1M: 25.00 },
|
|
62
54
|
'claude-sonnet-4-6': { inputPer1M: 3.00, outputPer1M: 15.00 },
|
|
63
55
|
'claude-haiku-4-5-20251001': { inputPer1M: 1.00, outputPer1M: 5.00 },
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "2.
|
|
1
|
+
export declare const VERSION = "2.12.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.12.0';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeep",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.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",
|