@vincemakes/kiso-runtime 0.42.0 → 0.42.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/compose.d.ts CHANGED
@@ -43,7 +43,8 @@ export declare function composeToolTable(registry: ToolRegistry, rules?: ToolRul
43
43
  * No appends → the base passes through byte-identical.
44
44
  */
45
45
  /** An extension's append as text: a string as is, a function evaluated
46
- * NOW (0.42.0 — the per-run seam; call this once per composition). */
46
+ * NOW (0.42.0 — call this once per attempt). 0.42.1 (#14): a function
47
+ * may answer undefined — no append this attempt, no separator. */
47
48
  export declare function appendOf(extension: KisoExtension): string | undefined;
48
49
  export declare function composeSystemPrompt(base: string | undefined, extensions: readonly KisoExtension[]): string | undefined;
49
50
  /** The base and the append texts, \n\n-joined; no appends → the base as is. */
package/dist/compose.js CHANGED
@@ -4,10 +4,13 @@
4
4
  * hook composition (the existing come first), and the loop's microcompact config lookup.
5
5
  */
6
6
  export function runBasePrompt(systemPrompt, registry, rules = [], table = "on") {
7
+ // 0.42.1 (the products' request #15): "" composes as ABSENT — never a
8
+ // bare separator ahead of the table or the appends.
9
+ const base = systemPrompt === "" ? undefined : systemPrompt;
7
10
  if (table === "off")
8
- return systemPrompt;
11
+ return base;
9
12
  const toolTable = composeToolTable(registry, rules);
10
- return toolTable === "" ? systemPrompt : systemPrompt === undefined ? toolTable : `${systemPrompt}\n\n${toolTable}`;
13
+ return toolTable === "" ? base : base === undefined ? toolTable : `${base}\n\n${toolTable}`;
11
14
  }
12
15
  /** The table, or "" when the registry is empty (no vocabulary, no tools). */
13
16
  export function composeToolTable(registry, rules = []) {
@@ -36,7 +39,8 @@ export function composeToolTable(registry, rules = []) {
36
39
  * No appends → the base passes through byte-identical.
37
40
  */
38
41
  /** An extension's append as text: a string as is, a function evaluated
39
- * NOW (0.42.0 — the per-run seam; call this once per composition). */
42
+ * NOW (0.42.0 — call this once per attempt). 0.42.1 (#14): a function
43
+ * may answer undefined — no append this attempt, no separator. */
40
44
  export function appendOf(extension) {
41
45
  const append = extension.systemPrompt?.append;
42
46
  return typeof append === "function" ? append() : append;
@@ -49,9 +53,10 @@ export function composeSystemPrompt(base, extensions) {
49
53
  }
50
54
  /** The base and the append texts, \n\n-joined; no appends → the base as is. */
51
55
  export function joinPrompt(base, appends) {
56
+ const head = base === "" ? undefined : base; // 0.42.1 (#15): "" is absent
52
57
  if (appends.length === 0)
53
- return base;
54
- return base === undefined ? appends.join("\n\n") : `${base}\n\n${appends.join("\n\n")}`;
58
+ return head;
59
+ return head === undefined ? appends.join("\n\n") : `${head}\n\n${appends.join("\n\n")}`;
55
60
  }
56
61
  /** 0.42.0: the OUTERMOST adapter layer — `compose` runs exactly once per
57
62
  * provider attempt (a retry is a new attempt) and its result is the
@@ -274,7 +274,7 @@ export class RequestTracer {
274
274
  this.#provider === "anthropic"
275
275
  ? p.inputTokens ?? 0
276
276
  : p.inputTokens !== null
277
- ? Math.max(0, p.inputTokens - (p.cacheRead ?? 0))
277
+ ? Math.max(0, p.inputTokens - (p.cacheRead ?? 0) - (p.cacheWrite ?? 0)) // 0.42.2 (#17): the same arithmetic as canonical.ts
278
278
  : 0;
279
279
  record.cacheRead = p.cacheRead ?? 0;
280
280
  record.cacheWrite = p.cacheWrite ?? null;
@@ -118,7 +118,11 @@ export declare function priceFor(route: string, u: {
118
118
  }, table: PricingTable): number | null;
119
119
  /** Raw → canonical (the accounting boundary). Behavior-preserving against
120
120
  * the guard's incumbent per-provider branch (guard.ts settle): anthropic
121
- * input is fresh as-is; every other route subtracts cacheRead.
121
+ * input is fresh as-is; every other route subtracts cacheRead — and,
122
+ * 0.42.2 (#17), cacheWrite when the provider reported one: a "total"
123
+ * prompt count includes the tokens written to the cache, and they are
124
+ * priced as the write, never twice. total = input + cacheRead +
125
+ * cacheWrite holds by construction on both routes.
122
126
  *
123
127
  * The trailing `table` parameter is the injection slot (R5b-④a): the
124
128
  * R5a-1-commercial table rides it on day one, defaulting to the pinned
@@ -35,7 +35,7 @@ import { lookupModelMetadata } from "../provider/metadata.js";
35
35
  * total), preserved by construction. */
36
36
  export const INPUT_CONVENTIONS = {
37
37
  anthropic: "fresh", // input_tokens excludes the cached prefix
38
- "openai-compat": "total", // prompt_tokens includes the cached prefix
38
+ "openai-compat": "total", // prompt_tokens includes the cached prefix AND, on a gateway that reports it, the written one
39
39
  };
40
40
  /** Pricing table v1. Freeze date 2026-08-13 (the E2 ruling). Rates:
41
41
  * DeepSeek's published rates (https://api-docs.deepseek.com/quick_start/pricing),
@@ -80,7 +80,11 @@ export function priceFor(route, u, table) {
80
80
  }
81
81
  /** Raw → canonical (the accounting boundary). Behavior-preserving against
82
82
  * the guard's incumbent per-provider branch (guard.ts settle): anthropic
83
- * input is fresh as-is; every other route subtracts cacheRead.
83
+ * input is fresh as-is; every other route subtracts cacheRead — and,
84
+ * 0.42.2 (#17), cacheWrite when the provider reported one: a "total"
85
+ * prompt count includes the tokens written to the cache, and they are
86
+ * priced as the write, never twice. total = input + cacheRead +
87
+ * cacheWrite holds by construction on both routes.
84
88
  *
85
89
  * The trailing `table` parameter is the injection slot (R5b-④a): the
86
90
  * R5a-1-commercial table rides it on day one, defaulting to the pinned
@@ -92,7 +96,7 @@ export function canonicalizeUsage(route, raw, table = PRICING_TABLE_V1) {
92
96
  ? 0
93
97
  : convention === "fresh"
94
98
  ? raw.inputTokens
95
- : Math.max(0, raw.inputTokens - (raw.cacheRead ?? 0));
99
+ : Math.max(0, raw.inputTokens - (raw.cacheRead ?? 0) - (raw.cacheWrite ?? 0));
96
100
  const cacheRead = raw.cacheRead ?? 0;
97
101
  const cacheWrite = raw.cacheWrite ?? null;
98
102
  const output = raw.outputTokens ?? 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vincemakes/kiso-runtime",
3
- "version": "0.42.0",
3
+ "version": "0.42.2",
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.42.0"
28
+ "@vincemakes/kiso-core": "0.42.2"
29
29
  },
30
30
  "peerDependencies": {
31
- "@vincemakes/kiso-provider-anthropic": "0.42.0",
32
- "@vincemakes/kiso-provider-openai": "0.42.0",
33
- "@vincemakes/kiso-provider-openai-responses": "0.42.0"
31
+ "@vincemakes/kiso-provider-anthropic": "0.42.2",
32
+ "@vincemakes/kiso-provider-openai": "0.42.2",
33
+ "@vincemakes/kiso-provider-openai-responses": "0.42.2"
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.42.0",
47
+ "@vincemakes/kiso-evals": "0.42.2",
48
48
  "@types/node": "^26.1.2",
49
49
  "typescript": "^5.7.2",
50
50
  "vitest": "^3.0.0"