clawmoney 0.10.18 → 0.10.20
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/relay/executor.js +12 -11
- package/dist/relay/pricing.d.ts +7 -2
- package/dist/relay/pricing.js +11 -3
- package/dist/relay/provider.js +15 -11
- package/dist/relay/types.d.ts +7 -2
- package/package.json +1 -1
package/dist/relay/executor.js
CHANGED
|
@@ -100,24 +100,23 @@ export function parseClaudeOutput(raw) {
|
|
|
100
100
|
// modelUsage is a dict: { "model-name": { inputTokens, outputTokens, cacheReadInputTokens, ... } }
|
|
101
101
|
let inputTokens = 0;
|
|
102
102
|
let outputTokens = 0;
|
|
103
|
-
let
|
|
103
|
+
let cacheCreationTokens = 0;
|
|
104
|
+
let cacheReadTokens = 0;
|
|
104
105
|
let model = "";
|
|
105
106
|
const modelUsage = obj.modelUsage;
|
|
106
107
|
if (modelUsage) {
|
|
107
108
|
for (const [modelName, usage] of Object.entries(modelUsage)) {
|
|
108
109
|
model = modelName;
|
|
109
|
-
|
|
110
|
-
inputTokens += (usage.inputTokens ?? 0)
|
|
111
|
-
+ (usage.cacheCreationInputTokens ?? 0)
|
|
112
|
-
+ (usage.cacheReadInputTokens ?? 0);
|
|
110
|
+
inputTokens += usage.inputTokens ?? 0;
|
|
113
111
|
outputTokens += usage.outputTokens ?? 0;
|
|
114
|
-
|
|
112
|
+
cacheCreationTokens += usage.cacheCreationInputTokens ?? 0;
|
|
113
|
+
cacheReadTokens += usage.cacheReadInputTokens ?? 0;
|
|
115
114
|
}
|
|
116
115
|
}
|
|
117
116
|
return {
|
|
118
117
|
text,
|
|
119
118
|
sessionId,
|
|
120
|
-
usage: { input_tokens: inputTokens, output_tokens: outputTokens,
|
|
119
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens, cache_creation_tokens: cacheCreationTokens, cache_read_tokens: cacheReadTokens },
|
|
121
120
|
model,
|
|
122
121
|
costUsd,
|
|
123
122
|
};
|
|
@@ -126,7 +125,7 @@ export function parseClaudeOutput(raw) {
|
|
|
126
125
|
return {
|
|
127
126
|
text: raw.trim().slice(0, 5000),
|
|
128
127
|
sessionId: "",
|
|
129
|
-
usage: { input_tokens: 0, output_tokens: 0 },
|
|
128
|
+
usage: { input_tokens: 0, output_tokens: 0, cache_creation_tokens: 0, cache_read_tokens: 0 },
|
|
130
129
|
model: "",
|
|
131
130
|
costUsd: 0,
|
|
132
131
|
};
|
|
@@ -173,7 +172,7 @@ export function parseCodexOutput(raw) {
|
|
|
173
172
|
return {
|
|
174
173
|
text: text || raw.trim().slice(0, 5000),
|
|
175
174
|
sessionId: threadId,
|
|
176
|
-
usage: { input_tokens: inputTokens, output_tokens: outputTokens },
|
|
175
|
+
usage: { input_tokens: inputTokens, output_tokens: outputTokens, cache_creation_tokens: 0, cache_read_tokens: 0 },
|
|
177
176
|
model,
|
|
178
177
|
costUsd: 0,
|
|
179
178
|
};
|
|
@@ -193,6 +192,7 @@ export function parseGeminiOutput(raw) {
|
|
|
193
192
|
const sessionId = obj.session_id ?? "";
|
|
194
193
|
let inputTokens = 0;
|
|
195
194
|
let outputTokens = 0;
|
|
195
|
+
let cachedTokens = 0;
|
|
196
196
|
let model = "";
|
|
197
197
|
const stats = obj.stats;
|
|
198
198
|
const models = stats?.models;
|
|
@@ -203,13 +203,14 @@ export function parseGeminiOutput(raw) {
|
|
|
203
203
|
if (tokens) {
|
|
204
204
|
inputTokens += tokens.input ?? tokens.prompt ?? 0;
|
|
205
205
|
outputTokens += tokens.candidates ?? tokens.output ?? 0;
|
|
206
|
+
cachedTokens += tokens.cached ?? 0;
|
|
206
207
|
}
|
|
207
208
|
}
|
|
208
209
|
}
|
|
209
210
|
return {
|
|
210
211
|
text,
|
|
211
212
|
sessionId,
|
|
212
|
-
usage: { input_tokens: inputTokens, output_tokens: outputTokens },
|
|
213
|
+
usage: { input_tokens: inputTokens - cachedTokens, output_tokens: outputTokens, cache_creation_tokens: 0, cache_read_tokens: cachedTokens },
|
|
213
214
|
model,
|
|
214
215
|
costUsd: 0,
|
|
215
216
|
};
|
|
@@ -218,7 +219,7 @@ export function parseGeminiOutput(raw) {
|
|
|
218
219
|
return {
|
|
219
220
|
text: raw.trim().slice(0, 5000),
|
|
220
221
|
sessionId: "",
|
|
221
|
-
usage: { input_tokens: 0, output_tokens: 0 },
|
|
222
|
+
usage: { input_tokens: 0, output_tokens: 0, cache_creation_tokens: 0, cache_read_tokens: 0 },
|
|
222
223
|
model: "",
|
|
223
224
|
costUsd: 0,
|
|
224
225
|
};
|
package/dist/relay/pricing.d.ts
CHANGED
|
@@ -13,8 +13,13 @@ export declare const API_PRICES: Record<string, ModelPricing>;
|
|
|
13
13
|
export declare const RELAY_DISCOUNT = 0.3;
|
|
14
14
|
export declare const PLATFORM_FEE = 0.05;
|
|
15
15
|
export declare function getModelPricing(model: string): ModelPricing;
|
|
16
|
-
export
|
|
16
|
+
export interface CostBreakdown {
|
|
17
|
+
inputCost: number;
|
|
18
|
+
cacheCreationCost: number;
|
|
19
|
+
cacheReadCost: number;
|
|
20
|
+
outputCost: number;
|
|
17
21
|
apiCost: number;
|
|
18
22
|
relayCost: number;
|
|
19
23
|
providerEarn: number;
|
|
20
|
-
}
|
|
24
|
+
}
|
|
25
|
+
export declare function calculateCost(model: string, inputTokens: number, outputTokens: number, cacheCreationTokens?: number, cacheReadTokens?: number): CostBreakdown;
|
package/dist/relay/pricing.js
CHANGED
|
@@ -36,10 +36,18 @@ export const PLATFORM_FEE = 0.05; // 5%
|
|
|
36
36
|
export function getModelPricing(model) {
|
|
37
37
|
return API_PRICES[model] ?? DEFAULT_PRICING;
|
|
38
38
|
}
|
|
39
|
-
|
|
39
|
+
// Cache pricing multipliers (relative to base input price)
|
|
40
|
+
const CACHE_WRITE_MULTIPLIER = 1.25; // 5-minute cache write
|
|
41
|
+
const CACHE_READ_MULTIPLIER = 0.10; // cache hit
|
|
42
|
+
export function calculateCost(model, inputTokens, outputTokens, cacheCreationTokens = 0, cacheReadTokens = 0) {
|
|
40
43
|
const p = getModelPricing(model);
|
|
41
|
-
const
|
|
44
|
+
const M = 1_000_000;
|
|
45
|
+
const inputCost = (inputTokens * p.input) / M;
|
|
46
|
+
const cacheCreationCost = (cacheCreationTokens * p.input * CACHE_WRITE_MULTIPLIER) / M;
|
|
47
|
+
const cacheReadCost = (cacheReadTokens * p.input * CACHE_READ_MULTIPLIER) / M;
|
|
48
|
+
const outputCost = (outputTokens * p.output) / M;
|
|
49
|
+
const apiCost = inputCost + cacheCreationCost + cacheReadCost + outputCost;
|
|
42
50
|
const relayCost = apiCost * RELAY_DISCOUNT;
|
|
43
51
|
const providerEarn = relayCost * (1 - PLATFORM_FEE);
|
|
44
|
-
return { apiCost, relayCost, providerEarn };
|
|
52
|
+
return { inputCost, cacheCreationCost, cacheReadCost, outputCost, apiCost, relayCost, providerEarn };
|
|
45
53
|
}
|
package/dist/relay/provider.js
CHANGED
|
@@ -97,7 +97,9 @@ async function executeRelayRequest(request, config) {
|
|
|
97
97
|
const { request_id, max_budget_usd } = request;
|
|
98
98
|
const cliType = request.cli_type ?? config.relay.cli_type;
|
|
99
99
|
const model = request.model ?? config.relay.model;
|
|
100
|
-
|
|
100
|
+
const stateful = request.stateful ?? false;
|
|
101
|
+
const cliSessionId = request.cli_session_id ?? undefined;
|
|
102
|
+
// Build prompt from messages
|
|
101
103
|
const prompt = request.messages
|
|
102
104
|
? messagesToPrompt(request.messages)
|
|
103
105
|
: request.prompt ?? "";
|
|
@@ -107,33 +109,35 @@ async function executeRelayRequest(request, config) {
|
|
|
107
109
|
const turns = request.messages
|
|
108
110
|
? request.messages.filter((m) => m.role === "user").length
|
|
109
111
|
: 1;
|
|
112
|
+
const modeLabel = stateful
|
|
113
|
+
? (cliSessionId ? `stateful[resume ${cliSessionId.slice(0, 8)}]` : "stateful[new]")
|
|
114
|
+
: "stateless";
|
|
110
115
|
logger.info(` ┌─ Request ${request_id.slice(0, 8)}`);
|
|
111
|
-
logger.info(` │ CLI: ${cliType} / ${model}`);
|
|
116
|
+
logger.info(` │ CLI: ${cliType} / ${model} (${modeLabel})`);
|
|
112
117
|
logger.info(` │ Turns: ${turns}`);
|
|
113
118
|
logger.info(` │ Prompt: ${String(lastUserMsg).slice(0, 80)}`);
|
|
114
119
|
try {
|
|
115
|
-
// No session_id — each request is stateless, full history in prompt
|
|
116
120
|
const startMs = Date.now();
|
|
117
|
-
|
|
121
|
+
// In stateful mode, pass cli_session_id so buildCliArgs adds --resume
|
|
122
|
+
const args = buildCliArgs(cliType, prompt, cliSessionId, max_budget_usd, model);
|
|
118
123
|
const raw = await spawnCli(cliType, args);
|
|
119
124
|
const elapsedMs = Date.now() - startMs;
|
|
120
125
|
const parsed = parseCliOutput(cliType, raw);
|
|
121
126
|
const answer = parsed.text.replace(/\n/g, " ").slice(0, 80);
|
|
122
|
-
const inT = parsed.usage
|
|
123
|
-
const
|
|
124
|
-
const cachedT = parsed.usage.cached_tokens ?? 0;
|
|
125
|
-
const { apiCost, relayCost, providerEarn } = calculateCost(model, inT, outT);
|
|
127
|
+
const { input_tokens: inT, output_tokens: outT, cache_creation_tokens: cacheWriteT, cache_read_tokens: cacheReadT } = parsed.usage;
|
|
128
|
+
const cost = calculateCost(model, inT, outT, cacheWriteT, cacheReadT);
|
|
126
129
|
const elapsedSec = (elapsedMs / 1000).toFixed(1);
|
|
127
130
|
logger.info(` │ Answer: ${answer}`);
|
|
128
|
-
logger.info(` │ Tokens:
|
|
131
|
+
logger.info(` │ Tokens: input=${inT} cache_write=${cacheWriteT} cache_read=${cacheReadT} output=${outT}`);
|
|
129
132
|
logger.info(` │ Time: ${elapsedSec}s`);
|
|
130
|
-
logger.info(` │ Cost:
|
|
133
|
+
logger.info(` │ Cost: input=$${cost.inputCost.toFixed(4)} cache_w=$${cost.cacheCreationCost.toFixed(4)} cache_r=$${cost.cacheReadCost.toFixed(4)} output=$${cost.outputCost.toFixed(4)}`);
|
|
134
|
+
logger.info(` │ Total: API $${cost.apiCost.toFixed(4)} → Relay $${cost.relayCost.toFixed(4)} → Earn $${cost.providerEarn.toFixed(4)}`);
|
|
131
135
|
logger.info(` └─ Done`);
|
|
132
136
|
return {
|
|
133
137
|
event: "relay_response",
|
|
134
138
|
request_id,
|
|
135
139
|
content: parsed.text,
|
|
136
|
-
|
|
140
|
+
cli_session_id: parsed.sessionId || undefined,
|
|
137
141
|
usage: parsed.usage,
|
|
138
142
|
model_used: parsed.model || model,
|
|
139
143
|
cost_usd: parsed.costUsd || undefined,
|
package/dist/relay/types.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export interface RelayRequest {
|
|
|
8
8
|
}>;
|
|
9
9
|
cli_type?: string;
|
|
10
10
|
session_id?: string;
|
|
11
|
+
cli_session_id?: string | null;
|
|
12
|
+
stateful?: boolean;
|
|
11
13
|
model?: string;
|
|
12
14
|
max_budget_usd?: number;
|
|
13
15
|
}
|
|
@@ -27,10 +29,12 @@ export interface RelayResponse {
|
|
|
27
29
|
request_id: string;
|
|
28
30
|
content: string;
|
|
29
31
|
session_id?: string;
|
|
32
|
+
cli_session_id?: string;
|
|
30
33
|
usage?: {
|
|
31
34
|
input_tokens: number;
|
|
32
35
|
output_tokens: number;
|
|
33
|
-
|
|
36
|
+
cache_creation_tokens?: number;
|
|
37
|
+
cache_read_tokens?: number;
|
|
34
38
|
};
|
|
35
39
|
model_used?: string;
|
|
36
40
|
cost_usd?: number;
|
|
@@ -43,7 +47,8 @@ export interface ParsedOutput {
|
|
|
43
47
|
usage: {
|
|
44
48
|
input_tokens: number;
|
|
45
49
|
output_tokens: number;
|
|
46
|
-
|
|
50
|
+
cache_creation_tokens: number;
|
|
51
|
+
cache_read_tokens: number;
|
|
47
52
|
};
|
|
48
53
|
model: string;
|
|
49
54
|
costUsd: number;
|