deepccc 0.1.14 → 0.1.16
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 +34 -14
- package/dist/cli.js +17 -4
- package/dist/config.d.ts +6 -0
- package/dist/config.js +12 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +66 -11
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -45,16 +45,19 @@ deepccc 的本地缓存优化实测命中率 **96.7%**,有效降低重复请
|
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
47
|
export DEEPCCC_API_KEY="sk-..."
|
|
48
|
-
export DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
|
|
49
|
-
export DEEPCCC_MODEL="deepseek-v4-pro"
|
|
48
|
+
export DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
|
|
49
|
+
export DEEPCCC_MODEL="deepseek-v4-pro"
|
|
50
|
+
export DEEPCCC_STREAMING="true"
|
|
50
51
|
```
|
|
51
52
|
|
|
52
53
|
Windows PowerShell:
|
|
53
54
|
|
|
54
55
|
```powershell
|
|
55
|
-
$env:DEEPCCC_API_KEY="sk-..."
|
|
56
|
-
$env:
|
|
57
|
-
$env:
|
|
56
|
+
$env:DEEPCCC_API_KEY="sk-..."
|
|
57
|
+
$env:DEEPCCC_PROVIDER="openai"
|
|
58
|
+
$env:DEEPCCC_BASE_URL="https://api.deepseek.com/v1"
|
|
59
|
+
$env:DEEPCCC_MODEL="deepseek-v4-pro"
|
|
60
|
+
$env:DEEPCCC_STREAMING="true"
|
|
58
61
|
```
|
|
59
62
|
|
|
60
63
|
也兼容这些 DeepSeek 别名:
|
|
@@ -67,19 +70,30 @@ $env:DEEPCCC_MODEL="deepseek-v4-pro"
|
|
|
67
70
|
也可以创建 `~/.deepccc/config.json`:
|
|
68
71
|
|
|
69
72
|
```json
|
|
70
|
-
{
|
|
71
|
-
"
|
|
73
|
+
{
|
|
74
|
+
"provider": "openai",
|
|
75
|
+
"apiKey": "sk-...",
|
|
72
76
|
"baseURL": "https://api.deepseek.com/v1",
|
|
73
|
-
"model": "deepseek-v4-pro",
|
|
74
|
-
"effort": "",
|
|
77
|
+
"model": "deepseek-v4-pro",
|
|
78
|
+
"effort": "",
|
|
79
|
+
"streaming": true,
|
|
75
80
|
"rawStreamLogs": {
|
|
76
81
|
"enabled": false,
|
|
77
82
|
"maxBytesPerTurn": 1048576,
|
|
78
83
|
"retentionDays": 7,
|
|
79
84
|
"keepCompleted": false
|
|
80
85
|
}
|
|
81
|
-
}
|
|
82
|
-
```
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`provider` 可选 `openai` 或 `anthropic`,默认 `openai`,也可以通过
|
|
90
|
+
`DEEPCCC_PROVIDER` 或命令行 `--provider` 覆盖:
|
|
91
|
+
|
|
92
|
+
- `openai` 使用 OpenAI-compatible Chat Completions 协议,兼容 DeepSeek、OpenAI、LiteLLM、vLLM 等服务。
|
|
93
|
+
- `anthropic` 使用 Anthropic Messages 协议。配置中的 `baseURL` 可以继续填写同一个服务基址;DeepCCC 会为不带 `/v1` 的地址自动补上 `/v1`。`effort` 是 OpenAI/DeepSeek 扩展参数,在 Anthropic 模式下不会发送。
|
|
94
|
+
|
|
95
|
+
`streaming` 控制主对话是否使用流式请求,默认 `true`;也可以通过
|
|
96
|
+
`DEEPCCC_STREAMING=true|false` 覆盖。关闭后,终端会在整条模型响应完成后一次性显示结果。
|
|
83
97
|
|
|
84
98
|
## 命令行交互
|
|
85
99
|
|
|
@@ -89,11 +103,17 @@ $env:DEEPCCC_MODEL="deepseek-v4-pro"
|
|
|
89
103
|
deepccc
|
|
90
104
|
```
|
|
91
105
|
|
|
92
|
-
指定其他模型或 OpenAI-compatible 接口:
|
|
106
|
+
指定其他模型或 OpenAI-compatible 接口:
|
|
93
107
|
|
|
94
108
|
```bash
|
|
95
|
-
deepccc --base-url https://api.openai.com/v1 --api-key "$OPENAI_API_KEY" --model gpt-4.1
|
|
96
|
-
```
|
|
109
|
+
deepccc --base-url https://api.openai.com/v1 --api-key "$OPENAI_API_KEY" --model gpt-4.1
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
使用 Anthropic Messages 协议(同样支持流式输出):
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
deepccc --provider anthropic --base-url https://api.example.com --api-key "$API_KEY" --model claude-sonnet-4-6
|
|
116
|
+
```
|
|
97
117
|
|
|
98
118
|
指定工作目录:
|
|
99
119
|
|
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* 非 TTY(管道/CI)或 --plain 回退为纯文本流式输出;--stream-json 机器接口不变。
|
|
12
12
|
*/
|
|
13
13
|
import * as readline from "node:readline";
|
|
14
|
-
import
|
|
14
|
+
import process from "node:process";
|
|
15
15
|
import { appendFileSync, existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
16
16
|
import { homedir } from "node:os";
|
|
17
17
|
import { join, resolve as resolvePath } from "node:path";
|
|
@@ -31,6 +31,12 @@ function parsePositiveIntegerOption(name, value) {
|
|
|
31
31
|
}
|
|
32
32
|
return parsed;
|
|
33
33
|
}
|
|
34
|
+
function parseProviderOption(value) {
|
|
35
|
+
const normalized = value.trim().toLowerCase();
|
|
36
|
+
if (normalized === "openai" || normalized === "anthropic")
|
|
37
|
+
return normalized;
|
|
38
|
+
throw new Error(`--provider must be "openai" or "anthropic", received: ${value}`);
|
|
39
|
+
}
|
|
34
40
|
function parseArgs(argv = process.argv.slice(2)) {
|
|
35
41
|
const config = {};
|
|
36
42
|
const options = {};
|
|
@@ -43,7 +49,11 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
43
49
|
for (let i = 0; i < argv.length; i++) {
|
|
44
50
|
const arg = argv[i];
|
|
45
51
|
const next = argv[i + 1];
|
|
46
|
-
if (arg === "--
|
|
52
|
+
if (arg === "--provider" && next !== undefined) {
|
|
53
|
+
config.provider = parseProviderOption(next);
|
|
54
|
+
i++;
|
|
55
|
+
}
|
|
56
|
+
else if (arg === "--model" && next !== undefined) {
|
|
47
57
|
config.model = next;
|
|
48
58
|
i++;
|
|
49
59
|
}
|
|
@@ -113,9 +123,10 @@ function printHelp(appConfig) {
|
|
|
113
123
|
"Usage: deepccc [options]",
|
|
114
124
|
"",
|
|
115
125
|
"Options:",
|
|
126
|
+
` --provider <name> API protocol: openai or anthropic (current default ${appConfig.provider})`,
|
|
116
127
|
` --model <name> Model name (current default ${appConfig.model})`,
|
|
117
128
|
` --effort <level> Reasoning effort: none/minimal/low/medium/high/xhigh/max (overrides config.effort)`,
|
|
118
|
-
` --base-url <url>
|
|
129
|
+
` --base-url <url> Provider API base URL (current default ${appConfig.baseURL})`,
|
|
119
130
|
" --api-key <key> API key",
|
|
120
131
|
" --cwd <path> Working directory",
|
|
121
132
|
" --max-steps <n> Optional tool-step limit. Omit for no step limit",
|
|
@@ -348,6 +359,7 @@ async function runRepl(args) {
|
|
|
348
359
|
process.exit(1);
|
|
349
360
|
}
|
|
350
361
|
console.log(`${C.dim}DeepCCC agent${C.reset}`);
|
|
362
|
+
console.log(`${C.dim}Provider: ${args.config.provider ?? appConfig.provider}${C.reset}`);
|
|
351
363
|
console.log(`${C.dim}Model: ${args.config.model ?? appConfig.model}${C.reset}`);
|
|
352
364
|
console.log(`${C.dim}Directory: ${cwd}${C.reset}`);
|
|
353
365
|
console.log(`${C.dim}Session: ${resolvedSession.sessionId} (${resolvedSession.mode === "new" ? "new" : "resumed"})${C.reset}`);
|
|
@@ -595,7 +607,8 @@ async function main() {
|
|
|
595
607
|
const args = parseArgs();
|
|
596
608
|
if (args.streamJson) {
|
|
597
609
|
const code = await runStreamJson(args);
|
|
598
|
-
process.
|
|
610
|
+
process.exitCode = code;
|
|
611
|
+
return;
|
|
599
612
|
}
|
|
600
613
|
if (args.help) {
|
|
601
614
|
const { appConfig } = await loadRuntime();
|
package/dist/config.d.ts
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
export type DeepCccProvider = "openai" | "anthropic";
|
|
1
2
|
export interface DeepCccConfig {
|
|
3
|
+
/** API protocol/provider. Defaults to OpenAI-compatible. */
|
|
4
|
+
provider: DeepCccProvider;
|
|
2
5
|
apiKey: string;
|
|
3
6
|
baseURL: string;
|
|
4
7
|
model: string;
|
|
5
8
|
/** Reasoning effort(none/minimal/low/medium/high/xhigh/max),留空不传 reasoning_effort */
|
|
6
9
|
effort: string;
|
|
10
|
+
/** 主对话是否使用流式请求;默认开启 */
|
|
11
|
+
streaming: boolean;
|
|
7
12
|
rawStreamLogs: {
|
|
8
13
|
enabled: boolean;
|
|
9
14
|
maxBytesPerTurn: number;
|
|
@@ -13,5 +18,6 @@ export interface DeepCccConfig {
|
|
|
13
18
|
}
|
|
14
19
|
export declare const DEEPCCC_HOME: string;
|
|
15
20
|
export declare const RAW_STREAM_LOGS_DIR: string;
|
|
21
|
+
export declare function normalizeDeepCccProvider(value: unknown): DeepCccProvider;
|
|
16
22
|
export declare function ensureConfigDir(): void;
|
|
17
23
|
export declare const config: DeepCccConfig;
|
package/dist/config.js
CHANGED
|
@@ -5,10 +5,12 @@ export const DEEPCCC_HOME = join(homedir(), ".deepccc");
|
|
|
5
5
|
export const RAW_STREAM_LOGS_DIR = join(DEEPCCC_HOME, "raw-stream-logs");
|
|
6
6
|
const CONFIG_PATH = join(DEEPCCC_HOME, "config.json");
|
|
7
7
|
const DEFAULT_CONFIG = {
|
|
8
|
+
provider: "openai",
|
|
8
9
|
apiKey: "",
|
|
9
10
|
baseURL: "https://api.deepseek.com/v1",
|
|
10
11
|
model: "deepseek-v4-pro",
|
|
11
12
|
effort: "",
|
|
13
|
+
streaming: true,
|
|
12
14
|
rawStreamLogs: {
|
|
13
15
|
enabled: false,
|
|
14
16
|
maxBytesPerTurn: 1024 * 1024,
|
|
@@ -40,16 +42,26 @@ function numberEnv(name) {
|
|
|
40
42
|
const value = Number(env(name));
|
|
41
43
|
return Number.isFinite(value) && value >= 0 ? value : undefined;
|
|
42
44
|
}
|
|
45
|
+
export function normalizeDeepCccProvider(value) {
|
|
46
|
+
if (value === undefined || value === null || String(value).trim() === "")
|
|
47
|
+
return "openai";
|
|
48
|
+
const normalized = String(value).trim().toLowerCase();
|
|
49
|
+
if (normalized === "openai" || normalized === "anthropic")
|
|
50
|
+
return normalized;
|
|
51
|
+
throw new Error(`DEEPCCC_PROVIDER/provider must be "openai" or "anthropic", received: ${String(value)}`);
|
|
52
|
+
}
|
|
43
53
|
function loadConfig() {
|
|
44
54
|
const file = readConfigFile();
|
|
45
55
|
const rawLogs = file.rawStreamLogs && typeof file.rawStreamLogs === "object"
|
|
46
56
|
? file.rawStreamLogs
|
|
47
57
|
: {};
|
|
48
58
|
return {
|
|
59
|
+
provider: normalizeDeepCccProvider(env("DEEPCCC_PROVIDER") ?? file.provider ?? DEFAULT_CONFIG.provider),
|
|
49
60
|
apiKey: env("DEEPCCC_API_KEY") ?? env("DEEPSEEK_API_KEY") ?? file.apiKey ?? DEFAULT_CONFIG.apiKey,
|
|
50
61
|
baseURL: env("DEEPCCC_BASE_URL") ?? env("DEEPSEEK_BASE_URL") ?? file.baseURL ?? DEFAULT_CONFIG.baseURL,
|
|
51
62
|
model: env("DEEPCCC_MODEL") ?? env("DEEPSEEK_MODEL") ?? file.model ?? DEFAULT_CONFIG.model,
|
|
52
63
|
effort: env("DEEPCCC_EFFORT") ?? env("DEEPSEEK_EFFORT") ?? file.effort ?? DEFAULT_CONFIG.effort,
|
|
64
|
+
streaming: boolEnv("DEEPCCC_STREAMING") ?? file.streaming ?? DEFAULT_CONFIG.streaming,
|
|
53
65
|
rawStreamLogs: {
|
|
54
66
|
enabled: boolEnv("DEEPCCC_RAW_STREAM_LOGS") ?? rawLogs.enabled ?? DEFAULT_CONFIG.rawStreamLogs.enabled,
|
|
55
67
|
maxBytesPerTurn: numberEnv("DEEPCCC_RAW_STREAM_MAX_BYTES") ?? rawLogs.maxBytesPerTurn ?? DEFAULT_CONFIG.rawStreamLogs.maxBytesPerTurn,
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* ChatSession 是程序化入口,既可以被 CLI 调用,也可以被其他模块调用。
|
|
5
5
|
*/
|
|
6
|
+
import { type DeepCccProvider } from "./config.js";
|
|
6
7
|
import { type PermissionMode, type PermissionResolver } from "./permissions.js";
|
|
7
8
|
export declare const DEFAULT_COMPACTION_TIMEOUT_MS: number;
|
|
8
9
|
/**
|
|
@@ -19,7 +20,9 @@ export declare function loadPlatformCommandPrompt(platform?: string, dirs?: {
|
|
|
19
20
|
userDir?: string;
|
|
20
21
|
}): string;
|
|
21
22
|
export interface ChatSessionConfig {
|
|
22
|
-
/**
|
|
23
|
+
/** API protocol/provider. Defaults to DEEPCCC_PROVIDER/config, then openai. */
|
|
24
|
+
provider?: DeepCccProvider;
|
|
25
|
+
/** Provider service base URL. Defaults to DEEPCCC_BASE_URL/config. */
|
|
23
26
|
baseURL?: string;
|
|
24
27
|
/** API key. Defaults to DEEPCCC_API_KEY/config. */
|
|
25
28
|
apiKey?: string;
|
|
@@ -107,6 +110,7 @@ interface ChatMessage {
|
|
|
107
110
|
}
|
|
108
111
|
export declare class ChatSession {
|
|
109
112
|
private model;
|
|
113
|
+
private provider;
|
|
110
114
|
private cwd;
|
|
111
115
|
private context;
|
|
112
116
|
private compactionTimeoutMs;
|
package/dist/index.js
CHANGED
|
@@ -4,12 +4,13 @@
|
|
|
4
4
|
* ChatSession 是程序化入口,既可以被 CLI 调用,也可以被其他模块调用。
|
|
5
5
|
*/
|
|
6
6
|
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
|
|
7
|
+
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
7
8
|
import { generateText, isLoopFinished, stepCountIs, streamText } from "ai";
|
|
8
9
|
import { existsSync, readFileSync } from "node:fs";
|
|
9
10
|
import { homedir } from "node:os";
|
|
10
11
|
import { join } from "node:path";
|
|
11
12
|
import { fileURLToPath } from "node:url";
|
|
12
|
-
import { config as appConfig, RAW_STREAM_LOGS_DIR } from "./config.js";
|
|
13
|
+
import { config as appConfig, normalizeDeepCccProvider, RAW_STREAM_LOGS_DIR, } from "./config.js";
|
|
13
14
|
import { createRawStreamLog, } from "./raw-stream-log.js";
|
|
14
15
|
import { buildPersistedAssistantMessage, buildSummaryPrompt, BuiltinContextManager, defaultBuiltinSessionId, } from "./context.js";
|
|
15
16
|
import { createBuiltinFileTools } from "./file-tools.js";
|
|
@@ -147,8 +148,13 @@ function normalizeMaxSteps(value) {
|
|
|
147
148
|
}
|
|
148
149
|
return value;
|
|
149
150
|
}
|
|
151
|
+
function normalizeAnthropicBaseURL(baseURL) {
|
|
152
|
+
const normalized = baseURL.trim().replace(/\/+$/, "");
|
|
153
|
+
return normalized.endsWith("/v1") ? normalized : `${normalized}/v1`;
|
|
154
|
+
}
|
|
150
155
|
export class ChatSession {
|
|
151
156
|
model;
|
|
157
|
+
provider;
|
|
152
158
|
cwd;
|
|
153
159
|
context;
|
|
154
160
|
compactionTimeoutMs;
|
|
@@ -166,13 +172,24 @@ export class ChatSession {
|
|
|
166
172
|
}
|
|
167
173
|
const baseURL = overrides.baseURL ?? appConfig.baseURL;
|
|
168
174
|
const modelId = overrides.model ?? appConfig.model;
|
|
175
|
+
this.provider = normalizeDeepCccProvider(overrides.provider ?? appConfig.provider);
|
|
169
176
|
this.effort = (overrides.effort ?? appConfig.effort ?? "").trim();
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
177
|
+
if (this.provider === "anthropic") {
|
|
178
|
+
const provider = createAnthropic({
|
|
179
|
+
baseURL: normalizeAnthropicBaseURL(baseURL),
|
|
180
|
+
apiKey,
|
|
181
|
+
});
|
|
182
|
+
this.model = provider(modelId);
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
const provider = createOpenAICompatible({
|
|
186
|
+
name: "deepccc",
|
|
187
|
+
baseURL,
|
|
188
|
+
apiKey,
|
|
189
|
+
includeUsage: true,
|
|
190
|
+
});
|
|
191
|
+
this.model = provider(modelId);
|
|
192
|
+
}
|
|
176
193
|
this.cwd = options.cwd ?? process.cwd();
|
|
177
194
|
this.maxSteps = normalizeMaxSteps(options.maxSteps);
|
|
178
195
|
this.compactionTimeoutMs = Math.max(1, options.compactionTimeoutMs ?? DEFAULT_COMPACTION_TIMEOUT_MS);
|
|
@@ -259,7 +276,7 @@ export class ChatSession {
|
|
|
259
276
|
const skills = await scanSkillsDirs(this.skillDirs);
|
|
260
277
|
const system = this.buildSystemPrompt(skills);
|
|
261
278
|
this.systemPrompt = system;
|
|
262
|
-
const
|
|
279
|
+
const generationOptions = {
|
|
263
280
|
model: this.model,
|
|
264
281
|
system,
|
|
265
282
|
messages: this.context.buildModelMessages(),
|
|
@@ -268,9 +285,19 @@ export class ChatSession {
|
|
|
268
285
|
abortSignal: signal,
|
|
269
286
|
// DeepSeek OpenAI 兼容接口:providerOptions.deepseek.reasoningEffort
|
|
270
287
|
// 由 @ai-sdk/openai-compatible 自动映射为请求体 reasoning_effort 字段
|
|
271
|
-
...(this.
|
|
272
|
-
|
|
273
|
-
|
|
288
|
+
...(this.provider === "openai" && this.effort
|
|
289
|
+
? { providerOptions: { deepseek: { reasoningEffort: this.effort } } }
|
|
290
|
+
: {}),
|
|
291
|
+
};
|
|
292
|
+
let stream;
|
|
293
|
+
if (appConfig.streaming) {
|
|
294
|
+
const result = streamText(generationOptions);
|
|
295
|
+
stream = result.fullStream ?? textStreamToFullStream(result.textStream);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
const result = await generateText(generationOptions);
|
|
299
|
+
stream = generateResultToFullStream(result);
|
|
300
|
+
}
|
|
274
301
|
for await (const part of stream) {
|
|
275
302
|
rawLog?.writeLine(safeRawStreamJson(part));
|
|
276
303
|
if (part.type === "text-delta") {
|
|
@@ -432,6 +459,34 @@ async function* textStreamToFullStream(stream) {
|
|
|
432
459
|
yield { type: "text-delta", text };
|
|
433
460
|
}
|
|
434
461
|
}
|
|
462
|
+
async function* generateResultToFullStream(result) {
|
|
463
|
+
let emittedText = false;
|
|
464
|
+
for (const step of result.steps ?? []) {
|
|
465
|
+
for (const call of step.toolCalls ?? []) {
|
|
466
|
+
yield {
|
|
467
|
+
type: "tool-call",
|
|
468
|
+
toolCallId: call.toolCallId,
|
|
469
|
+
toolName: call.toolName,
|
|
470
|
+
input: call.input,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
for (const toolResult of step.toolResults ?? []) {
|
|
474
|
+
yield {
|
|
475
|
+
type: "tool-result",
|
|
476
|
+
toolCallId: toolResult.toolCallId,
|
|
477
|
+
toolName: toolResult.toolName,
|
|
478
|
+
output: toolResult.output,
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
if (step.text) {
|
|
482
|
+
emittedText = true;
|
|
483
|
+
yield { type: "text-delta", text: step.text };
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (!emittedText && result.text) {
|
|
487
|
+
yield { type: "text-delta", text: result.text };
|
|
488
|
+
}
|
|
489
|
+
}
|
|
435
490
|
function safeJson(value) {
|
|
436
491
|
try {
|
|
437
492
|
return JSON.stringify(value);
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deepccc",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A lightweight
|
|
3
|
+
"version": "0.1.16",
|
|
4
|
+
"description": "A lightweight coding agent with OpenAI-compatible and Anthropic Messages API support.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"agent",
|
|
8
8
|
"deepseek",
|
|
9
9
|
"coding-agent",
|
|
10
10
|
"openai-compatible",
|
|
11
|
+
"anthropic",
|
|
11
12
|
"cli"
|
|
12
13
|
],
|
|
13
14
|
"repository": {
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"typecheck": "node node_modules/typescript/bin/tsc --noEmit"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
51
|
+
"@ai-sdk/anthropic": "^3.0.105",
|
|
50
52
|
"@ai-sdk/openai-compatible": "^2.0.47",
|
|
51
53
|
"@vscode/ripgrep": "^1.18.0",
|
|
52
54
|
"ai": "^6.0.184"
|