@mohanscodex/spectra-ai 0.4.7 → 0.5.0

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pricing.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pricing.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,101 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { calculateCost, formatCost, formatTokens, isFreeModel, getModelPricing, } from '../pricing.js';
3
+ describe('Pricing — calculateCost', () => {
4
+ it('calculates cost for known model', () => {
5
+ const cost = calculateCost('claude-sonnet-4-5', { input: 1_000_000, output: 1_000_000 });
6
+ expect(cost.input).toBeCloseTo(3, 2);
7
+ expect(cost.output).toBeCloseTo(15, 2);
8
+ expect(cost.total).toBeCloseTo(18, 2);
9
+ });
10
+ it('returns zero for unknown model', () => {
11
+ const cost = calculateCost('nonexistent-model', { input: 1000, output: 1000 });
12
+ expect(cost.total).toBe(0);
13
+ });
14
+ it('calculates partial token usage', () => {
15
+ const cost = calculateCost('gpt-4o', { input: 500_000, output: 250_000 });
16
+ expect(cost.input).toBeCloseTo(1.25, 2);
17
+ expect(cost.output).toBeCloseTo(2.5, 2);
18
+ });
19
+ it('handles zero tokens', () => {
20
+ const cost = calculateCost('claude-sonnet-4-5', { input: 0, output: 0 });
21
+ expect(cost.total).toBe(0);
22
+ });
23
+ it('calculates cache read/write costs', () => {
24
+ const cost = calculateCost('claude-sonnet-4-5', {
25
+ input: 0,
26
+ output: 0,
27
+ cacheRead: 1_000_000,
28
+ cacheWrite: 1_000_000,
29
+ });
30
+ expect(cost.cacheRead).toBeCloseTo(0.3, 2);
31
+ expect(cost.cacheWrite).toBeCloseTo(3.75, 2);
32
+ });
33
+ });
34
+ describe('Pricing — formatCost', () => {
35
+ it('formats zero as Free', () => {
36
+ expect(formatCost(0)).toBe('Free');
37
+ });
38
+ it('formats very small values', () => {
39
+ expect(formatCost(0.0005)).toBe('<$0.001');
40
+ });
41
+ it('formats normal values', () => {
42
+ expect(formatCost(0.1234)).toBe('$0.1234');
43
+ });
44
+ it('formats larger values', () => {
45
+ expect(formatCost(1.5)).toBe('$1.5000');
46
+ });
47
+ });
48
+ describe('Pricing — formatTokens', () => {
49
+ it('formats small numbers', () => {
50
+ expect(formatTokens(500)).toBe('500');
51
+ });
52
+ it('formats thousands', () => {
53
+ expect(formatTokens(1500)).toBe('1.5K');
54
+ });
55
+ it('formats millions', () => {
56
+ expect(formatTokens(2_500_000)).toBe('2.5M');
57
+ });
58
+ it('formats exact thousand', () => {
59
+ expect(formatTokens(1000)).toBe('1.0K');
60
+ });
61
+ it('formats exact million', () => {
62
+ expect(formatTokens(1_000_000)).toBe('1.0M');
63
+ });
64
+ });
65
+ describe('Pricing — isFreeModel', () => {
66
+ it('returns false for paid models', () => {
67
+ expect(isFreeModel('claude-sonnet-4-5')).toBe(false);
68
+ expect(isFreeModel('gpt-4o')).toBe(false);
69
+ });
70
+ it('returns true for unknown models (no pricing)', () => {
71
+ expect(isFreeModel('nonexistent-model')).toBe(true);
72
+ });
73
+ });
74
+ describe('Pricing — getModelPricing', () => {
75
+ it('returns pricing for hardcoded models', () => {
76
+ const pricing = getModelPricing('claude-sonnet-4-5');
77
+ expect(pricing).not.toBeNull();
78
+ expect(pricing.input).toBe(3);
79
+ expect(pricing.output).toBe(15);
80
+ });
81
+ it('returns pricing for gpt-4o', () => {
82
+ const pricing = getModelPricing('gpt-4o');
83
+ expect(pricing).not.toBeNull();
84
+ expect(pricing.input).toBe(2.5);
85
+ expect(pricing.output).toBe(10);
86
+ });
87
+ it('matches model IDs with date suffixes', () => {
88
+ const pricing = getModelPricing('claude-sonnet-4-5-20250514');
89
+ expect(pricing).not.toBeNull();
90
+ expect(pricing.input).toBe(3);
91
+ });
92
+ it('returns null for unknown models', () => {
93
+ const pricing = getModelPricing('totally-unknown-model');
94
+ expect(pricing).toBeNull();
95
+ });
96
+ it('handles partial matches', () => {
97
+ const pricing = getModelPricing('claude-opus-4');
98
+ expect(pricing).not.toBeNull();
99
+ });
100
+ });
101
+ //# sourceMappingURL=pricing.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.test.js","sourceRoot":"","sources":["../../src/__tests__/pricing.test.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,5 +4,7 @@ export type { StreamFunction, Provider } from './registry.js';
4
4
  export { initProviders } from './providers/register-builtins.js';
5
5
  export { getProviderModels } from './models.js';
6
6
  export type { ModelEntry } from './models.js';
7
+ export { getModelPricing, isFreeModel, calculateCost, formatCost, formatTokens, loadPricingFromModelsDev, } from './pricing.js';
8
+ export type { ModelPricing } from './pricing.js';
7
9
  export type { TextContent, ThinkingContent, ImageContent, ToolCall, StopReason, Usage, UserMessage, AssistantMessage, ToolResultMessage, Message, Tool, Context, AssistantMessageEvent, StreamOptions, Model, } from './types.js';
8
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1G,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,WAAW,EACX,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,OAAO,EACP,IAAI,EACJ,OAAO,EACP,qBAAqB,EACrB,aAAa,EACb,KAAK,GACL,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1G,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EACN,eAAe,EACf,WAAW,EACX,aAAa,EACb,UAAU,EACV,YAAY,EACZ,wBAAwB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,YAAY,EACX,WAAW,EACX,eAAe,EACf,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,OAAO,EACP,IAAI,EACJ,OAAO,EACP,qBAAqB,EACrB,aAAa,EACb,KAAK,GACL,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -2,4 +2,5 @@ export { EventStream, AssistantMessageEventStream } from './event-stream.js';
2
2
  export { stream, complete, registerProvider, getProvider, listProviders, getModels } from './registry.js';
3
3
  export { initProviders } from './providers/register-builtins.js';
4
4
  export { getProviderModels } from './models.js';
5
+ export { getModelPricing, isFreeModel, calculateCost, formatCost, formatTokens, loadPricingFromModelsDev, } from './pricing.js';
5
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1G,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1G,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EACN,eAAe,EACf,WAAW,EACX,aAAa,EACb,UAAU,EACV,YAAY,EACZ,wBAAwB,GACxB,MAAM,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA+5nBD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,CAElE"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AA41oBD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,EAAE,CAElE"}