jevprune 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,462 @@
1
+ import { EntryType, Fetch } from '@typesafe-ai/sdk';
2
+
3
+ declare class JevCoreError extends Error {
4
+ readonly name: string;
5
+ constructor(message: string, options?: {
6
+ cause?: unknown;
7
+ });
8
+ }
9
+ declare class JevConfigError extends JevCoreError {
10
+ readonly name = "JevConfigError";
11
+ }
12
+ declare class JevInputError extends JevCoreError {
13
+ readonly name = "JevInputError";
14
+ }
15
+ declare class JevBudgetError extends JevCoreError {
16
+ readonly name = "JevBudgetError";
17
+ }
18
+ declare class JevRequestError extends JevCoreError {
19
+ readonly name = "JevRequestError";
20
+ readonly status: number | undefined;
21
+ readonly retryable: boolean;
22
+ readonly requestId: string | undefined;
23
+ constructor(message: string, details: {
24
+ status?: number;
25
+ retryable: boolean;
26
+ requestId?: string;
27
+ cause?: unknown;
28
+ });
29
+ }
30
+ declare class JevTimeoutError extends JevCoreError {
31
+ readonly name = "JevTimeoutError";
32
+ readonly timeoutMs: number;
33
+ constructor(timeoutMs: number, message?: string, options?: {
34
+ cause?: unknown;
35
+ });
36
+ }
37
+ declare class JevAbortError extends JevCoreError {
38
+ readonly name = "JevAbortError";
39
+ constructor(message?: string, options?: {
40
+ cause?: unknown;
41
+ });
42
+ }
43
+ declare class JevResponseError extends JevCoreError {
44
+ readonly name = "JevResponseError";
45
+ }
46
+ declare function describeError(error: unknown): string;
47
+
48
+ type JevState = EntryType;
49
+ interface JevUsage {
50
+ readonly inputTokens: number;
51
+ readonly outputTokens: number;
52
+ }
53
+ interface NoulRequest {
54
+ readonly state: JevState;
55
+ readonly questions: Readonly<Record<string, string>>;
56
+ }
57
+ interface NoulResult {
58
+ readonly model: string;
59
+ readonly answers: Readonly<Record<string, number>>;
60
+ readonly usage: JevUsage;
61
+ }
62
+ interface ChoiceQuestionSpec<L extends string> {
63
+ readonly instructions: string;
64
+ readonly labels: readonly L[];
65
+ readonly descriptions?: Readonly<Partial<Record<L, string>>>;
66
+ }
67
+ interface ChoiceRequest<L extends string> {
68
+ readonly state: JevState;
69
+ readonly questions: Readonly<Record<string, ChoiceQuestionSpec<L>>>;
70
+ }
71
+ interface ChoiceAnswer<L extends string> {
72
+ readonly choice: L;
73
+ readonly confidence: number;
74
+ readonly probabilities: Readonly<Record<L, number>>;
75
+ }
76
+ interface ChoiceResult<L extends string> {
77
+ readonly model: string;
78
+ readonly answers: Readonly<Record<string, ChoiceAnswer<L>>>;
79
+ readonly usage: JevUsage;
80
+ }
81
+ interface JevRequestOptions {
82
+ readonly signal?: AbortSignal;
83
+ readonly timeoutMs?: number;
84
+ }
85
+ interface JevClient {
86
+ noul(request: NoulRequest, options?: JevRequestOptions): Promise<NoulResult>;
87
+ choice<L extends string>(request: ChoiceRequest<L>, options?: JevRequestOptions): Promise<ChoiceResult<L>>;
88
+ }
89
+ interface TypeSafeJevClientConfig {
90
+ readonly apiKey: string;
91
+ readonly baseUrl?: string;
92
+ readonly model?: string;
93
+ readonly timeoutMs?: number;
94
+ readonly maxRetries?: number;
95
+ readonly fetch?: Fetch;
96
+ }
97
+ declare const DEFAULT_JEV_MODEL = "jev-latest";
98
+ declare const DEFAULT_JEV_TIMEOUT_MS = 10000;
99
+ declare const DEFAULT_JEV_MAX_RETRIES = 1;
100
+ declare const TYPESAFE_API_KEY_ENV = "TYPESAFE_API_KEY";
101
+ declare const TYPESAFE_BASE_URL_ENV = "TYPESAFE_BASE_URL";
102
+ declare class TypeSafeJevClient implements JevClient {
103
+ #private;
104
+ constructor(config: TypeSafeJevClientConfig);
105
+ noul(request: NoulRequest, options?: JevRequestOptions): Promise<NoulResult>;
106
+ choice<L extends string>(request: ChoiceRequest<L>, options?: JevRequestOptions): Promise<ChoiceResult<L>>;
107
+ }
108
+ declare function createJevClientFromEnv(env?: Readonly<Record<string, string | undefined>>, overrides?: Partial<Omit<TypeSafeJevClientConfig, "apiKey">>): TypeSafeJevClient;
109
+ declare function toJevError(error: unknown): Error;
110
+ declare function validateNoulAnswers(ids: readonly string[], answers: unknown): Record<string, number>;
111
+ declare function validateChoiceAnswers<L extends string>(questions: Readonly<Record<string, ChoiceQuestionSpec<L>>>, answers: unknown): Record<string, ChoiceAnswer<L>>;
112
+
113
+ declare const CHARS_PER_TOKEN = 3;
114
+ declare const DEFAULT_WINDOW_TOKENS = 25000;
115
+ declare const MAX_REQUEST_TOKENS = 32000;
116
+ declare function estimateTokens(text: string): number;
117
+ declare function estimateJsonTokens(value: unknown): number;
118
+
119
+ interface WindowItem {
120
+ readonly id: string;
121
+ readonly text: string;
122
+ }
123
+ interface PlanWindowsOptions<T extends WindowItem> {
124
+ readonly budgetTokens?: number;
125
+ readonly overheadTokens?: number;
126
+ readonly itemOverheadTokens?: number;
127
+ readonly costTokens?: (item: T) => number;
128
+ }
129
+ interface WindowPlan<T extends WindowItem> {
130
+ readonly windows: readonly (readonly T[])[];
131
+ readonly oversize: readonly T[];
132
+ }
133
+ declare function planWindows<T extends WindowItem>(items: readonly T[], options?: PlanWindowsOptions<T>): WindowPlan<T>;
134
+ declare const DEFAULT_WINDOW_CONCURRENCY = 4;
135
+ declare const DEFAULT_WINDOW_TIMEOUT_MS = 10000;
136
+ interface RunWindowsOptions {
137
+ readonly concurrency?: number;
138
+ readonly timeoutMs?: number;
139
+ readonly signal?: AbortSignal;
140
+ }
141
+ type WindowJudge<T, R> = (window: readonly T[], index: number, options: JevRequestOptions) => Promise<R>;
142
+ declare function runWindows<T, R>(windows: readonly (readonly T[])[], judge: WindowJudge<T, R>, options?: RunWindowsOptions): Promise<R[]>;
143
+
144
+ type NoulScorer = (id: string, instructions: string, state: JevState) => number;
145
+ type ChoiceScorer = (id: string, spec: ChoiceQuestionSpec<string>, state: JevState) => string | ChoiceAnswer<string>;
146
+ interface FakeJevCall {
147
+ readonly kind: "noul" | "choice";
148
+ readonly state: JevState;
149
+ readonly ids: readonly string[];
150
+ }
151
+ interface FakeJevOptions {
152
+ readonly noul?: NoulScorer;
153
+ readonly choice?: ChoiceScorer;
154
+ readonly delayMs?: number;
155
+ readonly failWith?: (call: number) => Error | undefined;
156
+ readonly model?: string;
157
+ }
158
+ declare class FakeJevClient implements JevClient {
159
+ #private;
160
+ readonly calls: FakeJevCall[];
161
+ constructor(options?: FakeJevOptions);
162
+ noul(request: NoulRequest, options?: JevRequestOptions): Promise<NoulResult>;
163
+ choice<L extends string>(request: ChoiceRequest<L>, options?: JevRequestOptions): Promise<ChoiceResult<L>>;
164
+ }
165
+
166
+ declare function isValidUtf8(bytes: Buffer): boolean;
167
+ declare function byteLineStarts(bytes: Buffer): number[];
168
+ declare function countByteLines(bytes: Buffer): number;
169
+
170
+ interface RetentionConfig {
171
+ readonly maxRuns: number;
172
+ readonly maxBytes: number;
173
+ }
174
+ interface Config {
175
+ readonly threshold: number;
176
+ readonly fastPathLines: number;
177
+ readonly tailLines: number;
178
+ readonly headLines: number;
179
+ readonly contextLines: number;
180
+ readonly minCollapseLines: number;
181
+ readonly windowTokens: number;
182
+ readonly windowTimeoutMs: number;
183
+ readonly concurrency: number;
184
+ readonly maxPruneBytes: number;
185
+ readonly retention: RetentionConfig;
186
+ readonly autoWrap: boolean;
187
+ readonly allowlist: readonly string[];
188
+ }
189
+ interface ResolvedConfig extends Config {
190
+ readonly home: string;
191
+ }
192
+ declare const DEFAULT_ALLOWLIST: readonly string[];
193
+ declare const DEFAULT_CONFIG: Config;
194
+ declare function resolveHome(env?: NodeJS.ProcessEnv): string;
195
+ declare function loadConfig(env?: NodeJS.ProcessEnv): Promise<ResolvedConfig>;
196
+ declare function parseThreshold(value: string): number;
197
+
198
+ declare class JevpruneError extends Error {
199
+ readonly name: string;
200
+ constructor(message: string, options?: {
201
+ cause?: unknown;
202
+ });
203
+ }
204
+ declare class ConfigError extends JevpruneError {
205
+ readonly name = "ConfigError";
206
+ }
207
+ declare class UsageError extends JevpruneError {
208
+ readonly name = "UsageError";
209
+ }
210
+ declare class RunStoreError extends JevpruneError {
211
+ readonly name = "RunStoreError";
212
+ readonly code: string | undefined;
213
+ constructor(message: string, details?: {
214
+ code?: string;
215
+ cause?: unknown;
216
+ });
217
+ }
218
+ declare class SpawnError extends JevpruneError {
219
+ readonly name = "SpawnError";
220
+ readonly executable: string;
221
+ readonly code: string | undefined;
222
+ constructor(message: string, details: {
223
+ executable: string;
224
+ code?: string;
225
+ cause?: unknown;
226
+ });
227
+ }
228
+ declare class TranscriptError extends JevpruneError {
229
+ readonly name = "TranscriptError";
230
+ readonly path: string;
231
+ constructor(message: string, details: {
232
+ path: string;
233
+ cause?: unknown;
234
+ });
235
+ }
236
+ declare class RunNotFoundError extends JevpruneError {
237
+ readonly name = "RunNotFoundError";
238
+ readonly id: string;
239
+ constructor(id: string, options?: {
240
+ cause?: unknown;
241
+ });
242
+ }
243
+ declare class LineRangeError extends JevpruneError {
244
+ readonly name = "LineRangeError";
245
+ }
246
+
247
+ type SelectionMode = "fast-path" | "passthrough" | "jev" | "fallback";
248
+ type DecisionReason = "fast-path" | "passthrough" | "tail" | "signature" | "context" | "blank" | "oversize" | "jev" | "collapse-min" | "head" | "fallback";
249
+ interface Decision {
250
+ keep: boolean;
251
+ reason: DecisionReason;
252
+ noul?: number;
253
+ }
254
+ interface DroppedRange {
255
+ readonly from: number;
256
+ readonly to: number;
257
+ readonly count: number;
258
+ }
259
+
260
+ interface FooterInput {
261
+ readonly mode: SelectionMode;
262
+ readonly linesIn: number;
263
+ readonly linesOut: number;
264
+ readonly exitCode?: number | null;
265
+ readonly logPath?: string;
266
+ readonly fallbackReason?: string;
267
+ readonly passthroughNote?: string;
268
+ readonly storeFailureCode?: string;
269
+ readonly home?: string;
270
+ }
271
+ declare function formatFooter(input: FooterInput): string;
272
+ declare function footerAfter(lastByte: number | undefined, footer: string): string;
273
+ declare function withFooter(kept: string, footer: string): string;
274
+ declare function formatCount(value: number): string;
275
+ declare function displayPath(path: string, home?: string): string;
276
+
277
+ type LineTerminator = "" | "\n" | "\r\n" | "\r";
278
+ interface Line {
279
+ readonly n: number;
280
+ readonly text: string;
281
+ readonly terminator: LineTerminator;
282
+ }
283
+ declare function splitLines(text: string): Line[];
284
+ declare function joinLines(lines: Iterable<Line>): string;
285
+
286
+ type KeepReason = "tail" | "signature" | "context";
287
+ declare const SIGNATURE_CASE_SENSITIVE: RegExp;
288
+ declare const SIGNATURE_CASE_INSENSITIVE: RegExp;
289
+ declare function isSignatureLine(text: string): boolean;
290
+ declare function computeKeeps(lines: readonly Line[], options: {
291
+ tailLines: number;
292
+ contextLines: number;
293
+ }): Map<number, KeepReason>;
294
+
295
+ interface MergeOptions {
296
+ readonly minCollapseLines: number;
297
+ readonly runId: string;
298
+ readonly totalLines?: number;
299
+ }
300
+ interface MergeResult {
301
+ readonly kept: string;
302
+ readonly dropped: DroppedRange[];
303
+ }
304
+ declare function collapseMarker(range: DroppedRange, runId: string): string;
305
+ declare function mergeDecisions(lines: readonly Line[], decisions: Map<number, Decision>, options: MergeOptions): MergeResult;
306
+
307
+ interface OversizeCapture {
308
+ readonly lines: number;
309
+ readonly headSegmentLines: number;
310
+ }
311
+ declare const NOT_UTF8_REASON = "not valid UTF-8";
312
+ declare const NOT_UTF8_NOTE = "output is not valid UTF-8";
313
+ declare const RUBRIC = "A line is needed when a developer acting on the task would want to read it: errors, failures, assertions, stack frames, diagnostics, timings or statuses that bear on the task, and the lines that give them meaning. Progress bars, download counters, repeated banners, unchanged status lines and routine success noise are not needed.";
314
+ interface SelectInput {
315
+ readonly text: string;
316
+ readonly task: string;
317
+ readonly command: string;
318
+ readonly exitCode?: number | null;
319
+ readonly interrupted?: boolean;
320
+ readonly oversize?: OversizeCapture;
321
+ readonly client: JevClient | null;
322
+ readonly config: ResolvedConfig;
323
+ readonly runId: string;
324
+ readonly signal?: AbortSignal;
325
+ }
326
+ interface PassthroughInput {
327
+ readonly bytes: number;
328
+ readonly lines: number;
329
+ readonly reason?: string;
330
+ }
331
+ interface SelectionResult {
332
+ readonly mode: SelectionMode;
333
+ readonly kept: string;
334
+ readonly dropped: DroppedRange[];
335
+ readonly linesIn: number;
336
+ readonly linesOut: number;
337
+ readonly bytesIn: number;
338
+ readonly bytesOut: number;
339
+ readonly windows: number;
340
+ readonly jevRequests: number;
341
+ readonly jevInputTokens: number;
342
+ readonly fallbackReason?: string;
343
+ readonly decisions: Map<number, Decision>;
344
+ }
345
+ declare function passthroughSelection(input: PassthroughInput): SelectionResult;
346
+ declare function questionFor(n: number): string;
347
+ declare function selectLines(input: SelectInput): Promise<SelectionResult>;
348
+
349
+ interface RunMeta {
350
+ readonly id: string;
351
+ readonly command: string;
352
+ readonly argv: readonly string[];
353
+ readonly startedAt: string;
354
+ readonly endedAt: string;
355
+ readonly exitCode: number | null;
356
+ readonly signal: string | null;
357
+ readonly bytes: number;
358
+ readonly lines: number;
359
+ readonly mode: SelectionMode;
360
+ readonly linesOut: number;
361
+ readonly fallbackReason?: string;
362
+ readonly task: string;
363
+ }
364
+ interface GainEntry {
365
+ readonly ts: string;
366
+ readonly id: string;
367
+ readonly mode: SelectionMode;
368
+ readonly linesIn: number;
369
+ readonly linesOut: number;
370
+ readonly bytesIn: number;
371
+ readonly bytesOut: number;
372
+ readonly reason?: string;
373
+ }
374
+ interface GainTotals {
375
+ readonly runs: number;
376
+ readonly linesIn: number;
377
+ readonly linesOut: number;
378
+ readonly bytesIn: number;
379
+ readonly bytesOut: number;
380
+ }
381
+ interface RunRecord {
382
+ readonly id: string;
383
+ readonly path: string;
384
+ readonly text: string;
385
+ readonly meta: RunMeta | null;
386
+ }
387
+ interface RunWriter {
388
+ readonly path: string;
389
+ readonly failure: RunStoreError | undefined;
390
+ write(chunk: Buffer): boolean;
391
+ onDrain(listener: () => void): void;
392
+ close(): Promise<void>;
393
+ }
394
+ declare function newRunId(): string;
395
+ declare class RunStore {
396
+ #private;
397
+ readonly home: string;
398
+ constructor(options: {
399
+ home: string;
400
+ retention?: RetentionConfig;
401
+ });
402
+ get runsDir(): string;
403
+ get gainPath(): string;
404
+ logPath(id: string): string;
405
+ metaPath(id: string): string;
406
+ openRun(run: {
407
+ id: string;
408
+ }): Promise<RunWriter>;
409
+ finalizeRun(id: string, meta: RunMeta): Promise<void>;
410
+ readRunBytes(id: string): Promise<Buffer>;
411
+ readRunChunks(id: string): AsyncGenerator<Buffer>;
412
+ readRun(id: string): Promise<RunRecord>;
413
+ readRunLineBytes(id: string, from?: number, to?: number): Promise<Buffer>;
414
+ readRunLines(id: string, from?: number, to?: number): Promise<string>;
415
+ appendGain(entry: GainEntry): Promise<void>;
416
+ readGain(): Promise<GainTotals>;
417
+ enforceRetention(): Promise<void>;
418
+ discardRun(id: string): Promise<void>;
419
+ }
420
+
421
+ interface PruneInput {
422
+ readonly text: string;
423
+ readonly task: string;
424
+ readonly command?: string;
425
+ readonly exitCode?: number | null;
426
+ readonly client?: JevClient | null;
427
+ readonly config?: Partial<Config>;
428
+ readonly save?: boolean;
429
+ readonly env?: NodeJS.ProcessEnv;
430
+ }
431
+ interface PruneStreamInput extends Omit<PruneInput, "text"> {
432
+ readonly stream: NodeJS.ReadableStream;
433
+ }
434
+ interface PruneResult {
435
+ readonly kept: string;
436
+ readonly dropped: DroppedRange[];
437
+ readonly runId: string;
438
+ readonly mode: SelectionMode;
439
+ readonly linesIn: number;
440
+ readonly linesOut: number;
441
+ readonly fallbackReason?: string;
442
+ readonly logPath?: string;
443
+ readonly footer: string;
444
+ }
445
+ declare function pruneOutput(input: PruneInput): Promise<PruneResult>;
446
+ declare function pruneStream(input: PruneStreamInput): Promise<PruneResult>;
447
+
448
+ declare const MAX_TASK_LENGTH = 400;
449
+ type TaskSource = "flag" | "env" | "transcript" | "command";
450
+ interface TaskInput {
451
+ readonly flag?: string;
452
+ readonly env?: NodeJS.ProcessEnv;
453
+ readonly transcriptPath?: string;
454
+ readonly command: string;
455
+ }
456
+ interface ResolvedTask {
457
+ readonly task: string;
458
+ readonly source: TaskSource;
459
+ }
460
+ declare function resolveTask(input: TaskInput): Promise<ResolvedTask>;
461
+
462
+ export { CHARS_PER_TOKEN, type ChoiceAnswer, type ChoiceQuestionSpec, type ChoiceRequest, type ChoiceResult, type ChoiceScorer, type Config, ConfigError, DEFAULT_ALLOWLIST, DEFAULT_CONFIG, DEFAULT_JEV_MAX_RETRIES, DEFAULT_JEV_MODEL, DEFAULT_JEV_TIMEOUT_MS, DEFAULT_WINDOW_CONCURRENCY, DEFAULT_WINDOW_TIMEOUT_MS, DEFAULT_WINDOW_TOKENS, type Decision, type DecisionReason, type DroppedRange, type FakeJevCall, FakeJevClient, type FakeJevOptions, type FooterInput, type GainEntry, type GainTotals, JevAbortError, JevBudgetError, type JevClient, JevConfigError, JevCoreError, JevInputError, JevRequestError, type JevRequestOptions, JevResponseError, type JevState, JevTimeoutError, type JevUsage, JevpruneError, type KeepReason, type Line, LineRangeError, type LineTerminator, MAX_REQUEST_TOKENS, MAX_TASK_LENGTH, type MergeOptions, type MergeResult, NOT_UTF8_NOTE, NOT_UTF8_REASON, type NoulRequest, type NoulResult, type NoulScorer, type OversizeCapture, type PassthroughInput, type PlanWindowsOptions, type PruneInput, type PruneResult, type PruneStreamInput, RUBRIC, type ResolvedConfig, type ResolvedTask, type RetentionConfig, type RunMeta, RunNotFoundError, type RunRecord, RunStore, RunStoreError, type RunWindowsOptions, type RunWriter, SIGNATURE_CASE_INSENSITIVE, SIGNATURE_CASE_SENSITIVE, type SelectInput, type SelectionMode, type SelectionResult, SpawnError, TYPESAFE_API_KEY_ENV, TYPESAFE_BASE_URL_ENV, type TaskInput, type TaskSource, TranscriptError, TypeSafeJevClient, type TypeSafeJevClientConfig, UsageError, type WindowItem, type WindowJudge, type WindowPlan, byteLineStarts, collapseMarker, computeKeeps, countByteLines, createJevClientFromEnv, describeError, displayPath, estimateJsonTokens, estimateTokens, footerAfter, formatCount, formatFooter, isSignatureLine, isValidUtf8, joinLines, loadConfig, mergeDecisions, newRunId, parseThreshold, passthroughSelection, planWindows, pruneOutput, pruneStream, questionFor, resolveHome, resolveTask, runWindows, selectLines, splitLines, toJevError, validateChoiceAnswers, validateNoulAnswers, withFooter };