@yanlinglabs/winter-agent-runtime 0.0.27

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 (311) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE +41 -0
  3. package/README.md +64 -0
  4. package/dist/checkpoint/file-history.d.ts +81 -0
  5. package/dist/checkpoint/rewind.d.ts +55 -0
  6. package/dist/checkpoint/seam.d.ts +47 -0
  7. package/dist/checkpoint/sink.d.ts +66 -0
  8. package/dist/commands/builtins-listing.d.ts +40 -0
  9. package/dist/commands/resolver.d.ts +103 -0
  10. package/dist/commands/seam.d.ts +53 -0
  11. package/dist/compaction/controller.d.ts +23 -0
  12. package/dist/compaction/retention.d.ts +35 -0
  13. package/dist/compaction/seam.d.ts +115 -0
  14. package/dist/compaction/summarizer.d.ts +79 -0
  15. package/dist/context/agent-listing.d.ts +39 -0
  16. package/dist/context/assembler.d.ts +46 -0
  17. package/dist/context/attachments.d.ts +104 -0
  18. package/dist/context/dynamic-sections.d.ts +31 -0
  19. package/dist/context/git-fixture.d.ts +18 -0
  20. package/dist/context/git-status.d.ts +16 -0
  21. package/dist/context/imports.d.ts +22 -0
  22. package/dist/context/injection.d.ts +53 -0
  23. package/dist/context/memory-key.d.ts +46 -0
  24. package/dist/context/memory.d.ts +28 -0
  25. package/dist/context/minimal-prompt.d.ts +5 -0
  26. package/dist/context/output-styles.d.ts +68 -0
  27. package/dist/context/plan-mode.d.ts +29 -0
  28. package/dist/context/request-layout.d.ts +138 -0
  29. package/dist/context/rules.d.ts +63 -0
  30. package/dist/context/seam.d.ts +136 -0
  31. package/dist/context/tool-epoch.d.ts +118 -0
  32. package/dist/context/winter-code-preset.d.ts +39 -0
  33. package/dist/context/winter-md.d.ts +81 -0
  34. package/dist/embedded-host.d.ts +48 -0
  35. package/dist/embedded-host.js +155 -0
  36. package/dist/embedded-protocol.d.ts +44 -0
  37. package/dist/embedded-worker.d.ts +1 -0
  38. package/dist/embedded-worker.js +74 -0
  39. package/dist/embedded.d.ts +34 -0
  40. package/dist/embedded.js +9 -0
  41. package/dist/engine.d.ts +1298 -0
  42. package/dist/hooks/additional-context.d.ts +21 -0
  43. package/dist/hooks/bounds.d.ts +6 -0
  44. package/dist/hooks/bridge-invoker.d.ts +3 -0
  45. package/dist/hooks/command-invoker.d.ts +52 -0
  46. package/dist/hooks/from-config.d.ts +31 -0
  47. package/dist/hooks/hook-stage.d.ts +25 -0
  48. package/dist/hooks/input-validator.d.ts +6 -0
  49. package/dist/hooks/reducer.d.ts +74 -0
  50. package/dist/hooks/registry.d.ts +33 -0
  51. package/dist/hooks/runner.d.ts +105 -0
  52. package/dist/index-584yahed.js +6037 -0
  53. package/dist/index-97t2rmtf.js +42 -0
  54. package/dist/index-9qgkpv56.js +27183 -0
  55. package/dist/index-bef62z3r.js +437 -0
  56. package/dist/index-rkhh0457.js +187 -0
  57. package/dist/index.d.ts +37 -0
  58. package/dist/index.js +353 -0
  59. package/dist/main.d.ts +1 -0
  60. package/dist/mcp/client.d.ts +105 -0
  61. package/dist/mcp/control-seam.d.ts +25 -0
  62. package/dist/mcp/control.d.ts +5 -0
  63. package/dist/mcp/elicitation.d.ts +35 -0
  64. package/dist/mcp/env.d.ts +12 -0
  65. package/dist/mcp/lifecycle.d.ts +142 -0
  66. package/dist/mcp/output-cap.d.ts +15 -0
  67. package/dist/mcp/state.d.ts +24 -0
  68. package/dist/mcp/test-fixtures.d.ts +88 -0
  69. package/dist/mcp/transports/__fixtures__/stdio-server.d.ts +1 -0
  70. package/dist/mcp/transports/http.d.ts +5 -0
  71. package/dist/mcp/transports/sdk.d.ts +5 -0
  72. package/dist/mcp/transports/sse.d.ts +3 -0
  73. package/dist/mcp/transports/stdio.d.ts +35 -0
  74. package/dist/mcp/winter-server.d.ts +2 -0
  75. package/dist/messaging/reference-adapter.d.ts +88 -0
  76. package/dist/messaging/router.d.ts +8 -0
  77. package/dist/paths/project-dir-name.d.ts +2 -0
  78. package/dist/paths/temp.d.ts +25 -0
  79. package/dist/permissions/approvals.d.ts +107 -0
  80. package/dist/permissions/auto/caches.d.ts +53 -0
  81. package/dist/permissions/auto/config.d.ts +37 -0
  82. package/dist/permissions/auto/engine.d.ts +74 -0
  83. package/dist/permissions/auto/envelope.d.ts +45 -0
  84. package/dist/permissions/auto/inheritance.d.ts +27 -0
  85. package/dist/permissions/edit-recognition.d.ts +30 -0
  86. package/dist/permissions/evaluator.d.ts +284 -0
  87. package/dist/permissions/file-rules.d.ts +384 -0
  88. package/dist/permissions/grammar.d.ts +113 -0
  89. package/dist/permissions/paths.d.ts +32 -0
  90. package/dist/permissions/policy-state.d.ts +64 -0
  91. package/dist/permissions/prompt-stage.d.ts +3 -0
  92. package/dist/permissions/protected.d.ts +54 -0
  93. package/dist/permissions/ruleset.d.ts +134 -0
  94. package/dist/permissions/shell-structure.d.ts +41 -0
  95. package/dist/plugins/bundle.d.ts +100 -0
  96. package/dist/plugins/installed.d.ts +30 -0
  97. package/dist/plugins/loader.d.ts +56 -0
  98. package/dist/plugins/manifest.d.ts +115 -0
  99. package/dist/production-wiring.d.ts +340 -0
  100. package/dist/protocol/channel.d.ts +22 -0
  101. package/dist/provider/advisor-route.d.ts +47 -0
  102. package/dist/provider/bridge.d.ts +124 -0
  103. package/dist/provider/classifier/model-classifier.d.ts +82 -0
  104. package/dist/provider/classifier/prompt.d.ts +62 -0
  105. package/dist/provider/classifier/verdict-schema.d.ts +83 -0
  106. package/dist/provider/credential-api.d.ts +160 -0
  107. package/dist/provider/family-listing.d.ts +27 -0
  108. package/dist/provider/first-party.d.ts +4 -0
  109. package/dist/provider/keychain-store.d.ts +59 -0
  110. package/dist/provider/lean-prompt.d.ts +7 -0
  111. package/dist/provider/mock.d.ts +55 -0
  112. package/dist/provider/scenario-fake.d.ts +96 -0
  113. package/dist/provider/selection.d.ts +115 -0
  114. package/dist/provider/session-provider.d.ts +426 -0
  115. package/dist/provider/slots.d.ts +120 -0
  116. package/dist/provider/stream-frames.d.ts +25 -0
  117. package/dist/provider/tool-secret.d.ts +57 -0
  118. package/dist/rpc/bridge.d.ts +14 -0
  119. package/dist/rpc/mcp-control.d.ts +26 -0
  120. package/dist/runtime.d.ts +14 -0
  121. package/dist/sandbox/profile.d.ts +249 -0
  122. package/dist/sandbox/spawn.d.ts +139 -0
  123. package/dist/settings/env-filter.d.ts +52 -0
  124. package/dist/settings/loaders/hooks.d.ts +44 -0
  125. package/dist/settings/loaders/mcp-config.d.ts +83 -0
  126. package/dist/settings/loaders/plugin-mcp.d.ts +3 -0
  127. package/dist/settings/loaders/strict-plugin-only.d.ts +13 -0
  128. package/dist/settings/resolve.d.ts +2 -0
  129. package/dist/settings/sources.d.ts +2 -0
  130. package/dist/settings/trust.d.ts +36 -0
  131. package/dist/skills/attachment.d.ts +25 -0
  132. package/dist/skills/frontmatter.d.ts +64 -0
  133. package/dist/skills/index.d.ts +16 -0
  134. package/dist/skills/listing.d.ts +89 -0
  135. package/dist/skills/loader.d.ts +104 -0
  136. package/dist/skills/option.d.ts +68 -0
  137. package/dist/skills/permission-rules.d.ts +21 -0
  138. package/dist/skills/runtime.d.ts +21 -0
  139. package/dist/skills/store.d.ts +163 -0
  140. package/dist/store/continuation-attach.d.ts +44 -0
  141. package/dist/store/dialect.d.ts +526 -0
  142. package/dist/store/provider-state.d.ts +188 -0
  143. package/dist/store/resume.d.ts +92 -0
  144. package/dist/structured/ajv-seam.d.ts +7 -0
  145. package/dist/structured/descriptor.d.ts +9 -0
  146. package/dist/structured/seam.d.ts +51 -0
  147. package/dist/structured/validator.d.ts +22 -0
  148. package/dist/subagents/activity.d.ts +13 -0
  149. package/dist/subagents/availability.d.ts +30 -0
  150. package/dist/subagents/builtin-agents.d.ts +37 -0
  151. package/dist/subagents/child-engine.d.ts +198 -0
  152. package/dist/subagents/child-handle.d.ts +344 -0
  153. package/dist/subagents/definitions.d.ts +189 -0
  154. package/dist/subagents/fork.d.ts +55 -0
  155. package/dist/subagents/git-root.d.ts +1 -0
  156. package/dist/subagents/limits.d.ts +28 -0
  157. package/dist/subagents/notification-queue.d.ts +233 -0
  158. package/dist/subagents/plugin-agents.d.ts +5 -0
  159. package/dist/subagents/policy.d.ts +46 -0
  160. package/dist/subagents/register-default-factory.d.ts +66 -0
  161. package/dist/subagents/resolution.d.ts +56 -0
  162. package/dist/subagents/restore.d.ts +9 -0
  163. package/dist/subagents/roster.d.ts +17 -0
  164. package/dist/subagents/test-fakes.d.ts +12 -0
  165. package/dist/subagents/tool-pools.d.ts +69 -0
  166. package/dist/subagents/watchdog.d.ts +13 -0
  167. package/dist/subagents/workspace.d.ts +27 -0
  168. package/dist/testing.d.ts +5 -0
  169. package/dist/testing.js +194 -0
  170. package/dist/tools/background-tasks.d.ts +10 -0
  171. package/dist/tools/descriptors/_shared.d.ts +34 -0
  172. package/dist/tools/descriptors/advisor.d.ts +1 -0
  173. package/dist/tools/descriptors/agent.d.ts +47 -0
  174. package/dist/tools/descriptors/artifact.d.ts +1 -0
  175. package/dist/tools/descriptors/ask-user-question.d.ts +1 -0
  176. package/dist/tools/descriptors/bash.d.ts +20 -0
  177. package/dist/tools/descriptors/claude-design.d.ts +1 -0
  178. package/dist/tools/descriptors/cron-create.d.ts +1 -0
  179. package/dist/tools/descriptors/cron-delete.d.ts +1 -0
  180. package/dist/tools/descriptors/cron-list.d.ts +1 -0
  181. package/dist/tools/descriptors/edit.d.ts +1 -0
  182. package/dist/tools/descriptors/end-conversation.d.ts +1 -0
  183. package/dist/tools/descriptors/enter-plan-mode.d.ts +1 -0
  184. package/dist/tools/descriptors/enter-worktree.d.ts +1 -0
  185. package/dist/tools/descriptors/exit-plan-mode.d.ts +1 -0
  186. package/dist/tools/descriptors/exit-worktree.d.ts +1 -0
  187. package/dist/tools/descriptors/glob.d.ts +1 -0
  188. package/dist/tools/descriptors/grep.d.ts +1 -0
  189. package/dist/tools/descriptors/index.d.ts +59 -0
  190. package/dist/tools/descriptors/list-agents.d.ts +1 -0
  191. package/dist/tools/descriptors/list-mcp-resources-tool.d.ts +1 -0
  192. package/dist/tools/descriptors/lsp.d.ts +1 -0
  193. package/dist/tools/descriptors/monitor.d.ts +1 -0
  194. package/dist/tools/descriptors/notebook-edit.d.ts +1 -0
  195. package/dist/tools/descriptors/powershell.d.ts +1 -0
  196. package/dist/tools/descriptors/projects.d.ts +1 -0
  197. package/dist/tools/descriptors/propose-goal.d.ts +1 -0
  198. package/dist/tools/descriptors/propose-skills.d.ts +1 -0
  199. package/dist/tools/descriptors/push-notification.d.ts +1 -0
  200. package/dist/tools/descriptors/read-mcp-resource-dir-tool.d.ts +1 -0
  201. package/dist/tools/descriptors/read-mcp-resource-tool.d.ts +1 -0
  202. package/dist/tools/descriptors/read-notifications.d.ts +1 -0
  203. package/dist/tools/descriptors/read.d.ts +1 -0
  204. package/dist/tools/descriptors/refresh-mcp-tools.d.ts +1 -0
  205. package/dist/tools/descriptors/remote-trigger.d.ts +1 -0
  206. package/dist/tools/descriptors/repl.d.ts +1 -0
  207. package/dist/tools/descriptors/report-findings.d.ts +1 -0
  208. package/dist/tools/descriptors/schedule-wakeup.d.ts +1 -0
  209. package/dist/tools/descriptors/send-feedback.d.ts +1 -0
  210. package/dist/tools/descriptors/send-message.d.ts +1 -0
  211. package/dist/tools/descriptors/send-user-file.d.ts +1 -0
  212. package/dist/tools/descriptors/share-onboarding-guide.d.ts +1 -0
  213. package/dist/tools/descriptors/show-onboarding-role-picker.d.ts +1 -0
  214. package/dist/tools/descriptors/skill.d.ts +1 -0
  215. package/dist/tools/descriptors/structured-output.d.ts +1 -0
  216. package/dist/tools/descriptors/task-create.d.ts +1 -0
  217. package/dist/tools/descriptors/task-get.d.ts +1 -0
  218. package/dist/tools/descriptors/task-list.d.ts +1 -0
  219. package/dist/tools/descriptors/task-output.d.ts +1 -0
  220. package/dist/tools/descriptors/task-stop.d.ts +1 -0
  221. package/dist/tools/descriptors/task-update.d.ts +1 -0
  222. package/dist/tools/descriptors/todo-write.d.ts +1 -0
  223. package/dist/tools/descriptors/tool-search.d.ts +1 -0
  224. package/dist/tools/descriptors/wait-for-mcp-servers.d.ts +1 -0
  225. package/dist/tools/descriptors/web-fetch.d.ts +8 -0
  226. package/dist/tools/descriptors/web-search.d.ts +15 -0
  227. package/dist/tools/descriptors/winter-list-agents.d.ts +1 -0
  228. package/dist/tools/descriptors/winter-send-message.d.ts +1 -0
  229. package/dist/tools/descriptors/workflow.d.ts +1 -0
  230. package/dist/tools/descriptors/write.d.ts +1 -0
  231. package/dist/tools/impl/_caller.d.ts +14 -0
  232. package/dist/tools/impl/_domains.d.ts +25 -0
  233. package/dist/tools/impl/_exa-client.d.ts +122 -0
  234. package/dist/tools/impl/_exa-session-client.d.ts +23 -0
  235. package/dist/tools/impl/_inner-model.d.ts +135 -0
  236. package/dist/tools/impl/_search-budget.d.ts +36 -0
  237. package/dist/tools/impl/_web-fetch-cache.d.ts +37 -0
  238. package/dist/tools/impl/_web-fetch-html.d.ts +26 -0
  239. package/dist/tools/impl/_web-fetch-net.d.ts +99 -0
  240. package/dist/tools/impl/_web-search-assembler.d.ts +57 -0
  241. package/dist/tools/impl/advisor.d.ts +37 -0
  242. package/dist/tools/impl/agent.d.ts +10 -0
  243. package/dist/tools/impl/ask-user-question.d.ts +5 -0
  244. package/dist/tools/impl/background-task-runtime.d.ts +272 -0
  245. package/dist/tools/impl/bash.d.ts +78 -0
  246. package/dist/tools/impl/cron.d.ts +11 -0
  247. package/dist/tools/impl/edit.d.ts +1 -0
  248. package/dist/tools/impl/enter-plan-mode.d.ts +4 -0
  249. package/dist/tools/impl/enter-worktree.d.ts +25 -0
  250. package/dist/tools/impl/exit-plan-mode.d.ts +4 -0
  251. package/dist/tools/impl/exit-worktree.d.ts +4 -0
  252. package/dist/tools/impl/glob.d.ts +1 -0
  253. package/dist/tools/impl/grep.d.ts +19 -0
  254. package/dist/tools/impl/index.d.ts +37 -0
  255. package/dist/tools/impl/list-agents.d.ts +7 -0
  256. package/dist/tools/impl/list-mcp-resources-tool.d.ts +9 -0
  257. package/dist/tools/impl/monitor.d.ts +66 -0
  258. package/dist/tools/impl/notebook-edit.d.ts +1 -0
  259. package/dist/tools/impl/push-notification.d.ts +4 -0
  260. package/dist/tools/impl/read-ladder.d.ts +25 -0
  261. package/dist/tools/impl/read-mcp-resource-dir-tool.d.ts +9 -0
  262. package/dist/tools/impl/read-mcp-resource-tool.d.ts +9 -0
  263. package/dist/tools/impl/read-notifications.d.ts +5 -0
  264. package/dist/tools/impl/read.d.ts +44 -0
  265. package/dist/tools/impl/refresh-mcp-tools.d.ts +8 -0
  266. package/dist/tools/impl/report-findings.d.ts +1 -0
  267. package/dist/tools/impl/schedule-wakeup.d.ts +2 -0
  268. package/dist/tools/impl/send-message.d.ts +7 -0
  269. package/dist/tools/impl/skill.d.ts +5 -0
  270. package/dist/tools/impl/task-graph.d.ts +1 -0
  271. package/dist/tools/impl/task-output.d.ts +16 -0
  272. package/dist/tools/impl/task-stop.d.ts +11 -0
  273. package/dist/tools/impl/todo-write.d.ts +8 -0
  274. package/dist/tools/impl/tool-search.d.ts +4 -0
  275. package/dist/tools/impl/wait-for-mcp-servers.d.ts +29 -0
  276. package/dist/tools/impl/web-fetch.d.ts +36 -0
  277. package/dist/tools/impl/web-search.d.ts +30 -0
  278. package/dist/tools/impl/workflow.d.ts +5 -0
  279. package/dist/tools/impl/write.d.ts +8 -0
  280. package/dist/tools/paths-seam.d.ts +6 -0
  281. package/dist/tools/read-state.d.ts +12 -0
  282. package/dist/tools/registry.d.ts +423 -0
  283. package/dist/tools/task-graph-store.d.ts +61 -0
  284. package/dist/toolsearch/aliases.d.ts +26 -0
  285. package/dist/toolsearch/exposure.d.ts +30 -0
  286. package/dist/toolsearch/ranking.d.ts +6 -0
  287. package/dist/toolsearch/search.d.ts +45 -0
  288. package/dist/version.d.ts +1 -0
  289. package/dist/version.js +5 -0
  290. package/dist/web/fetchable-url.d.ts +28 -0
  291. package/dist/web/preapproved-hosts.d.ts +52 -0
  292. package/dist/web/private-address.d.ts +55 -0
  293. package/dist/web/session-runtime.d.ts +86 -0
  294. package/dist/workflows/bridge.d.ts +87 -0
  295. package/dist/workflows/budget.d.ts +24 -0
  296. package/dist/workflows/host-registry.d.ts +142 -0
  297. package/dist/workflows/journal.d.ts +29 -0
  298. package/dist/workflows/meta.d.ts +45 -0
  299. package/dist/workflows/registry.d.ts +24 -0
  300. package/dist/workflows/runtime.d.ts +254 -0
  301. package/dist/workflows/sandbox.d.ts +49 -0
  302. package/dist/workflows/script-api.d.ts +58 -0
  303. package/dist/workflows/seam.d.ts +92 -0
  304. package/dist/workflows/semaphore.d.ts +16 -0
  305. package/dist/workflows/store.d.ts +177 -0
  306. package/dist/workflows/subprocess-entry.d.ts +38 -0
  307. package/dist/workflows/subprocess-entry.js +14 -0
  308. package/dist/workflows/transcript.d.ts +56 -0
  309. package/dist/workflows/types.d.ts +84 -0
  310. package/dist/workflows/worker-harness.d.ts +45 -0
  311. package/package.json +76 -0
@@ -0,0 +1,1298 @@
1
+ import { type CredentialRef, type RuntimeConfig, type PermissionUpdate, type RuleSource, DEFAULT_CONTEXT_WINDOW_TOKENS, type InitPluginInfo, type SDKAssistantMessageError, type WireStreamEvent, type ModelFamilyListing, type ActiveSlotSet, type BrandProfile, type SettingSource } from "@yanlinglabs/winter-agent-sdk";
2
+ import type { ContinuityEndpoint, MessageOrigin, ProviderNativeState, SystemPromptBlock, ToolChangeSet, TurnRequest } from "@yanlinglabs/winter-provider-runtime";
3
+ export type { MessageOrigin, ProviderNativeState };
4
+ import { type ProviderStateRecord, type ProviderStateRecordInput } from "./store/provider-state.js";
5
+ import { type SlotProviderResolution } from "./provider/slots.js";
6
+ import type { FrameSource, FrameSink } from "./protocol/channel.js";
7
+ import type { McpServerStateSource } from "./mcp/state.js";
8
+ import type { McpControlSeam } from "./mcp/control-seam.js";
9
+ import type { SkillListing, SystemPromptAssembler } from "./context/seam.js";
10
+ import type { CompactBoundaryRecord, CompactBoundaryWriteResult, CompactionController } from "./compaction/seam.js";
11
+ import { type StructuredOutputSeam } from "./structured/seam.js";
12
+ import { type FileCheckpointSink } from "./checkpoint/seam.js";
13
+ import { type CommandResolver } from "./commands/seam.js";
14
+ import { type McpServerSource } from "./mcp/lifecycle.js";
15
+ import { type ChildHandle } from "./subagents/child-handle.js";
16
+ import { type SourcedRuleEntry } from "./permissions/ruleset.js";
17
+ import { type AutoAuditRecorder, type ClassifierInterface } from "./permissions/auto/engine.js";
18
+ import { type AutoCounterStore } from "./permissions/auto/caches.js";
19
+ import { type SourcedHookEntry } from "./hooks/registry.js";
20
+ import { type AttachmentPayload } from "./context/attachments.js";
21
+ import { type SessionRequestLayout, type ToolChangeRendering } from "./context/request-layout.js";
22
+ import { type HookAuditRecord } from "./hooks/runner.js";
23
+ import { type DurableApprovalStore } from "./permissions/approvals.js";
24
+ import "./tools/descriptors/index.ts";
25
+ import "./tools/impl/index.ts";
26
+ import { type ResolvedReviewer } from "./tools/impl/advisor.js";
27
+ import type { AuxiliaryModelResolution } from "./provider/session-provider.js";
28
+ import type { ToolSecretResolver } from "./provider/tool-secret.js";
29
+ export type ContentBlock = {
30
+ type: "text";
31
+ text: string;
32
+ } | {
33
+ type: "tool_use";
34
+ id: string;
35
+ name: string;
36
+ input: unknown;
37
+ } | {
38
+ type: "tool_reference";
39
+ tool_names: string[];
40
+ } | {
41
+ type: "tool_result";
42
+ tool_use_id: string;
43
+ content: string | ContentBlock[];
44
+ is_error?: boolean;
45
+ interrupted?: boolean;
46
+ error?: boolean;
47
+ denied?: boolean;
48
+ deferred?: boolean;
49
+ loadFirst?: boolean;
50
+ loadedTools?: string[];
51
+ loadedToolDefinitions?: LoadedToolDefinition[];
52
+ } | {
53
+ type: "thinking";
54
+ thinking: string;
55
+ signature: string;
56
+ } | {
57
+ type: "redacted_thinking";
58
+ data: string;
59
+ } | {
60
+ type: "image";
61
+ source: {
62
+ type: "base64";
63
+ media_type: string;
64
+ data: string;
65
+ };
66
+ };
67
+ /** WS-23 (midconv, review I-2): one loaded tool's definition as it stood at load time (see `tool_result.loadedToolDefinitions`). */
68
+ export interface LoadedToolDefinition {
69
+ name: string;
70
+ description: string;
71
+ inputSchema: Record<string, unknown>;
72
+ /** The MCP server group (`mcp__<server>`) of an MCP tool whose name carries that prefix. */
73
+ namespace?: string;
74
+ }
75
+ export interface ProviderMessage {
76
+ /**
77
+ * `system` (WS-23) exists ONLY on an outbound request, never in this engine's own history: an
78
+ * effort-only marker (`outputConfig`) or, later, a mid-conversation system reminder, each inserted by
79
+ * the request layout for a model whose catalog row documents the shape. See `ProviderMessageLike`.
80
+ */
81
+ role: "user" | "assistant" | "tool" | "system";
82
+ content: string | ContentBlock[];
83
+ /** WS-23: a `system` marker's per-message effort change. Never set on another role. */
84
+ outputConfig?: {
85
+ effort: string;
86
+ };
87
+ /**
88
+ * WS-23 (midconv): a `system` message's mid-conversation tool changes, built by the request layout from
89
+ * the tool epoch's `tool_changes` entries (context/tool-epoch.ts) -- never in the history itself. See
90
+ * provider-runtime's `ProviderMessageLike.toolChanges`.
91
+ */
92
+ toolChanges?: ToolChangeSet;
93
+ /**
94
+ * WS-23 (claude's own transcript fields, `effort`/`perTurnEffort` on an assistant entry): the
95
+ * TOP-LEVEL effort the request that produced this assistant message sent, and the level actually IN
96
+ * FORCE for its turn. They differ only on a model with per-message effort, where the top-level value
97
+ * stays frozen and a change rides a `system` marker. Set on assistant messages only, and only when
98
+ * the session has a named effort at all -- so a session with none stays byte-identical. The markers
99
+ * of every later request are DERIVED from these two fields (`withEffortMarkers`), live and resumed
100
+ * alike, which is what keeps the cached prefix byte-stable across turns.
101
+ */
102
+ effort?: string;
103
+ perTurnEffort?: string;
104
+ uuid?: string;
105
+ /** Which provider/model produced this message. The input to R6-9's continuation-domain check on resume, fallback and handoff. */
106
+ origin?: MessageOrigin;
107
+ /**
108
+ * OPAQUE, adapter-owned continuation state. Its ONLY sink is the provider-state sidecar (R6-7).
109
+ * Never logged, never model-readable, never in a frame or an error message -- `items` is
110
+ * `unknown[]` precisely so nothing is tempted to inspect it.
111
+ */
112
+ nativeState?: ProviderNativeState;
113
+ /**
114
+ * A Winter-authored annotation shown to the model -- a handoff note, or a foreign model's reasoning
115
+ * summary carried across a family boundary. Carried PLAINLY, never dressed as signed thinking
116
+ * (R6-8): `door` says which channel Lane C's renderer places it on, and neither door produces a
117
+ * `thinking` block with a fabricated signature.
118
+ */
119
+ decoration?: {
120
+ text: string;
121
+ door: "tag" | "thinking-channel";
122
+ };
123
+ /**
124
+ * 0.0.16 request layout (P16-5/P16-6): a PERSISTED ATTACHMENT -- claude's `type: "attachment"`
125
+ * transcript entry. The message is a `user`-role entry in the engine's history whose `content` is
126
+ * the attachment's rendered, `<system-reminder>`-wrapped text; `attachment` is the payload the
127
+ * transcript stores and the history folds read back (context/attachments.ts). It is placed right
128
+ * after the user prompt or tool results that triggered it, persisted through
129
+ * `SessionPersistence.recordAttachmentEntry`, and survives resume.
130
+ */
131
+ meta?: {
132
+ attachment: AttachmentPayload;
133
+ };
134
+ /**
135
+ * 0.0.16 request layout: the per-request userContext message (claude's `mbt`) at INDEX 0 of the
136
+ * live request. Never in the engine's history and never persisted; it only appears on an outbound
137
+ * request whose first history message it could not be merged into (context/request-layout.ts).
138
+ */
139
+ isMeta?: true;
140
+ }
141
+ export declare function providerMessageContentToText(content: string | ContentBlock[]): string;
142
+ /**
143
+ * WS-23: the session's system-prompt cache lifetime -- `RuntimeConfig.promptCacheTtl`, defaulted HERE
144
+ * and nowhere else. `"5m"` is the vendor's own default and what claude 2.1.282 uses with an API key;
145
+ * `"1h"` is the host's choice for sessions with long idle gaps (it is written at twice the input
146
+ * price). Only `"1h"` reaches a request, so a default session's requests are byte-identical to before.
147
+ */
148
+ export declare function promptCacheTtlFor(config: {
149
+ promptCacheTtl?: "5m" | "1h";
150
+ }): "5m" | "1h";
151
+ /**
152
+ * WS-23: the cache-routing key for one conversation -- the session id, and for a subagent the session
153
+ * id plus its agent id (a child's prefix is its own, so sharing the parent's key would only mix two
154
+ * prefixes under one routing group). Opaque ids only: nothing about the user or the content.
155
+ */
156
+ export declare function promptCacheKeyFor(config: {
157
+ sessionId: string;
158
+ agentId?: string;
159
+ }): string;
160
+ /** WS-23: a named effort tier -- the string half of `TurnRequest["effort"]`. */
161
+ declare const NAMED_EFFORTS: readonly ["low", "medium", "high", "xhigh", "max"];
162
+ export declare function isNamedEffort(value: unknown): value is (typeof NAMED_EFFORTS)[number];
163
+ /**
164
+ * WS-23: the catalog facts about a model's WIRE that the engine's request layout keys on. Each is a
165
+ * catalog-evidence flag the production wiring reads off the model's row (`describeCatalogModel`);
166
+ * absent means "today's layout", which is every scripted double and every row without the evidence.
167
+ */
168
+ export interface ModelWireFeatures {
169
+ /** `reasoning.perMessageEffort`: an effort change rides a `system` marker while the top-level value stays frozen. */
170
+ perMessageEffort?: true;
171
+ /** `deferredToolLoading`: every deferred tool is declared up front with `defer_loading: true`, and ToolSearch surfaces one by reference. */
172
+ deferredToolLoading?: true;
173
+ /** `midConversationSystem`: a reminder whose renderer opted in rides as a `role: "system"` message after the user turn it follows. */
174
+ midConversationSystem?: true;
175
+ /**
176
+ * WS-23 (midconv): how a change to the tool list reaches this model without editing `tools` (the tool
177
+ * epoch, context/tool-epoch.ts): `"inline"` -- Anthropic by value and by reference
178
+ * (`inlineToolDefinitions`); `"reference"` -- Anthropic by reference only (`midConversationToolChanges`).
179
+ */
180
+ toolChanges?: "inline" | "reference";
181
+ /** WS-23 (midconv): OpenAI's client-executed `tool_search` stands in for Winter's ToolSearch (`clientToolSearch`). */
182
+ clientToolSearch?: true;
183
+ /** WS-23 (midconv): OpenAI's `additional_tools` input item adds or redefines a tool mid-conversation (`additionalToolsItem`). */
184
+ additionalToolsItem?: true;
185
+ /** WS-23 (midconv): OpenAI's `tool_choice: allowed_tools` restricts the callable set without editing `tools` (`allowedToolsChoice`). */
186
+ allowedToolsChoice?: true;
187
+ }
188
+ /** What `EngineOptions.describeModel` knows about a model: its display name, its verified effort vocabulary, and its wire features. */
189
+ export interface ModelDescription {
190
+ displayName?: string;
191
+ /** The row's own `reasoning.efforts`, verbatim -- `set_effort` validates a requested level against it. */
192
+ efforts?: string[];
193
+ /** The row's own `reasoning.defaultEffort`: the level in force when no effort is named. */
194
+ defaultEffort?: string;
195
+ wire?: ModelWireFeatures;
196
+ /** WS-23 (reasoning-state, decision 5): the row's context window and output ceiling, in tokens -- the switch fit check's budget and the context accountant's limit after a switch. */
197
+ contextWindow?: number;
198
+ maxOutputTokens?: number;
199
+ /** WS-23 (reasoning-state, decision 9): `false` when the row reads no images (its input modalities omit them). Absent: unknown, read as yes. */
200
+ readsImages?: boolean;
201
+ }
202
+ export interface ProviderRequest {
203
+ messages: ProviderMessage[];
204
+ /**
205
+ * The assembled system prompt for this generation.
206
+ *
207
+ * ONE PRODUCER, deliberately. At Task 2 nothing in runEngine sets it -- Task 3 owns prompt
208
+ * assembly, and a second producer here is exactly the failure mode a new optional field invites
209
+ * (nothing fails to compile when a producer simply doesn't set it, so the sweep has to be by
210
+ * MEANING, not by build breakage). A consumer must therefore treat an absent `system` as "this
211
+ * host supplied no system prompt", never as an error.
212
+ */
213
+ system?: string;
214
+ /**
215
+ * 0.0.16 request layout (P16-5): `system` as claude's ordered cache blocks -- the static prefix
216
+ * (`global`), then the session-specific rest with the systemContext lines appended LAST (`org`).
217
+ * When present, `system` equals the texts joined by a blank line, so a provider that only reads
218
+ * `system` sees the same prompt.
219
+ */
220
+ systemBlocks?: SystemPromptBlock[];
221
+ /**
222
+ * The session's ADVERTISED tool set with real JSON Schemas -- what an adapter puts in the request's
223
+ * own `tools` array. Only tools this session actually advertises reach here, and a DEFERRED tool
224
+ * appears only once it has been LOADED (WS-09 §8.2's "load != permission"): advertising a schema
225
+ * for a tool the engine would refuse to dispatch invites the model to call it.
226
+ */
227
+ tools?: ProviderToolSpec[];
228
+ toolChoice?: TurnRequest["toolChoice"];
229
+ /** WS-23: the system prompt's cache lifetime, sent only when the session asked for `"1h"` (`promptCacheTtlFor`). */
230
+ cacheTtl?: "1h";
231
+ /**
232
+ * WS-23: cache diagnostics -- the previous MAIN-LOOP response's id on the same model, or `null` to
233
+ * opt in with nothing to compare against (a session's first request, after a compaction rewrote the
234
+ * history, after a model switch). Main-loop requests only: an auxiliary call in between would make
235
+ * the next comparison meaningless.
236
+ */
237
+ cacheDiagnostics?: {
238
+ previousMessageId: string | null;
239
+ };
240
+ /** WS-23: this conversation's cache-routing key (`promptCacheKeyFor`) -- the session id, plus the agent id for a subagent. */
241
+ cacheKey?: string;
242
+ /** WS-23 (midconv): the callable subset of `tools` on this request (OpenAI `allowed_tools`); see `TurnRequest.allowedTools`. */
243
+ allowedTools?: string[];
244
+ /** WS-23 (midconv): the conversation carries mid-conversation tool changes -- the opt-in rides every request (`TurnRequest.toolChanges`). */
245
+ toolChanges?: true;
246
+ /** WS-23 (midconv): this request re-sends a `pause_turn` response (`TurnRequest.resumesPausedTurn`). */
247
+ resumesPausedTurn?: true;
248
+ /** The resolved model for THIS generation. Present once selection is wired; absent means "the provider's own configured default", which is what every pre-P6 double sees. */
249
+ model?: string;
250
+ effort?: TurnRequest["effort"];
251
+ thinking?: TurnRequest["thinking"];
252
+ /** WS-23: the host's output-token ceiling (`RuntimeConfig.maxOutputTokens`). Absent -> the adapter's own default. */
253
+ maxOutputTokens?: number;
254
+ /**
255
+ * R6-6: TRUE cancellation. Aborted when this turn is interrupted, so an adapter can cancel
256
+ * pre-header and mid-stream instead of running to completion behind an abandoned await. The same
257
+ * signal reaches `ToolExecutor` through `ToolExecutionContext.signal`, so an interrupt stops the
258
+ * generation AND kills the in-flight Bash process group.
259
+ */
260
+ signal?: AbortSignal;
261
+ /**
262
+ * R6-5: where live observations go. A provider that streams calls these as the stream arrives; the
263
+ * engine turns them into frames under the gating each frame carries (`stream_event` only under
264
+ * `includePartialMessages`, `rate_limit_event` only for subscription-shaped quota per R6-B).
265
+ *
266
+ * ABSENT for an AUXILIARY generation (R6-G): the compaction summariser, the classifier, the advisor
267
+ * and `countTokens` never emit `stream_event`s -- capture (F) observed the pinned runtime
268
+ * suppressing exactly that call's stream events, and a Winter emitter that streamed every provider
269
+ * call would emit frames the pin does not.
270
+ */
271
+ sink?: ProviderStreamSink;
272
+ }
273
+ /** One advertised tool as an adapter serialises it. `inputSchema` is the tool's real JSON Schema, never a placeholder. */
274
+ export interface ProviderToolSpec {
275
+ name: string;
276
+ description: string;
277
+ inputSchema: Record<string, unknown>;
278
+ /**
279
+ * WS-23: declared up front but WITHHELD from the model until a `tool_reference` surfaces it
280
+ * (Anthropic's `defer_loading: true`). Set only for a model whose row documents deferred tool
281
+ * loading (`ModelWireFeatures.deferredToolLoading`), so no other adapter ever receives one.
282
+ */
283
+ deferLoading?: true;
284
+ /** WS-23 (midconv): the MCP server group a deferred tool belongs to, for OpenAI's client tool search (`TurnRequest.tools[].namespace`). */
285
+ namespace?: string;
286
+ /** WS-23 (midconv): this is Winter's ToolSearch, rendered as OpenAI's native client `tool_search` (`TurnRequest.tools[].toolSearch`). */
287
+ toolSearch?: true;
288
+ }
289
+ /** WS-23 (midconv): one request's tool plan -- see the engine's `planToolsForRequest`. */
290
+ export interface ToolPlan {
291
+ tools: ProviderToolSpec[];
292
+ allowedTools?: string[];
293
+ toolChanges?: ToolChangeRendering;
294
+ /** The vendor's tool-change opt-in rides this request (`ProviderRequest.toolChanges`). */
295
+ optIn?: true;
296
+ }
297
+ /**
298
+ * R6-5: the pinned Anthropic-shaped raw stream-event vocabulary every adapter normalises into.
299
+ *
300
+ * ALIASED, never re-declared. The declaration home is `packages/sdk/src/protocol/frames.ts`
301
+ * (`WireStreamEvent`), because the sdk is where a wire shape a host decodes belongs and because a
302
+ * second structural copy here is exactly the drift R6-D exists to avoid.
303
+ */
304
+ export type ProviderRawStreamEvent = WireStreamEvent;
305
+ /**
306
+ * The live observations a streaming provider reports. Every method is fire-and-forget: a sink
307
+ * implementation that throws must never break a generation, so the engine's own implementation
308
+ * catches and drops.
309
+ */
310
+ export interface ProviderStreamSink {
311
+ onStreamEvent(event: ProviderRawStreamEvent): void;
312
+ onRetry(info: RetryInfo): void;
313
+ /**
314
+ * R6-B: SUBSCRIPTION-QUOTA states ONLY, and the payload's own `kind` says so. An HTTP 429 is NOT
315
+ * this callback -- capture (G) proved the pinned runtime emits zero `rate_limit_event` frames for a
316
+ * 429 carrying a full `anthropic-ratelimit-*` header set; the pinned 429 path is `api_retry`.
317
+ */
318
+ onRateLimit(info: {
319
+ kind: "subscription-quota";
320
+ info: Record<string, unknown>;
321
+ }): void;
322
+ /** R6-F: a LOGIN-FLOW progress channel (codex-oauth login/refresh only), never the credential-failure channel. */
323
+ onAuthStatus(info: {
324
+ isAuthenticating: boolean;
325
+ output?: string[];
326
+ error?: string;
327
+ }): void;
328
+ /** R6-8: a FOREIGN model's readable reasoning summary. It rides the sidecar and the Winter-only `system/reasoning_summary` frame -- never `assistant.message.content`. */
329
+ onReasoningSummary(text: string): void;
330
+ }
331
+ /** The `api_retry` payload minus its frame envelope (`uuid`/`session_id`, which the engine stamps). Mirrors provider-runtime's own `retry` event. */
332
+ export interface RetryInfo {
333
+ attempt: number;
334
+ maxRetries: number;
335
+ retryDelayMs: number;
336
+ /** ABSENT, never `null`, for a connection error with no HTTP response -- the engine maps absence to the frame's pinned `error_status: null`. */
337
+ errorStatus?: number;
338
+ error: SDKAssistantMessageError;
339
+ }
340
+ /** R6-8: what a turn reports about its own reasoning. `blocks` are IN-DIALECT Anthropic-family blocks, complete and in order, carrying their REAL signatures; `summary`/`exposed` are foreign and never enter `assistant.message.content`. */
341
+ export interface ProviderThinkingOutput {
342
+ summary?: string;
343
+ exposed?: string;
344
+ exposedComplete?: boolean;
345
+ blocks?: ContentBlock[];
346
+ }
347
+ /**
348
+ * Why the provider stopped. Mirrors provider-runtime's `done` event so the bridge folds one into the
349
+ * other without a mapping table. WS-23 adds the two that are NOT an end of turn: `pause_turn` (the turn
350
+ * continues by re-sending) and `model_context_window_exceeded` (reactive compaction, then one retry).
351
+ */
352
+ export type ProviderStopReason = "end_turn" | "tool_use" | "max_tokens" | "aborted" | "refusal" | "pause_turn" | "model_context_window_exceeded";
353
+ /** WS-23: a refusal's own details (Anthropic's `stop_details`). `explanation` is display prose, never parsed. */
354
+ export interface ProviderStopDetails {
355
+ category: string | null;
356
+ explanation: string | null;
357
+ }
358
+ /**
359
+ * Phase 6 Task 3 (R6-F): the ONE error class the engine recognises as a PROVIDER failure.
360
+ *
361
+ * A provider failure that ends a turn does not get its own result subtype. Capture (I) observed the
362
+ * pinned runtime landing an API failure on `subtype: "success"` with `is_error: true`,
363
+ * `terminal_reason: "api_error"` and `api_error_status: <status | null>` -- so the engine has to be
364
+ * able to TELL a provider failure from any other throw, which would otherwise stay
365
+ * `error_during_execution` exactly as before this phase.
366
+ *
367
+ * DECLARED HERE, not in `provider/bridge.ts`, for the same structural reason `ProviderTurn` is
368
+ * (R6-4): the engine must recognise the type without importing the bridge, and a value import from
369
+ * engine.ts into bridge.ts and back would be a runtime cycle whose compiled and dev resolutions can
370
+ * differ. `bridge.ts` re-exports it, so a lane reads it from the module it is working in.
371
+ *
372
+ * `status` is ABSENT -- never `null` -- for a connection error with no HTTP response; the frame
373
+ * producer maps absence to the pinned `api_error_status: null`. (Declared with `declare` and assigned
374
+ * conditionally because `useDefineForClassFields` would otherwise EMIT an own `status` key holding
375
+ * `undefined`, making `"status" in err` true for exactly the case the pin distinguishes -- Task 2 hit
376
+ * this same trap on `ProviderRequestError`.)
377
+ *
378
+ * `message` is REDACTED BY CONSTRUCTION at every construction site: no credential material, no
379
+ * opaque provider state, no raw response body (Global Constraints).
380
+ */
381
+ export declare class ProviderTurnError extends Error {
382
+ /** The structural marker the engine matches on, so an error crossing a package boundary is still recognised. */
383
+ readonly winterProviderFailure: true;
384
+ readonly status?: number;
385
+ readonly providerCode: string | undefined;
386
+ /**
387
+ * P6 fix wave (Ruling E-3): the normalized error's Winter CODE (`server`/`rate_limit`/`network`/
388
+ * `timeout`/...) and R6-6's own `retryable` verdict, carried off the adapter's normalized error by
389
+ * the bridge. `retryable === true` is the fallback trigger: it is exactly the class `withRetry`
390
+ * retries and has, by the time the engine sees the error, given up on. Absent on an error that
391
+ * was never normalized (a bare throw with no provider shape).
392
+ */
393
+ readonly code: string | undefined;
394
+ readonly retryable: boolean | undefined;
395
+ /**
396
+ * Fix wave round 2 (R-E2, R6-6): had the stream already BEGUN when this failure happened? Set by the
397
+ * bridge from the fold's own event count. `withRetry`'s first-byte rule ("after `commit()` every
398
+ * failure is final -- the caller may already have shown text") binds the fallback exactly as it
399
+ * binds a retry: a committed failure ends the turn on R6-F and never engages a candidate.
400
+ */
401
+ readonly committed: boolean | undefined;
402
+ /**
403
+ * WS-23: the provider refused the request because the prompt does not fit the model's context
404
+ * window (Anthropic's 400 "prompt is too long"). The adapter's own verdict, carried by the bridge;
405
+ * the engine answers it with one reactive compaction and one retry. `undefined` for any other failure.
406
+ */
407
+ readonly contextOverflow: true | undefined;
408
+ constructor(message: string, opts?: {
409
+ status?: number;
410
+ providerCode?: string;
411
+ code?: string;
412
+ retryable?: boolean;
413
+ committed?: boolean;
414
+ contextOverflow?: true;
415
+ cause?: unknown;
416
+ });
417
+ }
418
+ /**
419
+ * True for a provider failure that must land on R6-F's result shape.
420
+ *
421
+ * STRUCTURAL for `ProviderTurnError` (the error may have been constructed in another package's copy
422
+ * of this module), and by NAME for `WinterProviderResolutionError` -- which is Task 2's frozen class
423
+ * and carries no marker of its own. R6-9 is explicit that "no model + no provider" is surfaced in
424
+ * R6-F's captured failure shape, so a resolution refusal thrown from `generate()` must not fall
425
+ * through to `error_during_execution` the way an ordinary bug does. It has no HTTP status, so
426
+ * `api_error_status` is `null` -- exactly capture (I)'s run (i), where the runtime failed closed
427
+ * without making a request at all.
428
+ */
429
+ export declare function isProviderTurnError(err: unknown): err is ProviderTurnError;
430
+ /**
431
+ * P1 carry: the per-message input byte cap on provider input.
432
+ *
433
+ * A DISCLOSED DEFAULT WITH A TYPED ERROR, never a silent truncation -- truncating a message would
434
+ * hand the model a conversation it never had, and the failure would surface as a confusing answer
435
+ * rather than as an error. 4 MiB is far above any real message and far below anything that would
436
+ * stall a serializer.
437
+ */
438
+ export declare const DEFAULT_MAX_PROVIDER_MESSAGE_BYTES: number;
439
+ /**
440
+ * Per-generation token accounting (R5-3). `inputTokens`/`outputTokens` are required because a
441
+ * provider that reports usage at all always knows both; the cache counters are optional because not
442
+ * every provider family exposes them.
443
+ *
444
+ * Review r1 finding 5: ONE convention for every family (provider-runtime's `usage` event):
445
+ * `inputTokens` is the NON-cached prompt; `cacheReadTokens`/`cacheWriteTokens` are disjoint from it.
446
+ */
447
+ export interface ProviderUsage {
448
+ inputTokens: number;
449
+ outputTokens: number;
450
+ cacheReadTokens?: number;
451
+ cacheWriteTokens?: number;
452
+ /** WS-23: the 1-hour-lifetime SUBSET of `cacheWriteTokens` (provider-runtime's `usage` event says why). */
453
+ cacheWrite1hTokens?: number;
454
+ /** WS-23: the provider's own verdict on where this request's prefix diverged from the previous one. */
455
+ cacheMiss?: {
456
+ type: string;
457
+ missedInputTokens?: number;
458
+ };
459
+ /** WS-23: replayed thinking blocks the provider dropped (Anthropic's `input_transformations`). */
460
+ thinkingBlocksDropped?: number;
461
+ }
462
+ export type ProviderTurn = {
463
+ kind: "text";
464
+ text: string;
465
+ usage?: ProviderUsage;
466
+ stopReason?: ProviderStopReason;
467
+ stopDetails?: ProviderStopDetails;
468
+ thinking?: ProviderThinkingOutput;
469
+ nativeState?: ProviderNativeState;
470
+ content?: ContentBlock[];
471
+ responseId?: string;
472
+ } | {
473
+ kind: "tool_use";
474
+ calls: Array<{
475
+ id: string;
476
+ name: string;
477
+ input: unknown;
478
+ }>;
479
+ text?: string;
480
+ usage?: ProviderUsage;
481
+ stopReason?: ProviderStopReason;
482
+ stopDetails?: ProviderStopDetails;
483
+ thinking?: ProviderThinkingOutput;
484
+ nativeState?: ProviderNativeState;
485
+ content?: ContentBlock[];
486
+ responseId?: string;
487
+ };
488
+ export interface Provider {
489
+ generate(input: ProviderRequest): Promise<ProviderTurn>;
490
+ }
491
+ /** WS-23 (M-7): the tool result a call gets when its turn stopped at the output limit, so the call was never run. */
492
+ export declare const OUTPUT_LIMIT_TRUNCATED_CALL_TEXT = "Error: this tool call was not run. Your response hit the output token limit (max_tokens) before the call's input was complete, so its arguments may be truncated. Issue the call again; if its input is large (a whole file, a long command), split it into smaller calls.";
493
+ /** WS-23: the most times one user envelope re-sends a `pause_turn` response before ending typed. The vendor's own handling guide caps continuations at 5. */
494
+ export declare const MAX_PAUSE_TURN_CONTINUATIONS = 5;
495
+ /**
496
+ * WS-23 (block order): a turn's assistant content in STREAM ORDER (`ProviderTurn.content`), or
497
+ * `undefined` when the provider reported none -- the caller then falls back to the per-kind assembly.
498
+ *
499
+ * CHECKED, NOT TRUSTED: the tool loop answers `turn.calls`, so a `tool_use` turn's ordered content must
500
+ * name exactly those calls, in that order. A persisted `tool_use` with no `tool_result` after it (or a
501
+ * result for a call the content never carried) is a 400 on the very next request, so a list that
502
+ * disagrees with `calls` is ignored rather than persisted; likewise a `text` turn's content may carry
503
+ * no call at all.
504
+ */
505
+ export declare function inStreamOrder(turn: ProviderTurn): ContentBlock[] | undefined;
506
+ /**
507
+ * WS-23 (reasoning-state): an assistant turn's content as the HOST sees it on the `assistant` frame --
508
+ * every in-dialect reasoning block keeps its readable text and loses its attestation: `signature` and
509
+ * `redacted_thinking.data` become `""`. Those bytes exist for one reader, the Anthropic API on the next
510
+ * request, and they reach it from the provider-state sidecar; a host (the daemon, a phone, a log) has no
511
+ * use for them and every copy is one more place an opaque token can leak from. The block SHAPES stay,
512
+ * so a host that renders "thinking…" or "[redacted]" keeps working.
513
+ */
514
+ export declare function contentForHost(content: ContentBlock[]): ContentBlock[];
515
+ /**
516
+ * Phase 6 (R6-9), widened by the fix wave: the session's RESOLVED provider identity as the engine
517
+ * carries it -- the `MessageOrigin` half every `origin` record and `providerAnnotations` read, plus
518
+ * the catalog/credential half the dialect record stores. One shape for the startup identity
519
+ * (`EngineOptions.providerIdentity`) and for every identity a switch installs, so a restamp after a
520
+ * `set_model` or a fallback writes the SAME fields the startup stamp did.
521
+ */
522
+ export interface EngineProviderIdentity {
523
+ providerId: string;
524
+ modelKey: string;
525
+ family: string;
526
+ continuationDomain?: string;
527
+ adapterId?: string;
528
+ adapterVersion?: string;
529
+ catalogVersion?: string;
530
+ authRefKind?: string;
531
+ }
532
+ /**
533
+ * P6 fix wave (Ruling E-2): what the switch seam answers for a target model it could resolve.
534
+ *
535
+ * `provider` is BUILT (a fresh `adapterAsProvider` under Ruling E-1's material rule), `identity` is
536
+ * what the engine installs as `currentProviderIdentity`, `to` carries the target's continuity facts
537
+ * for `classifySwitch`, and `from` the source's when the caller named one.
538
+ */
539
+ export interface ModelSwitchResolution {
540
+ provider: Provider;
541
+ identity: EngineProviderIdentity;
542
+ to: ContinuityEndpoint;
543
+ from?: ContinuityEndpoint;
544
+ }
545
+ /**
546
+ * P6 fix wave (Ruling E-4, R6-H): what the wiring answers when it can PRICE a generation. `undefined`
547
+ * for an unpriced row -- then no cost field is emitted and `maxBudgetUsd` is inert (disclosed).
548
+ * `costBasis` is always `"list"` here: `estimateCostUsd` reports a price only for `official-doc`
549
+ * pricing evidence, and an unpriced or inferred row is exactly the `undefined` case.
550
+ */
551
+ export interface PricedUsage {
552
+ costUsd: number;
553
+ costBasis: "list";
554
+ /** The catalog key the price was looked up under (`ModelUsage.canonicalModel`). */
555
+ canonicalModel: string;
556
+ /** The pinned `AccountInfo.apiProvider` family when the provider has one; omitted otherwise. */
557
+ provider?: string;
558
+ /** From the descriptor when known, otherwise OMITTED -- never invented (R6-H). */
559
+ contextWindow?: number;
560
+ maxOutputTokens?: number;
561
+ }
562
+ /** The seam's typed refusal: R6-K's `provider-mismatch`, `unknown-model`, and every other resolution code -- NEVER a parked switch. */
563
+ export interface ModelSwitchRefusal {
564
+ refused: true;
565
+ code: string;
566
+ message: string;
567
+ }
568
+ /**
569
+ * P6 fix wave (Ruling E-2): the switch seam, shaped like `resolveChildProvider`. Owned by
570
+ * `provider/session-provider.ts`: R6-K resolution UNDER THE SESSION PROVIDER (a qualified key naming
571
+ * another provider is `provider-mismatch`), `buildProvider` under Ruling E-1, and the resolved
572
+ * identity. The engine calls it FIRST -- before parking anything -- so an unresolvable target is a
573
+ * control-response refusal, never a model string the wire later chokes on.
574
+ */
575
+ export type ResolveModelSwitch = (model: string, from?: MessageOrigin) => ModelSwitchResolution | ModelSwitchRefusal;
576
+ /**
577
+ * The session's running context-window accounting (R5-3), and the input R5-4's compaction trigger
578
+ * reads: compact when `contextTokens() >= compactionThreshold * limit()`.
579
+ *
580
+ * `contextTokens()` is the LAST generation's input + output, not a running total -- an accumulated
581
+ * sum would grow without bound across a conversation and cross any threshold regardless of how much
582
+ * context actually survives, which is the opposite of what the trigger means. Cache read/write
583
+ * counters are informational and deliberately excluded: they describe how the same input was BILLED,
584
+ * not how much of the window it occupies.
585
+ *
586
+ * `limit()` is `contextWindowTokens` -- a DISCLOSED Winter session option, default 200000, until P6's
587
+ * model catalogue supplies real per-model values. The pin has no per-session equivalent at all (its
588
+ * nearest relative is the `autoCompactWindow` SETTING, `sdk.d.ts:7599`).
589
+ */
590
+ export interface ContextAccountant {
591
+ contextTokens(): number;
592
+ limit(): number;
593
+ record(usage: ProviderUsage): void;
594
+ /**
595
+ * RULING P5-J (Phase 5 fix wave): the session's CUMULATIVE token spend, monotonically increasing.
596
+ *
597
+ * DELIBERATELY NOT `contextTokens()`, and the difference is the whole ruling.
598
+ * `contextTokens()` is the LAST provider call's context SIZE -- an overwrite, not an accumulation.
599
+ * It goes DOWN after a compaction and it says nothing about what a session has spent, so a budget
600
+ * ceiling read off it would be un-reached by a smaller call and un-reached again by a compaction.
601
+ * `spentTokens()` only ever grows, which is the only shape a ceiling can be built on.
602
+ *
603
+ * CHILD USAGE ROLLS UP. A child engine records into its own accountant for its own context
604
+ * arithmetic AND adds the same usage here, so a workflow's `budget` bounds the work its agents do
605
+ * rather than only the parent's own turns -- which was the gap that made `budget.spent()` report
606
+ * an honest but useless 0.
607
+ */
608
+ spentTokens(): number;
609
+ /**
610
+ * P5-J: fold a DESCENDANT's usage into this accountant's cumulative total WITHOUT touching
611
+ * `contextTokens()`.
612
+ *
613
+ * Two counters, one call, and they must not be conflated: a child's tokens are spend the session
614
+ * is responsible for, and they are NOT part of the parent's own next request, so adding them to
615
+ * the context reading would make the parent compact on a window it does not have.
616
+ */
617
+ recordDescendantUsage(usage: ProviderUsage): void;
618
+ /**
619
+ * WS-23 (reasoning-state, decision 5): the window moves with the model. A switch re-sources the limit
620
+ * from the TARGET's row -- the auto-compaction threshold used to keep reading the first model's window
621
+ * for the rest of the session. Optional: an injected accountant without it keeps its own limit.
622
+ */
623
+ setLimit?(limit: number): void;
624
+ }
625
+ export { DEFAULT_CONTEXT_WINDOW_TOKENS };
626
+ export interface ContextAccountantOptions {
627
+ /** Defaults to DEFAULT_CONTEXT_WINDOW_TOKENS. A non-positive value is ignored (the default stands) rather than producing a limit no session could ever sit under. */
628
+ limit?: number;
629
+ }
630
+ export declare function createContextAccountant(opts?: ContextAccountantOptions): ContextAccountant;
631
+ export interface ToolExecutor {
632
+ /**
633
+ * Phase 6 Task 3 (R6-6, P4 carry): `opts.signal` is ABORTED when the turn is interrupted.
634
+ *
635
+ * OPTIONAL on both sides, and additive: every pre-existing executor keeps satisfying this
636
+ * interface unchanged, and an executor that ignores the signal behaves exactly as before. What
637
+ * changes is that an executor which HONOURS it stops the work rather than merely being abandoned --
638
+ * "a stopped child starts nothing new AND its in-flight Bash is killed" (R6-6), which was
639
+ * previously impossible because the interrupt was a raced Promise with no channel into the tool.
640
+ */
641
+ execute(call: {
642
+ id: string;
643
+ name: string;
644
+ input: unknown;
645
+ }, opts?: {
646
+ signal?: AbortSignal;
647
+ explicitApproval?: "prompt" | "rule";
648
+ }): Promise<{
649
+ output: string;
650
+ isError?: boolean;
651
+ }>;
652
+ }
653
+ /**
654
+ * SDK 0.0.16: one extra attachment producer (`EngineOptions.attachmentProducers`). `messages` is the
655
+ * engine's live history -- after a compaction, claude's post-boundary slice -- for folds to read.
656
+ */
657
+ export type AttachmentProducer = (ctx: {
658
+ phase: "turn-start" | "tool-round" | "compaction";
659
+ messages: readonly ProviderMessage[];
660
+ sessionId: string;
661
+ agentId?: string;
662
+ }) => AttachmentPayload[] | Promise<AttachmentPayload[]>;
663
+ /**
664
+ * SDK 0.0.16 Lane N: what marks a user entry as one the RUNTIME wrote rather than the human. claude's
665
+ * own transcript shape: `isMeta: true` plus an `origin` naming why the turn exists (today only
666
+ * `{kind: "task-notification"}`). Optional on both sides -- a store that ignores it records exactly
667
+ * what it recorded before.
668
+ */
669
+ export interface UserEntryMeta {
670
+ isMeta?: boolean;
671
+ origin?: {
672
+ kind: string;
673
+ [k: string]: unknown;
674
+ };
675
+ }
676
+ export interface SessionPersistence {
677
+ /**
678
+ * WS-23: the durable transcript's absolute path, when the store knows it (store/dialect.ts's
679
+ * writer does). A command hook's stdin names it as `transcript_path`; absent, that field is `""`.
680
+ */
681
+ transcriptPath?: string;
682
+ recordUserEntry(content: string | ContentBlock[], opts?: UserEntryMeta): void | Promise<void>;
683
+ /**
684
+ * SDK 0.0.16 (P16-5/P16-6): one persisted attachment -- claude's `{type: "attachment", attachment}`
685
+ * transcript entry, chained like any other. Optional: a store without it keeps the attachment in
686
+ * this run's memory only (a resumed session then re-announces it).
687
+ */
688
+ recordAttachmentEntry?(attachment: AttachmentPayload): void | Promise<void>;
689
+ /**
690
+ * Phase 6 Task 3 (R6-7): `opts.uuid` PRE-ALLOCATES the entry's own dialect uuid.
691
+ *
692
+ * The engine mints the uuid, appends the sidecar `origin` record naming it as `anchorUuid`, and
693
+ * only THEN calls this -- write-ahead, so a crash can leave a record without an entry (ignorable,
694
+ * garbage-collectable) but never an entry without a record it needed. Omitted by every pre-P6
695
+ * caller, in which case the writer mints its own exactly as before.
696
+ */
697
+ /**
698
+ * WS-23: `effort`/`perTurnEffort` are claude's own assistant-entry fields -- the top-level effort
699
+ * the request sent and the level in force for the turn. Present only when the session has a named
700
+ * effort; the store writes them as top-level entry fields, and resume carries them back onto the
701
+ * rebuilt message so the effort markers re-derive at the same positions.
702
+ */
703
+ recordAssistantEntry(content: ContentBlock[], opts?: {
704
+ uuid?: string;
705
+ effort?: string;
706
+ perTurnEffort?: string;
707
+ }): void | Promise<void>;
708
+ /**
709
+ * R6-7: one provider-state record. MUST be called BEFORE `recordAssistantEntry` for the same
710
+ * `anchorUuid` -- that ordering is the whole guarantee, and provider-state.ts's crash-pair fixture
711
+ * asserts the file order rather than trusting this comment.
712
+ *
713
+ * Optional, matching every other method here: a store that predates this field (or a bare test
714
+ * double) simply never gets asked, and the session keeps an in-memory chain only.
715
+ */
716
+ recordProviderState?(record: ProviderStateRecordInput): void | Promise<void>;
717
+ /** R6-7: the chain, oldest-first, for a resumed session. `undefined`/absent means "no durable chain", which degrades every resumed assistant message to summary-level with a `continuity_warning`. */
718
+ loadProviderState?(): Promise<ProviderStateRecord[]>;
719
+ /**
720
+ * R6-9 / WS-16 §4: the resolved provider identity every subsequent dialect record carries
721
+ * (`providerId`/`modelKey`/`adapterId`/`adapterVersion`/`catalogVersion`/`authRef`/`classifierPin`).
722
+ *
723
+ * A SEAM ADDITION beyond the brief's literal block, and it has to be one: the identity fields are
724
+ * named as this task's deliverable and `SessionPersistence` is the only channel the engine has to
725
+ * the store. `authRef` is the credential ref's KIND, never its material (R6-10).
726
+ */
727
+ setProviderIdentity?(identity: {
728
+ providerId: string;
729
+ modelKey: string;
730
+ adapterId?: string;
731
+ adapterVersion?: string;
732
+ catalogVersion?: string;
733
+ authRefKind?: string;
734
+ classifierPin?: string;
735
+ }): void;
736
+ /**
737
+ * Review round 1 (I1): did this session ever RECORD a provider identity?
738
+ *
739
+ * `undefined` means "no identity block" -- a pre-P6 transcript, or one written before selection was
740
+ * wired. That is the ONLY thing distinguishing R6-7's two silent-looking resumes: a session with no
741
+ * records and no identity has nothing to degrade from, while one with an identity and no records
742
+ * had its sidecar DELETED and every message is degraded.
743
+ */
744
+ loadProviderIdentity?(): Promise<{
745
+ providerId: string;
746
+ modelKey: string;
747
+ } | undefined>;
748
+ /** R6-C: records a model swap in the dialect record's `providerHistory`, alongside the Winter-only `system/model_switch` frame. */
749
+ recordProviderSwitch?(entry: {
750
+ from: string;
751
+ to: string;
752
+ reason: "fallback" | "set_model" | "interrupt";
753
+ }): void;
754
+ flush?(): void | Promise<void>;
755
+ recordPermissionUpdate?(update: PermissionUpdate, authority: RuleSource): void | Promise<void>;
756
+ recordHookAudit?(entry: HookAuditRecord): void | Promise<void>;
757
+ /**
758
+ * Phase 5 Task 8 (rider 16): Lane S's `invoked_skills` attachment. Optional, like every other
759
+ * method here. The engine never calls it -- `skills/runtime.ts`'s `onInvoked` sink does, wired by
760
+ * `production-wiring.ts` -- but it lives on this interface because it is a DURABLE session record
761
+ * and this is the one seam the engine's storage-agnostic contract exposes for those.
762
+ */
763
+ recordInvokedSkills?(attachment: {
764
+ type: string;
765
+ skills: unknown[];
766
+ }): void | Promise<void>;
767
+ /**
768
+ * Phase 5 Task 8 (riders 9/16): one of Lane K's checkpoint records, as a transcript-visible entry.
769
+ * See `store/dialect.ts`'s `FILE_HISTORY_ENTRY_TYPE_BY_KIND` for what this closes (a transcript
770
+ * reader can see that a rewind is possible) and what it does not (the `backups/index.jsonl`
771
+ * sidecar remains the rewind's own read authority).
772
+ */
773
+ recordFileHistory?(record: {
774
+ kind: "snapshot" | "delta";
775
+ userMessageUuid: string;
776
+ path: string;
777
+ pathHash: string;
778
+ tool: string;
779
+ at: string;
780
+ version: number;
781
+ absent?: boolean;
782
+ parentRealPath?: string;
783
+ anchorPath?: string;
784
+ anchorRealPath?: string;
785
+ }): void | Promise<void>;
786
+ recordCompactBoundary?(record: CompactBoundaryRecord): CompactBoundaryWriteResult | void | Promise<CompactBoundaryWriteResult | void>;
787
+ }
788
+ export interface EngineOptions {
789
+ config: RuntimeConfig;
790
+ input: FrameSource;
791
+ output: FrameSink;
792
+ provider: Provider;
793
+ tools?: ToolExecutor;
794
+ unregisteredToolExecutor?: ToolExecutor;
795
+ store?: SessionPersistence;
796
+ initialMessages?: ProviderMessage[];
797
+ approvalStore?: DurableApprovalStore;
798
+ autoStateStore?: AutoCounterStore;
799
+ env?: Record<string, string | undefined>;
800
+ providerSupportsToolSearch?: boolean;
801
+ deferrableContextShare?: number;
802
+ mcpServerStateSource?: McpServerStateSource;
803
+ /**
804
+ * Fix round 20/21: every MCP server the PARENT run can see (`ParentMcpState.visibleServerNames`,
805
+ * read at call time), handed to EVERY child engine -- whether or not it owns servers of its own --
806
+ * so the scope recurses: a grandchild of a subagent that owns a server sees the session's servers
807
+ * and that subagent's. Read ONLY to scope the advertised partition's MCP tools and ToolSearch's pool
808
+ * (`computeAdvertisedPartition`); never connected, never reported on `mcp_servers`/`mcp_status`.
809
+ * Round 20 carried the parent's board only, and only to a child with object-form servers.
810
+ */
811
+ inheritedMcpServerNames?: () => readonly string[];
812
+ mcpControlSeam?: McpControlSeam;
813
+ contextAccountant?: ContextAccountant;
814
+ onChildRosterReady?: (getChildren: () => readonly ChildHandle[]) => void;
815
+ onForegroundChildrenReady?: (getForeground: () => readonly ChildHandle[]) => void;
816
+ /**
817
+ * R5-16: prompt assembly (Lane C). Called once per user envelope; its `system` goes on the live
818
+ * `ProviderRequest`. SDK 0.0.16: its `userContext()` builds the index-0 context message, memoized
819
+ * per session (context/request-layout.ts). ABSENT => the engine sends `agentSystemPrompt` (or
820
+ * nothing), no index-0 message, and authors no text of its own -- see context/seam.ts.
821
+ */
822
+ systemPromptAssembler?: SystemPromptAssembler;
823
+ /**
824
+ * SDK 0.0.16 (P16-5/P16-6): extra PERSISTED-ATTACHMENT producers, run by the attachment scan at the
825
+ * start of every turn, after every tool round and after a compaction -- after the built-in ones
826
+ * (agent listing, skill listing, date change). Whatever they return is appended to the history as
827
+ * attachment messages (context/attachments.ts), persisted, and sent in claude's positions. The
828
+ * reusable door for other lanes' attachments (task notifications, plan-mode reminders).
829
+ */
830
+ attachmentProducers?: readonly AttachmentProducer[];
831
+ /**
832
+ * WS-21 §6.3 item 1 (fix round 2): the session's ENABLED plugins that ship a `workflows/`
833
+ * directory -- threaded into `RegistryToolExecutorDeps.pluginWorkflows` (registry.ts) so the
834
+ * Workflow tool's `<plugin>:<name>` resolution (`workflows/store.ts`) can find them. A plain
835
+ * value, not a getter: a session's loaded-plugin set is resolved once per incarnation, like
836
+ * skills/agents/MCP are.
837
+ *
838
+ * Fix round 4 (minors, M-3's last bullet): `workflowsPaths` (a manifest `workflows` override,
839
+ * `plugins/bundle.ts`'s own citation) is carried alongside `workflowsPath` from here on -- every
840
+ * hop between `production-wiring.ts`'s own local array and `workflows/store.ts`'s consumption of
841
+ * it forwards this SAME array reference rather than rebuilding each element, so the value already
842
+ * survived the trip before this type caught up; widened here so a future hop that DOES rebuild an
843
+ * element is caught by the type checker instead of silently dropping the field.
844
+ */
845
+ pluginWorkflows?: readonly {
846
+ name: string;
847
+ workflowsPath?: string;
848
+ workflowsPaths?: readonly string[];
849
+ }[];
850
+ /**
851
+ * SV-5 fix round 3 (I-4): the session's resolved `settingSources`, threaded to
852
+ * `RegistryToolExecutorDeps.settingSources` / `ToolExecutionContext.settingSources` so the
853
+ * Workflow tool's project/user tier resolution is gated on `"project"`/`"user"` membership, not
854
+ * `trustedWorkspace` alone -- the same fact `production-wiring.ts` already resolves once per
855
+ * incarnation for skills/agents/rules. Absent means every tier is allowed, matching every
856
+ * pre-fix-round-3 caller.
857
+ */
858
+ settingSources?: readonly SettingSource[];
859
+ /**
860
+ * SDK 0.0.16: the model's display name for the `# Environment` section's model line, when the host
861
+ * knows one (production wiring answers from the catalog). Absent => the bare-id line.
862
+ */
863
+ describeModel?: (model: string, providerId?: string) => ModelDescription | undefined;
864
+ /** SDK 0.0.16: the engine's clock for the `currentDate` entry and the `date_change` fold. Tests only; absent => `new Date()`. */
865
+ now?: () => Date;
866
+ /**
867
+ * R5-3 / P4-J retirement: the child persona a subagent runs with (`AgentDefinition.prompt`
868
+ * composed over any inherited base). Reaches the assembler as `SystemPromptInput.agentPrompt`, and
869
+ * IS the system prompt when no assembler is registered. Set by subagents/child-engine.ts; never by
870
+ * a top-level host.
871
+ */
872
+ agentSystemPrompt?: string;
873
+ /**
874
+ * Spawn-surface parity (research §A1, `omitClaudeMd`): set by subagents/child-engine.ts from the
875
+ * child's resolved definition (`RuntimeAgentDefinition.omitProjectContext` -- the `Explore`/`Plan`/
876
+ * `web-fetch` built-ins). The assembler then drops the discovered instructions files and the git
877
+ * summary for this run. Never set by a top-level host.
878
+ */
879
+ omitProjectContext?: boolean;
880
+ /**
881
+ * SDK 0.0.16 (P16-7, R3a §2): a FORK child's exact inherited request layout -- set ONLY by
882
+ * `subagents/child-engine.ts`'s own fork branch, from `ChildInheritance.requestLayout`, never by a
883
+ * top-level host. When present, this run's system prompt, tool specs and userContext are sent
884
+ * EXACTLY as captured (`assemblePrompt`/`ensureSessionContext`/`requestSystem`/`providerToolSpecs`
885
+ * below all short-circuit to it) -- never re-rendered, however faithfully, because WS-10 §3.5's
886
+ * "inherits... system prompt... tool pool... verbatim" cannot survive a second independent render
887
+ * (a different registry snapshot, a different git status, a different local clock all touch the
888
+ * SAME bytes claude's own fork keeps frozen). `systemPromptAssembler`/`agentSystemPrompt` are never
889
+ * consulted while this is set -- not even to build the FIRST-turn input, which a fork never needs
890
+ * one for (its own directive rides `initialMessages`, not `agentSystemPrompt`).
891
+ */
892
+ exactRequestLayout?: SessionRequestLayout;
893
+ /**
894
+ * R5-14: slash-command resolution (Lane S owns the filesystem half; the engine owns the built-ins
895
+ * and the ordering between them). Consulted BEFORE the model sees a prompt. ABSENT => only the
896
+ * built-ins resolve and every other prompt passes through verbatim.
897
+ */
898
+ commandResolver?: CommandResolver;
899
+ /**
900
+ * R5-4: the compaction vehicle (Lane K). Consulted before every provider call of a turn (the AUTO
901
+ * trigger) and by `/compact` (the MANUAL one). ABSENT => no auto-compaction happens and `/compact`
902
+ * says so -- the engine never summarizes on its own.
903
+ */
904
+ compactionController?: CompactionController;
905
+ /**
906
+ * R5-10: structured output (Lane K). REQUIRED for `config.outputFormat` to do anything -- the
907
+ * engine registers the host-generated `StructuredOutput` descriptor this seam builds and validates
908
+ * every call through it. `outputFormat` set with NO seam is reported as a configuration error on
909
+ * the first turn rather than silently ignored: a session that believes it will get a structured
910
+ * result and instead gets prose has no way to tell that from a model failure.
911
+ */
912
+ structuredOutput?: StructuredOutputSeam;
913
+ /**
914
+ * R5-11: file checkpointing (Lane K). Consulted before every Write/Edit/NotebookEdit when
915
+ * `config.enableFileCheckpointing` is on, and by the `rewind_files` control request. ABSENT with
916
+ * checkpointing enabled means nothing is backed up and `rewind_files` answers `canRewind: false` --
917
+ * never a throw, and never a silent "success" that restores nothing.
918
+ */
919
+ fileCheckpointSink?: FileCheckpointSink;
920
+ /**
921
+ * The resolved winter root for THIS session (`config.winterHome ?? resolveWinterHome(env, brand)`).
922
+ * Passed rather than re-derived so this file and `store/dialect.ts` can never disagree about where
923
+ * a session lives -- and because `dialect.ts` imports types from this module, so the reverse import
924
+ * would be circular. Consumed by the workflow session registration below.
925
+ */
926
+ winterHome?: string;
927
+ /**
928
+ * Hook entries from SETTINGS FILES and PLUGIN MANIFESTS, already parsed by
929
+ * `buildHookEntriesFromSettings` (the one parser for that block shape). Concatenated with this
930
+ * session's own `config.hooks` entries; the WHOLE array feeds both `buildHookRegistry` (which
931
+ * applies the workspace-trust filter) and `createCommandHookInvoker` (which dispatches
932
+ * `{type:"command"}` entries BY ID -- so it must be built from the same array, or an id will not
933
+ * be found).
934
+ */
935
+ extraHookEntries?: readonly SourcedHookEntry[];
936
+ /**
937
+ * WS-23: set ONLY by `subagents/child-engine.ts` for a child's own engine. A subagent fires
938
+ * `SubagentStart` where a session fires `SessionStart`, and `SubagentStop` where a session fires
939
+ * `Stop` -- claude's own split ("Converting Stop hook to SubagentStop"), so a hook can tell a
940
+ * subagent finishing from the session finishing, and a SubagentStop `block` keeps THE SUBAGENT
941
+ * going (the child's own turn loop, below) rather than the parent. `agentType` is the resolved
942
+ * `subagent_type`; `agentTranscriptPath` the child's own transcript (`""` when it has none).
943
+ */
944
+ subagentHooks?: {
945
+ agentType: string;
946
+ agentTranscriptPath: string;
947
+ };
948
+ /**
949
+ * MCP server sources beyond the host's own `config.mcpServers`: the settings tiers,
950
+ * the project `mcp.json`, and plugin manifests. Appended AFTER the explicit source, so an explicitly
951
+ * configured server still wins; `resolveMcpServerSources` owns precedence, duplicate names, the
952
+ * reserved `winter` name and the project-origin trust gate, exactly as before.
953
+ *
954
+ * "PROJECT-ORIGIN", NOT "STDIO" (rd-1, residual round 2). P4's gate was stdio-literal because
955
+ * process execution was the visible danger; RULING P5-K widened it to every transport, and
956
+ * `lifecycle.ts`'s own header has said so since. This sentence kept the old name -- a stale
957
+ * summary of a rule that had moved, which is exactly how a reader concludes an http server from a
958
+ * clone connects freely.
959
+ */
960
+ extraMcpServerSources?: readonly McpServerSource[];
961
+ /**
962
+ * `system/init.slash_commands`. Produced by `slashCommandNames(resolver, cwd)`, which ALREADY
963
+ * includes the engine's own `/compact` -- the engine must not prepend it a second time.
964
+ */
965
+ initSlashCommands?: readonly string[];
966
+ /** `system/init.skills` -- this session's EFFECTIVE set (the `skills` filter applied), not the whole index. */
967
+ initSkills?: readonly string[];
968
+ /** `system/init.plugins` -- `pluginInitInfo(bundles)`, with resolved absolute paths. */
969
+ initPlugins?: readonly InitPluginInfo[];
970
+ /** `system/init.output_style` -- the CONFIGURED name (`config.outputStyle ?? settings.outputStyle ?? "default"`). */
971
+ initOutputStyle?: string;
972
+ /**
973
+ * The POST-TRUNCATION model-facing skill listing (R5-17). Lane S produces it; Lane C's assembler
974
+ * places it; neither re-derives the other's caps.
975
+ *
976
+ * The engine's own contribution is the one thing neither lane can see: it withholds the listing
977
+ * whenever `Skill` is NOT in this session's advertised set. Lane C's NEEDS_CONTEXT 3 named that
978
+ * gap exactly -- a listing tells the model to "call the `Skill` tool", and a session with a
979
+ * restricted `tools` list would be instructed to call a tool it does not have. `Skill` is in the
980
+ * pinned default 24 (capture (g)), so the default path is unaffected.
981
+ *
982
+ * SDK 0.0.16: rendered as claude's persisted `skill_listing` attachment -- once, then only the
983
+ * skills not yet sent (session state, seeded on resume, kept across compaction). A GETTER is read
984
+ * afresh at every attachment scan, which is how a skill added mid-session reaches the model.
985
+ */
986
+ skillListing?: SkillListing | (() => SkillListing);
987
+ /**
988
+ * Phase 5 fix wave, C1: the settings-file `permissions` block, per tier.
989
+ *
990
+ * Before this the engine seeded its rule set from `config.{allowedTools,disallowedTools,permissions}`
991
+ * ALONE, so the only `project`/`local`/`user`-sourced entry a live session could hold came from a
992
+ * `canUseTool` answer carrying `addRules`. A `deny` in `~/.winter/settings.json` was silently not a
993
+ * deny; the whole P5-A/P5-D trust matrix guarded a path a settings file never entered.
994
+ *
995
+ * PLAIN DATA, resolved once by `production-wiring.ts` (both entrypoints), so a spawned or compiled
996
+ * child gets the identical seed. Folded into `initialRules` AFTER the managed baseline denies and
997
+ * BEFORE the `sdk` entries -- which is the pinned precedence: managed floor, then files
998
+ * (`perSource`'s own highest-first order), then the host's own `Options`.
999
+ */
1000
+ settingsRules?: EngineSettingsRuleSeed;
1001
+ /**
1002
+ * Phase 6 Task 3 (P1 carry): the per-message input byte cap on provider input, overridable for
1003
+ * tests and for a host that knows its own provider's real limit.
1004
+ *
1005
+ * An ENGINE OPTION rather than a `RuntimeConfig`/`Options` field, deliberately and disclosed: the
1006
+ * default is a Winter-authored safety bound with no pinned counterpart, and adding an `Options`
1007
+ * field would put an un-pinned knob on the public compatibility surface for a value no host has
1008
+ * asked to tune. Absent -> `DEFAULT_MAX_PROVIDER_MESSAGE_BYTES`.
1009
+ */
1010
+ maxProviderMessageBytes?: number;
1011
+ /**
1012
+ * Phase 6 Task 3 (R6-9): the session's RESOLVED provider identity.
1013
+ *
1014
+ * The one input that makes the write-ahead sidecar path live: with no identity there is nothing to
1015
+ * name in an `origin` record, so `recordAssistant` writes none and the session behaves exactly as
1016
+ * it did before this phase. `provider/selection.ts` produces this and T10's wiring passes it in --
1017
+ * an ENGINE OPTION rather than something the engine resolves itself, for the same reason the
1018
+ * provider is (the engine must stay driveable by a plain double).
1019
+ */
1020
+ providerIdentity?: EngineProviderIdentity;
1021
+ /**
1022
+ * Phase 6 Task 10: the pinned `system/init.apiKeySource` (`sdk.d.ts:4860`, REQUIRED).
1023
+ *
1024
+ * An ENGINE OPTION rather than something derived here, for the same reason `providerIdentity` is:
1025
+ * the mapping from Winter's own `CredentialRef` kinds onto the pin's four-member vocabulary is the
1026
+ * WIRING's decision (`provider/session-provider.ts`'s `apiKeySourceFor`, which documents why every
1027
+ * non-`ANTHROPIC_API_KEY` shape reports `'none'`), and the engine must stay driveable by a plain
1028
+ * double that has no credential model at all.
1029
+ *
1030
+ * Absent -> `"none"`, which is the honest value for a session with no credential ref and is what
1031
+ * every pre-P6 golden's init frame is regenerated against.
1032
+ */
1033
+ apiKeySource?: string;
1034
+ /**
1035
+ * Phase 6 Task 10 (R6-I): the session's model catalogue and account surface, as the control
1036
+ * handlers below answer them.
1037
+ *
1038
+ * BOTH ARE FUNCTIONS, not values, and both come from the WIRING rather than being computed here:
1039
+ * the engine has no registry and no credential model, and giving it one would be a second
1040
+ * resolution path that could disagree with the session's own.
1041
+ *
1042
+ * `supportedModels` answers the pinned payload-free `list_models` control request
1043
+ * (`sdk.d.ts:3855`), whose own JSDoc frames it as "ask the worker" — a table inside the binary, per
1044
+ * capture (J), never a `/v1/models` fetch. Absent -> the handler answers an empty array, which is
1045
+ * the honest answer for a session running a scripted double.
1046
+ */
1047
+ supportedModels?: () => unknown[];
1048
+ /**
1049
+ * WS-13c §7 (P6.6): the session's MODEL FAMILY listing — the active slot set plus every family
1050
+ * behind "more options".
1051
+ *
1052
+ * TAKES THE LIVE MODEL KEY (R-6c-21), for the same reason `activeSlotSet` does: the wiring's own
1053
+ * view of the session's model is the START model, so a listing computed without the key reports
1054
+ * the family a session has already switched away from. Optional, so a producer that ignores it
1055
+ * still satisfies the type.
1056
+ *
1057
+ * A function from the WIRING for the same reason `supportedModels` is: the listing needs the
1058
+ * catalog, the session's effective model AND the credential/enablement view, none of which the
1059
+ * engine has. Absent -> the handler answers `{ active: undefined, families: [] }`, the honest
1060
+ * answer for a session running a scripted double (`active: undefined` means "no effective model
1061
+ * to derive a family from", NOT "no families" — that is the empty array beside it).
1062
+ *
1063
+ * Winter-only and disclosed: `Query.supportedModels()` keeps its pinned `ModelInfo[]` shape
1064
+ * unchanged, and this is a separate surface rather than a widening of it.
1065
+ */
1066
+ listModelFamilies?: (currentModelKey?: string) => ModelFamilyListing;
1067
+ /**
1068
+ * WS-13c §3 (P6.6): the session's ACTIVE SLOT SET, for the model key given.
1069
+ *
1070
+ * TAKES THE MODEL KEY rather than reading one, and that is the whole re-render mechanism (R13c-4).
1071
+ * The wiring's own view of the session's model is the START model (`providerWiring.resolved`);
1072
+ * `installIdentity` updates the ENGINE's `currentModel` and never writes back, so a getter that
1073
+ * closed over the wiring's value would keep advertising the family the session started on after a
1074
+ * `set_model` across families — the exact "false information" D25 forbids. The engine passes
1075
+ * `currentProviderIdentity?.modelKey ?? currentModel` and memoises on `(that key, settingsVersion())`,
1076
+ * so all three re-render points (session start, a `set_model` that lands, a `modelSlots` change)
1077
+ * are one comparison made at the next `providerToolSpecs()` — which happens per turn, and a turn
1078
+ * boundary IS the quiescent boundary R13c-4 names.
1079
+ *
1080
+ * WHAT THIS DOES AND DOES NOT GUARANTEE (R-6c-28). The ENGINE half needs no watcher and no restart:
1081
+ * whenever `settingsVersion()` changes, the next turn re-renders. What no part of this SDK does yet
1082
+ * is RE-RESOLVE the settings cascade mid-session — `production-wiring.ts` resolves once and hands
1083
+ * down a live getter, exactly as R6b-7's `providerSettings` has since WS-13b — so today the version
1084
+ * only moves when a HOST hands down a new resolved view. Until P8's host integration does that, a
1085
+ * `modelSlots` edit to a file is not seen by a running session. Plumbed, not yet reachable.
1086
+ *
1087
+ * ABSENT -> the Agent descriptor keeps its STATIC pinned enum and its description's marker block is
1088
+ * stripped, which is what every scripted double and every pre-P6.6 fixture sees.
1089
+ */
1090
+ activeSlotSet?: (currentModelKey: string | undefined) => ActiveSlotSet;
1091
+ /**
1092
+ * WS-13c §4 (P6.6): the slot -> provider resolver, for the model key given.
1093
+ *
1094
+ * Consulted for a CHILD's requested model (`AgentInput.model`, `AgentDefinition.model`,
1095
+ * `WINTER_SUBAGENT_MODEL`, and the inherited `config.model`). A refusal is THROWN out of
1096
+ * `spawnChild` so `tools/impl/agent.ts` reports it as the tool's own typed error — never a
1097
+ * substitution onto some other model (WS-13 §9).
1098
+ *
1099
+ * ABSENT -> the pre-P6.6 chain, verbatim: the requested string goes on the child unresolved.
1100
+ */
1101
+ resolveSlot?: (requested: string, currentModelKey: string | undefined) => SlotProviderResolution;
1102
+ /**
1103
+ * WS-13c §5 (P6.6): a monotonically increasing number the WIRING bumps whenever the resolved
1104
+ * settings view changes, so a `modelSlots`/`preferredProviders` change re-renders the Agent tool at
1105
+ * the next quiescent boundary. See `activeSlotSet` for what "the resolved view changes" requires
1106
+ * today (a host handing one down) and what it does not (a watcher in this SDK).
1107
+ *
1108
+ * A NUMBER rather than the settings object, deliberately: the memo compares it, and comparing a
1109
+ * settings OBJECT by identity would re-render on every re-resolve that changed nothing while
1110
+ * comparing it by value would mean serialising the whole cascade once per turn.
1111
+ */
1112
+ settingsVersion?: () => number;
1113
+ /**
1114
+ * `account_info` is a WINTER-ONLY control subtype, disclosed.
1115
+ *
1116
+ * The pin carries `AccountInfo` on the `initialize`/`reinitialize` RESPONSE (`sdk.d.ts:3804`), and
1117
+ * derived-shapes-p6 item (d) is explicit that `system/init` must NOT grow an `account` field for
1118
+ * parity. Winter's protocol has no `initialize` control request to hang it on, so the surface it
1119
+ * does expose (`Query.accountInfo()`) needs a subtype of its own rather than a field on a frame the
1120
+ * pin does not put it on.
1121
+ */
1122
+ accountInfo?: () => unknown;
1123
+ /**
1124
+ * Phase 6 Task 10 (R6-14): the session's REAL classifier, or absent for a Manual fallback.
1125
+ *
1126
+ * P2 shipped `createAutoEngine`'s own `alwaysNoVerdictClassifier` default and said the real
1127
+ * model-routed classifier was P6's job. This is that wire. ABSENCE IS MEANINGFUL and is not the
1128
+ * same as a classifier that abstains: R6-14's Manual fallback is a session that was never given a
1129
+ * reviewer it had evidence for, and `selectClassifierRoute` records WHY.
1130
+ */
1131
+ classifier?: ClassifierInterface;
1132
+ /**
1133
+ * P6 fix wave (Ruling E-2): the switch seam -- see `ResolveModelSwitch`. The production wiring
1134
+ * passes it for every catalog-resolved session AND for a session whose model failed to resolve
1135
+ * (the recovery path), and WITHHOLDS it for the reserved `winter-test/<name>` namespace; absent,
1136
+ * `set_model` keeps its pre-fix shape: the requested string is parked verbatim and applied at the
1137
+ * boundary with no identity to rebuild (every pre-P6 fixture, every scripted double).
1138
+ */
1139
+ resolveModelSwitch?: ResolveModelSwitch;
1140
+ /**
1141
+ * P6 fix wave (Ruling E-3): `fallbackModel`'s candidates as CATALOG KEYS, in order, already
1142
+ * domain-checked at init by selection. Engaged through `resolveModelSwitch` when a generation fails
1143
+ * on an R6-6 retryable class after `withRetry` gave up -- see the generation catch.
1144
+ */
1145
+ fallbackModels?: string[];
1146
+ /**
1147
+ * P6 fix wave (Ruling E-4, R6-H): prices ONE generation's usage for the model it ran on. The
1148
+ * wiring implements it over the catalog's `pricing` evidence; absent (a scripted double) or
1149
+ * `undefined` for an unpriced row means no cost is reported and the budget is inert.
1150
+ */
1151
+ priceUsage?: (modelKey: string, usage: ProviderUsage) => PricedUsage | undefined;
1152
+ /**
1153
+ * The catalog facts a `modelUsage` row carries for a generation `priceUsage` could NOT price (a
1154
+ * subscription or pricing-less row): the key, the window, the provider family. Such a generation's
1155
+ * TOKENS still land on `modelUsage` at `costUSD: 0` -- claude folds every API call into it whatever
1156
+ * its price -- while `total_cost_usd` and `maxBudgetUsd` stay governed by priced generations only.
1157
+ * Absent (a scripted double), or `undefined` for a key the catalog cannot resolve: the row carries
1158
+ * the key as its `canonicalModel` and nothing it would have to invent.
1159
+ */
1160
+ usageRowFacts?: (modelKey: string) => UsageRowFacts | undefined;
1161
+ /**
1162
+ * P6 fix wave (Ruling E-5, R6-14): the classifier's own resolved identity, so the session can PIN it
1163
+ * on the first successful classification. Present only when `classifier` is.
1164
+ */
1165
+ classifierIdentity?: {
1166
+ modelKey: string;
1167
+ };
1168
+ /**
1169
+ * P6 fix wave (Ruling E-5): the auto-mode audit recorder. Defaults to the no-op recorder every
1170
+ * session ran with before (audit persistence is WS-15's projector work); a fixture injects one to
1171
+ * observe the pin's `fallback_state` record.
1172
+ */
1173
+ autoAudit?: AutoAuditRecorder;
1174
+ /**
1175
+ * P7a LANE B (D29/D30, WS-06 §4): the ADVISOR's reviewer, for the model key given.
1176
+ *
1177
+ * TAKES THE MODEL KEY for the same reason `activeSlotSet` and `listModelFamilies` do: D30's
1178
+ * default is per FAMILY, the family comes from the session's effective model, and the wiring's own
1179
+ * view of that model is the START snapshot (`installIdentity` updates the ENGINE's, never writes
1180
+ * back). A resolver that closed over the wiring's value would keep reviewing with the family the
1181
+ * session began on after a cross-family `set_model` — the same false-information class D25 forbids
1182
+ * for the Agent tool's enum, with the transcript as the payload.
1183
+ *
1184
+ * TWO CONSUMERS, one authority: the `advisor` tool's executor (which calls it per invocation, so a
1185
+ * hot `settings.advisor.model` edit is seen at the next call) and the `winter.reviewer-model`
1186
+ * capability (WS-06 §4's availability predicate — "a reviewer model is resolvable in the session's
1187
+ * provider catalog", which is this function answering).
1188
+ *
1189
+ * ABSENT -> no reviewer, which is what a scripted double and a session whose own model failed to
1190
+ * resolve both get: the tool is not advertised, and if a host advertised it anyway (by supplying
1191
+ * the capability token) it returns WS-06 §4's ordinary "reviewer unavailable" tool error.
1192
+ */
1193
+ resolveReviewer?: (currentModelKey?: string) => ResolvedReviewer | undefined;
1194
+ /**
1195
+ * A TOOL'S STATED INNER MODEL, by tag (`RuntimeConfig.web.fetch.digestModel` is the first) -- the
1196
+ * wiring's `resolveAuxiliaryModel`, under the cross-provider credential rule. Takes the live model
1197
+ * key for the same reason `resolveReviewer` does: a slot NAME resolves against the family the
1198
+ * session is on NOW, and the wiring's own view of that is the start snapshot.
1199
+ *
1200
+ * NOT consulted for "the session's own model": the engine already holds that provider, live.
1201
+ * ABSENT (a scripted double, a refused session, a child engine) -> a root run treats a stated tag
1202
+ * as unresolvable; a child inherits the root's through the web session registry.
1203
+ */
1204
+ resolveAuxiliaryModel?: (tag: string, opts?: {
1205
+ authRef?: CredentialRef;
1206
+ currentModelKey?: string;
1207
+ }) => AuxiliaryModelResolution;
1208
+ /** The wiring's tool-secret resolver (`provider/tool-secret.ts`), reached by a tool through the web session registry. */
1209
+ resolveToolSecret?: ToolSecretResolver;
1210
+ /**
1211
+ * Called for EVERY generation this run prices -- its own main-loop and inner generations, and
1212
+ * every descendant's it folded in. A CHILD engine is handed its parent's
1213
+ * `ChildEngineRunContext.recordDescendantCost` here, which is what makes a subagent's spend reach
1214
+ * the SESSION's `total_cost_usd`/`modelUsage` and therefore `maxBudgetUsd`. The token roll-up
1215
+ * (`recordDescendantUsage`) cannot do this job: it carries no model key, and a price is per model.
1216
+ */
1217
+ onPricedGeneration?: (entry: PricedGenerationEntry) => void;
1218
+ /**
1219
+ * A SUBAGENT run only: has an ANCESTOR crossed its `maxBudgetUsd`? ORed into this run's own
1220
+ * `budgetExceeded()`. A child's config deliberately carries NO ceiling of its own -- its ledger is
1221
+ * only its own subtree, so the root's number would be compared against the wrong total -- which left
1222
+ * a child's main loop (and any inner-model pass inside it) the one place a session could keep
1223
+ * spending past its limit. Costs fold upward SYNCHRONOUSLY (`onPricedGeneration`), so the owning
1224
+ * run's answer is already true for the whole tree by the time a descendant asks. Each level hands
1225
+ * its OWN `budgetExceeded` down, so the chain reaches the root through any depth.
1226
+ */
1227
+ ancestorBudgetExceeded?: () => boolean;
1228
+ }
1229
+ /**
1230
+ * One generation, as it travels up the agent tree: the model it ran on, what it used, and -- when
1231
+ * the row is priced -- what that cost. `priced` ABSENT is an unpriced generation (subscription or
1232
+ * pricing-less row): its tokens still land on `modelUsage` at `costUSD: 0`, described by `row`.
1233
+ */
1234
+ export interface PricedGenerationEntry {
1235
+ modelKey: string;
1236
+ usage: ProviderUsage;
1237
+ priced?: PricedUsage;
1238
+ /** For an unpriced generation: the row facts `modelUsage` carries (from `EngineOptions.usageRowFacts`). */
1239
+ row?: UsageRowFacts;
1240
+ }
1241
+ /** What a `modelUsage` row states about a model it could not price. Omitted fields are unknown, never invented. */
1242
+ export interface UsageRowFacts {
1243
+ canonicalModel: string;
1244
+ provider?: string;
1245
+ contextWindow?: number;
1246
+ maxOutputTokens?: number;
1247
+ }
1248
+ /**
1249
+ * The settings seed as the ENGINE consumes it -- named and exported by the residual round (NEW-4)
1250
+ * because a CHILD engine needs the identical value and the chain that carries it
1251
+ * (`production-wiring.ts` -> `register-default-factory.ts` -> `child-engine.ts`) would otherwise
1252
+ * have re-declared this shape three more times. `production-wiring.ts`'s `SettingsRuleSeed` is the
1253
+ * producer's view (mutable arrays plus its own `warnings`); this is the consumer's.
1254
+ */
1255
+ export interface EngineSettingsRuleSeed {
1256
+ entries: readonly SourcedRuleEntry[];
1257
+ directories: ReadonlyArray<{
1258
+ path: string;
1259
+ source: RuleSource;
1260
+ }>;
1261
+ defaultMode?: string;
1262
+ disableBypassPermissionsMode?: boolean;
1263
+ }
1264
+ /**
1265
+ * The turn engine (WS-04 §4.1 state machine: `initializing → idle → turn_active → draining →
1266
+ * closing`). A "turn" is one user envelope through its terminal result; a "tool round" is one
1267
+ * provider tool_use → execute → results-appended → provider-again cycle. Always terminates when
1268
+ * input ends (stdin EOF or an explicit `end_input` control request) — the P0 dangling-loop bug
1269
+ * class is structurally impossible here, though the SHAPE of that guarantee inverted under Ruling
1270
+ * P2-B: `end_input` no longer ends the pump's own read (it only ends `userFrames`, so a runtime-
1271
+ * originated permission RPC arriving after end_input can still be answered) — engine completion now
1272
+ * explicitly cancels the pump instead, once the turn loop has fully drained. See the pump's own
1273
+ * definition further down for the full re-argued termination guarantee.
1274
+ */
1275
+ export declare function buildBaselineDenyRules(resolvedWinterHome?: string, brand?: Pick<BrandProfile, "homeDirName">, resolvedStoreHome?: string): SourcedRuleEntry[];
1276
+ /**
1277
+ * Fix r2 (N4): the facet's PROCESS-LEVEL registrations, withdrawn from a `finally` that no throw can
1278
+ * skip.
1279
+ *
1280
+ * `runEngine`'s own teardown is a straight-line block near the end of ~2400 lines, and its own
1281
+ * comment says plainly that the `finally` half was never landed ("the residual exposure is: a future
1282
+ * throw from anywhere in those 1800 lines"). That was tolerable while only a session a host had
1283
+ * SUBSCRIBED to held a handle; unconditional self-peer registration made it every session, and a
1284
+ * leaked handle keeps answering `list_reachable` and `deliverToSession` for a session that is gone,
1285
+ * out of a `status()` closure reading dead state.
1286
+ *
1287
+ * This is the cheap half the review asked for rather than the restructure the comment declines: the
1288
+ * body is unchanged and unindented, and only the two registrations that are now universal move into a
1289
+ * disposer list this wrapper drains. Draining is idempotent (`splice`), so the ordinary teardown may
1290
+ * still run them at its own point in the sequence and this is purely the backstop.
1291
+ */
1292
+ /**
1293
+ * WS-23: how many times one turn's Stop/SubagentStop hooks may send the model back to work before
1294
+ * the turn ends regardless. Winter's own number (claude has an equivalent cap); the `stop_hook_active`
1295
+ * input flag is the first guard, this is the backstop for a hook that ignores it.
1296
+ */
1297
+ export declare const STOP_HOOK_BLOCK_CAP = 8;
1298
+ export declare function runEngine(opts: EngineOptions): Promise<number>;