@directive-run/knowledge 1.23.1 → 1.24.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/ai/ai-adapters.md CHANGED
@@ -74,6 +74,27 @@ const proxiedRunner = createAnthropicRunner({
74
74
  });
75
75
  ```
76
76
 
77
+ ### Prompt Caching (Anthropic)
78
+
79
+ Opt in with `promptCaching: "automatic"` to add a `cache_control` breakpoint on the agent's instructions. Anthropic caches that stable system prefix so repeat calls that share it read from cache (~0.1x input cost) instead of reprocessing it; the variable message suffix stays uncached. Off by default (bare-string system, unchanged prior behavior), non-breaking, and no beta header is required on `anthropic-version: 2023-06-01`. Supported on the non-streaming `createAnthropicRunner` (streaming is a follow-up).
80
+
81
+ ```typescript
82
+ const runner = createAnthropicRunner({
83
+ apiKey: process.env.ANTHROPIC_API_KEY,
84
+ promptCaching: "automatic",
85
+ });
86
+ const result = await runner(agent, prompt);
87
+
88
+ // Cache usage is surfaced on tokenUsage – present only when caching is active:
89
+ const { cacheReadTokens = 0, cacheCreationTokens = 0 } = result.tokenUsage;
90
+ // cacheCreationTokens – tokens written to cache on the first call (~1.25x cost)
91
+ // cacheReadTokens – tokens served from cache on repeat calls (~0.1x cost)
92
+ ```
93
+
94
+ `inputTokens` remains the uncached remainder; the cache fields are separate and additive, and `totalTokens` includes all four (input + output + cache-read + cache-creation).
95
+
96
+ **Minimum cacheable prefix (the #1 support gotcha).** Anthropic silently ignores `cache_control` when the cached prefix is below a per-model minimum – ~1024 tokens on Sonnet-tier models, 2048 on Sonnet-4.6 & Haiku-3.5, 4096 on Opus & Haiku-4.5. No error is raised: caching simply doesn't happen and `cacheReadTokens` stays `0` on repeat calls (that `0` is the diagnostic). Since Directive caches `agent.instructions`, short instructions commonly fall below the threshold. The `ephemeral` breakpoint also carries a 5-minute default TTL – a prefix not re-read within that window is evicted. (Cost note: `withBudget`/`estimateCost` weight all tokens equally today, so cached runs are not yet repriced for the ~0.1x read / ~1.25x write rates – cache-aware pricing is a planned follow-up.)
97
+
77
98
  ## OpenAI Adapter
78
99
 
79
100
  ```typescript
@@ -147,7 +168,7 @@ console.log(result.tokenUsage.input_tokens); // undefined!
147
168
  const result = await runner.run(agent, prompt);
148
169
  console.log(result.tokenUsage.inputTokens); // number
149
170
  console.log(result.tokenUsage.outputTokens); // number
150
- console.log(result.totalTokens); // inputTokens + outputTokens
171
+ console.log(result.totalTokens); // inputTokens + outputTokens (+ cache tokens when caching is active)
151
172
  ```
152
173
 
153
174
  All adapters normalize token usage to the same shape regardless of provider:
@@ -156,9 +177,14 @@ All adapters normalize token usage to the same shape regardless of provider:
156
177
  interface NormalizedTokenUsage {
157
178
  inputTokens: number;
158
179
  outputTokens: number;
180
+ // Populated by adapters with prompt caching active (e.g. Anthropic
181
+ // `promptCaching: "automatic"`); omitted otherwise.
182
+ cacheReadTokens?: number;
183
+ cacheCreationTokens?: number;
159
184
  }
160
185
 
161
186
  // result.totalTokens = inputTokens + outputTokens
187
+ // + cacheReadTokens + cacheCreationTokens (cache fields are 0 when absent)
162
188
  ```
163
189
 
164
190
  ## Adapter Hooks
@@ -244,7 +270,7 @@ const orchestrator = createAgentOrchestrator({ runner });
244
270
 
245
271
  | Adapter | Import Path | Key Options |
246
272
  |---|---|---|
247
- | Anthropic | `@directive-run/ai/anthropic` | `apiKey`, `defaultModel`, `maxTokens` |
273
+ | Anthropic | `@directive-run/ai/anthropic` | `apiKey`, `defaultModel`, `maxTokens`, `promptCaching` |
248
274
  | OpenAI | `@directive-run/ai/openai` | `apiKey`, `defaultModel`, `organization` |
249
275
  | Ollama | `@directive-run/ai/ollama` | `baseURL`, `defaultModel` |
250
276
  | Gemini | `@directive-run/ai/gemini` | `apiKey`, `defaultModel` |
@@ -55,7 +55,11 @@ interface RunResult<T = unknown> {
55
55
  interface TokenUsage {
56
56
  inputTokens: number;
57
57
  outputTokens: number;
58
- // Note: NO `total` field sum `inputTokens + outputTokens` when needed, or use `result.totalTokens`.
58
+ // Populated by adapters with prompt caching active (e.g. Anthropic
59
+ // `promptCaching: "automatic"`); omitted otherwise.
60
+ cacheReadTokens?: number;
61
+ cacheCreationTokens?: number;
62
+ // Note: NO `total` field — sum `inputTokens + outputTokens` (+ cache tokens when present) when needed, or use `result.totalTokens`.
59
63
  }
60
64
  ```
61
65
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@directive-run/knowledge",
3
- "version": "1.23.1",
3
+ "version": "1.24.0",
4
4
  "description": "Knowledge files, examples, and validation for Directive — the constraint-driven TypeScript runtime.",
5
5
  "license": "(MIT OR Apache-2.0)",
6
6
  "author": "Jason Comes",
@@ -53,8 +53,8 @@
53
53
  "tsx": "^4.19.2",
54
54
  "typescript": "^5.7.2",
55
55
  "vitest": "^3.2.6",
56
- "@directive-run/core": "1.23.1",
57
- "@directive-run/ai": "1.23.1"
56
+ "@directive-run/core": "1.24.0",
57
+ "@directive-run/ai": "1.24.0"
58
58
  },
59
59
  "scripts": {
60
60
  "build": "tsx scripts/generate-api-skeleton.ts && tsx scripts/generate-sitemap.ts && tsx scripts/extract-examples.ts && tsup",