Add fast-jev-compaction extension — Jev System One compaction hook (session_before_compact): prunes stale tool calls/results, keeps user/assistant text verbatim

This commit is contained in:
2026-09-18 12:59:38 +10:00
parent d89e848b8d
commit bf4494c49d
10 changed files with 5438 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
import { buildJevRequest, parseJevResponse } from './request.js';
import type { JevAsker, JevQuestions, JevResponse, JevState } from './types.js';
export interface JevClientOptions {
/** Defaults to `process.env.TYPESAFE_API_KEY`. */
apiKey?: string;
/** Defaults to `jev-latest`. */
model?: string;
/** Defaults to the System One endpoint. */
baseUrl?: string;
/** Defaults to the global `fetch`. */
fetch?: typeof fetch;
}
/** Asks Jev over HTTP with the global `fetch` (or an injected one). */
export class JevClient implements JevAsker {
private readonly apiKey: string;
private readonly model: string | undefined;
private readonly baseUrl: string | undefined;
private readonly fetcher: typeof fetch;
constructor(options: JevClientOptions = {}) {
this.apiKey = options.apiKey ?? process.env.TYPESAFE_API_KEY ?? '';
this.model = options.model;
this.baseUrl = options.baseUrl;
this.fetcher = options.fetch ?? fetch;
}
async ask(state: JevState, questions: JevQuestions): Promise<JevResponse> {
if (!this.apiKey) throw new Error('TYPESAFE_API_KEY is not configured');
const request = buildJevRequest(
{ apiKey: this.apiKey, model: this.model, baseUrl: this.baseUrl },
state,
questions,
);
const response = await this.fetcher(request.url, {
method: request.method,
headers: request.headers,
body: request.body,
});
return parseJevResponse(response.status, response.ok, await response.text());
}
}