@trazum/core 1.8.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.
Files changed (223) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +163 -0
  3. package/dist/advisories.d.ts +23 -0
  4. package/dist/advisories.d.ts.map +1 -0
  5. package/dist/advisories.js +376 -0
  6. package/dist/advisories.js.map +1 -0
  7. package/dist/aws-sigv4.d.ts +88 -0
  8. package/dist/aws-sigv4.d.ts.map +1 -0
  9. package/dist/aws-sigv4.js +117 -0
  10. package/dist/aws-sigv4.js.map +1 -0
  11. package/dist/baseline.d.ts +171 -0
  12. package/dist/baseline.d.ts.map +1 -0
  13. package/dist/baseline.js +273 -0
  14. package/dist/baseline.js.map +1 -0
  15. package/dist/cache.d.ts +26 -0
  16. package/dist/cache.d.ts.map +1 -0
  17. package/dist/cache.js +28 -0
  18. package/dist/cache.js.map +1 -0
  19. package/dist/changes.d.ts +29 -0
  20. package/dist/changes.d.ts.map +1 -0
  21. package/dist/changes.js +142 -0
  22. package/dist/changes.js.map +1 -0
  23. package/dist/compare.d.ts +65 -0
  24. package/dist/compare.d.ts.map +1 -0
  25. package/dist/compare.js +58 -0
  26. package/dist/compare.js.map +1 -0
  27. package/dist/config-schema.d.ts +118 -0
  28. package/dist/config-schema.d.ts.map +1 -0
  29. package/dist/config-schema.js +315 -0
  30. package/dist/config-schema.js.map +1 -0
  31. package/dist/config.d.ts +47 -0
  32. package/dist/config.d.ts.map +1 -0
  33. package/dist/config.js +112 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/detect.d.ts +70 -0
  36. package/dist/detect.d.ts.map +1 -0
  37. package/dist/detect.js +228 -0
  38. package/dist/detect.js.map +1 -0
  39. package/dist/evaluate.d.ts +98 -0
  40. package/dist/evaluate.d.ts.map +1 -0
  41. package/dist/evaluate.js +110 -0
  42. package/dist/evaluate.js.map +1 -0
  43. package/dist/extract.d.ts +81 -0
  44. package/dist/extract.d.ts.map +1 -0
  45. package/dist/extract.js +280 -0
  46. package/dist/extract.js.map +1 -0
  47. package/dist/gcp-auth.d.ts +58 -0
  48. package/dist/gcp-auth.d.ts.map +1 -0
  49. package/dist/gcp-auth.js +113 -0
  50. package/dist/gcp-auth.js.map +1 -0
  51. package/dist/glob.d.ts +49 -0
  52. package/dist/glob.d.ts.map +1 -0
  53. package/dist/glob.js +154 -0
  54. package/dist/glob.js.map +1 -0
  55. package/dist/host.d.ts +30 -0
  56. package/dist/host.d.ts.map +1 -0
  57. package/dist/host.js +69 -0
  58. package/dist/host.js.map +1 -0
  59. package/dist/i18n/en.d.ts +4 -0
  60. package/dist/i18n/en.d.ts.map +1 -0
  61. package/dist/i18n/en.js +168 -0
  62. package/dist/i18n/en.js.map +1 -0
  63. package/dist/i18n/es.d.ts +4 -0
  64. package/dist/i18n/es.d.ts.map +1 -0
  65. package/dist/i18n/es.js +168 -0
  66. package/dist/i18n/es.js.map +1 -0
  67. package/dist/i18n/index.d.ts +36 -0
  68. package/dist/i18n/index.d.ts.map +1 -0
  69. package/dist/i18n/index.js +50 -0
  70. package/dist/i18n/index.js.map +1 -0
  71. package/dist/i18n/types.d.ts +180 -0
  72. package/dist/i18n/types.d.ts.map +1 -0
  73. package/dist/i18n/types.js +11 -0
  74. package/dist/i18n/types.js.map +1 -0
  75. package/dist/index.d.ts +66 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +69 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/llm.d.ts +226 -0
  80. package/dist/llm.d.ts.map +1 -0
  81. package/dist/llm.js +485 -0
  82. package/dist/llm.js.map +1 -0
  83. package/dist/nearest.d.ts +20 -0
  84. package/dist/nearest.d.ts.map +1 -0
  85. package/dist/nearest.js +54 -0
  86. package/dist/nearest.js.map +1 -0
  87. package/dist/net.d.ts +90 -0
  88. package/dist/net.d.ts.map +1 -0
  89. package/dist/net.js +203 -0
  90. package/dist/net.js.map +1 -0
  91. package/dist/node.d.ts +32 -0
  92. package/dist/node.d.ts.map +1 -0
  93. package/dist/node.js +33 -0
  94. package/dist/node.js.map +1 -0
  95. package/dist/openrouter.d.ts +25 -0
  96. package/dist/openrouter.d.ts.map +1 -0
  97. package/dist/openrouter.js +72 -0
  98. package/dist/openrouter.js.map +1 -0
  99. package/dist/optimize.d.ts +38 -0
  100. package/dist/optimize.d.ts.map +1 -0
  101. package/dist/optimize.js +183 -0
  102. package/dist/optimize.js.map +1 -0
  103. package/dist/otlp.d.ts +91 -0
  104. package/dist/otlp.d.ts.map +1 -0
  105. package/dist/otlp.js +102 -0
  106. package/dist/otlp.js.map +1 -0
  107. package/dist/phrases.d.ts +169 -0
  108. package/dist/phrases.d.ts.map +1 -0
  109. package/dist/phrases.js +939 -0
  110. package/dist/phrases.js.map +1 -0
  111. package/dist/pricing-overlay.d.ts +55 -0
  112. package/dist/pricing-overlay.d.ts.map +1 -0
  113. package/dist/pricing-overlay.js +241 -0
  114. package/dist/pricing-overlay.js.map +1 -0
  115. package/dist/pricing.d.ts +115 -0
  116. package/dist/pricing.d.ts.map +1 -0
  117. package/dist/pricing.js +400 -0
  118. package/dist/pricing.js.map +1 -0
  119. package/dist/profile.d.ts +71 -0
  120. package/dist/profile.d.ts.map +1 -0
  121. package/dist/profile.js +55 -0
  122. package/dist/profile.js.map +1 -0
  123. package/dist/promptfoo.d.ts +58 -0
  124. package/dist/promptfoo.d.ts.map +1 -0
  125. package/dist/promptfoo.js +149 -0
  126. package/dist/promptfoo.js.map +1 -0
  127. package/dist/prune.d.ts +91 -0
  128. package/dist/prune.d.ts.map +1 -0
  129. package/dist/prune.js +110 -0
  130. package/dist/prune.js.map +1 -0
  131. package/dist/reorder.d.ts +82 -0
  132. package/dist/reorder.d.ts.map +1 -0
  133. package/dist/reorder.js +215 -0
  134. package/dist/reorder.js.map +1 -0
  135. package/dist/review.d.ts +54 -0
  136. package/dist/review.d.ts.map +1 -0
  137. package/dist/review.js +131 -0
  138. package/dist/review.js.map +1 -0
  139. package/dist/rules.d.ts +5 -0
  140. package/dist/rules.d.ts.map +1 -0
  141. package/dist/rules.js +279 -0
  142. package/dist/rules.js.map +1 -0
  143. package/dist/savings.d.ts +36 -0
  144. package/dist/savings.d.ts.map +1 -0
  145. package/dist/savings.js +83 -0
  146. package/dist/savings.js.map +1 -0
  147. package/dist/segment.d.ts +8 -0
  148. package/dist/segment.d.ts.map +1 -0
  149. package/dist/segment.js +74 -0
  150. package/dist/segment.js.map +1 -0
  151. package/dist/shared-prefix.d.ts +63 -0
  152. package/dist/shared-prefix.d.ts.map +1 -0
  153. package/dist/shared-prefix.js +151 -0
  154. package/dist/shared-prefix.js.map +1 -0
  155. package/dist/similarity.d.ts +13 -0
  156. package/dist/similarity.d.ts.map +1 -0
  157. package/dist/similarity.js +30 -0
  158. package/dist/similarity.js.map +1 -0
  159. package/dist/structure.d.ts +144 -0
  160. package/dist/structure.d.ts.map +1 -0
  161. package/dist/structure.js +455 -0
  162. package/dist/structure.js.map +1 -0
  163. package/dist/suggest.d.ts +100 -0
  164. package/dist/suggest.d.ts.map +1 -0
  165. package/dist/suggest.js +151 -0
  166. package/dist/suggest.js.map +1 -0
  167. package/dist/tokenizer.d.ts +57 -0
  168. package/dist/tokenizer.d.ts.map +1 -0
  169. package/dist/tokenizer.js +157 -0
  170. package/dist/tokenizer.js.map +1 -0
  171. package/dist/types.d.ts +296 -0
  172. package/dist/types.d.ts.map +1 -0
  173. package/dist/types.js +3 -0
  174. package/dist/types.js.map +1 -0
  175. package/dist/walk.d.ts +40 -0
  176. package/dist/walk.d.ts.map +1 -0
  177. package/dist/walk.js +95 -0
  178. package/dist/walk.js.map +1 -0
  179. package/package.json +56 -0
  180. package/src/advisories.ts +431 -0
  181. package/src/aws-sigv4.ts +174 -0
  182. package/src/baseline.ts +390 -0
  183. package/src/cache.ts +54 -0
  184. package/src/changes.ts +158 -0
  185. package/src/compare.ts +131 -0
  186. package/src/config-schema.ts +451 -0
  187. package/src/config.ts +161 -0
  188. package/src/detect.ts +312 -0
  189. package/src/evaluate.ts +188 -0
  190. package/src/extract.ts +336 -0
  191. package/src/gcp-auth.ts +166 -0
  192. package/src/glob.ts +160 -0
  193. package/src/host.ts +90 -0
  194. package/src/i18n/en.ts +236 -0
  195. package/src/i18n/es.ts +236 -0
  196. package/src/i18n/index.ts +68 -0
  197. package/src/i18n/types.ts +230 -0
  198. package/src/index.ts +228 -0
  199. package/src/llm.ts +708 -0
  200. package/src/nearest.ts +61 -0
  201. package/src/net.ts +233 -0
  202. package/src/node.ts +63 -0
  203. package/src/openrouter.ts +125 -0
  204. package/src/optimize.ts +228 -0
  205. package/src/otlp.ts +179 -0
  206. package/src/phrases.ts +1047 -0
  207. package/src/pricing-overlay.ts +319 -0
  208. package/src/pricing.ts +468 -0
  209. package/src/profile.ts +124 -0
  210. package/src/promptfoo.ts +213 -0
  211. package/src/prune.ts +211 -0
  212. package/src/reorder.ts +307 -0
  213. package/src/review.ts +180 -0
  214. package/src/rules.ts +324 -0
  215. package/src/savings.ts +121 -0
  216. package/src/segment.ts +106 -0
  217. package/src/shared-prefix.ts +198 -0
  218. package/src/similarity.ts +28 -0
  219. package/src/structure.ts +652 -0
  220. package/src/suggest.ts +254 -0
  221. package/src/tokenizer.ts +190 -0
  222. package/src/types.ts +323 -0
  223. package/src/walk.ts +117 -0
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Internationalisation contract for the core.
3
+ *
4
+ * Every user-facing string the core produces lives in a locale catalogue
5
+ * instead of being hardcoded next to the logic. Adding a locale means adding
6
+ * one file — it never means touching the rules engine or the pricing model.
7
+ */
8
+
9
+ /** Locales shipped with Trazum. English is the source of truth. */
10
+ export const LOCALES = ['en', 'es'] as const;
11
+
12
+ export type Locale = (typeof LOCALES)[number];
13
+
14
+ export const DEFAULT_LOCALE: Locale = 'en';
15
+
16
+ /**
17
+ * Identifier of every deterministic rule.
18
+ *
19
+ * Declared as a union rather than `string` on purpose: adding a rule fails to
20
+ * compile until every locale catalogue describes it, so a new rule can never
21
+ * ship with a missing translation.
22
+ */
23
+ export type RuleId =
24
+ | 'duplicate-blocks'
25
+ | 'near-duplicate-blocks'
26
+ | 'duplicate-lines'
27
+ | 'verbose-phrases'
28
+ | 'politeness'
29
+ | 'filler'
30
+ | 'hedges'
31
+ | 'intensifiers'
32
+ | 'self-check'
33
+ | 'emphasis'
34
+ | 'decoration'
35
+ | 'whitespace';
36
+
37
+ /** A headline plus its explanation, both already translated. */
38
+ export interface LocalizedMessage {
39
+ title: string;
40
+ detail: string;
41
+ }
42
+
43
+ export interface RuleCopy {
44
+ title: string;
45
+ /** What the rule does and why it is safe at its level. */
46
+ rationale: string;
47
+ }
48
+
49
+ // --------------------------------------------------------------------------
50
+ // Advisory parameters
51
+ // --------------------------------------------------------------------------
52
+
53
+ export interface ContextOverflowParams {
54
+ tokens: number;
55
+ modelName: string;
56
+ contextWindow: number;
57
+ }
58
+
59
+ export interface PromptCachingParams {
60
+ /** First template placeholder, or `null` when the prompt has none. */
61
+ placeholder: string | null;
62
+ prefixTokens: number;
63
+ totalTokens: number;
64
+ minTokens: number;
65
+ modelName: string;
66
+ /** Cache hit rate as a whole percentage. */
67
+ hitRatePct: number;
68
+ /** Cache read price as a percentage of the input price, for this provider. */
69
+ readPct: number;
70
+ /** Cache write price as a percentage of the input price, for this provider. */
71
+ writePct: number;
72
+ /**
73
+ * Whether the caller has to mark the prefix.
74
+ *
75
+ * Telling somebody on OpenAI to "set cache_control" names a parameter that
76
+ * does not exist for them: their caching is automatic above a threshold. The
77
+ * advice to move stable content forward is identical either way — a prefix is
78
+ * a prefix — but the instruction that follows it is not.
79
+ */
80
+ explicit: boolean;
81
+ }
82
+
83
+ export interface BelowCacheMinimumParams {
84
+ modelName: string;
85
+ minTokens: number;
86
+ placeholder: string | null;
87
+ prefixTokens: number;
88
+ totalTokens: number;
89
+ /** Whether to point at Claude Opus 5's lower 512-token minimum. */
90
+ mentionLowerMinimum: boolean;
91
+ }
92
+
93
+ export interface CachePrefixReorderParams {
94
+ staticTokensAfter: number;
95
+ sharePct: number;
96
+ placeholder: string;
97
+ }
98
+
99
+ export interface ModelDowngradeParams {
100
+ modelName: string;
101
+ tier: string;
102
+ candidateName: string;
103
+ currentUsd: string;
104
+ candidateUsd: string;
105
+ }
106
+
107
+ export interface OutputDominatedParams {
108
+ outputUsd: string;
109
+ inputUsd: string;
110
+ }
111
+
112
+ export interface PromoPricingParams {
113
+ modelName: string;
114
+ promoInput: number;
115
+ promoOutput: number;
116
+ until: string;
117
+ listInput: number;
118
+ listOutput: number;
119
+ }
120
+
121
+ export interface ContradictoryInstructionsParams {
122
+ /** Human-readable name of the axis the two instructions disagree on. */
123
+ axis: string;
124
+ firstValue: string;
125
+ firstSnippet: string;
126
+ secondValue: string;
127
+ secondSnippet: string;
128
+ /** How many other axes also disagree, beyond this one. */
129
+ otherCount: number;
130
+ }
131
+
132
+ export interface RedundantExamplesParams {
133
+ redundantCount: number;
134
+ totalCount: number;
135
+ redundantTokens: number;
136
+ /** Similarity of the closest pair, 0-100. */
137
+ topSimilarityPct: number;
138
+ }
139
+
140
+ export interface MovableSchemaParams {
141
+ /** How many cued schema blocks were found. */
142
+ blocks: number;
143
+ /** Tokens they hold, fences included. */
144
+ tokens: number;
145
+ /** The keys, already formatted for prose. */
146
+ keyList: string;
147
+ /** The phrase that identified the block as an output contract. */
148
+ cue: string;
149
+ }
150
+
151
+ export interface RestatedOutputFormatParams {
152
+ restatedCount: number;
153
+ totalCount: number;
154
+ restatedTokens: number;
155
+ /** The restated field names, already formatted for display. */
156
+ keyList: string;
157
+ }
158
+
159
+ /** Reasons the optional LLM pass can reject a candidate. */
160
+ export interface LlmMessages {
161
+ emptyResponse(): string;
162
+ protectedContentAltered(count: number): string;
163
+ notShorter(after: number, before: number): string;
164
+ suspiciousShrink(retainedPct: number): string;
165
+ }
166
+
167
+ /** Why a proposed rewrite did not survive checking against the prompt. */
168
+ export interface SuggestMessages {
169
+ 'not-found'(): string;
170
+ 'touches-protected'(): string;
171
+ 'introduces-protected'(): string;
172
+ 'no-saving'(): string;
173
+ overlaps(): string;
174
+ }
175
+
176
+ /** Everything the core needs to speak one language. */
177
+ export interface CoreMessages {
178
+ locale: Locale;
179
+ /** BCP 47 tag used for number formatting (e.g. `en-US`). */
180
+ numberLocale: string;
181
+ rules: Record<RuleId, RuleCopy>;
182
+ llm: LlmMessages;
183
+ suggest: SuggestMessages;
184
+ advisories: {
185
+ contextOverflow(p: ContextOverflowParams): LocalizedMessage;
186
+ promptCaching(p: PromptCachingParams): LocalizedMessage;
187
+ promptCachingNotWorthIt(): LocalizedMessage;
188
+ belowCacheMinimum(p: BelowCacheMinimumParams): LocalizedMessage;
189
+ cachePrefixReorder(p: CachePrefixReorderParams): LocalizedMessage;
190
+ batchApi(): LocalizedMessage;
191
+ modelDowngrade(p: ModelDowngradeParams): LocalizedMessage;
192
+ outputDominated(p: OutputDominatedParams): LocalizedMessage;
193
+ promoPricing(p: PromoPricingParams): LocalizedMessage;
194
+ contradictoryInstructions(p: ContradictoryInstructionsParams): LocalizedMessage;
195
+ redundantExamples(p: RedundantExamplesParams): LocalizedMessage;
196
+ restatedOutputFormat(p: RestatedOutputFormatParams): LocalizedMessage;
197
+ movableSchema(p: MovableSchemaParams): LocalizedMessage;
198
+ };
199
+ /** Names of the axes two instructions can disagree on. */
200
+ contradictionAxes: Record<ContradictionAxisId, string>;
201
+ /** Names of each end of those axes, as they read inside the advisory. */
202
+ contradictionValues: Record<ContradictionValueId, string>;
203
+ }
204
+
205
+ /**
206
+ * Kept in step with `ContradictionAxis` in `structure.ts`. Declared here so a
207
+ * new axis fails to compile until every catalogue names it.
208
+ */
209
+ export type ContradictionAxisId =
210
+ | 'response-language'
211
+ | 'output-format'
212
+ | 'response-length'
213
+ | 'reasoning-visibility';
214
+
215
+ /**
216
+ * The two ends of each axis. Identifiers rather than prose for the same reason
217
+ * the axes are: the advisory names both sides in its sentence, so leaving them
218
+ * as English strings in the detector would print English inside a Spanish
219
+ * report.
220
+ */
221
+ export type ContradictionValueId =
222
+ | 'fixed-language'
223
+ | 'mirror-language'
224
+ | 'format-json'
225
+ | 'format-markdown'
226
+ | 'format-plain-text'
227
+ | 'length-brief'
228
+ | 'length-detailed'
229
+ | 'reasoning-shown'
230
+ | 'reasoning-hidden';
package/src/index.ts ADDED
@@ -0,0 +1,228 @@
1
+ export * from './types.js';
2
+ export { estimateTokens, countTokensAnthropic } from './tokenizer.js';
3
+ export { countSentences, profilePrompt } from './profile.js';
4
+ export { PHRASE_LANGUAGES } from './phrases.js';
5
+ export { toPromptfoo } from './promptfoo.js';
6
+ export { toOtlpMetrics } from './otlp.js';
7
+ export type { OtlpAttribute, OtlpDataPoint, OtlpInput, OtlpMetric, OtlpPayload } from './otlp.js';
8
+ export type { PromptfooExport, PromptfooOptions, PromptfooWarning } from './promptfoo.js';
9
+ export type { ProfileOptions, PromptProfile } from './profile.js';
10
+ export { SUGGEST_SYSTEM_PROMPT, applyRewrites, rejectionText, suggestRewrites } from './suggest.js';
11
+ export type {
12
+ RejectedReason,
13
+ RewriteSuggestion,
14
+ SuggestOptions,
15
+ SuggestResult,
16
+ } from './suggest.js';
17
+ export type { AsyncTokenCounter, AnthropicCounterOptions } from './tokenizer.js';
18
+ export {
19
+ MODELS,
20
+ DEFAULT_MODEL,
21
+ COST_MULTIPLIERS,
22
+ PRICING_LAST_REVIEWED,
23
+ reviewAgeDays,
24
+ BUNDLED_CATALOGUE,
25
+ getModel,
26
+ listModels,
27
+ effectivePricing,
28
+ cheapestOfTier,
29
+ modelFrom,
30
+ cheapestOfTierIn,
31
+ multipliersFor,
32
+ } from './pricing.js';
33
+ export type { PricingCatalogue } from './pricing.js';
34
+ export type { CachingMode, Capability, CostMultipliers } from './types.js';
35
+
36
+ // Local price corrections, so a price change needs no library upgrade.
37
+ export {
38
+ MAX_PRICING_BYTES,
39
+ PRICING_MODEL_KEYS,
40
+ PRICING_OVERLAY_KEYS,
41
+ PricingOverlayError,
42
+ applyPricingOverlay,
43
+ catalogueFromOverlay,
44
+ parsePricingOverlay,
45
+ } from './pricing-overlay.js';
46
+ export type { PricingOverlay } from './pricing-overlay.js';
47
+ export { openrouterOverlay } from './openrouter.js';
48
+
49
+ // SigV4 and the Google service-account flow, both hand-rolled on WebCrypto to
50
+ // keep the zero-dependency invariant. Exported so they can be tested directly:
51
+ // a signer that is only reachable through a network call is a signer nothing
52
+ // checks.
53
+ export { amzDates, canonicalRequest, signRequest, signingKey } from './aws-sigv4.js';
54
+ export type { SignInput, SignedHeaders } from './aws-sigv4.js';
55
+ export { accessToken, pkcs8FromPem, signedJwt } from './gcp-auth.js';
56
+ export type { CachedToken, ServiceAccount } from './gcp-auth.js';
57
+ export type { OpenRouterResult } from './openrouter.js';
58
+ export {
59
+ BASELINE_FILENAME,
60
+ BASELINE_VERSION,
61
+ BaselineError,
62
+ MAX_BASELINE_BYTES,
63
+ breaches,
64
+ compareToBaseline,
65
+ formatBaseline,
66
+ moneyIsComparable,
67
+ parseBaseline,
68
+ } from './baseline.js';
69
+ export type {
70
+ BaselineBreach,
71
+ BaselineChange,
72
+ BaselineComparison,
73
+ BaselineDocument,
74
+ BaselineThresholds,
75
+ } from './baseline.js';
76
+ export { RULES, getRule } from './rules.js';
77
+ export { segment, join, protectedTexts } from './segment.js';
78
+ export { computeSavings, costOfCall, formatUsd, formatSignedUsd } from './savings.js';
79
+ export { buildAdvisories, recommendTier } from './advisories.js';
80
+ export type { AdvisoryOptions } from './advisories.js';
81
+ export { analyzeCachePrefix } from './cache.js';
82
+
83
+ // Rearranging a prompt so its stable instructions sit in the cacheable prefix.
84
+ // The largest saving Trazum knows about, and the most dangerous transformation
85
+ // here — see reorder.ts for what it refuses to move and why.
86
+ export { reorderForCache } from './reorder.js';
87
+ export type {
88
+ DeclinedBlock,
89
+ ReorderOptions,
90
+ ReorderResult,
91
+ ReorderedBlock,
92
+ } from './reorder.js';
93
+ export type { CachePrefixAnalysis } from './cache.js';
94
+
95
+ // The caching loss that only exists between prompts: a preamble shared by forty
96
+ // files and byte-identical in none of them. Reports no dollar figure on purpose
97
+ // — see shared-prefix.ts for why the cost model cannot price it.
98
+ export { cacheableMinimum, sharedPrefixes } from './shared-prefix.js';
99
+ export type {
100
+ PrefixCandidate,
101
+ SharedPrefix,
102
+ SharedPrefixOptions,
103
+ } from './shared-prefix.js';
104
+
105
+ // Prompts embedded in source files, found by an explicit marker rather than
106
+ // guessed at — see extract.ts for why a gate cannot afford a heuristic here.
107
+ export { extractPrompts, promptId, hasMarker, SOURCE_EXTENSIONS } from './extract.js';
108
+ export type { ExtractedPrompt, DeclinedPrompt, ExtractionResult } from './extract.js';
109
+
110
+ // Which provider a prompt is actually sent to, read from the code rather than
111
+ // assumed — see detect.ts for why it declines when a file points two ways.
112
+ export { detectFromSource } from './detect.js';
113
+ export type { Detection, Evidence, EvidenceKind, DetectOptions } from './detect.js';
114
+ export { optimize, withExactTokenCounts, DEFAULT_USAGE } from './optimize.js';
115
+ export {
116
+ refineWithLlm,
117
+ openAiCompatible,
118
+ anthropicProvider,
119
+ bedrockProvider,
120
+ geminiProvider,
121
+ vertexProvider,
122
+ customProvider,
123
+ providerFromEnv,
124
+ REFINER_SYSTEM_PROMPT,
125
+ } from './llm.js';
126
+ export type {
127
+ RefineOptions,
128
+ OpenAiCompatibleOptions,
129
+ AnthropicProviderOptions,
130
+ BedrockProviderOptions,
131
+ GeminiProviderOptions,
132
+ VertexProviderOptions,
133
+ CustomProviderOptions,
134
+ } from './llm.js';
135
+
136
+ // Internationalisation
137
+ export {
138
+ DEFAULT_LOCALE,
139
+ LOCALES,
140
+ getMessages,
141
+ isLocale,
142
+ matchLocale,
143
+ resolveLocale,
144
+ en,
145
+ es,
146
+ } from './i18n/index.js';
147
+ export type { CoreMessages, Locale, LocalizedMessage, RuleCopy, RuleId } from './i18n/index.js';
148
+
149
+ // Structural analysis
150
+ export {
151
+ analyzeExamples,
152
+ findContradictions,
153
+ findExamples,
154
+ findMovableSchema,
155
+ findRestatedFormat,
156
+ } from './structure.js';
157
+ export type {
158
+ Contradiction,
159
+ ContradictionAxis,
160
+ ContradictionSide,
161
+ ExampleAnalysis,
162
+ ExampleBlock,
163
+ MovableSchema,
164
+ RedundantExample,
165
+ RestatedFormat,
166
+ } from './structure.js';
167
+ export { jaccard, normalizeForCompare } from './similarity.js';
168
+ export { OUTPUT_CUES, OUTPUT_CUES_BY_LANGUAGE } from './phrases.js';
169
+
170
+ // Endpoint validation for the pluggable LLM layer
171
+ export {
172
+ SAFE_FETCH_INIT,
173
+ allowedEndpoints,
174
+ checkedEndpoint,
175
+ isPrivateHost,
176
+ resolveEndpoint,
177
+ validateLlmEndpoint,
178
+ } from './net.js';
179
+ export type { EndpointRejection, ValidateEndpointOptions } from './net.js';
180
+
181
+ // Per-rule change extraction
182
+ export { extractChanges, DEFAULT_CHANGE_LIMIT } from './changes.js';
183
+ export type { RuleChange } from './changes.js';
184
+
185
+ // Semantic review of few-shot examples (optional, costs an LLM call)
186
+ export { reviewExamples, EXAMPLE_REVIEW_SYSTEM_PROMPT } from './review.js';
187
+ export type { ExampleReview, ExampleRedundancy, ReviewExamplesOptions } from './review.js';
188
+
189
+ // Which few-shot examples earn their tokens, measured by leave-one-out. Optional,
190
+ // and the most expensive thing here: see prune.ts for the call arithmetic and for
191
+ // what the measurement cannot tell you.
192
+ export { NothingToPrune, plannedCalls, pruneExamples, withoutExample } from './prune.js';
193
+ export type { ExampleContribution, PruneOptions, PruneReport } from './prune.js';
194
+
195
+ // Golden-set evaluation (optional, costs three LLM calls per case)
196
+ export { evaluate, fillPrompt, verdictFor } from './evaluate.js';
197
+ export type { EvalCase, EvalReport, EvalVerdict, EvaluateOptions } from './evaluate.js';
198
+
199
+ // Comparing two prompt versions
200
+ export { comparePrompts } from './compare.js';
201
+ export type {
202
+ PromptComparison,
203
+ CompareOptions,
204
+ RuleDelta,
205
+ AdvisoryDelta,
206
+ } from './compare.js';
207
+
208
+ // Glob matching for config budget patterns. Pure, so it belongs here; the
209
+ // config loader and directory walk that use it read the filesystem and live in
210
+ // "@trazum/core/node" instead — see node.ts for why that split is structural.
211
+ export { matchGlob, mostSpecificMatch, specificity } from './glob.js';
212
+ export { editDistance, nearestName } from './nearest.js';
213
+
214
+ // The config *schema*, without the loader: validation is a pure function of a
215
+ // string, so it belongs on the browser-safe entry point. `loadConfig`, which
216
+ // actually opens the file, is only in "@trazum/core/node".
217
+ export {
218
+ CONFIG_FILENAME,
219
+ CONFIG_KEYS,
220
+ CONFIG_USAGE_KEYS,
221
+ ConfigError,
222
+ DEFAULT_EXTENSIONS,
223
+ MAX_CONFIG_BYTES,
224
+ MAX_CONFIG_SEARCH_DEPTH,
225
+ budgetFor,
226
+ parseConfig,
227
+ } from './config-schema.js';
228
+ export type { ResolvedBudget, TrazumConfig } from './config-schema.js';