@owlmeans/llm 0.1.18-rc.43 → 0.1.18-rc.45

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.
Files changed (339) hide show
  1. package/README.md +13 -12
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/inquiry/SKILL.md +21 -21
  4. package/agent-meta/skills/llm/SKILL.md +24 -24
  5. package/agent-meta/skills/llm-prompt-caching/SKILL.md +4 -4
  6. package/build/consts.d.ts +1 -8
  7. package/build/consts.d.ts.map +1 -1
  8. package/build/consts.js +0 -6
  9. package/build/consts.js.map +1 -1
  10. package/build/execution/index.d.ts +4 -0
  11. package/build/execution/index.d.ts.map +1 -1
  12. package/build/execution/index.js +2 -0
  13. package/build/execution/index.js.map +1 -1
  14. package/build/execution/policy/types.d.ts +34 -0
  15. package/build/execution/policy/types.d.ts.map +1 -0
  16. package/build/execution/policy/types.js +2 -0
  17. package/build/execution/policy/types.js.map +1 -0
  18. package/build/execution/policy.d.ts +4 -0
  19. package/build/execution/policy.d.ts.map +1 -0
  20. package/build/execution/policy.js +49 -0
  21. package/build/execution/policy.js.map +1 -0
  22. package/build/execution/service.d.ts +1 -1
  23. package/build/execution/service.d.ts.map +1 -1
  24. package/build/execution/service.js +29 -28
  25. package/build/execution/service.js.map +1 -1
  26. package/build/execution/state/types.d.ts +27 -0
  27. package/build/execution/state/types.d.ts.map +1 -0
  28. package/build/execution/state/types.js +2 -0
  29. package/build/execution/state/types.js.map +1 -0
  30. package/build/execution/state.d.ts +4 -0
  31. package/build/execution/state.d.ts.map +1 -0
  32. package/build/execution/state.js +33 -0
  33. package/build/execution/state.js.map +1 -0
  34. package/build/execution/utils.d.ts +10 -42
  35. package/build/execution/utils.d.ts.map +1 -1
  36. package/build/execution/utils.js +20 -111
  37. package/build/execution/utils.js.map +1 -1
  38. package/build/helpers/cache/types.d.ts +20 -0
  39. package/build/helpers/cache/types.d.ts.map +1 -0
  40. package/build/helpers/cache/types.js +2 -0
  41. package/build/helpers/cache/types.js.map +1 -0
  42. package/build/helpers/cache.d.ts +5 -10
  43. package/build/helpers/cache.d.ts.map +1 -1
  44. package/build/helpers/cache.js +17 -19
  45. package/build/helpers/cache.js.map +1 -1
  46. package/build/helpers/consts.d.ts +7 -0
  47. package/build/helpers/consts.d.ts.map +1 -0
  48. package/build/helpers/consts.js +9 -0
  49. package/build/helpers/consts.js.map +1 -0
  50. package/build/helpers/consts.local.d.ts +3 -0
  51. package/build/helpers/consts.local.d.ts.map +1 -0
  52. package/build/helpers/consts.local.js +3 -0
  53. package/build/helpers/consts.local.js.map +1 -0
  54. package/build/helpers/fallback.d.ts +0 -6
  55. package/build/helpers/fallback.d.ts.map +1 -1
  56. package/build/helpers/fallback.js +1 -8
  57. package/build/helpers/fallback.js.map +1 -1
  58. package/build/helpers/index.d.ts +4 -0
  59. package/build/helpers/index.d.ts.map +1 -1
  60. package/build/helpers/index.js +1 -0
  61. package/build/helpers/index.js.map +1 -1
  62. package/build/helpers/json/types.d.ts +27 -0
  63. package/build/helpers/json/types.d.ts.map +1 -0
  64. package/build/helpers/json/types.js +2 -0
  65. package/build/helpers/json/types.js.map +1 -0
  66. package/build/helpers/json.d.ts +5 -21
  67. package/build/helpers/json.d.ts.map +1 -1
  68. package/build/helpers/json.js +95 -109
  69. package/build/helpers/json.js.map +1 -1
  70. package/build/helpers/retry/types.d.ts +48 -0
  71. package/build/helpers/retry/types.d.ts.map +1 -0
  72. package/build/helpers/retry/types.js +2 -0
  73. package/build/helpers/retry/types.js.map +1 -0
  74. package/build/helpers/retry.d.ts +7 -29
  75. package/build/helpers/retry.d.ts.map +1 -1
  76. package/build/helpers/retry.js +50 -62
  77. package/build/helpers/retry.js.map +1 -1
  78. package/build/helpers/spectate.js +3 -3
  79. package/build/helpers/spectate.js.map +1 -1
  80. package/build/helpers/types.local.d.ts +6 -0
  81. package/build/helpers/types.local.d.ts.map +1 -0
  82. package/build/helpers/types.local.js +2 -0
  83. package/build/helpers/types.local.js.map +1 -0
  84. package/build/index.d.ts +10 -3
  85. package/build/index.d.ts.map +1 -1
  86. package/build/index.js +7 -2
  87. package/build/index.js.map +1 -1
  88. package/build/inquiry/index.d.ts +1 -0
  89. package/build/inquiry/index.d.ts.map +1 -1
  90. package/build/inquiry/index.js.map +1 -1
  91. package/build/inquiry/transport/types.d.ts +23 -0
  92. package/build/inquiry/transport/types.d.ts.map +1 -0
  93. package/build/inquiry/transport/types.js +2 -0
  94. package/build/inquiry/transport/types.js.map +1 -0
  95. package/build/inquiry/transport.d.ts +7 -6
  96. package/build/inquiry/transport.d.ts.map +1 -1
  97. package/build/inquiry/transport.js +27 -21
  98. package/build/inquiry/transport.js.map +1 -1
  99. package/build/model.d.ts.map +1 -1
  100. package/build/model.js +36 -36
  101. package/build/model.js.map +1 -1
  102. package/build/plugins/anthropic/consts.local.d.ts +7 -0
  103. package/build/plugins/anthropic/consts.local.d.ts.map +1 -0
  104. package/build/plugins/anthropic/consts.local.js +8 -0
  105. package/build/plugins/anthropic/consts.local.js.map +1 -0
  106. package/build/plugins/anthropic/support/types.d.ts +34 -0
  107. package/build/plugins/anthropic/support/types.d.ts.map +1 -0
  108. package/build/plugins/anthropic/support/types.js +2 -0
  109. package/build/plugins/anthropic/support/types.js.map +1 -0
  110. package/build/plugins/anthropic/support.d.ts +4 -0
  111. package/build/plugins/anthropic/support.d.ts.map +1 -0
  112. package/build/plugins/anthropic/support.js +17 -0
  113. package/build/plugins/anthropic/support.js.map +1 -0
  114. package/build/plugins/anthropic.d.ts +7 -98
  115. package/build/plugins/anthropic.d.ts.map +1 -1
  116. package/build/plugins/anthropic.js +38 -162
  117. package/build/plugins/anthropic.js.map +1 -1
  118. package/build/plugins/compatible.d.ts.map +1 -1
  119. package/build/plugins/compatible.js +3 -4
  120. package/build/plugins/compatible.js.map +1 -1
  121. package/build/plugins/consts.d.ts +92 -0
  122. package/build/plugins/consts.d.ts.map +1 -0
  123. package/build/plugins/consts.js +157 -0
  124. package/build/plugins/consts.js.map +1 -0
  125. package/build/plugins/consts.local.d.ts +11 -0
  126. package/build/plugins/consts.local.d.ts.map +1 -0
  127. package/build/plugins/consts.local.js +11 -0
  128. package/build/plugins/consts.local.js.map +1 -0
  129. package/build/plugins/export.d.ts +5 -0
  130. package/build/plugins/export.d.ts.map +1 -1
  131. package/build/plugins/export.js +3 -0
  132. package/build/plugins/export.js.map +1 -1
  133. package/build/plugins/index.d.ts +6 -9
  134. package/build/plugins/index.d.ts.map +1 -1
  135. package/build/plugins/index.js +13 -43
  136. package/build/plugins/index.js.map +1 -1
  137. package/build/plugins/openai.d.ts +2 -70
  138. package/build/plugins/openai.d.ts.map +1 -1
  139. package/build/plugins/openai.js +13 -70
  140. package/build/plugins/openai.js.map +1 -1
  141. package/build/plugins/registry/types.d.ts +25 -0
  142. package/build/plugins/registry/types.d.ts.map +1 -0
  143. package/build/plugins/registry/types.js +2 -0
  144. package/build/plugins/registry/types.js.map +1 -0
  145. package/build/plugins/registry.d.ts +4 -0
  146. package/build/plugins/registry.d.ts.map +1 -0
  147. package/build/plugins/registry.js +44 -0
  148. package/build/plugins/registry.js.map +1 -0
  149. package/build/plugins/types.d.ts +41 -0
  150. package/build/plugins/types.d.ts.map +1 -1
  151. package/build/plugins/types.local.d.ts +36 -0
  152. package/build/plugins/types.local.d.ts.map +1 -0
  153. package/build/plugins/types.local.js +2 -0
  154. package/build/plugins/types.local.js.map +1 -0
  155. package/build/plugins/utils/types.d.ts +46 -0
  156. package/build/plugins/utils/types.d.ts.map +1 -0
  157. package/build/plugins/utils/types.js +2 -0
  158. package/build/plugins/utils/types.js.map +1 -0
  159. package/build/plugins/utils.d.ts +3 -43
  160. package/build/plugins/utils.d.ts.map +1 -1
  161. package/build/plugins/utils.js +32 -59
  162. package/build/plugins/utils.js.map +1 -1
  163. package/build/prompt/consts.d.ts +7 -0
  164. package/build/prompt/consts.d.ts.map +1 -0
  165. package/build/prompt/consts.js +7 -0
  166. package/build/prompt/consts.js.map +1 -0
  167. package/build/prompt/consts.local.d.ts +3 -0
  168. package/build/prompt/consts.local.d.ts.map +1 -0
  169. package/build/prompt/consts.local.js +3 -0
  170. package/build/prompt/consts.local.js.map +1 -0
  171. package/build/prompt/index.d.ts +2 -0
  172. package/build/prompt/index.d.ts.map +1 -1
  173. package/build/prompt/index.js +1 -0
  174. package/build/prompt/index.js.map +1 -1
  175. package/build/prompt/plugins.js +5 -5
  176. package/build/prompt/plugins.js.map +1 -1
  177. package/build/prompt/render/types.d.ts +25 -0
  178. package/build/prompt/render/types.d.ts.map +1 -0
  179. package/build/prompt/render/types.js +2 -0
  180. package/build/prompt/render/types.js.map +1 -0
  181. package/build/prompt/render.d.ts +6 -25
  182. package/build/prompt/render.d.ts.map +1 -1
  183. package/build/prompt/render.js +24 -36
  184. package/build/prompt/render.js.map +1 -1
  185. package/build/prompt/service.d.ts +2 -4
  186. package/build/prompt/service.d.ts.map +1 -1
  187. package/build/prompt/service.js +5 -5
  188. package/build/prompt/service.js.map +1 -1
  189. package/build/prompt/types.d.ts +3 -0
  190. package/build/prompt/types.d.ts.map +1 -1
  191. package/build/service.d.ts +2 -4
  192. package/build/service.d.ts.map +1 -1
  193. package/build/service.js +2 -2
  194. package/build/service.js.map +1 -1
  195. package/build/types.d.ts +3 -14
  196. package/build/types.d.ts.map +1 -1
  197. package/build/types.local.d.ts +8 -0
  198. package/build/types.local.d.ts.map +1 -0
  199. package/build/types.local.js +2 -0
  200. package/build/types.local.js.map +1 -0
  201. package/build/utils/config/types.d.ts +27 -0
  202. package/build/utils/config/types.d.ts.map +1 -0
  203. package/build/utils/config/types.js +2 -0
  204. package/build/utils/config/types.js.map +1 -0
  205. package/build/utils/config.d.ts +3 -23
  206. package/build/utils/config.d.ts.map +1 -1
  207. package/build/utils/config.js +18 -32
  208. package/build/utils/config.js.map +1 -1
  209. package/build/utils/effort/types.d.ts +23 -0
  210. package/build/utils/effort/types.d.ts.map +1 -0
  211. package/build/utils/effort/types.js +2 -0
  212. package/build/utils/effort/types.js.map +1 -0
  213. package/build/utils/effort.d.ts +3 -23
  214. package/build/utils/effort.d.ts.map +1 -1
  215. package/build/utils/effort.js +19 -26
  216. package/build/utils/effort.js.map +1 -1
  217. package/build/utils/null-report/types.d.ts +34 -0
  218. package/build/utils/null-report/types.d.ts.map +1 -0
  219. package/build/utils/null-report/types.js +2 -0
  220. package/build/utils/null-report/types.js.map +1 -0
  221. package/build/utils/null-report.d.ts +2 -29
  222. package/build/utils/null-report.d.ts.map +1 -1
  223. package/build/utils/null-report.js +3 -1
  224. package/build/utils/null-report.js.map +1 -1
  225. package/build/utils/prompt/types.d.ts +51 -0
  226. package/build/utils/prompt/types.d.ts.map +1 -0
  227. package/build/utils/prompt/types.js +2 -0
  228. package/build/utils/prompt/types.js.map +1 -0
  229. package/build/utils/prompt.d.ts +3 -47
  230. package/build/utils/prompt.d.ts.map +1 -1
  231. package/build/utils/prompt.js +90 -126
  232. package/build/utils/prompt.js.map +1 -1
  233. package/build/utils/rungs/types.d.ts +26 -0
  234. package/build/utils/rungs/types.d.ts.map +1 -0
  235. package/build/utils/rungs/types.js +2 -0
  236. package/build/utils/rungs/types.js.map +1 -0
  237. package/build/utils/rungs.d.ts +3 -20
  238. package/build/utils/rungs.d.ts.map +1 -1
  239. package/build/utils/rungs.js +20 -21
  240. package/build/utils/rungs.js.map +1 -1
  241. package/build/utils/schema/consts.d.ts +5 -0
  242. package/build/utils/schema/consts.d.ts.map +1 -0
  243. package/build/utils/schema/consts.js +10 -0
  244. package/build/utils/schema/consts.js.map +1 -0
  245. package/build/utils/schema/types.d.ts +43 -0
  246. package/build/utils/schema/types.d.ts.map +1 -0
  247. package/build/utils/schema/types.js +2 -0
  248. package/build/utils/schema/types.js.map +1 -0
  249. package/build/utils/schema.d.ts +3 -37
  250. package/build/utils/schema.d.ts.map +1 -1
  251. package/build/utils/schema.js +121 -152
  252. package/build/utils/schema.js.map +1 -1
  253. package/build/utils/stream/types.d.ts +25 -0
  254. package/build/utils/stream/types.d.ts.map +1 -0
  255. package/build/utils/stream/types.js +2 -0
  256. package/build/utils/stream/types.js.map +1 -0
  257. package/build/utils/stream.d.ts +3 -21
  258. package/build/utils/stream.d.ts.map +1 -1
  259. package/build/utils/stream.js +32 -47
  260. package/build/utils/stream.js.map +1 -1
  261. package/build/utils.d.ts +7 -0
  262. package/build/utils.d.ts.map +1 -0
  263. package/build/utils.js +7 -0
  264. package/build/utils.js.map +1 -0
  265. package/package.json +17 -17
  266. package/src/consts.ts +1 -10
  267. package/src/execution/index.ts +4 -0
  268. package/src/execution/policy/types.ts +40 -0
  269. package/src/execution/policy.ts +73 -0
  270. package/src/execution/service.ts +31 -39
  271. package/src/execution/state/types.ts +27 -0
  272. package/src/execution/state.ts +42 -0
  273. package/src/execution/utils.ts +26 -123
  274. package/src/helpers/cache/types.ts +18 -0
  275. package/src/helpers/cache.ts +25 -26
  276. package/src/helpers/consts.local.ts +2 -0
  277. package/src/helpers/consts.ts +10 -0
  278. package/src/helpers/fallback.ts +1 -9
  279. package/src/helpers/index.ts +4 -0
  280. package/src/helpers/json/types.ts +26 -0
  281. package/src/helpers/json.ts +86 -95
  282. package/src/helpers/retry/types.ts +49 -0
  283. package/src/helpers/retry.ts +56 -62
  284. package/src/helpers/spectate.ts +3 -3
  285. package/src/helpers/types.local.ts +5 -0
  286. package/src/index.ts +10 -9
  287. package/src/inquiry/index.ts +1 -0
  288. package/src/inquiry/transport/types.ts +23 -0
  289. package/src/inquiry/transport.ts +35 -21
  290. package/src/model.ts +45 -59
  291. package/src/plugins/anthropic/consts.local.ts +8 -0
  292. package/src/plugins/anthropic/support/types.ts +34 -0
  293. package/src/plugins/anthropic/support.ts +31 -0
  294. package/src/plugins/anthropic.ts +46 -220
  295. package/src/plugins/compatible.ts +3 -5
  296. package/src/plugins/consts.local.ts +16 -0
  297. package/src/plugins/consts.ts +166 -0
  298. package/src/plugins/export.ts +5 -0
  299. package/src/plugins/index.ts +14 -48
  300. package/src/plugins/openai.ts +16 -89
  301. package/src/plugins/registry/types.ts +23 -0
  302. package/src/plugins/registry.ts +61 -0
  303. package/src/plugins/types.local.ts +33 -0
  304. package/src/plugins/types.ts +43 -0
  305. package/src/plugins/utils/types.ts +40 -0
  306. package/src/plugins/utils.ts +35 -60
  307. package/src/prompt/consts.local.ts +2 -0
  308. package/src/prompt/consts.ts +6 -0
  309. package/src/prompt/index.ts +2 -0
  310. package/src/prompt/plugins.ts +5 -5
  311. package/src/prompt/render/types.ts +25 -0
  312. package/src/prompt/render.ts +37 -46
  313. package/src/prompt/service.ts +8 -18
  314. package/src/prompt/types.ts +3 -0
  315. package/src/service.ts +4 -8
  316. package/src/types.local.ts +9 -0
  317. package/src/types.ts +3 -16
  318. package/src/utils/config/types.ts +27 -0
  319. package/src/utils/config.ts +22 -33
  320. package/src/utils/effort/types.ts +23 -0
  321. package/src/utils/effort.ts +34 -38
  322. package/src/utils/null-report/types.ts +28 -0
  323. package/src/utils/null-report.ts +5 -28
  324. package/src/utils/prompt/types.ts +51 -0
  325. package/src/utils/prompt.ts +86 -120
  326. package/src/utils/rungs/types.ts +28 -0
  327. package/src/utils/rungs.ts +25 -33
  328. package/src/utils/schema/consts.ts +11 -0
  329. package/src/utils/schema/types.ts +44 -0
  330. package/src/utils/schema.ts +121 -156
  331. package/src/utils/stream/types.ts +27 -0
  332. package/src/utils/stream.ts +37 -49
  333. package/src/utils.ts +7 -0
  334. package/tests/anthropic-families.spec.ts +12 -16
  335. package/tests/helpers.spec.ts +25 -31
  336. package/tests/inquiry.spec.ts +12 -16
  337. package/tests/internals.spec.ts +34 -35
  338. package/tests/plugins.spec.ts +28 -34
  339. package/tests/structured-schema.spec.ts +8 -12
package/README.md CHANGED
@@ -20,7 +20,7 @@ abstraction that resolves models from an inheritable policy.
20
20
  ## Installation
21
21
 
22
22
  ```bash
23
- bun add @owlmeans/llm@^0.1.18-rc.43 @owlmeans/llm-common@^0.1.18-rc.37
23
+ bun add @owlmeans/llm@^0.1.18-rc.45 @owlmeans/llm-common@^0.1.18-rc.39
24
24
  bun add @langchain/core @langchain/openai @langchain/anthropic # peer dependencies
25
25
  ```
26
26
 
@@ -100,10 +100,10 @@ const resumed = context.executions().restore(state, { models: () => context.llm(
100
100
  ### Add a provider
101
101
 
102
102
  ```typescript
103
- import { openAiFamily, registerLlmPlugin } from '@owlmeans/llm'
103
+ import { llmPluginRegistry, openAiFamily } from '@owlmeans/llm'
104
104
  import { StructuredMode } from '@owlmeans/llm-common'
105
105
 
106
- registerLlmPlugin({
106
+ llmPluginRegistry.register({
107
107
  ...openAiFamily, // shares owns/refine/toolChoice/responseFormat
108
108
  type: 'my-gateway',
109
109
  structuredMode: config => config.structuredOutput === true ? StructuredMode.Native : StructuredMode.Tool,
@@ -139,24 +139,25 @@ spectator entry), `filter` (reject a result and force a retry), `useCache` / `ca
139
139
  | Reasoning eats the whole output budget | Retry doubles `maxTokens` toward `maxTokensCap` **and** shrinks an absolute reasoning cap |
140
140
  | A weak cheap model keeps failing | Walks the `ModelConfig.fallback` chain, `FALLBACK_AFTER_ATTEMPTS` attempts per rung; a rung may be another provider, called in its own dialect |
141
141
  | The same model keeps giving the same weak answer | Climbs `ModelConfig.effort` one level per attempt of the rung, up to the model's ceiling; a `TemperatureFactory` request climbs it too |
142
- | Model stringifies arrays / over-wraps scalars | `coerceToSchema` reconciles the answer with the schema before validation |
143
- | Model ignores the tool and answers in prose | `parseJsonContent` salvages JSON from fences and surrounding text |
142
+ | Model stringifies arrays / over-wraps scalars | `jsonHelper.coerceToSchema` reconciles the answer with the schema before validation |
143
+ | Model ignores the tool and answers in prose | `jsonHelper.parseJsonContent` salvages JSON from fences and surrounding text |
144
144
  | A blank message poisons the request (Anthropic 400 `text content blocks must contain non-whitespace text`, typically an empty file read pasted into a prompt) | Whitespace-only text blocks are dropped before every call; blank tool results are stubbed to keep their `tool_use` pairing, and an all-blank input becomes one stub user message |
145
145
  | Nothing usable came back | `NullCapture` — request, response, token accounting and finish reason, to the spectator |
146
- | An error no retry can fix | `registerFatalError` / `LlmPlugin.isFatal` abort the loop immediately |
146
+ | An error no retry can fix | `retryHelper.registerFatalError` / `LlmPlugin.isFatal` abort the loop immediately |
147
147
 
148
148
  ### Helpers (usable alongside a model)
149
149
 
150
- `withRetry` · `registerFatalError` · `spectate` · `normalizeInput` · `parseJsonContent` ·
151
- `coerceToSchema` · `resolveFallbacks`. Also exported from `@owlmeans/llm/helpers`.
150
+ `retryHelper` (`withRetry`, `registerFatalError`, `isFatalError`) · `jsonHelper` (`parseJsonContent`,
151
+ `coerceToSchema`) · `cacheHelper` (`readCacheUsage`, `hasCacheActivity`) · `spectate` ·
152
+ `normalizeInput` · `resolveFallbacks`. Also exported from `@owlmeans/llm/helpers`.
152
153
 
153
154
  Everything under `src/utils/` is library-private and deliberately not exported.
154
155
 
155
156
  ### Plugins
156
157
 
157
- Exported from `@owlmeans/llm/plugins` as well as the root: `plugins` (the registry),
158
- `registerLlmPlugin`, `resolvePlugin`, `pluginOf`, `pluginFor`, `anthropicPlugin`,
159
- `openAiPlugin`, `compatiblePlugin`, `openAiFamily`.
158
+ Exported from `@owlmeans/llm/plugins` as well as the root: `llmPluginRegistry` (the registry —
159
+ `plugins`, `register`, `resolvePlugin`, `pluginOf`, `pluginFor`, `effortSupportOf`),
160
+ `anthropicSupportHelper`, `anthropicPlugin`, `openAiPlugin`, `compatiblePlugin`, `openAiFamily`.
160
161
 
161
162
  ## Tests
162
163
 
@@ -185,7 +186,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
185
186
  your project's skill store (`.agents/skills/`):
186
187
 
187
188
  ```sh
188
- npx @owlmeans/agent-skills@^0.1.18-rc.47
189
+ npx @owlmeans/agent-skills@^0.1.18-rc.49
189
190
  ```
190
191
 
191
192
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/llm",
4
- "version": "0.1.18-rc.43",
5
- "generatedAt": "2026-10-03T20:05:07.592Z",
4
+ "version": "0.1.18-rc.45",
5
+ "generatedAt": "2026-10-05T21:03:06.389Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -48,17 +48,17 @@ interface InquiryAnswer {
48
48
  value?: string | string[]
49
49
  text?: string
50
50
  declined?: boolean // nobody could decide — an ANSWER, never a failure
51
- truncated?: boolean // set by capAnswer or stateAnswerOf, never by an answerer
51
+ truncated?: boolean // set by inquiryHelper.capAnswer or .stateAnswerOf, never by an answerer
52
52
  }
53
53
 
54
54
  interface InquiryTransport { ask: (inquiry: Inquiry, signal?: AbortSignal) => Promise<InquiryAnswer> }
55
55
  interface InquiryConfig { transport?: string; policy: InquiryPolicy }
56
56
  ```
57
57
 
58
- The pure helpers are the ONE reading of an answer every layer uses — a second reading is a second
59
- contract: `defaultAnswerFor(inquiry)` (the default, or a decline), `answeredWith(answer)` (the first
60
- value, else the text, else `null`), `isDeclined(answer)`, `capAnswer(answer, max?)`,
61
- `stateAnswerOf(answer)`, `renderInquiry(inquiry)` (a one-line label for a note or a run row).
58
+ The pure `inquiryHelper` is the ONE reading of an answer every layer uses — a second reading is a second
59
+ contract: `inquiryHelper.defaultAnswerFor(inquiry)` (the default, or a decline), `.answeredWith(answer)` (the first
60
+ value, else the text, else `null`), `.isDeclined(answer)`, `.capAnswer(answer, max?)`,
61
+ `.stateAnswerOf(answer)`, `.renderInquiry(inquiry)` (a one-line label for a note or a run row).
62
62
 
63
63
  ## Three policies, and no fourth
64
64
 
@@ -69,7 +69,7 @@ policy.
69
69
  | Policy | `ExecutionService.ask` does |
70
70
  |---|---|
71
71
  | `Ask` | Hands the question to the seated transport and waits for the answer |
72
- | `Default` | Returns `defaultAnswerFor(inquiry)` and asks nobody. The caller is expected to RECORD the assumption where a user can read it |
72
+ | `Default` | Returns `inquiryHelper.defaultAnswerFor(inquiry)` and asks nobody. The caller is expected to RECORD the assumption where a user can read it |
73
73
  | `Refuse` | Throws `InquiryDeclined` — nobody may be asked at all |
74
74
 
75
75
  **No configuration means `Default`.** A run that was never given a channel must never block on one:
@@ -80,20 +80,20 @@ project pipeline, a scheduled job).
80
80
 
81
81
  `DEFAULT_INQUIRY_ANSWER_CHARS` (2 000) is the only ceiling on a stored answer. The connector's
82
82
  `CONNECT_INQUIRY_MAX_TEXT` equals it, the connector's answer schema caps `text` at it, and
83
- `capAnswer` enforces it. Three ceilings for one value is how a user's 3 000-character answer is
83
+ `inquiryHelper.capAnswer` enforces it. Three ceilings for one value is how a user's 3 000-character answer is
84
84
  accepted on the wire and silently halved further in — so never introduce a local cap; import this
85
85
  one.
86
86
 
87
87
  **Only the prose is ever cut.** A `value` is the decision itself — for a `Choice` it must equal one
88
88
  of the question's own option values — so a shortened one is not a degraded answer but a different
89
- answer, matching no option, which `answeredWith` would hand on as what the person chose. An
89
+ answer, matching no option, which `inquiryHelper.answeredWith` would hand on as what the person chose. An
90
90
  over-long `value` is a defect upstream (the connector's schema refuses one rather than shortening
91
- it): `capAnswer` passes it through whole and raises `truncated` on it.
91
+ it): `inquiryHelper.capAnswer` passes it through whole and raises `truncated` on it.
92
92
 
93
- `capAnswer` **reports** the cut (`truncated: true`). A silent truncation is exactly the class of
93
+ `inquiryHelper.capAnswer` **reports** the cut (`truncated: true`). A silent truncation is exactly the class of
94
94
  failure the primitive exists to prevent.
95
95
 
96
- A resumable pipeline **state** stores less: `stateAnswerOf` keeps the decision whole and cuts the
96
+ A resumable pipeline **state** stores less: `inquiryHelper.stateAnswerOf` keeps the decision whole and cuts the
97
97
  prose to `INQUIRY_STATE_TEXT_CHARS` (200), because a state is keys, markers and paths — two
98
98
  full-size answers would make it prose. The full answer still goes back to whoever asked; long text
99
99
  belongs in whatever document the application keeps for it (the converter writes
@@ -102,21 +102,21 @@ belongs in whatever document the application keeps for it (the converter writes
102
102
  ## The transport registry, and why an absent channel is fatal
103
103
 
104
104
  ```typescript
105
- registerInquiryTransport(key, transport) // seat on attach
106
- releaseInquiryTransport(key) // release when the channel goes away
107
- hasInquiryTransport(key)
108
- inquiryTransportFor(key | undefined) // throws InquiryUnavailable — never waits
105
+ inquiryTransportRegistry.register(key, transport) // seat on attach
106
+ inquiryTransportRegistry.release(key) // release when the channel goes away
107
+ inquiryTransportRegistry.has(key)
108
+ inquiryTransportRegistry.transportFor(key | undefined) // throws InquiryUnavailable — never waits
109
109
  ```
110
110
 
111
111
  Module-level and keyed by string, exactly like the delegate-transport and provider-plugin
112
112
  registries beside it: a process holds many at once, and an execution names the one its run belongs
113
- to. It is `inquiryTransportFor`, not `transportFor`, because `@owlmeans/llm` and
113
+ to. It is `inquiryTransportRegistry`, not a bare `transportRegistry`, because `@owlmeans/llm` and
114
114
  `@owlmeans/llm-delegate` are re-exported into one namespace by `@owlmeans/viable`.
115
115
 
116
116
  **A transport that cannot serve a question THROWS.** A declined answer is a decision; a channel that
117
117
  is gone is terminal, and the two must never look alike.
118
118
 
119
- `InquiryUnavailable` is registered fatal (`registerFatalError`) **beside the throw**, so no caller
119
+ `InquiryUnavailable` is registered fatal (`retryHelper.registerFatalError`) **beside the throw**, so no caller
120
120
  has to remember: every retry ladder aborts at once instead of spending itself on a channel nobody is
121
121
  behind. `InquiryDeclined` is deliberately NOT fatal — the run decides for itself and carries on.
122
122
 
@@ -148,8 +148,8 @@ is a tool the model tries once and remembers as broken.
148
148
 
149
149
  The body never throws, with exactly one exception: `InquiryUnavailable` is **rethrown**. No channel
150
150
  is an answerable situation (`{ error: 'Nobody can answer …' }`); a channel that WAS there and
151
- vanished is not. That escape only works if the agent passes `fatal: e => isFatalError(e) != null`
152
- into `safeInvokeTool` — **an agent installing this plugin must**, or the loop spends its whole turn
151
+ vanished is not. That escape only works if the agent passes `fatal: e => retryHelper.isFatalError(e) != null`
152
+ into `toolHelper.safeInvokeTool` — **an agent installing this plugin must**, or the loop spends its whole turn
153
153
  budget on a dead channel.
154
154
 
155
155
  ## Parking a pipeline: `Waiting`
@@ -157,7 +157,7 @@ budget on a dead channel.
157
157
  `PipelineRunContext.ask(inquiry)` has three outcomes, in order:
158
158
 
159
159
  1. An answer already in the state (a resume) is returned at once — a question is never asked twice.
160
- 2. A live channel answers: the answer is recorded in the state (`stateAnswerOf(capAnswer(...))`
160
+ 2. A live channel answers: the answer is recorded in the state (`inquiryHelper.stateAnswerOf(inquiryHelper.capAnswer(...))`
161
161
  under `state[INQUIRY_ANSWERS_KEY][inquiry.id]`) and the FULL answer is returned.
162
162
  3. Nobody is there: the run stops `Waiting` with the inquiry on its row, and the call never returns.
163
163
 
@@ -173,7 +173,7 @@ cannot park at all: it throws `PipelineNotResumableError`, because nothing would
173
173
  Answers are merged **by the runner**, in both `invoke` and `resume` (`resume(runId, { answers })`),
174
174
  never by a caller's mapping: the seed overwrites the restored state key by key, so a mapping that
175
175
  forwarded the answers map would wipe the child's own recorded answers. The merge applies the same
176
- `stateAnswerOf(capAnswer(...))` cut the live path does — a resume is how an answer usually arrives,
176
+ `inquiryHelper.stateAnswerOf(inquiryHelper.capAnswer(...))` cut the live path does — a resume is how an answer usually arrives,
177
177
  so a ceiling enforced on the live path alone is enforced where the least text comes in. Answers are
178
178
  also the one state key that ACCUMULATES, so `ctx.ask` re-reads the map at write time: steps with no
179
179
  edge between them run in one superstep, and a write built from a pre-await copy loses a sibling's
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/llm
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/llm": "^0.1.18-rc.43"` in `dependencies` (plus the `@langchain/*` peers)
11
+ **Install:** `"@owlmeans/llm": "^0.1.18-rc.45"` in `dependencies` (plus the `@langchain/*` peers)
12
12
 
13
13
  The inference runtime. Everything provider-specific is a **plugin**; the model itself only owns the
14
14
  provider-independent parts (streaming discipline, retries, validation, observability). Serializable
@@ -27,15 +27,15 @@ symbol "because a test needs it".
27
27
  | `makePromptService(options?, alias?)` · `appendPromptService(ctx, options?, alias?)` · `promptServiceApi(options, self)` | Skill registry + the composition plugin chain. Also at `@owlmeans/llm/prompt`. |
28
28
  | `rolePlugin`, `skillsPlugin`, `resultsPlugin`, `contextPlugin`, `BUILT_IN_PROMPT_PLUGINS` | The built-in composition plugins. |
29
29
  | `PromptContext.claim(key)` · `PromptComposeParams.utility` | Per-composition ownership of a key; a cheap model for one plugin-side call. |
30
- | `renderSkill`, `sortSkills`, `joinChunks`, `compareAlias`, `prefixHash` · `readCacheUsage`, `hasCacheActivity` | Deterministic rendering primitives — reuse them, never re-implement — and normalized prompt-cache accounting from a completion. |
31
- | `plugins`, `registerLlmPlugin`, `resolvePlugin`, `pluginOf`, `pluginFor` | The provider-plugin registry. Also at `@owlmeans/llm/plugins`. |
30
+ | `promptRenderHelper.{renderSkill, sortSkills, joinChunks, compareAlias, prefixHash}` · `cacheHelper.{readCacheUsage, hasCacheActivity}` | Deterministic rendering primitives — reuse them, never re-implement — and normalized prompt-cache accounting from a completion. |
31
+ | `llmPluginRegistry.{plugins, register, resolvePlugin, pluginOf, pluginFor}` | The provider-plugin registry. Also at `@owlmeans/llm/plugins`. |
32
32
  | `anthropicPlugin`, `openAiPlugin`, `compatiblePlugin`, `openAiFamily` | Built-in providers; `openAiFamily` is the shared OpenAI-client behaviour to spread into a new plugin. |
33
- | `NO_SAMPLING_PREFIXES` / `rejectsSampling(model)` · `RESPONSES_API_PREFIXES` / `usesResponsesApi(model)` | Which families reject which sampling parameters — see the table below. Consumers pin presets against them. |
34
- | `effortSupportOf(config)` · `OPENAI_EFFORT_SUPPORT`, `OPENAI_HIDDEN_PROPERTY_NAMES`, `ANTHROPIC_MODEL_SUPPORT` / `anthropicSupportOf(model)` · `REASONING_MIN_MAX_TOKENS` | Which `ModelConfig.effort` levels a model accepts, and the per-family Anthropic facts beside them — see "Fallback chains and provider effort". |
35
- | `ThinkingOff`, `thinkingOffFor(config)` · `rejectsForcedTool(model)` | The Anthropic off switch a config sends (`disabled`, `between_tools`, or none), and whether a model refuses a pinned `tool_choice`. |
36
- | `withRetry`, `registerFatalError`, `isFatalError`, `spectate`, `normalizeInput`, `parseJsonContent`, `coerceToSchema`, `resolveFallbacks`, `PROVIDER_NEUTRAL_FIELDS` | Helpers usable alongside a model. Also at `@owlmeans/llm/helpers`. |
33
+ | `NO_SAMPLING_PREFIXES` / `anthropicSupportHelper.rejectsSampling(model)` · `RESPONSES_API_PREFIXES` / `usesResponsesApi(model)` | Which families reject which sampling parameters — see the table below. Consumers pin presets against them. |
34
+ | `llmPluginRegistry.effortSupportOf(config)` · `OPENAI_EFFORT_SUPPORT`, `OPENAI_HIDDEN_PROPERTY_NAMES`, `ANTHROPIC_MODEL_SUPPORT` / `anthropicSupportHelper.anthropicSupportOf(model)` · `REASONING_MIN_MAX_TOKENS` | Which `ModelConfig.effort` levels a model accepts, and the per-family Anthropic facts beside them — see "Fallback chains and provider effort". |
35
+ | `ThinkingOff`, `anthropicSupportHelper.thinkingOffFor(config)` · `anthropicSupportHelper.rejectsForcedTool(model)` | The Anthropic off switch a config sends (`disabled`, `between_tools`, or none), and whether a model refuses a pinned `tool_choice`. |
36
+ | `retryHelper.{withRetry, registerFatalError, isFatalError}`, `spectate`, `normalizeInput`, `jsonHelper.{parseJsonContent, coerceToSchema}`, `resolveFallbacks`, `PROVIDER_NEUTRAL_FIELDS` | Helpers usable alongside a model. Also at `@owlmeans/llm/helpers`. |
37
37
  | `LlmError`, `LlmModelError`, `LlmMissconfiguredError`, `LlmPluginError`, `LlmRetryExceededError` | `ResilientError` family. `LlmModelError` is the RETRYABLE one. |
38
- | `mergePrompt`, `mergePolicy`, `resolveRole`, `effortPatch`, `freezeResults` | Execution merge helpers; `mergePrompt` unions skills and takes the deepest role; `freezeResults` deep-freezes a results view. |
38
+ | `executionPolicyHelper.{mergePrompt, mergePolicy, resolveRole, effortPatch}`, `executionStateHelper.freezeResults` | Execution merge helpers; `mergePrompt` unions skills and takes the deepest role; `freezeResults` deep-freezes a results view. |
39
39
  | `DEFAULT_MODEL_RETRIES`, `MODEL_STREAM_TIMEOUT_MS` (3 min idle), `FALLBACK_AFTER_ATTEMPTS`, `TEMPERATURE_PER_EFFORT_STEP`, `DEFAULT_EFFORT`, `EFFORT_TABLE`, `MAX_CACHE_BREAKPOINTS`, `MAX_SYSTEM_BREAKPOINTS`, `MIN_CACHEABLE_TOKENS`, `LLM_SERVICE`, `EXECUTION_SERVICE`, `PROMPT_SERVICE` | Tuning + aliases. |
40
40
 
41
41
  ## Provider differences are plugins, never `if`s
@@ -47,7 +47,7 @@ symbol "because a test needs it".
47
47
  | `build` | the provider switch in the model factory |
48
48
  | `owns` / `family` | `instanceof` checks; a `family` change between rungs re-renders the prompt |
49
49
  | `refine` | the per-provider retry rebuild (budget doubling, reasoning shrink, effort climb) |
50
- | `effort` | which `ModelConfig.effort` levels a model accepts (`effortSupportOf(config)`) |
50
+ | `effort` | which `ModelConfig.effort` levels a model accepts (`llmPluginRegistry.effortSupportOf(config)`) |
51
51
  | `structuredMode` | native `response_format` vs a structured-output tool call |
52
52
  | `toolChoice(toolName, config)` / `responseFormat` | the provider-specific call shapes; `config` is the ACTIVE rung's, so a model that refuses a pinned tool gets the automatic choice |
53
53
  | `pinsTool(config)` / `strictTool(config, schema)` | whether `toolChoice` pins the tool (when not, `prepare` appends `toolCallInstruction`), and whether the tool goes `strict` |
@@ -69,7 +69,7 @@ hooks, through a predicate the package root exports:
69
69
 
70
70
  | Family | Rejects | Predicate |
71
71
  |---|---|---|
72
- | Claude 4.7+ and the 5 family | `temperature`, `top_p`, `top_k` | `NO_SAMPLING_PREFIXES` / `rejectsSampling(model)` |
72
+ | Claude 4.7+ and the 5 family | `temperature`, `top_p`, `top_k` | `NO_SAMPLING_PREFIXES` / `anthropicSupportHelper.rejectsSampling(model)` |
73
73
  | OpenAI Responses API (`gpt-6*`, `gpt-5*`, `codex-*`) | `temperature`, `top_p` | `RESPONSES_API_PREFIXES` / `usesResponsesApi(model)` |
74
74
 
75
75
  A new OpenAI family goes into `RESPONSES_API_PREFIXES` the day it is pinned: outside it the model
@@ -82,7 +82,7 @@ primary's. Keep the predicate exported: consumers
82
82
  pin presets against it (viable-agent's `tests/presets.test.ts` asserts no preset entry declares a
83
83
  parameter its model rejects), and a second hand-written copy drifts when a family is added.
84
84
 
85
- **Registration order is load-bearing.** Instance lookup (`pluginFor`) returns the FIRST plugin whose
85
+ **Registration order is load-bearing.** Instance lookup (`llmPluginRegistry.pluginFor`) returns the FIRST plugin whose
86
86
  `owns` matches, and `compatible` is registered before `openai` because both build a `ChatOpenAI`:
87
87
  assuming the tool-calling hack for an unlabelled model is safe everywhere, assuming native
88
88
  JSON-schema support is not.
@@ -94,7 +94,7 @@ composes them into an ordered, cacheable system message; a caller's own leading
94
94
  folded into the volatile `Context` block, so an unmigrated call site still works. **Do not build a
95
95
  persona as a `SystemMessage` in a helper** — declare it as `PromptPolicy.role` plus registered
96
96
  skills, or the knowledge duplicates and the cache prefix stops being stable. Skills accumulate down
97
- the execution chain (project → task → helper) and the deepest declared `role` wins (`mergePrompt`).
97
+ the execution chain (project → task → helper) and the deepest declared `role` wins (`executionPolicyHelper.mergePrompt`).
98
98
  Block order, the breakpoint budget, the provider facts behind them, and the plugin seams
99
99
  `claim(key)` / `utility`: [[llm-prompt-caching]].
100
100
 
@@ -177,7 +177,7 @@ look retryable — costing the whole retry budget with the real message buried u
177
177
  (`ContextOverflowError` for an input past the context window, and its siblings) carrying the
178
178
  original **only under `cause`**, no `status` of its own — so `e.status === 400` misses it.
179
179
 
180
- Use `isBadRequest` from `plugins/utils.ts`: it walks the `cause` chain for `status === 400`, bounded
180
+ Use `pluginUtils.isBadRequest` from `plugins/utils.ts`: it walks the `cause` chain for `status === 400`, bounded
181
181
  in depth so a self-referential chain terminates. Both built-in `isFatal` implementations go through
182
182
  it. A context overflow makes this urgent: `refine` escalates the **output** budget on each retry, so
183
183
  an over-limit **input** can never improve — every attempt re-sends the identical oversized request,
@@ -216,13 +216,13 @@ model switch depends on preset data rather than code: the role must declare a `f
216
216
  in the other direction — a per-call resolver consulted before the global ones and the plugin's
217
217
  `isFatal`, for an error the caller knows no retry can fix.
218
218
 
219
- ### A loop ABOVE the model asks the same question with `isFatalError`
219
+ ### A loop ABOVE the model asks the same question with `retryHelper.isFatalError`
220
220
 
221
221
  A retry loop is not the only place that decides to carry on: a fix ladder rescues a failed repair and
222
222
  climbs to a stronger model, an agent runner catches a round that threw and reports "gave up". Both
223
223
  are right for a model that answered badly and wrong for a budget that ran out, and a blanket `catch`
224
224
  cannot tell them apart — an exhausted balance becomes more expensive calls instead of a halt.
225
- `isFatalError(e, fatal?)` runs the same resolvers, in the same order, that `withRetry` uses, and
225
+ `retryHelper.isFatalError(e, fatal?)` runs the same resolvers, in the same order, that `retryHelper.withRetry` uses, and
226
226
  returns the error to abort WITH (a resolver may unwrap a carrier and hand back the real cause) or
227
227
  `null` when nothing considers it terminal. Ask it rather than re-deriving the rule.
228
228
 
@@ -237,7 +237,7 @@ Four fields, and conflating them turns an escalation into a fatal 400 hours into
237
237
  | `maxOutput` | what the PROVIDER accepts in one request — a fact about the model |
238
238
  | `contextWindow` | total window (input + output); informational, never sent |
239
239
 
240
- `resolveOutputCap` (`utils/config.ts`) reconciles them: the declared cap chooses the ceiling and the
240
+ `configUtils.resolveOutputCap` (`utils/config.ts`) reconciles them: the declared cap chooses the ceiling and the
241
241
  capability trims it, and `DEFAULT_MAX_OUTPUT_CAP` applies only when neither is stated. `createModel`
242
242
  also clamps `maxTokens` to `maxOutput` and warns about a cap above it. For an aggregated model
243
243
  `maxOutput` is the limit of the `inferenceProvider` actually pinned, often far below what the model
@@ -301,14 +301,14 @@ lives — never an inline check on one id:
301
301
  | Sonnet 5, Opus 4.8/4.7 | `disabled` | all | accepted | 1024 |
302
302
  | Older models (Haiku 4.5, Sonnet 4.6, …) | none — they reason only when asked | per the effort table | accepted | 1024 |
303
303
 
304
- `thinkingOffFor(config)` is the value `build` sends; `refine` carries it through `lc_kwargs` and
304
+ `anthropicSupportHelper.thinkingOffFor(config)` is the value `build` sends; `refine` carries it through `lc_kwargs` and
305
305
  reads it back to keep the ceiling, so a climbed retry stops at `high` instead of answering 400. The
306
306
  cache minimum is the default under a preset's own `cacheMinTokens`.
307
307
 
308
- **Structured output on a model that refuses a pinned tool** (`rejectsForcedTool`): `toolChoice`
308
+ **Structured output on a model that refuses a pinned tool** (`anthropicSupportHelper.rejectsForcedTool`): `toolChoice`
309
309
  answers `{ type: 'auto' }`, `pinsTool` answers `false`, and `prepare` appends
310
310
  `toolCallInstruction(toolName)` to the per-call payload after the JSON mention — the prompt is all
311
- that asks for the call. The tool goes `strict: true` only when `isStrictSchema(schema)` (every object
311
+ that asks for the call. The tool goes `strict: true` only when `schemaUtils.isStrictSchema(schema)` (every object
312
312
  closed with `additionalProperties: false`, basic types, scalar `enum`/`const`, `anyOf`/`allOf`, the
313
313
  listed formats, `minItems` 0/1; no `$ref`, no length/pattern/numeric constraints, no `nullable`): a
314
314
  strict schema outside that subset is a 400 no retry fixes, while a non-strict one is still checked by
@@ -326,7 +326,7 @@ family, not Opus 4.8/4.7); the wire is unchanged.
326
326
  **Effort climbs on retries, one level per attempt of the rung** (`LlmRefineParams.rungAttempt`), from
327
327
  the rung's declared level — or its model's default once it has retried — to the model's ceiling. So
328
328
  each fallback starts from its OWN level. A `TemperatureFactory` request climbs it too
329
- (`temperatureSteps`: one level per `TEMPERATURE_PER_EFFORT_STEP` = 0.3, at least one), because the
329
+ (`effortUtils.temperatureSteps`: one level per `TEMPERATURE_PER_EFFORT_STEP` = 0.3, at least one), because the
330
330
  models that take effort have mostly taken sampling away and "hotter" alone changes nothing on the
331
331
  wire. Effort is part of Anthropic's cached prefix, so a climbed retry writes a new cache entry.
332
332
  At `high` and above the OpenAI plugin floors the output budget at `REASONING_MIN_MAX_TOKENS` (25k,
@@ -361,7 +361,7 @@ JSON pointer (only keys of a `properties` map — a keyword in keyword position
361
361
  fatal to every retry loop. Function calling (`structuredOutput: false`) and Anthropic's tool mode
362
362
  keep every name and are not refused. Rename the field (`mandatory` for `required`). `strict: true`
363
363
  is not sent to OpenAI: its strict mode also demands every property in `required`, which
364
- `isStrictSchema` (Anthropic's subset) does not check.
364
+ `schemaUtils.isStrictSchema` (Anthropic's subset) does not check.
365
365
 
366
366
  ### Reasoning is off unless a preset asks for it — and it is billed against the same budget
367
367
 
@@ -378,7 +378,7 @@ the idle deadline reads as a dead connection and retries from scratch
378
378
  `makeLlmModel` appends the literal `/no_think` to every request's prepared messages whenever the flag
379
379
  is set AND the plugin's `suppressesThinking(config)` does not answer `true` — the soft switch for
380
380
  models with no request-level control (Qwen3). The Anthropic plugin answers `true` only for
381
- `rejectsSampling(model)`, and for those puts the family's off switch (`thinkingOffFor`, the table
381
+ `anthropicSupportHelper.rejectsSampling(model)`, and for those puts the family's off switch (`anthropicSupportHelper.thinkingOffFor`, the table
382
382
  above) on the request in `build`, which `refine` carries through `lc_kwargs` on every attempt — on a
383
383
  model that always thinks nothing is sent and the flag only keeps the directive out. Below that line
384
384
  (`claude-haiku-4-5`, `claude-sonnet-4-6`) and under any plugin declaring no hook the flag injects
@@ -388,9 +388,9 @@ switches TO Anthropic inherits nothing and must name it (viable-agent's `presets
388
388
  rung). Turning reasoning ON is a per-role decision.
389
389
 
390
390
  `ADAPTIVE_MIN_MAX_TOKENS` (32k) is the output floor the Anthropic plugin's `build` applies to every
391
- `rejectsSampling(model)` config — `disableThinking` is not consulted, so a role with reasoning turned
391
+ `anthropicSupportHelper.rejectsSampling(model)` config — `disableThinking` is not consulted, so a role with reasoning turned
392
392
  off is floored just the same. It is a floor, not an override (a preset asking for more keeps it) and
393
- it is clamped through `resolveOutputCap`, so it can never exceed what the provider accepts and turn a
393
+ it is clamped through `configUtils.resolveOutputCap`, so it can never exceed what the provider accepts and turn a
394
394
  retryable empty answer into a fatal 400. Raising or removing it re-opens empty completions.
395
395
 
396
396
  Two diagnostics the above depends on:
@@ -34,7 +34,7 @@ its text simply travels a different route.
34
34
  ## Rules
35
35
 
36
36
  - **Order is the cache key.** `PROMPT_BLOCK_ORDER` is declared explicitly, skills sort by
37
- `(order, alias)` with a code-unit comparison (`compareAlias`, never `localeCompare` —
37
+ `(order, alias)` with a code-unit comparison (`promptRenderHelper.compareAlias`, never `localeCompare` —
38
38
  ICU data differs between hosts), and detected packages sort alphabetically.
39
39
  - **Skill bodies are pure constants.** No timestamps, no absolute paths, no interpolated
40
40
  request data. One varying byte invalidates the prefix for every call that shares it.
@@ -59,10 +59,10 @@ its text simply travels a different route.
59
59
  may spend at most `MAX_SYSTEM_BREAKPOINTS` (2) — its only STABLE boundaries are the end
60
60
  of role+skills and the end of packages — which always leaves two for the messages.
61
61
  - **The last message is never cached.** `patchCache` stops one short of the end: the final
62
- message is the per-call payload, and `ensureJsonMention` / `applyNoThink` append to it.
62
+ message is the per-call payload, and `promptUtils.ensureJsonMention` / `.applyNoThink` append to it.
63
63
  - **Markers are placed in-place, on the caller's objects.** A caller that carries its
64
64
  message array across calls (a coder's growing conversation, a fix loop) hands them back
65
- still marked, and they accumulate. `prepare()` therefore calls `stripCacheMarkers()`
65
+ still marked, and they accumulate. `prepare()` therefore calls `promptUtils.stripCacheMarkers()`
66
66
  first, so the per-request count depends on THIS call alone. Anything that places a
67
67
  marker outside that pipeline must do the same.
68
68
  - **A short prefix is not marked.** Below `MIN_CACHEABLE_TOKENS` (override per alias with
@@ -75,7 +75,7 @@ its text simply travels a different route.
75
75
  > logs for `Prompt cache [` lines and a non-zero `read`.
76
76
 
77
77
 
78
- `usage_metadata.input_token_details` is the only honest answer. `readCacheUsage(message)`
78
+ `usage_metadata.input_token_details` is the only honest answer. `cacheHelper.readCacheUsage(message)`
79
79
  (`@owlmeans/llm/helpers`) normalizes it; `spectate` logs a line whenever a provider reports
80
80
  any cache activity. **If `read` stays 0 across repeated calls that share a prefix, something
81
81
  is invalidating it** — diff `PromptResult.blocks` between two calls to find what.
package/build/consts.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { ExecutionEffort } from '@owlmeans/llm-common';
2
- import type { CacheTtl, ModelConfigPatch } from '@owlmeans/llm-common';
1
+ import { ExecutionEffort, type CacheTtl, type ModelConfigPatch } from '@owlmeans/llm-common';
3
2
  /** Context-service alias for the {@link LlmService} (model factory / registry). */
4
3
  export declare const LLM_SERVICE = "owlmeans-llm-service";
5
4
  /** Context-service alias for the {@link ExecutionService}. */
@@ -84,12 +83,6 @@ export declare const JSON_INSTRUCTION: string;
84
83
  * whole output budget on thinking and return empty content with `finish_reason="length"`.
85
84
  */
86
85
  export declare const NO_THINK_DIRECTIVE = "/no_think";
87
- /**
88
- * Appended to the prompt of `invoke`/`request` on a model that refuses a pinned tool: with
89
- * `tool_choice: auto` the instruction is what asks for the call. Generic on purpose — it names
90
- * only the tool.
91
- */
92
- export declare const toolCallInstruction: (toolName: string) => string;
93
86
  /** Tool name used for structured output when a schema carries no usable title/name. */
94
87
  export declare const DEFAULT_TOOL_NAME = "extract";
95
88
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAEtE,mFAAmF;AACnF,eAAO,MAAM,WAAW,yBAAyB,CAAA;AAEjD,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,mCAAmC,CAAA;AAEjE,0FAA0F;AAC1F,eAAO,MAAM,cAAc,gCAAgC,CAAA;AAE3D,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,QAAgB,CAAA;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAA;AAE9C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,QAAY,CAAA;AAE/C,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAEvC,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,EAAE,QAAe,CAAA;AAE/C;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAA;AAExC;;;;GAIG;AACH,eAAO,MAAM,eAAe,IAAI,CAAA;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAGkD,CAAA;AAE/E;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,cAAc,CAAA;AAE7C;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,aAAc,MAAM,KAAG,MACoD,CAAA;AAE3G,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,YAAY,CAAA;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAY,CAAA;AAE3C,8DAA8D;AAC9D,eAAO,MAAM,cAAc,2BAA2B,CAAA;AAEtD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAKlE,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAErC,CAAA"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAE5F,mFAAmF;AACnF,eAAO,MAAM,WAAW,yBAAyB,CAAA;AAEjD,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,mCAAmC,CAAA;AAEjE,0FAA0F;AAC1F,eAAO,MAAM,cAAc,gCAAgC,CAAA;AAE3D,6EAA6E;AAC7E,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,uBAAuB,QAAgB,CAAA;AAEpD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAA;AAE9C;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,QAAY,CAAA;AAE/C,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,IAAI,CAAA;AAEtC;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAEvC,kFAAkF;AAClF,eAAO,MAAM,iBAAiB,EAAE,QAAe,CAAA;AAE/C;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAA;AAExC;;;;GAIG;AACH,eAAO,MAAM,eAAe,IAAI,CAAA;AAEhC;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,QAGkD,CAAA;AAE/E;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,cAAc,CAAA;AAE7C,uFAAuF;AACvF,eAAO,MAAM,iBAAiB,YAAY,CAAA;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,YAAY,CAAA;AAE3C,8DAA8D;AAC9D,eAAO,MAAM,cAAc,2BAA2B,CAAA;AAEtD;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAKlE,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,EAErC,CAAA"}
package/build/consts.js CHANGED
@@ -86,12 +86,6 @@ export const JSON_INSTRUCTION = 'Respond with a single complete and valid JSON o
86
86
  * whole output budget on thinking and return empty content with `finish_reason="length"`.
87
87
  */
88
88
  export const NO_THINK_DIRECTIVE = '/no_think';
89
- /**
90
- * Appended to the prompt of `invoke`/`request` on a model that refuses a pinned tool: with
91
- * `tool_choice: auto` the instruction is what asks for the call. Generic on purpose — it names
92
- * only the tool.
93
- */
94
- export const toolCallInstruction = (toolName) => `Answer by calling the tool \`${toolName}\` with the complete result as its input. Do not reply in text.`;
95
89
  /** Tool name used for structured output when a schema carries no usable title/name. */
96
90
  export const DEFAULT_TOOL_NAME = 'extract';
97
91
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAGtD,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAG,sBAAsB,CAAA;AAEjD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,gCAAgC,CAAA;AAEjE,0FAA0F;AAC1F,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAA;AAE3D,6EAA6E;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAEtC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;AAEpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAA;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,KAAK,CAAA;AAE/C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAA;AAEvC,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAa,IAAI,CAAA;AAE/C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAA;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAA;AAEhC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,6DAA6D;MACzF,gHAAgH;MAChH,iGAAiG;MACjG,2EAA2E,CAAA;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAA;AAE7C;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAgB,EAAU,EAAE,CAC9D,gCAAgC,QAAQ,iEAAiE,CAAA;AAE3G,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAA;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAA;AAE3C,8DAA8D;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC,QAAQ,CAAA;AAEtD;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAA8C;IACrE,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE;IAClD,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,EAAE;IAC9B,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE;IACjE,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE;CACjE,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAa;IACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS;CACrF,CAAA"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAwC,MAAM,sBAAsB,CAAA;AAE5F,mFAAmF;AACnF,MAAM,CAAC,MAAM,WAAW,GAAG,sBAAsB,CAAA;AAEjD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,gCAAgC,CAAA;AAEjE,0FAA0F;AAC1F,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAA;AAE3D,6EAA6E;AAC7E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAEtC;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;AAEpD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAA;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,KAAK,CAAA;AAE/C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAA;AAEtC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAA;AAEvC,kFAAkF;AAClF,MAAM,CAAC,MAAM,iBAAiB,GAAa,IAAI,CAAA;AAE/C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAA;AAExC;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAA;AAEhC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,6DAA6D;MACzF,gHAAgH;MAChH,iGAAiG;MACjG,2EAA2E,CAAA;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAA;AAE7C,uFAAuF;AACvF,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAA;AAE1C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAA;AAE3C,8DAA8D;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,eAAe,CAAC,QAAQ,CAAA;AAEtD;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAA8C;IACrE,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE;IAClD,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,EAAE;IAC9B,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE;IACjE,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE;CACjE,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAa;IACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS;CACrF,CAAA"}
@@ -1,4 +1,8 @@
1
1
  export type * from './types.js';
2
+ export type * from './policy/types.js';
3
+ export type * from './state/types.js';
4
+ export * from './policy.js';
5
+ export * from './state.js';
2
6
  export * from './utils.js';
3
7
  export * from './service.js';
4
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/execution/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/execution/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,mBAAmB,mBAAmB,CAAA;AACtC,mBAAmB,kBAAkB,CAAA;AACrC,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA"}
@@ -1,3 +1,5 @@
1
+ export * from './policy.js';
2
+ export * from './state.js';
1
3
  export * from './utils.js';
2
4
  export * from './service.js';
3
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/execution/index.ts"],"names":[],"mappings":"AAEA,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/execution/index.ts"],"names":[],"mappings":"AAIA,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA"}
@@ -0,0 +1,34 @@
1
+ import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
2
+ import type { ExecutionEffort, ModelConfigOverride, ModelConfigPatch, ModelEffort, ModelPolicy, ModelRole, PromptPolicy } from '@owlmeans/llm-common';
3
+ /** How an execution's model policy and prompt policy are layered and resolved. */
4
+ export interface ExecutionPolicyHelper {
5
+ /** Overlay a partial policy onto a base one. Override maps are merged, not replaced. */
6
+ mergePolicy: (base: ModelPolicy, patch: Partial<ModelPolicy>) => ModelPolicy;
7
+ /**
8
+ * Overlay a prompt policy onto the one inherited from the parent level.
9
+ *
10
+ * Skills ACCUMULATE — a task adds to what the project declared, a helper adds to the
11
+ * task — because that is how a capability set is built up as work narrows. The role is
12
+ * replaced instead: the deepest level that names one owns the persona.
13
+ *
14
+ * The union preserves first-seen order and de-duplicates, so the composed prompt is
15
+ * byte-identical no matter how many levels contributed the same skill.
16
+ */
17
+ mergePrompt: (base: PromptPolicy | undefined, patch: PromptPolicy | undefined) => PromptPolicy | undefined;
18
+ /** Apply the policy's role→role remap. */
19
+ resolveRole: (policy: ModelPolicy, role: ModelRole) => ModelRole;
20
+ effortPatch: (effort: ExecutionEffort) => ModelConfigPatch;
21
+ /**
22
+ * The effort `steps` levels above what `model` was built with (its model's default when it
23
+ * declares none), or `undefined` when that model accepts no effort.
24
+ */
25
+ raisedEffort: (model: BaseChatModel, steps: number) => ModelEffort | undefined;
26
+ /** Normalize a {@link ModelConfigOverride} (alias or patch) to a patch. */
27
+ resolveModelConfig: (override: ModelConfigOverride) => ModelConfigPatch;
28
+ /**
29
+ * Merge effort < policy.modelOverride < call-site override into a single patch.
30
+ * Any field present in a higher-precedence source wins.
31
+ */
32
+ mergeOverride: (effortBase: ModelConfigPatch, policyOverride: ModelConfigOverride | undefined, callOverride: ModelConfigOverride | undefined) => ModelConfigPatch;
33
+ }
34
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/execution/policy/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAA;AAChF,OAAO,KAAK,EACV,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAC1G,MAAM,sBAAsB,CAAA;AAE7B,kFAAkF;AAClF,MAAM,WAAW,qBAAqB;IACpC,wFAAwF;IACxF,WAAW,EAAE,CAAC,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,WAAW,CAAA;IAC5E;;;;;;;;;OASG;IACH,WAAW,EAAE,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY,GAAG,SAAS,KAAK,YAAY,GAAG,SAAS,CAAA;IAC1G,0CAA0C;IAC1C,WAAW,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,KAAK,SAAS,CAAA;IAChE,WAAW,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,gBAAgB,CAAA;IAC1D;;;OAGG;IACH,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAA;IAC9E,2EAA2E;IAC3E,kBAAkB,EAAE,CAAC,QAAQ,EAAE,mBAAmB,KAAK,gBAAgB,CAAA;IACvE;;;OAGG;IACH,aAAa,EAAE,CACb,UAAU,EAAE,gBAAgB,EAC5B,cAAc,EAAE,mBAAmB,GAAG,SAAS,EAC/C,YAAY,EAAE,mBAAmB,GAAG,SAAS,KAC1C,gBAAgB,CAAA;CACtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/execution/policy/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { ExecutionPolicyHelper } from './policy/types.js';
2
+ export declare const createExecutionPolicyHelper: () => ExecutionPolicyHelper;
3
+ export declare const executionPolicyHelper: ExecutionPolicyHelper;
4
+ //# sourceMappingURL=policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/execution/policy.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAE9D,eAAO,MAAM,2BAA2B,QAAO,qBA4D9C,CAAA;AAED,eAAO,MAAM,qBAAqB,uBAAgC,CAAA"}
@@ -0,0 +1,49 @@
1
+ import { EFFORT_TABLE } from '../consts.js';
2
+ import { llmPluginRegistry } from '../plugins/registry.js';
3
+ import { configUtils } from '../utils/config.js';
4
+ import { effortUtils } from '../utils/effort.js';
5
+ export const createExecutionPolicyHelper = () => {
6
+ const mergePolicy = (base, patch) => {
7
+ const utilityRole = patch.utilityRole ?? base.utilityRole;
8
+ return {
9
+ effort: patch.effort ?? base.effort,
10
+ roleOverrides: patch.roleOverrides != null || base.roleOverrides != null
11
+ ? { ...base.roleOverrides, ...patch.roleOverrides }
12
+ : undefined,
13
+ modelOverrides: patch.modelOverrides != null || base.modelOverrides != null
14
+ ? { ...base.modelOverrides, ...patch.modelOverrides }
15
+ : undefined,
16
+ // Added only when it exists, unlike the maps above: a project that never names a
17
+ // cheap tier must not gain a `utilityRole` key it would then carry into every snapshot.
18
+ ...(utilityRole != null ? { utilityRole } : {}),
19
+ };
20
+ };
21
+ const mergePrompt = (base, patch) => {
22
+ if (base == null && patch == null) {
23
+ return undefined;
24
+ }
25
+ const skills = [...new Set([...(base?.skills ?? []), ...(patch?.skills ?? [])])];
26
+ return {
27
+ ...base,
28
+ ...patch,
29
+ ...(base?.role != null || patch?.role != null ? { role: patch?.role ?? base?.role } : {}),
30
+ ...(skills.length > 0 ? { skills } : {}),
31
+ };
32
+ };
33
+ const resolveRole = (policy, role) => policy.roleOverrides?.[role] ?? role;
34
+ const effortPatch = (effort) => EFFORT_TABLE[effort];
35
+ const raisedEffort = (model, steps) => {
36
+ const config = configUtils.readConfig(model);
37
+ const support = llmPluginRegistry.effortSupportOf(config);
38
+ return support != null ? effortUtils.raiseEffort(support, config.effort, steps) : undefined;
39
+ };
40
+ const resolveModelConfig = (override) => typeof override === 'string' ? { preset: override } : override;
41
+ const mergeOverride = (effortBase, policyOverride, callOverride) => {
42
+ const policy = policyOverride != null ? resolveModelConfig(policyOverride) : {};
43
+ const call = callOverride != null ? resolveModelConfig(callOverride) : {};
44
+ return { ...effortBase, ...policy, ...call };
45
+ };
46
+ return { mergePolicy, mergePrompt, resolveRole, effortPatch, raisedEffort, resolveModelConfig, mergeOverride };
47
+ };
48
+ export const executionPolicyHelper = createExecutionPolicyHelper();
49
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/execution/policy.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGhD,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAA0B,EAAE;IACrE,MAAM,WAAW,GAAG,CAAC,IAAiB,EAAE,KAA2B,EAAe,EAAE;QAClF,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,WAAW,CAAA;QAEzD,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;YACnC,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI;gBACtE,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,GAAG,KAAK,CAAC,aAAa,EAAE;gBACnD,CAAC,CAAC,SAAS;YACb,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,IAAI,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI;gBACzE,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,cAAc,EAAE,GAAG,KAAK,CAAC,cAAc,EAAE;gBACrD,CAAC,CAAC,SAAS;YACb,iFAAiF;YACjF,wFAAwF;YACxF,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAA;IACH,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAClB,IAA8B,EAC9B,KAA+B,EACL,EAAE;QAC5B,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClC,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAEhF,OAAO;YACL,GAAG,IAAI;YACP,GAAG,KAAK;YACR,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzF,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzC,CAAA;IACH,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,CAAC,MAAmB,EAAE,IAAe,EAAa,EAAE,CACrE,MAAM,CAAC,aAAa,EAAE,CAAC,IAAI,CAA2B,IAAI,IAAI,CAAA;IAEjE,MAAM,WAAW,GAAG,CAAC,MAAuB,EAAoB,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAA;IAEvF,MAAM,YAAY,GAAG,CAAC,KAAoB,EAAE,KAAa,EAA2B,EAAE;QACpF,MAAM,MAAM,GAAG,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;QAC5C,MAAM,OAAO,GAAG,iBAAiB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;QACzD,OAAO,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC7F,CAAC,CAAA;IAED,MAAM,kBAAkB,GAAG,CAAC,QAA6B,EAAoB,EAAE,CAC7E,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAA;IAEhE,MAAM,aAAa,GAAG,CACpB,UAA4B,EAC5B,cAA+C,EAC/C,YAA6C,EAC3B,EAAE;QACpB,MAAM,MAAM,GAAG,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAC/E,MAAM,IAAI,GAAG,YAAY,IAAI,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QACzE,OAAO,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,EAAE,GAAG,IAAI,EAAE,CAAA;IAC9C,CAAC,CAAA;IAED,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,kBAAkB,EAAE,aAAa,EAAE,CAAA;AAChH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,2BAA2B,EAAE,CAAA"}
@@ -1,4 +1,4 @@
1
- import type { BasicConfig, BasicContext } from '@owlmeans/context';
1
+ import { type BasicConfig, type BasicContext } from '@owlmeans/context';
2
2
  import type { ExecutionService, ExecutionServiceOptions, ExecutionShape, WithExecutionService } from './types.js';
3
3
  /**
4
4
  * Build the execution service implementation WITHOUT registering it as a context
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/execution/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAYlE,OAAO,KAAK,EACkB,gBAAgB,EAAE,uBAAuB,EAAE,cAAc,EACrD,oBAAoB,EACrD,MAAM,YAAY,CAAA;AASnB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,cAAc,GAAG,cAAc,WAClE,uBAAuB,QAC1B,MAAM,gBAAgB,CAAC,CAAC,CAAC,KAC9B,gBAAgB,CAAC,CAAC,CAoMpB,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,cAAc,GAAG,cAAc,UACrE,MAAM,YACJ,uBAAuB,KAC/B,gBAAgB,CAAC,CAAC,CAMpB,CAAA;AAED,eAAO,MAAM,sBAAsB,GACjC,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,cAAc,GAAG,cAAc,OAEtF,CAAC,UACC,MAAM,YACJ,uBAAuB,KAC/B,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAQ5B,CAAA"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/execution/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAOtF,OAAO,KAAK,EACkB,gBAAgB,EAAE,uBAAuB,EAAE,cAAc,EACrD,oBAAoB,EACrD,MAAM,YAAY,CAAA;AAOnB;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,cAAc,GAAG,cAAc,WAClE,uBAAuB,QAC1B,MAAM,gBAAgB,CAAC,CAAC,CAAC,KAC9B,gBAAgB,CAAC,CAAC,CAoMpB,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,cAAc,GAAG,cAAc,UACrE,MAAM,YACJ,uBAAuB,KAC/B,gBAAgB,CAAC,CAAC,CAMpB,CAAA;AAED,eAAO,MAAM,sBAAsB,GACjC,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,cAAc,GAAG,cAAc,OAEtF,CAAC,UACC,MAAM,YACJ,uBAAuB,KAC/B,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAQ5B,CAAA"}