@vincemakes/kiso-core 0.45.3 → 0.46.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.
@@ -33,7 +33,7 @@
33
33
  * re-stream that duplicates output or tool calls.
34
34
  */
35
35
  import { type Adapter, type AbortSignalLike } from "../protocol/adapter.js";
36
- import type { ContinuationScope, Event, StructuredError, UserInputVia } from "../protocol/events.js";
36
+ import { type ContinuationScope, type Event, type StructuredError, type UserInputVia } from "../protocol/events.js";
37
37
  import type { ApprovalChain } from "../protocol/extension.js";
38
38
  import { EventLog } from "./event-log.js";
39
39
  import type { EventInput } from "./event-log.js";
@@ -33,6 +33,7 @@
33
33
  * re-stream that duplicates output or tool calls.
34
34
  */
35
35
  import { isAdapterEvent } from "../protocol/adapter.js";
36
+ import { isRuntimeInput } from "../protocol/events.js";
36
37
  import { ERROR_CODES } from "../protocol/error-codes.js";
37
38
  import { EventLog } from "./event-log.js";
38
39
  import { ToolRegistry } from "../tools/registry.js";
@@ -161,8 +162,9 @@ export async function* loop(config) {
161
162
  }
162
163
  if (hooks.onUserMessage && messages.length > 0) {
163
164
  const last = messages.at(-1);
164
- if (last?.role === "user") {
165
- const inputEvent = [...log.all].reverse().find((e) => e.type === "user_input");
165
+ const inputEvent = [...log.all].reverse().find((e) => e.type === "user_input");
166
+ // ADR-0058 (3c): a wake run's first input is the runtime's — as at an admission site, no hook
167
+ if (last?.role === "user" && !isRuntimeInput(inputEvent)) {
166
168
  // round 6: the hook runs AT MOST ONCE per input. A replacement that
167
169
  // ALREADY exists (persisted before a crash, or before a resume)
168
170
  // means the hook already spoke for this input — it must never
@@ -151,17 +151,31 @@ export interface UserInputEvent {
151
151
  readonly content: string | readonly import("./messages.js").ContentBlock[];
152
152
  /** Provenance of the prompt (Area 6) — preserved losslessly. */
153
153
  readonly source?: import("./messages.js").MessageSource;
154
- /** 0.40.0 (ADR-0051 §5 rule 1): how a PERSON's turn was composed — a
155
- * skill they invoked, and the line they typed. Display provenance only:
156
- * `content` is what the model receives and the projection never reads
157
- * this, so no byte of it reaches a request. */
154
+ /** How the input entered the trajectory — a PERSON's skill invocation
155
+ * (0.40.0, ADR-0051 Amendment 7), or a runtime delivery of task
156
+ * transitions (ADR-0051 Amendment 8, the delivery's durable receipt).
157
+ * Display and receipt provenance only: `content` is what the model
158
+ * receives and the projection never reads this, so no byte of it
159
+ * reaches a request. */
158
160
  readonly via?: UserInputVia;
159
161
  }
160
- export interface UserInputVia {
162
+ export type UserInputVia = {
161
163
  readonly kind: "skill";
162
164
  readonly name: string;
163
165
  readonly line: string;
166
+ } | {
167
+ readonly kind: "tasks";
168
+ readonly items: readonly TaskDeliveryItem[];
169
+ };
170
+ export interface TaskDeliveryItem {
171
+ readonly taskId: string;
172
+ readonly transition: "ready" | "exited" | "failed" | "stopped" | "unknown";
164
173
  }
174
+ /** An input the runtime owes the model (a task notice) — never a person's,
175
+ * so it never passes onUserMessage (ADR-0057 §4, a wake run included). */
176
+ export declare const isRuntimeInput: (e: {
177
+ readonly via?: UserInputVia;
178
+ } | undefined) => boolean;
165
179
  /**
166
180
  * Compaction happened at this point in the trajectory. The EXACT
167
181
  * replacements are persisted; the projection applies them verbatim — it
@@ -30,6 +30,9 @@
30
30
  * is a compile error in the adapters' exhaustive switches.
31
31
  */
32
32
  import { ERROR_CODES } from "./error-codes.js";
33
+ /** An input the runtime owes the model (a task notice) — never a person's,
34
+ * so it never passes onUserMessage (ADR-0057 §4, a wake run included). */
35
+ export const isRuntimeInput = (e) => e?.via?.kind === "tasks";
33
36
  // ── deep-shape helpers (round 5): every variant is validated field by field —
34
37
  // legal enums, Terminal union members, Usage known/token combos, content
35
38
  // blocks, plain-object inputs, optional fields when present. A record that
@@ -90,11 +93,17 @@ function isContent(v) {
90
93
  function isSource(v) {
91
94
  return v.source === undefined || MESSAGE_SOURCES.has(v.source);
92
95
  }
96
+ const TASK_TRANSITIONS = new Set(["ready", "exited", "failed", "stopped", "unknown"]);
93
97
  function isVia(v) {
94
98
  if (v.via === undefined)
95
99
  return true;
96
100
  const via = v.via;
97
- return isPlainObject(via) && via.kind === "skill" && typeof via.name === "string" && via.name !== "" && typeof via.line === "string" && via.line !== "";
101
+ if (!isPlainObject(via))
102
+ return false;
103
+ if (via.kind === "skill")
104
+ return typeof via.name === "string" && via.name !== "" && typeof via.line === "string" && via.line !== "";
105
+ const items = via.items;
106
+ return via.kind === "tasks" && Array.isArray(items) && items.length > 0 && items.every((i) => isPlainObject(i) && typeof i.taskId === "string" && i.taskId !== "" && TASK_TRANSITIONS.has(i.transition));
98
107
  }
99
108
  function isTags(v) {
100
109
  return v.tags === undefined || (Array.isArray(v.tags) && v.tags.every((t) => typeof t === "string"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-core",
3
- "version": "0.45.3",
3
+ "version": "0.46.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.45.3",
36
+ "@vincemakes/kiso-evals": "0.46.0",
37
37
  "@types/node": "^26.1.2",
38
38
  "typescript": "^5.7.2",
39
39
  "vitest": "^3.0.0"