@vincemakes/kiso-runtime 0.40.7 → 0.41.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.
package/dist/agent.d.ts CHANGED
@@ -80,6 +80,15 @@ export interface AgentDefinition {
80
80
  * before the request is aborted and retried (default 120 s; 0 off).
81
81
  * Type-only additive; read by the runtime's idle guard. */
82
82
  readonly streamIdleMs?: number;
83
+ /** R1 (2026-09-23): the tool table's vocabulary rows — the product's
84
+ * routing policy, one line per tool NAME, injected only while that tool
85
+ * is active. Absent = no vocabulary lines (the fixed directives and the
86
+ * tools' own snippets still compose). Type-only additive; never part of
87
+ * the profile digest. */
88
+ readonly toolRules?: ReadonlyArray<{
89
+ readonly tool: string;
90
+ readonly line: string;
91
+ }>;
83
92
  /** E1: loaded extensions — their tools merge into the registry (a name
84
93
  * collision with a built-in is a loud startup error), their hooks
85
94
  * compose after the agent's own (the existing come first), their approvals join the
package/dist/agent.js CHANGED
@@ -177,6 +177,7 @@ export class AgentRuntime {
177
177
  ...(this.#definition.contextPolicy !== undefined ? { contextPolicy: this.#definition.contextPolicy } : {}),
178
178
  ...(this.#definition.maxRetries !== undefined ? { maxRetries: this.#definition.maxRetries } : {}),
179
179
  ...(this.#definition.streamIdleMs !== undefined ? { streamIdleMs: this.#definition.streamIdleMs } : {}),
180
+ ...(this.#definition.toolRules !== undefined ? { toolRules: this.#definition.toolRules } : {}),
180
181
  ...(this.#definition.extensions !== undefined ? { extensions: this.#definition.extensions } : {}),
181
182
  };
182
183
  // 0.40.0: the last bill's time rides the RECORD, not the event.
package/dist/compose.d.ts CHANGED
@@ -5,13 +5,33 @@
5
5
  */
6
6
  import type { ApprovalChain, Event, HookHost, KisoExtension, ToolRegistry } from "@vincemakes/kiso-core";
7
7
  import type { SessionConfig } from "./session.js";
8
+ /**
9
+ * 0.1.40 (R-C item 1) — the tool substitution table: vocabulary rows, each
10
+ * bound to the tool that makes it true, filtered to the ACTIVE tool set +
11
+ * each active tool's ONE-line snippet + its guideline bullets. The full
12
+ * descriptions NEVER enter the system prompt — the provider transmits them
13
+ * in the JSON schema anyway (never pay twice). Deterministic: same registry
14
+ * + same rows → same table.
15
+ *
16
+ * R1 (2026-09-23): the ROWS are the product's (`AgentDefinition.toolRules`),
17
+ * not the runtime's. They were a constant here — the coding agent's routing
18
+ * policy, keyed by tool name — and every host whose tool happened to be
19
+ * called read_file received "never shell cat/head/tail" whether or not it
20
+ * had a shell. The runtime keeps the mechanism: the filter, the position,
21
+ * the joining. It knows no row. No rows → no vocabulary lines; the two
22
+ * fixed directives and the tools' own snippets remain.
23
+ */
24
+ export type ToolRules = ReadonlyArray<{
25
+ readonly tool: string;
26
+ readonly line: string;
27
+ }>;
8
28
  /** The base a run's system prompt is composed on: the session's prompt,
9
29
  * then the tool table (generated machinery sits BETWEEN the base and the
10
30
  * extension appends). One function, so an in-band summary outside a run
11
31
  * (ADR-0055 A2, /compact) sends the exact prefix a run sends. */
12
- export declare function runBasePrompt(systemPrompt: string | undefined, registry: ToolRegistry): string | undefined;
32
+ export declare function runBasePrompt(systemPrompt: string | undefined, registry: ToolRegistry, rules?: ToolRules): string | undefined;
13
33
  /** The table, or "" when the registry is empty (no vocabulary, no tools). */
14
- export declare function composeToolTable(registry: ToolRegistry): string;
34
+ export declare function composeToolTable(registry: ToolRegistry, rules?: ToolRules): string;
15
35
  /**
16
36
  * E2: the session's systemPrompt plus every extension's append, in LOAD
17
37
  * order, \n\n-joined — deterministic (same extension list → same prompt).
package/dist/compose.js CHANGED
@@ -3,38 +3,23 @@
3
3
  * from session.ts: the extension system-prompt appends, the extension
4
4
  * hook composition (the existing come first), and the loop's microcompact config lookup.
5
5
  */
6
- /**
7
- * 0.1.40 (R-C item 1) — the tool substitution table: the fixed vocabulary
8
- * (the reference implementation's content in kiso's voice, each line bound
9
- * to the tool that makes
10
- * it true) filtered to the ACTIVE tool set + each active tool's ONE-line
11
- * snippet + its guideline bullets. The full descriptions NEVER enter the
12
- * system prompt — the provider transmits them in the JSON schema anyway
13
- * (never pay twice). Deterministic: same registry → same table.
14
- */
15
- const TOOL_RULES = [
16
- { tool: "read_file", line: "read files with read_file, never shell cat/head/tail" },
17
- { tool: "search_text", line: "search with search_text, never shell grep/rg" },
18
- { tool: "list_dir", line: "list with list_dir, never ls" },
19
- { tool: "shell", line: "shell for what the file tools cannot do: commands, git, the network, the system" },
20
- ];
21
6
  /** The base a run's system prompt is composed on: the session's prompt,
22
7
  * then the tool table (generated machinery sits BETWEEN the base and the
23
8
  * extension appends). One function, so an in-band summary outside a run
24
9
  * (ADR-0055 A2, /compact) sends the exact prefix a run sends. */
25
- export function runBasePrompt(systemPrompt, registry) {
26
- const toolTable = composeToolTable(registry);
10
+ export function runBasePrompt(systemPrompt, registry, rules = []) {
11
+ const toolTable = composeToolTable(registry, rules);
27
12
  return toolTable === "" ? systemPrompt : systemPrompt === undefined ? toolTable : `${systemPrompt}\n\n${toolTable}`;
28
13
  }
29
14
  /** The table, or "" when the registry is empty (no vocabulary, no tools). */
30
- export function composeToolTable(registry) {
15
+ export function composeToolTable(registry, rules = []) {
31
16
  const tools = registry.list();
32
17
  if (tools.length === 0)
33
18
  return "";
34
19
  const active = new Set(tools.map((t) => t.name));
35
20
  const lines = [
36
21
  "Tool use:",
37
- ...TOOL_RULES.filter((r) => active.has(r.tool)).map((r) => `- ${r.line}`),
22
+ ...rules.filter((r) => active.has(r.tool)).map((r) => `- ${r.line}`),
38
23
  // the parallel directive: the window applies to every active turn.
39
24
  "- batch independent tool calls into one reply — they run in parallel",
40
25
  // D1: a tool result is evidence, not an answer — the turn ends with
package/dist/run.js CHANGED
@@ -88,7 +88,7 @@ export class Run {
88
88
  // session's base prompt and the extension appends: generated
89
89
  // machinery never outranks the deliberate extension text (the E2
90
90
  // "append lands at the END" contract holds). "" when empty.
91
- const basePrompt = runBasePrompt(this.#config.systemPrompt, this.#config.registry);
91
+ const basePrompt = runBasePrompt(this.#config.systemPrompt, this.#config.registry, this.#config.toolRules ?? []);
92
92
  // E3 — the ledger's parts: the base as CONFIGURED (what the CLI
93
93
  // handed the runtime — the tool table is generated machinery, R3)
94
94
  // and the extension appends in load order (R4 attribution). The
package/dist/session.d.ts CHANGED
@@ -554,6 +554,11 @@ export interface SessionConfig {
554
554
  readonly maxRetries?: number;
555
555
  /** LT-1: the stream watchdog's idle bound (ms); default 120 s, 0 off. */
556
556
  readonly streamIdleMs?: number;
557
+ /** R1: the tool table's vocabulary rows, the product's (see AgentDefinition). */
558
+ readonly toolRules?: ReadonlyArray<{
559
+ readonly tool: string;
560
+ readonly line: string;
561
+ }>;
557
562
  /**
558
563
  * E1: loaded extensions — their tools join the registry (idempotently;
559
564
  * a collision with a built-in name was already rejected at agent
package/dist/session.js CHANGED
@@ -842,7 +842,7 @@ export class AgentSession {
842
842
  // the one fallback. The budget is unchanged: measured for the
843
843
  // manual gesture, fixed for the policy (0.39.2).
844
844
  const cfg = this.#effectiveConfig();
845
- const systemPrompt = composeSystemPrompt(runBasePrompt(cfg.systemPrompt, cfg.registry), cfg.extensions ?? []);
845
+ const systemPrompt = composeSystemPrompt(runBasePrompt(cfg.systemPrompt, cfg.registry, cfg.toolRules ?? []), cfg.extensions ?? []);
846
846
  const wire = cfg.reasoning === undefined ? undefined : resolveReasoning(binding.model, cfg.reasoning, binding.baseUrl);
847
847
  const { result: call, path } = await this.#checkpointCall({
848
848
  messages: this.projected(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-runtime",
3
- "version": "0.40.7",
3
+ "version": "0.41.0",
4
4
  "description": "kiso runtime \u2014 durable multi-turn agent sessions: AgentDefinition, AgentRuntime, AgentSession, Run, append-only JSONL store.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -25,12 +25,12 @@
25
25
  "test": "vitest run"
26
26
  },
27
27
  "dependencies": {
28
- "@vincemakes/kiso-core": "0.40.7"
28
+ "@vincemakes/kiso-core": "0.41.0"
29
29
  },
30
30
  "peerDependencies": {
31
- "@vincemakes/kiso-provider-anthropic": "0.40.7",
32
- "@vincemakes/kiso-provider-openai": "0.40.7",
33
- "@vincemakes/kiso-provider-openai-responses": "0.40.7"
31
+ "@vincemakes/kiso-provider-anthropic": "0.41.0",
32
+ "@vincemakes/kiso-provider-openai": "0.41.0",
33
+ "@vincemakes/kiso-provider-openai-responses": "0.41.0"
34
34
  },
35
35
  "peerDependenciesMeta": {
36
36
  "@vincemakes/kiso-provider-anthropic": {
@@ -44,7 +44,7 @@
44
44
  }
45
45
  },
46
46
  "devDependencies": {
47
- "@vincemakes/kiso-evals": "0.40.7",
47
+ "@vincemakes/kiso-evals": "0.41.0",
48
48
  "@types/node": "^26.1.2",
49
49
  "typescript": "^5.7.2",
50
50
  "vitest": "^3.0.0"