open-multi-agent-kit 0.98.5 → 0.99.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +3 -2
  3. package/dist/cli/help.d.ts.map +1 -1
  4. package/dist/cli/help.js +1 -0
  5. package/dist/cli/help.js.map +1 -1
  6. package/dist/commands/verified-run-cli.d.ts.map +1 -1
  7. package/dist/commands/verified-run-cli.js +2 -2
  8. package/dist/commands/verified-run-cli.js.map +1 -1
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +19 -2
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/devin-harness-dispatch.d.ts +12 -0
  13. package/dist/core/devin-harness-dispatch.d.ts.map +1 -0
  14. package/dist/core/devin-harness-dispatch.js +12 -0
  15. package/dist/core/devin-harness-dispatch.js.map +1 -0
  16. package/dist/core/devin-harness.d.ts +53 -0
  17. package/dist/core/devin-harness.d.ts.map +1 -0
  18. package/dist/core/devin-harness.js +112 -0
  19. package/dist/core/devin-harness.js.map +1 -0
  20. package/dist/core/domain-dispatch.d.ts +4 -1
  21. package/dist/core/domain-dispatch.d.ts.map +1 -1
  22. package/dist/core/domain-dispatch.js +5 -0
  23. package/dist/core/domain-dispatch.js.map +1 -1
  24. package/dist/core/domain-loadouts-provider-harness.d.ts +12 -0
  25. package/dist/core/domain-loadouts-provider-harness.d.ts.map +1 -0
  26. package/dist/core/domain-loadouts-provider-harness.js +122 -0
  27. package/dist/core/domain-loadouts-provider-harness.js.map +1 -0
  28. package/dist/core/domain-loadouts.d.ts +2 -33
  29. package/dist/core/domain-loadouts.d.ts.map +1 -1
  30. package/dist/core/domain-loadouts.js +3 -56
  31. package/dist/core/domain-loadouts.js.map +1 -1
  32. package/dist/core/domain-profile.d.ts +40 -0
  33. package/dist/core/domain-profile.d.ts.map +1 -0
  34. package/dist/core/domain-profile.js +7 -0
  35. package/dist/core/domain-profile.js.map +1 -0
  36. package/dist/core/grok-harness-dispatch.d.ts +6 -20
  37. package/dist/core/grok-harness-dispatch.d.ts.map +1 -1
  38. package/dist/core/grok-harness-dispatch.js +6 -55
  39. package/dist/core/grok-harness-dispatch.js.map +1 -1
  40. package/dist/core/grok-harness.d.ts +7 -9
  41. package/dist/core/grok-harness.d.ts.map +1 -1
  42. package/dist/core/grok-harness.js +9 -23
  43. package/dist/core/grok-harness.js.map +1 -1
  44. package/dist/core/harness-skills.d.ts +20 -0
  45. package/dist/core/harness-skills.d.ts.map +1 -0
  46. package/dist/core/harness-skills.js +36 -0
  47. package/dist/core/harness-skills.js.map +1 -0
  48. package/dist/core/loadout-runtime-state.d.ts +25 -0
  49. package/dist/core/loadout-runtime-state.d.ts.map +1 -0
  50. package/dist/core/loadout-runtime-state.js +39 -0
  51. package/dist/core/loadout-runtime-state.js.map +1 -0
  52. package/dist/core/loadout-runtime.d.ts +2 -12
  53. package/dist/core/loadout-runtime.d.ts.map +1 -1
  54. package/dist/core/loadout-runtime.js +6 -13
  55. package/dist/core/loadout-runtime.js.map +1 -1
  56. package/dist/core/model-resolver.d.ts +1 -41
  57. package/dist/core/model-resolver.d.ts.map +1 -1
  58. package/dist/core/model-resolver.js +2 -49
  59. package/dist/core/model-resolver.js.map +1 -1
  60. package/dist/core/provider-default-models.d.ts +42 -0
  61. package/dist/core/provider-default-models.d.ts.map +1 -0
  62. package/dist/core/provider-default-models.js +50 -0
  63. package/dist/core/provider-default-models.js.map +1 -0
  64. package/dist/core/provider-display-names.d.ts.map +1 -1
  65. package/dist/core/provider-display-names.js +1 -0
  66. package/dist/core/provider-display-names.js.map +1 -1
  67. package/dist/core/provider-harness-dispatch.d.ts +63 -0
  68. package/dist/core/provider-harness-dispatch.d.ts.map +1 -0
  69. package/dist/core/provider-harness-dispatch.js +60 -0
  70. package/dist/core/provider-harness-dispatch.js.map +1 -0
  71. package/dist/core/provider-usage-devin.d.ts +16 -0
  72. package/dist/core/provider-usage-devin.d.ts.map +1 -0
  73. package/dist/core/provider-usage-devin.js +61 -0
  74. package/dist/core/provider-usage-devin.js.map +1 -0
  75. package/dist/core/provider-usage-text.d.ts +5 -0
  76. package/dist/core/provider-usage-text.d.ts.map +1 -0
  77. package/dist/core/provider-usage-text.js +15 -0
  78. package/dist/core/provider-usage-text.js.map +1 -0
  79. package/dist/core/provider-usage-types.d.ts +2 -1
  80. package/dist/core/provider-usage-types.d.ts.map +1 -1
  81. package/dist/core/provider-usage-types.js.map +1 -1
  82. package/dist/core/provider-usage.d.ts +1 -2
  83. package/dist/core/provider-usage.d.ts.map +1 -1
  84. package/dist/core/provider-usage.js +12 -7
  85. package/dist/core/provider-usage.js.map +1 -1
  86. package/dist/core/run-execution-api.d.ts +1 -1
  87. package/dist/core/run-execution-api.d.ts.map +1 -1
  88. package/dist/core/run-execution-api.js.map +1 -1
  89. package/dist/core/sdk.d.ts.map +1 -1
  90. package/dist/core/sdk.js +23 -18
  91. package/dist/core/sdk.js.map +1 -1
  92. package/dist/core/verified-run/dag-phase.d.ts +1 -1
  93. package/dist/core/verified-run/dag-phase.d.ts.map +1 -1
  94. package/dist/core/verified-run/dag-phase.js +46 -8
  95. package/dist/core/verified-run/dag-phase.js.map +1 -1
  96. package/dist/core/verified-run/dag-projection.d.ts.map +1 -1
  97. package/dist/core/verified-run/dag-projection.js +25 -12
  98. package/dist/core/verified-run/dag-projection.js.map +1 -1
  99. package/dist/core/verified-run/dag-types.d.ts +11 -0
  100. package/dist/core/verified-run/dag-types.d.ts.map +1 -1
  101. package/dist/core/verified-run/dag-types.js.map +1 -1
  102. package/dist/core/verified-run/event-parser.d.ts.map +1 -1
  103. package/dist/core/verified-run/event-parser.js +1 -0
  104. package/dist/core/verified-run/event-parser.js.map +1 -1
  105. package/dist/core/verified-run/owned-execution.d.ts +1 -0
  106. package/dist/core/verified-run/owned-execution.d.ts.map +1 -1
  107. package/dist/core/verified-run/owned-execution.js +7 -1
  108. package/dist/core/verified-run/owned-execution.js.map +1 -1
  109. package/dist/core/verified-run/process-projection.d.ts +13 -0
  110. package/dist/core/verified-run/process-projection.d.ts.map +1 -0
  111. package/dist/core/verified-run/process-projection.js +82 -0
  112. package/dist/core/verified-run/process-projection.js.map +1 -0
  113. package/dist/core/verified-run/projection.d.ts.map +1 -1
  114. package/dist/core/verified-run/projection.js +11 -55
  115. package/dist/core/verified-run/projection.js.map +1 -1
  116. package/dist/core/verified-run/run-types.d.ts +1 -0
  117. package/dist/core/verified-run/run-types.d.ts.map +1 -1
  118. package/dist/core/verified-run/run-types.js.map +1 -1
  119. package/dist/core/verified-run/task-execution.d.ts +9 -0
  120. package/dist/core/verified-run/task-execution.d.ts.map +1 -0
  121. package/dist/core/verified-run/task-execution.js +29 -0
  122. package/dist/core/verified-run/task-execution.js.map +1 -0
  123. package/dist/core/verified-run/writer-projection.d.ts.map +1 -1
  124. package/dist/core/verified-run/writer-projection.js +6 -5
  125. package/dist/core/verified-run/writer-projection.js.map +1 -1
  126. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  127. package/dist/modes/interactive/interactive-mode.js +2 -5
  128. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  129. package/dist/modes/interactive/resource-description.d.ts +3 -0
  130. package/dist/modes/interactive/resource-description.d.ts.map +1 -0
  131. package/dist/modes/interactive/resource-description.js +15 -0
  132. package/dist/modes/interactive/resource-description.js.map +1 -0
  133. package/docs/devin-harness.md +121 -0
  134. package/docs/docs.json +4 -0
  135. package/docs/environment-variables.md +2 -1
  136. package/docs/index.md +1 -0
  137. package/docs/loadout-domains/README.md +2 -1
  138. package/docs/loadout-domains/devin-harness.md +72 -0
  139. package/docs/metrics.md +57 -16
  140. package/docs/providers.md +76 -0
  141. package/docs/release-audit-0.98.5.md +17 -0
  142. package/docs/release-audit-0.99.0.md +68 -0
  143. package/docs/run-protocol.md +4 -3
  144. package/docs/runtime-algorithms.md +4 -1
  145. package/docs/sdk.md +9 -5
  146. package/docs/settings.md +1 -1
  147. package/docs/startup-resource-labels-testing.md +47 -0
  148. package/docs/tb21-audit.md +18 -4
  149. package/docs/usage.md +5 -0
  150. package/docs/verified-run-remaining-design.md +881 -0
  151. package/docs/verified-run-testing.md +91 -0
  152. package/docs/verified-run.md +30 -9
  153. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  154. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  155. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  156. package/examples/extensions/gondolin/package-lock.json +2 -2
  157. package/examples/extensions/gondolin/package.json +1 -1
  158. package/examples/extensions/sandbox/package-lock.json +2 -2
  159. package/examples/extensions/sandbox/package.json +1 -1
  160. package/examples/extensions/with-deps/package-lock.json +2 -2
  161. package/examples/extensions/with-deps/package.json +1 -1
  162. package/npm-shrinkwrap.json +18 -18
  163. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tAgent,\n\ttype AgentMessage,\n\tinspectTranscriptIntegrity,\n\ttype ModelContract,\n\trepairTranscriptIntegrity,\n\ttype ThinkingLevel,\n} from \"omk-agent-core\";\nimport { createNodeResourceKeyResolver } from \"omk-agent-core/node\";\nimport { clampThinkingLevel, type Message, type Model, type ToolResultMessage } from \"omk-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { ReplayLedgerManager } from \"../guardrails/evidence-system.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type SessionTranscriptRepair } from \"./agent-session.ts\";\nimport { resolveAgentToolSettings } from \"./agent-tool-settings.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createDomainDispatchRuntimeSession, isDomainRoutingEnabled, tryDomainDispatch } from \"./domain-dispatch.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { tryGrokHarnessDispatch } from \"./grok-harness-dispatch.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { recordClaudePassiveUsage, recordCodexPassiveUsage } from \"./provider-usage.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { createSdkProviderStream } from \"./sdk-provider-stream.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { classifySessionTermination, SessionTerminationError } from \"./session-termination.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { BashSandboxPreflight } from \"./tools/bash.ts\";\nimport {\n\tallToolNames,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.omk/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Opt-in logical dispatch policy shared by the main loop and first-party summary stream. */\n\tmodelContract?: ModelContract;\n\t/** Optional main-loop output limit; a contract supplies the default cap when omitted. */\n\tmaxTokens?: number;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\t/** True when the user pinned `--model` / `--provider` for this process. */\n\tmodelPinned?: boolean;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, OMK enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/**\n\t * Optional prompt hint used only for opt-in domain routing (`OMK_DOMAIN_ROUTING=1`).\n\t * This text only selects a loadout policy and is never sent to the model.\n\t */\n\tdomainRoutingPrompt?: string;\n\t/** Optional loadout enforcement policy for SDK-created sessions. */\n\tloadoutAccessPolicy?: LoadoutAccessPolicy;\n\t/** Trusted sandbox preflight used for built-in local bash execution. */\n\tbashSandboxPreflight?: BashSandboxPreflight;\n\t/** Optional replay ledger shared with VerifiedEvidenceExecutor freshness checks. */\n\treplayLedger?: ReplayLedgerManager;\n\t/** Goal binding for AgentSession replay events; defaults to replayLedger.goalId. */\n\treplayGoalId?: string;\n\t/** Optional lane binding for AgentSession replay events. */\n\treplayLaneId?: string;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\ninterface SessionTranscriptRecovery {\n\tmessages: AgentMessage[];\n\trepair?: SessionTranscriptRepair;\n}\n\n/**\n * ALG001-A: inspect the restored transcript on every live session open/resume.\n *\n * - A clean transcript passes through untouched.\n * - Unambiguous missing-only tail results are auto-repaired: synthetic\n * terminal results (tool-result/v2 envelope) are persisted to the session\n * so the repair is durable and idempotent, together with a durable\n * `transcript_repaired` audit entry.\n * - Any duplicate/orphan/duplicate-call/interleaved corruption marks the\n * session (`session_corrupt` entry, once) and fails closed.\n */\nfunction recoverSessionTranscriptOnOpen(\n\tsessionManager: SessionManager,\n\tmessages: AgentMessage[],\n): SessionTranscriptRecovery {\n\tconst report = inspectTranscriptIntegrity(messages);\n\tif (report.ok) {\n\t\treturn { messages };\n\t}\n\n\tlet repaired: AgentMessage[];\n\ttry {\n\t\trepaired = repairTranscriptIntegrity(messages, \"Tool result missing; synthesized during session resume recovery\");\n\t} catch {\n\t\tconst alreadyMarked = sessionManager\n\t\t\t.getBranch()\n\t\t\t.some((entry) => entry.type === \"custom\" && entry.customType === \"session_corrupt\");\n\t\tif (!alreadyMarked) {\n\t\t\tsessionManager.appendCustomEntry(\"session_corrupt\", {\n\t\t\t\tissues: report.issues.map((issue) => ({\n\t\t\t\t\tkind: issue.kind,\n\t\t\t\t\ttoolCallId: issue.toolCallId,\n\t\t\t\t\t...(issue.toolName === undefined ? {} : { toolName: issue.toolName }),\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst summary = report.issues.map((issue) => `${issue.kind}:${issue.toolCallId}`).join(\", \");\n\t\tconst firstIssue = report.issues[0]?.kind ?? \"missing_result\";\n\t\tconst termination = classifySessionTermination({\n\t\t\tsessionId: sessionManager.getSessionId(),\n\t\t\trunId: `resume-${randomUUID()}`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsource: \"inferred_on_resume\",\n\t\t\tmessage: \"Session transcript has ambiguous tool-result corruption.\",\n\t\t\tcause: { area: \"transcript\", code: firstIssue },\n\t\t\tsideEffects: \"possible\",\n\t\t});\n\t\tthrow new SessionTerminationError(\n\t\t\t`Cannot open session: corrupt tool transcript (${summary}). ` +\n\t\t\t\t\"The session has been marked corrupt; repair it explicitly before resuming.\",\n\t\t\ttermination,\n\t\t);\n\t}\n\n\tconst inserted = repaired.slice(messages.length) as ToolResultMessage[];\n\tif (inserted.length === 0) {\n\t\treturn { messages: repaired };\n\t}\n\tfor (const message of inserted) {\n\t\tsessionManager.appendMessage(message);\n\t}\n\tconst insertedToolCallIds = inserted.map((message) => message.toolCallId);\n\tsessionManager.appendCustomEntry(\"transcript_repaired\", { insertedToolCallIds, reason: \"resume\" });\n\treturn { messages: repaired, repair: { insertedToolCallIds, reason: \"resume\" } };\n}\n\nfunction getDomainDispatchBaseToolNames(options: CreateAgentSessionOptions): string[] {\n\tif (!options.tools && (options.noTools === \"all\" || options.noTools === \"builtin\")) {\n\t\treturn [];\n\t}\n\treturn [...allToolNames];\n}\n\nfunction getAllowedToolNamesForDomainDispatch(options: CreateAgentSessionOptions): string[] | undefined {\n\treturn options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n}\n\nfunction createEffectiveLoadoutAccessPolicy(\n\toptions: CreateAgentSessionOptions,\n\tresourceLoader: ResourceLoader,\n\tcwd: string,\n\tagentDir: string,\n\tprovider?: string,\n): LoadoutAccessPolicy | undefined {\n\tif (options.loadoutAccessPolicy) {\n\t\treturn options.loadoutAccessPolicy;\n\t}\n\n\tconst session = createDomainDispatchRuntimeSession({\n\t\tbaseToolNames: getDomainDispatchBaseToolNames(options),\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tallowedToolNames: getAllowedToolNamesForDomainDispatch(options),\n\t\texcludedToolNames: options.excludeTools,\n\t});\n\n\t// Grok OAuth: apply grok-harness domain loadout without requiring OMK_DOMAIN_ROUTING=1.\n\tif (provider) {\n\t\ttry {\n\t\t\tconst grokDispatch = tryGrokHarnessDispatch({\n\t\t\t\tprovider,\n\t\t\t\tsession,\n\t\t\t\tresourceLoader,\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tenv: process.env,\n\t\t\t});\n\t\t\tif (grokDispatch.loadoutAccessPolicy) {\n\t\t\t\treturn grokDispatch.loadoutAccessPolicy;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to opt-in domain routing.\n\t\t}\n\t}\n\n\tconst domainRoutingPrompt = options.domainRoutingPrompt?.trim();\n\tif (!domainRoutingPrompt || !isDomainRoutingEnabled(process.env)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst dispatch = tryDomainDispatch({\n\t\t\trole: \"coder\",\n\t\t\tinitialPrompt: domainRoutingPrompt,\n\t\t\tsession,\n\t\t\tresourceLoader,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tenv: process.env,\n\t\t});\n\t\treturn dispatch.loadoutAccessPolicy;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from 'omk-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst agentToolSettings = resolveAgentToolSettings(settingsManager);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\tlet replayLedger = options.replayLedger;\n\tlet replayGoalId = options.replayGoalId;\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!replayLedger && sessionManager.isPersisted() && sessionFile) {\n\t\treplayGoalId ??=\n\t\t\tsessionManager\n\t\t\t\t.getSessionId()\n\t\t\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t\t\t.replace(/^[._-]+|[._-]+$/g, \"\") || \"session\";\n\t\treplayLedger = new ReplayLedgerManager(replayGoalId, `${sessionFile}.replay.jsonl`);\n\t}\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore. Live open/resume always\n\t// inspects the transcript and either auto-repairs missing-only tail results\n\t// or fails closed on ambiguous corruption (ALG001-A).\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst transcriptRecovery = recoverSessionTranscriptOnOpen(sessionManager, existingSession.messages);\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\t// Loadout policy after model resolution so Grok OAuth can auto-apply grok-harness.\n\tconst effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(\n\t\toptions,\n\t\tresourceLoader,\n\t\tcwd,\n\t\tagentDir,\n\t\tmodel?.provider,\n\t);\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\", \"diagnostics\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames: string[] = (\n\t\toptions.tools ? [...options.tools] : options.noTools ? [] : defaultActiveToolNames\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tmodelContract: options.modelContract,\n\t\tmaxTokens: options.maxTokens,\n\t\tstreamFn: createSdkProviderStream({\n\t\t\tmodelRegistry,\n\t\t\tsettingsManager,\n\t\t\tmodelContract: options.modelContract,\n\t\t\tonRateLimit: (apiKey, snapshot, responseModel) => {\n\t\t\t\tif (apiKey && /^openai-codex(?:-|$)/.test(responseModel.provider)) {\n\t\t\t\t\trecordCodexPassiveUsage(apiKey, snapshot);\n\t\t\t\t} else if (apiKey && responseModel.provider === \"anthropic\") {\n\t\t\t\t\trecordClaudePassiveUsage(apiKey, snapshot);\n\t\t\t\t}\n\t\t\t},\n\t\t}),\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\ttoolTimeoutMs: agentToolSettings.toolTimeoutMs,\n\t\ttoolTimeouts: agentToolSettings.toolTimeouts,\n\t\ttoolScheduler: agentToolSettings.toolScheduler,\n\t\tmaxToolConcurrency: agentToolSettings.maxToolConcurrency,\n\t\tstrictExtensionClaims: agentToolSettings.strictExtensionClaims,\n\t\tcwd,\n\t\t// §5.5 Node identity resolver: symlink/hardlink/drive/UNC path aliases\n\t\t// conflict in the dag-v2 scheduler instead of racing (ALG002-A).\n\t\tresourceKeyResolver: createNodeResourceKeyResolver(),\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = transcriptRecovery.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tloadoutAccessPolicy: effectiveLoadoutAccessPolicy,\n\t\tbashSandboxPreflight: options.bashSandboxPreflight,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tmodelPinned: options.modelPinned,\n\t\ttranscriptRepair: transcriptRecovery.repair,\n\t\treplayLedger,\n\t\treplayGoalId,\n\t\treplayLaneId: options.replayLaneId,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tAgent,\n\ttype AgentMessage,\n\tinspectTranscriptIntegrity,\n\ttype ModelContract,\n\trepairTranscriptIntegrity,\n\ttype ThinkingLevel,\n} from \"omk-agent-core\";\nimport { createNodeResourceKeyResolver } from \"omk-agent-core/node\";\nimport { clampThinkingLevel, type Message, type Model, type ToolResultMessage } from \"omk-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { ReplayLedgerManager } from \"../guardrails/evidence-system.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type SessionTranscriptRepair } from \"./agent-session.ts\";\nimport { resolveAgentToolSettings } from \"./agent-tool-settings.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { DEVIN_HARNESS_SPEC } from \"./devin-harness.ts\";\nimport {\n\tcreateDomainDispatchRuntimeSession,\n\tisDomainRoutingEnabled,\n\tLOADOUT_HARNESS_RUNTIME,\n\ttryDomainDispatch,\n} from \"./domain-dispatch.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { GROK_HARNESS_SPEC } from \"./grok-harness.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { tryProviderHarnessDispatch } from \"./provider-harness-dispatch.ts\";\nimport { recordClaudePassiveUsage, recordCodexPassiveUsage } from \"./provider-usage.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { createSdkProviderStream } from \"./sdk-provider-stream.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { classifySessionTermination, SessionTerminationError } from \"./session-termination.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { BashSandboxPreflight } from \"./tools/bash.ts\";\nimport {\n\tallToolNames,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.omk/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Opt-in logical dispatch policy shared by the main loop and first-party summary stream. */\n\tmodelContract?: ModelContract;\n\t/** Optional main-loop output limit; a contract supplies the default cap when omitted. */\n\tmaxTokens?: number;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\t/** True when the user pinned `--model` / `--provider` for this process. */\n\tmodelPinned?: boolean;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, OMK enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/**\n\t * Optional prompt hint used only for opt-in domain routing (`OMK_DOMAIN_ROUTING=1`).\n\t * This text only selects a loadout policy and is never sent to the model.\n\t */\n\tdomainRoutingPrompt?: string;\n\t/** Optional loadout enforcement policy for SDK-created sessions. */\n\tloadoutAccessPolicy?: LoadoutAccessPolicy;\n\t/** Trusted sandbox preflight used for built-in local bash execution. */\n\tbashSandboxPreflight?: BashSandboxPreflight;\n\t/** Optional replay ledger shared with VerifiedEvidenceExecutor freshness checks. */\n\treplayLedger?: ReplayLedgerManager;\n\t/** Goal binding for AgentSession replay events; defaults to replayLedger.goalId. */\n\treplayGoalId?: string;\n\t/** Optional lane binding for AgentSession replay events. */\n\treplayLaneId?: string;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\ninterface SessionTranscriptRecovery {\n\tmessages: AgentMessage[];\n\trepair?: SessionTranscriptRepair;\n}\n\n/**\n * ALG001-A: inspect the restored transcript on every live session open/resume.\n *\n * - A clean transcript passes through untouched.\n * - Unambiguous missing-only tail results are auto-repaired: synthetic\n * terminal results (tool-result/v2 envelope) are persisted to the session\n * so the repair is durable and idempotent, together with a durable\n * `transcript_repaired` audit entry.\n * - Any duplicate/orphan/duplicate-call/interleaved corruption marks the\n * session (`session_corrupt` entry, once) and fails closed.\n */\nfunction recoverSessionTranscriptOnOpen(\n\tsessionManager: SessionManager,\n\tmessages: AgentMessage[],\n): SessionTranscriptRecovery {\n\tconst report = inspectTranscriptIntegrity(messages);\n\tif (report.ok) {\n\t\treturn { messages };\n\t}\n\n\tlet repaired: AgentMessage[];\n\ttry {\n\t\trepaired = repairTranscriptIntegrity(messages, \"Tool result missing; synthesized during session resume recovery\");\n\t} catch {\n\t\tconst alreadyMarked = sessionManager\n\t\t\t.getBranch()\n\t\t\t.some((entry) => entry.type === \"custom\" && entry.customType === \"session_corrupt\");\n\t\tif (!alreadyMarked) {\n\t\t\tsessionManager.appendCustomEntry(\"session_corrupt\", {\n\t\t\t\tissues: report.issues.map((issue) => ({\n\t\t\t\t\tkind: issue.kind,\n\t\t\t\t\ttoolCallId: issue.toolCallId,\n\t\t\t\t\t...(issue.toolName === undefined ? {} : { toolName: issue.toolName }),\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst summary = report.issues.map((issue) => `${issue.kind}:${issue.toolCallId}`).join(\", \");\n\t\tconst firstIssue = report.issues[0]?.kind ?? \"missing_result\";\n\t\tconst termination = classifySessionTermination({\n\t\t\tsessionId: sessionManager.getSessionId(),\n\t\t\trunId: `resume-${randomUUID()}`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsource: \"inferred_on_resume\",\n\t\t\tmessage: \"Session transcript has ambiguous tool-result corruption.\",\n\t\t\tcause: { area: \"transcript\", code: firstIssue },\n\t\t\tsideEffects: \"possible\",\n\t\t});\n\t\tthrow new SessionTerminationError(\n\t\t\t`Cannot open session: corrupt tool transcript (${summary}). ` +\n\t\t\t\t\"The session has been marked corrupt; repair it explicitly before resuming.\",\n\t\t\ttermination,\n\t\t);\n\t}\n\n\tconst inserted = repaired.slice(messages.length) as ToolResultMessage[];\n\tif (inserted.length === 0) {\n\t\treturn { messages: repaired };\n\t}\n\tfor (const message of inserted) {\n\t\tsessionManager.appendMessage(message);\n\t}\n\tconst insertedToolCallIds = inserted.map((message) => message.toolCallId);\n\tsessionManager.appendCustomEntry(\"transcript_repaired\", { insertedToolCallIds, reason: \"resume\" });\n\treturn { messages: repaired, repair: { insertedToolCallIds, reason: \"resume\" } };\n}\n\nfunction getDomainDispatchBaseToolNames(options: CreateAgentSessionOptions): string[] {\n\tif (!options.tools && (options.noTools === \"all\" || options.noTools === \"builtin\")) {\n\t\treturn [];\n\t}\n\treturn [...allToolNames];\n}\n\nfunction getAllowedToolNamesForDomainDispatch(options: CreateAgentSessionOptions): string[] | undefined {\n\treturn options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n}\n\nfunction createEffectiveLoadoutAccessPolicy(\n\toptions: CreateAgentSessionOptions,\n\tresourceLoader: ResourceLoader,\n\tcwd: string,\n\tagentDir: string,\n\tprovider?: string,\n): LoadoutAccessPolicy | undefined {\n\tif (options.loadoutAccessPolicy) {\n\t\treturn options.loadoutAccessPolicy;\n\t}\n\n\tconst session = createDomainDispatchRuntimeSession({\n\t\tbaseToolNames: getDomainDispatchBaseToolNames(options),\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tallowedToolNames: getAllowedToolNamesForDomainDispatch(options),\n\t\texcludedToolNames: options.excludeTools,\n\t});\n\n\t// Provider harnesses (Grok OAuth → grok-harness, Devin → devin-harness) apply their\n\t// domain loadout without requiring OMK_DOMAIN_ROUTING=1.\n\tif (provider) {\n\t\tfor (const spec of [GROK_HARNESS_SPEC, DEVIN_HARNESS_SPEC]) {\n\t\t\ttry {\n\t\t\t\tconst result = tryProviderHarnessDispatch(spec, LOADOUT_HARNESS_RUNTIME, {\n\t\t\t\t\tprovider,\n\t\t\t\t\tsession,\n\t\t\t\t\tresourceLoader,\n\t\t\t\t\tcwd,\n\t\t\t\t\tagentDir,\n\t\t\t\t\tenv: process.env,\n\t\t\t\t});\n\t\t\t\tif (result.loadoutAccessPolicy) {\n\t\t\t\t\treturn result.loadoutAccessPolicy;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Fall through to opt-in domain routing.\n\t\t\t}\n\t\t}\n\t}\n\n\tconst domainRoutingPrompt = options.domainRoutingPrompt?.trim();\n\tif (!domainRoutingPrompt || !isDomainRoutingEnabled(process.env)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst dispatch = tryDomainDispatch({\n\t\t\trole: \"coder\",\n\t\t\tinitialPrompt: domainRoutingPrompt,\n\t\t\tsession,\n\t\t\tresourceLoader,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tenv: process.env,\n\t\t});\n\t\treturn dispatch.loadoutAccessPolicy;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from 'omk-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst agentToolSettings = resolveAgentToolSettings(settingsManager);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\tlet replayLedger = options.replayLedger;\n\tlet replayGoalId = options.replayGoalId;\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!replayLedger && sessionManager.isPersisted() && sessionFile) {\n\t\treplayGoalId ??=\n\t\t\tsessionManager\n\t\t\t\t.getSessionId()\n\t\t\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t\t\t.replace(/^[._-]+|[._-]+$/g, \"\") || \"session\";\n\t\treplayLedger = new ReplayLedgerManager(replayGoalId, `${sessionFile}.replay.jsonl`);\n\t}\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore. Live open/resume always\n\t// inspects the transcript and either auto-repairs missing-only tail results\n\t// or fails closed on ambiguous corruption (ALG001-A).\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst transcriptRecovery = recoverSessionTranscriptOnOpen(sessionManager, existingSession.messages);\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\t// Loadout policy after model resolution so provider harnesses (grok-harness, devin-harness) can auto-apply.\n\tconst effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(\n\t\toptions,\n\t\tresourceLoader,\n\t\tcwd,\n\t\tagentDir,\n\t\tmodel?.provider,\n\t);\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\", \"diagnostics\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames: string[] = (\n\t\toptions.tools ? [...options.tools] : options.noTools ? [] : defaultActiveToolNames\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tmodelContract: options.modelContract,\n\t\tmaxTokens: options.maxTokens,\n\t\tstreamFn: createSdkProviderStream({\n\t\t\tmodelRegistry,\n\t\t\tsettingsManager,\n\t\t\tmodelContract: options.modelContract,\n\t\t\tonRateLimit: (apiKey, snapshot, responseModel) => {\n\t\t\t\tif (apiKey && /^openai-codex(?:-|$)/.test(responseModel.provider)) {\n\t\t\t\t\trecordCodexPassiveUsage(apiKey, snapshot);\n\t\t\t\t} else if (apiKey && responseModel.provider === \"anthropic\") {\n\t\t\t\t\trecordClaudePassiveUsage(apiKey, snapshot);\n\t\t\t\t}\n\t\t\t},\n\t\t}),\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\ttoolTimeoutMs: agentToolSettings.toolTimeoutMs,\n\t\ttoolTimeouts: agentToolSettings.toolTimeouts,\n\t\ttoolScheduler: agentToolSettings.toolScheduler,\n\t\tmaxToolConcurrency: agentToolSettings.maxToolConcurrency,\n\t\tstrictExtensionClaims: agentToolSettings.strictExtensionClaims,\n\t\tcwd,\n\t\t// §5.5 Node identity resolver: symlink/hardlink/drive/UNC path aliases\n\t\t// conflict in the dag-v2 scheduler instead of racing (ALG002-A).\n\t\tresourceKeyResolver: createNodeResourceKeyResolver(),\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = transcriptRecovery.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tloadoutAccessPolicy: effectiveLoadoutAccessPolicy,\n\t\tbashSandboxPreflight: options.bashSandboxPreflight,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tmodelPinned: options.modelPinned,\n\t\ttranscriptRepair: transcriptRecovery.repair,\n\t\treplayLedger,\n\t\treplayGoalId,\n\t\treplayLaneId: options.replayLaneId,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
package/dist/core/sdk.js CHANGED
@@ -11,11 +11,13 @@ import { resolveAgentToolSettings } from "./agent-tool-settings.js";
11
11
  import { formatNoModelsAvailableMessage } from "./auth-guidance.js";
12
12
  import { AuthStorage } from "./auth-storage.js";
13
13
  import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
14
- import { createDomainDispatchRuntimeSession, isDomainRoutingEnabled, tryDomainDispatch } from "./domain-dispatch.js";
15
- import { tryGrokHarnessDispatch } from "./grok-harness-dispatch.js";
14
+ import { DEVIN_HARNESS_SPEC } from "./devin-harness.js";
15
+ import { createDomainDispatchRuntimeSession, isDomainRoutingEnabled, LOADOUT_HARNESS_RUNTIME, tryDomainDispatch, } from "./domain-dispatch.js";
16
+ import { GROK_HARNESS_SPEC } from "./grok-harness.js";
16
17
  import { convertToLlm } from "./messages.js";
17
18
  import { ModelRegistry } from "./model-registry.js";
18
19
  import { findInitialModel } from "./model-resolver.js";
20
+ import { tryProviderHarnessDispatch } from "./provider-harness-dispatch.js";
19
21
  import { recordClaudePassiveUsage, recordCodexPassiveUsage } from "./provider-usage.js";
20
22
  import { DefaultResourceLoader } from "./resource-loader.js";
21
23
  import { createSdkProviderStream } from "./sdk-provider-stream.js";
@@ -111,23 +113,26 @@ function createEffectiveLoadoutAccessPolicy(options, resourceLoader, cwd, agentD
111
113
  allowedToolNames: getAllowedToolNamesForDomainDispatch(options),
112
114
  excludedToolNames: options.excludeTools,
113
115
  });
114
- // Grok OAuth: apply grok-harness domain loadout without requiring OMK_DOMAIN_ROUTING=1.
116
+ // Provider harnesses (Grok OAuth → grok-harness, Devin → devin-harness) apply their
117
+ // domain loadout without requiring OMK_DOMAIN_ROUTING=1.
115
118
  if (provider) {
116
- try {
117
- const grokDispatch = tryGrokHarnessDispatch({
118
- provider,
119
- session,
120
- resourceLoader,
121
- cwd,
122
- agentDir,
123
- env: process.env,
124
- });
125
- if (grokDispatch.loadoutAccessPolicy) {
126
- return grokDispatch.loadoutAccessPolicy;
119
+ for (const spec of [GROK_HARNESS_SPEC, DEVIN_HARNESS_SPEC]) {
120
+ try {
121
+ const result = tryProviderHarnessDispatch(spec, LOADOUT_HARNESS_RUNTIME, {
122
+ provider,
123
+ session,
124
+ resourceLoader,
125
+ cwd,
126
+ agentDir,
127
+ env: process.env,
128
+ });
129
+ if (result.loadoutAccessPolicy) {
130
+ return result.loadoutAccessPolicy;
131
+ }
132
+ }
133
+ catch {
134
+ // Fall through to opt-in domain routing.
127
135
  }
128
- }
129
- catch {
130
- // Fall through to opt-in domain routing.
131
136
  }
132
137
  }
133
138
  const domainRoutingPrompt = options.domainRoutingPrompt?.trim();
@@ -250,7 +255,7 @@ export async function createAgentSession(options = {}) {
250
255
  modelFallbackMessage += `. Using ${model.provider}/${model.id}`;
251
256
  }
252
257
  }
253
- // Loadout policy after model resolution so Grok OAuth can auto-apply grok-harness.
258
+ // Loadout policy after model resolution so provider harnesses (grok-harness, devin-harness) can auto-apply.
254
259
  const effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(options, resourceLoader, cwd, agentDir, model?.provider);
255
260
  let thinkingLevel = options.thinkingLevel;
256
261
  // If session has data, restore thinking level from it
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tAgent,\n\ttype AgentMessage,\n\tinspectTranscriptIntegrity,\n\ttype ModelContract,\n\trepairTranscriptIntegrity,\n\ttype ThinkingLevel,\n} from \"omk-agent-core\";\nimport { createNodeResourceKeyResolver } from \"omk-agent-core/node\";\nimport { clampThinkingLevel, type Message, type Model, type ToolResultMessage } from \"omk-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { ReplayLedgerManager } from \"../guardrails/evidence-system.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type SessionTranscriptRepair } from \"./agent-session.ts\";\nimport { resolveAgentToolSettings } from \"./agent-tool-settings.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { createDomainDispatchRuntimeSession, isDomainRoutingEnabled, tryDomainDispatch } from \"./domain-dispatch.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { tryGrokHarnessDispatch } from \"./grok-harness-dispatch.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { recordClaudePassiveUsage, recordCodexPassiveUsage } from \"./provider-usage.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { createSdkProviderStream } from \"./sdk-provider-stream.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { classifySessionTermination, SessionTerminationError } from \"./session-termination.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { BashSandboxPreflight } from \"./tools/bash.ts\";\nimport {\n\tallToolNames,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.omk/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Opt-in logical dispatch policy shared by the main loop and first-party summary stream. */\n\tmodelContract?: ModelContract;\n\t/** Optional main-loop output limit; a contract supplies the default cap when omitted. */\n\tmaxTokens?: number;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\t/** True when the user pinned `--model` / `--provider` for this process. */\n\tmodelPinned?: boolean;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, OMK enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/**\n\t * Optional prompt hint used only for opt-in domain routing (`OMK_DOMAIN_ROUTING=1`).\n\t * This text only selects a loadout policy and is never sent to the model.\n\t */\n\tdomainRoutingPrompt?: string;\n\t/** Optional loadout enforcement policy for SDK-created sessions. */\n\tloadoutAccessPolicy?: LoadoutAccessPolicy;\n\t/** Trusted sandbox preflight used for built-in local bash execution. */\n\tbashSandboxPreflight?: BashSandboxPreflight;\n\t/** Optional replay ledger shared with VerifiedEvidenceExecutor freshness checks. */\n\treplayLedger?: ReplayLedgerManager;\n\t/** Goal binding for AgentSession replay events; defaults to replayLedger.goalId. */\n\treplayGoalId?: string;\n\t/** Optional lane binding for AgentSession replay events. */\n\treplayLaneId?: string;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\ninterface SessionTranscriptRecovery {\n\tmessages: AgentMessage[];\n\trepair?: SessionTranscriptRepair;\n}\n\n/**\n * ALG001-A: inspect the restored transcript on every live session open/resume.\n *\n * - A clean transcript passes through untouched.\n * - Unambiguous missing-only tail results are auto-repaired: synthetic\n * terminal results (tool-result/v2 envelope) are persisted to the session\n * so the repair is durable and idempotent, together with a durable\n * `transcript_repaired` audit entry.\n * - Any duplicate/orphan/duplicate-call/interleaved corruption marks the\n * session (`session_corrupt` entry, once) and fails closed.\n */\nfunction recoverSessionTranscriptOnOpen(\n\tsessionManager: SessionManager,\n\tmessages: AgentMessage[],\n): SessionTranscriptRecovery {\n\tconst report = inspectTranscriptIntegrity(messages);\n\tif (report.ok) {\n\t\treturn { messages };\n\t}\n\n\tlet repaired: AgentMessage[];\n\ttry {\n\t\trepaired = repairTranscriptIntegrity(messages, \"Tool result missing; synthesized during session resume recovery\");\n\t} catch {\n\t\tconst alreadyMarked = sessionManager\n\t\t\t.getBranch()\n\t\t\t.some((entry) => entry.type === \"custom\" && entry.customType === \"session_corrupt\");\n\t\tif (!alreadyMarked) {\n\t\t\tsessionManager.appendCustomEntry(\"session_corrupt\", {\n\t\t\t\tissues: report.issues.map((issue) => ({\n\t\t\t\t\tkind: issue.kind,\n\t\t\t\t\ttoolCallId: issue.toolCallId,\n\t\t\t\t\t...(issue.toolName === undefined ? {} : { toolName: issue.toolName }),\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst summary = report.issues.map((issue) => `${issue.kind}:${issue.toolCallId}`).join(\", \");\n\t\tconst firstIssue = report.issues[0]?.kind ?? \"missing_result\";\n\t\tconst termination = classifySessionTermination({\n\t\t\tsessionId: sessionManager.getSessionId(),\n\t\t\trunId: `resume-${randomUUID()}`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsource: \"inferred_on_resume\",\n\t\t\tmessage: \"Session transcript has ambiguous tool-result corruption.\",\n\t\t\tcause: { area: \"transcript\", code: firstIssue },\n\t\t\tsideEffects: \"possible\",\n\t\t});\n\t\tthrow new SessionTerminationError(\n\t\t\t`Cannot open session: corrupt tool transcript (${summary}). ` +\n\t\t\t\t\"The session has been marked corrupt; repair it explicitly before resuming.\",\n\t\t\ttermination,\n\t\t);\n\t}\n\n\tconst inserted = repaired.slice(messages.length) as ToolResultMessage[];\n\tif (inserted.length === 0) {\n\t\treturn { messages: repaired };\n\t}\n\tfor (const message of inserted) {\n\t\tsessionManager.appendMessage(message);\n\t}\n\tconst insertedToolCallIds = inserted.map((message) => message.toolCallId);\n\tsessionManager.appendCustomEntry(\"transcript_repaired\", { insertedToolCallIds, reason: \"resume\" });\n\treturn { messages: repaired, repair: { insertedToolCallIds, reason: \"resume\" } };\n}\n\nfunction getDomainDispatchBaseToolNames(options: CreateAgentSessionOptions): string[] {\n\tif (!options.tools && (options.noTools === \"all\" || options.noTools === \"builtin\")) {\n\t\treturn [];\n\t}\n\treturn [...allToolNames];\n}\n\nfunction getAllowedToolNamesForDomainDispatch(options: CreateAgentSessionOptions): string[] | undefined {\n\treturn options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n}\n\nfunction createEffectiveLoadoutAccessPolicy(\n\toptions: CreateAgentSessionOptions,\n\tresourceLoader: ResourceLoader,\n\tcwd: string,\n\tagentDir: string,\n\tprovider?: string,\n): LoadoutAccessPolicy | undefined {\n\tif (options.loadoutAccessPolicy) {\n\t\treturn options.loadoutAccessPolicy;\n\t}\n\n\tconst session = createDomainDispatchRuntimeSession({\n\t\tbaseToolNames: getDomainDispatchBaseToolNames(options),\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tallowedToolNames: getAllowedToolNamesForDomainDispatch(options),\n\t\texcludedToolNames: options.excludeTools,\n\t});\n\n\t// Grok OAuth: apply grok-harness domain loadout without requiring OMK_DOMAIN_ROUTING=1.\n\tif (provider) {\n\t\ttry {\n\t\t\tconst grokDispatch = tryGrokHarnessDispatch({\n\t\t\t\tprovider,\n\t\t\t\tsession,\n\t\t\t\tresourceLoader,\n\t\t\t\tcwd,\n\t\t\t\tagentDir,\n\t\t\t\tenv: process.env,\n\t\t\t});\n\t\t\tif (grokDispatch.loadoutAccessPolicy) {\n\t\t\t\treturn grokDispatch.loadoutAccessPolicy;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Fall through to opt-in domain routing.\n\t\t}\n\t}\n\n\tconst domainRoutingPrompt = options.domainRoutingPrompt?.trim();\n\tif (!domainRoutingPrompt || !isDomainRoutingEnabled(process.env)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst dispatch = tryDomainDispatch({\n\t\t\trole: \"coder\",\n\t\t\tinitialPrompt: domainRoutingPrompt,\n\t\t\tsession,\n\t\t\tresourceLoader,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tenv: process.env,\n\t\t});\n\t\treturn dispatch.loadoutAccessPolicy;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from 'omk-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst agentToolSettings = resolveAgentToolSettings(settingsManager);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\tlet replayLedger = options.replayLedger;\n\tlet replayGoalId = options.replayGoalId;\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!replayLedger && sessionManager.isPersisted() && sessionFile) {\n\t\treplayGoalId ??=\n\t\t\tsessionManager\n\t\t\t\t.getSessionId()\n\t\t\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t\t\t.replace(/^[._-]+|[._-]+$/g, \"\") || \"session\";\n\t\treplayLedger = new ReplayLedgerManager(replayGoalId, `${sessionFile}.replay.jsonl`);\n\t}\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore. Live open/resume always\n\t// inspects the transcript and either auto-repairs missing-only tail results\n\t// or fails closed on ambiguous corruption (ALG001-A).\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst transcriptRecovery = recoverSessionTranscriptOnOpen(sessionManager, existingSession.messages);\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\t// Loadout policy after model resolution so Grok OAuth can auto-apply grok-harness.\n\tconst effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(\n\t\toptions,\n\t\tresourceLoader,\n\t\tcwd,\n\t\tagentDir,\n\t\tmodel?.provider,\n\t);\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\", \"diagnostics\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames: string[] = (\n\t\toptions.tools ? [...options.tools] : options.noTools ? [] : defaultActiveToolNames\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tmodelContract: options.modelContract,\n\t\tmaxTokens: options.maxTokens,\n\t\tstreamFn: createSdkProviderStream({\n\t\t\tmodelRegistry,\n\t\t\tsettingsManager,\n\t\t\tmodelContract: options.modelContract,\n\t\t\tonRateLimit: (apiKey, snapshot, responseModel) => {\n\t\t\t\tif (apiKey && /^openai-codex(?:-|$)/.test(responseModel.provider)) {\n\t\t\t\t\trecordCodexPassiveUsage(apiKey, snapshot);\n\t\t\t\t} else if (apiKey && responseModel.provider === \"anthropic\") {\n\t\t\t\t\trecordClaudePassiveUsage(apiKey, snapshot);\n\t\t\t\t}\n\t\t\t},\n\t\t}),\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\ttoolTimeoutMs: agentToolSettings.toolTimeoutMs,\n\t\ttoolTimeouts: agentToolSettings.toolTimeouts,\n\t\ttoolScheduler: agentToolSettings.toolScheduler,\n\t\tmaxToolConcurrency: agentToolSettings.maxToolConcurrency,\n\t\tstrictExtensionClaims: agentToolSettings.strictExtensionClaims,\n\t\tcwd,\n\t\t// §5.5 Node identity resolver: symlink/hardlink/drive/UNC path aliases\n\t\t// conflict in the dag-v2 scheduler instead of racing (ALG002-A).\n\t\tresourceKeyResolver: createNodeResourceKeyResolver(),\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = transcriptRecovery.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tloadoutAccessPolicy: effectiveLoadoutAccessPolicy,\n\t\tbashSandboxPreflight: options.bashSandboxPreflight,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tmodelPinned: options.modelPinned,\n\t\ttranscriptRepair: transcriptRecovery.repair,\n\t\treplayLedger,\n\t\treplayGoalId,\n\t\treplayLaneId: options.replayLaneId,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
1
+ {"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../src/core/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACN,KAAK,EAEL,0BAA0B,EAE1B,yBAAyB,GAEzB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAoD,MAAM,QAAQ,CAAC;AAC9F,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAgC,MAAM,oBAAoB,CAAC;AAChF,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,8BAA8B,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACN,kCAAkC,EAClC,sBAAsB,EACtB,uBAAuB,EACvB,iBAAiB,GACjB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAExF,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEpC,OAAO,EACN,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,cAAc,EACd,eAAe,EAEf,qBAAqB,GACrB,MAAM,kBAAkB,CAAC;AAoF1B,aAAa;AAEb,cAAc,4BAA4B,CAAC;AAc3C,OAAO,EACN,qBAAqB;AACrB,kCAAkC;AAClC,iBAAiB,EACjB,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,GACZ,CAAC;AAEF,mBAAmB;AAEnB,SAAS,kBAAkB,GAAW;IACrC,OAAO,WAAW,EAAE,CAAC;AAAA,CACrB;AAOD;;;;;;;;;;GAUG;AACH,SAAS,8BAA8B,CACtC,cAA8B,EAC9B,QAAwB,EACI;IAC5B,MAAM,MAAM,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IACpD,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,EAAE,QAAQ,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,QAAwB,CAAC;IAC7B,IAAI,CAAC;QACJ,QAAQ,GAAG,yBAAyB,CAAC,QAAQ,EAAE,iEAAiE,CAAC,CAAC;IACnH,CAAC;IAAC,MAAM,CAAC;QACR,MAAM,aAAa,GAAG,cAAc;aAClC,SAAS,EAAE;aACX,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,UAAU,KAAK,iBAAiB,CAAC,CAAC;QACrF,IAAI,CAAC,aAAa,EAAE,CAAC;YACpB,cAAc,CAAC,iBAAiB,CAAC,iBAAiB,EAAE;gBACnD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBACrC,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,UAAU,EAAE,KAAK,CAAC,UAAU;oBAC5B,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;iBACrE,CAAC,CAAC;aACH,CAAC,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7F,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,gBAAgB,CAAC;QAC9D,MAAM,WAAW,GAAG,0BAA0B,CAAC;YAC9C,SAAS,EAAE,cAAc,CAAC,YAAY,EAAE;YACxC,KAAK,EAAE,UAAU,UAAU,EAAE,EAAE;YAC/B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,oBAAoB;YAC5B,OAAO,EAAE,0DAA0D;YACnE,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE;YAC/C,WAAW,EAAE,UAAU;SACvB,CAAC,CAAC;QACH,MAAM,IAAI,uBAAuB,CAChC,iDAAiD,OAAO,KAAK;YAC5D,4EAA4E,EAC7E,WAAW,CACX,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAwB,CAAC;IACxE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAC/B,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAChC,cAAc,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,mBAAmB,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC1E,cAAc,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,EAAE,mBAAmB,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,mBAAmB,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;AAAA,CACjF;AAED,SAAS,8BAA8B,CAAC,OAAkC,EAAY;IACrF,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,KAAK,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,EAAE,CAAC;QACpF,OAAO,EAAE,CAAC;IACX,CAAC;IACD,OAAO,CAAC,GAAG,YAAY,CAAC,CAAC;AAAA,CACzB;AAED,SAAS,oCAAoC,CAAC,OAAkC,EAAwB;IACvG,OAAO,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AAAA,CACrE;AAED,SAAS,kCAAkC,CAC1C,OAAkC,EAClC,cAA8B,EAC9B,GAAW,EACX,QAAgB,EAChB,QAAiB,EACiB;IAClC,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,mBAAmB,CAAC;IACpC,CAAC;IAED,MAAM,OAAO,GAAG,kCAAkC,CAAC;QAClD,aAAa,EAAE,8BAA8B,CAAC,OAAO,CAAC;QACtD,cAAc;QACd,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,gBAAgB,EAAE,oCAAoC,CAAC,OAAO,CAAC;QAC/D,iBAAiB,EAAE,OAAO,CAAC,YAAY;KACvC,CAAC,CAAC;IAEH,wFAAoF;IACpF,yDAAyD;IACzD,IAAI,QAAQ,EAAE,CAAC;QACd,KAAK,MAAM,IAAI,IAAI,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,EAAE,CAAC;YAC5D,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,0BAA0B,CAAC,IAAI,EAAE,uBAAuB,EAAE;oBACxE,QAAQ;oBACR,OAAO;oBACP,cAAc;oBACd,GAAG;oBACH,QAAQ;oBACR,GAAG,EAAE,OAAO,CAAC,GAAG;iBAChB,CAAC,CAAC;gBACH,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;oBAChC,OAAO,MAAM,CAAC,mBAAmB,CAAC;gBACnC,CAAC;YACF,CAAC;YAAC,MAAM,CAAC;gBACR,yCAAyC;YAC1C,CAAC;QACF,CAAC;IACF,CAAC;IAED,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,EAAE,IAAI,EAAE,CAAC;IAChE,IAAI,CAAC,mBAAmB,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACJ,MAAM,QAAQ,GAAG,iBAAiB,CAAC;YAClC,IAAI,EAAE,OAAO;YACb,aAAa,EAAE,mBAAmB;YAClC,OAAO;YACP,cAAc;YACd,GAAG;YACH,QAAQ;YACR,GAAG,EAAE,OAAO,CAAC,GAAG;SAChB,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,mBAAmB,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,SAAS,CAAC;IAClB,CAAC;AAAA,CACD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAO,GAA8B,EAAE,EAAqC;IACpH,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC1F,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC;IACzF,IAAI,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAE5C,uDAAuD;IACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAChF,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAE7F,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACzF,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,eAAe,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,EAAE,oBAAoB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IACjH,IAAI,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IACxC,IAAI,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IACxC,MAAM,WAAW,GAAG,cAAc,CAAC,cAAc,EAAE,CAAC;IACpD,IAAI,CAAC,YAAY,IAAI,cAAc,CAAC,WAAW,EAAE,IAAI,WAAW,EAAE,CAAC;QAClE,YAAY;YACX,cAAc;iBACZ,YAAY,EAAE;iBACd,OAAO,CAAC,mBAAmB,EAAE,GAAG,CAAC;iBACjC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC;QAChD,YAAY,GAAG,IAAI,mBAAmB,CAAC,YAAY,EAAE,GAAG,WAAW,eAAe,CAAC,CAAC;IACrF,CAAC;IAED,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,cAAc,GAAG,IAAI,qBAAqB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;QAC/E,MAAM,cAAc,CAAC,MAAM,EAAE,CAAC;QAC9B,IAAI,CAAC,uBAAuB,CAAC,CAAC;IAC/B,CAAC;IAED,yEAAyE;IACzE,4EAA4E;IAC5E,sDAAsD;IACtD,MAAM,eAAe,GAAG,cAAc,CAAC,mBAAmB,EAAE,CAAC;IAC7D,MAAM,kBAAkB,GAAG,8BAA8B,CAAC,cAAc,EAAE,eAAe,CAAC,QAAQ,CAAC,CAAC;IACpG,MAAM,kBAAkB,GAAG,eAAe,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IAC/D,MAAM,gBAAgB,GAAG,cAAc,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,uBAAuB,CAAC,CAAC;IAE5G,IAAI,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC1B,IAAI,oBAAwC,CAAC;IAE7C,oDAAoD;IACpD,IAAI,CAAC,KAAK,IAAI,kBAAkB,IAAI,eAAe,CAAC,KAAK,EAAE,CAAC;QAC3D,MAAM,aAAa,GAAG,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACxG,IAAI,aAAa,IAAI,aAAa,CAAC,iBAAiB,CAAC,aAAa,CAAC,EAAE,CAAC;YACrE,KAAK,GAAG,aAAa,CAAC;QACvB,CAAC;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,oBAAoB,GAAG,2BAA2B,eAAe,CAAC,KAAK,CAAC,QAAQ,IAAI,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;QACrH,CAAC;IACF,CAAC;IAED,4FAA4F;IAC5F,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;YACrC,YAAY,EAAE,EAAE;YAChB,YAAY,EAAE,kBAAkB;YAChC,eAAe,EAAE,eAAe,CAAC,kBAAkB,EAAE;YACrD,cAAc,EAAE,eAAe,CAAC,eAAe,EAAE;YACjD,oBAAoB,EAAE,eAAe,CAAC,uBAAuB,EAAE;YAC/D,aAAa;SACb,CAAC,CAAC;QACH,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QACrB,IAAI,CAAC,KAAK,EAAE,CAAC;YACZ,oBAAoB,GAAG,8BAA8B,EAAE,CAAC;QACzD,CAAC;aAAM,IAAI,oBAAoB,EAAE,CAAC;YACjC,oBAAoB,IAAI,WAAW,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;QACjE,CAAC;IACF,CAAC;IAED,4GAA4G;IAC5G,MAAM,4BAA4B,GAAG,kCAAkC,CACtE,OAAO,EACP,cAAc,EACd,GAAG,EACH,QAAQ,EACR,KAAK,EAAE,QAAQ,CACf,CAAC;IAEF,IAAI,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAE1C,sDAAsD;IACtD,IAAI,aAAa,KAAK,SAAS,IAAI,kBAAkB,EAAE,CAAC;QACvD,aAAa,GAAG,gBAAgB;YAC/B,CAAC,CAAE,eAAe,CAAC,aAA+B;YAClD,CAAC,CAAC,CAAC,eAAe,CAAC,uBAAuB,EAAE,IAAI,sBAAsB,CAAC,CAAC;IAC1E,CAAC;IAED,gCAAgC;IAChC,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QACjC,aAAa,GAAG,eAAe,CAAC,uBAAuB,EAAE,IAAI,sBAAsB,CAAC;IACrF,CAAC;IAED,8BAA8B;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,aAAa,GAAG,KAAK,CAAC;IACvB,CAAC;SAAM,CAAC;QACP,aAAa,GAAG,kBAAkB,CAAC,KAAK,EAAE,aAAa,CAAkB,CAAC;IAC3E,CAAC;IAED,MAAM,sBAAsB,GAAe,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;IAC5F,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACvF,MAAM,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAC/C,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvF,MAAM,sBAAsB,GAAa,CACxC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAClF,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,mBAAmB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAEpD,IAAI,KAAY,CAAC;IAEjB,+FAA+F;IAC/F,MAAM,2BAA2B,GAAG,CAAC,QAAwB,EAAa,EAAE,CAAC;QAC5E,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QACzC,+DAA+D;QAC/D,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,EAAE,CAAC;YACvC,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,6EAA6E;QAC7E,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC;YAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBACtD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;gBAC5B,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;oBAC1D,IAAI,SAAS,EAAE,CAAC;wBACf,MAAM,eAAe,GAAG,OAAO;6BAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACV,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC,CAAC,CAAC,CAAC,CACtF;6BACA,MAAM,CACN,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE;wBACb,wDAAwD;wBACxD,CAAC,CACA,CAAC,CAAC,IAAI,KAAK,MAAM;4BACjB,CAAC,CAAC,IAAI,KAAK,4BAA4B;4BACvC,CAAC,GAAG,CAAC;4BACL,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM;4BACzB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAoC,CAAC,IAAI,KAAK,4BAA4B,CACpF,CACF,CAAC;wBACH,OAAO,EAAE,GAAG,GAAG,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC;oBAC7C,CAAC;gBACF,CAAC;YACF,CAAC;YACD,OAAO,GAAG,CAAC;QAAA,CACX,CAAC,CAAC;IAAA,CACH,CAAC;IAEF,MAAM,kBAAkB,GAAkC,EAAE,CAAC;IAE7D,KAAK,GAAG,IAAI,KAAK,CAAC;QACjB,YAAY,EAAE;YACb,YAAY,EAAE,EAAE;YAChB,KAAK;YACL,aAAa;YACb,KAAK,EAAE,EAAE;SACT;QACD,YAAY,EAAE,2BAA2B;QACzC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,uBAAuB,CAAC;YACjC,aAAa;YACb,eAAe;YACf,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,WAAW,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE,CAAC;gBACjD,IAAI,MAAM,IAAI,sBAAsB,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACnE,uBAAuB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAC3C,CAAC;qBAAM,IAAI,MAAM,IAAI,aAAa,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;oBAC7D,wBAAwB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAC5C,CAAC;YAAA,CACD;SACD,CAAC;QACF,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC;YAC1C,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,yBAAyB,CAAC,EAAE,CAAC;gBACrD,OAAO,OAAO,CAAC;YAChB,CAAC;YACD,OAAO,MAAM,CAAC,yBAAyB,CAAC,OAAO,CAAC,CAAC;QAAA,CACjD;QACD,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC;YAC1C,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,yBAAyB,CAAC,EAAE,CAAC;gBACrD,OAAO;YACR,CAAC;YACD,MAAM,MAAM,CAAC,IAAI,CAAC;gBACjB,IAAI,EAAE,yBAAyB;gBAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,OAAO,EAAE,QAAQ,CAAC,OAAO;aACzB,CAAC,CAAC;QAAA,CACH;QACD,SAAS,EAAE,cAAc,CAAC,YAAY,EAAE;QACxC,gBAAgB,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC;YAC1C,IAAI,CAAC,MAAM;gBAAE,OAAO,QAAQ,CAAC;YAC7B,OAAO,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAAA,CACpC;QACD,YAAY,EAAE,eAAe,CAAC,eAAe,EAAE;QAC/C,YAAY,EAAE,eAAe,CAAC,eAAe,EAAE;QAC/C,SAAS,EAAE,eAAe,CAAC,YAAY,EAAE;QACzC,eAAe,EAAE,eAAe,CAAC,kBAAkB,EAAE;QACrD,eAAe,EAAE,eAAe,CAAC,wBAAwB,EAAE,CAAC,eAAe;QAC3E,aAAa,EAAE,iBAAiB,CAAC,aAAa;QAC9C,YAAY,EAAE,iBAAiB,CAAC,YAAY;QAC5C,aAAa,EAAE,iBAAiB,CAAC,aAAa;QAC9C,kBAAkB,EAAE,iBAAiB,CAAC,kBAAkB;QACxD,qBAAqB,EAAE,iBAAiB,CAAC,qBAAqB;QAC9D,GAAG;QACH,wEAAuE;QACvE,iEAAiE;QACjE,mBAAmB,EAAE,6BAA6B,EAAE;KACpD,CAAC,CAAC;IAEH,gDAAgD;IAChD,IAAI,kBAAkB,EAAE,CAAC;QACxB,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,kBAAkB,CAAC,QAAQ,CAAC;QACnD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACvB,cAAc,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;SAAM,CAAC;QACP,2FAA2F;QAC3F,IAAI,KAAK,EAAE,CAAC;YACX,cAAc,CAAC,iBAAiB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,cAAc,CAAC,yBAAyB,CAAC,aAAa,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,YAAY,CAAC;QAChC,KAAK;QACL,cAAc;QACd,eAAe;QACf,GAAG;QACH,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,cAAc;QACd,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,aAAa;QACb,sBAAsB;QACtB,gBAAgB;QAChB,iBAAiB;QACjB,kBAAkB;QAClB,mBAAmB,EAAE,4BAA4B;QACjD,oBAAoB,EAAE,OAAO,CAAC,oBAAoB;QAClD,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;QAC5C,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,gBAAgB,EAAE,kBAAkB,CAAC,MAAM;QAC3C,YAAY;QACZ,YAAY;QACZ,YAAY,EAAE,OAAO,CAAC,YAAY;KAClC,CAAC,CAAC;IACH,MAAM,gBAAgB,GAAG,cAAc,CAAC,aAAa,EAAE,CAAC;IAExD,OAAO;QACN,OAAO;QACP,gBAAgB;QAChB,oBAAoB;KACpB,CAAC;AAAA,CACF","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport {\n\tAgent,\n\ttype AgentMessage,\n\tinspectTranscriptIntegrity,\n\ttype ModelContract,\n\trepairTranscriptIntegrity,\n\ttype ThinkingLevel,\n} from \"omk-agent-core\";\nimport { createNodeResourceKeyResolver } from \"omk-agent-core/node\";\nimport { clampThinkingLevel, type Message, type Model, type ToolResultMessage } from \"omk-ai\";\nimport { getAgentDir } from \"../config.ts\";\nimport { ReplayLedgerManager } from \"../guardrails/evidence-system.ts\";\nimport { resolvePath } from \"../utils/paths.ts\";\nimport { AgentSession, type SessionTranscriptRepair } from \"./agent-session.ts\";\nimport { resolveAgentToolSettings } from \"./agent-tool-settings.ts\";\nimport { formatNoModelsAvailableMessage } from \"./auth-guidance.ts\";\nimport { AuthStorage } from \"./auth-storage.ts\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.ts\";\nimport { DEVIN_HARNESS_SPEC } from \"./devin-harness.ts\";\nimport {\n\tcreateDomainDispatchRuntimeSession,\n\tisDomainRoutingEnabled,\n\tLOADOUT_HARNESS_RUNTIME,\n\ttryDomainDispatch,\n} from \"./domain-dispatch.ts\";\nimport type { ExtensionRunner, LoadExtensionsResult, SessionStartEvent, ToolDefinition } from \"./extensions/index.ts\";\nimport { GROK_HARNESS_SPEC } from \"./grok-harness.ts\";\nimport type { LoadoutAccessPolicy } from \"./loadout-access-policy.ts\";\nimport { convertToLlm } from \"./messages.ts\";\nimport { ModelRegistry } from \"./model-registry.ts\";\nimport { findInitialModel } from \"./model-resolver.ts\";\nimport { tryProviderHarnessDispatch } from \"./provider-harness-dispatch.ts\";\nimport { recordClaudePassiveUsage, recordCodexPassiveUsage } from \"./provider-usage.ts\";\nimport type { ResourceLoader } from \"./resource-loader.ts\";\nimport { DefaultResourceLoader } from \"./resource-loader.ts\";\nimport { createSdkProviderStream } from \"./sdk-provider-stream.ts\";\nimport { getDefaultSessionDir, SessionManager } from \"./session-manager.ts\";\nimport { classifySessionTermination, SessionTerminationError } from \"./session-termination.ts\";\nimport { SettingsManager } from \"./settings-manager.ts\";\nimport { time } from \"./timings.ts\";\nimport type { BashSandboxPreflight } from \"./tools/bash.ts\";\nimport {\n\tallToolNames,\n\tcreateBashTool,\n\tcreateCodingTools,\n\tcreateEditTool,\n\tcreateFindTool,\n\tcreateGrepTool,\n\tcreateLsTool,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateWriteTool,\n\ttype ToolName,\n\twithFileMutationQueue,\n} from \"./tools/index.ts\";\n\nexport interface CreateAgentSessionOptions {\n\t/** Working directory for project-local discovery. Default: process.cwd() */\n\tcwd?: string;\n\t/** Global config directory. Default: ~/.omk/agent */\n\tagentDir?: string;\n\n\t/** Auth storage for credentials. Default: AuthStorage.create(agentDir/auth.json) */\n\tauthStorage?: AuthStorage;\n\t/** Model registry. Default: ModelRegistry.create(authStorage, agentDir/models.json) */\n\tmodelRegistry?: ModelRegistry;\n\n\t/** Model to use. Default: from settings, else first available */\n\tmodel?: Model<any>;\n\t/** Opt-in logical dispatch policy shared by the main loop and first-party summary stream. */\n\tmodelContract?: ModelContract;\n\t/** Optional main-loop output limit; a contract supplies the default cap when omitted. */\n\tmaxTokens?: number;\n\t/** Thinking level. Default: from settings, else 'medium' (clamped to model capabilities) */\n\tthinkingLevel?: ThinkingLevel;\n\t/** Models available for cycling (Ctrl+P in interactive mode) */\n\tscopedModels?: Array<{ model: Model<any>; thinkingLevel?: ThinkingLevel }>;\n\t/** True when the user pinned `--model` / `--provider` for this process. */\n\tmodelPinned?: boolean;\n\n\t/**\n\t * Optional default tool suppression mode when no explicit allowlist is provided.\n\t *\n\t * - \"all\": start with no tools enabled\n\t * - \"builtin\": disable the default built-in tools (read, bash, edit, write)\n\t * but keep extension/custom tools enabled\n\t */\n\tnoTools?: \"all\" | \"builtin\";\n\t/**\n\t * Optional allowlist of tool names.\n\t *\n\t * When omitted, OMK enables the default built-in tools (read, bash, edit, write)\n\t * and leaves extension/custom tools enabled unless `noTools` changes that default.\n\t * When provided, only the listed tool names are enabled.\n\t */\n\ttools?: string[];\n\t/** Optional denylist of tool names to disable. Applies after `tools` when both are provided. */\n\texcludeTools?: string[];\n\t/** Custom tools to register (in addition to built-in tools). */\n\tcustomTools?: ToolDefinition[];\n\n\t/** Resource loader. When omitted, DefaultResourceLoader is used. */\n\tresourceLoader?: ResourceLoader;\n\n\t/** Session manager. Default: SessionManager.create(cwd) */\n\tsessionManager?: SessionManager;\n\n\t/** Settings manager. Default: SettingsManager.create(cwd, agentDir) */\n\tsettingsManager?: SettingsManager;\n\t/** Session start event metadata for extension runtime startup. */\n\tsessionStartEvent?: SessionStartEvent;\n\t/**\n\t * Optional prompt hint used only for opt-in domain routing (`OMK_DOMAIN_ROUTING=1`).\n\t * This text only selects a loadout policy and is never sent to the model.\n\t */\n\tdomainRoutingPrompt?: string;\n\t/** Optional loadout enforcement policy for SDK-created sessions. */\n\tloadoutAccessPolicy?: LoadoutAccessPolicy;\n\t/** Trusted sandbox preflight used for built-in local bash execution. */\n\tbashSandboxPreflight?: BashSandboxPreflight;\n\t/** Optional replay ledger shared with VerifiedEvidenceExecutor freshness checks. */\n\treplayLedger?: ReplayLedgerManager;\n\t/** Goal binding for AgentSession replay events; defaults to replayLedger.goalId. */\n\treplayGoalId?: string;\n\t/** Optional lane binding for AgentSession replay events. */\n\treplayLaneId?: string;\n}\n\n/** Result from createAgentSession */\nexport interface CreateAgentSessionResult {\n\t/** The created session */\n\tsession: AgentSession;\n\t/** Extensions result (for UI context setup in interactive mode) */\n\textensionsResult: LoadExtensionsResult;\n\t/** Warning if session was restored with a different model than saved */\n\tmodelFallbackMessage?: string;\n}\n\n// Re-exports\n\nexport * from \"./agent-session-runtime.ts\";\nexport type {\n\tExtensionAPI,\n\tExtensionCommandContext,\n\tExtensionContext,\n\tExtensionFactory,\n\tSlashCommandInfo,\n\tSlashCommandSource,\n\tToolDefinition,\n} from \"./extensions/index.ts\";\nexport type { PromptTemplate } from \"./prompt-templates.ts\";\nexport type { Skill } from \"./skills.ts\";\nexport type { Tool } from \"./tools/index.ts\";\n\nexport {\n\twithFileMutationQueue,\n\t// Tool factories (for custom cwd)\n\tcreateCodingTools,\n\tcreateReadOnlyTools,\n\tcreateReadTool,\n\tcreateBashTool,\n\tcreateEditTool,\n\tcreateWriteTool,\n\tcreateGrepTool,\n\tcreateFindTool,\n\tcreateLsTool,\n};\n\n// Helper Functions\n\nfunction getDefaultAgentDir(): string {\n\treturn getAgentDir();\n}\n\ninterface SessionTranscriptRecovery {\n\tmessages: AgentMessage[];\n\trepair?: SessionTranscriptRepair;\n}\n\n/**\n * ALG001-A: inspect the restored transcript on every live session open/resume.\n *\n * - A clean transcript passes through untouched.\n * - Unambiguous missing-only tail results are auto-repaired: synthetic\n * terminal results (tool-result/v2 envelope) are persisted to the session\n * so the repair is durable and idempotent, together with a durable\n * `transcript_repaired` audit entry.\n * - Any duplicate/orphan/duplicate-call/interleaved corruption marks the\n * session (`session_corrupt` entry, once) and fails closed.\n */\nfunction recoverSessionTranscriptOnOpen(\n\tsessionManager: SessionManager,\n\tmessages: AgentMessage[],\n): SessionTranscriptRecovery {\n\tconst report = inspectTranscriptIntegrity(messages);\n\tif (report.ok) {\n\t\treturn { messages };\n\t}\n\n\tlet repaired: AgentMessage[];\n\ttry {\n\t\trepaired = repairTranscriptIntegrity(messages, \"Tool result missing; synthesized during session resume recovery\");\n\t} catch {\n\t\tconst alreadyMarked = sessionManager\n\t\t\t.getBranch()\n\t\t\t.some((entry) => entry.type === \"custom\" && entry.customType === \"session_corrupt\");\n\t\tif (!alreadyMarked) {\n\t\t\tsessionManager.appendCustomEntry(\"session_corrupt\", {\n\t\t\t\tissues: report.issues.map((issue) => ({\n\t\t\t\t\tkind: issue.kind,\n\t\t\t\t\ttoolCallId: issue.toolCallId,\n\t\t\t\t\t...(issue.toolName === undefined ? {} : { toolName: issue.toolName }),\n\t\t\t\t})),\n\t\t\t});\n\t\t}\n\t\tconst summary = report.issues.map((issue) => `${issue.kind}:${issue.toolCallId}`).join(\", \");\n\t\tconst firstIssue = report.issues[0]?.kind ?? \"missing_result\";\n\t\tconst termination = classifySessionTermination({\n\t\t\tsessionId: sessionManager.getSessionId(),\n\t\t\trunId: `resume-${randomUUID()}`,\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tsource: \"inferred_on_resume\",\n\t\t\tmessage: \"Session transcript has ambiguous tool-result corruption.\",\n\t\t\tcause: { area: \"transcript\", code: firstIssue },\n\t\t\tsideEffects: \"possible\",\n\t\t});\n\t\tthrow new SessionTerminationError(\n\t\t\t`Cannot open session: corrupt tool transcript (${summary}). ` +\n\t\t\t\t\"The session has been marked corrupt; repair it explicitly before resuming.\",\n\t\t\ttermination,\n\t\t);\n\t}\n\n\tconst inserted = repaired.slice(messages.length) as ToolResultMessage[];\n\tif (inserted.length === 0) {\n\t\treturn { messages: repaired };\n\t}\n\tfor (const message of inserted) {\n\t\tsessionManager.appendMessage(message);\n\t}\n\tconst insertedToolCallIds = inserted.map((message) => message.toolCallId);\n\tsessionManager.appendCustomEntry(\"transcript_repaired\", { insertedToolCallIds, reason: \"resume\" });\n\treturn { messages: repaired, repair: { insertedToolCallIds, reason: \"resume\" } };\n}\n\nfunction getDomainDispatchBaseToolNames(options: CreateAgentSessionOptions): string[] {\n\tif (!options.tools && (options.noTools === \"all\" || options.noTools === \"builtin\")) {\n\t\treturn [];\n\t}\n\treturn [...allToolNames];\n}\n\nfunction getAllowedToolNamesForDomainDispatch(options: CreateAgentSessionOptions): string[] | undefined {\n\treturn options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n}\n\nfunction createEffectiveLoadoutAccessPolicy(\n\toptions: CreateAgentSessionOptions,\n\tresourceLoader: ResourceLoader,\n\tcwd: string,\n\tagentDir: string,\n\tprovider?: string,\n): LoadoutAccessPolicy | undefined {\n\tif (options.loadoutAccessPolicy) {\n\t\treturn options.loadoutAccessPolicy;\n\t}\n\n\tconst session = createDomainDispatchRuntimeSession({\n\t\tbaseToolNames: getDomainDispatchBaseToolNames(options),\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tallowedToolNames: getAllowedToolNamesForDomainDispatch(options),\n\t\texcludedToolNames: options.excludeTools,\n\t});\n\n\t// Provider harnesses (Grok OAuth → grok-harness, Devin → devin-harness) apply their\n\t// domain loadout without requiring OMK_DOMAIN_ROUTING=1.\n\tif (provider) {\n\t\tfor (const spec of [GROK_HARNESS_SPEC, DEVIN_HARNESS_SPEC]) {\n\t\t\ttry {\n\t\t\t\tconst result = tryProviderHarnessDispatch(spec, LOADOUT_HARNESS_RUNTIME, {\n\t\t\t\t\tprovider,\n\t\t\t\t\tsession,\n\t\t\t\t\tresourceLoader,\n\t\t\t\t\tcwd,\n\t\t\t\t\tagentDir,\n\t\t\t\t\tenv: process.env,\n\t\t\t\t});\n\t\t\t\tif (result.loadoutAccessPolicy) {\n\t\t\t\t\treturn result.loadoutAccessPolicy;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// Fall through to opt-in domain routing.\n\t\t\t}\n\t\t}\n\t}\n\n\tconst domainRoutingPrompt = options.domainRoutingPrompt?.trim();\n\tif (!domainRoutingPrompt || !isDomainRoutingEnabled(process.env)) {\n\t\treturn undefined;\n\t}\n\n\ttry {\n\t\tconst dispatch = tryDomainDispatch({\n\t\t\trole: \"coder\",\n\t\t\tinitialPrompt: domainRoutingPrompt,\n\t\t\tsession,\n\t\t\tresourceLoader,\n\t\t\tcwd,\n\t\t\tagentDir,\n\t\t\tenv: process.env,\n\t\t});\n\t\treturn dispatch.loadoutAccessPolicy;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\n/**\n * Create an AgentSession with the specified options.\n *\n * @example\n * ```typescript\n * // Minimal - uses defaults\n * const { session } = await createAgentSession();\n *\n * // With explicit model\n * import { getModel } from 'omk-ai';\n * const { session } = await createAgentSession({\n * model: getModel('anthropic', 'claude-opus-4-5'),\n * thinkingLevel: 'high',\n * });\n *\n * // Continue previous session\n * const { session, modelFallbackMessage } = await createAgentSession({\n * continueSession: true,\n * });\n *\n * // Full control\n * const loader = new DefaultResourceLoader({\n * cwd: process.cwd(),\n * agentDir: getAgentDir(),\n * settingsManager: SettingsManager.create(),\n * });\n * await loader.reload();\n * const { session } = await createAgentSession({\n * model: myModel,\n * tools: [\"read\", \"bash\"],\n * resourceLoader: loader,\n * sessionManager: SessionManager.inMemory(),\n * });\n * ```\n */\nexport async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {\n\tconst cwd = resolvePath(options.cwd ?? options.sessionManager?.getCwd() ?? process.cwd());\n\tconst agentDir = options.agentDir ? resolvePath(options.agentDir) : getDefaultAgentDir();\n\tlet resourceLoader = options.resourceLoader;\n\n\t// Use provided or create AuthStorage and ModelRegistry\n\tconst authPath = options.agentDir ? join(agentDir, \"auth.json\") : undefined;\n\tconst modelsPath = options.agentDir ? join(agentDir, \"models.json\") : undefined;\n\tconst authStorage = options.authStorage ?? AuthStorage.create(authPath);\n\tconst modelRegistry = options.modelRegistry ?? ModelRegistry.create(authStorage, modelsPath);\n\n\tconst settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);\n\tconst agentToolSettings = resolveAgentToolSettings(settingsManager);\n\tconst sessionManager = options.sessionManager ?? SessionManager.create(cwd, getDefaultSessionDir(cwd, agentDir));\n\tlet replayLedger = options.replayLedger;\n\tlet replayGoalId = options.replayGoalId;\n\tconst sessionFile = sessionManager.getSessionFile();\n\tif (!replayLedger && sessionManager.isPersisted() && sessionFile) {\n\t\treplayGoalId ??=\n\t\t\tsessionManager\n\t\t\t\t.getSessionId()\n\t\t\t\t.replace(/[^A-Za-z0-9._-]+/g, \"-\")\n\t\t\t\t.replace(/^[._-]+|[._-]+$/g, \"\") || \"session\";\n\t\treplayLedger = new ReplayLedgerManager(replayGoalId, `${sessionFile}.replay.jsonl`);\n\t}\n\n\tif (!resourceLoader) {\n\t\tresourceLoader = new DefaultResourceLoader({ cwd, agentDir, settingsManager });\n\t\tawait resourceLoader.reload();\n\t\ttime(\"resourceLoader.reload\");\n\t}\n\n\t// Check if session has existing data to restore. Live open/resume always\n\t// inspects the transcript and either auto-repairs missing-only tail results\n\t// or fails closed on ambiguous corruption (ALG001-A).\n\tconst existingSession = sessionManager.buildSessionContext();\n\tconst transcriptRecovery = recoverSessionTranscriptOnOpen(sessionManager, existingSession.messages);\n\tconst hasExistingSession = existingSession.messages.length > 0;\n\tconst hasThinkingEntry = sessionManager.getBranch().some((entry) => entry.type === \"thinking_level_change\");\n\n\tlet model = options.model;\n\tlet modelFallbackMessage: string | undefined;\n\n\t// If session has data, try to restore model from it\n\tif (!model && hasExistingSession && existingSession.model) {\n\t\tconst restoredModel = modelRegistry.find(existingSession.model.provider, existingSession.model.modelId);\n\t\tif (restoredModel && modelRegistry.hasConfiguredAuth(restoredModel)) {\n\t\t\tmodel = restoredModel;\n\t\t}\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = `Could not restore model ${existingSession.model.provider}/${existingSession.model.modelId}`;\n\t\t}\n\t}\n\n\t// If still no model, use findInitialModel (checks settings default, then provider defaults)\n\tif (!model) {\n\t\tconst result = await findInitialModel({\n\t\t\tscopedModels: [],\n\t\t\tisContinuing: hasExistingSession,\n\t\t\tdefaultProvider: settingsManager.getDefaultProvider(),\n\t\t\tdefaultModelId: settingsManager.getDefaultModel(),\n\t\t\tdefaultThinkingLevel: settingsManager.getDefaultThinkingLevel(),\n\t\t\tmodelRegistry,\n\t\t});\n\t\tmodel = result.model;\n\t\tif (!model) {\n\t\t\tmodelFallbackMessage = formatNoModelsAvailableMessage();\n\t\t} else if (modelFallbackMessage) {\n\t\t\tmodelFallbackMessage += `. Using ${model.provider}/${model.id}`;\n\t\t}\n\t}\n\n\t// Loadout policy after model resolution so provider harnesses (grok-harness, devin-harness) can auto-apply.\n\tconst effectiveLoadoutAccessPolicy = createEffectiveLoadoutAccessPolicy(\n\t\toptions,\n\t\tresourceLoader,\n\t\tcwd,\n\t\tagentDir,\n\t\tmodel?.provider,\n\t);\n\n\tlet thinkingLevel = options.thinkingLevel;\n\n\t// If session has data, restore thinking level from it\n\tif (thinkingLevel === undefined && hasExistingSession) {\n\t\tthinkingLevel = hasThinkingEntry\n\t\t\t? (existingSession.thinkingLevel as ThinkingLevel)\n\t\t\t: (settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL);\n\t}\n\n\t// Fall back to settings default\n\tif (thinkingLevel === undefined) {\n\t\tthinkingLevel = settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;\n\t}\n\n\t// Clamp to model capabilities\n\tif (!model) {\n\t\tthinkingLevel = \"off\";\n\t} else {\n\t\tthinkingLevel = clampThinkingLevel(model, thinkingLevel) as ThinkingLevel;\n\t}\n\n\tconst defaultActiveToolNames: ToolName[] = [\"read\", \"bash\", \"edit\", \"write\", \"diagnostics\"];\n\tconst allowedToolNames = options.tools ?? (options.noTools === \"all\" ? [] : undefined);\n\tconst excludedToolNames = options.excludeTools;\n\tconst excludedToolNameSet = excludedToolNames ? new Set(excludedToolNames) : undefined;\n\tconst initialActiveToolNames: string[] = (\n\t\toptions.tools ? [...options.tools] : options.noTools ? [] : defaultActiveToolNames\n\t).filter((name) => !excludedToolNameSet?.has(name));\n\n\tlet agent: Agent;\n\n\t// Create convertToLlm wrapper that filters images if blockImages is enabled (defense-in-depth)\n\tconst convertToLlmWithBlockImages = (messages: AgentMessage[]): Message[] => {\n\t\tconst converted = convertToLlm(messages);\n\t\t// Check setting dynamically so mid-session changes take effect\n\t\tif (!settingsManager.getBlockImages()) {\n\t\t\treturn converted;\n\t\t}\n\t\t// Filter out ImageContent from all messages, replacing with text placeholder\n\t\treturn converted.map((msg) => {\n\t\t\tif (msg.role === \"user\" || msg.role === \"toolResult\") {\n\t\t\t\tconst content = msg.content;\n\t\t\t\tif (Array.isArray(content)) {\n\t\t\t\t\tconst hasImages = content.some((c) => c.type === \"image\");\n\t\t\t\t\tif (hasImages) {\n\t\t\t\t\t\tconst filteredContent = content\n\t\t\t\t\t\t\t.map((c) =>\n\t\t\t\t\t\t\t\tc.type === \"image\" ? { type: \"text\" as const, text: \"Image reading is disabled.\" } : c,\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t(c, i, arr) =>\n\t\t\t\t\t\t\t\t\t// Dedupe consecutive \"Image reading is disabled.\" texts\n\t\t\t\t\t\t\t\t\t!(\n\t\t\t\t\t\t\t\t\t\tc.type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\tc.text === \"Image reading is disabled.\" &&\n\t\t\t\t\t\t\t\t\t\ti > 0 &&\n\t\t\t\t\t\t\t\t\t\tarr[i - 1].type === \"text\" &&\n\t\t\t\t\t\t\t\t\t\t(arr[i - 1] as { type: \"text\"; text: string }).text === \"Image reading is disabled.\"\n\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\treturn { ...msg, content: filteredContent };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn msg;\n\t\t});\n\t};\n\n\tconst extensionRunnerRef: { current?: ExtensionRunner } = {};\n\n\tagent = new Agent({\n\t\tinitialState: {\n\t\t\tsystemPrompt: \"\",\n\t\t\tmodel,\n\t\t\tthinkingLevel,\n\t\t\ttools: [],\n\t\t},\n\t\tconvertToLlm: convertToLlmWithBlockImages,\n\t\tmodelContract: options.modelContract,\n\t\tmaxTokens: options.maxTokens,\n\t\tstreamFn: createSdkProviderStream({\n\t\t\tmodelRegistry,\n\t\t\tsettingsManager,\n\t\t\tmodelContract: options.modelContract,\n\t\t\tonRateLimit: (apiKey, snapshot, responseModel) => {\n\t\t\t\tif (apiKey && /^openai-codex(?:-|$)/.test(responseModel.provider)) {\n\t\t\t\t\trecordCodexPassiveUsage(apiKey, snapshot);\n\t\t\t\t} else if (apiKey && responseModel.provider === \"anthropic\") {\n\t\t\t\t\trecordClaudePassiveUsage(apiKey, snapshot);\n\t\t\t\t}\n\t\t\t},\n\t\t}),\n\t\tonPayload: async (payload, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"before_provider_request\")) {\n\t\t\t\treturn payload;\n\t\t\t}\n\t\t\treturn runner.emitBeforeProviderRequest(payload);\n\t\t},\n\t\tonResponse: async (response, _model) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner?.hasHandlers(\"after_provider_response\")) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait runner.emit({\n\t\t\t\ttype: \"after_provider_response\",\n\t\t\t\tstatus: response.status,\n\t\t\t\theaders: response.headers,\n\t\t\t});\n\t\t},\n\t\tsessionId: sessionManager.getSessionId(),\n\t\ttransformContext: async (messages) => {\n\t\t\tconst runner = extensionRunnerRef.current;\n\t\t\tif (!runner) return messages;\n\t\t\treturn runner.emitContext(messages);\n\t\t},\n\t\tsteeringMode: settingsManager.getSteeringMode(),\n\t\tfollowUpMode: settingsManager.getFollowUpMode(),\n\t\ttransport: settingsManager.getTransport(),\n\t\tthinkingBudgets: settingsManager.getThinkingBudgets(),\n\t\tmaxRetryDelayMs: settingsManager.getProviderRetrySettings().maxRetryDelayMs,\n\t\ttoolTimeoutMs: agentToolSettings.toolTimeoutMs,\n\t\ttoolTimeouts: agentToolSettings.toolTimeouts,\n\t\ttoolScheduler: agentToolSettings.toolScheduler,\n\t\tmaxToolConcurrency: agentToolSettings.maxToolConcurrency,\n\t\tstrictExtensionClaims: agentToolSettings.strictExtensionClaims,\n\t\tcwd,\n\t\t// §5.5 Node identity resolver: symlink/hardlink/drive/UNC path aliases\n\t\t// conflict in the dag-v2 scheduler instead of racing (ALG002-A).\n\t\tresourceKeyResolver: createNodeResourceKeyResolver(),\n\t});\n\n\t// Restore messages if session has existing data\n\tif (hasExistingSession) {\n\t\tagent.state.messages = transcriptRecovery.messages;\n\t\tif (!hasThinkingEntry) {\n\t\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t\t}\n\t} else {\n\t\t// Save initial model and thinking level for new sessions so they can be restored on resume\n\t\tif (model) {\n\t\t\tsessionManager.appendModelChange(model.provider, model.id);\n\t\t}\n\t\tsessionManager.appendThinkingLevelChange(thinkingLevel);\n\t}\n\n\tconst session = new AgentSession({\n\t\tagent,\n\t\tsessionManager,\n\t\tsettingsManager,\n\t\tcwd,\n\t\tscopedModels: options.scopedModels,\n\t\tresourceLoader,\n\t\tcustomTools: options.customTools,\n\t\tmodelRegistry,\n\t\tinitialActiveToolNames,\n\t\tallowedToolNames,\n\t\texcludedToolNames,\n\t\textensionRunnerRef,\n\t\tloadoutAccessPolicy: effectiveLoadoutAccessPolicy,\n\t\tbashSandboxPreflight: options.bashSandboxPreflight,\n\t\tsessionStartEvent: options.sessionStartEvent,\n\t\tmodelPinned: options.modelPinned,\n\t\ttranscriptRepair: transcriptRecovery.repair,\n\t\treplayLedger,\n\t\treplayGoalId,\n\t\treplayLaneId: options.replayLaneId,\n\t});\n\tconst extensionsResult = resourceLoader.getExtensions();\n\n\treturn {\n\t\tsession,\n\t\textensionsResult,\n\t\tmodelFallbackMessage,\n\t};\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { RunPhaseContext } from "./phase-context.ts";
2
- /** Deliberately one child at a time: all ownership and process fencing still use the existing broker. */
2
+ /** Bounded ready frontier; every started task is drained before this phase returns or throws. */
3
3
  export declare function executeDag(context: RunPhaseContext, options: {
4
4
  readonly workspace: string;
5
5
  readonly deadline: number;
@@ -1 +1 @@
1
- {"version":3,"file":"dag-phase.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/dag-phase.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAiE1D,yGAAyG;AACzG,wBAAsB,UAAU,CAC/B,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChE,OAAO,CAAC,IAAI,CAAC,CAmBf","sourcesContent":["import { join } from \"node:path\";\nimport { orderRunDag, type RunDagTask, runDagAncestors } from \"omk-protocol\";\nimport { ensureDurableDirectorySync } from \"../durable-file-io.ts\";\nimport { assertCandidateScope, captureCandidate, materializeCandidate, storeCandidate } from \"./candidate.ts\";\nimport { composeDagCandidate } from \"./dag-candidates.ts\";\nimport { readyDagTasks } from \"./dag-projection.ts\";\nimport { executeRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nfunction observeWork(context: RunPhaseContext): number {\n\tconst budget = context.journal.state.budget;\n\tif (!budget) throw new VerifiedRunError(\"input_checkpoint_missing\");\n\tconst clock = readRunClock();\n\tif (remainingRunTime(budget, budget.workDeadlineMs, clock) <= 0) throw new VerifiedRunError(\"deadline\");\n\treturn clock.nowMs;\n}\n\nasync function executeTask(context: RunPhaseContext, task: RunDagTask, deadline: number): Promise<void> {\n\tconst { contract, journal, runPath } = context;\n\tif (contract.profile !== \"linux-command-dag-v1\") throw new VerifiedRunError(\"unsupported\");\n\tif (context.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\tconst previous = journal.state.tasks.find((item) => item.taskId === task.id);\n\tif (previous?.status !== \"pending\") throw new VerifiedRunError(\"task_not_ready\");\n\tconst attempt = previous.attempt + 1;\n\tconst argv = task.attempts[previous.attempt];\n\tif (!argv) throw new VerifiedRunError(\"task_attempt_limit\");\n\tconst input = composeDagCandidate(context, runDagAncestors(contract.writer.tasks, task.id));\n\tstoreCandidate(input, runPath);\n\tconst workspace = join(runPath, \"tasks\", `${task.id}-${attempt}-g${journal.state.generation}`);\n\tmaterializeCandidate(input, workspace);\n\tjournal.append({\n\t\tkind: \"task_started\",\n\t\ttaskId: task.id,\n\t\tattempt,\n\t\tinputDigest: input.digest,\n\t\tobservedMs: observeWork(context),\n\t});\n\tconst { result } = await executeRunCommand(\n\t\tjournal,\n\t\t{ role: \"writer\", argv, workspace, deadline, claimId: null },\n\t\t{ ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) },\n\t);\n\tif (result.failure === \"deadline\" || result.failure === \"cancelled\") throw new VerifiedRunError(result.failure);\n\tlet outputDigest: string | null = null;\n\tlet failure = result.failure;\n\tif (!failure) {\n\t\ttry {\n\t\t\tconst output = captureCandidate(workspace, contract.budget);\n\t\t\tassertCandidateScope(input.manifest, output.manifest, task.writablePaths);\n\t\t\tstoreCandidate(output, runPath);\n\t\t\toutputDigest = output.digest;\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\t!(error instanceof VerifiedRunError) ||\n\t\t\t\t![\"scope_changed\", \"file_type\", \"storage_limit\"].includes(error.code)\n\t\t\t)\n\t\t\t\tthrow error;\n\t\t\tfailure = error.code;\n\t\t}\n\t}\n\tjournal.append({\n\t\tkind: \"task_finished\",\n\t\ttaskId: task.id,\n\t\tattempt,\n\t\toutputDigest,\n\t\tfailure,\n\t\tobservedMs: observeWork(context),\n\t});\n}\n\n/** Deliberately one child at a time: all ownership and process fencing still use the existing broker. */\nexport async function executeDag(\n\tcontext: RunPhaseContext,\n\toptions: { readonly workspace: string; readonly deadline: number },\n): Promise<void> {\n\tconst { contract, journal, runPath } = context;\n\tif (contract.profile !== \"linux-command-dag-v1\") throw new VerifiedRunError(\"unsupported\");\n\tensureDurableDirectorySync(join(runPath, \"tasks\"));\n\tconst order = orderRunDag(contract.writer.tasks);\n\tfor (;;) {\n\t\tconst ready = new Set(readyDagTasks(contract.writer, journal.state).map((task) => task.id));\n\t\tconst next = order.find((task) => ready.has(task.id));\n\t\tif (!next) break;\n\t\tawait executeTask(context, next, options.deadline);\n\t}\n\tif (\n\t\tjournal.state.tasks.some((task) => task.status !== \"succeeded\" || task.generation !== journal.state.generation)\n\t) {\n\t\tjournal.append({ kind: \"tasks_paused\" });\n\t\treturn;\n\t}\n\tobserveWork(context);\n\tmaterializeCandidate(composeDagCandidate(context, order), options.workspace);\n}\n"]}
1
+ {"version":3,"file":"dag-phase.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/dag-phase.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAqE1D,iGAAiG;AACjG,wBAAsB,UAAU,CAC/B,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAChE,OAAO,CAAC,IAAI,CAAC,CAuDf","sourcesContent":["import { join } from \"node:path\";\nimport { orderRunDag, type RunDagTask, runDagAncestors } from \"omk-protocol\";\nimport { ensureDurableDirectorySync } from \"../durable-file-io.ts\";\nimport { assertCandidateScope, captureCandidate, materializeCandidate, storeCandidate } from \"./candidate.ts\";\nimport { composeDagCandidate } from \"./dag-candidates.ts\";\nimport { readyDagTasks } from \"./dag-projection.ts\";\nimport { executeRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nfunction observeWork(context: RunPhaseContext): number {\n\tconst budget = context.journal.state.budget;\n\tif (!budget) throw new VerifiedRunError(\"input_checkpoint_missing\");\n\tconst clock = readRunClock();\n\tif (remainingRunTime(budget, budget.workDeadlineMs, clock) <= 0) throw new VerifiedRunError(\"deadline\");\n\treturn clock.nowMs;\n}\n\nasync function executeTask(context: RunPhaseContext, task: RunDagTask, deadline: number): Promise<void> {\n\tconst { contract, journal, runPath } = context;\n\tif (contract.profile !== \"linux-command-dag-v1\") throw new VerifiedRunError(\"unsupported\");\n\tif (context.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\tconst previous = journal.state.tasks.find((item) => item.taskId === task.id);\n\tif (previous?.status !== \"pending\") throw new VerifiedRunError(\"task_not_ready\");\n\tconst attempt = previous.attempt + 1;\n\tconst argv = task.attempts[previous.attempt];\n\tif (!argv) throw new VerifiedRunError(\"task_attempt_limit\");\n\tconst input = composeDagCandidate(context, runDagAncestors(contract.writer.tasks, task.id));\n\tstoreCandidate(input, runPath);\n\tconst workspace = join(runPath, \"tasks\", `${task.id}-${attempt}-g${journal.state.generation}`);\n\tmaterializeCandidate(input, workspace);\n\tjournal.append({\n\t\tkind: \"task_started\",\n\t\ttaskId: task.id,\n\t\tattempt,\n\t\tinputDigest: input.digest,\n\t\tobservedMs: observeWork(context),\n\t});\n\tconst { result } = await executeRunCommand(\n\t\tjournal,\n\t\t{ role: \"writer\", argv, workspace, deadline, claimId: null, taskId: task.id },\n\t\t{ ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) },\n\t);\n\tif (result.failure === \"deadline\" || result.failure === \"cancelled\") throw new VerifiedRunError(result.failure);\n\tlet outputDigest: string | null = null;\n\tlet failure = result.failure;\n\tif (!failure) {\n\t\ttry {\n\t\t\tconst output = captureCandidate(workspace, contract.budget);\n\t\t\tassertCandidateScope(input.manifest, output.manifest, task.writablePaths);\n\t\t\tstoreCandidate(output, runPath);\n\t\t\toutputDigest = output.digest;\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\t!(error instanceof VerifiedRunError) ||\n\t\t\t\t![\"scope_changed\", \"file_type\", \"storage_limit\"].includes(error.code)\n\t\t\t)\n\t\t\t\tthrow error;\n\t\t\tfailure = error.code;\n\t\t}\n\t}\n\tjournal.append({\n\t\tkind: \"task_finished\",\n\t\ttaskId: task.id,\n\t\tattempt,\n\t\toutputDigest,\n\t\tfailure,\n\t\tobservedMs: observeWork(context),\n\t});\n}\n\ntype TaskCompletion =\n\t| { readonly kind: \"done\"; readonly taskId: string }\n\t| { readonly kind: \"failed\"; readonly taskId: string; readonly error: unknown };\n\n/** Bounded ready frontier; every started task is drained before this phase returns or throws. */\nexport async function executeDag(\n\tcontext: RunPhaseContext,\n\toptions: { readonly workspace: string; readonly deadline: number },\n): Promise<void> {\n\tconst { contract, journal, runPath } = context;\n\tif (contract.profile !== \"linux-command-dag-v1\") throw new VerifiedRunError(\"unsupported\");\n\tensureDurableDirectorySync(join(runPath, \"tasks\"));\n\tconst order = orderRunDag(contract.writer.tasks);\n\tconst limit = contract.writer.maxConcurrentTasks ?? 1;\n\tconst stop = new AbortController();\n\tconst signal = context.signal ? AbortSignal.any([context.signal, stop.signal]) : stop.signal;\n\tconst work = { ...context, signal };\n\tconst inFlight = new Map<string, Promise<TaskCompletion>>();\n\tlet firstFailure: { readonly error: unknown } | undefined;\n\ttry {\n\t\tfor (;;) {\n\t\t\tif (firstFailure) throw firstFailure.error;\n\t\t\tif (signal.aborted) throw new VerifiedRunError(\"cancelled\");\n\t\t\tconst ready = new Set(readyDagTasks(contract.writer, journal.state).map((task) => task.id));\n\t\t\tfor (const task of order) {\n\t\t\t\tif (inFlight.size >= limit) break;\n\t\t\t\tif (!ready.has(task.id) || inFlight.has(task.id)) continue;\n\t\t\t\tconst completion = executeTask(work, task, options.deadline).then<TaskCompletion, TaskCompletion>(\n\t\t\t\t\t() => ({ kind: \"done\", taskId: task.id }),\n\t\t\t\t\t(error: unknown) => {\n\t\t\t\t\t\tfirstFailure ??= { error };\n\t\t\t\t\t\tstop.abort();\n\t\t\t\t\t\treturn { kind: \"failed\", taskId: task.id, error };\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tinFlight.set(task.id, completion);\n\t\t\t}\n\t\t\tif (!inFlight.size) break;\n\t\t\tconst completed = await Promise.race(inFlight.values());\n\t\t\tinFlight.delete(completed.taskId);\n\t\t\tswitch (completed.kind) {\n\t\t\t\tcase \"failed\":\n\t\t\t\t\tthrow completed.error;\n\t\t\t\tcase \"done\":\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: {\n\t\t\t\t\tconst exhaustive: never = completed;\n\t\t\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tstop.abort();\n\t\tawait Promise.all(inFlight.values());\n\t}\n\tif (\n\t\tjournal.state.tasks.some((task) => task.status !== \"succeeded\" || task.generation !== journal.state.generation)\n\t) {\n\t\tjournal.append({ kind: \"tasks_paused\" });\n\t\treturn;\n\t}\n\tobserveWork(context);\n\tmaterializeCandidate(composeDagCandidate(context, order), options.workspace);\n}\n"]}
@@ -40,7 +40,7 @@ async function executeTask(context, task, deadline) {
40
40
  inputDigest: input.digest,
41
41
  observedMs: observeWork(context),
42
42
  });
43
- const { result } = await executeRunCommand(journal, { role: "writer", argv, workspace, deadline, claimId: null }, { ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) });
43
+ const { result } = await executeRunCommand(journal, { role: "writer", argv, workspace, deadline, claimId: null, taskId: task.id }, { ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) });
44
44
  if (result.failure === "deadline" || result.failure === "cancelled")
45
45
  throw new VerifiedRunError(result.failure);
46
46
  let outputDigest = null;
@@ -68,19 +68,57 @@ async function executeTask(context, task, deadline) {
68
68
  observedMs: observeWork(context),
69
69
  });
70
70
  }
71
- /** Deliberately one child at a time: all ownership and process fencing still use the existing broker. */
71
+ /** Bounded ready frontier; every started task is drained before this phase returns or throws. */
72
72
  export async function executeDag(context, options) {
73
73
  const { contract, journal, runPath } = context;
74
74
  if (contract.profile !== "linux-command-dag-v1")
75
75
  throw new VerifiedRunError("unsupported");
76
76
  ensureDurableDirectorySync(join(runPath, "tasks"));
77
77
  const order = orderRunDag(contract.writer.tasks);
78
- for (;;) {
79
- const ready = new Set(readyDagTasks(contract.writer, journal.state).map((task) => task.id));
80
- const next = order.find((task) => ready.has(task.id));
81
- if (!next)
82
- break;
83
- await executeTask(context, next, options.deadline);
78
+ const limit = contract.writer.maxConcurrentTasks ?? 1;
79
+ const stop = new AbortController();
80
+ const signal = context.signal ? AbortSignal.any([context.signal, stop.signal]) : stop.signal;
81
+ const work = { ...context, signal };
82
+ const inFlight = new Map();
83
+ let firstFailure;
84
+ try {
85
+ for (;;) {
86
+ if (firstFailure)
87
+ throw firstFailure.error;
88
+ if (signal.aborted)
89
+ throw new VerifiedRunError("cancelled");
90
+ const ready = new Set(readyDagTasks(contract.writer, journal.state).map((task) => task.id));
91
+ for (const task of order) {
92
+ if (inFlight.size >= limit)
93
+ break;
94
+ if (!ready.has(task.id) || inFlight.has(task.id))
95
+ continue;
96
+ const completion = executeTask(work, task, options.deadline).then(() => ({ kind: "done", taskId: task.id }), (error) => {
97
+ firstFailure ??= { error };
98
+ stop.abort();
99
+ return { kind: "failed", taskId: task.id, error };
100
+ });
101
+ inFlight.set(task.id, completion);
102
+ }
103
+ if (!inFlight.size)
104
+ break;
105
+ const completed = await Promise.race(inFlight.values());
106
+ inFlight.delete(completed.taskId);
107
+ switch (completed.kind) {
108
+ case "failed":
109
+ throw completed.error;
110
+ case "done":
111
+ break;
112
+ default: {
113
+ const exhaustive = completed;
114
+ throw new VerifiedRunError(String(exhaustive));
115
+ }
116
+ }
117
+ }
118
+ }
119
+ finally {
120
+ stop.abort();
121
+ await Promise.all(inFlight.values());
84
122
  }
85
123
  if (journal.state.tasks.some((task) => task.status !== "succeeded" || task.generation !== journal.state.generation)) {
86
124
  journal.append({ kind: "tasks_paused" });
@@ -1 +1 @@
1
- {"version":3,"file":"dag-phase.js","sourceRoot":"","sources":["../../../src/core/verified-run/dag-phase.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { orderRunDag, type RunDagTask, runDagAncestors } from \"omk-protocol\";\nimport { ensureDurableDirectorySync } from \"../durable-file-io.ts\";\nimport { assertCandidateScope, captureCandidate, materializeCandidate, storeCandidate } from \"./candidate.ts\";\nimport { composeDagCandidate } from \"./dag-candidates.ts\";\nimport { readyDagTasks } from \"./dag-projection.ts\";\nimport { executeRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nfunction observeWork(context: RunPhaseContext): number {\n\tconst budget = context.journal.state.budget;\n\tif (!budget) throw new VerifiedRunError(\"input_checkpoint_missing\");\n\tconst clock = readRunClock();\n\tif (remainingRunTime(budget, budget.workDeadlineMs, clock) <= 0) throw new VerifiedRunError(\"deadline\");\n\treturn clock.nowMs;\n}\n\nasync function executeTask(context: RunPhaseContext, task: RunDagTask, deadline: number): Promise<void> {\n\tconst { contract, journal, runPath } = context;\n\tif (contract.profile !== \"linux-command-dag-v1\") throw new VerifiedRunError(\"unsupported\");\n\tif (context.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\tconst previous = journal.state.tasks.find((item) => item.taskId === task.id);\n\tif (previous?.status !== \"pending\") throw new VerifiedRunError(\"task_not_ready\");\n\tconst attempt = previous.attempt + 1;\n\tconst argv = task.attempts[previous.attempt];\n\tif (!argv) throw new VerifiedRunError(\"task_attempt_limit\");\n\tconst input = composeDagCandidate(context, runDagAncestors(contract.writer.tasks, task.id));\n\tstoreCandidate(input, runPath);\n\tconst workspace = join(runPath, \"tasks\", `${task.id}-${attempt}-g${journal.state.generation}`);\n\tmaterializeCandidate(input, workspace);\n\tjournal.append({\n\t\tkind: \"task_started\",\n\t\ttaskId: task.id,\n\t\tattempt,\n\t\tinputDigest: input.digest,\n\t\tobservedMs: observeWork(context),\n\t});\n\tconst { result } = await executeRunCommand(\n\t\tjournal,\n\t\t{ role: \"writer\", argv, workspace, deadline, claimId: null },\n\t\t{ ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) },\n\t);\n\tif (result.failure === \"deadline\" || result.failure === \"cancelled\") throw new VerifiedRunError(result.failure);\n\tlet outputDigest: string | null = null;\n\tlet failure = result.failure;\n\tif (!failure) {\n\t\ttry {\n\t\t\tconst output = captureCandidate(workspace, contract.budget);\n\t\t\tassertCandidateScope(input.manifest, output.manifest, task.writablePaths);\n\t\t\tstoreCandidate(output, runPath);\n\t\t\toutputDigest = output.digest;\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\t!(error instanceof VerifiedRunError) ||\n\t\t\t\t![\"scope_changed\", \"file_type\", \"storage_limit\"].includes(error.code)\n\t\t\t)\n\t\t\t\tthrow error;\n\t\t\tfailure = error.code;\n\t\t}\n\t}\n\tjournal.append({\n\t\tkind: \"task_finished\",\n\t\ttaskId: task.id,\n\t\tattempt,\n\t\toutputDigest,\n\t\tfailure,\n\t\tobservedMs: observeWork(context),\n\t});\n}\n\n/** Deliberately one child at a time: all ownership and process fencing still use the existing broker. */\nexport async function executeDag(\n\tcontext: RunPhaseContext,\n\toptions: { readonly workspace: string; readonly deadline: number },\n): Promise<void> {\n\tconst { contract, journal, runPath } = context;\n\tif (contract.profile !== \"linux-command-dag-v1\") throw new VerifiedRunError(\"unsupported\");\n\tensureDurableDirectorySync(join(runPath, \"tasks\"));\n\tconst order = orderRunDag(contract.writer.tasks);\n\tfor (;;) {\n\t\tconst ready = new Set(readyDagTasks(contract.writer, journal.state).map((task) => task.id));\n\t\tconst next = order.find((task) => ready.has(task.id));\n\t\tif (!next) break;\n\t\tawait executeTask(context, next, options.deadline);\n\t}\n\tif (\n\t\tjournal.state.tasks.some((task) => task.status !== \"succeeded\" || task.generation !== journal.state.generation)\n\t) {\n\t\tjournal.append({ kind: \"tasks_paused\" });\n\t\treturn;\n\t}\n\tobserveWork(context);\n\tmaterializeCandidate(composeDagCandidate(context, order), options.workspace);\n}\n"]}
1
+ {"version":3,"file":"dag-phase.js","sourceRoot":"","sources":["../../../src/core/verified-run/dag-phase.ts"],"names":[],"mappings":"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","sourcesContent":["import { join } from \"node:path\";\nimport { orderRunDag, type RunDagTask, runDagAncestors } from \"omk-protocol\";\nimport { ensureDurableDirectorySync } from \"../durable-file-io.ts\";\nimport { assertCandidateScope, captureCandidate, materializeCandidate, storeCandidate } from \"./candidate.ts\";\nimport { composeDagCandidate } from \"./dag-candidates.ts\";\nimport { readyDagTasks } from \"./dag-projection.ts\";\nimport { executeRunCommand } from \"./owned-execution.ts\";\nimport type { RunPhaseContext } from \"./phase-context.ts\";\nimport { readRunClock, remainingRunTime } from \"./recovery-clock.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nfunction observeWork(context: RunPhaseContext): number {\n\tconst budget = context.journal.state.budget;\n\tif (!budget) throw new VerifiedRunError(\"input_checkpoint_missing\");\n\tconst clock = readRunClock();\n\tif (remainingRunTime(budget, budget.workDeadlineMs, clock) <= 0) throw new VerifiedRunError(\"deadline\");\n\treturn clock.nowMs;\n}\n\nasync function executeTask(context: RunPhaseContext, task: RunDagTask, deadline: number): Promise<void> {\n\tconst { contract, journal, runPath } = context;\n\tif (contract.profile !== \"linux-command-dag-v1\") throw new VerifiedRunError(\"unsupported\");\n\tif (context.signal?.aborted) throw new VerifiedRunError(\"cancelled\");\n\tconst previous = journal.state.tasks.find((item) => item.taskId === task.id);\n\tif (previous?.status !== \"pending\") throw new VerifiedRunError(\"task_not_ready\");\n\tconst attempt = previous.attempt + 1;\n\tconst argv = task.attempts[previous.attempt];\n\tif (!argv) throw new VerifiedRunError(\"task_attempt_limit\");\n\tconst input = composeDagCandidate(context, runDagAncestors(contract.writer.tasks, task.id));\n\tstoreCandidate(input, runPath);\n\tconst workspace = join(runPath, \"tasks\", `${task.id}-${attempt}-g${journal.state.generation}`);\n\tmaterializeCandidate(input, workspace);\n\tjournal.append({\n\t\tkind: \"task_started\",\n\t\ttaskId: task.id,\n\t\tattempt,\n\t\tinputDigest: input.digest,\n\t\tobservedMs: observeWork(context),\n\t});\n\tconst { result } = await executeRunCommand(\n\t\tjournal,\n\t\t{ role: \"writer\", argv, workspace, deadline, claimId: null, taskId: task.id },\n\t\t{ ...contract.budget, ...(context.signal ? { signal: context.signal } : {}) },\n\t);\n\tif (result.failure === \"deadline\" || result.failure === \"cancelled\") throw new VerifiedRunError(result.failure);\n\tlet outputDigest: string | null = null;\n\tlet failure = result.failure;\n\tif (!failure) {\n\t\ttry {\n\t\t\tconst output = captureCandidate(workspace, contract.budget);\n\t\t\tassertCandidateScope(input.manifest, output.manifest, task.writablePaths);\n\t\t\tstoreCandidate(output, runPath);\n\t\t\toutputDigest = output.digest;\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\t!(error instanceof VerifiedRunError) ||\n\t\t\t\t![\"scope_changed\", \"file_type\", \"storage_limit\"].includes(error.code)\n\t\t\t)\n\t\t\t\tthrow error;\n\t\t\tfailure = error.code;\n\t\t}\n\t}\n\tjournal.append({\n\t\tkind: \"task_finished\",\n\t\ttaskId: task.id,\n\t\tattempt,\n\t\toutputDigest,\n\t\tfailure,\n\t\tobservedMs: observeWork(context),\n\t});\n}\n\ntype TaskCompletion =\n\t| { readonly kind: \"done\"; readonly taskId: string }\n\t| { readonly kind: \"failed\"; readonly taskId: string; readonly error: unknown };\n\n/** Bounded ready frontier; every started task is drained before this phase returns or throws. */\nexport async function executeDag(\n\tcontext: RunPhaseContext,\n\toptions: { readonly workspace: string; readonly deadline: number },\n): Promise<void> {\n\tconst { contract, journal, runPath } = context;\n\tif (contract.profile !== \"linux-command-dag-v1\") throw new VerifiedRunError(\"unsupported\");\n\tensureDurableDirectorySync(join(runPath, \"tasks\"));\n\tconst order = orderRunDag(contract.writer.tasks);\n\tconst limit = contract.writer.maxConcurrentTasks ?? 1;\n\tconst stop = new AbortController();\n\tconst signal = context.signal ? AbortSignal.any([context.signal, stop.signal]) : stop.signal;\n\tconst work = { ...context, signal };\n\tconst inFlight = new Map<string, Promise<TaskCompletion>>();\n\tlet firstFailure: { readonly error: unknown } | undefined;\n\ttry {\n\t\tfor (;;) {\n\t\t\tif (firstFailure) throw firstFailure.error;\n\t\t\tif (signal.aborted) throw new VerifiedRunError(\"cancelled\");\n\t\t\tconst ready = new Set(readyDagTasks(contract.writer, journal.state).map((task) => task.id));\n\t\t\tfor (const task of order) {\n\t\t\t\tif (inFlight.size >= limit) break;\n\t\t\t\tif (!ready.has(task.id) || inFlight.has(task.id)) continue;\n\t\t\t\tconst completion = executeTask(work, task, options.deadline).then<TaskCompletion, TaskCompletion>(\n\t\t\t\t\t() => ({ kind: \"done\", taskId: task.id }),\n\t\t\t\t\t(error: unknown) => {\n\t\t\t\t\t\tfirstFailure ??= { error };\n\t\t\t\t\t\tstop.abort();\n\t\t\t\t\t\treturn { kind: \"failed\", taskId: task.id, error };\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tinFlight.set(task.id, completion);\n\t\t\t}\n\t\t\tif (!inFlight.size) break;\n\t\t\tconst completed = await Promise.race(inFlight.values());\n\t\t\tinFlight.delete(completed.taskId);\n\t\t\tswitch (completed.kind) {\n\t\t\t\tcase \"failed\":\n\t\t\t\t\tthrow completed.error;\n\t\t\t\tcase \"done\":\n\t\t\t\t\tbreak;\n\t\t\t\tdefault: {\n\t\t\t\t\tconst exhaustive: never = completed;\n\t\t\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} finally {\n\t\tstop.abort();\n\t\tawait Promise.all(inFlight.values());\n\t}\n\tif (\n\t\tjournal.state.tasks.some((task) => task.status !== \"succeeded\" || task.generation !== journal.state.generation)\n\t) {\n\t\tjournal.append({ kind: \"tasks_paused\" });\n\t\treturn;\n\t}\n\tobserveWork(context);\n\tmaterializeCandidate(composeDagCandidate(context, order), options.workspace);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"dag-projection.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/dag-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,gBAAgB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGrE,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,UAAU,EAAE,CAU/F;AAED,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAsF9E","sourcesContent":["import type { RunDagTask, RunDagWriter } from \"omk-protocol\";\nimport type { DagEvent, RunTaskProjection } from \"./dag-types.ts\";\nimport type { RunProjection, WriterReduction } from \"./run-types.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport function readyDagTasks(writer: RunDagWriter, state: RunProjection): readonly RunDagTask[] {\n\tconst states = new Map(state.tasks.map((task) => [task.taskId, task]));\n\treturn writer.tasks.filter(\n\t\t(task) =>\n\t\t\tstates.get(task.id)?.status === \"pending\" &&\n\t\t\ttask.dependsOn.every((id) => {\n\t\t\t\tconst dependency = states.get(id);\n\t\t\t\treturn dependency?.status === \"succeeded\" && dependency.generation === state.generation;\n\t\t\t}),\n\t);\n}\n\n/** Task outputs are execution checkpoints, never verifier receipts or completion authority. */\nexport function reduceDagEvent(context: WriterReduction, event: DagEvent): void {\n\tconst { state, contract } = context;\n\tif (\n\t\tcontract.profile !== \"linux-command-dag-v1\" ||\n\t\t!state.inputDigest ||\n\t\t!state.budget ||\n\t\tstate.candidateDigest ||\n\t\tstate.writerOpen ||\n\t\tstate.activeExecutionIds.length ||\n\t\tstate.execution === \"paused\"\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\tif (event.kind === \"tasks_paused\") {\n\t\tif (\n\t\t\tstate.tasks.some((task) => task.status === \"running\") ||\n\t\t\t!state.tasks.some((task) => task.status === \"failed\") ||\n\t\t\treadyDagTasks(contract.writer, state).length\n\t\t)\n\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\tcontext.state = { ...state, execution: \"paused\", settlement: \"settled\" };\n\t\treturn;\n\t}\n\tif (\n\t\tevent.observedMs < (state.lastClockMs ?? state.budget.startedMs) ||\n\t\tevent.observedMs >= state.budget.workDeadlineMs\n\t)\n\t\tthrow new VerifiedRunError(\"deadline\");\n\tconst task = state.tasks.find((task) => task.taskId === event.taskId);\n\tconst definition = contract.writer.tasks.find((task) => task.id === event.taskId);\n\tif (!task || !definition) throw new VerifiedRunError(\"integrity\");\n\tlet next: RunTaskProjection;\n\tswitch (event.kind) {\n\t\tcase \"task_started\":\n\t\t\tif (\n\t\t\t\ttask.status !== \"pending\" ||\n\t\t\t\tstate.tasks.some((task) => task.status === \"running\") ||\n\t\t\t\tevent.attempt !== task.attempt + 1 ||\n\t\t\t\tevent.attempt > definition.attempts.length ||\n\t\t\t\t!readyDagTasks(contract.writer, state).some((task) => task.id === event.taskId)\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"task_not_ready\");\n\t\t\tnext = {\n\t\t\t\ttaskId: task.taskId,\n\t\t\t\tgeneration: state.generation,\n\t\t\t\tattempt: event.attempt,\n\t\t\t\tstatus: \"running\",\n\t\t\t\tinputDigest: event.inputDigest,\n\t\t\t\toutputDigest: null,\n\t\t\t\tfailure: null,\n\t\t\t};\n\t\t\tcontext.writerStarted = false;\n\t\t\tcontext.writerFinished = false;\n\t\t\tbreak;\n\t\tcase \"task_finished\":\n\t\t\tif (\n\t\t\t\ttask.status !== \"running\" ||\n\t\t\t\ttask.generation !== state.generation ||\n\t\t\t\ttask.attempt !== event.attempt ||\n\t\t\t\t!context.writerStarted\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\tif (event.outputDigest !== null) {\n\t\t\t\tif (event.failure !== null || state.failure || !context.writerFinished)\n\t\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\t\tnext = { ...task, status: \"succeeded\", outputDigest: event.outputDigest };\n\t\t\t} else {\n\t\t\t\tif (!event.failure || (state.failure && event.failure !== state.failure))\n\t\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\t\tnext = { ...task, status: \"failed\", failure: event.failure };\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault: {\n\t\t\tconst exhaustive: never = event;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n\tconst tasks = state.tasks.map((task) => (task.taskId === next.taskId ? next : task));\n\tcontext.writerFinished = tasks.every((task) => task.status === \"succeeded\" && task.generation === state.generation);\n\tcontext.state = {\n\t\t...state,\n\t\ttasks,\n\t\texecution: \"running\",\n\t\tsettlement: \"settled\",\n\t\tfailure: null,\n\t\tlastClockMs: event.observedMs,\n\t};\n}\n"]}
1
+ {"version":3,"file":"dag-projection.d.ts","sourceRoot":"","sources":["../../../src/core/verified-run/dag-projection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAqB,MAAM,gBAAgB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGrE,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,UAAU,EAAE,CAU/F;AAED,+FAA+F;AAC/F,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAgG9E","sourcesContent":["import type { RunDagTask, RunDagWriter } from \"omk-protocol\";\nimport type { DagEvent, RunTaskProjection } from \"./dag-types.ts\";\nimport type { RunProjection, WriterReduction } from \"./run-types.ts\";\nimport { VerifiedRunError } from \"./storage.ts\";\n\nexport function readyDagTasks(writer: RunDagWriter, state: RunProjection): readonly RunDagTask[] {\n\tconst states = new Map(state.tasks.map((task) => [task.taskId, task]));\n\treturn writer.tasks.filter(\n\t\t(task) =>\n\t\t\tstates.get(task.id)?.status === \"pending\" &&\n\t\t\ttask.dependsOn.every((id) => {\n\t\t\t\tconst dependency = states.get(id);\n\t\t\t\treturn dependency?.status === \"succeeded\" && dependency.generation === state.generation;\n\t\t\t}),\n\t);\n}\n\n/** Task outputs are execution checkpoints, never verifier receipts or completion authority. */\nexport function reduceDagEvent(context: WriterReduction, event: DagEvent): void {\n\tconst { state, contract } = context;\n\tif (\n\t\tcontract.profile !== \"linux-command-dag-v1\" ||\n\t\t!state.inputDigest ||\n\t\t!state.budget ||\n\t\tstate.candidateDigest ||\n\t\tstate.writerOpen ||\n\t\tstate.execution === \"paused\"\n\t)\n\t\tthrow new VerifiedRunError(\"integrity\");\n\tif (event.kind === \"tasks_paused\") {\n\t\tif (\n\t\t\tstate.activeExecutionIds.length ||\n\t\t\tstate.tasks.some((task) => task.status === \"running\") ||\n\t\t\t!state.tasks.some((task) => task.status === \"failed\") ||\n\t\t\treadyDagTasks(contract.writer, state).length\n\t\t)\n\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\tcontext.state = { ...state, execution: \"paused\", settlement: \"settled\" };\n\t\treturn;\n\t}\n\tif (\n\t\tevent.observedMs < (state.lastClockMs ?? state.budget.startedMs) ||\n\t\tevent.observedMs >= state.budget.workDeadlineMs\n\t)\n\t\tthrow new VerifiedRunError(\"deadline\");\n\tconst task = state.tasks.find((task) => task.taskId === event.taskId);\n\tconst definition = contract.writer.tasks.find((task) => task.id === event.taskId);\n\tif (!task || !definition) throw new VerifiedRunError(\"integrity\");\n\tlet next: RunTaskProjection;\n\tswitch (event.kind) {\n\t\tcase \"task_started\":\n\t\t\tif (\n\t\t\t\ttask.status !== \"pending\" ||\n\t\t\t\tstate.tasks.filter((task) => task.status === \"running\").length >=\n\t\t\t\t\t(contract.writer.maxConcurrentTasks ?? 1) ||\n\t\t\t\tevent.attempt !== task.attempt + 1 ||\n\t\t\t\tevent.attempt > definition.attempts.length ||\n\t\t\t\t!readyDagTasks(contract.writer, state).some((task) => task.id === event.taskId)\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"task_not_ready\");\n\t\t\tnext = {\n\t\t\t\ttaskId: task.taskId,\n\t\t\t\tgeneration: state.generation,\n\t\t\t\tattempt: event.attempt,\n\t\t\t\tstatus: \"running\",\n\t\t\t\texecution: Object.freeze({ kind: \"ready\" }),\n\t\t\t\tinputDigest: event.inputDigest,\n\t\t\t\toutputDigest: null,\n\t\t\t\tfailure: null,\n\t\t\t};\n\t\t\tbreak;\n\t\tcase \"task_finished\": {\n\t\t\tif (\n\t\t\t\ttask.status !== \"running\" ||\n\t\t\t\ttask.generation !== state.generation ||\n\t\t\t\ttask.attempt !== event.attempt ||\n\t\t\t\ttask.execution.kind !== \"exited\"\n\t\t\t)\n\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\t// Keep checkpoint shape stable: process state belongs only to an in-flight task.\n\t\t\tconst checkpoint = {\n\t\t\t\ttaskId: task.taskId,\n\t\t\t\tgeneration: task.generation,\n\t\t\t\tattempt: task.attempt,\n\t\t\t\tinputDigest: task.inputDigest,\n\t\t\t};\n\t\t\tif (event.outputDigest !== null) {\n\t\t\t\tif (event.failure !== null || task.execution.failure) throw new VerifiedRunError(\"integrity\");\n\t\t\t\tnext = { ...checkpoint, status: \"succeeded\", outputDigest: event.outputDigest, failure: null };\n\t\t\t} else {\n\t\t\t\tif (!event.failure || (task.execution.failure && event.failure !== task.execution.failure))\n\t\t\t\t\tthrow new VerifiedRunError(\"integrity\");\n\t\t\t\tnext = { ...checkpoint, status: \"failed\", outputDigest: null, failure: event.failure };\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tconst exhaustive: never = event;\n\t\t\tthrow new VerifiedRunError(String(exhaustive));\n\t\t}\n\t}\n\tconst tasks = state.tasks.map((task) => (task.taskId === next.taskId ? next : task));\n\tcontext.writerFinished = tasks.every((task) => task.status === \"succeeded\" && task.generation === state.generation);\n\tlet settlement: RunProjection[\"settlement\"] = \"settled\";\n\tif (tasks.some((task) => task.status === \"running\")) settlement = \"open\";\n\tif (state.activeExecutionIds.length) settlement = \"draining\";\n\tcontext.state = {\n\t\t...state,\n\t\ttasks,\n\t\texecution: \"running\",\n\t\tsettlement,\n\t\tfailure: null,\n\t\tlastClockMs: event.observedMs,\n\t};\n}\n"]}