@vincemakes/kiso-core 0.41.2 → 0.42.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.
@@ -38,7 +38,7 @@ import { ToolRegistry } from "../tools/registry.js";
38
38
  import { validateArgs } from "../tools/validate.js";
39
39
  import { NoOpHooks } from "./hooks.js";
40
40
  import { denialResult } from "./permission.js";
41
- import { messagesToEvents, MICROCOMPACTABLE, DO_NOT_COMPACT, projectMessages } from "./project.js";
41
+ import { messagesToEvents, MICROCOMPACTABLE, DO_NOT_COMPACT, END_TURN, projectMessages } from "./project.js";
42
42
  /**
43
43
  * R3e (owner ruling, 2026-08-28) — there is NO default turn limit.
44
44
  *
@@ -481,6 +481,19 @@ export async function* loop(config) {
481
481
  yield await terminal({ kind: "aborted", by: "user" });
482
482
  return;
483
483
  }
484
+ // 0.42.0: a settled result tagged END_TURN in the OPEN turn — after
485
+ // the most recent stop, user_input or terminal — completes the run
486
+ // instead of asking again. Read from the log at the HEAD of every
487
+ // turn, before compaction and the request, so a cold resume
488
+ // (CONTINUE_MODEL re-enters here) decides exactly as the fresh path
489
+ // did before the crash: zero requests.
490
+ for (let i = log.all.length - 1; i >= 0 && log.all[i].type !== "stop" && log.all[i].type !== "user_input" && log.all[i].type !== "terminal"; i -= 1) {
491
+ const e = log.all[i];
492
+ if (e.type === "tool_result" && (e.tags ?? []).includes(END_TURN)) {
493
+ yield await terminal({ kind: "completed" });
494
+ return;
495
+ }
496
+ }
484
497
  if (turns >= maxTurns) {
485
498
  yield await terminal({ kind: "max_turns", turns });
486
499
  return;
@@ -1249,7 +1262,7 @@ async function runLedgered(call, registry, hooks, ctx, signal, push) {
1249
1262
  // a cancel.
1250
1263
  result = signal?.aborted
1251
1264
  ? { content: "aborted before execution", isError: true, errorKind: "precondition" }
1252
- : await tool.execute(call.input, ctx);
1265
+ : await tool.execute(call.input, { ...ctx, callId: call.callId, executionId });
1253
1266
  }
1254
1267
  catch (err) {
1255
1268
  result = {
@@ -36,6 +36,11 @@ import type { AssistantBlock, Message, MessageSource } from "../protocol/message
36
36
  export declare const MICROCOMPACTABLE: Set<string>;
37
37
  /** The tag that makes a tool result un-clearable (C area). */
38
38
  export declare const DO_NOT_COMPACT = "do-not-compact";
39
+ /** 0.42.0 — a tool result carrying this tag ENDS THE TURN: once its batch
40
+ * has settled the loop writes `terminal { kind: "completed" }` instead of
41
+ * asking the model again; the next user input continues. It rides the
42
+ * durable tool_result event, so a resumed run honours it (docs/extensions.md). */
43
+ export declare const END_TURN = "end-turn";
39
44
  /** E6 (e) — the summary renders as a USER message with this framing (the
40
45
  * boundary honesty): the model reads the compressed history as context,
41
46
  * not as a reply it produced. The text rides verbatim after the frame —
@@ -33,6 +33,11 @@
33
33
  export const MICROCOMPACTABLE = new Set(["read_file", "list_dir", "search_text", "shell"]);
34
34
  /** The tag that makes a tool result un-clearable (C area). */
35
35
  export const DO_NOT_COMPACT = "do-not-compact";
36
+ /** 0.42.0 — a tool result carrying this tag ENDS THE TURN: once its batch
37
+ * has settled the loop writes `terminal { kind: "completed" }` instead of
38
+ * asking the model again; the next user input continues. It rides the
39
+ * durable tool_result event, so a resumed run honours it (docs/extensions.md). */
40
+ export const END_TURN = "end-turn";
36
41
  /** E6 (e) — the summary renders as a USER message with this framing (the
37
42
  * boundary honesty): the model reads the compressed history as context,
38
43
  * not as a reply it produced. The text rides verbatim after the frame —
@@ -86,9 +86,18 @@ export interface KisoExtension {
86
86
  * deny > allow > ask and the veto short-circuit). The session's own
87
87
  * systemPrompt comes first, then each extension's append in load order,
88
88
  * \n\n-joined.
89
+ *
90
+ * 0.42.0: the append may be a FUNCTION, evaluated exactly once per
91
+ * provider attempt — as each model request is built (a retry is a new
92
+ * attempt; an in-band summary reads the last attempt's text), never
93
+ * during a tool — the seam for text that changes as the run goes (a
94
+ * plan, a stage a tool just opened, a model-specific note). The
95
+ * session's own systemPrompt stays byte-stable for its lifetime (it is
96
+ * what the profile digest hashes); what varies lives here. A function
97
+ * that throws fails the run — it is the product's code.
89
98
  */
90
99
  readonly systemPrompt?: {
91
- readonly append: string;
100
+ readonly append: string | (() => string);
92
101
  };
93
102
  /**
94
103
  * An optional readiness datum: true while the extension's tool table is
@@ -32,6 +32,12 @@ export interface ToolContext {
32
32
  readonly sessionId?: string;
33
33
  /** Free-form per-call metadata the kernel passes through untouched. */
34
34
  readonly meta?: Readonly<Record<string, unknown>>;
35
+ /** 0.42.0: this invocation's ids — the model's call id (the tool_result
36
+ * event's `callId`) and the durable execution id (the
37
+ * tool_execution_* events'), so a host can pair what it shows while a
38
+ * tool runs with the exact call, even among same-named parallel calls. */
39
+ readonly callId?: string;
40
+ readonly executionId?: string;
35
41
  }
36
42
  /**
37
43
  * round 5(P1-9): a DISCRIMINATED union — `errorKind` is structurally
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-core",
3
- "version": "0.41.2",
3
+ "version": "0.42.0",
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.41.2",
36
+ "@vincemakes/kiso-evals": "0.42.0",
37
37
  "@types/node": "^26.1.2",
38
38
  "typescript": "^5.7.2",
39
39
  "vitest": "^3.0.0"