@codemieai/code 0.15.3 → 0.15.4

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.
Files changed (173) hide show
  1. package/dist/agents/core/AgentCLI.d.ts.map +1 -1
  2. package/dist/agents/core/AgentCLI.js +9 -0
  3. package/dist/agents/core/AgentCLI.js.map +1 -1
  4. package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
  5. package/dist/agents/core/BaseAgentAdapter.js +34 -9
  6. package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
  7. package/dist/agents/plugins/claude/claude.models.d.ts +58 -0
  8. package/dist/agents/plugins/claude/claude.models.d.ts.map +1 -1
  9. package/dist/agents/plugins/claude/claude.models.js +196 -10
  10. package/dist/agents/plugins/claude/claude.models.js.map +1 -1
  11. package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
  12. package/dist/agents/plugins/claude/claude.plugin.js +147 -45
  13. package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
  14. package/dist/agents/plugins/claude/plugin/statusline.bundle.mjs +729 -0
  15. package/dist/agents/plugins/claude/statusline-installer.d.ts +1 -1
  16. package/dist/agents/plugins/claude/statusline-installer.d.ts.map +1 -1
  17. package/dist/agents/plugins/claude/statusline-installer.js +41 -3
  18. package/dist/agents/plugins/claude/statusline-installer.js.map +1 -1
  19. package/dist/agents/plugins/codex/codex-models.d.ts.map +1 -1
  20. package/dist/agents/plugins/codex/codex-models.js +109 -8
  21. package/dist/agents/plugins/codex/codex-models.js.map +1 -1
  22. package/dist/agents/plugins/codex/codex.correlation.d.ts +39 -0
  23. package/dist/agents/plugins/codex/codex.correlation.d.ts.map +1 -0
  24. package/dist/agents/plugins/codex/codex.correlation.js +150 -0
  25. package/dist/agents/plugins/codex/codex.correlation.js.map +1 -0
  26. package/dist/agents/plugins/codex/codex.plugin.d.ts.map +1 -1
  27. package/dist/agents/plugins/codex/codex.plugin.js +8 -40
  28. package/dist/agents/plugins/codex/codex.plugin.js.map +1 -1
  29. package/dist/agents/plugins/kimi/kimi.env-model.d.ts +27 -0
  30. package/dist/agents/plugins/kimi/kimi.env-model.d.ts.map +1 -0
  31. package/dist/agents/plugins/kimi/kimi.env-model.js +52 -0
  32. package/dist/agents/plugins/kimi/kimi.env-model.js.map +1 -0
  33. package/dist/agents/plugins/kimi/kimi.session.d.ts +6 -0
  34. package/dist/agents/plugins/kimi/kimi.session.d.ts.map +1 -1
  35. package/dist/agents/plugins/kimi/kimi.session.js +24 -2
  36. package/dist/agents/plugins/kimi/kimi.session.js.map +1 -1
  37. package/dist/agents/plugins/opencode/opencode-dynamic-models.js +1 -1
  38. package/dist/agents/plugins/opencode/opencode-dynamic-models.js.map +1 -1
  39. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts +19 -2
  40. package/dist/cli/commands/analytics/cost/cost-enricher.d.ts.map +1 -1
  41. package/dist/cli/commands/analytics/cost/cost-enricher.js +171 -14
  42. package/dist/cli/commands/analytics/cost/cost-enricher.js.map +1 -1
  43. package/dist/cli/commands/analytics/cost/local-models.d.ts +15 -0
  44. package/dist/cli/commands/analytics/cost/local-models.d.ts.map +1 -0
  45. package/dist/cli/commands/analytics/cost/local-models.js +21 -0
  46. package/dist/cli/commands/analytics/cost/local-models.js.map +1 -0
  47. package/dist/cli/commands/analytics/cost/types.d.ts +60 -0
  48. package/dist/cli/commands/analytics/cost/types.d.ts.map +1 -1
  49. package/dist/cli/commands/analytics/cost/types.js.map +1 -1
  50. package/dist/cli/commands/analytics/cost/usage-readers.d.ts +25 -2
  51. package/dist/cli/commands/analytics/cost/usage-readers.d.ts.map +1 -1
  52. package/dist/cli/commands/analytics/cost/usage-readers.js +61 -3
  53. package/dist/cli/commands/analytics/cost/usage-readers.js.map +1 -1
  54. package/dist/cli/commands/analytics/formatter.d.ts +11 -0
  55. package/dist/cli/commands/analytics/formatter.d.ts.map +1 -1
  56. package/dist/cli/commands/analytics/formatter.js +28 -0
  57. package/dist/cli/commands/analytics/formatter.js.map +1 -1
  58. package/dist/cli/commands/analytics/index.d.ts.map +1 -1
  59. package/dist/cli/commands/analytics/index.js +70 -73
  60. package/dist/cli/commands/analytics/index.js.map +1 -1
  61. package/dist/cli/commands/analytics/otel-loader.d.ts.map +1 -1
  62. package/dist/cli/commands/analytics/otel-loader.js +60 -14
  63. package/dist/cli/commands/analytics/otel-loader.js.map +1 -1
  64. package/dist/cli/commands/analytics/otel-pricing.d.ts +38 -0
  65. package/dist/cli/commands/analytics/otel-pricing.d.ts.map +1 -0
  66. package/dist/cli/commands/analytics/otel-pricing.js +33 -0
  67. package/dist/cli/commands/analytics/otel-pricing.js.map +1 -0
  68. package/dist/cli/commands/analytics/report/client/app.js +279 -18
  69. package/dist/cli/commands/analytics/report/output-target.d.ts +22 -0
  70. package/dist/cli/commands/analytics/report/output-target.d.ts.map +1 -0
  71. package/dist/cli/commands/analytics/report/output-target.js +56 -0
  72. package/dist/cli/commands/analytics/report/output-target.js.map +1 -0
  73. package/dist/cli/commands/analytics/report/payload-builder.d.ts.map +1 -1
  74. package/dist/cli/commands/analytics/report/payload-builder.js +6 -0
  75. package/dist/cli/commands/analytics/report/payload-builder.js.map +1 -1
  76. package/dist/cli/commands/analytics/report/report-generator.d.ts +1 -1
  77. package/dist/cli/commands/analytics/report/report-generator.js +1 -1
  78. package/dist/cli/commands/analytics/report/session-report.d.ts +1 -3
  79. package/dist/cli/commands/analytics/report/session-report.d.ts.map +1 -1
  80. package/dist/cli/commands/analytics/report/session-report.js +1 -3
  81. package/dist/cli/commands/analytics/report/session-report.js.map +1 -1
  82. package/dist/cli/commands/analytics/report/template.html +6 -6
  83. package/dist/cli/commands/analytics/report/types.d.ts +17 -1
  84. package/dist/cli/commands/analytics/report/types.d.ts.map +1 -1
  85. package/dist/cli/commands/analytics/sources/sessions-source.d.ts.map +1 -1
  86. package/dist/cli/commands/analytics/sources/sessions-source.js +9 -11
  87. package/dist/cli/commands/analytics/sources/sessions-source.js.map +1 -1
  88. package/dist/cli/commands/analytics/sources/types.d.ts +0 -2
  89. package/dist/cli/commands/analytics/sources/types.d.ts.map +1 -1
  90. package/dist/cli/commands/analytics/types.d.ts +8 -8
  91. package/dist/cli/commands/analytics/types.d.ts.map +1 -1
  92. package/dist/cli/commands/models.d.ts.map +1 -1
  93. package/dist/cli/commands/models.js +16 -3
  94. package/dist/cli/commands/models.js.map +1 -1
  95. package/dist/cli/commands/proxy/connect-orchestrator.js +1 -1
  96. package/dist/cli/commands/proxy/connect-orchestrator.js.map +1 -1
  97. package/dist/cli/commands/proxy/connectors/tenant-catalog.d.ts +16 -4
  98. package/dist/cli/commands/proxy/connectors/tenant-catalog.d.ts.map +1 -1
  99. package/dist/cli/commands/proxy/connectors/tenant-catalog.js +42 -14
  100. package/dist/cli/commands/proxy/connectors/tenant-catalog.js.map +1 -1
  101. package/dist/cli/commands/proxy/connectors/vscode-models.d.ts +18 -0
  102. package/dist/cli/commands/proxy/connectors/vscode-models.d.ts.map +1 -1
  103. package/dist/cli/commands/proxy/connectors/vscode-models.js +58 -0
  104. package/dist/cli/commands/proxy/connectors/vscode-models.js.map +1 -1
  105. package/dist/cli/commands/proxy/connectors/vscode.d.ts +2 -2
  106. package/dist/cli/commands/proxy/connectors/vscode.d.ts.map +1 -1
  107. package/dist/cli/commands/proxy/connectors/vscode.js +27 -38
  108. package/dist/cli/commands/proxy/connectors/vscode.js.map +1 -1
  109. package/dist/providers/core/codemie-auth-helpers.d.ts.map +1 -1
  110. package/dist/providers/core/codemie-auth-helpers.js +6 -1
  111. package/dist/providers/core/codemie-auth-helpers.js.map +1 -1
  112. package/dist/providers/core/default-agent-hooks.d.ts.map +1 -1
  113. package/dist/providers/core/default-agent-hooks.js +9 -0
  114. package/dist/providers/core/default-agent-hooks.js.map +1 -1
  115. package/dist/providers/plugins/bedrock/bedrock.template.d.ts.map +1 -1
  116. package/dist/providers/plugins/bedrock/bedrock.template.js +5 -31
  117. package/dist/providers/plugins/bedrock/bedrock.template.js.map +1 -1
  118. package/dist/providers/plugins/sso/proxy/plugins/background-request-normalizer.plugin.d.ts +44 -0
  119. package/dist/providers/plugins/sso/proxy/plugins/background-request-normalizer.plugin.d.ts.map +1 -0
  120. package/dist/providers/plugins/sso/proxy/plugins/background-request-normalizer.plugin.js +106 -0
  121. package/dist/providers/plugins/sso/proxy/plugins/background-request-normalizer.plugin.js.map +1 -0
  122. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts +3 -1
  123. package/dist/providers/plugins/sso/proxy/plugins/index.d.ts.map +1 -1
  124. package/dist/providers/plugins/sso/proxy/plugins/index.js +5 -1
  125. package/dist/providers/plugins/sso/proxy/plugins/index.js.map +1 -1
  126. package/dist/providers/plugins/sso/proxy/plugins/routing-header-injector.plugin.d.ts +67 -0
  127. package/dist/providers/plugins/sso/proxy/plugins/routing-header-injector.plugin.d.ts.map +1 -0
  128. package/dist/providers/plugins/sso/proxy/plugins/routing-header-injector.plugin.js +203 -0
  129. package/dist/providers/plugins/sso/proxy/plugins/routing-header-injector.plugin.js.map +1 -0
  130. package/dist/providers/plugins/sso/sso.http-client.d.ts +95 -0
  131. package/dist/providers/plugins/sso/sso.http-client.d.ts.map +1 -1
  132. package/dist/providers/plugins/sso/sso.http-client.js +79 -0
  133. package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
  134. package/dist/providers/plugins/sso/sso.models.d.ts +7 -0
  135. package/dist/providers/plugins/sso/sso.models.d.ts.map +1 -1
  136. package/dist/providers/plugins/sso/sso.models.js +22 -14
  137. package/dist/providers/plugins/sso/sso.models.js.map +1 -1
  138. package/dist/utils/bedrock-pricing.mjs +111 -0
  139. package/dist/utils/cli-updater.d.ts.map +1 -1
  140. package/dist/utils/cli-updater.js +32 -7
  141. package/dist/utils/cli-updater.js.map +1 -1
  142. package/dist/utils/credential-crypto.d.ts +51 -0
  143. package/dist/utils/credential-crypto.d.ts.map +1 -0
  144. package/dist/utils/credential-crypto.js +96 -0
  145. package/dist/utils/credential-crypto.js.map +1 -0
  146. package/dist/utils/model-normalizer.d.ts +6 -0
  147. package/dist/utils/model-normalizer.d.ts.map +1 -1
  148. package/dist/utils/model-normalizer.js +37 -19
  149. package/dist/utils/model-normalizer.js.map +1 -1
  150. package/dist/utils/price-resolution.d.ts +42 -0
  151. package/dist/utils/price-resolution.d.ts.map +1 -0
  152. package/dist/utils/price-resolution.js +112 -0
  153. package/dist/utils/price-resolution.js.map +1 -0
  154. package/dist/utils/pricing.d.ts +65 -6
  155. package/dist/utils/pricing.d.ts.map +1 -1
  156. package/dist/utils/pricing.js +91 -117
  157. package/dist/utils/pricing.js.map +1 -1
  158. package/dist/utils/pricing.json +201 -20
  159. package/dist/utils/routing-headers.mjs +104 -0
  160. package/dist/utils/security.d.ts +0 -32
  161. package/dist/utils/security.d.ts.map +1 -1
  162. package/dist/utils/security.js +20 -102
  163. package/dist/utils/security.js.map +1 -1
  164. package/package.json +4 -2
  165. package/scripts/bundle-statusline.mjs +37 -0
  166. package/scripts/copy-plugins.js +19 -2
  167. package/src/utils/tips.json +9 -9
  168. package/dist/agents/plugins/claude/plugin/__tests__/statusline.test.ts +0 -323
  169. package/dist/agents/plugins/claude/plugin/statusline.mjs +0 -282
  170. package/dist/cli/commands/analytics/exporter.d.ts +0 -20
  171. package/dist/cli/commands/analytics/exporter.d.ts.map +0 -1
  172. package/dist/cli/commands/analytics/exporter.js +0 -91
  173. package/dist/cli/commands/analytics/exporter.js.map +0 -1
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Model-id → pricing-table-key resolution, shared by every consumer that prices a model id:
3
+ * src/utils/pricing.ts (the analytics report's resolvePrice()) and the standalone Claude
4
+ * statusline (src/agents/plugins/claude/plugin/statusline.ts, bundled into one self-contained file
5
+ * by scripts/bundle-statusline.mjs). Keeping one copy is what stops the live statusline cost and
6
+ * the analytics report from disagreeing on the same transcript.
7
+ *
8
+ * Deliberately free of I/O and of any import beyond model-normalizer.ts (itself dependency-free),
9
+ * so the statusline bundle stays small and never drags in fs/config/keytar-bearing modules. It
10
+ * knows nothing about the shape of a price row — callers pass a key lookup over their own table.
11
+ */
12
+ /** How an observed model id was matched to a table key. */
13
+ export type PriceMatch = 'exact' | 'snapshot' | 'reordered';
14
+ /** A table key an observed id resolved to, the value found under it, and how it matched. */
15
+ export interface PriceKeyHit<T> {
16
+ key: string;
17
+ match: PriceMatch;
18
+ value: T;
19
+ }
20
+ /**
21
+ * The table-key form of a raw pricing-data key: lowercased, dots turned to dashes, so `GLM-4.7`
22
+ * and `glm-4-7` land on the same entry. Both sides of a lookup must be folded the same way —
23
+ * observed ids go through {@link canonicalizeModelId}, which ends in this same folding.
24
+ */
25
+ export declare function priceTableKey(rawKey: string): string;
26
+ /**
27
+ * Canonicalizes an observed model id into the form used as a pricing-table key. Extends
28
+ * {@link normalizeModelName} (which strips Bedrock/Kimi/vendor-path prefixes) with:
29
+ * 1. Lowercasing, dots turned to dashes, and `@` turned to `-` (so Vertex's `claude-x@20260205`
30
+ * folds to the same shape as a dated id).
31
+ * 2. Stripping a trailing `-vertex` suffix.
32
+ * Used by the pricing resolver, the statusline and cost reconciliation, so every consumer treats
33
+ * the same observed id the same way.
34
+ */
35
+ export declare function canonicalizeModelId(model: string): string;
36
+ /**
37
+ * Resolves an observed model id against a pricing table through `lookup`, trying the keys of
38
+ * {@link priceKeyCandidates} in order and returning the first hit. Returns null when nothing
39
+ * matches — the model is unpriced, never a guessed price.
40
+ */
41
+ export declare function resolvePriceKey<T>(model: string, lookup: (key: string) => T | undefined): PriceKeyHit<T> | null;
42
+ //# sourceMappingURL=price-resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price-resolution.d.ts","sourceRoot":"","sources":["../../src/utils/price-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAsBH,2DAA2D;AAC3D,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;AAE5D,4FAA4F;AAC5F,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,CAAC,CAAC;CACV;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzD;AAoDD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAQ/G"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Model-id → pricing-table-key resolution, shared by every consumer that prices a model id:
3
+ * src/utils/pricing.ts (the analytics report's resolvePrice()) and the standalone Claude
4
+ * statusline (src/agents/plugins/claude/plugin/statusline.ts, bundled into one self-contained file
5
+ * by scripts/bundle-statusline.mjs). Keeping one copy is what stops the live statusline cost and
6
+ * the analytics report from disagreeing on the same transcript.
7
+ *
8
+ * Deliberately free of I/O and of any import beyond model-normalizer.ts (itself dependency-free),
9
+ * so the statusline bundle stays small and never drags in fs/config/keytar-bearing modules. It
10
+ * knows nothing about the shape of a price row — callers pass a key lookup over their own table.
11
+ */
12
+ import { normalizeModelName } from './model-normalizer.js';
13
+ /**
14
+ * A trailing snapshot/version suffix stripped once during lookup (never during canonicalization):
15
+ * an 8-digit date (`-20260205`), a dashed date (`-2026-02-05`), or the `-latest`/`-preview` tags.
16
+ * Applied at most once, so a key that is itself dated (`gpt-4o-2024-05-13`) is tried as an exact
17
+ * match first and never has a second suffix stripped from it.
18
+ */
19
+ const SNAPSHOT_SUFFIX_PATTERN = /-(?:\d{8}|\d{4}-\d{2}-\d{2}|latest|preview)$/;
20
+ /**
21
+ * Matches a Claude id given in version-first order — `claude-<ver>-<family>[<rest>]`, where `ver`
22
+ * is one or more dash-separated numeric segments and `family` is `opus`/`sonnet`/`haiku` — so it
23
+ * can be reordered to the family-first form (`claude-<family>-<ver>[<rest>]`) the pricing table
24
+ * keys newer Claude generations under (e.g. `claude-sonnet-4-5`, `claude-opus-4-8`; see
25
+ * pricing.json's own rows). Never applied to a key that is already family-first, since that
26
+ * doesn't match this pattern in the first place.
27
+ */
28
+ const CLAUDE_VERSION_FIRST_PATTERN = /^claude-(\d+(?:-\d+)*)-(opus|sonnet|haiku)(-.+)?$/;
29
+ /**
30
+ * The table-key form of a raw pricing-data key: lowercased, dots turned to dashes, so `GLM-4.7`
31
+ * and `glm-4-7` land on the same entry. Both sides of a lookup must be folded the same way —
32
+ * observed ids go through {@link canonicalizeModelId}, which ends in this same folding.
33
+ */
34
+ export function priceTableKey(rawKey) {
35
+ return rawKey.toLowerCase().replace(/\./g, '-');
36
+ }
37
+ /**
38
+ * Canonicalizes an observed model id into the form used as a pricing-table key. Extends
39
+ * {@link normalizeModelName} (which strips Bedrock/Kimi/vendor-path prefixes) with:
40
+ * 1. Lowercasing, dots turned to dashes, and `@` turned to `-` (so Vertex's `claude-x@20260205`
41
+ * folds to the same shape as a dated id).
42
+ * 2. Stripping a trailing `-vertex` suffix.
43
+ * Used by the pricing resolver, the statusline and cost reconciliation, so every consumer treats
44
+ * the same observed id the same way.
45
+ */
46
+ export function canonicalizeModelId(model) {
47
+ return priceTableKey(normalizeModelName(model))
48
+ .replace(/@/g, '-')
49
+ .replace(/-vertex$/, '');
50
+ }
51
+ /**
52
+ * Reorders a version-first Claude id (`claude-4-5-sonnet`) to the family-first form
53
+ * (`claude-sonnet-4-5`) the table keys such rows under, preserving any trailing suffix (a
54
+ * snapshot date, `-latest`, ...). Returns null when `id` isn't in that shape.
55
+ */
56
+ function reorderClaudeVersionFamily(id) {
57
+ const match = id.match(CLAUDE_VERSION_FIRST_PATTERN);
58
+ if (!match) {
59
+ return null;
60
+ }
61
+ const [, version, family, rest = ''] = match;
62
+ return `claude-${family}-${version}${rest}`;
63
+ }
64
+ /** `key` with one trailing snapshot suffix stripped, or null when it carries none. */
65
+ function withoutSnapshot(key) {
66
+ const stripped = key.replace(SNAPSHOT_SUFFIX_PATTERN, '');
67
+ return stripped === key ? null : stripped;
68
+ }
69
+ /**
70
+ * The ordered table keys tried for an observed id, against its {@link canonicalizeModelId} form:
71
+ * 1. Exact match — keeps distinct dated rows (e.g. `gpt-4o-2024-05-13`) authoritative.
72
+ * 2. Exact match after stripping one trailing snapshot suffix — e.g. `claude-opus-4-6-20260205`
73
+ * resolves to the `claude-opus-4-6` row.
74
+ * 3. A version-first Claude id (`claude-4-5-sonnet`) reordered to the table's family-first form
75
+ * (`claude-sonnet-4-5`), tried exact and then with a trailing snapshot suffix stripped — only
76
+ * once steps 1-2 have already failed on the as-is id. That ordering is what keeps every
77
+ * pre-existing version-first key (`claude-3-5-sonnet`, `claude-3-7-sonnet-20250219`, ...)
78
+ * resolving unchanged: those rows match as-is at step 1 and this fallback is never reached.
79
+ * There is no segment/family match and no same-tier fallback.
80
+ */
81
+ function priceKeyCandidates(model) {
82
+ const canonical = canonicalizeModelId(model);
83
+ const candidates = [{ key: canonical, match: 'exact' }];
84
+ const snapshot = withoutSnapshot(canonical);
85
+ if (snapshot) {
86
+ candidates.push({ key: snapshot, match: 'snapshot' });
87
+ }
88
+ const reordered = reorderClaudeVersionFamily(canonical);
89
+ if (reordered) {
90
+ candidates.push({ key: reordered, match: 'reordered' });
91
+ const reorderedSnapshot = withoutSnapshot(reordered);
92
+ if (reorderedSnapshot) {
93
+ candidates.push({ key: reorderedSnapshot, match: 'reordered' });
94
+ }
95
+ }
96
+ return candidates;
97
+ }
98
+ /**
99
+ * Resolves an observed model id against a pricing table through `lookup`, trying the keys of
100
+ * {@link priceKeyCandidates} in order and returning the first hit. Returns null when nothing
101
+ * matches — the model is unpriced, never a guessed price.
102
+ */
103
+ export function resolvePriceKey(model, lookup) {
104
+ for (const { key, match } of priceKeyCandidates(model)) {
105
+ const value = key ? lookup(key) : undefined;
106
+ if (value !== undefined) {
107
+ return { key, match, value };
108
+ }
109
+ }
110
+ return null;
111
+ }
112
+ //# sourceMappingURL=price-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price-resolution.js","sourceRoot":"","sources":["../../src/utils/price-resolution.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,8 @@
5
5
  * re-copy that file. Prices are USD per 1,000,000 tokens. The source uses
6
6
  * `cacheWrite`; we expose it as `cacheCreation` to match Claude's terminology.
7
7
  */
8
+ import { type PriceMatch } from './price-resolution.js';
9
+ export { canonicalizeModelId } from './price-resolution.js';
8
10
  /** USD per 1,000,000 tokens. */
9
11
  export interface ModelPrice {
10
12
  input: number;
@@ -12,14 +14,71 @@ export interface ModelPrice {
12
14
  cacheRead: number;
13
15
  cacheCreation: number;
14
16
  cacheWrite1h?: number;
17
+ /**
18
+ * Amazon Bedrock's premium for a regional/multi-region endpoint over this model's global one
19
+ * — present only on rows where Anthropic documents the two-endpoint-type Bedrock pricing
20
+ * structure (Sonnet 4.5+, Haiku 4.5+, Opus 4.5+ and their dated snapshots). Absent (no premium)
21
+ * on every older row, since Anthropic does not document this structure applying there. See
22
+ * isBedrockRegionalPremium()'s own doc comment (bedrock-pricing.mjs) for the source.
23
+ */
24
+ bedrockRegionalMultiplier?: number;
25
+ /**
26
+ * True when this row is not a directly published rate but an estimate (e.g. a tier-price
27
+ * carried forward for a model generation with no confirmed pricing yet). Every row's
28
+ * provenance should be cited in `pricing.json`'s `_meta.sources`/`note`; this flag is what
29
+ * callers use to surface "estimated" alongside the resolved price rather than presenting it
30
+ * as authoritative.
31
+ */
32
+ estimated?: boolean;
15
33
  }
34
+ export interface RawPrice {
35
+ input?: number;
36
+ output?: number;
37
+ cacheRead?: number;
38
+ cacheWrite?: number;
39
+ cacheWrite1h?: number;
40
+ bedrockRegionalMultiplier?: number;
41
+ estimated?: boolean;
42
+ }
43
+ /**
44
+ * Builds the rate card from a bag of raw rows (a parsed `pricing.json`, an injected fixture for
45
+ * tests, or any merge of the two): every key is lowercased and dots are turned to dashes, so
46
+ * `GLM-4.7` and `glm-4-7` land on the same table entry. When two distinct raw keys normalize to
47
+ * the same table key, they must carry identical prices — that is the only way the pricing data
48
+ * itself can declare two spellings of the same model (e.g. `gemini-3.7-flash` / `gemini-3-7-flash`)
49
+ * — otherwise the table is ambiguous and this throws rather than silently picking one.
50
+ */
51
+ export declare function buildPriceTable(rows: Record<string, RawPrice>): Record<string, ModelPrice>;
52
+ /**
53
+ * The fully built rate card: the vendored table with {@link CODEMIE_PRICES} merged over it and every
54
+ * key lowercased. Exported so consumers that cannot import this module — the standalone Claude
55
+ * statusline, which runs as a detached `node <path>` process — can be handed the same rates rather
56
+ * than a copy of the raw `pricing.json`, which carries none of the CodeMie-only rows.
57
+ */
58
+ export declare function priceTable(): Record<string, ModelPrice>;
59
+ /** How {@link resolvePrice} matched an observed model id to a table row. */
60
+ export interface PriceResolution {
61
+ price: ModelPrice;
62
+ key: string;
63
+ match: PriceMatch;
64
+ estimated: boolean;
65
+ }
66
+ /**
67
+ * Resolves pricing for a model, reporting how it was matched. Returns null when no entry
68
+ * matches (the caller marks the model `unpriced` — never a silent $0, and never a guessed
69
+ * family/tier price). The lookup order (exact, then one snapshot suffix stripped, then a
70
+ * version-first Claude id reordered to family-first) lives in {@link resolvePriceKey}, shared
71
+ * with the Claude statusline so the two can never price the same id differently.
72
+ *
73
+ * `model` is also checked, in its original unnormalized form, for a Bedrock region qualifier
74
+ * (see {@link applyBedrockRegionalPremium}) — pass the raw backend id straight through rather
75
+ * than pre-normalizing it, or the premium this exists to detect is invisible by the time it gets
76
+ * here.
77
+ */
78
+ export declare function resolvePrice(model: string): PriceResolution | null;
16
79
  /**
17
- * Look up pricing for a model. Returns null when no entry matches (the caller marks the model
18
- * `unpriced` — never a silent $0). Resolution order:
19
- * 1. Exact (normalized) match — authoritative.
20
- * 2. Longest key aligned to a segment boundary — a deliberate family fallback, logged as inexact.
21
- * 3. Latest same-tier Claude price — for a model newer than every table entry, logged as inexact.
22
- * Dots are folded to dashes first because the table keys use dashes (e.g. `gpt-4-1`, not `gpt-4.1`).
80
+ * Look up pricing for a model. Returns null when no entry matches. Thin wrapper over
81
+ * {@link resolvePrice} for callers that only need the price, not its provenance.
23
82
  */
24
83
  export declare function lookupPrice(model: string): ModelPrice | null;
25
84
  //# sourceMappingURL=pricing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/utils/pricing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,gCAAgC;AAChC,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA0HD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CA2B5D"}
1
+ {"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/utils/pricing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,OAAO,EAAkC,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExF,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,gCAAgC;AAChC,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;OAMG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA4CD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAiB1F;AAWD;;;;;GAKG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAEvD;AAED,4EAA4E;AAC5E,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAYlE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAE5D"}
@@ -8,142 +8,116 @@
8
8
  import { readFileSync } from 'node:fs';
9
9
  import { join } from 'node:path';
10
10
  import { getDirname } from './paths.js';
11
- import { normalizeModelName } from './model-normalizer.js';
12
- import { logger } from './logger.js';
11
+ import { applyBedrockRegionalPremium } from './bedrock-pricing.mjs';
12
+ import { ConfigurationError } from './errors.js';
13
+ import { priceTableKey, resolvePriceKey } from './price-resolution.js';
14
+ export { canonicalizeModelId } from './price-resolution.js';
15
+ /**
16
+ * CodeMie-specific ids the vendored table will never carry. Merged over the vendored rows
17
+ * in {@link table}, so re-copying `pricing.json` from agentlytics does not silently drop them.
18
+ *
19
+ * `claude-smart-router` is a Switchyard routing alias, not a generation model. The alias bills
20
+ * only the Haiku classifier hop that picks a target; the generation itself is billed against the
21
+ * model the router dispatched to, which arrives in the response body's own `model` field and is
22
+ * priced from its own row. Haiku rates therefore price what this id actually costs — without a
23
+ * row at all, `lookupPrice` returns null and the turn drops out of every cost total.
24
+ */
25
+ const CODEMIE_PRICES = {
26
+ 'claude-smart-router': { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25, cacheWrite1h: 2 },
27
+ };
13
28
  const HERE = getDirname(import.meta.url);
14
29
  let TABLE = null;
15
- function table() {
16
- if (TABLE) {
17
- return TABLE;
18
- }
19
- const raw = JSON.parse(readFileSync(join(HERE, 'pricing.json'), 'utf-8'));
20
- const built = {};
21
- for (const [key, p] of Object.entries(raw)) {
22
- if (key.startsWith('_')) {
23
- continue; // skip _meta and similar
24
- }
25
- built[key.toLowerCase()] = {
26
- input: p.input ?? 0,
27
- output: p.output ?? 0,
28
- cacheRead: p.cacheRead ?? 0,
29
- cacheCreation: p.cacheWrite ?? 0,
30
- cacheWrite1h: p.cacheWrite1h,
31
- };
32
- }
33
- TABLE = built;
34
- return TABLE;
30
+ function toModelPrice(p) {
31
+ return {
32
+ input: p.input ?? 0,
33
+ output: p.output ?? 0,
34
+ cacheRead: p.cacheRead ?? 0,
35
+ cacheCreation: p.cacheWrite ?? 0,
36
+ cacheWrite1h: p.cacheWrite1h,
37
+ bedrockRegionalMultiplier: p.bedrockRegionalMultiplier,
38
+ estimated: p.estimated,
39
+ };
40
+ }
41
+ function pricesEqual(a, b) {
42
+ return (a.input === b.input
43
+ && a.output === b.output
44
+ && a.cacheRead === b.cacheRead
45
+ && a.cacheCreation === b.cacheCreation
46
+ && a.cacheWrite1h === b.cacheWrite1h
47
+ && a.bedrockRegionalMultiplier === b.bedrockRegionalMultiplier
48
+ && a.estimated === b.estimated);
35
49
  }
36
50
  /**
37
- * True when `key` aligns to a segment boundary within `name` (delimited by `-` or the
38
- * string edges), so a key is never matched mid-token — e.g. `gpt-4` does not match inside
39
- * `gpt-4o` (which resolves to its own `gpt-4o` entry), and `gpt-4` does not match `gpt-4.1`
40
- * (folded to `gpt-4-1`, which has its own entry).
51
+ * Builds the rate card from a bag of raw rows (a parsed `pricing.json`, an injected fixture for
52
+ * tests, or any merge of the two): every key is lowercased and dots are turned to dashes, so
53
+ * `GLM-4.7` and `glm-4-7` land on the same table entry. When two distinct raw keys normalize to
54
+ * the same table key, they must carry identical prices — that is the only way the pricing data
55
+ * itself can declare two spellings of the same model (e.g. `gemini-3.7-flash` / `gemini-3-7-flash`)
56
+ * — otherwise the table is ambiguous and this throws rather than silently picking one.
41
57
  */
42
- function isSegmentMatch(name, key) {
43
- for (let from = 0;;) {
44
- const idx = name.indexOf(key, from);
45
- if (idx === -1) {
46
- return false;
58
+ export function buildPriceTable(rows) {
59
+ const built = {};
60
+ for (const [rawKey, raw] of Object.entries(rows)) {
61
+ if (rawKey.startsWith('_')) {
62
+ continue; // skip _meta and similar
47
63
  }
48
- const before = idx === 0 ? '-' : name[idx - 1];
49
- const afterIdx = idx + key.length;
50
- const after = afterIdx === name.length ? '-' : name[afterIdx];
51
- if (before === '-' && after === '-') {
52
- return true;
64
+ const key = priceTableKey(rawKey);
65
+ const price = toModelPrice(raw);
66
+ const existing = built[key];
67
+ if (existing && !pricesEqual(existing, price)) {
68
+ throw new ConfigurationError(`[pricing] "${rawKey}" normalizes to key "${key}", which already holds a different price`);
53
69
  }
54
- from = idx + 1;
70
+ built[key] = price;
55
71
  }
72
+ return built;
56
73
  }
57
- /** Claude pricing tiers whose per-tier rate has stayed flat across every `-4-*` version bump seen so far. */
58
- const CLAUDE_TIERS = ['claude-opus', 'claude-sonnet', 'claude-haiku'];
59
- /**
60
- * Parse the version segments trailing a tier prefix into a numeric tuple for comparison, e.g.
61
- * `claude-sonnet-4-8` under tier `claude-sonnet` -> `[4, 8]`. Returns null for keys that don't
62
- * fit the plain `<tier>(-<digits>)*` shape — non-numeric segments (`-latest`) or a long numeric
63
- * segment (a pinned date snapshot like `-20250514`, 8 digits) — since those aren't meaningful
64
- * "is this newer" signals and would otherwise outrank a real version bump by raw magnitude.
65
- */
66
- function tierVersionTuple(key, tier) {
67
- const rest = key.slice(tier.length);
68
- if (!rest) {
69
- return [0];
70
- }
71
- const segments = rest.split('-').filter(Boolean);
72
- const nums = [];
73
- for (const segment of segments) {
74
- if (!/^\d+$/.test(segment) || segment.length >= 8) {
75
- return null;
76
- }
77
- nums.push(Number(segment));
74
+ function table() {
75
+ if (TABLE) {
76
+ return TABLE;
78
77
  }
79
- return nums;
78
+ const raw = JSON.parse(readFileSync(join(HERE, 'pricing.json'), 'utf-8'));
79
+ TABLE = buildPriceTable({ ...raw, ...CODEMIE_PRICES });
80
+ return TABLE;
80
81
  }
81
- function compareVersionTuples(a, b) {
82
- for (let i = 0; i < Math.max(a.length, b.length); i++) {
83
- const diff = (a[i] ?? 0) - (b[i] ?? 0);
84
- if (diff !== 0) {
85
- return diff;
86
- }
87
- }
88
- return 0;
82
+ /**
83
+ * The fully built rate card: the vendored table with {@link CODEMIE_PRICES} merged over it and every
84
+ * key lowercased. Exported so consumers that cannot import this module — the standalone Claude
85
+ * statusline, which runs as a detached `node <path>` process — can be handed the same rates rather
86
+ * than a copy of the raw `pricing.json`, which carries none of the CodeMie-only rows.
87
+ */
88
+ export function priceTable() {
89
+ return table();
89
90
  }
90
91
  /**
91
- * Fall back to the latest known price within the same Claude tier (opus/sonnet/haiku) when a
92
- * model name matches no table entry at all — e.g. a new major-version model (`claude-sonnet-5`)
93
- * that shares no version segment with any `-4-*` key, so {@link isSegmentMatch} can't find it.
94
- * Every version bump observed within a tier so far has kept the same per-token rate, so the
95
- * latest known entry is the best available estimate; callers must still log this as inexact.
92
+ * Resolves pricing for a model, reporting how it was matched. Returns null when no entry
93
+ * matches (the caller marks the model `unpriced` — never a silent $0, and never a guessed
94
+ * family/tier price). The lookup order (exact, then one snapshot suffix stripped, then a
95
+ * version-first Claude id reordered to family-first) lives in {@link resolvePriceKey}, shared
96
+ * with the Claude statusline so the two can never price the same id differently.
97
+ *
98
+ * `model` is also checked, in its original unnormalized form, for a Bedrock region qualifier
99
+ * (see {@link applyBedrockRegionalPremium}) — pass the raw backend id straight through rather
100
+ * than pre-normalizing it, or the premium this exists to detect is invisible by the time it gets
101
+ * here.
96
102
  */
97
- function claudeTierFallback(normalized, prices) {
98
- const tier = CLAUDE_TIERS.find((t) => normalized === t || normalized.startsWith(`${t}-`));
99
- if (!tier) {
103
+ export function resolvePrice(model) {
104
+ const prices = table();
105
+ const hit = resolvePriceKey(model, (key) => (Object.hasOwn(prices, key) ? prices[key] : undefined));
106
+ if (!hit) {
100
107
  return null;
101
108
  }
102
- let best = null;
103
- for (const [key, price] of Object.entries(prices)) {
104
- if (key !== tier && !key.startsWith(`${tier}-`)) {
105
- continue;
106
- }
107
- const version = tierVersionTuple(key, tier);
108
- if (version === null) {
109
- continue;
110
- }
111
- if (!best || compareVersionTuples(version, best.version) > 0) {
112
- best = { key, version, price };
113
- }
114
- }
115
- return best ? { key: best.key, price: best.price } : null;
109
+ return {
110
+ price: applyBedrockRegionalPremium(hit.value, model),
111
+ key: hit.key,
112
+ match: hit.match,
113
+ estimated: hit.value.estimated ?? false,
114
+ };
116
115
  }
117
116
  /**
118
- * Look up pricing for a model. Returns null when no entry matches (the caller marks the model
119
- * `unpriced` — never a silent $0). Resolution order:
120
- * 1. Exact (normalized) match — authoritative.
121
- * 2. Longest key aligned to a segment boundary — a deliberate family fallback, logged as inexact.
122
- * 3. Latest same-tier Claude price — for a model newer than every table entry, logged as inexact.
123
- * Dots are folded to dashes first because the table keys use dashes (e.g. `gpt-4-1`, not `gpt-4.1`).
117
+ * Look up pricing for a model. Returns null when no entry matches. Thin wrapper over
118
+ * {@link resolvePrice} for callers that only need the price, not its provenance.
124
119
  */
125
120
  export function lookupPrice(model) {
126
- const normalized = normalizeModelName(model).toLowerCase().replace(/\./g, '-');
127
- const prices = table();
128
- const exact = prices[normalized];
129
- if (exact) {
130
- return exact;
131
- }
132
- let best = null;
133
- for (const [key, price] of Object.entries(prices)) {
134
- if (isSegmentMatch(normalized, key) && (!best || key.length > best.key.length)) {
135
- best = { key, price };
136
- }
137
- }
138
- if (best) {
139
- logger.debug(`[pricing] no exact entry for "${normalized}"; using family price "${best.key}"`);
140
- return best.price;
141
- }
142
- const tierFallback = claudeTierFallback(normalized, prices);
143
- if (tierFallback) {
144
- logger.debug(`[pricing] no entry for "${normalized}"; using latest same-tier price "${tierFallback.key}"`);
145
- return tierFallback.price;
146
- }
147
- return null;
121
+ return resolvePrice(model)?.price ?? null;
148
122
  }
149
123
  //# sourceMappingURL=pricing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/utils/pricing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAmBrC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEzC,IAAI,KAAK,GAAsC,IAAI,CAAC;AAEpD,SAAS,KAAK;IACZ,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAA6B,CAAC;IACtG,MAAM,KAAK,GAA+B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,SAAS,CAAC,yBAAyB;QACrC,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG;YACzB,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;YACnB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC;YACrB,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC;YAC3B,aAAa,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC;YAChC,YAAY,EAAE,CAAC,CAAC,YAAY;SAC7B,CAAC;IACJ,CAAC;IACD,KAAK,GAAG,KAAK,CAAC;IACd,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,IAAY,EAAE,GAAW;IAC/C,KAAK,IAAI,IAAI,GAAG,CAAC,IAAM,CAAC;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;YACf,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC;QAClC,MAAM,KAAK,GAAG,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,MAAM,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC;IACjB,CAAC;AACH,CAAC;AAED,6GAA6G;AAC7G,MAAM,YAAY,GAAG,CAAC,aAAa,EAAE,eAAe,EAAE,cAAc,CAAC,CAAC;AAEtE;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,GAAW,EAAE,IAAY;IACjD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,CAAC,CAAC,CAAC;IACb,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YAClD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,oBAAoB,CAAC,CAAW,EAAE,CAAW;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;GAMG;AACH,SAAS,kBAAkB,CAAC,UAAkB,EAAE,MAAkC;IAChF,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,KAAK,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1F,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,GAAiE,IAAI,CAAC;IAC9E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;YAChD,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC5C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,oBAAoB,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7D,IAAI,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACjC,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC5D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,KAAK,EAAE,CAAC;IAEvB,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACjC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,IAAI,GAA8C,IAAI,CAAC;IAC3D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,cAAc,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/E,IAAI,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;QACxB,CAAC;IACH,CAAC;IACD,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,CAAC,KAAK,CAAC,iCAAiC,UAAU,0BAA0B,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,MAAM,YAAY,GAAG,kBAAkB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC5D,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,KAAK,CAAC,2BAA2B,UAAU,oCAAoC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC;QAC3G,OAAO,YAAY,CAAC,KAAK,CAAC;IAC5B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/utils/pricing.ts"],"names":[],"mappings":"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"}