portable-agent-layer 0.62.0 → 0.62.1
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.
|
@@ -18,6 +18,20 @@
|
|
|
18
18
|
"Bash(stat //*)",
|
|
19
19
|
"Bash(readlink //*)",
|
|
20
20
|
"Bash(lsof *)",
|
|
21
|
+
"Bash(rtk read *)",
|
|
22
|
+
"Bash(rtk ls *)",
|
|
23
|
+
"Bash(rtk tree *)",
|
|
24
|
+
"Bash(rtk find *)",
|
|
25
|
+
"Bash(rtk grep *)",
|
|
26
|
+
"Bash(rtk rg *)",
|
|
27
|
+
"Bash(rtk wc *)",
|
|
28
|
+
"Bash(rtk diff *)",
|
|
29
|
+
"Bash(rtk json *)",
|
|
30
|
+
"Bash(rtk log *)",
|
|
31
|
+
"Bash(rtk deps *)",
|
|
32
|
+
"Bash(rtk env *)",
|
|
33
|
+
"Bash(rtk smart *)",
|
|
34
|
+
"Bash(rtk gain *)",
|
|
21
35
|
"Bash(bun ~/.pal/skills/*/tools/*.ts *)",
|
|
22
36
|
"Bash(bun ~/.pal/tools/*.ts *)",
|
|
23
37
|
"Bash(node --experimental-strip-types ~/.pal/skills/consulting-report/tools/generate-pdf.ts *)"
|
package/package.json
CHANGED
package/src/hooks/lib/models.ts
CHANGED
|
@@ -26,17 +26,24 @@ export function flagshipAuthorModel(agent: AgentType): string | undefined {
|
|
|
26
26
|
return FLAGSHIP_AUTHOR_MODEL[agent];
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
export interface ModelPricing {
|
|
30
|
+
input: number;
|
|
31
|
+
output: number;
|
|
32
|
+
cacheWrite5m: number;
|
|
33
|
+
cacheWrite1h: number;
|
|
34
|
+
cacheRead: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface TokenUsage {
|
|
38
|
+
input: number;
|
|
39
|
+
output: number;
|
|
40
|
+
cacheWrite5m: number;
|
|
41
|
+
cacheWrite1h: number;
|
|
42
|
+
cacheRead: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
29
45
|
/** Pricing per million tokens (USD) — from https://platform.claude.com/docs/en/about-claude/pricing */
|
|
30
|
-
export const MODEL_PRICING: Record<
|
|
31
|
-
string,
|
|
32
|
-
{
|
|
33
|
-
input: number;
|
|
34
|
-
output: number;
|
|
35
|
-
cacheWrite5m: number;
|
|
36
|
-
cacheWrite1h: number;
|
|
37
|
-
cacheRead: number;
|
|
38
|
-
}
|
|
39
|
-
> = {
|
|
46
|
+
export const MODEL_PRICING: Record<string, ModelPricing> = {
|
|
40
47
|
[HAIKU_MODEL]: {
|
|
41
48
|
input: 1,
|
|
42
49
|
output: 5,
|
|
@@ -51,6 +58,13 @@ export const MODEL_PRICING: Record<
|
|
|
51
58
|
cacheWrite1h: 20,
|
|
52
59
|
cacheRead: 1,
|
|
53
60
|
},
|
|
61
|
+
"claude-opus-5": {
|
|
62
|
+
input: 5,
|
|
63
|
+
output: 25,
|
|
64
|
+
cacheWrite5m: 6.25,
|
|
65
|
+
cacheWrite1h: 10,
|
|
66
|
+
cacheRead: 0.5,
|
|
67
|
+
},
|
|
54
68
|
"claude-opus-4-8": {
|
|
55
69
|
input: 5,
|
|
56
70
|
output: 25,
|
|
@@ -72,6 +86,13 @@ export const MODEL_PRICING: Record<
|
|
|
72
86
|
cacheWrite1h: 10,
|
|
73
87
|
cacheRead: 0.5,
|
|
74
88
|
},
|
|
89
|
+
"claude-opus-4-5": {
|
|
90
|
+
input: 5,
|
|
91
|
+
output: 25,
|
|
92
|
+
cacheWrite5m: 6.25,
|
|
93
|
+
cacheWrite1h: 10,
|
|
94
|
+
cacheRead: 0.5,
|
|
95
|
+
},
|
|
75
96
|
// Claude Sonnet 5 — introductory pricing through 2026-08-31; standard (3/15/3.75/6/0.30) applies from 2026-09-01.
|
|
76
97
|
"claude-sonnet-5": {
|
|
77
98
|
input: 2,
|
|
@@ -95,3 +116,37 @@ export const MODEL_PRICING: Record<
|
|
|
95
116
|
cacheRead: 0.3,
|
|
96
117
|
},
|
|
97
118
|
};
|
|
119
|
+
|
|
120
|
+
function longestPrefixKey(model: string): string | null {
|
|
121
|
+
let best: string | null = null;
|
|
122
|
+
for (const key of Object.keys(MODEL_PRICING)) {
|
|
123
|
+
if (model.startsWith(key) && (best === null || key.length > best.length)) best = key;
|
|
124
|
+
}
|
|
125
|
+
return best;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Rates for a model ID. Transcripts carry variants of the same model — dated
|
|
130
|
+
* (`claude-opus-5-20260115`) and context-tagged (`claude-opus-5[1m]`) — so an
|
|
131
|
+
* exact miss falls back to the longest table key the ID starts with.
|
|
132
|
+
*/
|
|
133
|
+
export function pricingFor(model: string): ModelPricing | null {
|
|
134
|
+
const exact = MODEL_PRICING[model];
|
|
135
|
+
if (exact) return exact;
|
|
136
|
+
const prefix = longestPrefixKey(model);
|
|
137
|
+
return prefix ? MODEL_PRICING[prefix] : null;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** USD cost of a token usage record. Unpriced models bill as 0. */
|
|
141
|
+
export function costOfUsage(model: string, usage: TokenUsage): number {
|
|
142
|
+
const p = pricingFor(model);
|
|
143
|
+
if (!p) return 0;
|
|
144
|
+
return (
|
|
145
|
+
(usage.input * p.input +
|
|
146
|
+
usage.output * p.output +
|
|
147
|
+
usage.cacheWrite5m * p.cacheWrite5m +
|
|
148
|
+
usage.cacheWrite1h * p.cacheWrite1h +
|
|
149
|
+
usage.cacheRead * p.cacheRead) /
|
|
150
|
+
1_000_000
|
|
151
|
+
);
|
|
152
|
+
}
|
|
@@ -9,7 +9,7 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
|
9
9
|
import { homedir } from "node:os";
|
|
10
10
|
import { resolve } from "node:path";
|
|
11
11
|
import { parseArgs } from "node:util";
|
|
12
|
-
import {
|
|
12
|
+
import { costOfUsage } from "../hooks/lib/models";
|
|
13
13
|
|
|
14
14
|
// ── Types ──
|
|
15
15
|
|
|
@@ -142,16 +142,13 @@ function parseSession(filepath: string, sessionId: string): Usage {
|
|
|
142
142
|
: (u.cache_creation_input_tokens ?? 0);
|
|
143
143
|
const cacheWrite1h = cw1h ?? 0;
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
cr * p.cacheRead) /
|
|
153
|
-
1_000_000;
|
|
154
|
-
}
|
|
145
|
+
usage.cost += costOfUsage(model, {
|
|
146
|
+
input,
|
|
147
|
+
output,
|
|
148
|
+
cacheWrite5m,
|
|
149
|
+
cacheWrite1h,
|
|
150
|
+
cacheRead: cr,
|
|
151
|
+
});
|
|
155
152
|
|
|
156
153
|
usage.input += input;
|
|
157
154
|
usage.output += output;
|
package/src/tools/token-cost.ts
CHANGED
|
@@ -13,7 +13,7 @@ import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
|
13
13
|
import { homedir } from "node:os";
|
|
14
14
|
import { resolve } from "node:path";
|
|
15
15
|
import { parseArgs } from "node:util";
|
|
16
|
-
import {
|
|
16
|
+
import { costOfUsage } from "../hooks/lib/models";
|
|
17
17
|
import { palHome } from "../hooks/lib/paths";
|
|
18
18
|
import { findBinaryOnPath } from "../hooks/lib/which";
|
|
19
19
|
|
|
@@ -59,34 +59,6 @@ function emptyTimeBuckets(): TimeBuckets {
|
|
|
59
59
|
|
|
60
60
|
// ── Helpers ──
|
|
61
61
|
|
|
62
|
-
function findPricing(model: string): (typeof MODEL_PRICING)[string] | null {
|
|
63
|
-
if (MODEL_PRICING[model]) return MODEL_PRICING[model];
|
|
64
|
-
for (const key of Object.keys(MODEL_PRICING)) {
|
|
65
|
-
if (model.startsWith(key)) return MODEL_PRICING[key];
|
|
66
|
-
}
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function costForUsage(
|
|
71
|
-
model: string,
|
|
72
|
-
input: number,
|
|
73
|
-
output: number,
|
|
74
|
-
cacheWrite5m: number,
|
|
75
|
-
cacheWrite1h: number,
|
|
76
|
-
cacheRead: number
|
|
77
|
-
): number {
|
|
78
|
-
const p = findPricing(model);
|
|
79
|
-
if (!p) return 0;
|
|
80
|
-
return (
|
|
81
|
-
(input * p.input +
|
|
82
|
-
output * p.output +
|
|
83
|
-
cacheWrite5m * p.cacheWrite5m +
|
|
84
|
-
cacheWrite1h * p.cacheWrite1h +
|
|
85
|
-
cacheRead * p.cacheRead) /
|
|
86
|
-
1_000_000
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
62
|
function addToBucket(
|
|
91
63
|
bucket: Bucket,
|
|
92
64
|
model: string,
|
|
@@ -101,14 +73,13 @@ function addToBucket(
|
|
|
101
73
|
bucket.cacheWrite5m += cacheWrite5m;
|
|
102
74
|
bucket.cacheWrite1h += cacheWrite1h;
|
|
103
75
|
bucket.cacheRead += cacheRead;
|
|
104
|
-
bucket.cost +=
|
|
105
|
-
model,
|
|
76
|
+
bucket.cost += costOfUsage(model, {
|
|
106
77
|
input,
|
|
107
78
|
output,
|
|
108
79
|
cacheWrite5m,
|
|
109
80
|
cacheWrite1h,
|
|
110
|
-
cacheRead
|
|
111
|
-
);
|
|
81
|
+
cacheRead,
|
|
82
|
+
});
|
|
112
83
|
bucket.calls++;
|
|
113
84
|
}
|
|
114
85
|
|