@vincemakes/kiso-core 0.40.1 → 0.40.2
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/errors.js +8 -3
- package/dist/kernel/project.js +14 -16
- package/dist/protocol/events.d.ts +11 -10
- package/package.json +2 -2
package/dist/errors.js
CHANGED
|
@@ -28,8 +28,8 @@ export function parseRetryAfter(value, now = Date.now()) {
|
|
|
28
28
|
}
|
|
29
29
|
/** ADR-0055 §3: how the providers word a refused context — openai-compat's
|
|
30
30
|
* "maximum context length" / `context_length_exceeded`, Anthropic's
|
|
31
|
-
* "prompt is too long".
|
|
32
|
-
* the kernel compacts once and retries once. */
|
|
31
|
+
* "prompt is too long". It is an overflow, not a malformed request, at any
|
|
32
|
+
* status (Amendment 2): the kernel compacts once and retries once. */
|
|
33
33
|
const CONTEXT_TOO_LONG = /maximum context length|context_length_exceeded|prompt is too long|context window/i;
|
|
34
34
|
export function mapApiError(status, message, retryAfterMs) {
|
|
35
35
|
const withStatus = (e) => ({
|
|
@@ -37,6 +37,11 @@ export function mapApiError(status, message, retryAfterMs) {
|
|
|
37
37
|
...(status !== undefined ? { status } : {}),
|
|
38
38
|
...(retryAfterMs !== undefined && Number.isFinite(retryAfterMs) && retryAfterMs >= 0 ? { retryAfterMs } : {}),
|
|
39
39
|
});
|
|
40
|
+
// ADR-0055 Amendment 2 (decision 3): the refusal is recognised by what it
|
|
41
|
+
// SAYS, whatever the status — a streamed 400 arrives with none (d4fc), and
|
|
42
|
+
// a 5xx that says so would only re-send what cannot fit.
|
|
43
|
+
if (CONTEXT_TOO_LONG.test(message))
|
|
44
|
+
return withStatus({ code: "context_overflow", retryable: false, message });
|
|
40
45
|
switch (status) {
|
|
41
46
|
case 401:
|
|
42
47
|
case 403:
|
|
@@ -48,7 +53,7 @@ export function mapApiError(status, message, retryAfterMs) {
|
|
|
48
53
|
case 529:
|
|
49
54
|
return withStatus({ code: "overloaded", retryable: true, message });
|
|
50
55
|
case 400:
|
|
51
|
-
return withStatus({ code:
|
|
56
|
+
return withStatus({ code: "invalid_request", retryable: false, message });
|
|
52
57
|
default:
|
|
53
58
|
if (status !== undefined && status >= 500 && status < 600) {
|
|
54
59
|
// D4: every 500-599 is api_5xx and retryable.
|
package/dist/kernel/project.js
CHANGED
|
@@ -143,23 +143,21 @@ export function projectMessages(events) {
|
|
|
143
143
|
if (ev.type === "tool_call_end")
|
|
144
144
|
callMeta.set(ev.callId, { name: ev.name, input: ev.input });
|
|
145
145
|
}
|
|
146
|
-
// ADR-
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
//
|
|
151
|
-
//
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
//
|
|
146
|
+
// ADR-0055 Amendment 2: a checkpoint REPLACES every earlier one. The
|
|
147
|
+
// summarized event with the greatest coversToSeq covers (−1,
|
|
148
|
+
// coversToSeq] of ORDINARY events and is the ONE summary that renders;
|
|
149
|
+
// the superseded ones stay durable and render nothing. (ADR-0044's
|
|
150
|
+
// disjoint ranges kept every earlier summary beside an in-band
|
|
151
|
+
// checkpoint that already restated them — the 0.40.1 stacking.) The
|
|
152
|
+
// boundary is a turn boundary by construction, so a skipped event never
|
|
153
|
+
// splits a message. The summary renders AT ITS BOUNDARY — the first
|
|
154
|
+
// event after the covered range — NOT at the summarized event itself:
|
|
155
|
+
// the event sits at the log's END (the kept rounds live between the
|
|
156
|
+
// boundary and it), and the summary must precede the kept conversation.
|
|
155
157
|
const summaryRanges = [];
|
|
156
|
-
{
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
if (ev.type === "summarized") {
|
|
160
|
-
summaryRanges.push({ from: prev, to: ev.coversToSeq, summary: ev.summary });
|
|
161
|
-
prev = ev.coversToSeq;
|
|
162
|
-
}
|
|
158
|
+
for (const ev of events) {
|
|
159
|
+
if (ev.type === "summarized" && (summaryRanges[0] === undefined || ev.coversToSeq >= summaryRanges[0].to)) {
|
|
160
|
+
summaryRanges[0] = { from: -1, to: ev.coversToSeq, summary: ev.summary };
|
|
163
161
|
}
|
|
164
162
|
}
|
|
165
163
|
// R-E 0.1.43 (Gap B): a model_output_abandoned marker voids the range
|
|
@@ -365,15 +365,16 @@ export interface MicroCompactEvent {
|
|
|
365
365
|
}
|
|
366
366
|
/**
|
|
367
367
|
* ADR-0044 — a model-generated summary replaced the covered conversation
|
|
368
|
-
* range. `coversToSeq` is the seq of the LAST covered event
|
|
369
|
-
*
|
|
370
|
-
* (
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
375
|
-
*
|
|
376
|
-
*
|
|
368
|
+
* range. `coversToSeq` is the seq of the LAST covered event. ADR-0055
|
|
369
|
+
* Amendment 2: a checkpoint REPLACES every earlier one — the covered range
|
|
370
|
+
* is (−1, coversToSeq], ranges nest, and only the summarized event with the
|
|
371
|
+
* greatest coversToSeq renders; superseded ones stay durable and render
|
|
372
|
+
* nothing. The projection replaces the covered events with ONE USER
|
|
373
|
+
* message carrying the summary behind a fixed framing line (E6's boundary
|
|
374
|
+
* honesty: the model reads compressed history as CONTEXT, never as a reply
|
|
375
|
+
* it produced — see SUMMARY_FRAMING in kernel/project.ts). Byte-stable: a
|
|
376
|
+
* summarized event is a persisted fact, so the same events derive the
|
|
377
|
+
* same messages on every replay.
|
|
377
378
|
*
|
|
378
379
|
* The summary is generated OFF-LOOP through the session's own adapter —
|
|
379
380
|
* the summary request itself never enters the log, and a failed summary
|
|
@@ -383,7 +384,7 @@ export interface MicroCompactEvent {
|
|
|
383
384
|
export interface SummarizedEvent {
|
|
384
385
|
readonly seq: number;
|
|
385
386
|
readonly type: "summarized";
|
|
386
|
-
/** The last covered event's seq; the range is (
|
|
387
|
+
/** The last covered event's seq; the range is (−1, coversToSeq] — the latest checkpoint replaces the earlier ones. */
|
|
387
388
|
readonly coversToSeq: number;
|
|
388
389
|
/** The model's compression — replaces the covered range in the projection. */
|
|
389
390
|
readonly summary: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-core",
|
|
3
|
-
"version": "0.40.
|
|
3
|
+
"version": "0.40.2",
|
|
4
4
|
"description": "kiso core \u2014 protocol, event log, loop, hooks, modes, permissions, compaction, delivery truth. The 2,000-line kernel at the bottom of the kiso framework.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"openai"
|
|
34
34
|
],
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@vincemakes/kiso-evals": "0.40.
|
|
36
|
+
"@vincemakes/kiso-evals": "0.40.2",
|
|
37
37
|
"@types/node": "^26.1.2",
|
|
38
38
|
"typescript": "^5.7.2",
|
|
39
39
|
"vitest": "^3.0.0"
|