jinzd-ai-cli 0.4.54 → 0.4.56
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/{chunk-6FYFVPVE.js → chunk-2DC5ABAM.js} +220 -67
- package/dist/{chunk-NP5KZVP6.js → chunk-7FOGK5TM.js} +1 -1
- package/dist/{chunk-TAR67QTH.js → chunk-FJSEFQ54.js} +1 -1
- package/dist/{chunk-FOFQAEU6.js → chunk-REWBXK2G.js} +1 -1
- package/dist/{hub-6V54V4O3.js → hub-HQ5QX7CV.js} +1 -1
- package/dist/index.js +112 -42
- package/dist/{run-tests-6G65OGSL.js → run-tests-FRHDE3VB.js} +1 -1
- package/dist/{run-tests-P53FNUJY.js → run-tests-GISOOQZC.js} +1 -1
- package/dist/{server-BQHIMEBH.js → server-MOTFJN6L.js} +128 -29
- package/dist/{task-orchestrator-TSY7CJE6.js → task-orchestrator-6RGRKSTU.js} +2 -2
- package/dist/web/client/app.js +63 -1
- package/package.json +1 -1
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
ProviderNotFoundError,
|
|
8
8
|
RateLimitError,
|
|
9
9
|
schemaToJsonSchema
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-FJSEFQ54.js";
|
|
11
11
|
import {
|
|
12
12
|
APP_NAME,
|
|
13
13
|
CONFIG_DIR_NAME,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
MCP_TOOL_PREFIX,
|
|
21
21
|
PLUGINS_DIR_NAME,
|
|
22
22
|
VERSION
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-7FOGK5TM.js";
|
|
24
24
|
|
|
25
25
|
// src/config/config-manager.ts
|
|
26
26
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
@@ -172,6 +172,10 @@ var ConfigSchema = z.object({
|
|
|
172
172
|
// 建议范围:25(保守)~ 1000(宽松,接近 Claude Code)。
|
|
173
173
|
// CLI `--max-tool-rounds <n>` 可覆盖此值。
|
|
174
174
|
maxToolRounds: z.number().int().min(1).max(1e4).default(200),
|
|
175
|
+
// Auto-pause checkpoint:Agentic 循环每隔多少轮暂停一次,让用户确认方向或中途介入。
|
|
176
|
+
// 默认 50;设为 0 禁用(完全自动执行到完成或 maxToolRounds 用尽)。
|
|
177
|
+
// CLI 与 Web UI 行为一致:CLI 用 readline question 提示,Web UI 弹出对话框。
|
|
178
|
+
autoPauseInterval: z.number().int().min(0).max(1e4).default(50),
|
|
175
179
|
// 单次工具输出(如 read_file、bash、grep_files)返回给 AI 的最大字符数上限。
|
|
176
180
|
// 默认 500_000 (~500K chars ≈ 6000-8000 行代码)。
|
|
177
181
|
// 实际上限还会受模型 contextWindow 动态约束(取 contextWindow/4 作为下限)。
|
|
@@ -312,6 +316,7 @@ var BaseProvider = class {
|
|
|
312
316
|
};
|
|
313
317
|
|
|
314
318
|
// src/providers/claude.ts
|
|
319
|
+
var CACHE_MIN_SYSTEM_CHARS = 2e3;
|
|
315
320
|
var ClaudeProvider = class extends BaseProvider {
|
|
316
321
|
client;
|
|
317
322
|
info = {
|
|
@@ -382,6 +387,52 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
382
387
|
}
|
|
383
388
|
return blocks.length > 0 ? blocks : "";
|
|
384
389
|
}
|
|
390
|
+
/**
|
|
391
|
+
* Build a cacheable system prompt payload.
|
|
392
|
+
* When the prompt is long enough to be worth caching, return an array with a
|
|
393
|
+
* single text block carrying `cache_control: { type: 'ephemeral' }`. This caches
|
|
394
|
+
* system + memory + context files across every request in an agentic loop.
|
|
395
|
+
* Short prompts pass through as a plain string (no caching overhead).
|
|
396
|
+
*/
|
|
397
|
+
buildSystemParam(systemPrompt) {
|
|
398
|
+
if (!systemPrompt) return void 0;
|
|
399
|
+
if (systemPrompt.length < CACHE_MIN_SYSTEM_CHARS) return systemPrompt;
|
|
400
|
+
return [
|
|
401
|
+
{
|
|
402
|
+
type: "text",
|
|
403
|
+
text: systemPrompt,
|
|
404
|
+
cache_control: { type: "ephemeral" }
|
|
405
|
+
}
|
|
406
|
+
];
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Mark the last tool definition with `cache_control: ephemeral` so the entire
|
|
410
|
+
* tool block (all 24+ tools) is cached together. Anthropic caches everything
|
|
411
|
+
* up to and including a cache breakpoint, so one marker covers all tools.
|
|
412
|
+
* Returns a new array — does not mutate the input.
|
|
413
|
+
*/
|
|
414
|
+
addToolsCacheControl(tools) {
|
|
415
|
+
if (tools.length === 0) return tools;
|
|
416
|
+
const last = tools[tools.length - 1];
|
|
417
|
+
return [
|
|
418
|
+
...tools.slice(0, -1),
|
|
419
|
+
{ ...last, cache_control: { type: "ephemeral" } }
|
|
420
|
+
];
|
|
421
|
+
}
|
|
422
|
+
/** Extract usage (including cache fields) from an Anthropic response. */
|
|
423
|
+
extractUsage(u) {
|
|
424
|
+
const usage = {
|
|
425
|
+
inputTokens: u.input_tokens,
|
|
426
|
+
outputTokens: u.output_tokens
|
|
427
|
+
};
|
|
428
|
+
if (u.cache_creation_input_tokens != null && u.cache_creation_input_tokens > 0) {
|
|
429
|
+
usage.cacheCreationTokens = u.cache_creation_input_tokens;
|
|
430
|
+
}
|
|
431
|
+
if (u.cache_read_input_tokens != null && u.cache_read_input_tokens > 0) {
|
|
432
|
+
usage.cacheReadTokens = u.cache_read_input_tokens;
|
|
433
|
+
}
|
|
434
|
+
return usage;
|
|
435
|
+
}
|
|
385
436
|
/**
|
|
386
437
|
* 构建 Extended Thinking 参数。
|
|
387
438
|
* - thinking 启用时 temperature 必须为 1 或不设置(Anthropic API 要求)
|
|
@@ -432,7 +483,7 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
432
483
|
const response = await this.client.messages.create({
|
|
433
484
|
model: request.model,
|
|
434
485
|
messages,
|
|
435
|
-
system: request.systemPrompt,
|
|
486
|
+
system: this.buildSystemParam(request.systemPrompt),
|
|
436
487
|
max_tokens: request.maxTokens ?? 8192,
|
|
437
488
|
temperature,
|
|
438
489
|
thinking
|
|
@@ -441,10 +492,7 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
441
492
|
return {
|
|
442
493
|
content,
|
|
443
494
|
model: response.model,
|
|
444
|
-
usage:
|
|
445
|
-
inputTokens: response.usage.input_tokens,
|
|
446
|
-
outputTokens: response.usage.output_tokens
|
|
447
|
-
}
|
|
495
|
+
usage: this.extractUsage(response.usage)
|
|
448
496
|
};
|
|
449
497
|
} catch (err) {
|
|
450
498
|
throw this.wrapError(err);
|
|
@@ -460,7 +508,7 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
460
508
|
const stream = this.client.messages.stream({
|
|
461
509
|
model: request.model,
|
|
462
510
|
messages,
|
|
463
|
-
system: request.systemPrompt,
|
|
511
|
+
system: this.buildSystemParam(request.systemPrompt),
|
|
464
512
|
max_tokens: request.maxTokens ?? 8192,
|
|
465
513
|
temperature,
|
|
466
514
|
thinking
|
|
@@ -493,20 +541,22 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
493
541
|
}
|
|
494
542
|
async chatWithTools(request, tools) {
|
|
495
543
|
try {
|
|
496
|
-
const anthropicTools =
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
Object.
|
|
503
|
-
key,
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
544
|
+
const anthropicTools = this.addToolsCacheControl(
|
|
545
|
+
tools.map((t) => ({
|
|
546
|
+
name: t.name,
|
|
547
|
+
description: t.description,
|
|
548
|
+
input_schema: {
|
|
549
|
+
type: "object",
|
|
550
|
+
properties: Object.fromEntries(
|
|
551
|
+
Object.entries(t.parameters).map(([key, schema]) => [
|
|
552
|
+
key,
|
|
553
|
+
schemaToJsonSchema(schema)
|
|
554
|
+
])
|
|
555
|
+
),
|
|
556
|
+
required: Object.entries(t.parameters).filter(([, s]) => s.required).map(([k]) => k)
|
|
557
|
+
}
|
|
558
|
+
}))
|
|
559
|
+
);
|
|
510
560
|
const baseMessages = request.messages.filter((m) => m.role !== "system").map((m) => ({ role: m.role, content: this.contentToClaudeParts(m.content) }));
|
|
511
561
|
const extraMessages = request._extraMessages ?? [];
|
|
512
562
|
const allMessages = [...baseMessages, ...extraMessages];
|
|
@@ -515,15 +565,12 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
515
565
|
model: request.model,
|
|
516
566
|
messages: allMessages,
|
|
517
567
|
tools: anthropicTools,
|
|
518
|
-
system: request.systemPrompt,
|
|
568
|
+
system: this.buildSystemParam(request.systemPrompt),
|
|
519
569
|
max_tokens: request.maxTokens ?? 8192,
|
|
520
570
|
temperature,
|
|
521
571
|
thinking
|
|
522
572
|
});
|
|
523
|
-
const usage =
|
|
524
|
-
inputTokens: response.usage.input_tokens,
|
|
525
|
-
outputTokens: response.usage.output_tokens
|
|
526
|
-
};
|
|
573
|
+
const usage = this.extractUsage(response.usage);
|
|
527
574
|
const toolUseBlocks = response.content.filter(
|
|
528
575
|
(b) => b.type === "tool_use"
|
|
529
576
|
);
|
|
@@ -547,20 +594,22 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
547
594
|
* 同时收集原始 content blocks 供 buildToolResultMessages 使用。
|
|
548
595
|
*/
|
|
549
596
|
async *chatWithToolsStream(request, tools) {
|
|
550
|
-
const anthropicTools =
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
Object.
|
|
557
|
-
key,
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
597
|
+
const anthropicTools = this.addToolsCacheControl(
|
|
598
|
+
tools.map((t) => ({
|
|
599
|
+
name: t.name,
|
|
600
|
+
description: t.description,
|
|
601
|
+
input_schema: {
|
|
602
|
+
type: "object",
|
|
603
|
+
properties: Object.fromEntries(
|
|
604
|
+
Object.entries(t.parameters).map(([key, schema]) => [
|
|
605
|
+
key,
|
|
606
|
+
schemaToJsonSchema(schema)
|
|
607
|
+
])
|
|
608
|
+
),
|
|
609
|
+
required: Object.entries(t.parameters).filter(([, s]) => s.required).map(([k]) => k)
|
|
610
|
+
}
|
|
611
|
+
}))
|
|
612
|
+
);
|
|
564
613
|
const baseMessages = request.messages.filter((m) => m.role !== "system").map((m) => ({ role: m.role, content: this.contentToClaudeParts(m.content) }));
|
|
565
614
|
const extraMessages = request._extraMessages ?? [];
|
|
566
615
|
const allMessages = [...baseMessages, ...extraMessages];
|
|
@@ -572,7 +621,7 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
572
621
|
model: request.model,
|
|
573
622
|
messages: allMessages,
|
|
574
623
|
tools: anthropicTools,
|
|
575
|
-
system: request.systemPrompt,
|
|
624
|
+
system: this.buildSystemParam(request.systemPrompt),
|
|
576
625
|
max_tokens: request.maxTokens ?? 8192,
|
|
577
626
|
temperature,
|
|
578
627
|
thinking
|
|
@@ -580,7 +629,13 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
580
629
|
let currentBlockType = null;
|
|
581
630
|
let currentToolIndex = 0;
|
|
582
631
|
let currentBlockData = {};
|
|
632
|
+
let startUsage = null;
|
|
583
633
|
for await (const event of stream) {
|
|
634
|
+
if (event.type === "message_start") {
|
|
635
|
+
const msgUsage = event.message?.usage;
|
|
636
|
+
if (msgUsage) startUsage = msgUsage;
|
|
637
|
+
continue;
|
|
638
|
+
}
|
|
584
639
|
if (event.type === "content_block_start") {
|
|
585
640
|
const block = event.content_block;
|
|
586
641
|
currentBlockType = block.type;
|
|
@@ -641,15 +696,17 @@ var ClaudeProvider = class extends BaseProvider {
|
|
|
641
696
|
currentBlockType = null;
|
|
642
697
|
currentBlockData = {};
|
|
643
698
|
} else if (event.type === "message_delta") {
|
|
644
|
-
const
|
|
645
|
-
if (
|
|
699
|
+
const deltaUsage = event.usage;
|
|
700
|
+
if (deltaUsage) {
|
|
646
701
|
doneEmitted = true;
|
|
647
702
|
yield {
|
|
648
703
|
type: "done",
|
|
649
|
-
usage: {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
704
|
+
usage: this.extractUsage({
|
|
705
|
+
input_tokens: startUsage?.input_tokens ?? deltaUsage.input_tokens ?? 0,
|
|
706
|
+
output_tokens: deltaUsage.output_tokens ?? 0,
|
|
707
|
+
cache_creation_input_tokens: startUsage?.cache_creation_input_tokens,
|
|
708
|
+
cache_read_input_tokens: startUsage?.cache_read_input_tokens
|
|
709
|
+
}),
|
|
653
710
|
rawContent: rawContentBlocks
|
|
654
711
|
};
|
|
655
712
|
}
|
|
@@ -1003,6 +1060,16 @@ Node.js does not automatically use system proxies. Try one of the following:
|
|
|
1003
1060
|
|
|
1004
1061
|
// src/providers/openai-compatible.ts
|
|
1005
1062
|
import OpenAI from "openai";
|
|
1063
|
+
function toUsage(u) {
|
|
1064
|
+
if (!u) return void 0;
|
|
1065
|
+
const cached = u.prompt_tokens_details?.cached_tokens ?? 0;
|
|
1066
|
+
const usage = {
|
|
1067
|
+
inputTokens: Math.max(0, u.prompt_tokens - cached),
|
|
1068
|
+
outputTokens: u.completion_tokens
|
|
1069
|
+
};
|
|
1070
|
+
if (cached > 0) usage.cacheReadTokens = cached;
|
|
1071
|
+
return usage;
|
|
1072
|
+
}
|
|
1006
1073
|
var OpenAICompatibleProvider = class extends BaseProvider {
|
|
1007
1074
|
client;
|
|
1008
1075
|
defaultTimeout = 6e4;
|
|
@@ -1056,10 +1123,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1056
1123
|
return {
|
|
1057
1124
|
content: firstChoice.message.content ?? "",
|
|
1058
1125
|
model: response.model,
|
|
1059
|
-
usage: response.usage
|
|
1060
|
-
inputTokens: response.usage.prompt_tokens,
|
|
1061
|
-
outputTokens: response.usage.completion_tokens
|
|
1062
|
-
} : void 0
|
|
1126
|
+
usage: toUsage(response.usage)
|
|
1063
1127
|
};
|
|
1064
1128
|
} catch (err) {
|
|
1065
1129
|
throw this.wrapError(err);
|
|
@@ -1088,10 +1152,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1088
1152
|
yield {
|
|
1089
1153
|
delta: "",
|
|
1090
1154
|
done: true,
|
|
1091
|
-
usage:
|
|
1092
|
-
inputTokens: chunk.usage.prompt_tokens,
|
|
1093
|
-
outputTokens: chunk.usage.completion_tokens
|
|
1094
|
-
}
|
|
1155
|
+
usage: toUsage(chunk.usage)
|
|
1095
1156
|
};
|
|
1096
1157
|
continue;
|
|
1097
1158
|
}
|
|
@@ -1159,10 +1220,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1159
1220
|
return { content: "", usage: void 0 };
|
|
1160
1221
|
}
|
|
1161
1222
|
const message = firstChoice.message;
|
|
1162
|
-
const usage = response.usage
|
|
1163
|
-
inputTokens: response.usage.prompt_tokens,
|
|
1164
|
-
outputTokens: response.usage.completion_tokens
|
|
1165
|
-
} : void 0;
|
|
1223
|
+
const usage = toUsage(response.usage);
|
|
1166
1224
|
const reasoningContent = message.reasoning_content;
|
|
1167
1225
|
if (message.tool_calls && message.tool_calls.length > 0) {
|
|
1168
1226
|
const toolCalls = message.tool_calls.map((tc) => {
|
|
@@ -1275,10 +1333,7 @@ var OpenAICompatibleProvider = class extends BaseProvider {
|
|
|
1275
1333
|
}
|
|
1276
1334
|
yield {
|
|
1277
1335
|
type: "done",
|
|
1278
|
-
usage:
|
|
1279
|
-
inputTokens: chunk.usage.prompt_tokens,
|
|
1280
|
-
outputTokens: chunk.usage.completion_tokens
|
|
1281
|
-
}
|
|
1336
|
+
usage: toUsage(chunk.usage)
|
|
1282
1337
|
};
|
|
1283
1338
|
continue;
|
|
1284
1339
|
}
|
|
@@ -2331,7 +2386,12 @@ var Session = class _Session {
|
|
|
2331
2386
|
updated;
|
|
2332
2387
|
messages = [];
|
|
2333
2388
|
title;
|
|
2334
|
-
tokenUsage = {
|
|
2389
|
+
tokenUsage = {
|
|
2390
|
+
inputTokens: 0,
|
|
2391
|
+
outputTokens: 0,
|
|
2392
|
+
cacheCreationTokens: 0,
|
|
2393
|
+
cacheReadTokens: 0
|
|
2394
|
+
};
|
|
2335
2395
|
checkpoints = [];
|
|
2336
2396
|
constructor(id, provider, model) {
|
|
2337
2397
|
this.id = id;
|
|
@@ -2359,11 +2419,18 @@ var Session = class _Session {
|
|
|
2359
2419
|
addTokenUsage(usage) {
|
|
2360
2420
|
this.tokenUsage.inputTokens += usage.inputTokens;
|
|
2361
2421
|
this.tokenUsage.outputTokens += usage.outputTokens;
|
|
2422
|
+
this.tokenUsage.cacheCreationTokens += usage.cacheCreationTokens ?? 0;
|
|
2423
|
+
this.tokenUsage.cacheReadTokens += usage.cacheReadTokens ?? 0;
|
|
2362
2424
|
}
|
|
2363
2425
|
clear() {
|
|
2364
2426
|
this.messages = [];
|
|
2365
2427
|
this.title = void 0;
|
|
2366
|
-
this.tokenUsage = {
|
|
2428
|
+
this.tokenUsage = {
|
|
2429
|
+
inputTokens: 0,
|
|
2430
|
+
outputTokens: 0,
|
|
2431
|
+
cacheCreationTokens: 0,
|
|
2432
|
+
cacheReadTokens: 0
|
|
2433
|
+
};
|
|
2367
2434
|
this.updated = /* @__PURE__ */ new Date();
|
|
2368
2435
|
}
|
|
2369
2436
|
/**
|
|
@@ -2491,7 +2558,9 @@ var Session = class _Session {
|
|
|
2491
2558
|
if (tu && typeof tu === "object") {
|
|
2492
2559
|
session.tokenUsage = {
|
|
2493
2560
|
inputTokens: typeof tu.inputTokens === "number" ? tu.inputTokens : 0,
|
|
2494
|
-
outputTokens: typeof tu.outputTokens === "number" ? tu.outputTokens : 0
|
|
2561
|
+
outputTokens: typeof tu.outputTokens === "number" ? tu.outputTokens : 0,
|
|
2562
|
+
cacheCreationTokens: typeof tu.cacheCreationTokens === "number" ? tu.cacheCreationTokens : 0,
|
|
2563
|
+
cacheReadTokens: typeof tu.cacheReadTokens === "number" ? tu.cacheReadTokens : 0
|
|
2495
2564
|
};
|
|
2496
2565
|
}
|
|
2497
2566
|
if (Array.isArray(d.checkpoints)) {
|
|
@@ -3495,6 +3564,87 @@ async function setupProxy(configProxy) {
|
|
|
3495
3564
|
}
|
|
3496
3565
|
}
|
|
3497
3566
|
|
|
3567
|
+
// src/core/pricing.ts
|
|
3568
|
+
var PRICING_TABLE = {
|
|
3569
|
+
// ── Anthropic Claude ──────────────────────────────────────────
|
|
3570
|
+
"claude-opus-4-6": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
|
|
3571
|
+
"claude-opus-4-5": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
|
|
3572
|
+
"claude-sonnet-4-6": { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.3 },
|
|
3573
|
+
"claude-sonnet-4-5-20250929": { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.3 },
|
|
3574
|
+
"claude-haiku-4-5-20251001": { input: 1, output: 5, cacheWrite: 1.25, cacheRead: 0.1 },
|
|
3575
|
+
"claude-haiku-4-5": { input: 1, output: 5, cacheWrite: 1.25, cacheRead: 0.1 },
|
|
3576
|
+
// Legacy Claude 3.x families (prefix fallback handles minor date suffixes)
|
|
3577
|
+
"claude-3-5-sonnet": { input: 3, output: 15, cacheWrite: 3.75, cacheRead: 0.3 },
|
|
3578
|
+
"claude-3-5-haiku": { input: 0.8, output: 4, cacheWrite: 1, cacheRead: 0.08 },
|
|
3579
|
+
"claude-3-opus": { input: 15, output: 75, cacheWrite: 18.75, cacheRead: 1.5 },
|
|
3580
|
+
// ── OpenAI ────────────────────────────────────────────────────
|
|
3581
|
+
"gpt-4o": { input: 2.5, output: 10, cacheRead: 1.25 },
|
|
3582
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6, cacheRead: 0.075 },
|
|
3583
|
+
"gpt-4-turbo": { input: 10, output: 30 },
|
|
3584
|
+
"gpt-4": { input: 30, output: 60 },
|
|
3585
|
+
"gpt-4.1": { input: 2, output: 8, cacheRead: 0.5 },
|
|
3586
|
+
"gpt-4.1-mini": { input: 0.4, output: 1.6, cacheRead: 0.1 },
|
|
3587
|
+
"gpt-4.1-nano": { input: 0.1, output: 0.4, cacheRead: 0.025 },
|
|
3588
|
+
"o1": { input: 15, output: 60, cacheRead: 7.5 },
|
|
3589
|
+
"o1-mini": { input: 3, output: 12, cacheRead: 1.5 },
|
|
3590
|
+
"o3": { input: 10, output: 40, cacheRead: 2.5 },
|
|
3591
|
+
"o3-mini": { input: 1.1, output: 4.4, cacheRead: 0.55 },
|
|
3592
|
+
// ── Google Gemini ─────────────────────────────────────────────
|
|
3593
|
+
"gemini-2.5-pro": { input: 1.25, output: 10 },
|
|
3594
|
+
"gemini-2.5-flash": { input: 0.3, output: 2.5 },
|
|
3595
|
+
"gemini-2.0-flash": { input: 0.1, output: 0.4 },
|
|
3596
|
+
"gemini-1.5-pro": { input: 1.25, output: 5 },
|
|
3597
|
+
"gemini-1.5-flash": { input: 0.075, output: 0.3 },
|
|
3598
|
+
// ── DeepSeek ──────────────────────────────────────────────────
|
|
3599
|
+
"deepseek-chat": { input: 0.27, output: 1.1, cacheRead: 0.07 },
|
|
3600
|
+
"deepseek-reasoner": { input: 0.55, output: 2.19, cacheRead: 0.14 },
|
|
3601
|
+
"deepseek-v3": { input: 0.27, output: 1.1, cacheRead: 0.07 },
|
|
3602
|
+
// ── Moonshot Kimi ─────────────────────────────────────────────
|
|
3603
|
+
"moonshot-v1-8k": { input: 0.17, output: 0.17 },
|
|
3604
|
+
"moonshot-v1-32k": { input: 0.33, output: 0.33 },
|
|
3605
|
+
"moonshot-v1-128k": { input: 0.83, output: 0.83 },
|
|
3606
|
+
"kimi-k2": { input: 0.6, output: 2.5 },
|
|
3607
|
+
"kimi-latest": { input: 0.6, output: 2.5 },
|
|
3608
|
+
// ── Zhipu GLM ─────────────────────────────────────────────────
|
|
3609
|
+
"glm-4-plus": { input: 0.7, output: 0.7 },
|
|
3610
|
+
"glm-4": { input: 0.14, output: 0.14 },
|
|
3611
|
+
"glm-4-flash": { input: 0, output: 0 },
|
|
3612
|
+
"glm-4.5": { input: 0.29, output: 1.14 },
|
|
3613
|
+
"glm-4.6": { input: 0.6, output: 2.2 }
|
|
3614
|
+
// ── OpenRouter (pass-through — actual cost depends on underlying model) ──
|
|
3615
|
+
// Left empty; callers should resolve via underlying model ID.
|
|
3616
|
+
// ── Ollama (local, zero cost) ─────────────────────────────────
|
|
3617
|
+
// Handled via provider check below.
|
|
3618
|
+
};
|
|
3619
|
+
var FREE_PROVIDERS = /* @__PURE__ */ new Set(["ollama"]);
|
|
3620
|
+
function getPricing(provider, model) {
|
|
3621
|
+
if (FREE_PROVIDERS.has(provider.toLowerCase())) {
|
|
3622
|
+
return { input: 0, output: 0 };
|
|
3623
|
+
}
|
|
3624
|
+
const key = model.toLowerCase();
|
|
3625
|
+
if (PRICING_TABLE[key]) return PRICING_TABLE[key];
|
|
3626
|
+
const keys = Object.keys(PRICING_TABLE).sort((a, b) => b.length - a.length);
|
|
3627
|
+
for (const k of keys) {
|
|
3628
|
+
if (key.startsWith(k)) return PRICING_TABLE[k];
|
|
3629
|
+
}
|
|
3630
|
+
return null;
|
|
3631
|
+
}
|
|
3632
|
+
function computeCost(provider, model, usage) {
|
|
3633
|
+
const p = getPricing(provider, model);
|
|
3634
|
+
if (!p) return null;
|
|
3635
|
+
const input = usage.inputTokens * p.input;
|
|
3636
|
+
const output = usage.outputTokens * p.output;
|
|
3637
|
+
const cacheWrite = (usage.cacheCreationTokens ?? 0) * (p.cacheWrite ?? p.input);
|
|
3638
|
+
const cacheRead = (usage.cacheReadTokens ?? 0) * (p.cacheRead ?? p.input);
|
|
3639
|
+
return (input + output + cacheWrite + cacheRead) / 1e6;
|
|
3640
|
+
}
|
|
3641
|
+
function formatCost(amount) {
|
|
3642
|
+
if (amount === 0) return "$0.0000";
|
|
3643
|
+
if (amount < 0.01) return `$${amount.toFixed(4)}`;
|
|
3644
|
+
if (amount < 1) return `$${amount.toFixed(3)}`;
|
|
3645
|
+
return `$${amount.toFixed(2)}`;
|
|
3646
|
+
}
|
|
3647
|
+
|
|
3498
3648
|
// src/repl/dev-state.ts
|
|
3499
3649
|
import { existsSync as existsSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync3, unlinkSync as unlinkSync2, mkdirSync as mkdirSync4 } from "fs";
|
|
3500
3650
|
import { join as join5 } from "path";
|
|
@@ -3601,6 +3751,9 @@ export {
|
|
|
3601
3751
|
getGitRoot,
|
|
3602
3752
|
getGitContext,
|
|
3603
3753
|
formatGitContextForPrompt,
|
|
3754
|
+
getPricing,
|
|
3755
|
+
computeCost,
|
|
3756
|
+
formatCost,
|
|
3604
3757
|
parseSimpleYaml,
|
|
3605
3758
|
SNAPSHOT_PROMPT,
|
|
3606
3759
|
sessionHasMeaningfulContent,
|
|
@@ -385,7 +385,7 @@ ${content}`);
|
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
388
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
388
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-6RGRKSTU.js");
|
|
389
389
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
390
390
|
let interrupted = false;
|
|
391
391
|
const onSigint = () => {
|