@elevasis/sdk 1.44.2 → 1.45.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 (245) hide show
  1. package/dist/cli.cjs +1001 -652
  2. package/dist/index.d.ts +1045 -509
  3. package/dist/index.js +748 -690
  4. package/dist/node/index.d.ts +105 -97
  5. package/dist/test-utils/index.d.ts +42 -28
  6. package/dist/test-utils/index.js +549 -732
  7. package/dist/worker/index.d.ts +12112 -0
  8. package/dist/worker/index.js +211 -186
  9. package/package.json +6 -9
  10. package/reference/_navigation.md +151 -21
  11. package/reference/_reference-manifest.json +186 -4
  12. package/reference/claude-config.md +8 -0
  13. package/reference/core/index.mdx +3 -3
  14. package/reference/examples/organization-model.ts +117 -111
  15. package/reference/index.mdx +4 -4
  16. package/reference/rules/active-change-index.md +40 -54
  17. package/reference/rules/agent-runtime.md +81 -0
  18. package/reference/rules/agent-start-here.md +71 -163
  19. package/reference/rules/deployment.md +33 -10
  20. package/reference/rules/error-handling.md +26 -0
  21. package/reference/rules/execution.md +13 -0
  22. package/reference/rules/frontend.md +10 -3
  23. package/reference/rules/observability.md +9 -1
  24. package/reference/rules/operations.md +26 -17
  25. package/reference/rules/organization-model.md +74 -88
  26. package/reference/rules/organization-os.md +71 -88
  27. package/reference/rules/package-taxonomy.md +11 -2
  28. package/reference/rules/platform.md +13 -7
  29. package/reference/rules/shared-types.md +15 -0
  30. package/reference/rules/task-tracking.md +30 -5
  31. package/reference/rules/ui.md +145 -3
  32. package/reference/rules/vibe-intents.md +271 -0
  33. package/reference/rules/vibe.md +17 -243
  34. package/reference/scaffold/core/organization-graph.mdx +111 -97
  35. package/reference/scaffold/core/organization-model.mdx +234 -214
  36. package/reference/scaffold/operations/propagation-pipeline.md +1 -1
  37. package/reference/scaffold/operations/scaffold-maintenance.md +19 -18
  38. package/reference/scaffold/operations/workflow-recipes.md +71 -19
  39. package/reference/scaffold/recipes/add-a-feature.md +156 -146
  40. package/reference/scaffold/recipes/add-a-resource.md +123 -117
  41. package/reference/scaffold/recipes/customize-crm-actions.md +25 -10
  42. package/reference/scaffold/recipes/customize-knowledge-browser.md +52 -117
  43. package/reference/scaffold/recipes/customize-organization-model.md +161 -149
  44. package/reference/scaffold/recipes/extend-a-base-entity.md +156 -140
  45. package/reference/scaffold/recipes/extend-crm.md +16 -11
  46. package/reference/scaffold/recipes/extend-lead-gen.md +25 -7
  47. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +160 -118
  48. package/reference/scaffold/recipes/index.md +2 -2
  49. package/reference/scaffold/recipes/query-the-knowledge-graph.md +23 -23
  50. package/reference/scaffold/reference/contracts.md +12 -1
  51. package/reference/scaffold/reference/glossary.md +3 -3
  52. package/reference/scaffold/reference/system-interface-capabilities.md +5 -4
  53. package/reference/scaffold/ui/composition-extensibility.mdx +271 -232
  54. package/reference/scaffold/ui/feature-flags-and-gating.md +14 -6
  55. package/reference/scaffold/ui/feature-shell.mdx +279 -62
  56. package/reference/scaffold/ui/recipes.md +229 -197
  57. package/reference/sdk/cli-management.mdx +77 -29
  58. package/reference/sdk/concepts.mdx +2 -0
  59. package/reference/sdk/define-builders.mdx +76 -0
  60. package/reference/sdk/deployment/command-center.mdx +6 -2
  61. package/reference/sdk/deployment/execution-reference.mdx +64 -186
  62. package/reference/sdk/deployment/index.mdx +2 -0
  63. package/reference/sdk/exports.mdx +4 -4
  64. package/reference/sdk/framework/agent.mdx +49 -119
  65. package/reference/sdk/framework/index.mdx +46 -65
  66. package/reference/sdk/framework/project-structure.mdx +150 -205
  67. package/reference/sdk/framework/tutorial-system.mdx +2 -2
  68. package/reference/sdk/human-in-the-loop.mdx +152 -0
  69. package/reference/sdk/index.mdx +6 -7
  70. package/reference/sdk/platform-tools/index.mdx +12 -0
  71. package/reference/sdk/platform-tools/type-safety.mdx +4 -0
  72. package/reference/sdk/project-deployment-spec.mdx +131 -0
  73. package/reference/sdk/resources/index.mdx +23 -7
  74. package/reference/sdk/resources/patterns.mdx +54 -24
  75. package/reference/sdk/resources/types.mdx +7 -4
  76. package/reference/sdk/templates/data-enrichment.mdx +7 -3
  77. package/reference/sdk/templates/email-sender.mdx +139 -135
  78. package/reference/sdk/templates/lead-scorer.mdx +5 -1
  79. package/reference/sdk/templates/pdf-generator.mdx +155 -151
  80. package/reference/sdk/templates/recurring-job.mdx +195 -189
  81. package/reference/sdk/templates/text-classifier.mdx +4 -0
  82. package/reference/sdk/templates/web-scraper.mdx +139 -135
  83. package/reference/spine/spine-primer.md +135 -96
  84. package/reference/ui/index.mdx +14 -7
  85. package/dist/types/worker/adapters/anymailfinder.d.ts +0 -14
  86. package/dist/types/worker/adapters/apify.d.ts +0 -14
  87. package/dist/types/worker/adapters/approval.d.ts +0 -23
  88. package/dist/types/worker/adapters/attio.d.ts +0 -22
  89. package/dist/types/worker/adapters/clickup.d.ts +0 -22
  90. package/dist/types/worker/adapters/create-adapter.d.ts +0 -41
  91. package/dist/types/worker/adapters/crm.d.ts +0 -20
  92. package/dist/types/worker/adapters/dropbox.d.ts +0 -14
  93. package/dist/types/worker/adapters/email.d.ts +0 -25
  94. package/dist/types/worker/adapters/execution.d.ts +0 -22
  95. package/dist/types/worker/adapters/gmail.d.ts +0 -14
  96. package/dist/types/worker/adapters/google-sheets.d.ts +0 -14
  97. package/dist/types/worker/adapters/index.d.ts +0 -33
  98. package/dist/types/worker/adapters/instantly.d.ts +0 -14
  99. package/dist/types/worker/adapters/lead.d.ts +0 -28
  100. package/dist/types/worker/adapters/list.d.ts +0 -9
  101. package/dist/types/worker/adapters/llm.d.ts +0 -45
  102. package/dist/types/worker/adapters/millionverifier.d.ts +0 -14
  103. package/dist/types/worker/adapters/notification.d.ts +0 -28
  104. package/dist/types/worker/adapters/pdf.d.ts +0 -22
  105. package/dist/types/worker/adapters/projects.d.ts +0 -20
  106. package/dist/types/worker/adapters/resend.d.ts +0 -14
  107. package/dist/types/worker/adapters/scheduler.d.ts +0 -25
  108. package/dist/types/worker/adapters/signature-api.d.ts +0 -14
  109. package/dist/types/worker/adapters/storage.d.ts +0 -33
  110. package/dist/types/worker/adapters/stripe.d.ts +0 -14
  111. package/dist/types/worker/adapters/tomba.d.ts +0 -14
  112. package/dist/types/worker/index.d.ts +0 -60
  113. package/dist/types/worker/platform.d.ts +0 -90
  114. package/dist/types/worker/utils.d.ts +0 -9
  115. package/reference/claude-config/Overview.md +0 -230
  116. package/reference/claude-config/hooks/post-edit-validate.mjs +0 -98
  117. package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +0 -187
  118. package/reference/claude-config/hooks/tool-failure-recovery.mjs +0 -73
  119. package/reference/claude-config/registries/graph-skills.json +0 -4
  120. package/reference/claude-config/registries/knowledge-flags.json +0 -154
  121. package/reference/claude-config/registries/skill-coverage.json +0 -20
  122. package/reference/claude-config/rules/active-change-index.md +0 -22
  123. package/reference/claude-config/rules/agent-start-here.md +0 -22
  124. package/reference/claude-config/rules/deployment.md +0 -22
  125. package/reference/claude-config/rules/error-handling.md +0 -22
  126. package/reference/claude-config/rules/execution.md +0 -22
  127. package/reference/claude-config/rules/frontend.md +0 -22
  128. package/reference/claude-config/rules/observability.md +0 -22
  129. package/reference/claude-config/rules/operations.md +0 -22
  130. package/reference/claude-config/rules/organization-model.md +0 -22
  131. package/reference/claude-config/rules/organization-os.md +0 -22
  132. package/reference/claude-config/rules/package-taxonomy.md +0 -22
  133. package/reference/claude-config/rules/platform.md +0 -22
  134. package/reference/claude-config/rules/shared-types.md +0 -22
  135. package/reference/claude-config/rules/task-tracking.md +0 -22
  136. package/reference/claude-config/rules/topbar-actions.md +0 -70
  137. package/reference/claude-config/rules/ui.md +0 -22
  138. package/reference/claude-config/rules/vibe.md +0 -22
  139. package/reference/claude-config/scripts/statusline-command.js +0 -18
  140. package/reference/claude-config/settings.json +0 -30
  141. package/reference/claude-config/skills/client/SKILL.md +0 -201
  142. package/reference/claude-config/skills/deploy/SKILL.md +0 -159
  143. package/reference/claude-config/skills/dsp/SKILL.md +0 -66
  144. package/reference/claude-config/skills/elevasis/SKILL.md +0 -251
  145. package/reference/claude-config/skills/explore/SKILL.md +0 -78
  146. package/reference/claude-config/skills/git-sync/SKILL.md +0 -166
  147. package/reference/claude-config/skills/om/SKILL.md +0 -475
  148. package/reference/claude-config/skills/om/operations/build.md +0 -237
  149. package/reference/claude-config/skills/om/operations/codify-level-a.md +0 -109
  150. package/reference/claude-config/skills/om/operations/codify-level-b.md +0 -159
  151. package/reference/claude-config/skills/om/operations/customers.md +0 -114
  152. package/reference/claude-config/skills/om/operations/features.md +0 -88
  153. package/reference/claude-config/skills/om/operations/goals.md +0 -123
  154. package/reference/claude-config/skills/om/operations/identity.md +0 -97
  155. package/reference/claude-config/skills/om/operations/labels.md +0 -110
  156. package/reference/claude-config/skills/om/operations/offerings.md +0 -114
  157. package/reference/claude-config/skills/om/operations/roles.md +0 -104
  158. package/reference/claude-config/skills/om/operations/scaffold.md +0 -163
  159. package/reference/claude-config/skills/om/operations/techStack.md +0 -38
  160. package/reference/claude-config/skills/project/SKILL.md +0 -1114
  161. package/reference/claude-config/skills/run-ui/SKILL.md +0 -73
  162. package/reference/claude-config/skills/save/SKILL.md +0 -183
  163. package/reference/claude-config/skills/setup/SKILL.md +0 -290
  164. package/reference/claude-config/skills/status/SKILL.md +0 -59
  165. package/reference/claude-config/skills/submit-request/SKILL.md +0 -180
  166. package/reference/claude-config/skills/sync/SKILL.md +0 -47
  167. package/reference/claude-config/skills/tutorial/SKILL.md +0 -259
  168. package/reference/claude-config/skills/tutorial/progress-template.md +0 -74
  169. package/reference/claude-config/skills/tutorial/technical.md +0 -1303
  170. package/reference/claude-config/skills/tutorial/vibe-coder.md +0 -890
  171. package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +0 -27
  172. package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +0 -30
  173. package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +0 -73
  174. package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +0 -86
  175. package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +0 -55
  176. package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +0 -97
  177. package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +0 -112
  178. package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +0 -93
  179. package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +0 -58
  180. package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +0 -56
  181. package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +0 -71
  182. package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +0 -83
  183. package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +0 -59
  184. package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +0 -42
  185. package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +0 -60
  186. package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +0 -37
  187. package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +0 -34
  188. package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +0 -38
  189. package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +0 -32
  190. package/reference/claude-config/sync-notes/2026-05-09-command-system.md +0 -33
  191. package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +0 -69
  192. package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +0 -30
  193. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +0 -45
  194. package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +0 -52
  195. package/reference/claude-config/sync-notes/2026-05-17-sdk-boundary-consolidation.md +0 -33
  196. package/reference/claude-config/sync-notes/2026-05-20-om-define-helpers.md +0 -32
  197. package/reference/claude-config/sync-notes/2026-05-22-access-model-and-right-panel.md +0 -43
  198. package/reference/claude-config/sync-notes/2026-05-22-lead-gen-tenant-config.md +0 -40
  199. package/reference/claude-config/sync-notes/2026-05-22-org-model-multi-file-split.md +0 -61
  200. package/reference/claude-config/sync-notes/2026-05-23-branding-names-to-identity.md +0 -49
  201. package/reference/claude-config/sync-notes/2026-05-23-lead-gen-manage-access.md +0 -31
  202. package/reference/claude-config/sync-notes/2026-05-23-om-deployment-drift-detection.md +0 -42
  203. package/reference/claude-config/sync-notes/2026-05-23-om-full-model-deploy-contract.md +0 -33
  204. package/reference/claude-config/sync-notes/2026-05-23-ui-sdk-package-fixes.md +0 -37
  205. package/reference/claude-config/sync-notes/2026-05-24-platform-invite-router-core-baseline.md +0 -28
  206. package/reference/claude-config/sync-notes/2026-05-24-system-interface-readiness.md +0 -43
  207. package/reference/claude-config/sync-notes/2026-05-25-invitation-login-loader.md +0 -26
  208. package/reference/claude-config/sync-notes/2026-05-25-om-topbar-requests.md +0 -33
  209. package/reference/claude-config/sync-notes/2026-05-25-system-interface-profile-registry-and-substrate.md +0 -35
  210. package/reference/claude-config/sync-notes/2026-05-25-tenant-om-scaffold-cli.md +0 -49
  211. package/reference/claude-config/sync-notes/2026-05-25-vibe-operate-intent.md +0 -47
  212. package/reference/claude-config/sync-notes/2026-05-28-om-snapshot-sdk-workflow-config.md +0 -33
  213. package/reference/claude-config/sync-notes/2026-05-30-client-source-and-om-profiles.md +0 -39
  214. package/reference/claude-config/sync-notes/2026-06-02-knowledge-nested-group-routing.md +0 -27
  215. package/reference/claude-config/sync-notes/2026-06-02-nest-projects-under-platform.md +0 -45
  216. package/reference/claude-config/sync-notes/2026-06-03-skill-autogen-and-client-skill.md +0 -34
  217. package/reference/claude-config/sync-notes/2026-06-04-scaffold-registry-lane-severity.md +0 -34
  218. package/reference/claude-config/sync-notes/2026-06-05-appearance-app-mode-decouple.md +0 -29
  219. package/reference/claude-config/sync-notes/2026-06-05-ontology-endpoint-rename-and-knowledge-browser-ui.md +0 -86
  220. package/reference/claude-config/sync-notes/2026-06-06-om-build-systems-scaffold.md +0 -47
  221. package/reference/claude-config/sync-notes/2026-06-06-om-item-copy-references.md +0 -50
  222. package/reference/claude-config/sync-notes/2026-06-08-knowledge-base-page-not-found-fix.md +0 -76
  223. package/reference/claude-config/sync-notes/2026-06-09-agent-sessions-public-agent-chat-route.md +0 -75
  224. package/reference/claude-config/sync-notes/2026-06-09-sdk-cli-load-org-model-resolution.md +0 -42
  225. package/reference/claude-config/sync-notes/2026-06-12-agent-grants-visualizer-operations.md +0 -30
  226. package/reference/claude-config/sync-notes/2026-06-14-session-ux-and-project-cli-json.md +0 -33
  227. package/reference/claude-config/sync-notes/2026-06-14-shared-session-conversation-view.md +0 -26
  228. package/reference/claude-config/sync-notes/2026-06-15-session-chat-zero-wiring.md +0 -46
  229. package/reference/claude-config/sync-notes/2026-06-17-agent-session-ux-features.md +0 -34
  230. package/reference/claude-config/sync-notes/2026-06-25-shared-page-scroll-contract-guard.md +0 -52
  231. package/reference/claude-config/sync-notes/2026-06-26-leadgen-overview-om-telemetry.md +0 -47
  232. package/reference/claude-config/sync-notes/2026-07-21-agent-scaffold-hardening.md +0 -75
  233. package/reference/claude-config/sync-notes/2026-07-23-agent-session-memory.md +0 -49
  234. package/reference/claude-config/sync-notes/2026-07-23-workos-org-marker.md +0 -50
  235. package/reference/claude-config/sync-notes/2026-07-24-claude-5-models-and-session-surface-fixes.md +0 -116
  236. package/reference/claude-config/sync-notes/2026-07-27-agent-strict-output-and-turn-drift.md +0 -73
  237. package/reference/claude-config/sync-notes/2026-07-28-agent-reply-is-its-own-field.md +0 -84
  238. package/reference/claude-config/sync-notes/2026-07-30-login-screen-and-member-provisioning-state.md +0 -114
  239. package/reference/claude-config/sync-notes/2026-08-02-auth-guard-defaults-and-truncation-fix.md +0 -122
  240. package/reference/claude-config/sync-notes/2026-08-03-cli-gateway-errors-and-request-timeout.md +0 -120
  241. package/reference/claude-config/sync-notes/README.md +0 -43
  242. package/reference/sdk/framework/interaction-guidance.mdx +0 -182
  243. package/reference/sdk/framework/memory.mdx +0 -326
  244. package/reference/sdk/framework/resource-documentation.mdx +0 -90
  245. package/reference/sdk/roadmap.mdx +0 -164
@@ -4343,6 +4343,23 @@ var Workflow = class {
4343
4343
 
4344
4344
  // ../core/src/execution/engine/agent/observability/logging.ts
4345
4345
  function createAgentLogger(logger, agentId, sessionId) {
4346
+ function emitAction(actionType, message, iteration, startTime, endTime, duration) {
4347
+ const event = {
4348
+ type: "agent",
4349
+ agentId,
4350
+ lifecycle: "iteration",
4351
+ eventType: "action",
4352
+ iteration,
4353
+ actionType,
4354
+ startTime,
4355
+ endTime,
4356
+ duration,
4357
+ data: { message },
4358
+ ...sessionId && { sessionId }
4359
+ // Include sessionId if present
4360
+ };
4361
+ logger.info("action", event);
4362
+ }
4346
4363
  return {
4347
4364
  lifecycle(lifecycle, stage, data) {
4348
4365
  let event;
@@ -4409,21 +4426,15 @@ function createAgentLogger(logger, agentId, sessionId) {
4409
4426
  logger.info("reasoning", event);
4410
4427
  },
4411
4428
  action(actionType, message, iteration, startTime, endTime, duration) {
4412
- const event = {
4413
- type: "agent",
4414
- agentId,
4415
- lifecycle: "iteration",
4416
- eventType: "action",
4417
- iteration,
4418
- actionType,
4419
- startTime,
4420
- endTime,
4421
- duration,
4422
- data: { message },
4423
- ...sessionId && { sessionId }
4424
- // Include sessionId if present
4425
- };
4426
- logger.info("action", event);
4429
+ emitAction(actionType, message, iteration, startTime, endTime, duration);
4430
+ },
4431
+ async timed(actionType, iteration, work, message) {
4432
+ const startTime = Date.now();
4433
+ const result = await work();
4434
+ const endTime = Date.now();
4435
+ const resolvedActionType = typeof actionType === "function" ? actionType(result) : actionType;
4436
+ emitAction(resolvedActionType, message(result), iteration, startTime, endTime, endTime - startTime);
4437
+ return result;
4427
4438
  },
4428
4439
  toolCall(toolName, iteration, startTime, endTime, duration, success, error, input, output) {
4429
4440
  const event = {
@@ -4479,6 +4490,11 @@ every response:
4479
4490
  and never continue the response envelope in the reasoning text -- nextActions is a separate field
4480
4491
  that you fill separately. A response carrying reasoning alone is discarded and retried.
4481
4492
 
4493
+ **Prose fields take real characters, never escape sequences.** A line break in ${includeMessage ? "message or reasoning" : "reasoning"} is
4494
+ a real line break -- not the two characters \\n. A quotation mark is the character ", not \\". The
4495
+ response is serialized for you; typing the escape yourself puts those literal characters into the
4496
+ stored text and in front of the reader.
4497
+
4482
4498
  ## Rules
4483
4499
 
4484
4500
  - Batch independent tool calls in one iteration (faster execution)
@@ -5074,7 +5090,7 @@ function buildIterationResponseSchemaUncached(tools, capabilities) {
5074
5090
  if (capabilities.message !== "off") {
5075
5091
  properties.message = {
5076
5092
  type: "string",
5077
- description: "Your reply to the user, as plain prose. This is the ONLY field the user sees. Use an empty string only when this iteration just calls tools and you have nothing to say yet."
5093
+ description: 'Your reply to the user, as plain prose. This is the ONLY field the user sees. Use an empty string only when this iteration just calls tools and you have nothing to say yet. Write real line breaks and real quotation marks -- the two characters \\n are not a line break, and \\" is not a quotation mark. Serialization is handled for you.'
5078
5094
  };
5079
5095
  }
5080
5096
  properties.reasoning = { type: "string", description: "Your reasoning process" };
@@ -5094,7 +5110,15 @@ function buildIterationResponseSchemaUncached(tools, capabilities) {
5094
5110
  type: "object",
5095
5111
  properties: {
5096
5112
  key: { type: "string" },
5097
- value: { type: "string" }
5113
+ value: {
5114
+ type: "string",
5115
+ // `memoryOps` has NO framework prompt section -- a grep across `prompt-sections/`
5116
+ // returns zero memory references -- so this description is the only framework-owned
5117
+ // lever on how a memory value is written. It matters more here than in `message`:
5118
+ // a session-memory value is re-sent on every iteration of every subsequent turn and
5119
+ // never ages out, so one literal escape stored here is one the model re-reads forever.
5120
+ description: "Stored verbatim and replayed to you on every later turn. Write real line breaks and real quotation marks -- the two characters \\n are not a line break."
5121
+ }
5098
5122
  },
5099
5123
  required: ["key", "value"],
5100
5124
  additionalProperties: false
@@ -5113,6 +5137,59 @@ function buildIterationResponseSchemaUncached(tools, capabilities) {
5113
5137
  };
5114
5138
  }
5115
5139
 
5140
+ // ../core/src/execution/engine/agent/reasoning/adapters/prose-escapes.ts
5141
+ var BACKSLASH = String.fromCharCode(92);
5142
+ function normalizeProseEscapes(text) {
5143
+ if (!text.includes(BACKSLASH)) return text;
5144
+ let out = "";
5145
+ let i = 0;
5146
+ while (i < text.length) {
5147
+ const char = text[i];
5148
+ if (char !== BACKSLASH || i + 1 >= text.length) {
5149
+ out += char;
5150
+ i += 1;
5151
+ continue;
5152
+ }
5153
+ switch (text[i + 1]) {
5154
+ case BACKSLASH:
5155
+ out += BACKSLASH + BACKSLASH;
5156
+ i += 2;
5157
+ break;
5158
+ case "n":
5159
+ out += "\n";
5160
+ i += 2;
5161
+ break;
5162
+ case "r":
5163
+ if (text[i + 2] === BACKSLASH && text[i + 3] === "n") {
5164
+ out += "\n";
5165
+ i += 4;
5166
+ } else {
5167
+ out += "\n";
5168
+ i += 2;
5169
+ }
5170
+ break;
5171
+ case "t":
5172
+ out += " ";
5173
+ i += 2;
5174
+ break;
5175
+ case '"':
5176
+ out += '"';
5177
+ i += 2;
5178
+ break;
5179
+ default:
5180
+ out += char;
5181
+ i += 1;
5182
+ }
5183
+ }
5184
+ return out;
5185
+ }
5186
+ function normalizeMemoryValue(value) {
5187
+ if (typeof value !== "string") return value;
5188
+ const trimmed = value.trim();
5189
+ if (trimmed.startsWith("{") || trimmed.startsWith("[")) return value;
5190
+ return normalizeProseEscapes(value);
5191
+ }
5192
+
5116
5193
  // ../core/src/execution/engine/agent/reasoning/adapters/agent-adapter-helpers.ts
5117
5194
  var MemoryKeyValuePairSchema = z.object({ key: z.string(), value: z.any() });
5118
5195
  var MemorySetSchema = z.union([z.record(z.string(), z.any()), z.array(MemoryKeyValuePairSchema)]).transform((value) => {
@@ -5124,13 +5201,33 @@ var MemoryOperationsSchema = z.object({
5124
5201
  // Accept any value type - framework will stringify
5125
5202
  delete: z.array(z.string()).optional()
5126
5203
  });
5127
- var AgentIterationOutputSchema = z.object({
5204
+ var AgentIterationOutputObjectSchema = z.object({
5128
5205
  reasoning: z.string(),
5129
5206
  message: z.string().optional(),
5130
5207
  memoryOps: MemoryOperationsSchema.optional(),
5131
5208
  nextActions: z.array(AgentActionSchema)
5132
5209
  });
5133
- var REQUIRED_ITERATION_KEYS = Object.entries(AgentIterationOutputSchema.shape).filter(([, fieldSchema]) => !fieldSchema.isOptional()).map(([key]) => key);
5210
+ function normalizeIterationProse(output) {
5211
+ const normalized = { ...output };
5212
+ normalized.reasoning = normalizeProseEscapes(output.reasoning);
5213
+ if (typeof output.message === "string") {
5214
+ normalized.message = normalizeProseEscapes(output.message);
5215
+ }
5216
+ if (output.memoryOps?.set) {
5217
+ normalized.memoryOps = {
5218
+ ...output.memoryOps,
5219
+ set: Object.fromEntries(
5220
+ Object.entries(output.memoryOps.set).map(([key, value]) => [key, normalizeMemoryValue(value)])
5221
+ )
5222
+ };
5223
+ }
5224
+ normalized.nextActions = output.nextActions.map(
5225
+ (action) => action.type === "message" ? { ...action, text: normalizeProseEscapes(action.text) } : action
5226
+ );
5227
+ return normalized;
5228
+ }
5229
+ var AgentIterationOutputSchema = AgentIterationOutputObjectSchema.transform(normalizeIterationProse);
5230
+ var REQUIRED_ITERATION_KEYS = Object.entries(AgentIterationOutputObjectSchema.shape).filter(([, fieldSchema]) => !fieldSchema.isOptional()).map(([key]) => key);
5134
5231
  function withSynthesizedMessage(nextActions, message) {
5135
5232
  const text = message?.trim();
5136
5233
  if (!text) {
@@ -5265,66 +5362,21 @@ async function processReasoning(iterationContext) {
5265
5362
  reasoning: response.reasoning
5266
5363
  });
5267
5364
  iterationContext.logger.reasoning(response.reasoning, iterationContext.iteration, startTime, endTime, duration);
5268
- const memoryStartTime = Date.now();
5269
- iterationContext.memoryManager.addToHistory({
5270
- type: "reasoning",
5271
- content: response.reasoning,
5272
- turnNumber: iterationContext.executionContext.sessionTurnNumber ?? null,
5273
- iterationNumber: iterationContext.iteration,
5274
- source: "model"
5275
- });
5276
- const memoryEndTime = Date.now();
5277
- const memoryDuration = memoryEndTime - memoryStartTime;
5278
- iterationContext.logger.action(
5365
+ await iterationContext.logger.timed(
5279
5366
  "memory-reasoning",
5280
- `Stored reasoning (${response.reasoning.length} chars), history size: ${iterationContext.memoryManager.getHistoryLength()}, actions: ${response.nextActions.map((a3) => a3.type).join(", ")}`,
5281
5367
  iterationContext.iteration,
5282
- memoryStartTime,
5283
- memoryEndTime,
5284
- memoryDuration
5368
+ () => iterationContext.memoryManager.addToHistory({
5369
+ type: "reasoning",
5370
+ content: response.reasoning,
5371
+ turnNumber: iterationContext.executionContext.sessionTurnNumber ?? null,
5372
+ iterationNumber: iterationContext.iteration,
5373
+ source: "model"
5374
+ }),
5375
+ () => `Stored reasoning (${response.reasoning.length} chars), history size: ${iterationContext.memoryManager.getHistoryLength()}, actions: ${response.nextActions.map((a3) => a3.type).join(", ")}`
5285
5376
  );
5286
5377
  return response;
5287
5378
  }
5288
5379
 
5289
- // ../core/src/execution/engine/agent/memory/domains.ts
5290
- var MEMORY_DOMAINS = {
5291
- /**
5292
- * Tool-owned keys
5293
- * Updated automatically by tools as side effects
5294
- * LLM cannot modify these via memoryOps
5295
- *
5296
- * Tools manage complex structured data (caches, indexes, etc.)
5297
- * that would be error-prone for LLM to update via JSON strings.
5298
- *
5299
- * No tool currently writes these three keys, so in practice the guard reserves the names
5300
- * against the LLM rather than arbitrating a live conflict. That is still enforcement --
5301
- * see `validateMemoryKeyOwnership` in `./utils` -- not dead code.
5302
- */
5303
- TOOL_OWNED: [
5304
- "notion-pages-cache",
5305
- // Notion tools manage page hierarchy
5306
- "github-repo-cache",
5307
- // GitHub tools manage repository structure
5308
- "slack-channel-cache"
5309
- // Slack tools manage channel data
5310
- ]
5311
- /**
5312
- * LLM-owned keys
5313
- * All keys NOT in TOOL_OWNED
5314
- * Managed via memoryOps by agent reasoning
5315
- *
5316
- * LLM manages semantic memory (business context, decisions, etc.)
5317
- * that requires understanding and judgment.
5318
- */
5319
- };
5320
- function isToolOwnedKey(key) {
5321
- return MEMORY_DOMAINS.TOOL_OWNED.includes(key);
5322
- }
5323
- function getKeyOwner(key) {
5324
- if (isToolOwnedKey(key)) return "tool";
5325
- return "llm";
5326
- }
5327
-
5328
5380
  // ../core/src/execution/engine/agent/memory/utils.ts
5329
5381
  function addToolError(memoryManager, action, errorMessage, iteration, turnNumber = null, metadata) {
5330
5382
  memoryManager.addToHistory({
@@ -5348,11 +5400,10 @@ function addToolError(memoryManager, action, errorMessage, iteration, turnNumber
5348
5400
  });
5349
5401
  }
5350
5402
  function validateMemoryKeyOwnership(key, logger, iteration) {
5351
- if (isToolOwnedKey(key)) {
5352
- const owner = getKeyOwner(key);
5403
+ if (key.startsWith("_")) {
5353
5404
  logger.action(
5354
5405
  "memory-set-rejected",
5355
- `Rejected LLM update to ${owner}-managed key: ${key}`,
5406
+ `Rejected LLM update to framework-reserved key: ${key}`,
5356
5407
  iteration,
5357
5408
  Date.now(),
5358
5409
  Date.now(),
@@ -5594,25 +5645,19 @@ async function executeToolCall(iterationContext, action) {
5594
5645
  action.input,
5595
5646
  boundedResult
5596
5647
  );
5597
- const memoryStartTime = Date.now();
5598
5648
  const memoryContent = typeof boundedResult === "string" ? boundedResult : JSON.stringify(boundedResult);
5599
- iterationContext.memoryManager.addToHistory({
5600
- type: "tool-result",
5601
- content: memoryContent,
5602
- toolName: action.name,
5603
- turnNumber: iterationContext.executionContext.sessionTurnNumber ?? null,
5604
- iterationNumber: iterationContext.iteration,
5605
- source: "tool"
5606
- });
5607
- const memoryEndTime = Date.now();
5608
- const memoryDuration = memoryEndTime - memoryStartTime;
5609
- iterationContext.logger.action(
5649
+ await iterationContext.logger.timed(
5610
5650
  "memory-tool-result",
5611
- `Stored tool-result for ${action.name} (${memoryContent.length} chars), history size: ${iterationContext.memoryManager.getHistoryLength()}`,
5612
5651
  iterationContext.iteration,
5613
- memoryStartTime,
5614
- memoryEndTime,
5615
- memoryDuration
5652
+ () => iterationContext.memoryManager.addToHistory({
5653
+ type: "tool-result",
5654
+ content: memoryContent,
5655
+ toolName: action.name,
5656
+ turnNumber: iterationContext.executionContext.sessionTurnNumber ?? null,
5657
+ iterationNumber: iterationContext.iteration,
5658
+ source: "tool"
5659
+ }),
5660
+ () => `Stored tool-result for ${action.name} (${memoryContent.length} chars), history size: ${iterationContext.memoryManager.getHistoryLength()}`
5616
5661
  );
5617
5662
  } catch (error) {
5618
5663
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -5635,29 +5680,25 @@ async function executeToolCall(iterationContext, action) {
5635
5680
  action.input,
5636
5681
  void 0
5637
5682
  );
5638
- const memoryStartTime = Date.now();
5639
- const metadata = error instanceof ToolingError ? {
5640
- errorType: error.errorType,
5641
- severity: error.severity,
5642
- isRetryable: error.isRetryable()
5643
- } : void 0;
5644
- addToolError(
5645
- iterationContext.memoryManager,
5646
- action,
5647
- errorMessage,
5648
- iterationContext.iteration,
5649
- iterationContext.executionContext.sessionTurnNumber ?? null,
5650
- metadata
5651
- );
5652
- const memoryEndTime = Date.now();
5653
- const memoryDuration = memoryEndTime - memoryStartTime;
5654
- iterationContext.logger.action(
5683
+ await iterationContext.logger.timed(
5655
5684
  "memory-tool-error",
5656
- `Stored error for ${action.name}: ${errorMessage}, history size: ${iterationContext.memoryManager.getHistoryLength()}`,
5657
5685
  iterationContext.iteration,
5658
- memoryStartTime,
5659
- memoryEndTime,
5660
- memoryDuration
5686
+ () => {
5687
+ const metadata = error instanceof ToolingError ? {
5688
+ errorType: error.errorType,
5689
+ severity: error.severity,
5690
+ isRetryable: error.isRetryable()
5691
+ } : void 0;
5692
+ addToolError(
5693
+ iterationContext.memoryManager,
5694
+ action,
5695
+ errorMessage,
5696
+ iterationContext.iteration,
5697
+ iterationContext.executionContext.sessionTurnNumber ?? null,
5698
+ metadata
5699
+ );
5700
+ },
5701
+ () => `Stored error for ${action.name}: ${errorMessage}, history size: ${iterationContext.memoryManager.getHistoryLength()}`
5661
5702
  );
5662
5703
  }
5663
5704
  }
@@ -5895,11 +5936,13 @@ async function processMemory(memoryManager, response, logger, iteration) {
5895
5936
  if (!validateMemoryKeyOwnership(key, logger, iteration)) {
5896
5937
  continue;
5897
5938
  }
5898
- const startTime = Date.now();
5899
- const stringValue2 = typeof content === "string" ? content : JSON.stringify(content);
5900
- memoryManager.set(key, stringValue2);
5901
- const endTime = Date.now();
5902
- logger.action("memory-set", `Set: ${key}`, iteration, startTime, endTime, endTime - startTime);
5939
+ await logger.timed(
5940
+ "memory-set",
5941
+ iteration,
5942
+ // Auto-stringify non-string values (arrays, objects, etc.)
5943
+ () => memoryManager.set(key, typeof content === "string" ? content : JSON.stringify(content)),
5944
+ () => `Set: ${key}`
5945
+ );
5903
5946
  }
5904
5947
  }
5905
5948
  if (memoryOps.delete) {
@@ -5907,21 +5950,12 @@ async function processMemory(memoryManager, response, logger, iteration) {
5907
5950
  if (!validateMemoryKeyOwnership(key, logger, iteration)) {
5908
5951
  continue;
5909
5952
  }
5910
- const startTime = Date.now();
5911
- const deleted = memoryManager.delete(key);
5912
- const endTime = Date.now();
5913
- if (deleted) {
5914
- logger.action("memory-delete", `Deleted: ${key}`, iteration, startTime, endTime, endTime - startTime);
5915
- } else {
5916
- logger.action(
5917
- "memory-delete-missing",
5918
- `Attempted to delete non-existent key: ${key}`,
5919
- iteration,
5920
- startTime,
5921
- endTime,
5922
- endTime - startTime
5923
- );
5924
- }
5953
+ await logger.timed(
5954
+ (deleted) => deleted ? "memory-delete" : "memory-delete-missing",
5955
+ iteration,
5956
+ () => memoryManager.delete(key),
5957
+ (deleted) => deleted ? `Deleted: ${key}` : `Attempted to delete non-existent key: ${key}`
5958
+ );
5925
5959
  }
5926
5960
  }
5927
5961
  }
@@ -6048,7 +6082,6 @@ var MemoryManager = class {
6048
6082
  this.constraints = constraints;
6049
6083
  this.logger = logger;
6050
6084
  }
6051
- cachedSnapshot;
6052
6085
  /**
6053
6086
  * Rolling correction for `estimateTokens`'s bias, learned from real provider usage.
6054
6087
  * `undefined` until the first `recordActualUsage` call -- the cold-start state, where
@@ -6337,21 +6370,15 @@ var MemoryManager = class {
6337
6370
  };
6338
6371
  }
6339
6372
  /**
6340
- * Create memory snapshot for persistence
6341
- * Caches snapshot internally for later retrieval
6373
+ * Create a memory snapshot for persistence.
6374
+ *
6375
+ * Stateless: every call returns a fresh `structuredClone` of the current memory, so the caller
6376
+ * owns caching if it needs to hold onto the result across calls (see `Agent.memorySnapshot`).
6377
+ *
6342
6378
  * @returns Deep copy of current memory state
6343
6379
  */
6344
- toSnapshot() {
6345
- this.cachedSnapshot = structuredClone(this.memory);
6346
- return this.cachedSnapshot;
6347
- }
6348
- /**
6349
- * Get cached memory snapshot
6350
- * Returns snapshot created by toSnapshot()
6351
- * @returns Cached snapshot (undefined if toSnapshot() not called yet)
6352
- */
6353
- getSnapshot() {
6354
- return this.cachedSnapshot;
6380
+ snapshot() {
6381
+ return structuredClone(this.memory);
6355
6382
  }
6356
6383
  /**
6357
6384
  * Build the framework framing and the untrusted data envelope for an LLM call.
@@ -6483,6 +6510,12 @@ var Agent = class {
6483
6510
  * reading memory history after the fact, because the emit is the user-visible event and memory
6484
6511
  * can be compacted or restructured without changing whether the turn spoke. */
6485
6512
  spokeThisTurn = false;
6513
+ /** Cached result of `memoryManager.snapshot()` -- `MemoryManager.snapshot()` itself is stateless
6514
+ * (a fresh `structuredClone` every call), so caching the LAST one taken is this class's job. Set
6515
+ * once, in the `finally` around `iterate()` and again in `complete()` -- see `getMemorySnapshot()`
6516
+ * for why `undefined`-before-first-iteration is a contract other callers (`session.ts`, the SDK
6517
+ * worker) depend on. */
6518
+ memorySnapshot;
6486
6519
  /**
6487
6520
  * Create a new agent instance from definition
6488
6521
  * Memory will be initialized during execution
@@ -6523,7 +6556,7 @@ var Agent = class {
6523
6556
  try {
6524
6557
  await this.iterate(this.executionContext);
6525
6558
  } finally {
6526
- this.memoryManager.toSnapshot();
6559
+ this.memorySnapshot = this.memoryManager.snapshot();
6527
6560
  }
6528
6561
  }
6529
6562
  const output = await this.complete();
@@ -6636,22 +6669,21 @@ var Agent = class {
6636
6669
  async initializeMemoryManager(context) {
6637
6670
  const memory = await this.resolveInitialMemory(context);
6638
6671
  const memoryManager = new MemoryManager(memory, this.config.constraints, this.logger);
6639
- const inputStartTime = Date.now();
6640
- memoryManager.addToHistory({
6641
- type: "input",
6642
- content: this.currentInput,
6643
- turnNumber: context.sessionTurnNumber ?? null,
6644
- iterationNumber: 0,
6645
- source: "user"
6646
- });
6647
- const inputEndTime = Date.now();
6648
- this.logger.action(
6672
+ await this.logger.timed(
6649
6673
  "memory-input",
6650
- `Added input entry to history`,
6651
6674
  0,
6652
- inputStartTime,
6653
- inputEndTime,
6654
- inputEndTime - inputStartTime
6675
+ // Kept in history even though the input also travels as its own message: history is what
6676
+ // later iterations and later turns read, and `autoCompact` anchors on `history[0]` as the
6677
+ // original input. `toContextParts` excludes this entry from the current turn's envelope so
6678
+ // the model does not see the same text twice.
6679
+ () => memoryManager.addToHistory({
6680
+ type: "input",
6681
+ content: this.currentInput,
6682
+ turnNumber: context.sessionTurnNumber ?? null,
6683
+ iterationNumber: 0,
6684
+ source: "user"
6685
+ }),
6686
+ () => `Added input entry to history`
6655
6687
  );
6656
6688
  flowLog("agent.initialize", {
6657
6689
  resourceId: this.config.resourceId,
@@ -6673,32 +6705,20 @@ var Agent = class {
6673
6705
  */
6674
6706
  async resolveInitialMemory(context) {
6675
6707
  if (this.initialMemory) {
6676
- const restoreStartTime = Date.now();
6677
- const memory = structuredClone(this.initialMemory);
6678
- const restoreEndTime = Date.now();
6679
- this.logger.action(
6708
+ return this.logger.timed(
6680
6709
  "memory-restore",
6681
- `Restored ${Object.keys(memory.sessionMemory).length} session memory entries`,
6682
6710
  0,
6683
- restoreStartTime,
6684
- restoreEndTime,
6685
- restoreEndTime - restoreStartTime
6711
+ () => structuredClone(this.initialMemory),
6712
+ (memory) => `Restored ${Object.keys(memory.sessionMemory).length} session memory entries`
6686
6713
  );
6687
- return memory;
6688
6714
  }
6689
6715
  if (this.definition.preloadMemory) {
6690
- const preloadStartTime = Date.now();
6691
- const memory = await this.definition.preloadMemory(context);
6692
- const preloadEndTime = Date.now();
6693
- this.logger.action(
6716
+ return this.logger.timed(
6694
6717
  "memory-preload",
6695
- `Preloaded ${Object.keys(memory.sessionMemory).length} session memory entries`,
6696
6718
  0,
6697
- preloadStartTime,
6698
- preloadEndTime,
6699
- preloadEndTime - preloadStartTime
6719
+ () => this.definition.preloadMemory(context),
6720
+ (memory) => `Preloaded ${Object.keys(memory.sessionMemory).length} session memory entries`
6700
6721
  );
6701
- return memory;
6702
6722
  }
6703
6723
  return { sessionMemory: {}, history: [] };
6704
6724
  }
@@ -6832,8 +6852,8 @@ var Agent = class {
6832
6852
  0
6833
6853
  );
6834
6854
  }
6835
- this.memoryManager.toSnapshot();
6836
- const snapshot = this.memoryManager.getSnapshot();
6855
+ const snapshot = this.memoryManager.snapshot();
6856
+ this.memorySnapshot = snapshot;
6837
6857
  const completionEndTime = Date.now();
6838
6858
  this.logger.lifecycle("completion", "completed", {
6839
6859
  startTime: completionStartTime,
@@ -7049,12 +7069,17 @@ Fix the errors and generate a valid output.
7049
7069
  `.trim();
7050
7070
  }
7051
7071
  /**
7052
- * Get memory snapshot after execution
7053
- * Delegates to MemoryManager.getSnapshot()
7054
- * @returns Memory snapshot (only available after execute() completes)
7072
+ * Get memory snapshot after execution.
7073
+ *
7074
+ * `undefined` until the `finally` around `iterate()` (or `complete()`) takes the first snapshot --
7075
+ * `session.ts` and the SDK worker both rely on this to distinguish "no memory produced yet" (a
7076
+ * throw during `initialize()`, before any iteration ran) from "memory exists".
7077
+ *
7078
+ * @returns Memory snapshot (only available after execute() completes, or after a mid-turn throw
7079
+ * past the point `iterate()` began)
7055
7080
  */
7056
7081
  getMemorySnapshot() {
7057
- return this.memoryManager.getSnapshot();
7082
+ return this.memorySnapshot;
7058
7083
  }
7059
7084
  /**
7060
7085
  * How the just-finished turn ended -- see `AgentStopReason`. Set once `iterate()` returns,
@@ -8981,17 +9006,23 @@ var SystemInterfaceResourceScopeSchema = z.array(ModelIdSchema).default([]);
8981
9006
  var SystemApiInterfaceReadinessContractSchema = z.object({
8982
9007
  /** Ontology IDs of object types the interface depends on. */
8983
9008
  requiredObjects: z.array(z.string().trim().min(1)).default([]),
8984
- /** Ontology IDs of catalog types the interface requires (must be non-empty). */
8985
- requiredCatalogs: z.array(z.string().trim().min(1)).default([]),
8986
- /** Optional ontology kind filters (reserved for future profile extensions). */
8987
- requiredKinds: z.array(z.string().trim().min(1)).optional()
9009
+ /**
9010
+ * Ontology IDs of catalog types the interface requires. Must declare at least one
9011
+ * entry a `readinessContract` with no `requiredCatalogs` asserts nothing at all,
9012
+ * so it has no `.default([])`; omitting the field is rejected the same as an
9013
+ * explicit empty array.
9014
+ */
9015
+ requiredCatalogs: z.array(z.string().trim().min(1)).min(1)
8988
9016
  }).strict();
8989
9017
  var SystemApiInterfaceSchema = z.object({
8990
9018
  lifecycle: SystemInterfaceLifecycleSchema.default("active"),
8991
9019
  /**
8992
9020
  * Open-string profile id. Built-in platform presets are looked up through
8993
9021
  * the profile registry; custom ids are validated structurally via
8994
- * `readinessContract`. Optional `profileForInterface` provides a default.
9022
+ * `readinessContract`. Optional at the schema layer, but readiness
9023
+ * computation rejects an interface that omits it with a
9024
+ * `missing-readiness-profile` diagnostic — there is no positional
9025
+ * fallback to `${systemPath}.${interfaceKey}`.
8995
9026
  */
8996
9027
  readinessProfile: SystemInterfaceReadinessProfileSchema.optional(),
8997
9028
  /**
@@ -9012,9 +9043,6 @@ var _profileRegistry = new Map(
9012
9043
  { profileId, kind: "built-in" }
9013
9044
  ])
9014
9045
  );
9015
- function profileForInterface(systemPath, interfaceKey, readinessProfile) {
9016
- return readinessProfile ?? `${systemPath}.${interfaceKey}`;
9017
- }
9018
9046
  function isBuiltInReadinessProfile(profileId) {
9019
9047
  return _profileRegistry.get(profileId)?.kind === "built-in";
9020
9048
  }
@@ -9111,412 +9139,80 @@ z.record(z.string(), SystemEntrySchema).refine((record) => Object.entries(record
9111
9139
  message: "Each system entry id must match its map key"
9112
9140
  }).default({});
9113
9141
 
9114
- // ../core/src/organization-model/migration-helpers.ts
9115
- function catalogRecords(model) {
9116
- return Object.values(compileOrganizationOntology(model).ontology.catalogTypes);
9142
+ // ../core/src/organization-model/readiness/profile-registry.ts
9143
+ var _builtInProfileValidators = /* @__PURE__ */ new Map();
9144
+ function getBuiltInReadinessProfile(profileId) {
9145
+ return _builtInProfileValidators.get(profileId);
9117
9146
  }
9118
- function systemScope(id, fallback) {
9119
- return parseOntologyId(id).scope || fallback || "";
9147
+ var _interfaceMarkerResolvers = /* @__PURE__ */ new Map();
9148
+ function interfaceMarkerKey(systemPath, interfaceKey) {
9149
+ return `${systemPath}::${interfaceKey}`;
9120
9150
  }
9121
- function entriesOf(catalog) {
9122
- return Object.entries(catalog.entries ?? {}).map(([id, value]) => [
9123
- id,
9124
- value && typeof value === "object" && !Array.isArray(value) ? value : {}
9125
- ]);
9151
+ function resolveReadinessInterfaceMarker(model, systemPath, interfaceKey) {
9152
+ return _interfaceMarkerResolvers.get(interfaceMarkerKey(systemPath, interfaceKey))?.(model);
9126
9153
  }
9127
- function stringValue(value) {
9128
- return typeof value === "string" ? value : void 0;
9154
+
9155
+ // ../core/src/organization-model/readiness/engine.ts
9156
+ function addReadinessIssue(issues, family, code, message, details = {}) {
9157
+ issues.push({
9158
+ family,
9159
+ code,
9160
+ message,
9161
+ ...details
9162
+ });
9129
9163
  }
9130
- function stringArray(value) {
9131
- return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
9164
+ function formatInterfaceIdentity(systemPath, interfaceKey) {
9165
+ return `${systemPath}/${interfaceKey}`;
9132
9166
  }
9133
- function numberValue(value, fallback = 0) {
9134
- return typeof value === "number" ? value : fallback;
9167
+ function readinessMarkerPath(context) {
9168
+ return context.interfaceKey === "api" ? `systems.${context.systemPath}.apiInterface` : void 0;
9135
9169
  }
9136
- function appliesToLocalId(catalog) {
9137
- const appliesTo = catalog.appliesTo;
9138
- if (appliesTo === void 0) return void 0;
9139
- return parseOntologyId(appliesTo).localId;
9170
+ function readinessMarkerFieldPath(context, suffix) {
9171
+ const base = readinessMarkerPath(context);
9172
+ return base === void 0 ? void 0 : `${base}${suffix}`;
9140
9173
  }
9141
- function appliesToEntityKind(catalog) {
9142
- const id = appliesToLocalId(catalog);
9143
- if (id === "company" || id === "contact" || id === "project" || id === "milestone" || id === "task") return id;
9144
- if (id === "deal") return void 0;
9145
- return void 0;
9174
+ function formatSupportedReadinessProfiles() {
9175
+ return SYSTEM_INTERFACE_PROFILES.map((p3) => `"${p3.readinessProfile}"`).join(", ");
9146
9176
  }
9147
- function getLeadGenStageCatalog(model) {
9148
- const results = {};
9149
- for (const catalog of catalogRecords(model).filter(
9150
- (record) => record.kind === "stage" && (record.ownerSystemId ?? systemScope(record.id)) === "sales.lead-gen"
9151
- )) {
9152
- const catalogEntity = appliesToEntityKind(catalog);
9153
- if (catalogEntity !== "company" && catalogEntity !== "contact") continue;
9154
- for (const [entryId, entry] of entriesOf(catalog)) {
9155
- const entity = entry.entity === "contact" ? "contact" : entry.entity === "company" ? "company" : catalogEntity;
9156
- const additionalEntities = stringArray(entry.additionalEntities).filter(
9157
- (item) => item === "company" || item === "contact"
9158
- );
9159
- const recordEntity = entry.recordEntity === "company" || entry.recordEntity === "contact" ? entry.recordEntity : void 0;
9160
- const recordStageKey = stringValue(entry.recordStageKey);
9161
- const readinessTarget = entry.readinessTarget === true ? true : void 0;
9162
- results[entryId] = {
9163
- key: entryId,
9164
- label: stringValue(entry.label) ?? entryId,
9165
- description: stringValue(entry.description) ?? "",
9166
- order: numberValue(entry.order),
9167
- entity,
9168
- ...additionalEntities.length > 0 ? { additionalEntities } : {},
9169
- ...recordEntity ? { recordEntity } : {},
9170
- ...recordStageKey ? { recordStageKey } : {},
9171
- ...readinessTarget ? { readinessTarget } : {}
9172
- };
9173
- }
9174
- }
9175
- return Object.fromEntries(
9176
- Object.entries(results).sort(([, a3], [, b2]) => a3.order - b2.order || a3.key.localeCompare(b2.key))
9177
- );
9177
+ function isPlainRecord(value) {
9178
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
9178
9179
  }
9179
- z.object({
9180
- success: z.boolean(),
9181
- tool: z.string(),
9182
- method: z.string(),
9183
- result: z.unknown().optional(),
9184
- error: z.string().optional(),
9185
- durationMs: z.number().optional()
9186
- });
9187
- z.object({
9188
- credential: z.string().describe("Credential name registered for this integration")
9189
- });
9190
-
9191
- // ../core/src/execution/engine/llm/schema/compile.ts
9192
- function isPlainObject(value) {
9193
- return typeof value === "object" && value !== null && !Array.isArray(value);
9180
+ function getCatalogEntries(catalog) {
9181
+ return isPlainRecord(catalog.entries) ? catalog.entries : {};
9194
9182
  }
9195
- var UNSUPPORTED_KEYWORDS = /* @__PURE__ */ new Set([
9196
- "minimum",
9197
- "maximum",
9198
- "exclusiveMinimum",
9199
- "exclusiveMaximum",
9200
- "multipleOf",
9201
- "minLength",
9202
- "maxLength",
9203
- "pattern",
9204
- "maxItems",
9205
- "uniqueItems",
9206
- "minProperties",
9207
- "maxProperties",
9208
- "patternProperties",
9209
- "propertyNames",
9210
- "contains",
9211
- "minContains",
9212
- "maxContains",
9213
- "dependentRequired",
9214
- "dependentSchemas",
9215
- "if",
9216
- "then",
9217
- "else",
9218
- "not",
9219
- "$id",
9220
- "$anchor"
9221
- ]);
9222
- var SUPPORTED_FORMATS = /* @__PURE__ */ new Set([
9223
- "date-time",
9224
- "time",
9225
- "date",
9226
- "duration",
9227
- "email",
9228
- "hostname",
9229
- "uri",
9230
- "ipv4",
9231
- "ipv6",
9232
- "uuid"
9233
- ]);
9234
- var MAX_SCHEMA_DEPTH = 32;
9235
- function convertNode(node, state, depth) {
9236
- if (depth > MAX_SCHEMA_DEPTH && state.dialect.strict !== "unsupported") {
9237
- state.blockers.push("depth>32");
9238
- return node;
9239
- }
9240
- if (Array.isArray(node)) {
9241
- return node.map((item) => convertNode(item, state, depth + 1));
9242
- }
9243
- if (!isPlainObject(node)) {
9244
- return node;
9245
- }
9246
- const strictEngaged = state.dialect.strict !== "unsupported";
9247
- const out = {};
9248
- for (const [key, value] of Object.entries(node)) {
9249
- if (key === "$ref" || key === "$defs" || key === "definitions") {
9250
- if (state.dialect.refs === "refuse") {
9251
- state.blockers.push(`unsupported:${key}`);
9252
- out[key] = value;
9253
- continue;
9254
- }
9255
- out[key] = value;
9256
- continue;
9257
- }
9258
- if (key === "$schema") {
9259
- if (!state.dialect.allowsSchemaKeyword) {
9260
- continue;
9261
- }
9262
- out.$schema = value;
9183
+ function getActiveScopedResources(model, resourceIds, issues, context) {
9184
+ const resources = [];
9185
+ for (const [index2, resourceId] of resourceIds.entries()) {
9186
+ const resource = model.resources?.[resourceId];
9187
+ const path = readinessMarkerFieldPath(context, `.resourceIds.${index2}`);
9188
+ if (resource === void 0) {
9189
+ addReadinessIssue(
9190
+ issues,
9191
+ "SYSTEM_INTERFACE_NOT_READY",
9192
+ "missing-resource",
9193
+ `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" scopes missing resource "${resourceId}".`,
9194
+ { path, ref: resourceId }
9195
+ );
9263
9196
  continue;
9264
9197
  }
9265
- if (key === "properties") {
9266
- if (!isPlainObject(value)) {
9267
- out.properties = value;
9268
- continue;
9269
- }
9270
- const properties = {};
9271
- for (const [propertyName, propertySchema] of Object.entries(value)) {
9272
- properties[propertyName] = convertNode(propertySchema, state, depth + 1);
9273
- }
9274
- out.properties = properties;
9198
+ if (resource.systemPath !== context.systemPath) {
9199
+ addReadinessIssue(
9200
+ issues,
9201
+ "SYSTEM_INTERFACE_INVALID",
9202
+ "resource-system-mismatch",
9203
+ `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" scopes resource "${resourceId}" from system "${resource.systemPath}".`,
9204
+ { path, ref: resourceId }
9205
+ );
9275
9206
  continue;
9276
9207
  }
9277
- if (key === "items") {
9278
- out.items = convertNode(value, state, depth + 1);
9279
- continue;
9280
- }
9281
- if (strictEngaged) {
9282
- if (UNSUPPORTED_KEYWORDS.has(key)) {
9283
- continue;
9284
- }
9285
- if (key === "oneOf") {
9286
- out.anyOf = convertNode(value, state, depth + 1);
9287
- continue;
9288
- }
9289
- if (key === "format") {
9290
- if (typeof value === "string" && SUPPORTED_FORMATS.has(value)) {
9291
- out.format = value;
9292
- }
9293
- continue;
9294
- }
9295
- if (key === "minItems") {
9296
- const n2 = typeof value === "number" ? value : 0;
9297
- out.minItems = n2 > 1 ? 1 : n2;
9298
- continue;
9299
- }
9300
- if (key === "type" && Array.isArray(value)) {
9301
- out.anyOf = value.map((t) => ({ type: t }));
9302
- continue;
9303
- }
9304
- if (key === "additionalProperties") {
9305
- continue;
9306
- }
9307
- }
9308
- out[key] = convertNode(value, state, depth + 1);
9309
- }
9310
- const isObjectNode = out.type === "object" || isPlainObject(out.properties);
9311
- if (isObjectNode) {
9312
- const properties = isPlainObject(out.properties) ? out.properties : void 0;
9313
- const originalAdditionalProperties = node.additionalProperties;
9314
- if (strictEngaged) {
9315
- if (properties) {
9316
- const declared = Object.keys(properties);
9317
- const required = Array.isArray(out.required) ? out.required : [];
9318
- const optional = declared.filter((k2) => !required.includes(k2));
9319
- if (state.dialect.strict === "allRequired" && optional.length > 0) {
9320
- state.blockers.push(`optionalProperty:${optional[0]}`);
9321
- }
9322
- state.optionalProperties += optional.length;
9323
- }
9324
- if (originalAdditionalProperties !== void 0 && originalAdditionalProperties !== false && (!properties || Object.keys(properties).length === 0)) {
9325
- state.blockers.push("freeFormObject");
9326
- }
9327
- out.additionalProperties = false;
9328
- }
9329
- if (strictEngaged && (!properties || Object.keys(properties).length === 0)) {
9330
- out.properties = {};
9331
- }
9332
- }
9333
- return out;
9334
- }
9335
- function dedupe(values) {
9336
- return [...new Set(values)];
9337
- }
9338
- function compileSchema(schema, dialect) {
9339
- if (!isPlainObject(schema)) {
9340
- const strictEngaged = dialect.strict !== "unsupported";
9341
- return {
9342
- schema,
9343
- sendStrict: false,
9344
- status: strictEngaged ? "refused" : "notAttempted",
9345
- refusalReasons: strictEngaged ? ["notAnObject"] : []
9346
- };
9347
- }
9348
- const state = { dialect, blockers: [], optionalProperties: 0 };
9349
- const compiled = convertNode(schema, state, 0);
9350
- if (state.blockers.length === 0 && dialect.maxOptionalProperties !== void 0 && state.optionalProperties > dialect.maxOptionalProperties) {
9351
- state.blockers.push(`optionalPropertyLimit:${state.optionalProperties}>${dialect.maxOptionalProperties}`);
9352
- }
9353
- if (dialect.strict === "unsupported") {
9354
- return {
9355
- schema: compiled,
9356
- sendStrict: false,
9357
- status: "notAttempted",
9358
- refusalReasons: []
9359
- };
9360
- }
9361
- if (state.blockers.length > 0) {
9362
- return {
9363
- schema,
9364
- sendStrict: false,
9365
- status: "refused",
9366
- refusalReasons: dedupe(state.blockers)
9367
- };
9368
- }
9369
- return { schema: compiled, sendStrict: true, status: "applied", refusalReasons: [] };
9370
- }
9371
-
9372
- // ../core/src/execution/engine/llm/schema/dialect.ts
9373
- var ANTHROPIC_DIALECT = {
9374
- strict: "optionalAllowed",
9375
- // No placeholder of its own: an empty or absent `properties` becomes a bare `properties: {}`,
9376
- // synthesized directly by the walk for any dialect engaging strict.
9377
- // Refuses rather than inlining: detecting recursion through `$defs` is more machinery than the
9378
- // payoff justifies for a tool-input schema.
9379
- refs: "refuse",
9380
- allowsSchemaKeyword: false,
9381
- // Anthropic's published ceiling. Measured live before this was added: the Command Center
9382
- // assistant's iteration schema declares 33, so 8 of 8 iterations across a 3-turn session were
9383
- // 400'd and retried unstrict. `optionalAllowed` is still correct -- an optional property is
9384
- // representable in this grammar, there is just a cap on how many.
9385
- maxOptionalProperties: 24
9386
- };
9387
- var OPENAI_DIALECT = {
9388
- strict: "allRequired",
9389
- refs: "passthrough",
9390
- allowsSchemaKeyword: false
9391
- };
9392
- var OPENROUTER_DIALECT = {
9393
- strict: "allRequired",
9394
- refs: "refuse",
9395
- allowsSchemaKeyword: false
9396
- };
9397
- var PROVIDER_DIALECTS = {
9398
- anthropic: ANTHROPIC_DIALECT,
9399
- openai: OPENAI_DIALECT,
9400
- openrouter: OPENROUTER_DIALECT
9401
- };
9402
-
9403
- // ../core/src/business/acquisition/ontology-validation.ts
9404
- var LEAD_GEN_API_INTERFACE = SYSTEM_INTERFACE_PROFILES[0];
9405
- var CRM_API_INTERFACE = SYSTEM_INTERFACE_PROFILES[1];
9406
- var LEAD_GEN_CRM_HANDOFF_INTERFACE = SYSTEM_INTERFACE_PROFILES[2];
9407
- LEAD_GEN_API_INTERFACE.readinessProfile;
9408
- CRM_API_INTERFACE.readinessProfile;
9409
- LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile;
9410
- var LEAD_GEN_LIST_OBJECT_ONTOLOGY_ID = formatOntologyId({
9411
- scope: "sales.lead-gen",
9412
- kind: "object",
9413
- localId: "list"
9414
- });
9415
- var LEAD_GEN_COMPANY_OBJECT_ONTOLOGY_ID = formatOntologyId({
9416
- scope: "sales.lead-gen",
9417
- kind: "object",
9418
- localId: "company"
9419
- });
9420
- var LEAD_GEN_CONTACT_OBJECT_ONTOLOGY_ID = formatOntologyId({
9421
- scope: "sales.lead-gen",
9422
- kind: "object",
9423
- localId: "contact"
9424
- });
9425
- var LEAD_GEN_BUILD_TEMPLATE_CATALOG_ONTOLOGY_ID = formatOntologyId({
9426
- scope: "sales.lead-gen",
9427
- kind: "catalog",
9428
- localId: "build-template"
9429
- });
9430
- var LEAD_GEN_COMPANY_STAGE_CATALOG_ONTOLOGY_ID = formatOntologyId({
9431
- scope: "sales.lead-gen",
9432
- kind: "catalog",
9433
- localId: "company-stage"
9434
- });
9435
- var LEAD_GEN_CONTACT_STAGE_CATALOG_ONTOLOGY_ID = formatOntologyId({
9436
- scope: "sales.lead-gen",
9437
- kind: "catalog",
9438
- localId: "contact-stage"
9439
- });
9440
- var CRM_PIPELINE_CATALOG_ONTOLOGY_ID = formatOntologyId({
9441
- scope: "sales.crm",
9442
- kind: "catalog",
9443
- localId: "crm.pipeline"
9444
- });
9445
- var LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID = formatOntologyId({
9446
- scope: "sales.lead-gen",
9447
- kind: "catalog",
9448
- localId: "lead-gen.stage-catalog"
9449
- });
9450
- function createLeadGenStageCatalog(model) {
9451
- return {
9452
- id: LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID,
9453
- label: "Lead Gen Processing Stages",
9454
- ownerSystemId: "sales.lead-gen",
9455
- kind: "processing-stage-catalog",
9456
- entries: Object.fromEntries(
9457
- Object.entries(getLeadGenStageCatalog(model)).map(([key, entry]) => [
9458
- key,
9459
- {
9460
- ...entry
9461
- }
9462
- ])
9463
- ),
9464
- legacyCatalogKey: "LEAD_GEN_STAGE_CATALOG"
9465
- };
9466
- }
9467
- function isPlainRecord(value) {
9468
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
9469
- }
9470
- function addReadinessIssue(issues, family, code, message, details = {}) {
9471
- issues.push({
9472
- family,
9473
- code,
9474
- message,
9475
- ...details
9476
- });
9477
- }
9478
- function formatInterfaceIdentity(systemPath, interfaceKey) {
9479
- return `${systemPath}/${interfaceKey}`;
9480
- }
9481
- function readinessMarkerPath(context) {
9482
- return context.interfaceKey === "api" ? `systems.${context.systemPath}.apiInterface` : `systems.${context.systemPath}.derivedCrmHandoffReadiness`;
9483
- }
9484
- function formatSupportedReadinessProfiles() {
9485
- return SYSTEM_INTERFACE_PROFILES.map((p3) => `"${p3.readinessProfile}"`).join(", ");
9486
- }
9487
- function getActiveScopedResources(model, resourceIds, issues, context) {
9488
- const resources = [];
9489
- for (const [index2, resourceId] of resourceIds.entries()) {
9490
- const resource = model.resources?.[resourceId];
9491
- const path = `${readinessMarkerPath(context)}.resourceIds.${index2}`;
9492
- if (resource === void 0) {
9493
- addReadinessIssue(
9494
- issues,
9495
- "SYSTEM_INTERFACE_NOT_READY",
9496
- "missing-resource",
9497
- `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" scopes missing resource "${resourceId}".`,
9498
- { path, ref: resourceId }
9499
- );
9500
- continue;
9501
- }
9502
- if (resource.systemPath !== context.systemPath) {
9503
- addReadinessIssue(
9504
- issues,
9505
- "SYSTEM_INTERFACE_INVALID",
9506
- "resource-system-mismatch",
9507
- `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" scopes resource "${resourceId}" from system "${resource.systemPath}".`,
9508
- { path, ref: resourceId }
9509
- );
9510
- continue;
9511
- }
9512
- if (resource.status !== "active") {
9513
- addReadinessIssue(
9514
- issues,
9515
- "SYSTEM_INTERFACE_NOT_READY",
9516
- "inactive-resource",
9517
- `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" scopes inactive resource "${resourceId}".`,
9518
- { path, ref: resourceId }
9519
- );
9208
+ if (resource.status !== "active") {
9209
+ addReadinessIssue(
9210
+ issues,
9211
+ "SYSTEM_INTERFACE_NOT_READY",
9212
+ "inactive-resource",
9213
+ `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" scopes inactive resource "${resourceId}".`,
9214
+ { path, ref: resourceId }
9215
+ );
9520
9216
  continue;
9521
9217
  }
9522
9218
  resources.push(resource);
@@ -9533,7 +9229,7 @@ function requireScopedBinding(issues, boundIds, bindingKey, ontologyId, context)
9533
9229
  "SYSTEM_INTERFACE_NOT_READY",
9534
9230
  "missing-resource-binding",
9535
9231
  `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" has no active scoped resource with ontology.${bindingKey} binding "${ontologyId}".`,
9536
- { path: `${readinessMarkerPath(context)}.resourceIds`, ref: ontologyId }
9232
+ { path: readinessMarkerFieldPath(context, ".resourceIds"), ref: ontologyId }
9537
9233
  );
9538
9234
  }
9539
9235
  function ontologyOwnerMatches(ontologyId, expectedSystemPath, catalog) {
@@ -9595,129 +9291,40 @@ function requireCatalogReadiness(issues, index2, catalogId, context) {
9595
9291
  }
9596
9292
  return catalog;
9597
9293
  }
9598
- function requireLeadGenInterfaceReadiness(issues, index2, resources, context) {
9294
+ function requireContractReadiness(issues, index2, resources, contract, context) {
9599
9295
  const reads = resourceBindingIds(resources, "reads");
9600
9296
  const catalogs = resourceBindingIds(resources, "usesCatalogs");
9601
- for (const objectId of [
9602
- LEAD_GEN_LIST_OBJECT_ONTOLOGY_ID,
9603
- LEAD_GEN_COMPANY_OBJECT_ONTOLOGY_ID,
9604
- LEAD_GEN_CONTACT_OBJECT_ONTOLOGY_ID
9605
- ]) {
9297
+ for (const objectId of contract.requiredObjects) {
9606
9298
  requireObjectReadiness(issues, index2, objectId, context);
9607
9299
  requireScopedBinding(issues, reads, "reads", objectId, context);
9608
9300
  }
9609
- for (const catalogId of [
9610
- LEAD_GEN_BUILD_TEMPLATE_CATALOG_ONTOLOGY_ID,
9611
- LEAD_GEN_COMPANY_STAGE_CATALOG_ONTOLOGY_ID,
9612
- LEAD_GEN_CONTACT_STAGE_CATALOG_ONTOLOGY_ID
9613
- ]) {
9301
+ for (const catalogId of contract.requiredCatalogs) {
9614
9302
  requireCatalogReadiness(issues, index2, catalogId, context);
9615
9303
  requireScopedBinding(issues, catalogs, "usesCatalogs", catalogId, context);
9616
9304
  }
9617
- const templateStepCatalog = findLeadGenTemplateStepCatalog(index2);
9618
- if (templateStepCatalog === void 0) {
9619
- addReadinessIssue(
9620
- issues,
9621
- "SYSTEM_INTERFACE_NOT_READY",
9622
- "missing-template-step-catalog",
9623
- `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" is missing a lead-gen template-step catalog.`
9624
- );
9625
- } else {
9626
- requireCatalogReadiness(issues, index2, templateStepCatalog.id, context);
9627
- requireScopedBinding(issues, catalogs, "usesCatalogs", templateStepCatalog.id, context);
9628
- }
9629
- const leadGenStageCatalog = requireCatalogReadiness(issues, index2, LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID, context);
9630
- return leadGenStageCatalog;
9631
- }
9632
- function requireCrmInterfaceReadiness(issues, index2, resources, context) {
9633
- const catalogs = resourceBindingIds(resources, "usesCatalogs");
9634
- const crmPipelineCatalog = requireCatalogReadiness(issues, index2, CRM_PIPELINE_CATALOG_ONTOLOGY_ID, context);
9635
- requireScopedBinding(issues, catalogs, "usesCatalogs", CRM_PIPELINE_CATALOG_ONTOLOGY_ID, context);
9636
- return crmPipelineCatalog;
9637
- }
9638
- function findSystemInterfaceGrant(model, consumer, provider) {
9639
- return Object.values(model.topology?.relationships ?? {}).find((relationship) => {
9640
- const grant = relationship.metadata?.["systemInterfaceGrant"];
9641
- if (!isPlainRecord(grant) || !isPlainRecord(grant.consumer) || !isPlainRecord(grant.provider)) return false;
9642
- return grant.consumer.systemPath === consumer.systemPath && grant.consumer.interfaceKey === consumer.interfaceKey && grant.provider.systemPath === provider.systemPath && grant.provider.interfaceKey === provider.interfaceKey;
9643
- });
9644
- }
9645
- function requireHandoffBridgeReadiness(issues, model, context) {
9646
- const crmResult = computeInterfaceReadiness(model, CRM_API_INTERFACE);
9647
- if (!crmResult.ready) {
9648
- for (const issue of crmResult.issues) {
9649
- addReadinessIssue(
9650
- issues,
9651
- "SYSTEM_BRIDGE_NOT_READY",
9652
- issue.code,
9653
- `Provider interface ${formatInterfaceIdentity(CRM_API_INTERFACE.systemPath, CRM_API_INTERFACE.interfaceKey)} is not ready: ${issue.message}`,
9654
- { path: issue.path, ref: issue.ref }
9655
- );
9656
- }
9657
- }
9658
- const bridgeGrant = findSystemInterfaceGrant(model, context, CRM_API_INTERFACE);
9659
- if (bridgeGrant === void 0) {
9660
- addReadinessIssue(
9661
- issues,
9662
- "SYSTEM_BRIDGE_NOT_READY",
9663
- "missing-topology-grant",
9664
- `System Interface "${formatInterfaceIdentity(context.systemPath, context.interfaceKey)}" requires a scoped topology grant to "${formatInterfaceIdentity(CRM_API_INTERFACE.systemPath, CRM_API_INTERFACE.interfaceKey)}".`
9665
- );
9666
- }
9667
- return bridgeGrant;
9668
- }
9669
- function getLeadGenCrmHandoffResourceIds(model) {
9670
- return Object.values(model.resources ?? {}).filter(
9671
- (resource) => resource.systemPath === LEAD_GEN_CRM_HANDOFF_INTERFACE.systemPath && resource.ontology?.usesCatalogs?.includes(CRM_PIPELINE_CATALOG_ONTOLOGY_ID) === true
9672
- ).map((resource) => resource.id);
9673
9305
  }
9674
9306
  function getSystemInterfaceReadinessMarker(model, request) {
9675
9307
  const system = getSystem(model, request.systemPath);
9676
9308
  if (system === void 0) return void 0;
9677
- if (request.systemPath === LEAD_GEN_CRM_HANDOFF_INTERFACE.systemPath && request.interfaceKey === LEAD_GEN_CRM_HANDOFF_INTERFACE.interfaceKey) {
9678
- return {
9679
- lifecycle: "active",
9680
- readinessProfile: LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile,
9681
- resourceIds: getLeadGenCrmHandoffResourceIds(model)
9682
- };
9683
- }
9309
+ const registeredMarker = resolveReadinessInterfaceMarker(model, request.systemPath, request.interfaceKey);
9310
+ if (registeredMarker !== void 0) return registeredMarker;
9684
9311
  if (request.interfaceKey === "api" && system.apiInterface !== void 0) {
9685
9312
  return system.apiInterface;
9686
9313
  }
9687
9314
  return void 0;
9688
9315
  }
9689
- function mergeLeadGenDerivedCatalogs(model) {
9690
- const baseCatalogTypes = model.ontology?.catalogTypes ?? {};
9691
- const derivedCatalogTypes = {};
9692
- if (baseCatalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID] === void 0) {
9693
- derivedCatalogTypes[LEAD_GEN_STAGE_CATALOG_ONTOLOGY_ID] = createLeadGenStageCatalog(model);
9694
- }
9695
- if (Object.keys(derivedCatalogTypes).length === 0) return model;
9696
- return {
9697
- ...model,
9698
- ontology: {
9699
- ...model.ontology ?? {},
9700
- catalogTypes: {
9701
- ...baseCatalogTypes,
9702
- ...derivedCatalogTypes
9703
- }
9704
- }
9705
- };
9706
- }
9707
- function compileBusinessOntology(model, contractId) {
9708
- const compilation = compileOrganizationOntology(mergeLeadGenDerivedCatalogs(model));
9316
+ function compileReadinessOntology(model, readinessProfile, prepareModel) {
9317
+ const preparedModel = prepareModel !== void 0 ? prepareModel(model) : model;
9318
+ const compilation = compileOrganizationOntology(preparedModel);
9709
9319
  if (compilation.diagnostics.length > 0) {
9710
9320
  const summary = compilation.diagnostics.map((diagnostic) => diagnostic.message).join("; ");
9711
- throw new Error(`${contractId} ontology validation index failed to compile: ${summary}`);
9321
+ throw new Error(`${readinessProfile} ontology validation index failed to compile: ${summary}`);
9712
9322
  }
9713
- return {
9714
- ontology: compilation.ontology,
9715
- actionTypesByLegacyId: indexActionTypesByLegacyId(compilation.ontology.actionTypes)
9716
- };
9323
+ return { ontology: compilation.ontology };
9717
9324
  }
9718
- function tryCompileBusinessOntology(model, readinessProfile, issues) {
9325
+ function tryCompileReadinessOntology(model, readinessProfile, prepareModel, issues) {
9719
9326
  try {
9720
- return compileBusinessOntology(model, readinessProfile);
9327
+ return compileReadinessOntology(model, readinessProfile, prepareModel);
9721
9328
  } catch (error) {
9722
9329
  addReadinessIssue(
9723
9330
  issues,
@@ -9728,23 +9335,11 @@ function tryCompileBusinessOntology(model, readinessProfile, issues) {
9728
9335
  return void 0;
9729
9336
  }
9730
9337
  }
9731
- function requireContractReadiness(issues, index2, resources, contract, context) {
9732
- const reads = resourceBindingIds(resources, "reads");
9733
- const catalogs = resourceBindingIds(resources, "usesCatalogs");
9734
- for (const objectId of contract.requiredObjects) {
9735
- requireObjectReadiness(issues, index2, objectId, context);
9736
- requireScopedBinding(issues, reads, "reads", objectId, context);
9737
- }
9738
- for (const catalogId of contract.requiredCatalogs) {
9739
- requireCatalogReadiness(issues, index2, catalogId, context);
9740
- requireScopedBinding(issues, catalogs, "usesCatalogs", catalogId, context);
9741
- }
9742
- }
9743
9338
  function computeInterfaceReadiness(model, request) {
9744
9339
  const issues = [];
9745
9340
  const system = getSystem(model, request.systemPath);
9746
9341
  const systemInterface = getSystemInterfaceReadinessMarker(model, request);
9747
- const readinessProfile = systemInterface === void 0 ? void 0 : profileForInterface(request.systemPath, request.interfaceKey, systemInterface.readinessProfile);
9342
+ const readinessProfile = systemInterface?.readinessProfile;
9748
9343
  const scopedResourceIds = systemInterface?.resourceIds ?? [];
9749
9344
  if (system === void 0) {
9750
9345
  addReadinessIssue(
@@ -9784,25 +9379,48 @@ function computeInterfaceReadiness(model, request) {
9784
9379
  "SYSTEM_INTERFACE_DISABLED",
9785
9380
  "inactive-interface",
9786
9381
  `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" lifecycle is "${systemInterface.lifecycle}".`,
9787
- { path: `${readinessMarkerPath(request)}.lifecycle` }
9382
+ { path: readinessMarkerFieldPath(request, ".lifecycle") }
9383
+ );
9384
+ return {
9385
+ ready: false,
9386
+ systemPath: request.systemPath,
9387
+ interfaceKey: request.interfaceKey,
9388
+ readinessProfile,
9389
+ scopedResourceIds,
9390
+ issues
9391
+ };
9392
+ }
9393
+ if (readinessProfile === void 0) {
9394
+ addReadinessIssue(
9395
+ issues,
9396
+ "SYSTEM_INTERFACE_INVALID",
9397
+ "missing-readiness-profile",
9398
+ `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" declares an apiInterface but no readinessProfile. Declare a built-in profile (${formatSupportedReadinessProfiles()}) or a custom id paired with a readinessContract.`,
9399
+ { path: readinessMarkerFieldPath(request, ".readinessProfile") }
9788
9400
  );
9401
+ return {
9402
+ ready: false,
9403
+ systemPath: request.systemPath,
9404
+ interfaceKey: request.interfaceKey,
9405
+ scopedResourceIds,
9406
+ issues
9407
+ };
9789
9408
  }
9790
- const checkedReadinessProfile = readinessProfile ?? profileForInterface(request.systemPath, request.interfaceKey);
9791
- const isBuiltIn = isBuiltInReadinessProfile(checkedReadinessProfile);
9409
+ const isBuiltIn = isBuiltInReadinessProfile(readinessProfile);
9792
9410
  const readinessContract = systemInterface.readinessContract;
9793
9411
  if (!isBuiltIn && readinessContract === void 0) {
9794
9412
  addReadinessIssue(
9795
9413
  issues,
9796
9414
  "SYSTEM_INTERFACE_INVALID",
9797
9415
  "missing-readiness-contract",
9798
- `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" uses custom readiness profile "${checkedReadinessProfile}" but declares no readinessContract. Built-in profiles: ${formatSupportedReadinessProfiles()}.`,
9799
- { path: `${readinessMarkerPath(request)}.readinessContract`, ref: checkedReadinessProfile }
9416
+ `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" uses custom readiness profile "${readinessProfile}" but declares no readinessContract. Built-in profiles: ${formatSupportedReadinessProfiles()}.`,
9417
+ { path: readinessMarkerFieldPath(request, ".readinessContract"), ref: readinessProfile }
9800
9418
  );
9801
9419
  return {
9802
9420
  ready: false,
9803
9421
  systemPath: request.systemPath,
9804
9422
  interfaceKey: request.interfaceKey,
9805
- readinessProfile: checkedReadinessProfile,
9423
+ readinessProfile,
9806
9424
  scopedResourceIds,
9807
9425
  issues
9808
9426
  };
@@ -9813,20 +9431,15 @@ function computeInterfaceReadiness(model, request) {
9813
9431
  "SYSTEM_INTERFACE_NOT_READY",
9814
9432
  "missing-scoped-resources",
9815
9433
  `System Interface "${formatInterfaceIdentity(request.systemPath, request.interfaceKey)}" must scope at least one active resource.`,
9816
- { path: `${readinessMarkerPath(request)}.resourceIds` }
9434
+ { path: readinessMarkerFieldPath(request, ".resourceIds") }
9817
9435
  );
9818
9436
  }
9819
9437
  const resources = getActiveScopedResources(model, scopedResourceIds, issues, request);
9820
- const index2 = tryCompileBusinessOntology(model, checkedReadinessProfile, issues);
9438
+ const registration = getBuiltInReadinessProfile(readinessProfile);
9439
+ const index2 = tryCompileReadinessOntology(model, readinessProfile, registration?.prepareModel, issues);
9821
9440
  if (index2 !== void 0) {
9822
- if (checkedReadinessProfile === LEAD_GEN_API_INTERFACE.readinessProfile) {
9823
- requireLeadGenInterfaceReadiness(issues, index2, resources, request);
9824
- } else if (checkedReadinessProfile === CRM_API_INTERFACE.readinessProfile) {
9825
- requireCrmInterfaceReadiness(issues, index2, resources, request);
9826
- } else if (checkedReadinessProfile === LEAD_GEN_CRM_HANDOFF_INTERFACE.readinessProfile) {
9827
- requireLeadGenInterfaceReadiness(issues, index2, resources, request);
9828
- requireCrmInterfaceReadiness(issues, index2, resources, { ...request, allowForeignOwner: true });
9829
- requireHandoffBridgeReadiness(issues, model, request);
9441
+ if (registration !== void 0) {
9442
+ registration.validate(issues, index2, resources, model, request);
9830
9443
  } else if (readinessContract !== void 0) {
9831
9444
  requireContractReadiness(issues, index2, resources, readinessContract, request);
9832
9445
  }
@@ -9835,30 +9448,235 @@ function computeInterfaceReadiness(model, request) {
9835
9448
  ready: issues.length === 0,
9836
9449
  systemPath: request.systemPath,
9837
9450
  interfaceKey: request.interfaceKey,
9838
- readinessProfile: checkedReadinessProfile,
9451
+ readinessProfile,
9839
9452
  scopedResourceIds,
9840
9453
  issues
9841
9454
  };
9842
9455
  }
9843
- function findLeadGenTemplateStepCatalog(index2) {
9844
- return Object.values(index2.ontology.catalogTypes).find(
9845
- (catalog) => catalog.ownerSystemId === "sales.lead-gen" && catalog.kind === "template-step" && catalog.appliesTo === LEAD_GEN_LIST_OBJECT_ONTOLOGY_ID
9846
- );
9456
+ z.object({
9457
+ success: z.boolean(),
9458
+ tool: z.string(),
9459
+ method: z.string(),
9460
+ result: z.unknown().optional(),
9461
+ error: z.string().optional(),
9462
+ durationMs: z.number().optional()
9463
+ });
9464
+ z.object({
9465
+ credential: z.string().describe("Credential name registered for this integration")
9466
+ });
9467
+
9468
+ // ../core/src/execution/engine/llm/schema/compile.ts
9469
+ function isPlainObject(value) {
9470
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9847
9471
  }
9848
- function indexActionTypesByLegacyId(actionTypes) {
9849
- const byLegacyId = {};
9850
- for (const actionType of Object.values(actionTypes)) {
9851
- const legacyActionId = actionType["legacyActionId"];
9852
- if (typeof legacyActionId === "string") {
9853
- byLegacyId[legacyActionId] = actionType;
9472
+ var UNSUPPORTED_KEYWORDS = /* @__PURE__ */ new Set([
9473
+ "minimum",
9474
+ "maximum",
9475
+ "exclusiveMinimum",
9476
+ "exclusiveMaximum",
9477
+ "multipleOf",
9478
+ "minLength",
9479
+ "maxLength",
9480
+ "pattern",
9481
+ "maxItems",
9482
+ "uniqueItems",
9483
+ "minProperties",
9484
+ "maxProperties",
9485
+ "patternProperties",
9486
+ "propertyNames",
9487
+ "contains",
9488
+ "minContains",
9489
+ "maxContains",
9490
+ "dependentRequired",
9491
+ "dependentSchemas",
9492
+ "if",
9493
+ "then",
9494
+ "else",
9495
+ "not",
9496
+ "$id",
9497
+ "$anchor"
9498
+ ]);
9499
+ var SUPPORTED_FORMATS = /* @__PURE__ */ new Set([
9500
+ "date-time",
9501
+ "time",
9502
+ "date",
9503
+ "duration",
9504
+ "email",
9505
+ "hostname",
9506
+ "uri",
9507
+ "ipv4",
9508
+ "ipv6",
9509
+ "uuid"
9510
+ ]);
9511
+ var MAX_SCHEMA_DEPTH = 32;
9512
+ function convertNode(node, state, depth) {
9513
+ if (depth > MAX_SCHEMA_DEPTH && state.dialect.strict !== "unsupported") {
9514
+ state.blockers.push("depth>32");
9515
+ return node;
9516
+ }
9517
+ if (Array.isArray(node)) {
9518
+ return node.map((item) => convertNode(item, state, depth + 1));
9519
+ }
9520
+ if (!isPlainObject(node)) {
9521
+ return node;
9522
+ }
9523
+ const strictEngaged = state.dialect.strict !== "unsupported";
9524
+ const out = {};
9525
+ for (const [key, value] of Object.entries(node)) {
9526
+ if (key === "$ref" || key === "$defs" || key === "definitions") {
9527
+ if (state.dialect.refs === "refuse") {
9528
+ state.blockers.push(`unsupported:${key}`);
9529
+ out[key] = value;
9530
+ continue;
9531
+ }
9532
+ out[key] = value;
9533
+ continue;
9534
+ }
9535
+ if (key === "$schema") {
9536
+ if (!state.dialect.allowsSchemaKeyword) {
9537
+ continue;
9538
+ }
9539
+ out.$schema = value;
9540
+ continue;
9541
+ }
9542
+ if (key === "properties") {
9543
+ if (!isPlainObject(value)) {
9544
+ out.properties = value;
9545
+ continue;
9546
+ }
9547
+ const properties = {};
9548
+ for (const [propertyName, propertySchema] of Object.entries(value)) {
9549
+ properties[propertyName] = convertNode(propertySchema, state, depth + 1);
9550
+ }
9551
+ out.properties = properties;
9552
+ continue;
9553
+ }
9554
+ if (key === "items") {
9555
+ out.items = convertNode(value, state, depth + 1);
9556
+ continue;
9557
+ }
9558
+ if (strictEngaged) {
9559
+ if (UNSUPPORTED_KEYWORDS.has(key)) {
9560
+ continue;
9561
+ }
9562
+ if (key === "oneOf") {
9563
+ out.anyOf = convertNode(value, state, depth + 1);
9564
+ continue;
9565
+ }
9566
+ if (key === "format") {
9567
+ if (typeof value === "string" && SUPPORTED_FORMATS.has(value)) {
9568
+ out.format = value;
9569
+ }
9570
+ continue;
9571
+ }
9572
+ if (key === "minItems") {
9573
+ const n2 = typeof value === "number" ? value : 0;
9574
+ out.minItems = n2 > 1 ? 1 : n2;
9575
+ continue;
9576
+ }
9577
+ if (key === "type" && Array.isArray(value)) {
9578
+ out.anyOf = value.map((t) => ({ type: t }));
9579
+ continue;
9580
+ }
9581
+ if (key === "additionalProperties") {
9582
+ continue;
9583
+ }
9584
+ }
9585
+ out[key] = convertNode(value, state, depth + 1);
9586
+ }
9587
+ const isObjectNode = out.type === "object" || isPlainObject(out.properties);
9588
+ if (isObjectNode) {
9589
+ const properties = isPlainObject(out.properties) ? out.properties : void 0;
9590
+ const originalAdditionalProperties = node.additionalProperties;
9591
+ if (strictEngaged) {
9592
+ if (properties) {
9593
+ const declared = Object.keys(properties);
9594
+ const required = Array.isArray(out.required) ? out.required : [];
9595
+ const optional = declared.filter((k2) => !required.includes(k2));
9596
+ if (state.dialect.strict === "allRequired" && optional.length > 0) {
9597
+ state.blockers.push(`optionalProperty:${optional[0]}`);
9598
+ }
9599
+ state.optionalProperties += optional.length;
9600
+ }
9601
+ if (originalAdditionalProperties !== void 0 && originalAdditionalProperties !== false && (!properties || Object.keys(properties).length === 0)) {
9602
+ state.blockers.push("freeFormObject");
9603
+ }
9604
+ out.additionalProperties = false;
9605
+ }
9606
+ if (strictEngaged && (!properties || Object.keys(properties).length === 0)) {
9607
+ out.properties = {};
9854
9608
  }
9855
9609
  }
9856
- return byLegacyId;
9610
+ return out;
9857
9611
  }
9858
- function getCatalogEntries(catalog) {
9859
- return isPlainRecord(catalog.entries) ? catalog.entries : {};
9612
+ function dedupe(values) {
9613
+ return [...new Set(values)];
9614
+ }
9615
+ function compileSchema(schema, dialect) {
9616
+ if (!isPlainObject(schema)) {
9617
+ const strictEngaged = dialect.strict !== "unsupported";
9618
+ return {
9619
+ schema,
9620
+ sendStrict: false,
9621
+ status: strictEngaged ? "refused" : "notAttempted",
9622
+ refusalReasons: strictEngaged ? ["notAnObject"] : []
9623
+ };
9624
+ }
9625
+ const state = { dialect, blockers: [], optionalProperties: 0 };
9626
+ const compiled = convertNode(schema, state, 0);
9627
+ if (state.blockers.length === 0 && dialect.maxOptionalProperties !== void 0 && state.optionalProperties > dialect.maxOptionalProperties) {
9628
+ state.blockers.push(`optionalPropertyLimit:${state.optionalProperties}>${dialect.maxOptionalProperties}`);
9629
+ }
9630
+ if (dialect.strict === "unsupported") {
9631
+ return {
9632
+ schema: compiled,
9633
+ sendStrict: false,
9634
+ status: "notAttempted",
9635
+ refusalReasons: []
9636
+ };
9637
+ }
9638
+ if (state.blockers.length > 0) {
9639
+ return {
9640
+ schema,
9641
+ sendStrict: false,
9642
+ status: "refused",
9643
+ refusalReasons: dedupe(state.blockers)
9644
+ };
9645
+ }
9646
+ return { schema: compiled, sendStrict: true, status: "applied", refusalReasons: [] };
9860
9647
  }
9861
9648
 
9649
+ // ../core/src/execution/engine/llm/schema/dialect.ts
9650
+ var ANTHROPIC_DIALECT = {
9651
+ strict: "optionalAllowed",
9652
+ // No placeholder of its own: an empty or absent `properties` becomes a bare `properties: {}`,
9653
+ // synthesized directly by the walk for any dialect engaging strict.
9654
+ // Refuses rather than inlining: detecting recursion through `$defs` is more machinery than the
9655
+ // payoff justifies for a tool-input schema.
9656
+ refs: "refuse",
9657
+ allowsSchemaKeyword: false,
9658
+ // Anthropic's published ceiling. Measured live before this was added: the Command Center
9659
+ // assistant's iteration schema declares 33, so 8 of 8 iterations across a 3-turn session were
9660
+ // 400'd and retried unstrict. `optionalAllowed` is still correct -- an optional property is
9661
+ // representable in this grammar, there is just a cap on how many.
9662
+ maxOptionalProperties: 24
9663
+ };
9664
+ var OPENAI_DIALECT = {
9665
+ strict: "allRequired",
9666
+ refs: "passthrough",
9667
+ allowsSchemaKeyword: false
9668
+ };
9669
+ var OPENROUTER_DIALECT = {
9670
+ strict: "allRequired",
9671
+ refs: "refuse",
9672
+ allowsSchemaKeyword: false
9673
+ };
9674
+ var PROVIDER_DIALECTS = {
9675
+ anthropic: ANTHROPIC_DIALECT,
9676
+ openai: OPENAI_DIALECT,
9677
+ openrouter: OPENROUTER_DIALECT
9678
+ };
9679
+
9862
9680
  // ../core/src/platform/registry/validation.ts
9863
9681
  var RegistryValidationError = class extends Error {
9864
9682
  constructor(orgName, resourceId, field, message) {
@@ -10226,7 +10044,6 @@ function validateDeclaredSystemInterfaceReadiness(orgName, organizationModel) {
10226
10044
  message: `System Interface "${path}/${interfaceKey}" references unknown readiness profile "${readinessProfile}".`
10227
10045
  });
10228
10046
  }
10229
- continue;
10230
10047
  }
10231
10048
  const result = computeInterfaceReadiness(model, { systemPath: path, interfaceKey });
10232
10049
  for (const issue of result.issues) {