@trazum/core 1.80.0 → 1.81.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.
- package/dist/claude-code.d.ts +28 -0
- package/dist/claude-code.d.ts.map +1 -1
- package/dist/claude-code.js +25 -1
- package/dist/claude-code.js.map +1 -1
- package/dist/i18n/en.js +17 -17
- package/dist/i18n/en.js.map +1 -1
- package/package.json +1 -1
- package/src/claude-code.ts +53 -1
- package/src/i18n/en.ts +17 -17
package/dist/claude-code.d.ts
CHANGED
|
@@ -82,6 +82,34 @@ export interface ClaudeCodeConversion {
|
|
|
82
82
|
* are excluded by name and counted here, and the caller says how many.
|
|
83
83
|
*/
|
|
84
84
|
synthetic: number;
|
|
85
|
+
/**
|
|
86
|
+
* Where a later run may safely pick this transcript up again.
|
|
87
|
+
*
|
|
88
|
+
* A transcript is append-only, so re-reading two hundred megabytes to learn
|
|
89
|
+
* what the last thirty seconds added is waste, and on the largest real
|
|
90
|
+
* session on one machine it is six and a half seconds of waste. The obstacle
|
|
91
|
+
* to resuming is this converter's own rule: **one call arrives as several
|
|
92
|
+
* lines and the last one stands**, so a call whose lines straddle the point
|
|
93
|
+
* where a run stopped would be recorded from its later half only.
|
|
94
|
+
*
|
|
95
|
+
* So the resume point is not the end of what was read. It is the first line
|
|
96
|
+
* of the last call seen, which is the only call that can still gain lines.
|
|
97
|
+
* `records` says how many of `records` above are settled and will never be
|
|
98
|
+
* revised; everything from `line` onwards is re-derived next time, and the
|
|
99
|
+
* caller drops the unsettled tail before appending.
|
|
100
|
+
*
|
|
101
|
+
* Measured on 208 real transcripts, 36,468 lines carrying a `requestId`: a
|
|
102
|
+
* call's lines are contiguous, and no `requestId` ever reappeared after
|
|
103
|
+
* another had begun. The design does not lean on that. It re-derives the
|
|
104
|
+
* final call whether or not it needed re-deriving, because a measurement on
|
|
105
|
+
* one machine is evidence and not a guarantee.
|
|
106
|
+
*/
|
|
107
|
+
resume: {
|
|
108
|
+
/** Line index to start from next time, counting every line of the text read. */
|
|
109
|
+
line: number;
|
|
110
|
+
/** How many leading entries of `records` are settled. */
|
|
111
|
+
records: number;
|
|
112
|
+
};
|
|
85
113
|
}
|
|
86
114
|
/** Convert one transcript's text. Pure, like every measuring function here. */
|
|
87
115
|
export declare function claudeCodeRecords(text: string, options?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../src/claude-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;QACrC,cAAc,CAAC,EAAE;YAAE,yBAAyB,CAAC,EAAE,MAAM,CAAC;YAAC,yBAAyB,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7F,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../src/claude-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;OAQG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;QACjC,2BAA2B,CAAC,EAAE,MAAM,CAAC;QACrC,cAAc,CAAC,EAAE;YAAE,yBAAyB,CAAC,EAAE,MAAM,CAAC;YAAC,yBAAyB,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7F,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,UAAU,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,WAAW,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,MAAM,EAAE;QACN,gFAAgF;QAChF,IAAI,EAAE,MAAM,CAAC;QACb,yDAAyD;QACzD,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAaD,+EAA+E;AAC/E,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,oBAAoB,CAgJtB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,OAAO,CAkBhF"}
|
package/dist/claude-code.js
CHANGED
|
@@ -40,12 +40,15 @@ export function claudeCodeRecords(text, options = {}) {
|
|
|
40
40
|
streamed: 0,
|
|
41
41
|
disagreements: 0,
|
|
42
42
|
synthetic: 0,
|
|
43
|
+
resume: { line: 0, records: 0 },
|
|
43
44
|
};
|
|
44
45
|
/** requestId → index into out.records, so a later line can replace the usage. */
|
|
45
46
|
const byRequest = new Map();
|
|
46
47
|
/** requestId → the usage currently standing, to classify a change when one arrives. */
|
|
47
48
|
const seenUsage = new Map();
|
|
48
|
-
|
|
49
|
+
const lines = text.split('\n');
|
|
50
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
51
|
+
const line = lines[index];
|
|
49
52
|
if (line.trim() === '')
|
|
50
53
|
continue;
|
|
51
54
|
let raw;
|
|
@@ -116,14 +119,20 @@ export function claudeCodeRecords(text, options = {}) {
|
|
|
116
119
|
};
|
|
117
120
|
const requestId = typeof entry.requestId === 'string' ? entry.requestId : null;
|
|
118
121
|
if (requestId === null) {
|
|
122
|
+
// Nothing keys this line, so nothing can ever revise it: it is settled
|
|
123
|
+
// the moment it is read, and the resume point moves past it.
|
|
119
124
|
out.noRequestId += 1;
|
|
120
125
|
out.records.push(record);
|
|
126
|
+
out.resume = { line: index + 1, records: out.records.length };
|
|
121
127
|
continue;
|
|
122
128
|
}
|
|
123
129
|
const standing = byRequest.get(requestId);
|
|
124
130
|
if (standing === undefined) {
|
|
131
|
+
// A call begins. Everything before it is settled; this call is not,
|
|
132
|
+
// because the next line of the transcript may still revise it.
|
|
125
133
|
byRequest.set(requestId, out.records.length);
|
|
126
134
|
seenUsage.set(requestId, record.usage);
|
|
135
|
+
out.resume = { line: index, records: out.records.length };
|
|
127
136
|
out.records.push(record);
|
|
128
137
|
continue;
|
|
129
138
|
}
|
|
@@ -148,6 +157,21 @@ export function claudeCodeRecords(text, options = {}) {
|
|
|
148
157
|
}
|
|
149
158
|
out.records[standing] = { ...record };
|
|
150
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Nothing carrying usage was found, so everything read is settled and the
|
|
162
|
+
* resume point is the end of it.
|
|
163
|
+
*
|
|
164
|
+
* With one exception, and it is the one that would lose a record rather than
|
|
165
|
+
* merely re-derive one: a transcript being appended to can be read mid-line,
|
|
166
|
+
* and that half-line parses as nothing. Resuming past it would drop the call
|
|
167
|
+
* it becomes. So when the text does not end in a newline, the resume point
|
|
168
|
+
* never passes the start of its final line.
|
|
169
|
+
*/
|
|
170
|
+
if (out.records.length === 0)
|
|
171
|
+
out.resume = { line: lines.length, records: 0 };
|
|
172
|
+
if (text !== '' && !text.endsWith('\n')) {
|
|
173
|
+
out.resume = { ...out.resume, line: Math.min(out.resume.line, lines.length - 1) };
|
|
174
|
+
}
|
|
151
175
|
return out;
|
|
152
176
|
}
|
|
153
177
|
/**
|
package/dist/claude-code.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../src/claude-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../src/claude-code.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n/en.js
CHANGED
|
@@ -60,7 +60,7 @@ export const en = {
|
|
|
60
60
|
suspiciousShrink: (retainedPct) => `The result keeps only ${retainedPct}% of the tokens. That looks like a summary rather than compression: review it by hand before using it.`,
|
|
61
61
|
},
|
|
62
62
|
suggest: {
|
|
63
|
-
'not-found': () => 'the quoted phrase is not in the prompt
|
|
63
|
+
'not-found': () => 'the quoted phrase is not in the prompt: the model paraphrased what it was copying',
|
|
64
64
|
'touches-protected': () => 'it would edit code, a URL, a placeholder or a tag, which are copied verbatim',
|
|
65
65
|
'introduces-protected': () => 'the replacement adds a placeholder or URL that was not there',
|
|
66
66
|
'no-saving': () => 'it is no shorter than what it replaces',
|
|
@@ -71,10 +71,10 @@ export const en = {
|
|
|
71
71
|
* Three shapes, not two, because *"how wrong might this estimate be"* has
|
|
72
72
|
* three answers and only two were written down.
|
|
73
73
|
*
|
|
74
|
-
* The count is exact
|
|
75
|
-
* estimate on the family the estimator was measured against
|
|
74
|
+
* The count is exact, and then the window verdict is a fact. The count is an
|
|
75
|
+
* estimate on the family the estimator was measured against, and then the
|
|
76
76
|
* margin is known and the verdict is a probability. Or the count is an
|
|
77
|
-
* estimate on a family nobody has measured
|
|
77
|
+
* estimate on a family nobody has measured, and then the margin itself is
|
|
78
78
|
* the unknown, which is neither of the first two and used to be told as the
|
|
79
79
|
* second.
|
|
80
80
|
*
|
|
@@ -92,24 +92,24 @@ export const en = {
|
|
|
92
92
|
detail: !uncertain
|
|
93
93
|
? `The optimised prompt is ~${n(tokens)} tokens and ${modelName} accepts ${n(contextWindow)}. The call will fail: split the content or move to a model with a larger window.`
|
|
94
94
|
: bandApplies
|
|
95
|
-
? `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}. That count is an estimate and it is close to the line, so the call will probably fail but might not
|
|
96
|
-
: `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which is over. That count is an estimate, and the estimator's error was measured against Claude's tokenizer
|
|
95
|
+
? `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}. That count is an estimate and it is close to the line, so the call will probably fail but might not. Settle it with --exact-tokens before rewriting anything. The counting endpoint is free. If it does exceed the window, split the content or move to a model with a larger one.`
|
|
96
|
+
: `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which is over. That count is an estimate, and the estimator's error was measured against Claude's tokenizer rather than ${modelName}'s, so how far over it really is cannot be said from here. Trazum will not tell you the call fails on a number it has not measured for this family. Count with your provider's own tooling before rewriting anything.`,
|
|
97
97
|
}),
|
|
98
98
|
contextNearLimit: ({ tokens, modelName, contextWindow, bandApplies }) => ({
|
|
99
99
|
title: 'The prompt may not fit in the context window',
|
|
100
100
|
detail: bandApplies
|
|
101
|
-
? `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which fits
|
|
102
|
-
: `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which fits on the estimate. This warning is raised because the estimator's measured error
|
|
101
|
+
? `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which fits, but that count is an estimate and its error range reaches past the window, so the real prompt may not. A call that exceeds the window fails outright rather than degrading, and nothing else here warns about it. Confirm with --exact-tokens; the counting endpoint is free.`
|
|
102
|
+
: `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which fits on the estimate. This warning is raised because the estimator's measured error, against Claude's tokenizer rather than ${modelName}'s, would reach past the window, and nobody has measured what that error is on this family. A call that exceeds the window fails outright rather than degrading. Count with your provider's own tooling before relying on the margin.`,
|
|
103
103
|
}),
|
|
104
104
|
promptCaching: ({ placeholder, prefixTokens, totalTokens, minTokens, modelName, hitRatePct, readPct, writePct, explicit, nearMinimum, }) => {
|
|
105
105
|
const scope = placeholder
|
|
106
|
-
? `The stable prefix
|
|
106
|
+
? `The stable prefix (everything before the first placeholder ${placeholder}) is ~${n(prefixTokens)} of the prompt's ${n(totalTokens)} tokens, and clears ${modelName}'s ${n(minTokens)}-token cacheable minimum.`
|
|
107
107
|
: `The prompt has no variable placeholders, so the whole thing is a cacheable prefix and it clears ${modelName}'s ${n(minTokens)}-token minimum.`;
|
|
108
108
|
const how = explicit
|
|
109
109
|
? 'Put the cache marker at the end of the stable prefix: any byte that changes before the cut invalidates everything after it.'
|
|
110
|
-
: `${modelName} caches automatically above its minimum, so there is nothing to set
|
|
110
|
+
: `${modelName} caches automatically above its minimum, so there is nothing to set, but the same rule applies: any byte that changes before the cut invalidates everything after it.`;
|
|
111
111
|
const hedge = nearMinimum
|
|
112
|
-
? ` One caveat on the figure: that prefix count is an estimate and it is close to the line, so the real one may be below the ${n(minTokens)}-token minimum
|
|
112
|
+
? ` One caveat on the figure: that prefix count is an estimate and it is close to the line, so the real one may be below the ${n(minTokens)}-token minimum, in which case nothing caches and this saving is not there. Settle it with --exact-tokens before budgeting from it. The counting endpoint is free.`
|
|
113
113
|
: '';
|
|
114
114
|
return {
|
|
115
115
|
title: 'Turn on prompt caching for the stable prefix',
|
|
@@ -131,13 +131,13 @@ export const en = {
|
|
|
131
131
|
? ' Claude Opus 5 lowers that minimum to 512 tokens, so short prompts that miss here would cache there.'
|
|
132
132
|
: '') +
|
|
133
133
|
(couldReachMinimum
|
|
134
|
-
? ' That prefix count is an estimate and it is close to the line, so the real one may already be above it
|
|
134
|
+
? ' That prefix count is an estimate and it is close to the line, so the real one may already be above it. Check with --exact-tokens before deciding this is not available to you. The counting endpoint is free.'
|
|
135
135
|
: ''),
|
|
136
136
|
};
|
|
137
137
|
},
|
|
138
138
|
cachePrefixReorder: ({ staticTokensAfter, sharePct, placeholder, command }) => ({
|
|
139
139
|
title: 'Move the stable instructions ahead of the first placeholder',
|
|
140
|
-
detail: `About ~${n(staticTokensAfter)} tokens of stable content (${sharePct}% of the prompt) sit after the first variable placeholder ${placeholder}, so today they never get cached. Fixed instructions and context first, placeholders last, and that content starts being read from cache at 10% of the price. Run \`${command}\` to attempt it: whole blocks only, and it refuses to move anything that refers back to earlier text. Read the diff
|
|
140
|
+
detail: `About ~${n(staticTokensAfter)} tokens of stable content (${sharePct}% of the prompt) sit after the first variable placeholder ${placeholder}, so today they never get cached. Fixed instructions and context first, placeholders last, and that content starts being read from cache at 10% of the price. Run \`${command}\` to attempt it: whole blocks only, and it refuses to move anything that refers back to earlier text. Read the diff: order carries meaning, and "summarise the text above" is nonsense in front of the text it points at.`,
|
|
141
141
|
}),
|
|
142
142
|
batchApi: () => ({
|
|
143
143
|
title: 'If the work tolerates latency, use the Batch API',
|
|
@@ -158,7 +158,7 @@ export const en = {
|
|
|
158
158
|
contradictoryInstructions: ({ axis, firstValue, firstSnippet, secondValue, secondSnippet, otherCount, }) => ({
|
|
159
159
|
title: `Two instructions disagree about ${axis}`,
|
|
160
160
|
detail: `One says ${firstValue} ("${firstSnippet}") and another says ${secondValue} ("${secondSnippet}"). ` +
|
|
161
|
-
'The model has to pick one, and which one it picks can change between calls
|
|
161
|
+
'The model has to pick one, and which one it picks can change between calls, so this is a correctness problem before it is a cost one. ' +
|
|
162
162
|
'Deleting the instruction you did not mean also shortens the prompt.' +
|
|
163
163
|
(otherCount > 0
|
|
164
164
|
? ` ${otherCount} other ${otherCount === 1 ? 'pair' : 'pairs'} of instructions disagree too.`
|
|
@@ -173,14 +173,14 @@ export const en = {
|
|
|
173
173
|
movableSchema: ({ blocks, tokens, keyList, cue }) => ({
|
|
174
174
|
title: 'The output schema could travel in the request instead of the prompt',
|
|
175
175
|
detail: `${blocks === 1 ? 'A schema block' : `${blocks} schema blocks`} introduced by "${cue}" defines ${keyList}, costing about ${n(tokens)} tokens on every call. ` +
|
|
176
|
-
'Every major API now takes a response schema as a request parameter
|
|
177
|
-
'Trazum cannot make this edit, because it changes the call rather than the prompt, and it does not check whether your provider offers the parameter
|
|
176
|
+
'Every major API now takes a response schema as a request parameter (output_config.format, response_format, responseSchema), and moving it there is the rare change that is both cheaper and stricter: prose asks the model to comply, a parameter makes the decoder comply. ' +
|
|
177
|
+
'Trazum cannot make this edit, because it changes the call rather than the prompt, and it does not check whether your provider offers the parameter; if it does not, this is not available to you.',
|
|
178
178
|
}),
|
|
179
179
|
restatedOutputFormat: ({ restatedCount, totalCount, restatedTokens, keyList }) => ({
|
|
180
180
|
title: 'The output format is specified twice',
|
|
181
181
|
detail: `The prose describes ${restatedCount} of the ${totalCount} fields your schema already defines (${keyList}), costing about ${n(restatedTokens)} tokens on every call. ` +
|
|
182
182
|
'The code block is the version worth keeping: it is unambiguous, and Trazum never edits it. ' +
|
|
183
|
-
'Check the two agree before deleting either
|
|
183
|
+
'Check the two agree before deleting either: when a prompt says one thing in prose and another in its schema, the prose is usually the one that went stale.',
|
|
184
184
|
}),
|
|
185
185
|
},
|
|
186
186
|
contradictionAxes: {
|
package/dist/i18n/en.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;AAEnE,iFAAiF;AACjF,MAAM,CAAC,MAAM,EAAE,GAAiB;IAC9B,MAAM,EAAE,IAAI;IACZ,YAAY,EAAE,OAAO;IAErB,KAAK,EAAE;QACL,kBAAkB,EAAE;YAClB,KAAK,EAAE,qBAAqB;YAC5B,SAAS,EACP,uMAAuM;SAC1M;QACD,uBAAuB,EAAE;YACvB,KAAK,EAAE,2BAA2B;YAClC,SAAS,EACP,gPAAgP;SACnP;QACD,iBAAiB,EAAE;YACjB,KAAK,EAAE,gBAAgB;YACvB,SAAS,EACP,0LAA0L;SAC7L;QACD,iBAAiB,EAAE;YACjB,KAAK,EAAE,gBAAgB;YACvB,SAAS,EACP,mKAAmK;SACtK;QACD,UAAU,EAAE;YACV,KAAK,EAAE,qBAAqB;YAC5B,SAAS,EACP,8JAA8J;SACjK;QACD,MAAM,EAAE;YACN,KAAK,EAAE,4BAA4B;YACnC,SAAS,EACP,+HAA+H;SAClI;QACD,MAAM,EAAE;YACN,KAAK,EAAE,SAAS;YAChB,SAAS,EACP,2HAA2H;SAC9H;QACD,YAAY,EAAE;YACZ,KAAK,EAAE,cAAc;YACrB,SAAS,EACP,kJAAkJ;SACrJ;QACD,YAAY,EAAE;YACZ,KAAK,EAAE,gCAAgC;YACvC,SAAS,EACP,+OAA+O;SAClP;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,kBAAkB;YACzB,SAAS,EACP,uNAAuN;SAC1N;QACD,UAAU,EAAE;YACV,KAAK,EAAE,uBAAuB;YAC9B,SAAS,EACP,sKAAsK;SACzK;QACD,UAAU,EAAE;YACV,KAAK,EAAE,kBAAkB;YACzB,SAAS,EACP,wLAAwL;SAC3L;KACF;IAED,GAAG,EAAE;QACH,aAAa,EAAE,GAAG,EAAE,CAAC,uCAAuC;QAC5D,uBAAuB,EAAE,CAAC,KAAK,EAAE,EAAE,CACjC,qBAAqB,KAAK,oGAAoG;QAChI,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAC5B,8BAA8B,KAAK,OAAO,MAAM,8CAA8C;QAChG,gBAAgB,EAAE,CAAC,WAAW,EAAE,EAAE,CAChC,yBAAyB,WAAW,wGAAwG;KAC/I;IAED,OAAO,EAAE;QACP,WAAW,EAAE,GAAG,EAAE,CAChB,
|
|
1
|
+
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trazum/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.81.0",
|
|
4
4
|
"description": "Trazum core: priced advisories for LLM prompts (caching, model tier, batching, schemas), plus deterministic trimming, token counting and pricing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "David Mu\u00f1oz Rey",
|
package/src/claude-code.ts
CHANGED
|
@@ -81,6 +81,34 @@ export interface ClaudeCodeConversion {
|
|
|
81
81
|
* are excluded by name and counted here, and the caller says how many.
|
|
82
82
|
*/
|
|
83
83
|
synthetic: number;
|
|
84
|
+
/**
|
|
85
|
+
* Where a later run may safely pick this transcript up again.
|
|
86
|
+
*
|
|
87
|
+
* A transcript is append-only, so re-reading two hundred megabytes to learn
|
|
88
|
+
* what the last thirty seconds added is waste, and on the largest real
|
|
89
|
+
* session on one machine it is six and a half seconds of waste. The obstacle
|
|
90
|
+
* to resuming is this converter's own rule: **one call arrives as several
|
|
91
|
+
* lines and the last one stands**, so a call whose lines straddle the point
|
|
92
|
+
* where a run stopped would be recorded from its later half only.
|
|
93
|
+
*
|
|
94
|
+
* So the resume point is not the end of what was read. It is the first line
|
|
95
|
+
* of the last call seen, which is the only call that can still gain lines.
|
|
96
|
+
* `records` says how many of `records` above are settled and will never be
|
|
97
|
+
* revised; everything from `line` onwards is re-derived next time, and the
|
|
98
|
+
* caller drops the unsettled tail before appending.
|
|
99
|
+
*
|
|
100
|
+
* Measured on 208 real transcripts, 36,468 lines carrying a `requestId`: a
|
|
101
|
+
* call's lines are contiguous, and no `requestId` ever reappeared after
|
|
102
|
+
* another had begun. The design does not lean on that. It re-derives the
|
|
103
|
+
* final call whether or not it needed re-deriving, because a measurement on
|
|
104
|
+
* one machine is evidence and not a guarantee.
|
|
105
|
+
*/
|
|
106
|
+
resume: {
|
|
107
|
+
/** Line index to start from next time, counting every line of the text read. */
|
|
108
|
+
line: number;
|
|
109
|
+
/** How many leading entries of `records` are settled. */
|
|
110
|
+
records: number;
|
|
111
|
+
};
|
|
84
112
|
}
|
|
85
113
|
|
|
86
114
|
/** The model id Claude Code writes for a turn no provider ever saw. */
|
|
@@ -109,13 +137,16 @@ export function claudeCodeRecords(
|
|
|
109
137
|
streamed: 0,
|
|
110
138
|
disagreements: 0,
|
|
111
139
|
synthetic: 0,
|
|
140
|
+
resume: { line: 0, records: 0 },
|
|
112
141
|
};
|
|
113
142
|
/** requestId → index into out.records, so a later line can replace the usage. */
|
|
114
143
|
const byRequest = new Map<string, number>();
|
|
115
144
|
/** requestId → the usage currently standing, to classify a change when one arrives. */
|
|
116
145
|
const seenUsage = new Map<string, ClaudeCodeRecord['usage']>();
|
|
117
146
|
|
|
118
|
-
|
|
147
|
+
const lines = text.split('\n');
|
|
148
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
149
|
+
const line = lines[index]!;
|
|
119
150
|
if (line.trim() === '') continue;
|
|
120
151
|
let raw: unknown;
|
|
121
152
|
try {
|
|
@@ -186,14 +217,20 @@ export function claudeCodeRecords(
|
|
|
186
217
|
|
|
187
218
|
const requestId = typeof entry.requestId === 'string' ? entry.requestId : null;
|
|
188
219
|
if (requestId === null) {
|
|
220
|
+
// Nothing keys this line, so nothing can ever revise it: it is settled
|
|
221
|
+
// the moment it is read, and the resume point moves past it.
|
|
189
222
|
out.noRequestId += 1;
|
|
190
223
|
out.records.push(record);
|
|
224
|
+
out.resume = { line: index + 1, records: out.records.length };
|
|
191
225
|
continue;
|
|
192
226
|
}
|
|
193
227
|
const standing = byRequest.get(requestId);
|
|
194
228
|
if (standing === undefined) {
|
|
229
|
+
// A call begins. Everything before it is settled; this call is not,
|
|
230
|
+
// because the next line of the transcript may still revise it.
|
|
195
231
|
byRequest.set(requestId, out.records.length);
|
|
196
232
|
seenUsage.set(requestId, record.usage);
|
|
233
|
+
out.resume = { line: index, records: out.records.length };
|
|
197
234
|
out.records.push(record);
|
|
198
235
|
continue;
|
|
199
236
|
}
|
|
@@ -217,6 +254,21 @@ export function claudeCodeRecords(
|
|
|
217
254
|
}
|
|
218
255
|
out.records[standing] = { ...record };
|
|
219
256
|
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Nothing carrying usage was found, so everything read is settled and the
|
|
260
|
+
* resume point is the end of it.
|
|
261
|
+
*
|
|
262
|
+
* With one exception, and it is the one that would lose a record rather than
|
|
263
|
+
* merely re-derive one: a transcript being appended to can be read mid-line,
|
|
264
|
+
* and that half-line parses as nothing. Resuming past it would drop the call
|
|
265
|
+
* it becomes. So when the text does not end in a newline, the resume point
|
|
266
|
+
* never passes the start of its final line.
|
|
267
|
+
*/
|
|
268
|
+
if (out.records.length === 0) out.resume = { line: lines.length, records: 0 };
|
|
269
|
+
if (text !== '' && !text.endsWith('\n')) {
|
|
270
|
+
out.resume = { ...out.resume, line: Math.min(out.resume.line, lines.length - 1) };
|
|
271
|
+
}
|
|
220
272
|
return out;
|
|
221
273
|
}
|
|
222
274
|
|
package/src/i18n/en.ts
CHANGED
|
@@ -82,7 +82,7 @@ export const en: CoreMessages = {
|
|
|
82
82
|
|
|
83
83
|
suggest: {
|
|
84
84
|
'not-found': () =>
|
|
85
|
-
'the quoted phrase is not in the prompt
|
|
85
|
+
'the quoted phrase is not in the prompt: the model paraphrased what it was copying',
|
|
86
86
|
'touches-protected': () =>
|
|
87
87
|
'it would edit code, a URL, a placeholder or a tag, which are copied verbatim',
|
|
88
88
|
'introduces-protected': () => 'the replacement adds a placeholder or URL that was not there',
|
|
@@ -95,10 +95,10 @@ export const en: CoreMessages = {
|
|
|
95
95
|
* Three shapes, not two, because *"how wrong might this estimate be"* has
|
|
96
96
|
* three answers and only two were written down.
|
|
97
97
|
*
|
|
98
|
-
* The count is exact
|
|
99
|
-
* estimate on the family the estimator was measured against
|
|
98
|
+
* The count is exact, and then the window verdict is a fact. The count is an
|
|
99
|
+
* estimate on the family the estimator was measured against, and then the
|
|
100
100
|
* margin is known and the verdict is a probability. Or the count is an
|
|
101
|
-
* estimate on a family nobody has measured
|
|
101
|
+
* estimate on a family nobody has measured, and then the margin itself is
|
|
102
102
|
* the unknown, which is neither of the first two and used to be told as the
|
|
103
103
|
* second.
|
|
104
104
|
*
|
|
@@ -116,15 +116,15 @@ export const en: CoreMessages = {
|
|
|
116
116
|
detail: !uncertain
|
|
117
117
|
? `The optimised prompt is ~${n(tokens)} tokens and ${modelName} accepts ${n(contextWindow)}. The call will fail: split the content or move to a model with a larger window.`
|
|
118
118
|
: bandApplies
|
|
119
|
-
? `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}. That count is an estimate and it is close to the line, so the call will probably fail but might not
|
|
120
|
-
: `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which is over. That count is an estimate, and the estimator's error was measured against Claude's tokenizer
|
|
119
|
+
? `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}. That count is an estimate and it is close to the line, so the call will probably fail but might not. Settle it with --exact-tokens before rewriting anything. The counting endpoint is free. If it does exceed the window, split the content or move to a model with a larger one.`
|
|
120
|
+
: `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which is over. That count is an estimate, and the estimator's error was measured against Claude's tokenizer rather than ${modelName}'s, so how far over it really is cannot be said from here. Trazum will not tell you the call fails on a number it has not measured for this family. Count with your provider's own tooling before rewriting anything.`,
|
|
121
121
|
}),
|
|
122
122
|
|
|
123
123
|
contextNearLimit: ({ tokens, modelName, contextWindow, bandApplies }) => ({
|
|
124
124
|
title: 'The prompt may not fit in the context window',
|
|
125
125
|
detail: bandApplies
|
|
126
|
-
? `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which fits
|
|
127
|
-
: `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which fits on the estimate. This warning is raised because the estimator's measured error
|
|
126
|
+
? `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which fits, but that count is an estimate and its error range reaches past the window, so the real prompt may not. A call that exceeds the window fails outright rather than degrading, and nothing else here warns about it. Confirm with --exact-tokens; the counting endpoint is free.`
|
|
127
|
+
: `The optimised prompt is ~${n(tokens)} tokens against ${modelName}'s ${n(contextWindow)}, which fits on the estimate. This warning is raised because the estimator's measured error, against Claude's tokenizer rather than ${modelName}'s, would reach past the window, and nobody has measured what that error is on this family. A call that exceeds the window fails outright rather than degrading. Count with your provider's own tooling before relying on the margin.`,
|
|
128
128
|
}),
|
|
129
129
|
|
|
130
130
|
promptCaching: ({
|
|
@@ -140,13 +140,13 @@ export const en: CoreMessages = {
|
|
|
140
140
|
nearMinimum,
|
|
141
141
|
}) => {
|
|
142
142
|
const scope = placeholder
|
|
143
|
-
? `The stable prefix
|
|
143
|
+
? `The stable prefix (everything before the first placeholder ${placeholder}) is ~${n(prefixTokens)} of the prompt's ${n(totalTokens)} tokens, and clears ${modelName}'s ${n(minTokens)}-token cacheable minimum.`
|
|
144
144
|
: `The prompt has no variable placeholders, so the whole thing is a cacheable prefix and it clears ${modelName}'s ${n(minTokens)}-token minimum.`;
|
|
145
145
|
const how = explicit
|
|
146
146
|
? 'Put the cache marker at the end of the stable prefix: any byte that changes before the cut invalidates everything after it.'
|
|
147
|
-
: `${modelName} caches automatically above its minimum, so there is nothing to set
|
|
147
|
+
: `${modelName} caches automatically above its minimum, so there is nothing to set, but the same rule applies: any byte that changes before the cut invalidates everything after it.`;
|
|
148
148
|
const hedge = nearMinimum
|
|
149
|
-
? ` One caveat on the figure: that prefix count is an estimate and it is close to the line, so the real one may be below the ${n(minTokens)}-token minimum
|
|
149
|
+
? ` One caveat on the figure: that prefix count is an estimate and it is close to the line, so the real one may be below the ${n(minTokens)}-token minimum, in which case nothing caches and this saving is not there. Settle it with --exact-tokens before budgeting from it. The counting endpoint is free.`
|
|
150
150
|
: '';
|
|
151
151
|
return {
|
|
152
152
|
title: 'Turn on prompt caching for the stable prefix',
|
|
@@ -180,14 +180,14 @@ export const en: CoreMessages = {
|
|
|
180
180
|
? ' Claude Opus 5 lowers that minimum to 512 tokens, so short prompts that miss here would cache there.'
|
|
181
181
|
: '') +
|
|
182
182
|
(couldReachMinimum
|
|
183
|
-
? ' That prefix count is an estimate and it is close to the line, so the real one may already be above it
|
|
183
|
+
? ' That prefix count is an estimate and it is close to the line, so the real one may already be above it. Check with --exact-tokens before deciding this is not available to you. The counting endpoint is free.'
|
|
184
184
|
: ''),
|
|
185
185
|
};
|
|
186
186
|
},
|
|
187
187
|
|
|
188
188
|
cachePrefixReorder: ({ staticTokensAfter, sharePct, placeholder, command }) => ({
|
|
189
189
|
title: 'Move the stable instructions ahead of the first placeholder',
|
|
190
|
-
detail: `About ~${n(staticTokensAfter)} tokens of stable content (${sharePct}% of the prompt) sit after the first variable placeholder ${placeholder}, so today they never get cached. Fixed instructions and context first, placeholders last, and that content starts being read from cache at 10% of the price. Run \`${command}\` to attempt it: whole blocks only, and it refuses to move anything that refers back to earlier text. Read the diff
|
|
190
|
+
detail: `About ~${n(staticTokensAfter)} tokens of stable content (${sharePct}% of the prompt) sit after the first variable placeholder ${placeholder}, so today they never get cached. Fixed instructions and context first, placeholders last, and that content starts being read from cache at 10% of the price. Run \`${command}\` to attempt it: whole blocks only, and it refuses to move anything that refers back to earlier text. Read the diff: order carries meaning, and "summarise the text above" is nonsense in front of the text it points at.`,
|
|
191
191
|
}),
|
|
192
192
|
|
|
193
193
|
batchApi: () => ({
|
|
@@ -222,7 +222,7 @@ export const en: CoreMessages = {
|
|
|
222
222
|
title: `Two instructions disagree about ${axis}`,
|
|
223
223
|
detail:
|
|
224
224
|
`One says ${firstValue} ("${firstSnippet}") and another says ${secondValue} ("${secondSnippet}"). ` +
|
|
225
|
-
'The model has to pick one, and which one it picks can change between calls
|
|
225
|
+
'The model has to pick one, and which one it picks can change between calls, so this is a correctness problem before it is a cost one. ' +
|
|
226
226
|
'Deleting the instruction you did not mean also shortens the prompt.' +
|
|
227
227
|
(otherCount > 0
|
|
228
228
|
? ` ${otherCount} other ${otherCount === 1 ? 'pair' : 'pairs'} of instructions disagree too.`
|
|
@@ -241,8 +241,8 @@ export const en: CoreMessages = {
|
|
|
241
241
|
title: 'The output schema could travel in the request instead of the prompt',
|
|
242
242
|
detail:
|
|
243
243
|
`${blocks === 1 ? 'A schema block' : `${blocks} schema blocks`} introduced by "${cue}" defines ${keyList}, costing about ${n(tokens)} tokens on every call. ` +
|
|
244
|
-
'Every major API now takes a response schema as a request parameter
|
|
245
|
-
'Trazum cannot make this edit, because it changes the call rather than the prompt, and it does not check whether your provider offers the parameter
|
|
244
|
+
'Every major API now takes a response schema as a request parameter (output_config.format, response_format, responseSchema), and moving it there is the rare change that is both cheaper and stricter: prose asks the model to comply, a parameter makes the decoder comply. ' +
|
|
245
|
+
'Trazum cannot make this edit, because it changes the call rather than the prompt, and it does not check whether your provider offers the parameter; if it does not, this is not available to you.',
|
|
246
246
|
}),
|
|
247
247
|
|
|
248
248
|
restatedOutputFormat: ({ restatedCount, totalCount, restatedTokens, keyList }) => ({
|
|
@@ -250,7 +250,7 @@ export const en: CoreMessages = {
|
|
|
250
250
|
detail:
|
|
251
251
|
`The prose describes ${restatedCount} of the ${totalCount} fields your schema already defines (${keyList}), costing about ${n(restatedTokens)} tokens on every call. ` +
|
|
252
252
|
'The code block is the version worth keeping: it is unambiguous, and Trazum never edits it. ' +
|
|
253
|
-
'Check the two agree before deleting either
|
|
253
|
+
'Check the two agree before deleting either: when a prompt says one thing in prose and another in its schema, the prose is usually the one that went stale.',
|
|
254
254
|
}),
|
|
255
255
|
},
|
|
256
256
|
|