@paean-ai/harness-model-pricing 0.1.1-rc.17

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/lib/index.js ADDED
@@ -0,0 +1,280 @@
1
+ import z from "@deepseek-ai/schemastery";
2
+ import { z as z$1 } from "zod";
3
+ //#region lib/types/defaults.js
4
+ /** Default market-price sheet; DeepSeek uses peak prices, Claude uses global/5-minute caching. */
5
+ const DEFAULT_SHEET = {
6
+ verifiedOn: "2026-10-02",
7
+ cards: [
8
+ {
9
+ id: "deepseek-v4.1-flash",
10
+ name: "DeepSeek V4.1 Flash",
11
+ input: .3,
12
+ output: 1.2,
13
+ cacheRead: .006,
14
+ cacheWrite: .3,
15
+ source: "https://api-docs.deepseek.com/quick_start/pricing/"
16
+ },
17
+ {
18
+ id: "gpt-6-sol",
19
+ name: "GPT-6 Sol",
20
+ input: 2,
21
+ output: 10,
22
+ cacheRead: .2,
23
+ cacheWrite: 2.5,
24
+ source: "https://developers.openai.com/api/docs/models/gpt-6-sol",
25
+ longContext: {
26
+ above: 272e3,
27
+ rates: {
28
+ input: 4,
29
+ output: 15,
30
+ cacheRead: .4,
31
+ cacheWrite: 5
32
+ }
33
+ }
34
+ },
35
+ {
36
+ id: "gpt-6.1-sol",
37
+ name: "GPT-6.1 Sol",
38
+ input: 2,
39
+ output: 10,
40
+ cacheRead: .1,
41
+ cacheWrite: 2.5,
42
+ source: "https://developers.openai.com/api/docs/models/gpt-6.1-sol",
43
+ longContext: {
44
+ above: 272e3,
45
+ rates: {
46
+ input: 4,
47
+ output: 15,
48
+ cacheRead: .2,
49
+ cacheWrite: 5
50
+ }
51
+ }
52
+ },
53
+ {
54
+ id: "gpt-6-astra",
55
+ name: "GPT-6 Astra",
56
+ input: 10,
57
+ output: 50,
58
+ cacheRead: 1,
59
+ cacheWrite: 12.5,
60
+ source: "https://developers.openai.com/api/docs/models/gpt-6-astra",
61
+ longContext: {
62
+ above: 272e3,
63
+ rates: {
64
+ input: 20,
65
+ output: 75,
66
+ cacheRead: 2,
67
+ cacheWrite: 25
68
+ }
69
+ }
70
+ },
71
+ {
72
+ id: "sonnet-5.5",
73
+ name: "Claude Sonnet 5.5",
74
+ input: 2,
75
+ output: 10,
76
+ cacheRead: .2,
77
+ cacheWrite: 2.5,
78
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing#claude_models"
79
+ },
80
+ {
81
+ id: "opus-5.5",
82
+ name: "Claude Opus 5.5",
83
+ input: 4,
84
+ output: 20,
85
+ cacheRead: .2,
86
+ cacheWrite: 5,
87
+ source: "https://cloud.google.com/vertex-ai/generative-ai/pricing#claude_models"
88
+ }
89
+ ],
90
+ routes: [
91
+ {
92
+ provider: "paean",
93
+ model: "praxis-auto",
94
+ card: "deepseek-v4.1-flash"
95
+ },
96
+ {
97
+ provider: "paean",
98
+ model: "praxis-lite",
99
+ card: "deepseek-v4.1-flash"
100
+ },
101
+ {
102
+ provider: "paean",
103
+ model: "praxis-flash",
104
+ card: "gpt-6-sol"
105
+ },
106
+ {
107
+ provider: "paean",
108
+ model: "praxis-pro",
109
+ card: "gpt-6-astra"
110
+ },
111
+ {
112
+ provider: "paean-anthropic",
113
+ model: "praxis-auto",
114
+ card: "deepseek-v4.1-flash"
115
+ },
116
+ {
117
+ provider: "paean-anthropic",
118
+ model: "praxis-lite",
119
+ card: "deepseek-v4.1-flash"
120
+ },
121
+ {
122
+ provider: "paean-anthropic",
123
+ model: "praxis-flash",
124
+ card: "sonnet-5.5"
125
+ },
126
+ {
127
+ provider: "paean-anthropic",
128
+ model: "praxis-pro",
129
+ card: "opus-5.5"
130
+ }
131
+ ]
132
+ };
133
+ //#endregion
134
+ //#region lib/types/projection.js
135
+ /** Whole-log usage attribution; prices remain read-side configuration, never durable billing facts. */
136
+ const count = z$1.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
137
+ const usageSchema = z$1.object({
138
+ inputTokens: count,
139
+ outputTokens: count,
140
+ cacheReadTokens: count.default(0),
141
+ cacheWriteTokens: count.default(0)
142
+ }).strict();
143
+ const requestSchema = z$1.object({
144
+ provider: z$1.string(),
145
+ model: z$1.string(),
146
+ purpose: z$1.enum(["assistant", "compaction"]),
147
+ usage: usageSchema.nullable()
148
+ }).strict();
149
+ const viewSchema = z$1.object({ requests: z$1.array(requestSchema) }).strict();
150
+ const stateSchema = z$1.object({
151
+ view: viewSchema,
152
+ route: z$1.object({
153
+ provider: z$1.string(),
154
+ model: z$1.string()
155
+ }).nullable()
156
+ }).strict();
157
+ /**
158
+ * Accept normalized SDK buckets, with omitted zero cache buckets and no reasoning surcharge.
159
+ * @param value - measured usage from the durable SDK stream.
160
+ * @returns disjoint buckets, or null for absent, invalid, or inconsistent evidence.
161
+ */
162
+ function measuredUsage(value) {
163
+ if (typeof value !== "object" || value === null) return null;
164
+ const raw = value;
165
+ const parsed = usageSchema.safeParse({
166
+ inputTokens: raw.inputTokens,
167
+ outputTokens: raw.outputTokens,
168
+ cacheReadTokens: raw.cacheReadTokens,
169
+ cacheWriteTokens: raw.cacheWriteTokens
170
+ });
171
+ if (!parsed.success) return null;
172
+ const usage = parsed.data;
173
+ const total = usage.inputTokens + usage.outputTokens + usage.cacheReadTokens + usage.cacheWriteTokens;
174
+ if (!Number.isSafeInteger(total)) return null;
175
+ if (raw.totalTokens !== void 0 && raw.totalTokens !== total) return null;
176
+ if (raw.reasoningTokens !== void 0 && (!count.safeParse(raw.reasoningTokens).success || Number(raw.reasoningTokens) > usage.outputTokens)) return null;
177
+ return usage;
178
+ }
179
+ /** Last normalized usage chunk in one compact native stream, without expanding its content. */
180
+ function usageFrom(stream) {
181
+ for (let index = stream.length - 1; index >= 0; index--) {
182
+ const record = stream[index];
183
+ if (record?.type === "chunk" && record.chunk.type === "usage") return record.chunk.usage;
184
+ }
185
+ }
186
+ /** Compact, whole-log request facts survive paging, compaction and price-sheet updates. */
187
+ const pricingUsageProjection = {
188
+ key: "paeanPricingUsage",
189
+ stateVersion: 1,
190
+ stateSchema,
191
+ init: () => ({
192
+ view: { requests: [] },
193
+ route: null
194
+ }),
195
+ apply: (state, event) => {
196
+ if (event.type === "request/header") {
197
+ const { provider, model } = event.data.header.config;
198
+ if (state.route?.provider === provider && state.route.model === model) return state;
199
+ return {
200
+ ...state,
201
+ route: {
202
+ provider,
203
+ model
204
+ }
205
+ };
206
+ }
207
+ if (event.type === "compaction/summary") {
208
+ const request = {
209
+ provider: event.data.provider,
210
+ model: event.data.model,
211
+ purpose: "compaction",
212
+ usage: measuredUsage(event.data.usage)
213
+ };
214
+ return {
215
+ ...state,
216
+ view: { requests: [...state.view.requests, request] }
217
+ };
218
+ }
219
+ if (event.type !== "assistant/message" && event.type !== "assistant/attempt") return state;
220
+ const route = event.type === "assistant/message" ? event.data.message.source : state.route;
221
+ const sample = event.type === "assistant/message" && event.data.usage !== void 0 ? event.data.usage : usageFrom(event.data.stream);
222
+ const request = {
223
+ provider: route?.provider ?? "",
224
+ model: route?.model ?? "",
225
+ purpose: "assistant",
226
+ usage: measuredUsage(sample)
227
+ };
228
+ return {
229
+ ...state,
230
+ view: { requests: [...state.view.requests, request] }
231
+ };
232
+ },
233
+ wire: {
234
+ viewSchema,
235
+ view: (state) => state.view
236
+ }
237
+ };
238
+ //#endregion
239
+ //#region lib/types/index.js
240
+ /** Cordis plugin identity. */
241
+ const name = "paean-model-pricing";
242
+ /** Services own configuration delivery and whole-log projection delivery. */
243
+ const inject = ["sessionProjections", "settings"];
244
+ const rate = z.number().required().min(0).max(1e6);
245
+ const rates = {
246
+ input: rate,
247
+ output: rate,
248
+ cacheRead: rate,
249
+ cacheWrite: rate
250
+ };
251
+ /** Validated market rates and protocol-specific mappings, served by the standard Settings API. */
252
+ const Config = z.object({ sheet: z.object({
253
+ verifiedOn: z.string().required().pattern(/^\d{4}-\d{2}-\d{2}$/),
254
+ cards: z.array(z.object({
255
+ id: z.string().required().min(1),
256
+ name: z.string().required().min(1),
257
+ source: z.string().required().pattern(/^https:\/\//),
258
+ ...rates,
259
+ longContext: z.union([z.object({
260
+ above: z.number().required().step(1).min(1),
261
+ rates: z.object(rates).required()
262
+ }), z.const(void 0)])
263
+ })).required(),
264
+ routes: z.array(z.object({
265
+ provider: z.string().required().min(1),
266
+ model: z.string().required().min(1),
267
+ card: z.string().required().min(1)
268
+ })).required()
269
+ }).default(DEFAULT_SHEET).volatile() });
270
+ /**
271
+ * Register the measured-usage fold and editable settings, both owned by this fiber.
272
+ * @param ctx - injected projection and Settings services.
273
+ * @param _config - live price sheet exposed to the browser through Settings.
274
+ */
275
+ function apply(ctx, _config) {
276
+ ctx.sessionProjections.register(pricingUsageProjection);
277
+ ctx.effect(() => ctx.settings.configure({ auto: true }));
278
+ }
279
+ //#endregion
280
+ export { Config, apply, inject, name };
@@ -0,0 +1,52 @@
1
+ /** Pure USD estimates over measured, request-attributed usage and an editable price sheet. */
2
+ import type { PriceCard, PriceSheet, PricedRequest, PricingUsage, Rates } from './types.ts';
3
+ /** Estimated request subtotal, with the tariff that produced it. */
4
+ export interface RequestEstimate {
5
+ card: PriceCard;
6
+ rates: Rates;
7
+ input: number;
8
+ output: number;
9
+ cacheRead: number;
10
+ cacheWrite: number;
11
+ total: number;
12
+ }
13
+ /** Priced subtotal and explicit coverage of the settled requests in this session. */
14
+ export interface UsageEstimate {
15
+ total: number;
16
+ priced: number;
17
+ unpriced: number;
18
+ byCard: {
19
+ card: PriceCard;
20
+ total: number;
21
+ requests: number;
22
+ }[];
23
+ }
24
+ /**
25
+ * Resolve an alias without querying account identity or changing its route.
26
+ * @param sheet - current tariff configuration.
27
+ * @param provider - recorded provider identity.
28
+ * @param model - recorded alias.
29
+ * @returns its tariff, or absence when no unambiguous mapping exists.
30
+ */
31
+ export declare function resolveCard(sheet: PriceSheet, provider: string, model: string): PriceCard | undefined;
32
+ /**
33
+ * Price disjoint usage buckets; reasoning is already part of output.
34
+ * @param sheet - current public rates, including any long-context band.
35
+ * @param request - one settled request's measured usage.
36
+ * @returns its estimate, or absence for unavailable usage or an unmapped route.
37
+ */
38
+ export declare function estimateRequest(sheet: PriceSheet, request: PricedRequest): RequestEstimate | undefined;
39
+ /**
40
+ * Revalue the complete session against the current sheet, preserving missing coverage.
41
+ * @param sheet - current market prices.
42
+ * @param usage - whole-log request facts from the projection.
43
+ * @returns a subtotal and per-model breakdown; unpriced requests never become zero-cost claims.
44
+ */
45
+ export declare function estimateUsage(sheet: PriceSheet, usage: PricingUsage): UsageEstimate;
46
+ /**
47
+ * Format USD with enough precision for a tiny test; positive amounts never display as zero.
48
+ * @param amount - nonnegative estimated dollars.
49
+ * @returns a compact USD amount, with an upper bound for sub-micro-dollar values.
50
+ */
51
+ export declare function formatUsd(amount: number): string;
52
+ //# sourceMappingURL=calculate.d.ts.map
@@ -0,0 +1,26 @@
1
+ import type { UseProjection } from '@deepseek-ai/dsh-api-session-controller/client';
2
+ import type { ConfigForm } from '@deepseek-ai/dsh-client-ui-settings/client';
3
+ import type { PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
4
+ import type { PriceSheet } from '../types.ts';
5
+ import type { NS } from './locales.ts';
6
+ /** Form access injected by the plugin; measured usage is supplied by the Session owner. */
7
+ export interface PricingFace {
8
+ form: ConfigForm<{
9
+ sheet: PriceSheet;
10
+ }>;
11
+ }
12
+ /**
13
+ * Render a compact estimate beside token statistics; details never enlarge the composer.
14
+ * @param props - standard read-only form, session projection hook and locale seat.
15
+ * @returns the composer price row; unavailable configuration shows no monetary claim.
16
+ */
17
+ export declare function ModelPricing({ form, useProjection, t }: PricingFace & {
18
+ useProjection: UseProjection;
19
+ } & PropsLocale<typeof NS>): import("react").JSX.Element | null;
20
+ /**
21
+ * Show the public price list in Settings before any session or credential exists.
22
+ * @param props - the same live price form and localized copy used by the composer.
23
+ * @returns the complete price list without a session cost claim.
24
+ */
25
+ export declare function ModelPricingSettings({ form, t }: PricingFace & PropsLocale<typeof NS>): import("react").JSX.Element;
26
+ //# sourceMappingURL=ModelPricing.d.ts.map
@@ -0,0 +1,11 @@
1
+ /** Browser plugin registering a read-only price row on the DSH composer dock. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ export type * from '../types.ts';
4
+ /** Services supplied by the browser composition. */
5
+ export declare const inject: string[];
6
+ /**
7
+ * Contribute localized prices while the matching Host settings namespace is served.
8
+ * @param ctx - browser composition services; all registrations withdraw with the fiber.
9
+ */
10
+ export declare function apply(ctx: Context): void;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,68 @@
1
+ /** Typed English and Chinese copy for estimated USD and public tariff assumptions. */
2
+ export declare const NS = "paeanModelPricing";
3
+ /** Keys owned by the price presentation. */
4
+ export type PricingKey = 'title' | 'total' | 'partialTotal' | 'empty' | 'loading' | 'coverage' | 'partial' | 'assumptions' | 'verified' | 'protocol' | 'alias' | 'input' | 'output' | 'cacheRead' | 'cacheWrite' | 'unit' | 'openai' | 'anthropic' | 'compactTotal' | 'unavailable' | 'hint' | 'disclaimer' | 'details' | 'close' | 'routeCount' | 'settingsHint';
5
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
6
+ interface LocaleNamespaceMap {
7
+ paeanModelPricing: PricingKey;
8
+ }
9
+ }
10
+ /** English price-estimation copy. */
11
+ export declare const en: {
12
+ title: string;
13
+ total: string;
14
+ partialTotal: string;
15
+ empty: string;
16
+ loading: string;
17
+ coverage: string;
18
+ partial: string;
19
+ assumptions: string;
20
+ verified: string;
21
+ protocol: string;
22
+ alias: string;
23
+ input: string;
24
+ output: string;
25
+ cacheRead: string;
26
+ cacheWrite: string;
27
+ unit: string;
28
+ openai: string;
29
+ anthropic: string;
30
+ compactTotal: string;
31
+ unavailable: string;
32
+ hint: string;
33
+ disclaimer: string;
34
+ details: string;
35
+ close: string;
36
+ routeCount: string;
37
+ settingsHint: string;
38
+ };
39
+ /** Simplified Chinese price-estimation copy. */
40
+ export declare const zh: {
41
+ title: string;
42
+ total: string;
43
+ partialTotal: string;
44
+ empty: string;
45
+ loading: string;
46
+ coverage: string;
47
+ partial: string;
48
+ assumptions: string;
49
+ verified: string;
50
+ protocol: string;
51
+ alias: string;
52
+ input: string;
53
+ output: string;
54
+ cacheRead: string;
55
+ cacheWrite: string;
56
+ unit: string;
57
+ openai: string;
58
+ anthropic: string;
59
+ compactTotal: string;
60
+ unavailable: string;
61
+ hint: string;
62
+ disclaimer: string;
63
+ details: string;
64
+ close: string;
65
+ routeCount: string;
66
+ settingsHint: string;
67
+ };
68
+ //# sourceMappingURL=locales.d.ts.map
@@ -0,0 +1,5 @@
1
+ /** Public standard tariffs checked on 2026-10-02, owned by this Paean plugin. */
2
+ import type { PriceSheet } from './types.ts';
3
+ /** Default market-price sheet; DeepSeek uses peak prices, Claude uses global/5-minute caching. */
4
+ export declare const DEFAULT_SHEET: PriceSheet;
5
+ //# sourceMappingURL=defaults.d.ts.map