@wildo-ai/saas-backend-lib 1.1.12 → 1.1.13

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 (226) hide show
  1. package/dist/esm/base-classes/models/manual-controllers.backend.definition.d.ts.map +1 -1
  2. package/dist/esm/base-classes/models/manual-controllers.backend.definition.js +2 -0
  3. package/dist/esm/base-classes/models/manual-controllers.backend.definition.js.map +1 -1
  4. package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.d.ts +4 -0
  5. package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.d.ts.map +1 -1
  6. package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.js +20 -5
  7. package/dist/esm/base-classes/services/repositories/stored-field-omission.backend.js.map +1 -1
  8. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts +3 -0
  9. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.d.ts.map +1 -1
  10. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js +10 -1
  11. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation-registry.backend.service.js.map +1 -1
  12. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts +22 -0
  13. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.d.ts.map +1 -1
  14. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js +25 -1
  15. package/dist/esm/base-classes/services/services/resource-operation-custom-implementation.factory.backend.js.map +1 -1
  16. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts +38 -3
  17. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.d.ts.map +1 -1
  18. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.js +68 -5
  19. package/dist/esm/base-classes/services/services/resource-operation-transaction-persistence.backend.utils.js.map +1 -1
  20. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts +2 -2
  21. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.d.ts.map +1 -1
  22. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js +6 -3
  23. package/dist/esm/base-classes/services/services/resource-status-transition.custom-impl.backend.service.js.map +1 -1
  24. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts +83 -0
  25. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.d.ts.map +1 -1
  26. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js +217 -14
  27. package/dist/esm/base-classes/services/services/services-registry-handler.backend.service.js.map +1 -1
  28. package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.d.ts +32 -0
  29. package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.d.ts.map +1 -0
  30. package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.js +36 -0
  31. package/dist/esm/compliance/approval-seals/approval-seal-currency.backend.js.map +1 -0
  32. package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.d.ts +38 -0
  33. package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.d.ts.map +1 -0
  34. package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.js +83 -0
  35. package/dist/esm/compliance/approval-seals/approval-seal-on-record.backend.js.map +1 -0
  36. package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.d.ts +36 -0
  37. package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.d.ts.map +1 -0
  38. package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.js +51 -0
  39. package/dist/esm/compliance/approval-seals/approval-seal-presentation-read.backend.js.map +1 -0
  40. package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.d.ts +46 -0
  41. package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.d.ts.map +1 -1
  42. package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.js +68 -0
  43. package/dist/esm/compliance/approval-seals/approval-seal-relay-store.backend.js.map +1 -1
  44. package/dist/esm/compliance/approval-seals/approval-seal-store.backend.d.ts +27 -0
  45. package/dist/esm/compliance/approval-seals/approval-seal-store.backend.d.ts.map +1 -1
  46. package/dist/esm/compliance/approval-seals/approval-seal-store.backend.js +42 -3
  47. package/dist/esm/compliance/approval-seals/approval-seal-store.backend.js.map +1 -1
  48. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.d.ts +26 -1
  49. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.d.ts.map +1 -1
  50. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.js +10 -0
  51. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.contracts.js.map +1 -1
  52. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.d.ts +10 -1
  53. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.d.ts.map +1 -1
  54. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.js +60 -28
  55. package/dist/esm/compliance/approval-seals/approval-seals-admin.backend.controller.js.map +1 -1
  56. package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.d.ts +90 -0
  57. package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.d.ts.map +1 -0
  58. package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.js +373 -0
  59. package/dist/esm/compliance/approval-seals/approval-seals-on-record.backend.controller.js.map +1 -0
  60. package/dist/esm/compliance/approval-seals/decision-presentation.backend.d.ts +29 -2
  61. package/dist/esm/compliance/approval-seals/decision-presentation.backend.d.ts.map +1 -1
  62. package/dist/esm/compliance/approval-seals/decision-presentation.backend.js +40 -3
  63. package/dist/esm/compliance/approval-seals/decision-presentation.backend.js.map +1 -1
  64. package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.d.ts.map +1 -1
  65. package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.js +34 -6
  66. package/dist/esm/compliance/electronic-signatures/pdf-signature-structure.backend.js.map +1 -1
  67. package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.d.ts +30 -6
  68. package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.d.ts.map +1 -1
  69. package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js +67 -22
  70. package/dist/esm/compliance/electronic-signatures/signature-request-evidence-files.backend.js.map +1 -1
  71. package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.d.ts.map +1 -1
  72. package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js +18 -1
  73. package/dist/esm/compliance/electronic-signatures/signature-request-poll.batch.backend.service.js.map +1 -1
  74. package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts +66 -1
  75. package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.d.ts.map +1 -1
  76. package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.js +161 -14
  77. package/dist/esm/compliance/electronic-signatures/signature-requests.backend.service.js.map +1 -1
  78. package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.d.ts +47 -0
  79. package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.d.ts.map +1 -1
  80. package/dist/esm/compliance/electronic-signatures/signed-document-validation.backend.js.map +1 -1
  81. package/dist/esm/external-providers/services/content-safety.backend.service.d.ts +27 -2
  82. package/dist/esm/external-providers/services/content-safety.backend.service.d.ts.map +1 -1
  83. package/dist/esm/external-providers/services/content-safety.backend.service.js +46 -1
  84. package/dist/esm/external-providers/services/content-safety.backend.service.js.map +1 -1
  85. package/dist/esm/external-providers/services/embeddings.backend.service.d.ts.map +1 -1
  86. package/dist/esm/external-providers/services/embeddings.backend.service.js +2 -0
  87. package/dist/esm/external-providers/services/embeddings.backend.service.js.map +1 -1
  88. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts +11 -0
  89. package/dist/esm/external-providers/services/external-providers-registry.backend.service.d.ts.map +1 -1
  90. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js +23 -0
  91. package/dist/esm/external-providers/services/external-providers-registry.backend.service.js.map +1 -1
  92. package/dist/esm/external-providers/services/provider-service-account-token.backend.d.ts +19 -1
  93. package/dist/esm/external-providers/services/provider-service-account-token.backend.d.ts.map +1 -1
  94. package/dist/esm/external-providers/services/provider-service-account-token.backend.js +41 -1
  95. package/dist/esm/external-providers/services/provider-service-account-token.backend.js.map +1 -1
  96. package/dist/esm/files/utils/file-parent-read-context.backend.d.ts +27 -2
  97. package/dist/esm/files/utils/file-parent-read-context.backend.d.ts.map +1 -1
  98. package/dist/esm/files/utils/file-parent-read-context.backend.js +23 -4
  99. package/dist/esm/files/utils/file-parent-read-context.backend.js.map +1 -1
  100. package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.d.ts +26 -0
  101. package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.d.ts.map +1 -1
  102. package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.js +100 -8
  103. package/dist/esm/flows-actors/content-guardrails/classifier-availability.backend.utils.js.map +1 -1
  104. package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.d.ts +3 -1
  105. package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.d.ts.map +1 -1
  106. package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.js +8 -2
  107. package/dist/esm/flows-actors/content-guardrails/record-owner-policy.backend.js.map +1 -1
  108. package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts +43 -0
  109. package/dist/esm/flows-actors/models/function-tools.backend.definitions.d.ts.map +1 -1
  110. package/dist/esm/flows-actors/models/function-tools.backend.definitions.js +37 -0
  111. package/dist/esm/flows-actors/models/function-tools.backend.definitions.js.map +1 -1
  112. package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.d.ts +7 -0
  113. package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.d.ts.map +1 -1
  114. package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.js +8 -3
  115. package/dist/esm/flows-actors/services/agent-work-decisions.backend.service.js.map +1 -1
  116. package/dist/esm/flows-actors/services/agents.backend.service.d.ts +31 -6
  117. package/dist/esm/flows-actors/services/agents.backend.service.d.ts.map +1 -1
  118. package/dist/esm/flows-actors/services/agents.backend.service.js +78 -30
  119. package/dist/esm/flows-actors/services/agents.backend.service.js.map +1 -1
  120. package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.d.ts.map +1 -1
  121. package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.js +4 -0
  122. package/dist/esm/flows-actors/services/autonomous-agent-turn.backend.service.js.map +1 -1
  123. package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts +28 -2
  124. package/dist/esm/flows-actors/services/conversational-execution.backend.service.d.ts.map +1 -1
  125. package/dist/esm/flows-actors/services/conversational-execution.backend.service.js +132 -22
  126. package/dist/esm/flows-actors/services/conversational-execution.backend.service.js.map +1 -1
  127. package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.d.ts.map +1 -1
  128. package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.js +12 -8
  129. package/dist/esm/flows-actors/services/flow-actor-executions.custom-impl.backend.service.js.map +1 -1
  130. package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts +5 -0
  131. package/dist/esm/flows-actors/services/flows-actors-registry.service.d.ts.map +1 -1
  132. package/dist/esm/flows-actors/services/flows-actors-registry.service.js +18 -2
  133. package/dist/esm/flows-actors/services/flows-actors-registry.service.js.map +1 -1
  134. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts +33 -0
  135. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.d.ts.map +1 -1
  136. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js +58 -0
  137. package/dist/esm/flows-actors/utils/acp-session-runner.backend.utils.js.map +1 -1
  138. package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.d.ts +12 -1
  139. package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.d.ts.map +1 -1
  140. package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.js +23 -4
  141. package/dist/esm/inbound/services/inbound-delivery-dispatch.backend.service.js.map +1 -1
  142. package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.d.ts +12 -1
  143. package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.d.ts.map +1 -1
  144. package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.js +55 -17
  145. package/dist/esm/inbound/services/inbound-delivery-receiver.backend.service.js.map +1 -1
  146. package/dist/esm/inbound/services/inbound-delivery-store.backend.service.d.ts +22 -1
  147. package/dist/esm/inbound/services/inbound-delivery-store.backend.service.d.ts.map +1 -1
  148. package/dist/esm/inbound/services/inbound-delivery-store.backend.service.js +52 -9
  149. package/dist/esm/inbound/services/inbound-delivery-store.backend.service.js.map +1 -1
  150. package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.d.ts +79 -0
  151. package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.d.ts.map +1 -0
  152. package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.js +211 -0
  153. package/dist/esm/inbound/services/inbound-delivery-stored-body.backend.service.js.map +1 -0
  154. package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.d.ts +2 -2
  155. package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.d.ts.map +1 -1
  156. package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.js +9 -1
  157. package/dist/esm/inbound/services/inbound-delivery-subject-erasure-severance.backend.js.map +1 -1
  158. package/dist/esm/index.d.ts +1 -0
  159. package/dist/esm/index.d.ts.map +1 -1
  160. package/dist/esm/index.js +1 -0
  161. package/dist/esm/index.js.map +1 -1
  162. package/dist/esm/inject/models/container.d.ts.map +1 -1
  163. package/dist/esm/inject/models/container.js +6 -0
  164. package/dist/esm/inject/models/container.js.map +1 -1
  165. package/dist/esm/inject/models/service-types.d.ts +5 -0
  166. package/dist/esm/inject/models/service-types.d.ts.map +1 -1
  167. package/dist/esm/inject/models/service-types.js +3 -0
  168. package/dist/esm/inject/models/service-types.js.map +1 -1
  169. package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts +5 -0
  170. package/dist/esm/monitoring/observability/models/observability.backend.schemas.d.ts.map +1 -1
  171. package/dist/esm/monitoring/observability/models/observability.backend.schemas.js.map +1 -1
  172. package/dist/esm/monitoring/observability/services/metrics.service.d.ts +34 -1
  173. package/dist/esm/monitoring/observability/services/metrics.service.d.ts.map +1 -1
  174. package/dist/esm/monitoring/observability/services/metrics.service.js +49 -0
  175. package/dist/esm/monitoring/observability/services/metrics.service.js.map +1 -1
  176. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts +6 -1
  177. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.d.ts.map +1 -1
  178. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js +15 -4
  179. package/dist/esm/notifications/webhooks/controllers/webhook-auto-controller.backend.service.js.map +1 -1
  180. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.d.ts.map +1 -1
  181. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.js +3 -1
  182. package/dist/esm/notifications/webhooks/outbound/services/m2m-webhook-delivery-log.custom-impl.backend.service.js.map +1 -1
  183. package/dist/esm/runtime/services/http-server.backend.service.d.ts +3 -1
  184. package/dist/esm/runtime/services/http-server.backend.service.d.ts.map +1 -1
  185. package/dist/esm/runtime/services/http-server.backend.service.js +11 -3
  186. package/dist/esm/runtime/services/http-server.backend.service.js.map +1 -1
  187. package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.d.ts +22 -0
  188. package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.d.ts.map +1 -1
  189. package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.js +54 -0
  190. package/dist/esm/runtime/services/utils/inbound-endpoint-raw-body.backend.utils.js.map +1 -1
  191. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts +51 -0
  192. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.d.ts.map +1 -1
  193. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js +87 -15
  194. package/dist/esm/security/authentications/services/auth-methods/auth-password-reset.backend.service.js.map +1 -1
  195. package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.d.ts.map +1 -1
  196. package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js +5 -2
  197. package/dist/esm/security/authentications/services/custom-impls/siem-delivery-dlq.custom-impl.backend.service.js.map +1 -1
  198. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.d.ts.map +1 -1
  199. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js +65 -24
  200. package/dist/esm/security/authentications/services/custom-impls/sso-config-domain-verification.custom-impl.backend.service.js.map +1 -1
  201. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts +64 -1
  202. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.d.ts.map +1 -1
  203. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js +84 -2
  204. package/dist/esm/security/authorizations/super-admin-floor.backend.utils.js.map +1 -1
  205. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts +14 -0
  206. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.d.ts.map +1 -1
  207. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js +13 -5
  208. package/dist/esm/security/oauth-clients/oauth-clients.custom-impl.backend.service.js.map +1 -1
  209. package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.d.ts.map +1 -1
  210. package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.js +6 -2
  211. package/dist/esm/users/services/anonymous-consent.custom-impl.backend.service.js.map +1 -1
  212. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts +7 -0
  213. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.d.ts.map +1 -1
  214. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.js +65 -20
  215. package/dist/esm/users/services/user-force-password-reset.custom-impl.backend.service.js.map +1 -1
  216. package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.d.ts.map +1 -1
  217. package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.js +11 -4
  218. package/dist/esm/users/services/user-role-administration.custom-impl.backend.service.js.map +1 -1
  219. package/dist/esm/users/services/user-self-custom-implementations.backend.d.ts.map +1 -1
  220. package/dist/esm/users/services/user-self-custom-implementations.backend.js +4 -2
  221. package/dist/esm/users/services/user-self-custom-implementations.backend.js.map +1 -1
  222. package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.d.ts.map +1 -1
  223. package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.js +16 -0
  224. package/dist/esm/users/services/user-super-admin-floor.custom-impl.backend.service.js.map +1 -1
  225. package/dist/tsconfig.build.tsbuildinfo +1 -1
  226. package/package.json +10 -10
@@ -348,6 +348,10 @@ export async function startACPAgentSession(options) {
348
348
  // Reset at the start of each turn.
349
349
  turnFinalMessage: '',
350
350
  turnLastUsageUpdate: undefined,
351
+ // The question the agent asked during this turn through `elicitation/create` (#3710); the first one wins.
352
+ turnExplicitQuestion: undefined,
353
+ // Cancels the turn in flight; set while a `promptTurn` runs, so a request handler can end the turn.
354
+ cancelActiveTurn: undefined,
351
355
  // NOT reset per turn: ACP's cost is the session's cumulative total, and an update that omits it
352
356
  // (rate-limit, compaction) does not mean the session cost nothing (see `readUsageUpdateCost`).
353
357
  sessionLastReportedCost: undefined,
@@ -596,6 +600,22 @@ export async function startACPAgentSession(options) {
596
600
  }
597
601
  return;
598
602
  }
603
+ case 'elicitation/create': {
604
+ /*
605
+ * The agent ASKS (#3710). Only a form, only in a turn, only when the caller can park: anything else is
606
+ * declined, which the agent reads as the person choosing not to answer, never as an answer.
607
+ */
608
+ const cancelTurn = session.cancelActiveTurn;
609
+ if (options.acceptsExplicitQuestions !== true || params.mode !== 'form' || cancelTurn === undefined) {
610
+ respond(id, { action: 'decline' });
611
+ return;
612
+ }
613
+ session.turnExplicitQuestion ??= renderElicitationQuestion(params);
614
+ // `cancel`, not `decline`: nobody saw the form. The turn is then cancelled, and the answer arrives as the next prompt.
615
+ respond(id, { action: 'cancel' });
616
+ cancelTurn();
617
+ return;
618
+ }
599
619
  default:
600
620
  // Deliberately including every `terminal/*` method: this runner does NOT
601
621
  // advertise the terminal capability, so an agent calling one has ignored
@@ -744,6 +764,8 @@ export async function startACPAgentSession(options) {
744
764
  // when the capability IS offered — so advertising it would add an
745
765
  // unexercised execution surface for no observed gain.
746
766
  terminal: false,
767
+ // Form elicitation is how an agent ASKS (#3710); offered only to a caller that can park a question.
768
+ ...(options.acceptsExplicitQuestions === true ? { elicitation: { form: {} } } : {}),
747
769
  },
748
770
  }),
749
771
  exitPromise,
@@ -868,6 +890,7 @@ export async function startACPAgentSession(options) {
868
890
  const fileLocStart = session.reportedFileLocations.length;
869
891
  session.turnFinalMessage = '';
870
892
  session.turnLastUsageUpdate = undefined;
893
+ session.turnExplicitQuestion = undefined;
871
894
  let settled = false;
872
895
  let timedOut = false;
873
896
  let timer;
@@ -879,6 +902,7 @@ export async function startACPAgentSession(options) {
879
902
  }, COOPERATIVE_CANCEL_GRACE_MS).unref?.();
880
903
  };
881
904
  const onAbort = () => cancelTurn();
905
+ session.cancelActiveTurn = cancelTurn;
882
906
  const turnPromise = request('session/prompt', {
883
907
  sessionId,
884
908
  prompt: [{ type: 'text', text: prompt }],
@@ -916,10 +940,12 @@ export async function startACPAgentSession(options) {
916
940
  eventsTruncated: session.eventsTruncated,
917
941
  deniedPermissionCount: session.deniedPermissionCount - deniedStart,
918
942
  permissionDecisions: session.permissionDecisions.slice(permissionStart),
943
+ ...(session.turnExplicitQuestion !== undefined ? { explicitQuestion: session.turnExplicitQuestion } : {}),
919
944
  };
920
945
  }
921
946
  finally {
922
947
  settled = true;
948
+ session.cancelActiveTurn = undefined;
923
949
  if (timer)
924
950
  clearTimeout(timer);
925
951
  turnOptions?.abortSignal?.removeEventListener('abort', onAbort);
@@ -978,6 +1004,38 @@ export async function runACPCodingSession(options) {
978
1004
  agentSession.close();
979
1005
  }
980
1006
  }
1007
+ /**
1008
+ * The text of a form elicitation (#3710): its `message`, then one line per field the form asks, with the choices it
1009
+ * offers. What a person reads in place of the form, and what an answer is written against.
1010
+ *
1011
+ * Generic over ACP's `ElicitationSchema` (primitive properties; a single choice as `enum` or titled `oneOf`, a multiple
1012
+ * choice as an array whose `items` carry `enum` or titled `anyOf`), never over one agent's form.
1013
+ *
1014
+ * spec-cite: ACP schema (`@agentclientprotocol/sdk` 1.5.0) — `CreateElicitationRequest` (`message`, `mode: "form"`,
1015
+ * `requestedSchema: ElicitationSchema`) and `CreateElicitationResponse` (`accept` / `decline` / `cancel`).
1016
+ */
1017
+ export function renderElicitationQuestion(params) {
1018
+ const message = typeof params.message === 'string' && params.message.trim().length > 0 ? params.message.trim() : 'The agent asked a question.';
1019
+ const schema = isRecord(params.requestedSchema) ? params.requestedSchema : {};
1020
+ const properties = isRecord(schema.properties) ? schema.properties : {};
1021
+ const choicesOf = (property) => {
1022
+ const source = isRecord(property.items) ? property.items : property;
1023
+ const titled = Array.isArray(source.oneOf) ? source.oneOf : Array.isArray(source.anyOf) ? source.anyOf : [];
1024
+ const fromTitled = titled
1025
+ .filter(isRecord)
1026
+ .map((option) => (typeof option.title === 'string' ? option.title : typeof option.const === 'string' ? option.const : undefined))
1027
+ .filter((value) => value !== undefined);
1028
+ const fromEnum = Array.isArray(source.enum) ? source.enum.filter((value) => typeof value === 'string') : [];
1029
+ return fromTitled.length > 0 ? fromTitled : fromEnum;
1030
+ };
1031
+ const lines = Object.values(properties).filter(isRecord).map((property) => {
1032
+ const label = [property.title, property.description].filter((part) => typeof part === 'string' && part.trim().length > 0).join(': ');
1033
+ const choices = choicesOf(property);
1034
+ const many = property.type === 'array';
1035
+ return `- ${label || 'answer'}${choices.length > 0 ? ` (${many ? 'any of' : 'one of'}: ${choices.join(' | ')})` : ''}`;
1036
+ });
1037
+ return lines.length > 0 ? `${message}\n${lines.join('\n')}` : message;
1038
+ }
981
1039
  /** Re-exported so callers reason about ceilings through one ordering definition. */
982
1040
  export { agentClientProtocolPermissionCeilingRank };
983
1041
  //# sourceMappingURL=acp-session-runner.backend.utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"acp-session-runner.backend.utils.js","sourceRoot":"","sources":["../../../../src/flows-actors/utils/acp-session-runner.backend.utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent Client Protocol session runner.\n *\n * Two shapes over one transport:\n *\n * - {@link startACPAgentSession} opens a LIVE session — spawn the agent,\n * negotiate `initialize`, open (or `session/load`-resume) a session against a\n * confined working directory — and returns a handle whose `promptTurn` drives\n * ONE turn at a time. The caller decides whether to send another prompt on\n * the same session, which is what makes the interactive/continuation lane\n * possible: a turn that ended with a question is answered by the next\n * `promptTurn`, on the same `sessionId`, with the agent's context intact.\n * - {@link runACPCodingSession} is the single-turn wrapper kept for every\n * existing caller: start, one turn, close.\n *\n * # Why the transport is written here rather than taken from a package\n *\n * ACP is JSON-RPC 2.0 over newline-delimited stdio, and an official TypeScript\n * SDK exists. This runner speaks the wire directly instead, for two reasons.\n * The mechanical one: adopting the SDK adds a third-party runtime dependency to\n * an engine package, which is a toolchain-baseline decision with a version pin,\n * and it must not be taken incidentally inside a feature slice. The substantive\n * one: everything below is the part Wildo must OWN anyway — which protocol\n * versions are acceptable, who answers a permission request, what a working\n * directory may be, how long a turn may run. An SDK would have supplied the\n * framing, which is the cheap half.\n *\n * Revisit if ACP 2 lands: version negotiation is one place, and adopting the\n * SDK then is a contained change.\n *\n * # The permission ceiling is enforced HERE, not by the agent's session mode\n *\n * Agents advertise their own session modes (`default`, `acceptEdits`,\n * `bypassPermissions`, …) and those identifiers are agent-specific strings. The\n * runner will select a matching mode when one is advertised, because it saves\n * round-trips — but it NEVER relies on that for the guarantee. The ceiling is\n * enforced by this runner's answer to every `session/request_permission` and by\n * the edit check on client-hosted filesystem writes. For agent-owned I/O, an\n * agent that advertises no modes at all, or renames the ones it has, is still\n * held to the authored ceiling when it raises permission requests. Mode selection is an optimisation; the handler\n * is the mechanism.\n */\n\nimport { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';\nimport { realpathSync, lstatSync } from 'node:fs';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { basename, dirname, isAbsolute, relative, resolve, sep } from 'node:path';\n\nimport {\n AgentClientProtocol_PermissionCeiling,\n CodingAgent_StopReason,\n agentClientProtocolPermissionCeilingRank,\n isWritingAcpToolKind,\n writtenLocationsOfAcpSessionUpdate,\n type CodingAgent_Usage,\n} from '@wildo-ai/external-connectors-models';\n\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\n/** Milliseconds allowed for the agent to honour `session/cancel` before it is killed. */\nconst COOPERATIVE_CANCEL_GRACE_MS = 10_000;\n/** Extra grace after SIGKILL so an unreapable child cannot hang a caller. */\nconst TERMINATION_SETTLE_GRACE_MS = 1_000;\n/** Default ceiling on persisted session-event bytes. Truncates; never fails the run. */\nconst DEFAULT_MAX_RECORDED_EVENT_BYTES = 4 * 1024 * 1024;\n\nexport class ACPSessionRunnerError extends Error {\n constructor(\n message: string,\n public readonly details: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'ACPSessionRunnerError';\n }\n}\n\n/** One `session/update` notification, recorded for the caller's traceability sink. */\nexport interface ACPSessionEvent {\n readonly kind: string;\n readonly payload: unknown;\n}\n\nexport interface ACPPermissionRequest {\n readonly toolCallTitle: string | undefined;\n readonly toolKind: string | undefined;\n /** Absolute paths the tool call declares it will touch, when it declares any. */\n readonly locations: readonly string[];\n readonly optionKinds: readonly string[];\n}\n\n/** Why a permission request was decided or a client filesystem callback was refused. */\nexport enum ACPPermissionDecisionReason {\n /** The declared ceiling does not admit this tool kind. */\n CEILING_REFUSED = 'ceiling_refused',\n /** A location the host's mutation or read scope does not authorise. */\n LOCATION_OUT_OF_SCOPE = 'location_out_of_scope',\n /** Admitted, and an `allow_once` option existed to say so with. */\n ALLOWED_ONCE = 'allowed_once',\n /**\n * Admitted by the ceiling and the scope, then refused anyway because the agent offered no\n * option this client is willing to select. `allow_always` is deliberately never chosen below\n * an UNRESTRICTED ceiling — it carries a session-wide permission change — so a request that\n * offers only that option has no answer other than refusal.\n */\n NO_SELECTABLE_OPTION = 'no_selectable_option',\n /**\n * The call is to a tool the HOST itself serves to the session (`mcpServers`), named by the host's\n * {@link ACPStartSessionOptions.admitsHostToolCall} predicate (#3472). Answered before the ceiling, because the\n * ceiling governs the agent's reach into the workspace and the host's own tool reaches nothing but the host.\n */\n HOST_TOOL_ADMITTED = 'host_tool_admitted',\n}\n\n/**\n * An MCP server the HOST serves to the session, passed in `session/new` (#3472).\n *\n * HTTP only: the host serves it in-process, so its tools run in the host and can validate against the host's own\n * schemas. The agent must advertise `mcpCapabilities.http`; the runner refuses the session otherwise rather than\n * open one whose only way to answer is missing.\n * spec-cite: Agent Client Protocol — Session Setup, MCP servers (https://agentclientprotocol.com/protocol/session-setup):\n * stdio is mandatory for agents, HTTP is optional and advertised as `mcpCapabilities.http` at `initialize`.\n */\nexport interface ACPHttpMcpServerDeclaration {\n readonly type: 'http';\n readonly name: string;\n readonly url: string;\n readonly headers: readonly { readonly name: string; readonly value: string }[];\n}\n\nexport interface ACPPermissionDecisionRecord {\n readonly allowed: boolean;\n readonly reason: ACPPermissionDecisionReason;\n /** The declared ACP tool kind, or `read`/`edit` for a direct filesystem callback. */\n readonly toolKind?: string;\n /** Paths the request declared. Empty when the agent declared none — which is why an\n * `execute` request cannot be scope-checked at all. */\n readonly locations: readonly string[];\n /** The option KINDS the agent offered, so a refusal for lack of a selectable one is visible. */\n readonly offeredOptionKinds: readonly string[];\n}\n\n/** Bounds the recorded decisions; a runaway agent must not grow this without limit. */\nconst PERMISSION_DECISION_RECORD_LIMIT = 200;\n\n/**\n * Options common to opening a session and running a one-shot turn.\n *\n * The single-turn {@link ACPCodingSessionOptions} extends this with `prompt`,\n * `turnTimeoutMs` and `abortSignal` — the per-turn concerns the live handle\n * takes as arguments to `promptTurn` instead.\n */\nexport interface ACPStartSessionOptions {\n command: string;\n args?: readonly string[];\n /** Already resolved and confined by `resolveTrustedWorkingDirectory`. */\n cwd: string;\n env: NodeJS.ProcessEnv;\n /** Protocol majors the caller will accept in the `initialize` response. */\n supportedProtocolVersions: readonly number[];\n permissionCeiling: AgentClientProtocol_PermissionCeiling;\n /**\n * Additional, caller-owned refusal on top of the ceiling — used to hold an\n * agent to a task's declared mutation scope. Returning false DENIES, whatever\n * the ceiling says. It can only narrow.\n */\n isPermittedLocation?: (absolutePath: string) => boolean;\n /**\n * Optional host restriction for client-hosted file reads and declared non-mutating tool locations.\n * Client callbacks also remain confined to cwd.\n * Research confines reads to its evidence store; coding runs normally read surrounding\n * application source even when their mutation scope is narrower. Keep those authorities separate.\n */\n isPermittedReadLocation?: (absolutePath: string) => boolean;\n /**\n * The agent's OWN session-mode ids to prefer, most-preferred first.\n *\n * Supplied by the caller from the provider contract rather than derived here:\n * mode ids are agent vocabulary, and a map hardcoded in this neutral runner\n * matched `default` for every ceiling — correct for one adapter and silently\n * empty for an agent whose modes are, say, `build`/`plan`. An unmatched or\n * unsettable mode costs round-trips, never safety: the ceiling is enforced by\n * this runner's answer to every permission request.\n */\n preferredSessionModeIds?: readonly string[];\n /**\n * Set the model over ACP as a session config option, before the first prompt.\n *\n * Only for agents whose provider declares the `session-config-option`\n * delivery channel; agents that read the model from their environment have it\n * in `env` already. A rejected call FAILS the session rather than proceeding:\n * an unset model means the agent silently runs its own default while the run\n * records the model that was requested.\n */\n modelSelection?: { configId: string; model: string };\n /** Opaque `_meta` for `session/new`; agent-specific by construction. */\n sessionMetaExtensions?: Record<string, unknown>;\n /** MCP servers the host serves to the session (#3472). Absent: none, as before. */\n mcpServers?: readonly ACPHttpMcpServerDeclaration[];\n /**\n * Admit a permission request for a tool the host serves itself (#3472), BEFORE the ceiling is consulted.\n *\n * Narrow by construction: the host names its own tool, and only an `allow_once` answer is ever given. Every other\n * request is decided exactly as before, so a language-model session opened under `PROMPT_ALWAYS` can call the\n * host's submit tool and nothing else.\n */\n admitsHostToolCall?: (request: { readonly toolCallTitle: string | undefined; readonly toolKind: string | undefined }) => boolean;\n maxRecordedEventBytes?: number;\n /** Live progress sink. Never allowed to fail the run. */\n onEvent?: (event: ACPSessionEvent) => void;\n /**\n * Resume a prior session by id instead of opening a new one.\n *\n * When set, the runner calls `session/load` rather than `session/new`, so the\n * agent restores the earlier conversation's context. REQUIRES the agent to\n * advertise the `loadSession` capability at `initialize`; a resume asked of an\n * agent that does not is REFUSED, not silently degraded to a fresh session —\n * presenting a context-less turn as a continuation is the failure this guards.\n * The replayed history is consumed and discarded: it is already on the durable\n * record from the run that parked, and re-recording it would double it.\n */\n resumeSessionId?: string;\n}\n\nexport interface ACPCodingSessionOptions extends ACPStartSessionOptions {\n prompt: string;\n turnTimeoutMs?: number;\n /**\n * Operator-initiated cancellation.\n *\n * Handled exactly like the timeout, and deliberately so: `session/cancel`\n * first, kill only if the agent does not honour it. An operator who stops a\n * run wants it to STOP, but a coding agent killed mid-edit leaves a worktree\n * nobody can characterise — whereas one that settles as `cancelled` leaves a\n * partial change set the caller knows is partial.\n */\n abortSignal?: AbortSignal;\n}\n\n/** Per-turn arguments to {@link ACPAgentSession.promptTurn}. */\nexport interface ACPPromptTurnOptions {\n turnTimeoutMs?: number;\n /** See {@link ACPCodingSessionOptions.abortSignal}. Scoped to this one turn. */\n abortSignal?: AbortSignal;\n}\n\n/** The outcome of one prompt turn on a live session. */\nexport interface ACPTurnResult {\n readonly finalMessage: string;\n readonly stopReason: CodingAgent_StopReason;\n /** The agent's verbatim value when `stopReason` is `UNRECOGNISED`. */\n readonly rawStopReason?: string;\n readonly usage?: CodingAgent_Usage;\n /**\n * File paths the agent reported WRITING during this turn: the locations of its `edit`, `delete` and\n * `move` tool calls, never of a read or a search (#1805). A concurrent run's accept reads these as its\n * claims, and a file the run only read is not its to be committed under.\n */\n readonly reportedFileLocations: readonly string[];\n /** `session/update` notifications recorded DURING THIS TURN. */\n readonly events: readonly ACPSessionEvent[];\n /** True when the session's cumulative event log hit its byte ceiling. */\n readonly eventsTruncated: boolean;\n /** Refused permission requests plus callback ceiling or scope refusals during this turn. */\n readonly deniedPermissionCount: number;\n /** Permission decisions and callback policy refusals recorded during this turn. */\n readonly permissionDecisions: readonly ACPPermissionDecisionRecord[];\n}\n\n/** What the agent declared about itself and the session at `initialize`/setup time. */\nexport interface ACPAgentSession {\n readonly sessionId: string;\n readonly negotiatedProtocolVersion: number;\n readonly agentName?: string;\n readonly agentVersion?: string;\n /** The agent-declared mode the session runs under, when one was selectable. */\n readonly sessionModeId?: string;\n /** Capabilities the agent advertised — the ones this runner branches on. */\n readonly capabilities: { readonly loadSession: boolean };\n /** Drive one turn. May be called repeatedly to continue the conversation. */\n promptTurn(prompt: string, options?: ACPPromptTurnOptions): Promise<ACPTurnResult>;\n /** Terminate the agent process. Idempotent; safe after any turn. */\n close(): void;\n}\n\nexport interface ACPCodingSessionResult {\n readonly finalMessage: string;\n readonly stopReason: CodingAgent_StopReason;\n /** The agent's verbatim value when `stopReason` is `UNRECOGNISED`. */\n readonly rawStopReason?: string;\n readonly usage?: CodingAgent_Usage;\n readonly reportedFileLocations: readonly string[];\n readonly sessionId: string;\n readonly negotiatedProtocolVersion: number;\n readonly agentName?: string;\n readonly agentVersion?: string;\n /** The agent-declared mode the turn ran under, when one was selectable. */\n readonly sessionModeId?: string;\n readonly events: readonly ACPSessionEvent[];\n /** True when the event log hit its byte ceiling and stopped recording. */\n readonly eventsTruncated: boolean;\n /** Refused permission requests plus callback ceiling or scope refusals. */\n readonly deniedPermissionCount: number;\n /**\n * Permission-request decisions and callback policy refusals, in order, with their reasons.\n *\n * A count alone is not diagnosable. A run under an UNRESTRICTED ceiling came back with two\n * denials and no files, and the recorded evidence could not say whether the scope predicate\n * had refused a path or the agent had simply offered no `allow_once` option — two very\n * different defects with the same visible outcome. This makes the decision auditable without\n * re-running an agent to find out.\n *\n * Carries no prompt or file CONTENT: tool kind, paths, the option kinds offered, and the\n * decision. Bounded by {@link PERMISSION_DECISION_RECORD_LIMIT}.\n */\n readonly permissionDecisions: readonly ACPPermissionDecisionRecord[];\n}\n\n/**\n * Agent-declared mode ids preferred for each ceiling.\n *\n * EVERY ceiling asks for the MOST-ESCALATING mode, and that is the correction\n * that matters. The obvious mapping — `AUTO_ACCEPT_EDITS` → the agent's own\n * `acceptEdits`, `UNRESTRICTED` → `bypassPermissions` — hands the decision to\n * the agent, which is exactly what this runner must not do. Measured live on\n * 2026-08-27: under `acceptEdits`, Claude's adapter auto-approved a mutating\n * shell command that wrote OUTSIDE the task's declared mutation scope, with no\n * permission request reaching the client at all. Under `default` the identical\n * prompt escalated, was denied, and nothing was written.\n *\n * Keeping the agent maximally escalating means every decision reaches\n * {@link permissionAllowedByCeiling}, where the ceiling means what it says —\n * and where the caller's mutation scope can still refuse a path.\n */\n\n/**\n * Tool kinds the Agent Client Protocol itself classes as NON-MUTATING, for the AUTO_ACCEPT_READS\n * ceiling.\n *\n * Taken from the protocol's own tool-kind categorisation rather than invented here, so the set does\n * not drift from what an agent means when it declares a kind.\n * spec-cite: Agent Client Protocol — Tool Calls, tool-kind list\n * (https://agentclientprotocol.com/protocol/tool-calls): `read`, `search`, `fetch` and `think` are\n * the non-mutating kinds; `edit`, `delete` and `move` are the mutating ones.\n *\n * `execute` is deliberately EXCLUDED: a command can mutate anything, and a runner cannot tell a\n * read-only command from a destructive one by its kind. `other` is excluded because it is the\n * protocol's unclassified catch-all — measured 2026-08-29, the agent's own `ToolSearch` arrived as\n * `other`, so admitting it would mean admitting whatever an agent declines to classify.\n */\nconst NON_MUTATING_TOOL_KINDS = new Set(['read', 'search', 'fetch', 'think']);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Decide one permission request from the ceiling alone (before the caller's\n * scope predicate narrows it further).\n *\n * Exported for direct testing: this is the security decision of the whole\n * transport, and it should be provable without spawning anything.\n * assurance-control: WILDO.SOFTWARE.AI_PRODUCED_CHANGE_CONTROL — a coding agent's tool kind is admitted only by the session's declared ceiling, and an unknown ceiling admits nothing.\n */\nexport function permissionAllowedByCeiling(\n ceiling: AgentClientProtocol_PermissionCeiling,\n toolKind: string | undefined,\n): boolean {\n switch (ceiling) {\n case AgentClientProtocol_PermissionCeiling.UNRESTRICTED:\n return true;\n case AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_EDITS:\n // Edits are pre-approved; anything else (executing a command, fetching a\n // URL, an unrecognised kind) still requires a decision this runner cannot\n // make on its own, so it is denied rather than guessed.\n //\n // This is only true because the agent is kept in its most-escalating\n // mode — `sessionModeIdsByPermissionCeiling` on the provider contract,\n // passed in as `preferredSessionModeIds`. (The runner-local\n // `PREFERRED_MODE_IDS` this used to name was deleted on 2026-09-04: mode\n // ids are agent vocabulary, so a map hardcoded here matched nothing for\n // every agent but the one it was written for.) Delegating to the agent's\n // own `acceptEdits` mode made `execute` bypass this branch entirely,\n // measured live.\n // An EDIT for the AUTO_ACCEPT_EDITS ceiling is a WRITING tool kind: the one named source (#1805).\n return isWritingAcpToolKind(toolKind);\n case AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_READS_AND_EDITS:\n // The union of the two sets above, refusing exactly what both refuse:\n // `execute` (a command can mutate anything) and `other` (unclassified,\n // fail-closed). The evidence-persisting research lane's ceiling — the\n // location predicate is what keeps its writes inside the store.\n return toolKind !== undefined && (NON_MUTATING_TOOL_KINDS.has(toolKind) || isWritingAcpToolKind(toolKind));\n case AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_READS:\n /*\n * Non-mutating kinds are pre-approved; everything else is denied rather than guessed — the\n * same posture AUTO_ACCEPT_EDITS takes for its complement, and for the same reason: with no\n * human at the other end there is nobody to ask.\n *\n * An UNDECLARED kind is denied. An agent that does not say what it is doing does not get the\n * benefit of the doubt on a ceiling whose whole promise is \"nothing mutates\".\n */\n return toolKind !== undefined && NON_MUTATING_TOOL_KINDS.has(toolKind);\n case AgentClientProtocol_PermissionCeiling.PROMPT_ALWAYS:\n // Nothing is pre-approved. With no human at the other end of this\n // transport, \"prompt\" resolves to \"deny\": a coding run that needed an\n // authorisation nobody could give did not have it.\n return false;\n default: {\n // An unknown ceiling is not a reason to proceed. Fail closed rather than\n // fall through to a permissive branch.\n const exhaustive: never = ceiling;\n void exhaustive;\n return false;\n }\n }\n}\n\n/**\n * Map an ACP stop-reason wire value onto the named vocabulary.\n *\n * An unknown value DEGRADES rather than throwing. This runs after the turn — so\n * after the workspace may already have been mutated — and throwing here would\n * turn a completed run into an error whose change set nobody records. The caller\n * gets `UNRECOGNISED` plus the verbatim value and can refuse it as a working\n * result while still capturing what changed.\n */\nexport function parseStopReason(raw: unknown): { stopReason: CodingAgent_StopReason; rawStopReason?: string } {\n const known = (Object.values(CodingAgent_StopReason) as string[])\n .filter((value) => value !== CodingAgent_StopReason.UNRECOGNISED);\n if (typeof raw === 'string' && known.includes(raw)) {\n return { stopReason: raw as CodingAgent_StopReason };\n }\n return {\n stopReason: CodingAgent_StopReason.UNRECOGNISED,\n rawStopReason: typeof raw === 'string' ? raw : JSON.stringify(raw ?? null),\n };\n}\n\n/**\n * The cost a `usage_update` carries, or `undefined` when it carries none.\n *\n * ACP defines that cost as the session's CUMULATIVE total, not the turn's increment, and makes it\n * optional per update. The pinned Claude adapter sends it only on the update that follows a `result`;\n * its rate-limit, compaction and streaming updates carry `used`/`size` alone. So the latest update of a\n * turn is not where the cost is: a rate-limit update arriving after the result would erase it. The\n * runner therefore keeps the latest cost it has SEEN on the session ({@link projectUsage}'s third\n * argument), and this reads one update's.\n *\n * spec-cite: ACP schema (`@agentclientprotocol/sdk` 1.5.0, `types.gen.d.ts`) — `UsageUpdate.cost` is typed\n * `Cost | null` and documented \"Cumulative session cost (optional)\"; `Cost.amount` \"Total cumulative cost for session\".\n */\nexport function readUsageUpdateCost(update: unknown): { readonly amount: number; readonly currency: string } | undefined {\n if (!isRecord(update)) return undefined;\n const cost = update.cost;\n return isRecord(cost) && typeof cost.amount === 'number' && Number.isFinite(cost.amount) && cost.amount >= 0\n && typeof cost.currency === 'string' && cost.currency.length > 0\n ? { amount: cost.amount, currency: cost.currency }\n : undefined;\n}\n\n/**\n * The session's cumulative cost after one more reading: the reading, unless it is absent or a ZERO following a\n * positive figure. The Agent SDK documents that a crash or startup-error result \"may carry zeroed values\"; a\n * cumulative total does not fall back to nothing, so such a reading says nothing about the session's spend.\n *\n * spec-cite: Claude Agent SDK `sdk.d.ts`, `SDKResultMessage.total_cost_usd` (the field the pinned adapter forwards as `cost.amount`).\n */\nexport function latestCumulativeCost(\n previous: { readonly amount: number; readonly currency: string } | undefined,\n reading: { readonly amount: number; readonly currency: string } | undefined,\n): { readonly amount: number; readonly currency: string } | undefined {\n if (reading === undefined) return previous;\n if (reading.amount === 0 && previous !== undefined && previous.amount > 0) return previous;\n return reading;\n}\n\n/**\n * Project ACP's usage shapes onto the coding-agent usage contract.\n *\n * Tokens come from the turn's `PromptResponse.usage`, which is the TURN's own tally (the Claude adapter\n * resets it when a turn starts). The context pair comes from the turn's last `usage_update`. The cost is\n * the session's latest cumulative figure (`sessionCost`), so it is the session's total up to this turn,\n * never this turn's alone — a reader combining turns keeps the latest, it does not add them\n * (`AgentsBackendService.mergeCodingUsage`). Without `sessionCost`, the last update's own cost is used.\n */\nexport function projectUsage(\n turnUsage: unknown,\n lastUsageUpdate: unknown,\n sessionCost?: { readonly amount: number; readonly currency: string },\n): CodingAgent_Usage | undefined {\n const usage: Record<string, unknown> = {};\n if (isRecord(turnUsage)) {\n for (const key of ['inputTokens', 'outputTokens', 'cachedReadTokens', 'cachedWriteTokens', 'totalTokens']) {\n if (typeof turnUsage[key] === 'number') usage[key] = turnUsage[key];\n }\n }\n if (isRecord(lastUsageUpdate)) {\n if (typeof lastUsageUpdate.used === 'number') usage.contextUsed = lastUsageUpdate.used;\n if (typeof lastUsageUpdate.size === 'number') usage.contextWindowSize = lastUsageUpdate.size;\n }\n const cost = sessionCost ?? readUsageUpdateCost(lastUsageUpdate);\n if (cost) usage.cost = { amount: cost.amount, currency: cost.currency };\n return Object.keys(usage).length > 0 ? (usage as CodingAgent_Usage) : undefined;\n}\n\n/**\n * True when `candidate` resolves inside `root`. Both must be absolute.\n *\n * Compares against the root AND its physical realpath. Agents report canonical\n * paths, so a root reached through a symlink (`/var/...` → `/private/var/...` on\n * macOS) would otherwise reject every request — a guard that silently denies\n * everything, which reads as the agent failing rather than the guard misfiring.\n * The same defect was found live in the companion's scope predicate.\n */\nexport function isPathWithin(root: string, candidate: string): boolean {\n if (!isAbsolute(root) || !isAbsolute(candidate)) return false;\n const roots = [root];\n try {\n const physical = realpathSync.native(root);\n if (physical !== root) roots.push(physical);\n } catch {\n // An unresolvable root stays as given; the containment check below still applies.\n }\n const resolved = resolve(candidate);\n return roots.some((candidateRoot) => {\n const rel = relative(candidateRoot, resolved);\n return rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n });\n}\n\n/**\n * Resolve an existing write target, or the nearest existing parent of a new one.\n * Resolving only cwd leaves a symlink inside the admitted tree free to point outside it.\n * A dangling symlink is an existing filesystem object, not a missing directory to create;\n * refuse it instead of appending an unresolved alias to an otherwise checked parent.\n * The caller validates and writes this physical path. This is a callback boundary,\n * not an operating-system sandbox against concurrent filesystem replacement.\n */\nfunction resolvePhysicalWritePath(path: string): string {\n let ancestor = resolve(path);\n const missing: string[] = [];\n for (;;) {\n try {\n return resolve(realpathSync.native(ancestor), ...missing.slice().reverse());\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n if (lstatSync(ancestor, { throwIfNoEntry: false }) !== undefined) throw error;\n const parent = dirname(ancestor);\n if (parent === ancestor) throw error;\n missing.push(basename(ancestor));\n ancestor = parent;\n }\n }\n}\n\n/**\n * Open a live ACP session and return a handle whose `promptTurn` drives one\n * turn at a time.\n *\n * The caller owns the turn cadence — this is the whole point of the handle. A\n * turn that ends with a question is not the end of the session; the caller\n * inspects it and may `promptTurn` again with the answer.\n */\nexport async function startACPAgentSession(options: ACPStartSessionOptions): Promise<ACPAgentSession> {\n const maxRecordedEventBytes = options.maxRecordedEventBytes ?? DEFAULT_MAX_RECORDED_EVENT_BYTES;\n const child: ChildProcessWithoutNullStreams = spawn(options.command, [...(options.args ?? [])], {\n cwd: options.cwd,\n env: options.env,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n // Cumulative session state. Per-turn slices are taken from these by index.\n const session = {\n nextId: 1,\n buffer: '',\n stderrTail: '',\n unparsedStdoutTail: '',\n events: [] as ACPSessionEvent[],\n recordedBytes: 0,\n eventsTruncated: false,\n reportedFileLocations: [] as string[],\n /** Each tool call's kind by id, for the updates that omit it (#1805). */\n toolCallKinds: new Map<string, string>(),\n permissionDecisions: [] as ACPPermissionDecisionRecord[],\n deniedPermissionCount: 0,\n // Reset at the start of each turn.\n turnFinalMessage: '',\n turnLastUsageUpdate: undefined as unknown,\n // NOT reset per turn: ACP's cost is the session's cumulative total, and an update that omits it\n // (rate-limit, compaction) does not mean the session cost nothing (see `readUsageUpdateCost`).\n sessionLastReportedCost: undefined as { readonly amount: number; readonly currency: string } | undefined,\n // True while `session/load` replay is streaming: replayed history is\n // consumed and discarded (it is already on the durable record).\n replaying: false,\n // Set once the child exits; a later `promptTurn` refuses rather than hanging.\n childExited: false,\n // Set BEFORE a deliberate terminate() so the exit handler does not reject\n // the exit promise for a shutdown the caller asked for.\n closed: false,\n };\n const pending = new Map<number, { resolve: (value: unknown) => void; reject: (error: unknown) => void }>();\n\n const write = (payload: unknown): void => {\n if (child.stdin.writable) child.stdin.write(`${JSON.stringify(payload)}\\n`);\n };\n const request = (method: string, params: unknown): Promise<unknown> => {\n const id = session.nextId++;\n return new Promise<unknown>((resolvePromise, rejectPromise) => {\n pending.set(id, { resolve: resolvePromise, reject: rejectPromise });\n write({ jsonrpc: '2.0', id, method, params });\n });\n };\n const respond = (id: number, result: unknown): void => write({ jsonrpc: '2.0', id, result });\n const respondError = (id: number, message: string): void =>\n write({ jsonrpc: '2.0', id, error: { code: -32603, message } });\n\n const recordEvent = (event: ACPSessionEvent): void => {\n // Replayed `session/load` history is neither persisted nor forwarded: it is\n // already recorded from the run that produced it, and re-emitting it would\n // double every earlier frame on the resuming run's record.\n if (session.replaying) return;\n if (!session.eventsTruncated) {\n const size = JSON.stringify(event).length;\n if (session.recordedBytes + size > maxRecordedEventBytes) {\n // Truncate, never reject. Losing the tail of a transcript is a reporting\n // loss; failing the run here would discard work already written to the\n // workspace, which is the mistake the transport this replaces made.\n session.eventsTruncated = true;\n } else {\n session.recordedBytes += size;\n session.events.push(event);\n }\n }\n try {\n options.onEvent?.(event);\n } catch {\n // A progress sink must never be able to fail the run it observes.\n }\n };\n\n // assurance-control: WILDO.SOFTWARE.AI_PRODUCED_CHANGE_CONTROL — the host answers every permission request: the ceiling first, then the task's write and read scope, which refuse a declared location even under an unrestricted ceiling.\n const decidePermission = (params: Record<string, unknown>): { allowed: boolean; optionId?: string } => {\n const toolCall = isRecord(params.toolCall) ? params.toolCall : {};\n const toolKind = typeof toolCall.kind === 'string' ? toolCall.kind : undefined;\n const locations = Array.isArray(toolCall.locations)\n ? toolCall.locations.flatMap((entry) => (isRecord(entry) && typeof entry.path === 'string' ? [entry.path] : []))\n : [];\n\n const rawOptions = Array.isArray(params.options) ? params.options : [];\n const offeredOptionKinds = rawOptions.flatMap((entry) => (isRecord(entry) && typeof entry.kind === 'string' ? [entry.kind] : []));\n const record = (allowed: boolean, reason: ACPPermissionDecisionReason): void => {\n if (session.permissionDecisions.length >= PERMISSION_DECISION_RECORD_LIMIT) return;\n session.permissionDecisions.push({\n allowed,\n reason,\n ...(toolKind !== undefined ? { toolKind } : {}),\n locations,\n offeredOptionKinds,\n });\n };\n\n const toolCallTitle = typeof toolCall.title === 'string' ? toolCall.title : undefined;\n if (options.admitsHostToolCall?.({ toolCallTitle, toolKind }) === true) {\n const hostToolOnce = rawOptions.find((entry) => isRecord(entry) && entry.kind === 'allow_once');\n if (isRecord(hostToolOnce) && typeof hostToolOnce.optionId === 'string') {\n record(true, ACPPermissionDecisionReason.HOST_TOOL_ADMITTED);\n return { allowed: true, optionId: hostToolOnce.optionId };\n }\n }\n if (!permissionAllowedByCeiling(options.permissionCeiling, toolKind)) {\n record(false, ACPPermissionDecisionReason.CEILING_REFUSED);\n return { allowed: false };\n }\n // The caller's scope predicate can only NARROW. A location the task did not\n // authorise is denied even under an UNRESTRICTED ceiling.\n //\n // But note WHAT IT IS QUANTIFIED OVER: `locations` comes from the request, and `some` over an\n // EMPTY array is `false`, so a request that declares NO locations passes this gate without the\n // predicate being consulted once. That is not an oversight to be closed here — a shell command\n // is unscoped BY NATURE (any derived scope is defeated by `sh -c \"$CMD\"` or a substituted\n // redirect), so the scope holds for DECLARED EDITS and commands are unbounded. It is stated\n // here because this is the line a reader arrives at believing the scope is total, and it is a\n // DIFFERENT hole from an agent whose guards never fire at all — see the `UNRESTRICTED` member\n // of `AgentClientProtocol_PermissionCeiling`, which carries the full reasoning.\n if (options.isPermittedLocation && locations.some((path) => !options.isPermittedLocation!(path))) {\n record(false, ACPPermissionDecisionReason.LOCATION_OUT_OF_SCOPE);\n return { allowed: false };\n }\n if (toolKind !== undefined && NON_MUTATING_TOOL_KINDS.has(toolKind)\n && options.isPermittedReadLocation && locations.some((path) => {\n try {\n // Declared read locations refer to existing files/directories. Resolve links\n // before applying host scope, so a permitted alias cannot expose a private target.\n return !isAbsolute(path) || !options.isPermittedReadLocation!(realpathSync.native(path));\n } catch {\n return true;\n }\n })) {\n record(false, ACPPermissionDecisionReason.LOCATION_OUT_OF_SCOPE);\n return { allowed: false };\n }\n // `allow_always` is never selected. Measured against Claude's adapter, that\n // option carries a `_meta` permission change that switches the SESSION into\n // an auto-accepting mode — so answering one request with it silently raises\n // the ceiling for every request after it.\n const once = rawOptions.find((entry) => isRecord(entry) && entry.kind === 'allow_once');\n if (isRecord(once) && typeof once.optionId === 'string') {\n record(true, ACPPermissionDecisionReason.ALLOWED_ONCE);\n return { allowed: true, optionId: once.optionId };\n }\n record(false, ACPPermissionDecisionReason.NO_SELECTABLE_OPTION);\n return { allowed: false };\n };\n\n const handleAgentRequest = async (id: number, method: string, params: Record<string, unknown>): Promise<void> => {\n switch (method) {\n case 'session/request_permission': {\n const decision = decidePermission(params);\n if (decision.allowed && decision.optionId) {\n respond(id, { outcome: { outcome: 'selected', optionId: decision.optionId } });\n return;\n }\n session.deniedPermissionCount++;\n const rawOptions = Array.isArray(params.options) ? params.options : [];\n const reject = rawOptions.find((entry) => isRecord(entry) && entry.kind === 'reject_once');\n if (isRecord(reject) && typeof reject.optionId === 'string') {\n respond(id, { outcome: { outcome: 'selected', optionId: reject.optionId } });\n } else {\n // No refusal option offered: cancelling the request is the only\n // remaining way to say no, and saying no is required.\n respond(id, { outcome: { outcome: 'cancelled' } });\n }\n return;\n }\n // assurance-control: WILDO.SOFTWARE.AI_PRODUCED_CHANGE_CONTROL — a client file read stays inside the session directory and the task's read scope, judged by the file's physical target.\n case 'fs/read_text_file': {\n const path = typeof params.path === 'string' ? params.path : '';\n if (!isPathWithin(options.cwd, path)) {\n respondError(id, 'Path is outside the session working directory');\n return;\n }\n let readPath: string;\n try {\n readPath = realpathSync.native(path);\n } catch (error) {\n respondError(id, `Unable to read file: ${(error as Error).message}`);\n return;\n }\n // Read the resolved name we checked, rather than following the original symlink again.\n // This is host callback containment, not an OS sandbox for the agent's own I/O.\n if (!isPathWithin(options.cwd, readPath)\n || (options.isPermittedReadLocation && !options.isPermittedReadLocation(readPath))) {\n session.deniedPermissionCount++;\n if (session.permissionDecisions.length < PERMISSION_DECISION_RECORD_LIMIT) {\n session.permissionDecisions.push({\n allowed: false,\n reason: ACPPermissionDecisionReason.LOCATION_OUT_OF_SCOPE,\n toolKind: 'read',\n locations: [path],\n offeredOptionKinds: [],\n });\n }\n respondError(id, 'Path is outside the task read scope');\n return;\n }\n try {\n respond(id, { content: await readFile(readPath, 'utf8') });\n } catch (error) {\n respondError(id, `Unable to read file: ${(error as Error).message}`);\n }\n return;\n }\n // assurance-control: WILDO.SOFTWARE.AI_PRODUCED_CHANGE_CONTROL — a client file write is refused by the edit ceiling and by the task's write scope before any byte is written.\n case 'fs/write_text_file': {\n const path = typeof params.path === 'string' ? params.path : '';\n // A client callback performs the mutation itself: an adapter need not send a\n // preceding request_permission. Enforce the same edit ceiling at this boundary,\n // even when the adapter ignores the advertised writeTextFile capability.\n if (!permissionAllowedByCeiling(options.permissionCeiling, 'edit')) {\n session.deniedPermissionCount++;\n if (session.permissionDecisions.length < PERMISSION_DECISION_RECORD_LIMIT) {\n session.permissionDecisions.push({\n allowed: false,\n reason: ACPPermissionDecisionReason.CEILING_REFUSED,\n toolKind: 'edit',\n locations: [path],\n offeredOptionKinds: [],\n });\n }\n respondError(id, 'File write refused by the session permission ceiling');\n return;\n }\n if (!isPathWithin(options.cwd, path)) {\n respondError(id, 'Path is outside the session working directory');\n return;\n }\n let writePath: string | undefined;\n try {\n writePath = resolvePhysicalWritePath(path);\n } catch {\n // An unresolved existing alias cannot establish a permitted write target.\n }\n // A configured cwd may itself be an alias (macOS /var -> /private/var).\n // Preserve predicates authored against either spelling, after physical\n // containment is established. Both spellings identify the checked target;\n // an alias into another subtree is mapped to that actual subtree.\n const inWorkingDirectory = writePath !== undefined && isPathWithin(options.cwd, writePath);\n const configuredWritePath = inWorkingDirectory\n ? resolve(options.cwd, relative(realpathSync.native(options.cwd), writePath))\n : undefined;\n if (!inWorkingDirectory || writePath === undefined\n || (options.isPermittedLocation && !options.isPermittedLocation(writePath)\n && (configuredWritePath === undefined || configuredWritePath === writePath || !options.isPermittedLocation(configuredWritePath)))) {\n session.deniedPermissionCount++;\n if (session.permissionDecisions.length < PERMISSION_DECISION_RECORD_LIMIT) {\n session.permissionDecisions.push({\n allowed: false, reason: ACPPermissionDecisionReason.LOCATION_OUT_OF_SCOPE,\n toolKind: 'edit', locations: [path], offeredOptionKinds: [],\n });\n }\n respondError(id, 'Path is outside the task mutation scope or cannot be resolved safely');\n return;\n }\n try {\n await mkdir(dirname(writePath), { recursive: true });\n await writeFile(writePath, typeof params.content === 'string' ? params.content : '', 'utf8');\n respond(id, null);\n } catch (error) {\n respondError(id, `Unable to write file: ${(error as Error).message}`);\n }\n return;\n }\n default:\n // Deliberately including every `terminal/*` method: this runner does NOT\n // advertise the terminal capability, so an agent calling one has ignored\n // the negotiated capability set. Refusing names that plainly.\n respondError(id, `Unsupported client method: ${method}`);\n }\n };\n\n const onLine = (line: string): void => {\n let message: unknown;\n try {\n message = JSON.parse(line);\n } catch {\n /*\n * Non-JSON stdout is the agent's own logging — and it IS our concern when the turn fails.\n *\n * This used to `return` with the comment \"not our concern\", and that is how an agent could\n * exit with code 0 in the middle of a turn while the only thing we could report was \"Agent\n * process exited before the turn completed\". A process that exits SUCCESSFULLY has almost\n * always said why, and a CLI says it in prose — which by definition does not parse as JSON-RPC\n * and so landed exactly here, in a discard.\n *\n * Kept in a bounded tail, mirroring `stderrTail`, and surfaced only on failure. The protocol\n * frames are excluded by construction: they parse, so they never reach this branch, and the\n * tail cannot fill with the session's own traffic.\n */\n session.unparsedStdoutTail = `${session.unparsedStdoutTail}${line}\\n`.slice(-4_000);\n return;\n }\n if (!isRecord(message)) return;\n\n if (message.method === 'session/update') {\n const update = isRecord(message.params) && isRecord(message.params.update) ? message.params.update : {};\n const kind = typeof update.sessionUpdate === 'string' ? update.sessionUpdate : 'unknown';\n if (!session.replaying) {\n if (kind === 'agent_message_chunk') {\n const content = isRecord(update.content) ? update.content : {};\n if (typeof content.text === 'string') session.turnFinalMessage += content.text;\n }\n if (kind === 'usage_update') {\n session.turnLastUsageUpdate = update;\n session.sessionLastReportedCost = latestCumulativeCost(session.sessionLastReportedCost, readUsageUpdateCost(update));\n }\n if (kind === 'tool_call' || kind === 'tool_call_update') {\n /*\n * A WRITE location only (#1805 review R2). ACP gives every tool call a kind, and an adapter reports\n * locations for reads and searches too (the pinned Claude adapter sets them on `Read`, `Grep` and\n * `Glob`), so a run that only read a sibling's file claimed it. An update may omit the kind, so it is\n * remembered by the call's id from the `tool_call` that opened it.\n */\n // The one rule, shared with the companion's on-disk claims (#3205): `writtenLocationsOfAcpSessionUpdate`.\n for (const location of writtenLocationsOfAcpSessionUpdate(kind, update, session.toolCallKinds)) {\n if (!session.reportedFileLocations.includes(location)) session.reportedFileLocations.push(location);\n }\n }\n }\n recordEvent({ kind, payload: update });\n return;\n }\n\n if (typeof message.method === 'string' && typeof message.id === 'number') {\n void handleAgentRequest(message.id, message.method, isRecord(message.params) ? message.params : {});\n return;\n }\n\n if (typeof message.id === 'number' && pending.has(message.id)) {\n const waiter = pending.get(message.id)!;\n pending.delete(message.id);\n if (message.error !== undefined) {\n /*\n * A JSON-RPC error is an OBJECT ({code, message, data?}), and rejecting with it raw is how a\n * real adapter answer became \"[object Object]\" at the choreography seam and \"Unknown agent\n * invocation error\" in the trace — three layers each normalizing for Error-or-string and\n * discarding everything else. The adapter names its failures; carry the name. (Found\n * 2026-09-03: a research turn's session/prompt error cost a full diagnosis cycle because all\n * that survived was the coercion.)\n */\n const rpcError = message.error as { code?: unknown; message?: unknown; data?: unknown };\n const detail = typeof rpcError?.message === 'string' ? rpcError.message : JSON.stringify(message.error)?.slice(0, 500);\n const rejection = new Error(`ACP agent error${typeof rpcError?.code === 'number' ? ` ${rpcError.code}` : ''}: ${detail}`);\n (rejection as Error & { acpError?: unknown }).acpError = message.error;\n waiter.reject(rejection);\n } else waiter.resolve(message.result);\n }\n };\n\n child.stdout.setEncoding('utf8');\n child.stdout.on('data', (chunk: string) => {\n session.buffer += chunk;\n let index: number;\n while ((index = session.buffer.indexOf('\\n')) >= 0) {\n const line = session.buffer.slice(0, index).trim();\n session.buffer = session.buffer.slice(index + 1);\n if (line) onLine(line);\n }\n });\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n session.stderrTail = `${session.stderrTail}${chunk}`.slice(-4_000);\n });\n\n const terminate = (): void => {\n // Mark the shutdown as deliberate BEFORE killing so the exit handler does\n // not reject the exit promise for a close the caller asked for.\n session.closed = true;\n if (!child.killed) child.kill('SIGTERM');\n setTimeout(() => {\n if (!child.killed) child.kill('SIGKILL');\n }, TERMINATION_SETTLE_GRACE_MS).unref?.();\n };\n\n const failed = (message: string, details: Record<string, unknown>): ACPSessionRunnerError =>\n new ACPSessionRunnerError(message, {\n ...details,\n stderrTail: session.stderrTail.trim().slice(-1_000),\n stdoutTail: session.unparsedStdoutTail.trim().slice(-1_000),\n });\n\n // ONE persistent \"the child died\" promise, raced against every awaited\n // request. It rejects at most once, only for an UNDELIBERATE exit — a close()\n // the caller asked for sets `closed` first and leaves it pending. Raced at\n // `initialize`, so it always carries a rejection handler and a later reject\n // (e.g. a crash between turns) never surfaces as an unhandled rejection.\n const exitPromise = new Promise<never>((_, rejectPromise) => {\n child.on('error', (error) => {\n session.childExited = true;\n if (!session.closed) rejectPromise(failed(`Agent process failed to start: ${error.message}`, {}));\n });\n child.on('exit', (code, signal) => {\n session.childExited = true;\n if (!session.closed) rejectPromise(failed('Agent process exited before the turn completed', { exitCode: code, signal }));\n });\n });\n\n try {\n // --- initialize ---------------------------------------------------------\n const initializeResult = await Promise.race([\n request('initialize', {\n protocolVersion: Math.max(...options.supportedProtocolVersions),\n clientCapabilities: {\n // `fs` is implemented above and confined to the session directory.\n fs: { readTextFile: true, writeTextFile: permissionAllowedByCeiling(options.permissionCeiling, 'edit') },\n // `terminal` is NOT advertised. An agent that wants to run a command\n // runs it itself — measured, that is what the default agent does even\n // when the capability IS offered — so advertising it would add an\n // unexercised execution surface for no observed gain.\n terminal: false,\n },\n }),\n exitPromise,\n ]);\n if (!isRecord(initializeResult)) {\n throw failed('Agent returned a malformed initialize result', { initializeResult });\n }\n const negotiatedProtocolVersion = initializeResult.protocolVersion;\n if (typeof negotiatedProtocolVersion !== 'number' || !options.supportedProtocolVersions.includes(negotiatedProtocolVersion)) {\n // Refused rather than attempted. A version we do not implement is not a\n // version we can hold to a permission ceiling.\n throw failed('Agent negotiated an unsupported ACP protocol version', {\n negotiatedProtocolVersion,\n supportedProtocolVersions: [...options.supportedProtocolVersions],\n });\n }\n const agentInfo = isRecord(initializeResult.agentInfo) ? initializeResult.agentInfo : {};\n const agentCapabilities = isRecord(initializeResult.agentCapabilities) ? initializeResult.agentCapabilities : {};\n const loadSessionSupported = agentCapabilities.loadSession === true;\n // An HTTP MCP server is optional for an agent (#3472). Refused rather than passed to an agent that would drop it:\n // a session whose only way to return its result is missing would run, spend, and answer nothing.\n if ((options.mcpServers ?? []).some((server) => server.type === 'http')) {\n const mcpCapabilities = isRecord(agentCapabilities.mcpCapabilities) ? agentCapabilities.mcpCapabilities : {};\n if (mcpCapabilities.http !== true) {\n throw failed('Agent does not advertise mcpCapabilities.http; the host-served MCP server cannot reach it', {\n mcpServers: (options.mcpServers ?? []).map((server) => server.name),\n });\n }\n }\n\n let sessionId: string;\n let sessionModeId: string | undefined;\n\n if (options.resumeSessionId !== undefined) {\n // --- session/load (resume) -------------------------------------------\n if (!loadSessionSupported) {\n // Refused, not degraded. Starting a fresh session here would present a\n // context-less turn as a continuation of a parked one.\n throw failed('Agent does not advertise the loadSession capability; cannot resume the session', {\n resumeSessionId: options.resumeSessionId,\n });\n }\n session.replaying = true;\n await Promise.race([\n request('session/load', {\n sessionId: options.resumeSessionId,\n cwd: options.cwd,\n mcpServers: [...(options.mcpServers ?? [])],\n }),\n exitPromise,\n ]);\n session.replaying = false;\n sessionId = options.resumeSessionId;\n // Modes are reported by session/new, not session/load. The permission\n // handler is the guarantee regardless, so a resumed session simply runs\n // without a reselected mode.\n } else {\n // --- session/new ------------------------------------------------------\n const sessionResult = await Promise.race([\n request('session/new', {\n cwd: options.cwd,\n mcpServers: [...(options.mcpServers ?? [])],\n ...(options.sessionMetaExtensions ? { _meta: options.sessionMetaExtensions } : {}),\n }),\n exitPromise,\n ]);\n if (!isRecord(sessionResult) || typeof sessionResult.sessionId !== 'string') {\n throw failed('Agent returned a malformed session/new result', { sessionResult });\n }\n sessionId = sessionResult.sessionId;\n\n // --- best-effort mode selection (an optimisation, never the guarantee) -\n const modes = isRecord(sessionResult.modes) ? sessionResult.modes : undefined;\n const available = modes && Array.isArray(modes.availableModes) ? modes.availableModes : [];\n const preferred = options.preferredSessionModeIds ?? [];\n const match = available.find((entry) => isRecord(entry) && typeof entry.id === 'string' && preferred.includes(entry.id));\n if (isRecord(match) && typeof match.id === 'string') {\n try {\n // Raced against the death signal: before this, a `session/set_mode` sent\n // to an agent that then died left a promise nobody would ever settle,\n // with the turn timeout not yet armed — the run hung forever.\n await Promise.race([request('session/set_mode', { sessionId, modeId: match.id }), exitPromise]);\n sessionModeId = match.id;\n } catch {\n // The ceiling is still enforced by the permission handler, so a mode we\n // could not set costs round-trips, not safety.\n sessionModeId = undefined;\n }\n } else if (typeof modes?.currentModeId === 'string') {\n sessionModeId = modes.currentModeId;\n }\n }\n\n // --- model delivery, when the agent takes it over ACP -------------------\n //\n // Unlike the mode selection above, this is NOT best-effort. A model that\n // could not be set means the agent runs its own default while the run\n // records the model that was requested — a false result rather than a\n // degraded one, which is precisely the failure the provider-declared\n // delivery channel exists to end. So a rejection fails the session before\n // any prompt is sent, i.e. before the agent has touched the workspace.\n if (options.modelSelection) {\n const setModelResult = await Promise.race([\n request('session/set_config_option', {\n sessionId,\n configId: options.modelSelection.configId,\n value: options.modelSelection.model,\n }),\n exitPromise,\n ]).catch((error: unknown) => {\n throw failed(\n `Agent refused the model selection: ${describeCaughtError(error)}`,\n { configId: options.modelSelection?.configId, model: options.modelSelection?.model },\n );\n });\n void setModelResult;\n }\n\n const promptTurn = async (prompt: string, turnOptions?: ACPPromptTurnOptions): Promise<ACPTurnResult> => {\n if (session.childExited) {\n throw failed('Agent process is no longer running; cannot start a turn', { sessionId });\n }\n\n // Per-turn slices are the cumulative arrays from this point on.\n const eventStart = session.events.length;\n const permissionStart = session.permissionDecisions.length;\n const deniedStart = session.deniedPermissionCount;\n const fileLocStart = session.reportedFileLocations.length;\n session.turnFinalMessage = '';\n session.turnLastUsageUpdate = undefined;\n\n let settled = false;\n let timedOut = false;\n let timer: NodeJS.Timeout | undefined;\n const cancelTurn = (): void => {\n write({ jsonrpc: '2.0', method: 'session/cancel', params: { sessionId } });\n setTimeout(() => {\n if (!settled) terminate();\n }, COOPERATIVE_CANCEL_GRACE_MS).unref?.();\n };\n const onAbort = (): void => cancelTurn();\n\n const turnPromise = request('session/prompt', {\n sessionId,\n prompt: [{ type: 'text', text: prompt }],\n });\n if (turnOptions?.turnTimeoutMs !== undefined) {\n timer = setTimeout(() => {\n timedOut = true;\n // Cooperative first: ACP requires the agent to answer a cancelled turn\n // with stop reason `cancelled`, which lets the caller distinguish an\n // interrupted run from a completed one. Kill only if it does not.\n cancelTurn();\n }, turnOptions.turnTimeoutMs);\n timer.unref?.();\n }\n if (turnOptions?.abortSignal) {\n if (turnOptions.abortSignal.aborted) cancelTurn();\n else turnOptions.abortSignal.addEventListener('abort', onAbort, { once: true });\n }\n\n try {\n const turnResult = await Promise.race([turnPromise, exitPromise]);\n settled = true;\n if (!isRecord(turnResult)) {\n throw failed('Agent returned a malformed session/prompt result', { turnResult, timedOut });\n }\n const { stopReason, rawStopReason } = parseStopReason(turnResult.stopReason);\n return {\n finalMessage: session.turnFinalMessage,\n stopReason,\n ...(rawStopReason ? { rawStopReason } : {}),\n usage: projectUsage(turnResult.usage, session.turnLastUsageUpdate, session.sessionLastReportedCost),\n reportedFileLocations: session.reportedFileLocations.slice(fileLocStart),\n events: session.events.slice(eventStart),\n eventsTruncated: session.eventsTruncated,\n deniedPermissionCount: session.deniedPermissionCount - deniedStart,\n permissionDecisions: session.permissionDecisions.slice(permissionStart),\n };\n } finally {\n settled = true;\n if (timer) clearTimeout(timer);\n turnOptions?.abortSignal?.removeEventListener('abort', onAbort);\n }\n };\n\n return {\n sessionId,\n negotiatedProtocolVersion,\n ...(typeof agentInfo.name === 'string' ? { agentName: agentInfo.name } : {}),\n ...(typeof agentInfo.version === 'string' ? { agentVersion: agentInfo.version } : {}),\n ...(sessionModeId ? { sessionModeId } : {}),\n capabilities: { loadSession: loadSessionSupported },\n promptTurn,\n close: terminate,\n };\n } catch (error) {\n // Setup failed: the child must not be left running.\n terminate();\n throw error;\n }\n}\n\n/**\n * Drive exactly one coding turn end to end: open a session, send one prompt,\n * settle, and close.\n *\n * The compatibility surface for every caller that does not need the turn\n * cadence. It is a thin composition of {@link startACPAgentSession} +\n * `promptTurn` + `close`, so its behaviour tracks the handle by construction.\n */\nexport async function runACPCodingSession(options: ACPCodingSessionOptions): Promise<ACPCodingSessionResult> {\n const agentSession = await startACPAgentSession(options);\n try {\n const turn = await agentSession.promptTurn(options.prompt, {\n ...(options.turnTimeoutMs !== undefined ? { turnTimeoutMs: options.turnTimeoutMs } : {}),\n ...(options.abortSignal ? { abortSignal: options.abortSignal } : {}),\n });\n return {\n finalMessage: turn.finalMessage,\n stopReason: turn.stopReason,\n ...(turn.rawStopReason ? { rawStopReason: turn.rawStopReason } : {}),\n usage: turn.usage,\n reportedFileLocations: turn.reportedFileLocations,\n sessionId: agentSession.sessionId,\n negotiatedProtocolVersion: agentSession.negotiatedProtocolVersion,\n ...(agentSession.agentName ? { agentName: agentSession.agentName } : {}),\n ...(agentSession.agentVersion ? { agentVersion: agentSession.agentVersion } : {}),\n ...(agentSession.sessionModeId ? { sessionModeId: agentSession.sessionModeId } : {}),\n events: turn.events,\n eventsTruncated: turn.eventsTruncated,\n deniedPermissionCount: turn.deniedPermissionCount,\n permissionDecisions: turn.permissionDecisions,\n };\n } finally {\n agentSession.close();\n }\n}\n\n/** Re-exported so callers reason about ceilings through one ordering definition. */\nexport { agentClientProtocolPermissionCeilingRank };\n"]}
1
+ {"version":3,"file":"acp-session-runner.backend.utils.js","sourceRoot":"","sources":["../../../../src/flows-actors/utils/acp-session-runner.backend.utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Agent Client Protocol session runner.\n *\n * Two shapes over one transport:\n *\n * - {@link startACPAgentSession} opens a LIVE session — spawn the agent,\n * negotiate `initialize`, open (or `session/load`-resume) a session against a\n * confined working directory — and returns a handle whose `promptTurn` drives\n * ONE turn at a time. The caller decides whether to send another prompt on\n * the same session, which is what makes the interactive/continuation lane\n * possible: a turn that ended with a question is answered by the next\n * `promptTurn`, on the same `sessionId`, with the agent's context intact.\n * - {@link runACPCodingSession} is the single-turn wrapper kept for every\n * existing caller: start, one turn, close.\n *\n * # Why the transport is written here rather than taken from a package\n *\n * ACP is JSON-RPC 2.0 over newline-delimited stdio, and an official TypeScript\n * SDK exists. This runner speaks the wire directly instead, for two reasons.\n * The mechanical one: adopting the SDK adds a third-party runtime dependency to\n * an engine package, which is a toolchain-baseline decision with a version pin,\n * and it must not be taken incidentally inside a feature slice. The substantive\n * one: everything below is the part Wildo must OWN anyway — which protocol\n * versions are acceptable, who answers a permission request, what a working\n * directory may be, how long a turn may run. An SDK would have supplied the\n * framing, which is the cheap half.\n *\n * Revisit if ACP 2 lands: version negotiation is one place, and adopting the\n * SDK then is a contained change.\n *\n * # The permission ceiling is enforced HERE, not by the agent's session mode\n *\n * Agents advertise their own session modes (`default`, `acceptEdits`,\n * `bypassPermissions`, …) and those identifiers are agent-specific strings. The\n * runner will select a matching mode when one is advertised, because it saves\n * round-trips — but it NEVER relies on that for the guarantee. The ceiling is\n * enforced by this runner's answer to every `session/request_permission` and by\n * the edit check on client-hosted filesystem writes. For agent-owned I/O, an\n * agent that advertises no modes at all, or renames the ones it has, is still\n * held to the authored ceiling when it raises permission requests. Mode selection is an optimisation; the handler\n * is the mechanism.\n */\n\nimport { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';\nimport { realpathSync, lstatSync } from 'node:fs';\nimport { readFile, writeFile, mkdir } from 'node:fs/promises';\nimport { basename, dirname, isAbsolute, relative, resolve, sep } from 'node:path';\n\nimport {\n AgentClientProtocol_PermissionCeiling,\n CodingAgent_StopReason,\n agentClientProtocolPermissionCeilingRank,\n isWritingAcpToolKind,\n writtenLocationsOfAcpSessionUpdate,\n type CodingAgent_Usage,\n} from '@wildo-ai/external-connectors-models';\n\nimport { describeCaughtError } from '~wildo-backend-lib/errors/utils/error-log-level-classification.backend.utils';\n/** Milliseconds allowed for the agent to honour `session/cancel` before it is killed. */\nconst COOPERATIVE_CANCEL_GRACE_MS = 10_000;\n/** Extra grace after SIGKILL so an unreapable child cannot hang a caller. */\nconst TERMINATION_SETTLE_GRACE_MS = 1_000;\n/** Default ceiling on persisted session-event bytes. Truncates; never fails the run. */\nconst DEFAULT_MAX_RECORDED_EVENT_BYTES = 4 * 1024 * 1024;\n\nexport class ACPSessionRunnerError extends Error {\n constructor(\n message: string,\n public readonly details: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'ACPSessionRunnerError';\n }\n}\n\n/** One `session/update` notification, recorded for the caller's traceability sink. */\nexport interface ACPSessionEvent {\n readonly kind: string;\n readonly payload: unknown;\n}\n\nexport interface ACPPermissionRequest {\n readonly toolCallTitle: string | undefined;\n readonly toolKind: string | undefined;\n /** Absolute paths the tool call declares it will touch, when it declares any. */\n readonly locations: readonly string[];\n readonly optionKinds: readonly string[];\n}\n\n/** Why a permission request was decided or a client filesystem callback was refused. */\nexport enum ACPPermissionDecisionReason {\n /** The declared ceiling does not admit this tool kind. */\n CEILING_REFUSED = 'ceiling_refused',\n /** A location the host's mutation or read scope does not authorise. */\n LOCATION_OUT_OF_SCOPE = 'location_out_of_scope',\n /** Admitted, and an `allow_once` option existed to say so with. */\n ALLOWED_ONCE = 'allowed_once',\n /**\n * Admitted by the ceiling and the scope, then refused anyway because the agent offered no\n * option this client is willing to select. `allow_always` is deliberately never chosen below\n * an UNRESTRICTED ceiling — it carries a session-wide permission change — so a request that\n * offers only that option has no answer other than refusal.\n */\n NO_SELECTABLE_OPTION = 'no_selectable_option',\n /**\n * The call is to a tool the HOST itself serves to the session (`mcpServers`), named by the host's\n * {@link ACPStartSessionOptions.admitsHostToolCall} predicate (#3472). Answered before the ceiling, because the\n * ceiling governs the agent's reach into the workspace and the host's own tool reaches nothing but the host.\n */\n HOST_TOOL_ADMITTED = 'host_tool_admitted',\n}\n\n/**\n * An MCP server the HOST serves to the session, passed in `session/new` (#3472).\n *\n * HTTP only: the host serves it in-process, so its tools run in the host and can validate against the host's own\n * schemas. The agent must advertise `mcpCapabilities.http`; the runner refuses the session otherwise rather than\n * open one whose only way to answer is missing.\n * spec-cite: Agent Client Protocol — Session Setup, MCP servers (https://agentclientprotocol.com/protocol/session-setup):\n * stdio is mandatory for agents, HTTP is optional and advertised as `mcpCapabilities.http` at `initialize`.\n */\nexport interface ACPHttpMcpServerDeclaration {\n readonly type: 'http';\n readonly name: string;\n readonly url: string;\n readonly headers: readonly { readonly name: string; readonly value: string }[];\n}\n\nexport interface ACPPermissionDecisionRecord {\n readonly allowed: boolean;\n readonly reason: ACPPermissionDecisionReason;\n /** The declared ACP tool kind, or `read`/`edit` for a direct filesystem callback. */\n readonly toolKind?: string;\n /** Paths the request declared. Empty when the agent declared none — which is why an\n * `execute` request cannot be scope-checked at all. */\n readonly locations: readonly string[];\n /** The option KINDS the agent offered, so a refusal for lack of a selectable one is visible. */\n readonly offeredOptionKinds: readonly string[];\n}\n\n/** Bounds the recorded decisions; a runaway agent must not grow this without limit. */\nconst PERMISSION_DECISION_RECORD_LIMIT = 200;\n\n/**\n * Options common to opening a session and running a one-shot turn.\n *\n * The single-turn {@link ACPCodingSessionOptions} extends this with `prompt`,\n * `turnTimeoutMs` and `abortSignal` — the per-turn concerns the live handle\n * takes as arguments to `promptTurn` instead.\n */\nexport interface ACPStartSessionOptions {\n command: string;\n args?: readonly string[];\n /** Already resolved and confined by `resolveTrustedWorkingDirectory`. */\n cwd: string;\n env: NodeJS.ProcessEnv;\n /** Protocol majors the caller will accept in the `initialize` response. */\n supportedProtocolVersions: readonly number[];\n permissionCeiling: AgentClientProtocol_PermissionCeiling;\n /**\n * Additional, caller-owned refusal on top of the ceiling — used to hold an\n * agent to a task's declared mutation scope. Returning false DENIES, whatever\n * the ceiling says. It can only narrow.\n */\n isPermittedLocation?: (absolutePath: string) => boolean;\n /**\n * Optional host restriction for client-hosted file reads and declared non-mutating tool locations.\n * Client callbacks also remain confined to cwd.\n * Research confines reads to its evidence store; coding runs normally read surrounding\n * application source even when their mutation scope is narrower. Keep those authorities separate.\n */\n isPermittedReadLocation?: (absolutePath: string) => boolean;\n /**\n * The agent's OWN session-mode ids to prefer, most-preferred first.\n *\n * Supplied by the caller from the provider contract rather than derived here:\n * mode ids are agent vocabulary, and a map hardcoded in this neutral runner\n * matched `default` for every ceiling — correct for one adapter and silently\n * empty for an agent whose modes are, say, `build`/`plan`. An unmatched or\n * unsettable mode costs round-trips, never safety: the ceiling is enforced by\n * this runner's answer to every permission request.\n */\n preferredSessionModeIds?: readonly string[];\n /**\n * Set the model over ACP as a session config option, before the first prompt.\n *\n * Only for agents whose provider declares the `session-config-option`\n * delivery channel; agents that read the model from their environment have it\n * in `env` already. A rejected call FAILS the session rather than proceeding:\n * an unset model means the agent silently runs its own default while the run\n * records the model that was requested.\n */\n modelSelection?: { configId: string; model: string };\n /** Opaque `_meta` for `session/new`; agent-specific by construction. */\n sessionMetaExtensions?: Record<string, unknown>;\n /** MCP servers the host serves to the session (#3472). Absent: none, as before. */\n mcpServers?: readonly ACPHttpMcpServerDeclaration[];\n /**\n * Admit a permission request for a tool the host serves itself (#3472), BEFORE the ceiling is consulted.\n *\n * Narrow by construction: the host names its own tool, and only an `allow_once` answer is ever given. Every other\n * request is decided exactly as before, so a language-model session opened under `PROMPT_ALWAYS` can call the\n * host's submit tool and nothing else.\n */\n admitsHostToolCall?: (request: { readonly toolCallTitle: string | undefined; readonly toolKind: string | undefined }) => boolean;\n maxRecordedEventBytes?: number;\n /** Live progress sink. Never allowed to fail the run. */\n onEvent?: (event: ACPSessionEvent) => void;\n /**\n * Let the agent ASK a question through the protocol (#3710): advertise form elicitation at `initialize` and treat\n * an `elicitation/create` the agent sends during a turn as that turn's question.\n *\n * The agent's question tool (Claude's `AskUserQuestion`) reaches a client only as a form elicitation, and an agent\n * enables the tool only for a client that advertises the capability, so without this the agent cannot ask at all:\n * whatever it writes in prose is narration, and nothing tells a question in it from a progress note but a guess.\n * With it, the question is a protocol message: the runner records it ({@link ACPTurnResult.explicitQuestion}),\n * answers the request `cancel` (the person is not here to fill the form during the turn), and cancels the turn, so\n * the caller can park the session and answer with the next `promptTurn`.\n *\n * Off by default: only a caller that can hold a parked session may let an agent ask. A request from an agent that\n * was not offered the capability is declined.\n */\n acceptsExplicitQuestions?: boolean;\n /**\n * Resume a prior session by id instead of opening a new one.\n *\n * When set, the runner calls `session/load` rather than `session/new`, so the\n * agent restores the earlier conversation's context. REQUIRES the agent to\n * advertise the `loadSession` capability at `initialize`; a resume asked of an\n * agent that does not is REFUSED, not silently degraded to a fresh session —\n * presenting a context-less turn as a continuation is the failure this guards.\n * The replayed history is consumed and discarded: it is already on the durable\n * record from the run that parked, and re-recording it would double it.\n */\n resumeSessionId?: string;\n}\n\nexport interface ACPCodingSessionOptions extends ACPStartSessionOptions {\n prompt: string;\n turnTimeoutMs?: number;\n /**\n * Operator-initiated cancellation.\n *\n * Handled exactly like the timeout, and deliberately so: `session/cancel`\n * first, kill only if the agent does not honour it. An operator who stops a\n * run wants it to STOP, but a coding agent killed mid-edit leaves a worktree\n * nobody can characterise — whereas one that settles as `cancelled` leaves a\n * partial change set the caller knows is partial.\n */\n abortSignal?: AbortSignal;\n}\n\n/** Per-turn arguments to {@link ACPAgentSession.promptTurn}. */\nexport interface ACPPromptTurnOptions {\n turnTimeoutMs?: number;\n /** See {@link ACPCodingSessionOptions.abortSignal}. Scoped to this one turn. */\n abortSignal?: AbortSignal;\n}\n\n/** The outcome of one prompt turn on a live session. */\nexport interface ACPTurnResult {\n readonly finalMessage: string;\n readonly stopReason: CodingAgent_StopReason;\n /** The agent's verbatim value when `stopReason` is `UNRECOGNISED`. */\n readonly rawStopReason?: string;\n readonly usage?: CodingAgent_Usage;\n /**\n * File paths the agent reported WRITING during this turn: the locations of its `edit`, `delete` and\n * `move` tool calls, never of a read or a search (#1805). A concurrent run's accept reads these as its\n * claims, and a file the run only read is not its to be committed under.\n */\n readonly reportedFileLocations: readonly string[];\n /** `session/update` notifications recorded DURING THIS TURN. */\n readonly events: readonly ACPSessionEvent[];\n /** True when the session's cumulative event log hit its byte ceiling. */\n readonly eventsTruncated: boolean;\n /** Refused permission requests plus callback ceiling or scope refusals during this turn. */\n readonly deniedPermissionCount: number;\n /** Permission decisions and callback policy refusals recorded during this turn. */\n readonly permissionDecisions: readonly ACPPermissionDecisionRecord[];\n /**\n * The question the agent ASKED during this turn through the protocol (`elicitation/create`, form mode), rendered as\n * text: present only when the session was opened with {@link ACPStartSessionOptions.acceptsExplicitQuestions}. The\n * turn was cancelled to put it, so its stop reason is `cancelled`; this field is what tells that from an operator's\n * cancel. Absent: the agent asked nothing, whatever its final message says (#3710).\n */\n readonly explicitQuestion?: string;\n}\n\n/** What the agent declared about itself and the session at `initialize`/setup time. */\nexport interface ACPAgentSession {\n readonly sessionId: string;\n readonly negotiatedProtocolVersion: number;\n readonly agentName?: string;\n readonly agentVersion?: string;\n /** The agent-declared mode the session runs under, when one was selectable. */\n readonly sessionModeId?: string;\n /** Capabilities the agent advertised — the ones this runner branches on. */\n readonly capabilities: { readonly loadSession: boolean };\n /** Drive one turn. May be called repeatedly to continue the conversation. */\n promptTurn(prompt: string, options?: ACPPromptTurnOptions): Promise<ACPTurnResult>;\n /** Terminate the agent process. Idempotent; safe after any turn. */\n close(): void;\n}\n\nexport interface ACPCodingSessionResult {\n readonly finalMessage: string;\n readonly stopReason: CodingAgent_StopReason;\n /** The agent's verbatim value when `stopReason` is `UNRECOGNISED`. */\n readonly rawStopReason?: string;\n readonly usage?: CodingAgent_Usage;\n readonly reportedFileLocations: readonly string[];\n readonly sessionId: string;\n readonly negotiatedProtocolVersion: number;\n readonly agentName?: string;\n readonly agentVersion?: string;\n /** The agent-declared mode the turn ran under, when one was selectable. */\n readonly sessionModeId?: string;\n readonly events: readonly ACPSessionEvent[];\n /** True when the event log hit its byte ceiling and stopped recording. */\n readonly eventsTruncated: boolean;\n /** Refused permission requests plus callback ceiling or scope refusals. */\n readonly deniedPermissionCount: number;\n /**\n * Permission-request decisions and callback policy refusals, in order, with their reasons.\n *\n * A count alone is not diagnosable. A run under an UNRESTRICTED ceiling came back with two\n * denials and no files, and the recorded evidence could not say whether the scope predicate\n * had refused a path or the agent had simply offered no `allow_once` option — two very\n * different defects with the same visible outcome. This makes the decision auditable without\n * re-running an agent to find out.\n *\n * Carries no prompt or file CONTENT: tool kind, paths, the option kinds offered, and the\n * decision. Bounded by {@link PERMISSION_DECISION_RECORD_LIMIT}.\n */\n readonly permissionDecisions: readonly ACPPermissionDecisionRecord[];\n}\n\n/**\n * Agent-declared mode ids preferred for each ceiling.\n *\n * EVERY ceiling asks for the MOST-ESCALATING mode, and that is the correction\n * that matters. The obvious mapping — `AUTO_ACCEPT_EDITS` → the agent's own\n * `acceptEdits`, `UNRESTRICTED` → `bypassPermissions` — hands the decision to\n * the agent, which is exactly what this runner must not do. Measured live on\n * 2026-08-27: under `acceptEdits`, Claude's adapter auto-approved a mutating\n * shell command that wrote OUTSIDE the task's declared mutation scope, with no\n * permission request reaching the client at all. Under `default` the identical\n * prompt escalated, was denied, and nothing was written.\n *\n * Keeping the agent maximally escalating means every decision reaches\n * {@link permissionAllowedByCeiling}, where the ceiling means what it says —\n * and where the caller's mutation scope can still refuse a path.\n */\n\n/**\n * Tool kinds the Agent Client Protocol itself classes as NON-MUTATING, for the AUTO_ACCEPT_READS\n * ceiling.\n *\n * Taken from the protocol's own tool-kind categorisation rather than invented here, so the set does\n * not drift from what an agent means when it declares a kind.\n * spec-cite: Agent Client Protocol — Tool Calls, tool-kind list\n * (https://agentclientprotocol.com/protocol/tool-calls): `read`, `search`, `fetch` and `think` are\n * the non-mutating kinds; `edit`, `delete` and `move` are the mutating ones.\n *\n * `execute` is deliberately EXCLUDED: a command can mutate anything, and a runner cannot tell a\n * read-only command from a destructive one by its kind. `other` is excluded because it is the\n * protocol's unclassified catch-all — measured 2026-08-29, the agent's own `ToolSearch` arrived as\n * `other`, so admitting it would mean admitting whatever an agent declines to classify.\n */\nconst NON_MUTATING_TOOL_KINDS = new Set(['read', 'search', 'fetch', 'think']);\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/**\n * Decide one permission request from the ceiling alone (before the caller's\n * scope predicate narrows it further).\n *\n * Exported for direct testing: this is the security decision of the whole\n * transport, and it should be provable without spawning anything.\n * assurance-control: WILDO.SOFTWARE.AI_PRODUCED_CHANGE_CONTROL — a coding agent's tool kind is admitted only by the session's declared ceiling, and an unknown ceiling admits nothing.\n */\nexport function permissionAllowedByCeiling(\n ceiling: AgentClientProtocol_PermissionCeiling,\n toolKind: string | undefined,\n): boolean {\n switch (ceiling) {\n case AgentClientProtocol_PermissionCeiling.UNRESTRICTED:\n return true;\n case AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_EDITS:\n // Edits are pre-approved; anything else (executing a command, fetching a\n // URL, an unrecognised kind) still requires a decision this runner cannot\n // make on its own, so it is denied rather than guessed.\n //\n // This is only true because the agent is kept in its most-escalating\n // mode — `sessionModeIdsByPermissionCeiling` on the provider contract,\n // passed in as `preferredSessionModeIds`. (The runner-local\n // `PREFERRED_MODE_IDS` this used to name was deleted on 2026-09-04: mode\n // ids are agent vocabulary, so a map hardcoded here matched nothing for\n // every agent but the one it was written for.) Delegating to the agent's\n // own `acceptEdits` mode made `execute` bypass this branch entirely,\n // measured live.\n // An EDIT for the AUTO_ACCEPT_EDITS ceiling is a WRITING tool kind: the one named source (#1805).\n return isWritingAcpToolKind(toolKind);\n case AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_READS_AND_EDITS:\n // The union of the two sets above, refusing exactly what both refuse:\n // `execute` (a command can mutate anything) and `other` (unclassified,\n // fail-closed). The evidence-persisting research lane's ceiling — the\n // location predicate is what keeps its writes inside the store.\n return toolKind !== undefined && (NON_MUTATING_TOOL_KINDS.has(toolKind) || isWritingAcpToolKind(toolKind));\n case AgentClientProtocol_PermissionCeiling.AUTO_ACCEPT_READS:\n /*\n * Non-mutating kinds are pre-approved; everything else is denied rather than guessed — the\n * same posture AUTO_ACCEPT_EDITS takes for its complement, and for the same reason: with no\n * human at the other end there is nobody to ask.\n *\n * An UNDECLARED kind is denied. An agent that does not say what it is doing does not get the\n * benefit of the doubt on a ceiling whose whole promise is \"nothing mutates\".\n */\n return toolKind !== undefined && NON_MUTATING_TOOL_KINDS.has(toolKind);\n case AgentClientProtocol_PermissionCeiling.PROMPT_ALWAYS:\n // Nothing is pre-approved. With no human at the other end of this\n // transport, \"prompt\" resolves to \"deny\": a coding run that needed an\n // authorisation nobody could give did not have it.\n return false;\n default: {\n // An unknown ceiling is not a reason to proceed. Fail closed rather than\n // fall through to a permissive branch.\n const exhaustive: never = ceiling;\n void exhaustive;\n return false;\n }\n }\n}\n\n/**\n * Map an ACP stop-reason wire value onto the named vocabulary.\n *\n * An unknown value DEGRADES rather than throwing. This runs after the turn — so\n * after the workspace may already have been mutated — and throwing here would\n * turn a completed run into an error whose change set nobody records. The caller\n * gets `UNRECOGNISED` plus the verbatim value and can refuse it as a working\n * result while still capturing what changed.\n */\nexport function parseStopReason(raw: unknown): { stopReason: CodingAgent_StopReason; rawStopReason?: string } {\n const known = (Object.values(CodingAgent_StopReason) as string[])\n .filter((value) => value !== CodingAgent_StopReason.UNRECOGNISED);\n if (typeof raw === 'string' && known.includes(raw)) {\n return { stopReason: raw as CodingAgent_StopReason };\n }\n return {\n stopReason: CodingAgent_StopReason.UNRECOGNISED,\n rawStopReason: typeof raw === 'string' ? raw : JSON.stringify(raw ?? null),\n };\n}\n\n/**\n * The cost a `usage_update` carries, or `undefined` when it carries none.\n *\n * ACP defines that cost as the session's CUMULATIVE total, not the turn's increment, and makes it\n * optional per update. The pinned Claude adapter sends it only on the update that follows a `result`;\n * its rate-limit, compaction and streaming updates carry `used`/`size` alone. So the latest update of a\n * turn is not where the cost is: a rate-limit update arriving after the result would erase it. The\n * runner therefore keeps the latest cost it has SEEN on the session ({@link projectUsage}'s third\n * argument), and this reads one update's.\n *\n * spec-cite: ACP schema (`@agentclientprotocol/sdk` 1.5.0, `types.gen.d.ts`) — `UsageUpdate.cost` is typed\n * `Cost | null` and documented \"Cumulative session cost (optional)\"; `Cost.amount` \"Total cumulative cost for session\".\n */\nexport function readUsageUpdateCost(update: unknown): { readonly amount: number; readonly currency: string } | undefined {\n if (!isRecord(update)) return undefined;\n const cost = update.cost;\n return isRecord(cost) && typeof cost.amount === 'number' && Number.isFinite(cost.amount) && cost.amount >= 0\n && typeof cost.currency === 'string' && cost.currency.length > 0\n ? { amount: cost.amount, currency: cost.currency }\n : undefined;\n}\n\n/**\n * The session's cumulative cost after one more reading: the reading, unless it is absent or a ZERO following a\n * positive figure. The Agent SDK documents that a crash or startup-error result \"may carry zeroed values\"; a\n * cumulative total does not fall back to nothing, so such a reading says nothing about the session's spend.\n *\n * spec-cite: Claude Agent SDK `sdk.d.ts`, `SDKResultMessage.total_cost_usd` (the field the pinned adapter forwards as `cost.amount`).\n */\nexport function latestCumulativeCost(\n previous: { readonly amount: number; readonly currency: string } | undefined,\n reading: { readonly amount: number; readonly currency: string } | undefined,\n): { readonly amount: number; readonly currency: string } | undefined {\n if (reading === undefined) return previous;\n if (reading.amount === 0 && previous !== undefined && previous.amount > 0) return previous;\n return reading;\n}\n\n/**\n * Project ACP's usage shapes onto the coding-agent usage contract.\n *\n * Tokens come from the turn's `PromptResponse.usage`, which is the TURN's own tally (the Claude adapter\n * resets it when a turn starts). The context pair comes from the turn's last `usage_update`. The cost is\n * the session's latest cumulative figure (`sessionCost`), so it is the session's total up to this turn,\n * never this turn's alone — a reader combining turns keeps the latest, it does not add them\n * (`AgentsBackendService.mergeCodingUsage`). Without `sessionCost`, the last update's own cost is used.\n */\nexport function projectUsage(\n turnUsage: unknown,\n lastUsageUpdate: unknown,\n sessionCost?: { readonly amount: number; readonly currency: string },\n): CodingAgent_Usage | undefined {\n const usage: Record<string, unknown> = {};\n if (isRecord(turnUsage)) {\n for (const key of ['inputTokens', 'outputTokens', 'cachedReadTokens', 'cachedWriteTokens', 'totalTokens']) {\n if (typeof turnUsage[key] === 'number') usage[key] = turnUsage[key];\n }\n }\n if (isRecord(lastUsageUpdate)) {\n if (typeof lastUsageUpdate.used === 'number') usage.contextUsed = lastUsageUpdate.used;\n if (typeof lastUsageUpdate.size === 'number') usage.contextWindowSize = lastUsageUpdate.size;\n }\n const cost = sessionCost ?? readUsageUpdateCost(lastUsageUpdate);\n if (cost) usage.cost = { amount: cost.amount, currency: cost.currency };\n return Object.keys(usage).length > 0 ? (usage as CodingAgent_Usage) : undefined;\n}\n\n/**\n * True when `candidate` resolves inside `root`. Both must be absolute.\n *\n * Compares against the root AND its physical realpath. Agents report canonical\n * paths, so a root reached through a symlink (`/var/...` → `/private/var/...` on\n * macOS) would otherwise reject every request — a guard that silently denies\n * everything, which reads as the agent failing rather than the guard misfiring.\n * The same defect was found live in the companion's scope predicate.\n */\nexport function isPathWithin(root: string, candidate: string): boolean {\n if (!isAbsolute(root) || !isAbsolute(candidate)) return false;\n const roots = [root];\n try {\n const physical = realpathSync.native(root);\n if (physical !== root) roots.push(physical);\n } catch {\n // An unresolvable root stays as given; the containment check below still applies.\n }\n const resolved = resolve(candidate);\n return roots.some((candidateRoot) => {\n const rel = relative(candidateRoot, resolved);\n return rel !== '..' && !rel.startsWith(`..${sep}`) && !isAbsolute(rel);\n });\n}\n\n/**\n * Resolve an existing write target, or the nearest existing parent of a new one.\n * Resolving only cwd leaves a symlink inside the admitted tree free to point outside it.\n * A dangling symlink is an existing filesystem object, not a missing directory to create;\n * refuse it instead of appending an unresolved alias to an otherwise checked parent.\n * The caller validates and writes this physical path. This is a callback boundary,\n * not an operating-system sandbox against concurrent filesystem replacement.\n */\nfunction resolvePhysicalWritePath(path: string): string {\n let ancestor = resolve(path);\n const missing: string[] = [];\n for (;;) {\n try {\n return resolve(realpathSync.native(ancestor), ...missing.slice().reverse());\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n if (lstatSync(ancestor, { throwIfNoEntry: false }) !== undefined) throw error;\n const parent = dirname(ancestor);\n if (parent === ancestor) throw error;\n missing.push(basename(ancestor));\n ancestor = parent;\n }\n }\n}\n\n/**\n * Open a live ACP session and return a handle whose `promptTurn` drives one\n * turn at a time.\n *\n * The caller owns the turn cadence — this is the whole point of the handle. A\n * turn that ends with a question is not the end of the session; the caller\n * inspects it and may `promptTurn` again with the answer.\n */\nexport async function startACPAgentSession(options: ACPStartSessionOptions): Promise<ACPAgentSession> {\n const maxRecordedEventBytes = options.maxRecordedEventBytes ?? DEFAULT_MAX_RECORDED_EVENT_BYTES;\n const child: ChildProcessWithoutNullStreams = spawn(options.command, [...(options.args ?? [])], {\n cwd: options.cwd,\n env: options.env,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n // Cumulative session state. Per-turn slices are taken from these by index.\n const session = {\n nextId: 1,\n buffer: '',\n stderrTail: '',\n unparsedStdoutTail: '',\n events: [] as ACPSessionEvent[],\n recordedBytes: 0,\n eventsTruncated: false,\n reportedFileLocations: [] as string[],\n /** Each tool call's kind by id, for the updates that omit it (#1805). */\n toolCallKinds: new Map<string, string>(),\n permissionDecisions: [] as ACPPermissionDecisionRecord[],\n deniedPermissionCount: 0,\n // Reset at the start of each turn.\n turnFinalMessage: '',\n turnLastUsageUpdate: undefined as unknown,\n // The question the agent asked during this turn through `elicitation/create` (#3710); the first one wins.\n turnExplicitQuestion: undefined as string | undefined,\n // Cancels the turn in flight; set while a `promptTurn` runs, so a request handler can end the turn.\n cancelActiveTurn: undefined as (() => void) | undefined,\n // NOT reset per turn: ACP's cost is the session's cumulative total, and an update that omits it\n // (rate-limit, compaction) does not mean the session cost nothing (see `readUsageUpdateCost`).\n sessionLastReportedCost: undefined as { readonly amount: number; readonly currency: string } | undefined,\n // True while `session/load` replay is streaming: replayed history is\n // consumed and discarded (it is already on the durable record).\n replaying: false,\n // Set once the child exits; a later `promptTurn` refuses rather than hanging.\n childExited: false,\n // Set BEFORE a deliberate terminate() so the exit handler does not reject\n // the exit promise for a shutdown the caller asked for.\n closed: false,\n };\n const pending = new Map<number, { resolve: (value: unknown) => void; reject: (error: unknown) => void }>();\n\n const write = (payload: unknown): void => {\n if (child.stdin.writable) child.stdin.write(`${JSON.stringify(payload)}\\n`);\n };\n const request = (method: string, params: unknown): Promise<unknown> => {\n const id = session.nextId++;\n return new Promise<unknown>((resolvePromise, rejectPromise) => {\n pending.set(id, { resolve: resolvePromise, reject: rejectPromise });\n write({ jsonrpc: '2.0', id, method, params });\n });\n };\n const respond = (id: number, result: unknown): void => write({ jsonrpc: '2.0', id, result });\n const respondError = (id: number, message: string): void =>\n write({ jsonrpc: '2.0', id, error: { code: -32603, message } });\n\n const recordEvent = (event: ACPSessionEvent): void => {\n // Replayed `session/load` history is neither persisted nor forwarded: it is\n // already recorded from the run that produced it, and re-emitting it would\n // double every earlier frame on the resuming run's record.\n if (session.replaying) return;\n if (!session.eventsTruncated) {\n const size = JSON.stringify(event).length;\n if (session.recordedBytes + size > maxRecordedEventBytes) {\n // Truncate, never reject. Losing the tail of a transcript is a reporting\n // loss; failing the run here would discard work already written to the\n // workspace, which is the mistake the transport this replaces made.\n session.eventsTruncated = true;\n } else {\n session.recordedBytes += size;\n session.events.push(event);\n }\n }\n try {\n options.onEvent?.(event);\n } catch {\n // A progress sink must never be able to fail the run it observes.\n }\n };\n\n // assurance-control: WILDO.SOFTWARE.AI_PRODUCED_CHANGE_CONTROL — the host answers every permission request: the ceiling first, then the task's write and read scope, which refuse a declared location even under an unrestricted ceiling.\n const decidePermission = (params: Record<string, unknown>): { allowed: boolean; optionId?: string } => {\n const toolCall = isRecord(params.toolCall) ? params.toolCall : {};\n const toolKind = typeof toolCall.kind === 'string' ? toolCall.kind : undefined;\n const locations = Array.isArray(toolCall.locations)\n ? toolCall.locations.flatMap((entry) => (isRecord(entry) && typeof entry.path === 'string' ? [entry.path] : []))\n : [];\n\n const rawOptions = Array.isArray(params.options) ? params.options : [];\n const offeredOptionKinds = rawOptions.flatMap((entry) => (isRecord(entry) && typeof entry.kind === 'string' ? [entry.kind] : []));\n const record = (allowed: boolean, reason: ACPPermissionDecisionReason): void => {\n if (session.permissionDecisions.length >= PERMISSION_DECISION_RECORD_LIMIT) return;\n session.permissionDecisions.push({\n allowed,\n reason,\n ...(toolKind !== undefined ? { toolKind } : {}),\n locations,\n offeredOptionKinds,\n });\n };\n\n const toolCallTitle = typeof toolCall.title === 'string' ? toolCall.title : undefined;\n if (options.admitsHostToolCall?.({ toolCallTitle, toolKind }) === true) {\n const hostToolOnce = rawOptions.find((entry) => isRecord(entry) && entry.kind === 'allow_once');\n if (isRecord(hostToolOnce) && typeof hostToolOnce.optionId === 'string') {\n record(true, ACPPermissionDecisionReason.HOST_TOOL_ADMITTED);\n return { allowed: true, optionId: hostToolOnce.optionId };\n }\n }\n if (!permissionAllowedByCeiling(options.permissionCeiling, toolKind)) {\n record(false, ACPPermissionDecisionReason.CEILING_REFUSED);\n return { allowed: false };\n }\n // The caller's scope predicate can only NARROW. A location the task did not\n // authorise is denied even under an UNRESTRICTED ceiling.\n //\n // But note WHAT IT IS QUANTIFIED OVER: `locations` comes from the request, and `some` over an\n // EMPTY array is `false`, so a request that declares NO locations passes this gate without the\n // predicate being consulted once. That is not an oversight to be closed here — a shell command\n // is unscoped BY NATURE (any derived scope is defeated by `sh -c \"$CMD\"` or a substituted\n // redirect), so the scope holds for DECLARED EDITS and commands are unbounded. It is stated\n // here because this is the line a reader arrives at believing the scope is total, and it is a\n // DIFFERENT hole from an agent whose guards never fire at all — see the `UNRESTRICTED` member\n // of `AgentClientProtocol_PermissionCeiling`, which carries the full reasoning.\n if (options.isPermittedLocation && locations.some((path) => !options.isPermittedLocation!(path))) {\n record(false, ACPPermissionDecisionReason.LOCATION_OUT_OF_SCOPE);\n return { allowed: false };\n }\n if (toolKind !== undefined && NON_MUTATING_TOOL_KINDS.has(toolKind)\n && options.isPermittedReadLocation && locations.some((path) => {\n try {\n // Declared read locations refer to existing files/directories. Resolve links\n // before applying host scope, so a permitted alias cannot expose a private target.\n return !isAbsolute(path) || !options.isPermittedReadLocation!(realpathSync.native(path));\n } catch {\n return true;\n }\n })) {\n record(false, ACPPermissionDecisionReason.LOCATION_OUT_OF_SCOPE);\n return { allowed: false };\n }\n // `allow_always` is never selected. Measured against Claude's adapter, that\n // option carries a `_meta` permission change that switches the SESSION into\n // an auto-accepting mode — so answering one request with it silently raises\n // the ceiling for every request after it.\n const once = rawOptions.find((entry) => isRecord(entry) && entry.kind === 'allow_once');\n if (isRecord(once) && typeof once.optionId === 'string') {\n record(true, ACPPermissionDecisionReason.ALLOWED_ONCE);\n return { allowed: true, optionId: once.optionId };\n }\n record(false, ACPPermissionDecisionReason.NO_SELECTABLE_OPTION);\n return { allowed: false };\n };\n\n const handleAgentRequest = async (id: number, method: string, params: Record<string, unknown>): Promise<void> => {\n switch (method) {\n case 'session/request_permission': {\n const decision = decidePermission(params);\n if (decision.allowed && decision.optionId) {\n respond(id, { outcome: { outcome: 'selected', optionId: decision.optionId } });\n return;\n }\n session.deniedPermissionCount++;\n const rawOptions = Array.isArray(params.options) ? params.options : [];\n const reject = rawOptions.find((entry) => isRecord(entry) && entry.kind === 'reject_once');\n if (isRecord(reject) && typeof reject.optionId === 'string') {\n respond(id, { outcome: { outcome: 'selected', optionId: reject.optionId } });\n } else {\n // No refusal option offered: cancelling the request is the only\n // remaining way to say no, and saying no is required.\n respond(id, { outcome: { outcome: 'cancelled' } });\n }\n return;\n }\n // assurance-control: WILDO.SOFTWARE.AI_PRODUCED_CHANGE_CONTROL — a client file read stays inside the session directory and the task's read scope, judged by the file's physical target.\n case 'fs/read_text_file': {\n const path = typeof params.path === 'string' ? params.path : '';\n if (!isPathWithin(options.cwd, path)) {\n respondError(id, 'Path is outside the session working directory');\n return;\n }\n let readPath: string;\n try {\n readPath = realpathSync.native(path);\n } catch (error) {\n respondError(id, `Unable to read file: ${(error as Error).message}`);\n return;\n }\n // Read the resolved name we checked, rather than following the original symlink again.\n // This is host callback containment, not an OS sandbox for the agent's own I/O.\n if (!isPathWithin(options.cwd, readPath)\n || (options.isPermittedReadLocation && !options.isPermittedReadLocation(readPath))) {\n session.deniedPermissionCount++;\n if (session.permissionDecisions.length < PERMISSION_DECISION_RECORD_LIMIT) {\n session.permissionDecisions.push({\n allowed: false,\n reason: ACPPermissionDecisionReason.LOCATION_OUT_OF_SCOPE,\n toolKind: 'read',\n locations: [path],\n offeredOptionKinds: [],\n });\n }\n respondError(id, 'Path is outside the task read scope');\n return;\n }\n try {\n respond(id, { content: await readFile(readPath, 'utf8') });\n } catch (error) {\n respondError(id, `Unable to read file: ${(error as Error).message}`);\n }\n return;\n }\n // assurance-control: WILDO.SOFTWARE.AI_PRODUCED_CHANGE_CONTROL — a client file write is refused by the edit ceiling and by the task's write scope before any byte is written.\n case 'fs/write_text_file': {\n const path = typeof params.path === 'string' ? params.path : '';\n // A client callback performs the mutation itself: an adapter need not send a\n // preceding request_permission. Enforce the same edit ceiling at this boundary,\n // even when the adapter ignores the advertised writeTextFile capability.\n if (!permissionAllowedByCeiling(options.permissionCeiling, 'edit')) {\n session.deniedPermissionCount++;\n if (session.permissionDecisions.length < PERMISSION_DECISION_RECORD_LIMIT) {\n session.permissionDecisions.push({\n allowed: false,\n reason: ACPPermissionDecisionReason.CEILING_REFUSED,\n toolKind: 'edit',\n locations: [path],\n offeredOptionKinds: [],\n });\n }\n respondError(id, 'File write refused by the session permission ceiling');\n return;\n }\n if (!isPathWithin(options.cwd, path)) {\n respondError(id, 'Path is outside the session working directory');\n return;\n }\n let writePath: string | undefined;\n try {\n writePath = resolvePhysicalWritePath(path);\n } catch {\n // An unresolved existing alias cannot establish a permitted write target.\n }\n // A configured cwd may itself be an alias (macOS /var -> /private/var).\n // Preserve predicates authored against either spelling, after physical\n // containment is established. Both spellings identify the checked target;\n // an alias into another subtree is mapped to that actual subtree.\n const inWorkingDirectory = writePath !== undefined && isPathWithin(options.cwd, writePath);\n const configuredWritePath = inWorkingDirectory\n ? resolve(options.cwd, relative(realpathSync.native(options.cwd), writePath))\n : undefined;\n if (!inWorkingDirectory || writePath === undefined\n || (options.isPermittedLocation && !options.isPermittedLocation(writePath)\n && (configuredWritePath === undefined || configuredWritePath === writePath || !options.isPermittedLocation(configuredWritePath)))) {\n session.deniedPermissionCount++;\n if (session.permissionDecisions.length < PERMISSION_DECISION_RECORD_LIMIT) {\n session.permissionDecisions.push({\n allowed: false, reason: ACPPermissionDecisionReason.LOCATION_OUT_OF_SCOPE,\n toolKind: 'edit', locations: [path], offeredOptionKinds: [],\n });\n }\n respondError(id, 'Path is outside the task mutation scope or cannot be resolved safely');\n return;\n }\n try {\n await mkdir(dirname(writePath), { recursive: true });\n await writeFile(writePath, typeof params.content === 'string' ? params.content : '', 'utf8');\n respond(id, null);\n } catch (error) {\n respondError(id, `Unable to write file: ${(error as Error).message}`);\n }\n return;\n }\n case 'elicitation/create': {\n /*\n * The agent ASKS (#3710). Only a form, only in a turn, only when the caller can park: anything else is\n * declined, which the agent reads as the person choosing not to answer, never as an answer.\n */\n const cancelTurn = session.cancelActiveTurn;\n if (options.acceptsExplicitQuestions !== true || params.mode !== 'form' || cancelTurn === undefined) {\n respond(id, { action: 'decline' });\n return;\n }\n session.turnExplicitQuestion ??= renderElicitationQuestion(params);\n // `cancel`, not `decline`: nobody saw the form. The turn is then cancelled, and the answer arrives as the next prompt.\n respond(id, { action: 'cancel' });\n cancelTurn();\n return;\n }\n default:\n // Deliberately including every `terminal/*` method: this runner does NOT\n // advertise the terminal capability, so an agent calling one has ignored\n // the negotiated capability set. Refusing names that plainly.\n respondError(id, `Unsupported client method: ${method}`);\n }\n };\n\n const onLine = (line: string): void => {\n let message: unknown;\n try {\n message = JSON.parse(line);\n } catch {\n /*\n * Non-JSON stdout is the agent's own logging — and it IS our concern when the turn fails.\n *\n * This used to `return` with the comment \"not our concern\", and that is how an agent could\n * exit with code 0 in the middle of a turn while the only thing we could report was \"Agent\n * process exited before the turn completed\". A process that exits SUCCESSFULLY has almost\n * always said why, and a CLI says it in prose — which by definition does not parse as JSON-RPC\n * and so landed exactly here, in a discard.\n *\n * Kept in a bounded tail, mirroring `stderrTail`, and surfaced only on failure. The protocol\n * frames are excluded by construction: they parse, so they never reach this branch, and the\n * tail cannot fill with the session's own traffic.\n */\n session.unparsedStdoutTail = `${session.unparsedStdoutTail}${line}\\n`.slice(-4_000);\n return;\n }\n if (!isRecord(message)) return;\n\n if (message.method === 'session/update') {\n const update = isRecord(message.params) && isRecord(message.params.update) ? message.params.update : {};\n const kind = typeof update.sessionUpdate === 'string' ? update.sessionUpdate : 'unknown';\n if (!session.replaying) {\n if (kind === 'agent_message_chunk') {\n const content = isRecord(update.content) ? update.content : {};\n if (typeof content.text === 'string') session.turnFinalMessage += content.text;\n }\n if (kind === 'usage_update') {\n session.turnLastUsageUpdate = update;\n session.sessionLastReportedCost = latestCumulativeCost(session.sessionLastReportedCost, readUsageUpdateCost(update));\n }\n if (kind === 'tool_call' || kind === 'tool_call_update') {\n /*\n * A WRITE location only (#1805 review R2). ACP gives every tool call a kind, and an adapter reports\n * locations for reads and searches too (the pinned Claude adapter sets them on `Read`, `Grep` and\n * `Glob`), so a run that only read a sibling's file claimed it. An update may omit the kind, so it is\n * remembered by the call's id from the `tool_call` that opened it.\n */\n // The one rule, shared with the companion's on-disk claims (#3205): `writtenLocationsOfAcpSessionUpdate`.\n for (const location of writtenLocationsOfAcpSessionUpdate(kind, update, session.toolCallKinds)) {\n if (!session.reportedFileLocations.includes(location)) session.reportedFileLocations.push(location);\n }\n }\n }\n recordEvent({ kind, payload: update });\n return;\n }\n\n if (typeof message.method === 'string' && typeof message.id === 'number') {\n void handleAgentRequest(message.id, message.method, isRecord(message.params) ? message.params : {});\n return;\n }\n\n if (typeof message.id === 'number' && pending.has(message.id)) {\n const waiter = pending.get(message.id)!;\n pending.delete(message.id);\n if (message.error !== undefined) {\n /*\n * A JSON-RPC error is an OBJECT ({code, message, data?}), and rejecting with it raw is how a\n * real adapter answer became \"[object Object]\" at the choreography seam and \"Unknown agent\n * invocation error\" in the trace — three layers each normalizing for Error-or-string and\n * discarding everything else. The adapter names its failures; carry the name. (Found\n * 2026-09-03: a research turn's session/prompt error cost a full diagnosis cycle because all\n * that survived was the coercion.)\n */\n const rpcError = message.error as { code?: unknown; message?: unknown; data?: unknown };\n const detail = typeof rpcError?.message === 'string' ? rpcError.message : JSON.stringify(message.error)?.slice(0, 500);\n const rejection = new Error(`ACP agent error${typeof rpcError?.code === 'number' ? ` ${rpcError.code}` : ''}: ${detail}`);\n (rejection as Error & { acpError?: unknown }).acpError = message.error;\n waiter.reject(rejection);\n } else waiter.resolve(message.result);\n }\n };\n\n child.stdout.setEncoding('utf8');\n child.stdout.on('data', (chunk: string) => {\n session.buffer += chunk;\n let index: number;\n while ((index = session.buffer.indexOf('\\n')) >= 0) {\n const line = session.buffer.slice(0, index).trim();\n session.buffer = session.buffer.slice(index + 1);\n if (line) onLine(line);\n }\n });\n child.stderr.setEncoding('utf8');\n child.stderr.on('data', (chunk: string) => {\n session.stderrTail = `${session.stderrTail}${chunk}`.slice(-4_000);\n });\n\n const terminate = (): void => {\n // Mark the shutdown as deliberate BEFORE killing so the exit handler does\n // not reject the exit promise for a close the caller asked for.\n session.closed = true;\n if (!child.killed) child.kill('SIGTERM');\n setTimeout(() => {\n if (!child.killed) child.kill('SIGKILL');\n }, TERMINATION_SETTLE_GRACE_MS).unref?.();\n };\n\n const failed = (message: string, details: Record<string, unknown>): ACPSessionRunnerError =>\n new ACPSessionRunnerError(message, {\n ...details,\n stderrTail: session.stderrTail.trim().slice(-1_000),\n stdoutTail: session.unparsedStdoutTail.trim().slice(-1_000),\n });\n\n // ONE persistent \"the child died\" promise, raced against every awaited\n // request. It rejects at most once, only for an UNDELIBERATE exit — a close()\n // the caller asked for sets `closed` first and leaves it pending. Raced at\n // `initialize`, so it always carries a rejection handler and a later reject\n // (e.g. a crash between turns) never surfaces as an unhandled rejection.\n const exitPromise = new Promise<never>((_, rejectPromise) => {\n child.on('error', (error) => {\n session.childExited = true;\n if (!session.closed) rejectPromise(failed(`Agent process failed to start: ${error.message}`, {}));\n });\n child.on('exit', (code, signal) => {\n session.childExited = true;\n if (!session.closed) rejectPromise(failed('Agent process exited before the turn completed', { exitCode: code, signal }));\n });\n });\n\n try {\n // --- initialize ---------------------------------------------------------\n const initializeResult = await Promise.race([\n request('initialize', {\n protocolVersion: Math.max(...options.supportedProtocolVersions),\n clientCapabilities: {\n // `fs` is implemented above and confined to the session directory.\n fs: { readTextFile: true, writeTextFile: permissionAllowedByCeiling(options.permissionCeiling, 'edit') },\n // `terminal` is NOT advertised. An agent that wants to run a command\n // runs it itself — measured, that is what the default agent does even\n // when the capability IS offered — so advertising it would add an\n // unexercised execution surface for no observed gain.\n terminal: false,\n // Form elicitation is how an agent ASKS (#3710); offered only to a caller that can park a question.\n ...(options.acceptsExplicitQuestions === true ? { elicitation: { form: {} } } : {}),\n },\n }),\n exitPromise,\n ]);\n if (!isRecord(initializeResult)) {\n throw failed('Agent returned a malformed initialize result', { initializeResult });\n }\n const negotiatedProtocolVersion = initializeResult.protocolVersion;\n if (typeof negotiatedProtocolVersion !== 'number' || !options.supportedProtocolVersions.includes(negotiatedProtocolVersion)) {\n // Refused rather than attempted. A version we do not implement is not a\n // version we can hold to a permission ceiling.\n throw failed('Agent negotiated an unsupported ACP protocol version', {\n negotiatedProtocolVersion,\n supportedProtocolVersions: [...options.supportedProtocolVersions],\n });\n }\n const agentInfo = isRecord(initializeResult.agentInfo) ? initializeResult.agentInfo : {};\n const agentCapabilities = isRecord(initializeResult.agentCapabilities) ? initializeResult.agentCapabilities : {};\n const loadSessionSupported = agentCapabilities.loadSession === true;\n // An HTTP MCP server is optional for an agent (#3472). Refused rather than passed to an agent that would drop it:\n // a session whose only way to return its result is missing would run, spend, and answer nothing.\n if ((options.mcpServers ?? []).some((server) => server.type === 'http')) {\n const mcpCapabilities = isRecord(agentCapabilities.mcpCapabilities) ? agentCapabilities.mcpCapabilities : {};\n if (mcpCapabilities.http !== true) {\n throw failed('Agent does not advertise mcpCapabilities.http; the host-served MCP server cannot reach it', {\n mcpServers: (options.mcpServers ?? []).map((server) => server.name),\n });\n }\n }\n\n let sessionId: string;\n let sessionModeId: string | undefined;\n\n if (options.resumeSessionId !== undefined) {\n // --- session/load (resume) -------------------------------------------\n if (!loadSessionSupported) {\n // Refused, not degraded. Starting a fresh session here would present a\n // context-less turn as a continuation of a parked one.\n throw failed('Agent does not advertise the loadSession capability; cannot resume the session', {\n resumeSessionId: options.resumeSessionId,\n });\n }\n session.replaying = true;\n await Promise.race([\n request('session/load', {\n sessionId: options.resumeSessionId,\n cwd: options.cwd,\n mcpServers: [...(options.mcpServers ?? [])],\n }),\n exitPromise,\n ]);\n session.replaying = false;\n sessionId = options.resumeSessionId;\n // Modes are reported by session/new, not session/load. The permission\n // handler is the guarantee regardless, so a resumed session simply runs\n // without a reselected mode.\n } else {\n // --- session/new ------------------------------------------------------\n const sessionResult = await Promise.race([\n request('session/new', {\n cwd: options.cwd,\n mcpServers: [...(options.mcpServers ?? [])],\n ...(options.sessionMetaExtensions ? { _meta: options.sessionMetaExtensions } : {}),\n }),\n exitPromise,\n ]);\n if (!isRecord(sessionResult) || typeof sessionResult.sessionId !== 'string') {\n throw failed('Agent returned a malformed session/new result', { sessionResult });\n }\n sessionId = sessionResult.sessionId;\n\n // --- best-effort mode selection (an optimisation, never the guarantee) -\n const modes = isRecord(sessionResult.modes) ? sessionResult.modes : undefined;\n const available = modes && Array.isArray(modes.availableModes) ? modes.availableModes : [];\n const preferred = options.preferredSessionModeIds ?? [];\n const match = available.find((entry) => isRecord(entry) && typeof entry.id === 'string' && preferred.includes(entry.id));\n if (isRecord(match) && typeof match.id === 'string') {\n try {\n // Raced against the death signal: before this, a `session/set_mode` sent\n // to an agent that then died left a promise nobody would ever settle,\n // with the turn timeout not yet armed — the run hung forever.\n await Promise.race([request('session/set_mode', { sessionId, modeId: match.id }), exitPromise]);\n sessionModeId = match.id;\n } catch {\n // The ceiling is still enforced by the permission handler, so a mode we\n // could not set costs round-trips, not safety.\n sessionModeId = undefined;\n }\n } else if (typeof modes?.currentModeId === 'string') {\n sessionModeId = modes.currentModeId;\n }\n }\n\n // --- model delivery, when the agent takes it over ACP -------------------\n //\n // Unlike the mode selection above, this is NOT best-effort. A model that\n // could not be set means the agent runs its own default while the run\n // records the model that was requested — a false result rather than a\n // degraded one, which is precisely the failure the provider-declared\n // delivery channel exists to end. So a rejection fails the session before\n // any prompt is sent, i.e. before the agent has touched the workspace.\n if (options.modelSelection) {\n const setModelResult = await Promise.race([\n request('session/set_config_option', {\n sessionId,\n configId: options.modelSelection.configId,\n value: options.modelSelection.model,\n }),\n exitPromise,\n ]).catch((error: unknown) => {\n throw failed(\n `Agent refused the model selection: ${describeCaughtError(error)}`,\n { configId: options.modelSelection?.configId, model: options.modelSelection?.model },\n );\n });\n void setModelResult;\n }\n\n const promptTurn = async (prompt: string, turnOptions?: ACPPromptTurnOptions): Promise<ACPTurnResult> => {\n if (session.childExited) {\n throw failed('Agent process is no longer running; cannot start a turn', { sessionId });\n }\n\n // Per-turn slices are the cumulative arrays from this point on.\n const eventStart = session.events.length;\n const permissionStart = session.permissionDecisions.length;\n const deniedStart = session.deniedPermissionCount;\n const fileLocStart = session.reportedFileLocations.length;\n session.turnFinalMessage = '';\n session.turnLastUsageUpdate = undefined;\n session.turnExplicitQuestion = undefined;\n\n let settled = false;\n let timedOut = false;\n let timer: NodeJS.Timeout | undefined;\n const cancelTurn = (): void => {\n write({ jsonrpc: '2.0', method: 'session/cancel', params: { sessionId } });\n setTimeout(() => {\n if (!settled) terminate();\n }, COOPERATIVE_CANCEL_GRACE_MS).unref?.();\n };\n const onAbort = (): void => cancelTurn();\n session.cancelActiveTurn = cancelTurn;\n\n const turnPromise = request('session/prompt', {\n sessionId,\n prompt: [{ type: 'text', text: prompt }],\n });\n if (turnOptions?.turnTimeoutMs !== undefined) {\n timer = setTimeout(() => {\n timedOut = true;\n // Cooperative first: ACP requires the agent to answer a cancelled turn\n // with stop reason `cancelled`, which lets the caller distinguish an\n // interrupted run from a completed one. Kill only if it does not.\n cancelTurn();\n }, turnOptions.turnTimeoutMs);\n timer.unref?.();\n }\n if (turnOptions?.abortSignal) {\n if (turnOptions.abortSignal.aborted) cancelTurn();\n else turnOptions.abortSignal.addEventListener('abort', onAbort, { once: true });\n }\n\n try {\n const turnResult = await Promise.race([turnPromise, exitPromise]);\n settled = true;\n if (!isRecord(turnResult)) {\n throw failed('Agent returned a malformed session/prompt result', { turnResult, timedOut });\n }\n const { stopReason, rawStopReason } = parseStopReason(turnResult.stopReason);\n return {\n finalMessage: session.turnFinalMessage,\n stopReason,\n ...(rawStopReason ? { rawStopReason } : {}),\n usage: projectUsage(turnResult.usage, session.turnLastUsageUpdate, session.sessionLastReportedCost),\n reportedFileLocations: session.reportedFileLocations.slice(fileLocStart),\n events: session.events.slice(eventStart),\n eventsTruncated: session.eventsTruncated,\n deniedPermissionCount: session.deniedPermissionCount - deniedStart,\n permissionDecisions: session.permissionDecisions.slice(permissionStart),\n ...(session.turnExplicitQuestion !== undefined ? { explicitQuestion: session.turnExplicitQuestion } : {}),\n };\n } finally {\n settled = true;\n session.cancelActiveTurn = undefined;\n if (timer) clearTimeout(timer);\n turnOptions?.abortSignal?.removeEventListener('abort', onAbort);\n }\n };\n\n return {\n sessionId,\n negotiatedProtocolVersion,\n ...(typeof agentInfo.name === 'string' ? { agentName: agentInfo.name } : {}),\n ...(typeof agentInfo.version === 'string' ? { agentVersion: agentInfo.version } : {}),\n ...(sessionModeId ? { sessionModeId } : {}),\n capabilities: { loadSession: loadSessionSupported },\n promptTurn,\n close: terminate,\n };\n } catch (error) {\n // Setup failed: the child must not be left running.\n terminate();\n throw error;\n }\n}\n\n/**\n * Drive exactly one coding turn end to end: open a session, send one prompt,\n * settle, and close.\n *\n * The compatibility surface for every caller that does not need the turn\n * cadence. It is a thin composition of {@link startACPAgentSession} +\n * `promptTurn` + `close`, so its behaviour tracks the handle by construction.\n */\nexport async function runACPCodingSession(options: ACPCodingSessionOptions): Promise<ACPCodingSessionResult> {\n const agentSession = await startACPAgentSession(options);\n try {\n const turn = await agentSession.promptTurn(options.prompt, {\n ...(options.turnTimeoutMs !== undefined ? { turnTimeoutMs: options.turnTimeoutMs } : {}),\n ...(options.abortSignal ? { abortSignal: options.abortSignal } : {}),\n });\n return {\n finalMessage: turn.finalMessage,\n stopReason: turn.stopReason,\n ...(turn.rawStopReason ? { rawStopReason: turn.rawStopReason } : {}),\n usage: turn.usage,\n reportedFileLocations: turn.reportedFileLocations,\n sessionId: agentSession.sessionId,\n negotiatedProtocolVersion: agentSession.negotiatedProtocolVersion,\n ...(agentSession.agentName ? { agentName: agentSession.agentName } : {}),\n ...(agentSession.agentVersion ? { agentVersion: agentSession.agentVersion } : {}),\n ...(agentSession.sessionModeId ? { sessionModeId: agentSession.sessionModeId } : {}),\n events: turn.events,\n eventsTruncated: turn.eventsTruncated,\n deniedPermissionCount: turn.deniedPermissionCount,\n permissionDecisions: turn.permissionDecisions,\n };\n } finally {\n agentSession.close();\n }\n}\n\n/**\n * The text of a form elicitation (#3710): its `message`, then one line per field the form asks, with the choices it\n * offers. What a person reads in place of the form, and what an answer is written against.\n *\n * Generic over ACP's `ElicitationSchema` (primitive properties; a single choice as `enum` or titled `oneOf`, a multiple\n * choice as an array whose `items` carry `enum` or titled `anyOf`), never over one agent's form.\n *\n * spec-cite: ACP schema (`@agentclientprotocol/sdk` 1.5.0) — `CreateElicitationRequest` (`message`, `mode: \"form\"`,\n * `requestedSchema: ElicitationSchema`) and `CreateElicitationResponse` (`accept` / `decline` / `cancel`).\n */\nexport function renderElicitationQuestion(params: Record<string, unknown>): string {\n const message = typeof params.message === 'string' && params.message.trim().length > 0 ? params.message.trim() : 'The agent asked a question.';\n const schema = isRecord(params.requestedSchema) ? params.requestedSchema : {};\n const properties = isRecord(schema.properties) ? schema.properties : {};\n const choicesOf = (property: Record<string, unknown>): string[] => {\n const source = isRecord(property.items) ? property.items : property;\n const titled = Array.isArray(source.oneOf) ? source.oneOf : Array.isArray(source.anyOf) ? source.anyOf : [];\n const fromTitled = titled\n .filter(isRecord)\n .map((option) => (typeof option.title === 'string' ? option.title : typeof option.const === 'string' ? option.const : undefined))\n .filter((value): value is string => value !== undefined);\n const fromEnum = Array.isArray(source.enum) ? source.enum.filter((value): value is string => typeof value === 'string') : [];\n return fromTitled.length > 0 ? fromTitled : fromEnum;\n };\n const lines = Object.values(properties).filter(isRecord).map((property) => {\n const label = [property.title, property.description].filter((part): part is string => typeof part === 'string' && part.trim().length > 0).join(': ');\n const choices = choicesOf(property);\n const many = property.type === 'array';\n return `- ${label || 'answer'}${choices.length > 0 ? ` (${many ? 'any of' : 'one of'}: ${choices.join(' | ')})` : ''}`;\n });\n return lines.length > 0 ? `${message}\\n${lines.join('\\n')}` : message;\n}\n\n/** Re-exported so callers reason about ceilings through one ordering definition. */\nexport { agentClientProtocolPermissionCeilingRank };\n"]}