codeep 2.16.0 → 2.18.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/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
- <img src="Codeep.gif" alt="Codeep demo" width="700">
12
+ <img src="promo/sources/tui-current.png" alt="Codeep terminal UI with agent timeline, changed files, checks, and resource estimates" width="1000">
13
13
  </p>
14
14
 
15
15
  <p align="center">
@@ -23,6 +23,16 @@
23
23
  <a href="https://github.com/VladoIvankovic/Codeep"><img src="https://img.shields.io/github/stars/VladoIvankovic/Codeep?style=social" alt="GitHub stars"></a>
24
24
  </p>
25
25
 
26
+ ## One agent, every surface
27
+
28
+ Codeep keeps the same project context, provider configuration, sessions, and
29
+ agent workflow wherever you work:
30
+
31
+ - **[Terminal / TUI](https://codeep.dev/docs/installation)** — the primary CLI experience, with Plan → Read → Edit → Verify → Summary, live file changes, checks, token cost, and estimated energy and cooling-water impact.
32
+ - **[macOS app](https://codeep.dev/docs/mac)** — a native SwiftUI workbench with project conversations and Run Inspector.
33
+ - **[VS Code extension](https://github.com/VladoIvankovic/Codeep-vscode)** — the same agent over ACP, directly inside the editor. Also available on the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=VladoIvankovic.codeep).
34
+ - **[Web dashboard](https://codeep.dev/dashboard)** — synced sessions, usage, costs, tasks, and project activity.
35
+
26
36
  ## Upgrading
27
37
 
28
38
  Running `npm install -g codeep@latest` picks up the new version — config,
@@ -1029,11 +1039,11 @@ After installation, `codeep` is available globally in your terminal. Simply run
1029
1039
  > /profile save fast
1030
1040
 
1031
1041
  > /provider # switch to openai
1032
- > /model gpt-4.1
1042
+ > /model gpt-5.6-sol
1033
1043
  > /profile save work
1034
1044
 
1035
1045
  > /model fast # instantly switch to z.ai / glm-5.2
1036
- > /model work # instantly switch to openai / gpt-4.1
1046
+ > /model work # instantly switch to openai / gpt-5.6-sol
1037
1047
  ```
1038
1048
 
1039
1049
  ### Session Management
@@ -1265,6 +1275,17 @@ With write access enabled:
1265
1275
  | `GOOGLE_API_KEY` | Google AI (Gemini) API key |
1266
1276
  | `MINIMAX_API_KEY` | MiniMax (international) API key |
1267
1277
  | `MINIMAX_CN_API_KEY` | MiniMax China API key |
1278
+ | `KIMI_CODE_API_KEY` | Kimi Code subscription key |
1279
+ | `MOONSHOT_API_KEY` | Kimi international pay-per-use key |
1280
+ | `MOONSHOT_CN_API_KEY` | Kimi China pay-per-use key |
1281
+ | `XAI_API_KEY` | Grok (xAI) API key |
1282
+ | `BAILIAN_CODING_PLAN_API_KEY` | Qwen international Coding Plan key |
1283
+ | `BAILIAN_TOKEN_PLAN_API_KEY` | Qwen international Token Plan key |
1284
+ | `DASHSCOPE_API_KEY` | Qwen international pay-per-use key |
1285
+ | `BAILIAN_CODING_PLAN_CN_API_KEY` | Qwen China Coding Plan key |
1286
+ | `DASHSCOPE_CN_API_KEY` | Qwen China pay-per-use key |
1287
+ | `MODELSCOPE_API_KEY` | ModelScope token for its live model catalog |
1288
+ | `OPENROUTER_API_KEY` | OpenRouter API key |
1268
1289
 
1269
1290
  ### Settings (`/settings`)
1270
1291
 
@@ -1366,6 +1387,10 @@ Contributions are welcome! Before opening a PR, please read the
1366
1387
  how to propose a change. For provider integrations specifically, the guide
1367
1388
  walks through the files you need to touch.
1368
1389
 
1390
+ The active-product scope, model source index, replacement rules, telemetry
1391
+ contract, and recurring review checklist live in the
1392
+ [**model maintenance policy**](./docs/MODEL_MAINTENANCE.md).
1393
+
1369
1394
  Quick version: `npm install` → `npm test` → `npx tsc --noEmit` clean → open a
1370
1395
  PR against `main`. To report a security issue, see
1371
1396
  [**Security policy**](./SECURITY.md).
@@ -1473,7 +1498,7 @@ The chat sidebar now surfaces two extra ACP signals that previously only the TUI
1473
1498
  ### Editor-native actions (new in 2.2)
1474
1499
 
1475
1500
  - **Code Actions (lightbulb)** — select code and press `Ctrl+.` for **Explain**, **Improve / refactor**, **Add tests**, and **Add doc comment**. On a line with an error/warning, a **Fix this problem** quick-fix sends the diagnostic plus the code to Codeep. Everything routes through the chat, so the full agent (file edits via the diff preview, MCP tools) is available.
1476
- - **Model picker in the status bar** — click `Codeep · <model>` (or run **Codeep: Select Provider & Model**) to switch provider + model from a quick-pick. Providers with open-ended catalogs (OpenRouter, Ollama, custom endpoints) let you type a model id.
1501
+ - **Model picker in the status bar** — click `Codeep · <model>` (or run **Codeep: Select Provider & Model**) to switch provider + model from a quick-pick. Providers with open-ended catalogs (OpenRouter, ModelScope, Ollama, custom endpoints) let you type a model id.
1477
1502
  - **Self-hosted endpoints from settings** — point the extension at vLLM / LiteLLM / LM Studio / text-generation-webui with `codeep.baseUrl` (e.g. `http://localhost:8000/v1`), plus `codeep.provider` (`custom` or `openai`) and `codeep.model`. The `codeep.provider` / `codeep.model` settings are applied on every connect, so they stay authoritative.
1478
1503
  - **Get Started walkthrough** — a native VS Code walkthrough (Help → Get Started) covering CLI install, opening the chat, editor actions, and choosing a model.
1479
1504
 
@@ -224,7 +224,7 @@ export function buildProviderList() {
224
224
  // Model metadata so ACP clients (e.g. the VS Code model picker) can
225
225
  // offer a provider → model selector without hardcoding a catalog.
226
226
  // `dynamicModels` flags providers whose model list is open-ended
227
- // (OpenRouter, Ollama, custom endpoints) — clients should let the
227
+ // (OpenRouter, ModelScope, Ollama, custom endpoints) — clients should let the
228
228
  // user type a model id rather than only pick from `models`.
229
229
  models: p.models.map((m) => ({ id: m.id, name: m.name })),
230
230
  defaultModel: p.defaultModel,
package/dist/api/index.js CHANGED
@@ -343,7 +343,13 @@ async function chatOpenAI(message, history, model, apiKey, onChunk, abortSignal)
343
343
  let baseUrl = resolveBaseUrl(providerId, 'openai');
344
344
  const authHeader = getProviderAuthHeader(providerId, 'openai');
345
345
  const useCompletionTokens = usesMaxCompletionTokens(providerId);
346
- const omitTemperature = requiresDefaultTemperature(providerId);
346
+ // Two independent reasons to leave temperature out, and both must be checked
347
+ // here: the provider-level flag (endpoints that only accept the default) and
348
+ // the per-model one (generations that removed the sampling params outright,
349
+ // e.g. gemini-3.7-flash). Testing only the provider flag let a rejecting
350
+ // model through, because every model this rule covers is served over the
351
+ // OpenAI-compatible path, not the Anthropic one.
352
+ const omitTemperature = requiresDefaultTemperature(providerId) || modelRejectsSamplingParams(model);
347
353
  if (!baseUrl) {
348
354
  throw new Error(`Provider ${providerId} does not support OpenAI protocol`);
349
355
  }
@@ -2,7 +2,7 @@ import Conf from 'conf';
2
2
  import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync, unlinkSync, statSync } from 'fs';
3
3
  import { join, dirname } from 'path';
4
4
  import { randomUUID } from 'crypto';
5
- import { PROVIDERS, getProvider, getProviderBaseUrl } from './providers.js';
5
+ import { PROVIDERS, getProvider, getProviderBaseUrl, replacementModelFor } from './providers.js';
6
6
  import { logSession } from '../utils/logger.js';
7
7
  import { createSecureStorage } from '../utils/keychain.js';
8
8
  // We'll initialize GLOBAL_SESSIONS_DIR after config is created (to use config.path)
@@ -255,8 +255,9 @@ if (config.get('agentMode') === 'auto') {
255
255
  // affected sliders were effectively lies). Each migration now runs exactly
256
256
  // once per config, recorded via `migrationVersion`; after that, whatever the
257
257
  // user sets sticks. Bump MIGRATION_VERSION when adding a new one.
258
- const MIGRATION_VERSION = 1;
259
- if ((config.get('migrationVersion') ?? 0) < 1) {
258
+ const MIGRATION_VERSION = 4;
259
+ const currentMigrationVersion = config.get('migrationVersion') ?? 0;
260
+ if (currentMigrationVersion < 1) {
260
261
  // Migrate the old runaway default (10000 iterations) down to a sane
261
262
  // ceiling, and old conservative defaults up to the current ones.
262
263
  if (config.get('agentMaxIterations') >= 10000) {
@@ -277,6 +278,18 @@ if ((config.get('migrationVersion') ?? 0) < 1) {
277
278
  if (config.get('rateLimitCommands') <= 100) {
278
279
  config.set('rateLimitCommands', 10000);
279
280
  }
281
+ }
282
+ if (currentMigrationVersion < 4) {
283
+ // Vendor aliases below were removed from Codeep's curated catalogue after
284
+ // their replacements became available. Migrate only exact known aliases:
285
+ // OpenRouter/Ollama/custom model ids remain user-controlled.
286
+ const provider = config.get('provider');
287
+ const model = config.get('model');
288
+ const replacement = replacementModelFor(provider, model);
289
+ if (replacement)
290
+ config.set('model', replacement);
291
+ }
292
+ if (currentMigrationVersion < MIGRATION_VERSION) {
280
293
  config.set('migrationVersion', MIGRATION_VERSION);
281
294
  }
282
295
  // Global sessions directory - use same directory as conf package for cross-platform consistency
@@ -1216,7 +1229,10 @@ export function loadProfile(name) {
1216
1229
  }
1217
1230
  export function applyProfile(profile) {
1218
1231
  config.set('provider', profile.provider);
1219
- config.set('model', profile.model);
1232
+ // A profile saved before a vendor retired a model would otherwise restore an
1233
+ // id the picker no longer offers. Normalize it exactly like the startup
1234
+ // migration does — dynamic OpenRouter/Ollama/custom ids are never rewritten.
1235
+ config.set('model', replacementModelFor(profile.provider, profile.model) ?? profile.model);
1220
1236
  config.set('protocol', profile.protocol);
1221
1237
  config.set('temperature', profile.temperature);
1222
1238
  config.set('maxTokens', profile.maxTokens);
@@ -34,6 +34,10 @@ export interface ProviderConfig {
34
34
  subscribeUrl?: string;
35
35
  noApiKey?: boolean;
36
36
  dynamicModels?: boolean;
37
+ /** Billed as a flat subscription (or free) — token counts are real, per-token
38
+ * cost is not. Cost surfaces must say "included in plan" instead of pricing
39
+ * these tokens at the provider's pay-per-use rates. */
40
+ flatFee?: boolean;
37
41
  groupLabel?: string;
38
42
  hint?: string;
39
43
  mcpEndpoints?: {
@@ -45,6 +49,7 @@ export interface ProviderConfig {
45
49
  export declare const PROVIDERS: Record<string, ProviderConfig>;
46
50
  export type ProviderId = keyof typeof PROVIDERS;
47
51
  export declare function getProvider(id: string): ProviderConfig | null;
52
+ export declare function replacementModelFor(providerId: string, modelId: string): string | undefined;
48
53
  export declare function getProviderList(): {
49
54
  id: string;
50
55
  name: string;
@@ -59,6 +64,11 @@ export declare function getProviderModels(providerId: string): {
59
64
  }[];
60
65
  export declare function isNoApiKeyProvider(providerId: string): boolean;
61
66
  export declare function isDynamicModelsProvider(providerId: string): boolean;
67
+ /**
68
+ * Returns true if the provider bills a flat subscription (or is free), so any
69
+ * per-token dollar figure we compute for it is invented — see `flatFee`.
70
+ */
71
+ export declare function isFlatFeeProvider(providerId: string): boolean;
62
72
  export declare function getProviderBaseUrl(providerId: string, protocol: 'openai' | 'anthropic'): string | null;
63
73
  export declare function getProviderAuthHeader(providerId: string, protocol: 'openai' | 'anthropic'): 'Bearer' | 'x-api-key';
64
74
  export declare function getProviderMcpEndpoints(providerId: string): ProviderConfig['mcpEndpoints'] | null;
@@ -133,8 +143,8 @@ export declare function availableReasoningTiers(providerId: string, model: strin
133
143
  /**
134
144
  * Map a (possibly out-of-range) tier to the tier this model actually distinguishes,
135
145
  * 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
146
+ * a tier picked on Opus ('medium') may not exist on Kimi K3; we show the level
147
+ * Kimi will really run (its 'medium' clamps to 'high'). Picks the tier whose
138
148
  * effective param equals the requested one. 'auto' (or unsupported) → 'auto'.
139
149
  */
140
150
  export declare function resolveReasoningTier(providerId: string, model: string, tier: ReasoningTier): ReasoningTier;