@costwise/sdk 0.0.1 → 0.0.3
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 +176 -0
- package/dist/cjs/cli.d.ts +3 -0
- package/dist/cjs/cli.d.ts.map +1 -0
- package/dist/cjs/cli.js +156 -0
- package/dist/cjs/cli.js.map +1 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/src/anthropic.d.ts +10 -0
- package/dist/cjs/src/anthropic.d.ts.map +1 -0
- package/dist/cjs/src/anthropic.js +55 -0
- package/dist/cjs/src/anthropic.js.map +1 -0
- package/dist/cjs/src/openai.d.ts +9 -0
- package/dist/cjs/src/openai.d.ts.map +1 -0
- package/dist/cjs/src/openai.js +51 -0
- package/dist/cjs/src/openai.js.map +1 -0
- package/dist/cjs/src/tracker.d.ts +23 -0
- package/dist/cjs/src/tracker.d.ts.map +1 -0
- package/dist/cjs/src/tracker.js +212 -0
- package/dist/cjs/src/tracker.js.map +1 -0
- package/dist/cjs/src/types.d.ts +56 -0
- package/dist/cjs/src/types.d.ts.map +1 -0
- package/dist/cjs/src/types.js +3 -0
- package/dist/cjs/src/types.js.map +1 -0
- package/dist/esm/cli.d.ts +3 -0
- package/dist/esm/cli.d.ts.map +1 -0
- package/dist/esm/cli.js +154 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/src/anthropic.d.ts +10 -0
- package/dist/esm/src/anthropic.d.ts.map +1 -0
- package/dist/esm/src/anthropic.js +48 -0
- package/dist/esm/src/anthropic.js.map +1 -0
- package/dist/esm/src/openai.d.ts +9 -0
- package/dist/esm/src/openai.d.ts.map +1 -0
- package/dist/esm/src/openai.js +44 -0
- package/dist/esm/src/openai.js.map +1 -0
- package/dist/esm/src/tracker.d.ts +23 -0
- package/dist/esm/src/tracker.d.ts.map +1 -0
- package/dist/esm/src/tracker.js +207 -0
- package/dist/esm/src/tracker.js.map +1 -0
- package/dist/esm/src/types.d.ts +56 -0
- package/dist/esm/src/types.d.ts.map +1 -0
- package/dist/esm/src/types.js +2 -0
- package/dist/esm/src/types.js.map +1 -0
- package/package.json +36 -2
- package/index.js +0 -3
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# @costwise/sdk
|
|
2
|
+
|
|
3
|
+
Track Anthropic and OpenAI API usage costs with a drop-in SDK wrapper.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @costwise/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
Replace:
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import OpenAI from "openai";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
with:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { CostwiseOpenAI } from "@costwise/sdk";
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Then initialize as usual:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { CostwiseOpenAI, CostwiseAnthropic } from "@costwise/sdk";
|
|
29
|
+
|
|
30
|
+
const openai = new CostwiseOpenAI({
|
|
31
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
32
|
+
costwiseKey: process.env.COSTWISE_API_KEY,
|
|
33
|
+
tag: "my-app"
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const anthropic = new CostwiseAnthropic({
|
|
37
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
38
|
+
costwiseKey: process.env.COSTWISE_API_KEY,
|
|
39
|
+
tag: "my-app"
|
|
40
|
+
});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
After each response, Costwise sends a non-blocking ingest event to:
|
|
44
|
+
|
|
45
|
+
`https://api.costwise.dev/ingest`
|
|
46
|
+
|
|
47
|
+
Tracking is fire-and-forget and never awaited, so request latency is not impacted. If ingest is unreachable, it fails silently.
|
|
48
|
+
|
|
49
|
+
## Environment variables
|
|
50
|
+
|
|
51
|
+
- `COSTWISE_API_KEY` (optional if `costwiseKey` is provided in constructor)
|
|
52
|
+
- Constructor key aliases supported: `costwiseKey` (canonical) and `costswiseKey` (compatibility alias)
|
|
53
|
+
- `COSTWISE_LOCAL_USAGE_PATH` (optional JSONL file path for local usage history used by CLI)
|
|
54
|
+
|
|
55
|
+
## Ingest payload
|
|
56
|
+
|
|
57
|
+
The SDK emits:
|
|
58
|
+
|
|
59
|
+
- `model`
|
|
60
|
+
- `input_tokens`
|
|
61
|
+
- `output_tokens`
|
|
62
|
+
- `cost` and `estimated_cost`
|
|
63
|
+
- `tag` and `endpoint_tag` (optional)
|
|
64
|
+
- `ts` and `timestamp`
|
|
65
|
+
|
|
66
|
+
## Compare model costs and capacity
|
|
67
|
+
|
|
68
|
+
Use tracker utilities to estimate what other models would have cost for the same token usage:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
import { CostwiseTracker } from "@costwise/sdk";
|
|
72
|
+
|
|
73
|
+
const tracker = new CostwiseTracker({
|
|
74
|
+
costwiseKey: process.env.COSTWISE_API_KEY
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const comparisons = tracker.compareCosts({
|
|
78
|
+
model: "gpt-4o",
|
|
79
|
+
inputTokens: 12000,
|
|
80
|
+
outputTokens: 2500
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const summary = tracker.summarizeComparison({
|
|
84
|
+
model: "gpt-4o",
|
|
85
|
+
inputTokens: 12000,
|
|
86
|
+
outputTokens: 2500
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`compareCosts()` returns each model's estimated cost and capacity metadata (context window and capacity class), sorted cheapest-first.
|
|
91
|
+
|
|
92
|
+
Group by capacity tier and read the cheapest model per tier:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
const { byClass, cheapestPerClass } = tracker.compareCostsByCapacity({
|
|
96
|
+
model: "gpt-4o",
|
|
97
|
+
inputTokens: 12000,
|
|
98
|
+
outputTokens: 2500
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// e.g. cheapestPerClass.mini?.model, cheapestPerClass.high?.estimatedCost
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`byClass` maps `nano` | `mini` | `standard` | `high` | `frontier` to full lists (cheapest-first within each class). `cheapestPerClass` is the single best-priced model in each class that has at least one priced model.
|
|
105
|
+
|
|
106
|
+
Format a ready-to-print CLI summary (without logging inside the SDK):
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
const cli = tracker.formatComparisonForCli({
|
|
110
|
+
model: "gpt-4o",
|
|
111
|
+
inputTokens: 12000,
|
|
112
|
+
outputTokens: 2500
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// App decides if/where to print:
|
|
116
|
+
// console.log(cli.text)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Smoke test
|
|
120
|
+
|
|
121
|
+
Run a local end-to-end smoke test (build + mocked ingest + comparison output):
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm run smoke
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## CLI for actual usage
|
|
128
|
+
|
|
129
|
+
The CLI reads **real usage events** from a local JSONL file written by the SDK at runtime.
|
|
130
|
+
|
|
131
|
+
1) Set a usage file path in your app environment:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
export COSTWISE_LOCAL_USAGE_PATH=.costwise-usage.jsonl
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
2) Run your app so events are recorded.
|
|
138
|
+
|
|
139
|
+
3) Query usage and compare alternatives:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
costwise usage
|
|
143
|
+
costwise compare-actual
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Optional:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
costwise usage --file .costwise-usage.jsonl --json
|
|
150
|
+
costwise compare-actual --file .costwise-usage.jsonl --json
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Automated tests
|
|
154
|
+
|
|
155
|
+
Run the Node test suite (build + unit tests):
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
npm test
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Current test coverage includes:
|
|
162
|
+
|
|
163
|
+
- Tracker cost math correctness for known models
|
|
164
|
+
- Unknown model handling (no ingest + empty comparison)
|
|
165
|
+
- Fire-and-forget tracking behavior (`fetch` not awaited)
|
|
166
|
+
- Silent ingest failure handling (`.catch(() => {})`)
|
|
167
|
+
- `compareCostsByCapacity()` output shape
|
|
168
|
+
- `formatComparisonForCli()` output shape
|
|
169
|
+
- OpenAI wrapper behavior:
|
|
170
|
+
- non-stream response returned untouched
|
|
171
|
+
- stream response returned untouched
|
|
172
|
+
- stream tracking via `finalChatCompletion()`
|
|
173
|
+
- Anthropic wrapper behavior:
|
|
174
|
+
- non-stream response returned untouched
|
|
175
|
+
- stream response returned untouched
|
|
176
|
+
- stream tracking via `finalMessage()`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../cli.ts"],"names":[],"mappings":""}
|
package/dist/cjs/cli.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const promises_1 = require("node:fs/promises");
|
|
5
|
+
const tracker_js_1 = require("./src/tracker.js");
|
|
6
|
+
function help(exitCode) {
|
|
7
|
+
process.stdout.write([
|
|
8
|
+
"Costwise CLI (actual usage only)",
|
|
9
|
+
"",
|
|
10
|
+
"Usage:",
|
|
11
|
+
" costwise usage [--file <path>] [--json]",
|
|
12
|
+
" costwise compare-actual [--file <path>] [--json]",
|
|
13
|
+
"",
|
|
14
|
+
"Notes:",
|
|
15
|
+
" - Reads usage events from JSONL recorded by SDK (`COSTWISE_LOCAL_USAGE_PATH`).",
|
|
16
|
+
" - No manual token input flags are supported."
|
|
17
|
+
].join("\n") + "\n");
|
|
18
|
+
process.exit(exitCode);
|
|
19
|
+
}
|
|
20
|
+
function parse(argv) {
|
|
21
|
+
if (argv.length === 0 || argv.includes("--help") || argv.includes("-h")) {
|
|
22
|
+
help(0);
|
|
23
|
+
}
|
|
24
|
+
const options = { json: false };
|
|
25
|
+
const first = argv[0];
|
|
26
|
+
if (first === "usage" || first === "compare-actual") {
|
|
27
|
+
options.command = first;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
help(1);
|
|
31
|
+
}
|
|
32
|
+
for (let i = 1; i < argv.length; i += 1) {
|
|
33
|
+
const arg = argv[i];
|
|
34
|
+
const next = argv[i + 1];
|
|
35
|
+
if (arg === "--file" && next) {
|
|
36
|
+
options.filePath = next;
|
|
37
|
+
i += 1;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (arg === "--json") {
|
|
41
|
+
options.json = true;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
help(1);
|
|
45
|
+
}
|
|
46
|
+
return options;
|
|
47
|
+
}
|
|
48
|
+
async function loadEvents(path) {
|
|
49
|
+
const content = await (0, promises_1.readFile)(path, "utf8");
|
|
50
|
+
const lines = content.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
51
|
+
return lines.map((line) => JSON.parse(line));
|
|
52
|
+
}
|
|
53
|
+
function runUsage(events, asJson) {
|
|
54
|
+
const totals = events.reduce((acc, event) => {
|
|
55
|
+
acc.input += event.input_tokens;
|
|
56
|
+
acc.output += event.output_tokens;
|
|
57
|
+
acc.cost += event.estimated_cost;
|
|
58
|
+
acc.byModel[event.model] = (acc.byModel[event.model] ?? 0) + event.estimated_cost;
|
|
59
|
+
return acc;
|
|
60
|
+
}, { input: 0, output: 0, cost: 0, byModel: {} });
|
|
61
|
+
const topModels = Object.entries(totals.byModel)
|
|
62
|
+
.map(([model, cost]) => ({ model, cost }))
|
|
63
|
+
.sort((a, b) => b.cost - a.cost)
|
|
64
|
+
.slice(0, 5);
|
|
65
|
+
if (asJson) {
|
|
66
|
+
process.stdout.write(`${JSON.stringify({
|
|
67
|
+
events: events.length,
|
|
68
|
+
input_tokens: totals.input,
|
|
69
|
+
output_tokens: totals.output,
|
|
70
|
+
estimated_cost: totals.cost,
|
|
71
|
+
top_models: topModels
|
|
72
|
+
}, null, 2)}\n`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const lines = [
|
|
76
|
+
`Events: ${events.length}`,
|
|
77
|
+
`Input tokens: ${totals.input}`,
|
|
78
|
+
`Output tokens: ${totals.output}`,
|
|
79
|
+
`Estimated cost: $${totals.cost.toFixed(6)}`,
|
|
80
|
+
"Top models by spend:"
|
|
81
|
+
];
|
|
82
|
+
for (const model of topModels) {
|
|
83
|
+
lines.push(` - ${model.model}: $${model.cost.toFixed(6)}`);
|
|
84
|
+
}
|
|
85
|
+
process.stdout.write(`${lines.join("\n")}\n`);
|
|
86
|
+
}
|
|
87
|
+
function runCompareActual(events, asJson) {
|
|
88
|
+
const totalInput = events.reduce((sum, event) => sum + event.input_tokens, 0);
|
|
89
|
+
const totalOutput = events.reduce((sum, event) => sum + event.output_tokens, 0);
|
|
90
|
+
const actualCost = events.reduce((sum, event) => sum + event.estimated_cost, 0);
|
|
91
|
+
const alternatives = Object.entries(tracker_js_1.PRICING)
|
|
92
|
+
.map(([model, rates]) => {
|
|
93
|
+
const estimated_cost = (totalInput / 1_000_000) * rates.input + (totalOutput / 1_000_000) * rates.output;
|
|
94
|
+
return {
|
|
95
|
+
model,
|
|
96
|
+
estimated_cost,
|
|
97
|
+
delta_vs_actual: estimated_cost - actualCost
|
|
98
|
+
};
|
|
99
|
+
})
|
|
100
|
+
.sort((a, b) => a.estimated_cost - b.estimated_cost);
|
|
101
|
+
const tracker = new tracker_js_1.CostwiseTracker();
|
|
102
|
+
const formatted = tracker.formatComparisonForCli({
|
|
103
|
+
model: alternatives[0]?.model ?? "unknown",
|
|
104
|
+
inputTokens: totalInput,
|
|
105
|
+
outputTokens: totalOutput
|
|
106
|
+
});
|
|
107
|
+
if (asJson) {
|
|
108
|
+
process.stdout.write(`${JSON.stringify({
|
|
109
|
+
actual: {
|
|
110
|
+
events: events.length,
|
|
111
|
+
input_tokens: totalInput,
|
|
112
|
+
output_tokens: totalOutput,
|
|
113
|
+
estimated_cost: actualCost
|
|
114
|
+
},
|
|
115
|
+
alternatives: alternatives.slice(0, 10)
|
|
116
|
+
}, null, 2)}\n`);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const lines = [
|
|
120
|
+
`Actual usage events: ${events.length}`,
|
|
121
|
+
`Actual estimated cost: $${actualCost.toFixed(6)}`,
|
|
122
|
+
"Top alternative models (same total tokens):",
|
|
123
|
+
...alternatives.slice(0, 5).map((alt) => ` - ${alt.model}: $${alt.estimated_cost.toFixed(6)} (delta ${alt.delta_vs_actual >= 0 ? "+" : ""}${alt.delta_vs_actual.toFixed(6)})`),
|
|
124
|
+
"",
|
|
125
|
+
"Cheapest-model summary:",
|
|
126
|
+
formatted.text
|
|
127
|
+
];
|
|
128
|
+
process.stdout.write(`${lines.join("\n")}\n`);
|
|
129
|
+
}
|
|
130
|
+
async function main() {
|
|
131
|
+
const options = parse(process.argv.slice(2));
|
|
132
|
+
const usagePath = options.filePath ?? process.env.COSTWISE_LOCAL_USAGE_PATH;
|
|
133
|
+
if (!usagePath) {
|
|
134
|
+
process.stderr.write("Missing usage file. Set COSTWISE_LOCAL_USAGE_PATH or pass --file.\n");
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
let events = [];
|
|
138
|
+
try {
|
|
139
|
+
events = await loadEvents(usagePath);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
process.stderr.write(`Unable to read usage file: ${usagePath}\n`);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
if (events.length === 0) {
|
|
146
|
+
process.stdout.write("No usage events found.\n");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
if (options.command === "usage") {
|
|
150
|
+
runUsage(events, options.json);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
runCompareActual(events, options.json);
|
|
154
|
+
}
|
|
155
|
+
void main();
|
|
156
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { CostwiseAnthropic } from "./src/anthropic.js";
|
|
2
|
+
export { CostwiseOpenAI } from "./src/openai.js";
|
|
3
|
+
export { CostwiseTracker, MODEL_CAPACITIES, PRICING } from "./src/tracker.js";
|
|
4
|
+
export type { CostwiseOptions, IngestPayload, CliComparisonFormat, LocalUsageEvent, ModelCapacity, ModelCapacityClass, ModelComparison, ModelComparisonByCapacity } from "./src/types.js";
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC9E,YAAY,EACV,eAAe,EACf,aAAa,EACb,mBAAmB,EACnB,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,eAAe,EACf,yBAAyB,EAC1B,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PRICING = exports.MODEL_CAPACITIES = exports.CostwiseTracker = exports.CostwiseOpenAI = exports.CostwiseAnthropic = void 0;
|
|
4
|
+
var anthropic_js_1 = require("./src/anthropic.js");
|
|
5
|
+
Object.defineProperty(exports, "CostwiseAnthropic", { enumerable: true, get: function () { return anthropic_js_1.CostwiseAnthropic; } });
|
|
6
|
+
var openai_js_1 = require("./src/openai.js");
|
|
7
|
+
Object.defineProperty(exports, "CostwiseOpenAI", { enumerable: true, get: function () { return openai_js_1.CostwiseOpenAI; } });
|
|
8
|
+
var tracker_js_1 = require("./src/tracker.js");
|
|
9
|
+
Object.defineProperty(exports, "CostwiseTracker", { enumerable: true, get: function () { return tracker_js_1.CostwiseTracker; } });
|
|
10
|
+
Object.defineProperty(exports, "MODEL_CAPACITIES", { enumerable: true, get: function () { return tracker_js_1.MODEL_CAPACITIES; } });
|
|
11
|
+
Object.defineProperty(exports, "PRICING", { enumerable: true, get: function () { return tracker_js_1.PRICING; } });
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../index.ts"],"names":[],"mappings":";;;AAAA,mDAAuD;AAA9C,iHAAA,iBAAiB,OAAA;AAC1B,6CAAiD;AAAxC,2GAAA,cAAc,OAAA;AACvB,+CAA8E;AAArE,6GAAA,eAAe,OAAA;AAAE,8GAAA,gBAAgB,OAAA;AAAE,qGAAA,OAAO,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import Anthropic from "@anthropic-ai/sdk";
|
|
2
|
+
import { CostwiseOptions } from "./types.js";
|
|
3
|
+
export declare class CostwiseAnthropic extends Anthropic {
|
|
4
|
+
private readonly tracker;
|
|
5
|
+
private readonly tag?;
|
|
6
|
+
constructor(options?: ConstructorParameters<typeof Anthropic>[0] & CostwiseOptions);
|
|
7
|
+
private wrapMessagesCreate;
|
|
8
|
+
private hasFinalMessage;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA0B7C,qBAAa,iBAAkB,SAAQ,SAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;IAC1C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAS;gBAElB,OAAO,GAAE,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,eAAoB;IAOtF,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,eAAe;CAQxB"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CostwiseAnthropic = void 0;
|
|
7
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
|
+
const tracker_js_1 = require("./tracker.js");
|
|
9
|
+
class CostwiseAnthropic extends sdk_1.default {
|
|
10
|
+
tracker;
|
|
11
|
+
tag;
|
|
12
|
+
constructor(options = {}) {
|
|
13
|
+
super(options);
|
|
14
|
+
this.tracker = new tracker_js_1.CostwiseTracker(options);
|
|
15
|
+
this.tag = options.tag;
|
|
16
|
+
this.wrapMessagesCreate();
|
|
17
|
+
}
|
|
18
|
+
wrapMessagesCreate() {
|
|
19
|
+
const originalCreate = this.messages.create.bind(this.messages);
|
|
20
|
+
this.messages.create = (async (...args) => {
|
|
21
|
+
const response = await originalCreate(...args);
|
|
22
|
+
if (this.hasFinalMessage(response)) {
|
|
23
|
+
void response
|
|
24
|
+
.finalMessage()
|
|
25
|
+
.then((message) => {
|
|
26
|
+
this.tracker.trackUsage({
|
|
27
|
+
model: message.model,
|
|
28
|
+
inputTokens: message.usage?.input_tokens ?? 0,
|
|
29
|
+
outputTokens: message.usage?.output_tokens ?? 0,
|
|
30
|
+
tag: this.tag
|
|
31
|
+
});
|
|
32
|
+
})
|
|
33
|
+
.catch(() => { });
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
const message = response;
|
|
37
|
+
this.tracker.trackUsage({
|
|
38
|
+
model: message.model,
|
|
39
|
+
inputTokens: message.usage?.input_tokens ?? 0,
|
|
40
|
+
outputTokens: message.usage?.output_tokens ?? 0,
|
|
41
|
+
tag: this.tag
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return response;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
hasFinalMessage(value) {
|
|
48
|
+
return (typeof value === "object" &&
|
|
49
|
+
value !== null &&
|
|
50
|
+
"finalMessage" in value &&
|
|
51
|
+
typeof value.finalMessage === "function");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.CostwiseAnthropic = CostwiseAnthropic;
|
|
55
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/anthropic.ts"],"names":[],"mappings":";;;;;;AAAA,4DAA0C;AAE1C,6CAA+C;AAyB/C,MAAa,iBAAkB,SAAQ,aAAS;IAC7B,OAAO,CAAkB;IACzB,GAAG,CAAU;IAE9B,YAAY,UAAwE,EAAE;QACpF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,IAAI,4BAAe,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAEO,kBAAkB;QACxB,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAoB,CAAC;QAEnF,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,GAAG,IAAiC,EAAE,EAAE;YACrE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,IAAI,CAAC,CAAC;YAE/C,IAAI,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACnC,KAAK,QAAQ;qBACV,YAAY,EAAE;qBACd,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;oBAChB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;wBACtB,KAAK,EAAE,OAAO,CAAC,KAAK;wBACpB,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC;wBAC7C,YAAY,EAAE,OAAO,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;wBAC/C,GAAG,EAAE,IAAI,CAAC,GAAG;qBACd,CAAC,CAAC;gBACL,CAAC,CAAC;qBACD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,MAAM,OAAO,GAAG,QAGf,CAAC;gBAEF,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;oBACtB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC;oBAC7C,YAAY,EAAE,OAAO,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;oBAC/C,GAAG,EAAE,IAAI,CAAC,GAAG;iBACd,CAAC,CAAC;YACL,CAAC;YAED,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAoB,CAAC;IACxB,CAAC;IAEO,eAAe,CAAC,KAAc;QACpC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,cAAc,IAAI,KAAK;YACvB,OAAQ,KAA6B,CAAC,YAAY,KAAK,UAAU,CAClE,CAAC;IACJ,CAAC;CACF;AAvDD,8CAuDC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import OpenAI from "openai";
|
|
2
|
+
import { CostwiseOptions } from "./types.js";
|
|
3
|
+
export declare class CostwiseOpenAI extends OpenAI {
|
|
4
|
+
private readonly tracker;
|
|
5
|
+
constructor(options?: ConstructorParameters<typeof OpenAI>[0] & CostwiseOptions);
|
|
6
|
+
private wrapChatCompletionsCreate;
|
|
7
|
+
private hasFinalChatCompletion;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/openai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAiB7C,qBAAa,cAAe,SAAQ,MAAM;IACxC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkB;gBAE9B,OAAO,GAAE,qBAAqB,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,eAAoB;IAMnF,OAAO,CAAC,yBAAyB;IA6BjC,OAAO,CAAC,sBAAsB;CAQ/B"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.CostwiseOpenAI = void 0;
|
|
7
|
+
const openai_1 = __importDefault(require("openai"));
|
|
8
|
+
const tracker_js_1 = require("./tracker.js");
|
|
9
|
+
class CostwiseOpenAI extends openai_1.default {
|
|
10
|
+
tracker;
|
|
11
|
+
constructor(options = {}) {
|
|
12
|
+
super(options);
|
|
13
|
+
this.tracker = new tracker_js_1.CostwiseTracker(options);
|
|
14
|
+
this.wrapChatCompletionsCreate();
|
|
15
|
+
}
|
|
16
|
+
wrapChatCompletionsCreate() {
|
|
17
|
+
const originalCreate = this.chat.completions.create.bind(this.chat.completions);
|
|
18
|
+
this.chat.completions.create = (async (...args) => {
|
|
19
|
+
const response = await originalCreate(...args);
|
|
20
|
+
if (this.hasFinalChatCompletion(response)) {
|
|
21
|
+
void response
|
|
22
|
+
.finalChatCompletion()
|
|
23
|
+
.then((completion) => {
|
|
24
|
+
this.tracker.trackUsage({
|
|
25
|
+
model: completion.model,
|
|
26
|
+
inputTokens: completion.usage?.prompt_tokens ?? 0,
|
|
27
|
+
outputTokens: completion.usage?.completion_tokens ?? 0
|
|
28
|
+
});
|
|
29
|
+
})
|
|
30
|
+
.catch(() => { });
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const completion = response;
|
|
34
|
+
this.tracker.trackUsage({
|
|
35
|
+
model: completion.model,
|
|
36
|
+
inputTokens: completion.usage?.prompt_tokens ?? 0,
|
|
37
|
+
outputTokens: completion.usage?.completion_tokens ?? 0
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
return response;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
hasFinalChatCompletion(value) {
|
|
44
|
+
return (typeof value === "object" &&
|
|
45
|
+
value !== null &&
|
|
46
|
+
"finalChatCompletion" in value &&
|
|
47
|
+
typeof value.finalChatCompletion === "function");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.CostwiseOpenAI = CostwiseOpenAI;
|
|
51
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/openai.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4B;AAE5B,6CAA+C;AAgB/C,MAAa,cAAe,SAAQ,gBAAM;IACvB,OAAO,CAAkB;IAE1C,YAAY,UAAqE,EAAE;QACjF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,OAAO,GAAG,IAAI,4BAAe,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,CAAC,yBAAyB,EAAE,CAAC;IACnC,CAAC;IAEO,yBAAyB;QAC/B,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAqB,CAAC;QAEpG,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,GAAG,IAAkC,EAAE,EAAE;YAC9E,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,GAAG,IAAI,CAAC,CAAC;YAE/C,IAAI,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1C,KAAK,QAAQ;qBACV,mBAAmB,EAAE;qBACrB,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE;oBACnB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;wBACtB,KAAK,EAAE,UAAU,CAAC,KAAK;wBACvB,WAAW,EAAE,UAAU,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;wBACjD,YAAY,EAAE,UAAU,CAAC,KAAK,EAAE,iBAAiB,IAAI,CAAC;qBACvD,CAAC,CAAC;gBACL,CAAC,CAAC;qBACD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrB,CAAC;iBAAM,CAAC;gBACN,MAAM,UAAU,GAAG,QAA4B,CAAC;gBAChD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;oBACtB,KAAK,EAAE,UAAU,CAAC,KAAK;oBACvB,WAAW,EAAE,UAAU,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;oBACjD,YAAY,EAAE,UAAU,CAAC,KAAK,EAAE,iBAAiB,IAAI,CAAC;iBACvD,CAAC,CAAC;YACL,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAqB,CAAC;IACzB,CAAC;IAEO,sBAAsB,CAAC,KAAc;QAC3C,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;YACzB,KAAK,KAAK,IAAI;YACd,qBAAqB,IAAI,KAAK;YAC9B,OAAQ,KAA0B,CAAC,mBAAmB,KAAK,UAAU,CACtE,CAAC;IACJ,CAAC;CACF;AA9CD,wCA8CC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { CostwiseOptions, ModelCapacity, CliComparisonFormat, ModelComparison, ModelComparisonByCapacity, UsageSnapshot } from "./types.js";
|
|
2
|
+
type ModelRates = {
|
|
3
|
+
input: number;
|
|
4
|
+
output: number;
|
|
5
|
+
};
|
|
6
|
+
declare const PRICING: Record<string, ModelRates>;
|
|
7
|
+
declare const MODEL_CAPACITIES: Record<string, ModelCapacity>;
|
|
8
|
+
export declare class CostwiseTracker {
|
|
9
|
+
private readonly apiKey?;
|
|
10
|
+
private readonly tag?;
|
|
11
|
+
private readonly localUsagePath?;
|
|
12
|
+
constructor(options?: CostwiseOptions);
|
|
13
|
+
trackUsage(snapshot: UsageSnapshot): void;
|
|
14
|
+
compareCosts(snapshot: UsageSnapshot): ModelComparison[];
|
|
15
|
+
compareCostsByCapacity(snapshot: UsageSnapshot): ModelComparisonByCapacity;
|
|
16
|
+
summarizeComparison(snapshot: UsageSnapshot): string;
|
|
17
|
+
formatComparisonForCli(snapshot: UsageSnapshot): CliComparisonFormat;
|
|
18
|
+
private createPayload;
|
|
19
|
+
private estimateCost;
|
|
20
|
+
private calculateCost;
|
|
21
|
+
}
|
|
22
|
+
export { MODEL_CAPACITIES, PRICING };
|
|
23
|
+
//# sourceMappingURL=tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../../src/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EAGf,aAAa,EAEb,mBAAmB,EACnB,eAAe,EACf,yBAAyB,EACzB,aAAa,EACd,MAAM,YAAY,CAAC;AAGpB,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AA6BF,QAAA,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAGvC,CAAC;AAEF,QAAA,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAsBnD,CAAC;AAIF,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAS;gBAE7B,OAAO,GAAE,eAAoB;IAMzC,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IA8BzC,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,eAAe,EAAE;IAqBxD,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,yBAAyB;IAgC1E,mBAAmB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM;IAWpD,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,mBAAmB;IA+BpE,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,aAAa;CAKtB;AAED,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,CAAC"}
|