eve 0.78.0 → 0.79.1

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 (397) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/src/approval/definition.d.ts +42 -0
  3. package/dist/src/chunks/{use-eve-agent-BSYe_Re7.js → use-eve-agent-Ch-Q-s12.js} +43 -13
  4. package/dist/src/chunks/{use-eve-agent-B8brxCk-.js → use-eve-agent-Vsl-S0yI.js} +43 -13
  5. package/dist/src/cli/commands/trace-detail.d.ts +2 -2
  6. package/dist/src/cli/commands/trace-detail.js +1 -1
  7. package/dist/src/cli/commands/trace.d.ts +1 -1
  8. package/dist/src/cli/commands/trace.js +1 -1
  9. package/dist/src/cli/dev/tui/traces/trace-conversation.d.ts +1 -1
  10. package/dist/src/cli/dev/tui/traces/trace-conversation.js +1 -1
  11. package/dist/src/cli/dev/tui/traces/trace-store.d.ts +1 -1
  12. package/dist/src/cli/dev/tui/traces/trace-store.js +1 -1
  13. package/dist/src/cli/dev/tui/traces/trace-view.d.ts +1 -1
  14. package/dist/src/cli/dev/tui/traces/trace-view.js +1 -1
  15. package/dist/src/cli/dev/tui/traces/trace-viewer-state.d.ts +1 -1
  16. package/dist/src/client/abort-signal.d.ts +2 -0
  17. package/dist/src/client/abort-signal.js +1 -0
  18. package/dist/src/client/conversation-client.d.ts +2 -0
  19. package/dist/src/client/conversation-client.js +1 -1
  20. package/dist/src/client/eve-agent-store-state.d.ts +9 -0
  21. package/dist/src/client/eve-agent-store.js +1 -1
  22. package/dist/src/client/ndjson.js +1 -1
  23. package/dist/src/client/open-stream.js +1 -1
  24. package/dist/src/client/session-turn-dispatch.js +1 -1
  25. package/dist/src/client/session-utils.js +1 -1
  26. package/dist/src/client/session.js +1 -1
  27. package/dist/src/compiled/.vendor-stamp.json +3 -1
  28. package/dist/src/compiled/@eve/tracing/adapters/agent-transport.d.ts +8 -0
  29. package/dist/src/compiled/@eve/tracing/adapters/ai-sdk-payload.d.ts +15 -0
  30. package/dist/src/compiled/@eve/tracing/adapters/ai-sdk-telemetry.d.ts +14 -0
  31. package/dist/src/{tracing/agent-span-id-generator.d.ts → compiled/@eve/tracing/adapters/otel-ids.d.ts} +1 -1
  32. package/dist/src/compiled/@eve/tracing/adapters/otel.d.ts +33 -0
  33. package/dist/src/{tracing/agent-otel-content.d.ts → compiled/@eve/tracing/adapters/serialization.d.ts} +9 -3
  34. package/dist/src/compiled/@eve/tracing/agent-tracing.d.ts +84 -0
  35. package/dist/src/compiled/@eve/tracing/ai-sdk.d.ts +7 -0
  36. package/dist/src/compiled/@eve/tracing/ai-sdk.js +1 -0
  37. package/dist/src/compiled/@eve/tracing/capture.d.ts +5 -0
  38. package/dist/src/compiled/@eve/tracing/core/activation.d.ts +3 -0
  39. package/dist/src/compiled/@eve/tracing/core/attributes.d.ts +14 -0
  40. package/dist/src/{tracing/content-attributes.d.ts → compiled/@eve/tracing/core/content-policy.d.ts} +1 -1
  41. package/dist/src/compiled/@eve/tracing/core/context.d.ts +3 -0
  42. package/dist/src/compiled/@eve/tracing/core/delegation.d.ts +13 -0
  43. package/dist/src/compiled/@eve/tracing/core/mcp.d.ts +24 -0
  44. package/dist/src/compiled/@eve/tracing/core/scopes.d.ts +59 -0
  45. package/dist/src/compiled/@eve/tracing/core/snapshot.d.ts +7 -0
  46. package/dist/src/compiled/@eve/tracing/core/span-kinds.d.ts +12 -0
  47. package/dist/src/compiled/@eve/tracing/core/types.d.ts +297 -0
  48. package/dist/src/compiled/@eve/tracing/core/writer.d.ts +15 -0
  49. package/dist/src/compiled/@eve/tracing/delegation.d.ts +2 -0
  50. package/dist/src/compiled/@eve/tracing/delegation.js +1 -0
  51. package/dist/src/compiled/@eve/tracing/index.d.ts +6 -0
  52. package/dist/src/compiled/@eve/tracing/index.js +1 -0
  53. package/dist/src/compiled/@eve/tracing/operations.d.ts +96 -0
  54. package/dist/src/compiled/@eve/tracing/otel.d.ts +12 -0
  55. package/dist/src/compiled/@eve/tracing/otel.js +1 -0
  56. package/dist/src/compiled/@opentelemetry/api/index.d.ts +4 -0
  57. package/dist/src/compiled/@workflow/world-vercel/index.js +7 -7
  58. package/dist/src/compiled/_chunks/workflow/delegation-BqhZ398D.js +1 -0
  59. package/dist/src/compiled/_chunks/workflow/mcp-C01bDEX-.js +5 -0
  60. package/dist/src/compiler/extension-compatibility.d.ts +6 -6
  61. package/dist/src/compiler/extension-compatibility.js +1 -1
  62. package/dist/src/compiler/project-sources.js +1 -1
  63. package/dist/src/context/build-dynamic-tools.js +1 -1
  64. package/dist/src/context/dynamic-tool-lifecycle.js +1 -1
  65. package/dist/src/context/memory-tools.js +1 -1
  66. package/dist/src/evals/assertions/collector.d.ts +4 -1
  67. package/dist/src/evals/assertions/collector.js +1 -1
  68. package/dist/src/evals/context.js +1 -1
  69. package/dist/src/evals/index.d.ts +1 -1
  70. package/dist/src/evals/runner/artifacts.js +1 -1
  71. package/dist/src/evals/runner/reporters/assertion-diagnostics.js +2 -2
  72. package/dist/src/evals/runner/reporters/assertion-scores.d.ts +13 -2
  73. package/dist/src/evals/runner/reporters/assertion-scores.js +1 -1
  74. package/dist/src/evals/runner/reporters/braintrust.js +1 -1
  75. package/dist/src/evals/runner/reporters/console.js +1 -1
  76. package/dist/src/evals/runner/reporters/datadog.js +2 -2
  77. package/dist/src/evals/runner/reporters/junit.js +1 -1
  78. package/dist/src/evals/runner/verdict.d.ts +2 -2
  79. package/dist/src/evals/runner/verdict.js +1 -1
  80. package/dist/src/evals/types.d.ts +22 -6
  81. package/dist/src/eve-channel/index.js +1 -1
  82. package/dist/src/eve-channel/request.js +1 -1
  83. package/dist/src/eve-channel/stream-headers.d.ts +1 -0
  84. package/dist/src/eve-channel/stream-headers.js +1 -0
  85. package/dist/src/execution/agent-sessions/context.d.ts +1 -1
  86. package/dist/src/execution/agent-sessions/context.js +1 -1
  87. package/dist/src/execution/agent-sessions/remote.js +1 -1
  88. package/dist/src/execution/agent-sessions/steps.js +1 -1
  89. package/dist/src/execution/authorization-callback-match.d.ts +2 -2
  90. package/dist/src/execution/authorization-callback-match.js +1 -1
  91. package/dist/src/execution/cancelled-model-call-batch.js +1 -1
  92. package/dist/src/execution/catalog/connection-entry.js +1 -1
  93. package/dist/src/execution/durable-session-store.js +1 -1
  94. package/dist/src/execution/dynamic-workflow/tool.js +1 -1
  95. package/dist/src/execution/eve-workflow-attributes.js +1 -1
  96. package/dist/src/execution/forward-session-input.js +1 -1
  97. package/dist/src/execution/invoke-tool.d.ts +1 -1
  98. package/dist/src/execution/invoke-tool.js +1 -1
  99. package/dist/src/execution/proxied-deliver-step.js +1 -1
  100. package/dist/src/execution/publish-session-events.d.ts +13 -2
  101. package/dist/src/execution/publish-session-events.js +1 -1
  102. package/dist/src/execution/sandbox/bindings/vercel-create-sdk.js +1 -1
  103. package/dist/src/execution/sandbox/bindings/vercel-credentials.d.ts +2 -0
  104. package/dist/src/execution/sandbox/bindings/vercel-credentials.js +1 -1
  105. package/dist/src/execution/sandbox/bindings/vercel-lifecycle.js +1 -1
  106. package/dist/src/execution/sandbox/bindings/vercel-lookup.js +1 -1
  107. package/dist/src/execution/sandbox/bindings/vercel.d.ts +3 -6
  108. package/dist/src/execution/sandbox/bindings/vercel.js +1 -1
  109. package/dist/src/execution/session/checkpoint-migrations.js +1 -1
  110. package/dist/src/execution/session/handoff-steps.js +1 -1
  111. package/dist/src/execution/session/handoff.d.ts +1 -1
  112. package/dist/src/execution/session/handoff.js +1 -1
  113. package/dist/src/execution/session/input-queue.d.ts +13 -6
  114. package/dist/src/execution/session/input-queue.js +1 -1
  115. package/dist/src/execution/session/pending-turn-state.js +1 -1
  116. package/dist/src/execution/session/turn-step.js +1 -1
  117. package/dist/src/execution/session/turn.d.ts +4 -1
  118. package/dist/src/execution/session/turn.js +1 -1
  119. package/dist/src/execution/tasks/steps.d.ts +1 -1
  120. package/dist/src/execution/tasks/steps.js +1 -1
  121. package/dist/src/execution/tool-auth.js +1 -1
  122. package/dist/src/execution/tools/agent-router-workflow.js +1 -1
  123. package/dist/src/execution/tools/workflow/answer.d.ts +1 -1
  124. package/dist/src/execution/tools/workflow/withdraw-step.d.ts +2 -2
  125. package/dist/src/execution/tools/workflow/withdraw-step.js +1 -1
  126. package/dist/src/execution/workflow-callback-url.d.ts +10 -1
  127. package/dist/src/execution/workflow-callback-url.js +1 -1
  128. package/dist/src/execution/workflow-runtime.js +1 -1
  129. package/dist/src/harness/authorization.d.ts +3 -13
  130. package/dist/src/harness/authorization.js +1 -1
  131. package/dist/src/harness/compaction/step.d.ts +1 -0
  132. package/dist/src/harness/compaction/step.js +1 -1
  133. package/dist/src/harness/coordination.js +1 -1
  134. package/dist/src/harness/execute-tool.d.ts +2 -2
  135. package/dist/src/harness/hitl/approvals.d.ts +1 -1
  136. package/dist/src/harness/hitl/approvals.js +1 -1
  137. package/dist/src/harness/hitl/approved-calls.d.ts +3 -0
  138. package/dist/src/harness/hitl/approved-calls.js +1 -1
  139. package/dist/src/harness/hitl/candidates.d.ts +13 -0
  140. package/dist/src/harness/hitl/candidates.js +1 -1
  141. package/dist/src/harness/hitl/coordinator.js +1 -1
  142. package/dist/src/harness/hitl/index.d.ts +2 -5
  143. package/dist/src/harness/hitl/index.js +1 -1
  144. package/dist/src/harness/hitl/intake.js +1 -1
  145. package/dist/src/harness/{proxy-input-requests.d.ts → hitl/relays.d.ts} +3 -39
  146. package/dist/src/harness/hitl/relays.js +1 -0
  147. package/dist/src/harness/hitl/requests.d.ts +64 -0
  148. package/dist/src/harness/hitl/requests.js +1 -0
  149. package/dist/src/harness/hitl/sign-ins.d.ts +9 -0
  150. package/dist/src/harness/hitl/sign-ins.js +1 -0
  151. package/dist/src/harness/inline-tool-authorization.js +1 -1
  152. package/dist/src/harness/input-extraction.js +1 -1
  153. package/dist/src/harness/model-call/call.js +1 -1
  154. package/dist/src/harness/model-call/model.d.ts +3 -1
  155. package/dist/src/harness/model-call/model.js +1 -1
  156. package/dist/src/harness/session-machine/commit.d.ts +14 -3
  157. package/dist/src/harness/session-machine/commit.js +1 -1
  158. package/dist/src/harness/session-machine/transitions.d.ts +16 -0
  159. package/dist/src/harness/session-machine/transitions.js +1 -1
  160. package/dist/src/instrumentation/ai-sdk-hook-bridge.js +1 -1
  161. package/dist/src/instrumentation/dispatch.js +1 -1
  162. package/dist/src/instrumentation/memory.d.ts +1 -4
  163. package/dist/src/instrumentation/memory.js +1 -1
  164. package/dist/src/instrumentation/principal-summary.js +1 -1
  165. package/dist/src/instrumentation/providers.js +1 -1
  166. package/dist/src/instrumentation/runtime-context.d.ts +1 -1
  167. package/dist/src/instrumentation/runtime.d.ts +4 -3
  168. package/dist/src/instrumentation/runtime.js +1 -1
  169. package/dist/src/instrumentation/session-init.js +1 -1
  170. package/dist/src/internal/application/stamped-package-version.js +1 -1
  171. package/dist/src/internal/authored-definition/approval.d.ts +3 -1
  172. package/dist/src/internal/authored-definition/approval.js +1 -1
  173. package/dist/src/internal/authored-definition/schema-backed.js +1 -1
  174. package/dist/src/internal/authored-definition/source-identity.d.ts +6 -0
  175. package/dist/src/internal/authored-definition/source-identity.js +1 -1
  176. package/dist/src/internal/authored-module-map-loader.js +1 -1
  177. package/dist/src/internal/helpers/markdown.js +1 -1
  178. package/dist/src/internal/logging.js +1 -1
  179. package/dist/src/internal/nitro/host/local-tracing-runtime-plugin.js +1 -1
  180. package/dist/src/internal/nitro/routes/channel-dispatch.js +1 -1
  181. package/dist/src/internal/nitro/routes/channel-request-instrumentation.d.ts +10 -31
  182. package/dist/src/internal/nitro/routes/channel-request-instrumentation.js +1 -1
  183. package/dist/src/internal/nitro/routes/route-invoke-tool.d.ts +1 -1
  184. package/dist/src/internal/workflow/is-inactive-workflow-run-error.d.ts +2 -0
  185. package/dist/src/internal/workflow/is-inactive-workflow-run-error.js +1 -1
  186. package/dist/src/internal/workflow-bundle/dynamic-tool-transform.js +1 -1
  187. package/dist/src/protocol/baggage.d.ts +1 -0
  188. package/dist/src/protocol/baggage.js +1 -1
  189. package/dist/src/public/channels/slack/hitl.js +1 -1
  190. package/dist/src/public/definitions/approval.d.ts +1 -1
  191. package/dist/src/public/definitions/connections/mcp.js +1 -1
  192. package/dist/src/public/definitions/connections/openapi.js +1 -1
  193. package/dist/src/public/instrumentation/otel.d.ts +2 -2
  194. package/dist/src/public/instrumentation/otel.js +1 -1
  195. package/dist/src/public/sandbox/vercel.d.ts +2 -0
  196. package/dist/src/public/tools/approval/index.d.ts +1 -1
  197. package/dist/src/public/tools/index.d.ts +1 -1
  198. package/dist/src/public/tools/result.d.ts +10 -7
  199. package/dist/src/react/use-eve-agent.d.ts +6 -0
  200. package/dist/src/react/use-eve-agent.js +1 -1
  201. package/dist/src/runtime/authorization-context.d.ts +5 -0
  202. package/dist/src/runtime/authorization-context.js +1 -1
  203. package/dist/src/runtime/connections/mcp-tracing.d.ts +10 -18
  204. package/dist/src/runtime/connections/mcp-tracing.js +1 -1
  205. package/dist/src/runtime/connections/openapi-operations.js +1 -1
  206. package/dist/src/runtime/connections/scoped-authorization.d.ts +6 -0
  207. package/dist/src/runtime/connections/scoped-authorization.js +1 -1
  208. package/dist/src/runtime/resolve-connection.js +1 -1
  209. package/dist/src/runtime/resolve-tool.js +1 -1
  210. package/dist/src/runtime/types.d.ts +2 -2
  211. package/dist/src/self-modification/extension/subagents/agent/tools/inspect_trace.d.ts +12 -12
  212. package/dist/src/self-modification/extension/subagents/agent/tools/inspect_trace.js +1 -1
  213. package/dist/src/self-modification/extension/subagents/agent/tools/search_traces.d.ts +1 -1
  214. package/dist/src/self-modification/extension/subagents/agent/tools/search_traces.js +1 -1
  215. package/dist/src/self-modification/extension/trace-inspection.d.ts +1 -1
  216. package/dist/src/self-modification/extension/trace-inspection.js +1 -1
  217. package/dist/src/setup/scaffold/create/project.js +1 -1
  218. package/dist/src/setup/scaffold/create/web-template.d.ts +1 -1
  219. package/dist/src/setup/scaffold/create/web-template.js +18 -10
  220. package/dist/src/shared/git.js +1 -1
  221. package/dist/src/shared/instrumentation-content.d.ts +1 -1
  222. package/dist/src/shared/instrumentation-content.js +1 -1
  223. package/dist/src/shared/instrumentation-decision.d.ts +3 -0
  224. package/dist/src/shared/instrumentation-decision.js +1 -1
  225. package/dist/src/shared/skill-package.js +1 -1
  226. package/dist/src/shared/trace-policy.d.ts +3 -0
  227. package/dist/src/shared/trace-policy.js +1 -1
  228. package/dist/src/subagents/adapter.js +1 -1
  229. package/dist/src/subagents/event-proxy-step.d.ts +1 -1
  230. package/dist/src/subagents/event-proxy-step.js +1 -1
  231. package/dist/src/subagents/hitl-proxy.d.ts +1 -1
  232. package/dist/src/subagents/hitl-proxy.js +1 -1
  233. package/dist/src/svelte/index.js +1 -1
  234. package/dist/src/svelte/use-eve-agent.d.ts +6 -0
  235. package/dist/src/svelte/use-eve-agent.js +1 -1
  236. package/dist/src/tools/definition.d.ts +41 -4
  237. package/dist/src/tools/durable-callbacks.d.ts +5 -3
  238. package/dist/src/tools/durable-callbacks.js +1 -1
  239. package/dist/src/tools/dynamic.d.ts +2 -2
  240. package/dist/src/tools/provided/ask-question-workflow.js +1 -1
  241. package/dist/src/tools/provided/sleep-workflow.js +1 -1
  242. package/dist/src/tools/workflow-definition.d.ts +2 -2
  243. package/dist/src/tracing/eve/agent-approval-instrumentation.d.ts +8 -0
  244. package/dist/src/tracing/eve/agent-approval-instrumentation.js +1 -0
  245. package/dist/src/tracing/{agent-channel-delivery-instrumentation.d.ts → eve/agent-channel-delivery-instrumentation.d.ts} +1 -1
  246. package/dist/src/tracing/{agent-channel-delivery-instrumentation.js → eve/agent-channel-delivery-instrumentation.js} +1 -1
  247. package/dist/src/tracing/eve/agent-invocation-coordinator.js +1 -0
  248. package/dist/src/tracing/eve/agent-memory-instrumentation.d.ts +12 -0
  249. package/dist/src/tracing/eve/agent-memory-instrumentation.js +1 -0
  250. package/dist/src/tracing/{agent-otel-provider.d.ts → eve/agent-otel-provider.d.ts} +6 -8
  251. package/dist/src/tracing/eve/agent-otel-provider.js +1 -0
  252. package/dist/src/tracing/eve/agent-tool-instrumentation.d.ts +44 -0
  253. package/dist/src/tracing/eve/agent-tool-instrumentation.js +1 -0
  254. package/dist/src/tracing/{agent-trace-context-store.d.ts → eve/agent-trace-context-store.d.ts} +8 -16
  255. package/dist/src/tracing/eve/agent-trace-context-store.js +1 -0
  256. package/dist/src/tracing/eve/agent-trace-context.js +1 -0
  257. package/dist/src/tracing/eve/agent-trace-state.d.ts +75 -0
  258. package/dist/src/tracing/{batch-span-processor.d.ts → eve/batch-span-processor.d.ts} +5 -1
  259. package/dist/src/tracing/eve/batch-span-processor.js +1 -0
  260. package/dist/src/tracing/{content-span-processor.d.ts → eve/content-span-processor.d.ts} +1 -1
  261. package/dist/src/tracing/eve/content-span-processor.js +1 -0
  262. package/dist/src/tracing/eve/delegation.d.ts +20 -0
  263. package/dist/src/tracing/eve/delegation.js +1 -0
  264. package/dist/src/tracing/eve/gateway.d.ts +17 -0
  265. package/dist/src/tracing/eve/gateway.js +1 -0
  266. package/dist/src/tracing/{install-instrumentation-runtime.d.ts → eve/install-instrumentation-runtime.d.ts} +1 -1
  267. package/dist/src/tracing/eve/install-instrumentation-runtime.js +1 -0
  268. package/dist/src/tracing/eve/invoke-tool-span.js +1 -0
  269. package/dist/src/tracing/eve/mcp.d.ts +29 -0
  270. package/dist/src/tracing/eve/mcp.js +1 -0
  271. package/dist/src/tracing/eve/metadata.d.ts +7 -0
  272. package/dist/src/tracing/eve/metadata.js +1 -0
  273. package/dist/src/tracing/eve/operation-input.d.ts +30 -0
  274. package/dist/src/tracing/eve/operation-input.js +1 -0
  275. package/dist/src/tracing/eve/otel-configuration.d.ts +70 -0
  276. package/dist/src/tracing/eve/otel-configuration.js +1 -0
  277. package/dist/src/tracing/{otel-declaration.d.ts → eve/otel-declaration.d.ts} +13 -19
  278. package/dist/src/tracing/eve/otel-declaration.js +1 -0
  279. package/dist/src/tracing/{otel-registration.d.ts → eve/otel-registration.d.ts} +12 -5
  280. package/dist/src/tracing/eve/otel-registration.js +1 -0
  281. package/dist/src/tracing/eve/policy.d.ts +15 -0
  282. package/dist/src/tracing/eve/policy.js +1 -0
  283. package/dist/src/tracing/eve/profile.d.ts +7 -0
  284. package/dist/src/tracing/eve/profile.js +1 -0
  285. package/dist/src/tracing/eve/session.d.ts +27 -0
  286. package/dist/src/tracing/eve/session.js +1 -0
  287. package/dist/src/tracing/{vercel-runtime-span-exporter.d.ts → eve/vercel-runtime-span-exporter.d.ts} +1 -1
  288. package/dist/src/tracing/local/agent-trace-span-processor.js +1 -0
  289. package/dist/src/tracing/local/inspection.d.ts +15 -0
  290. package/dist/src/tracing/local/inspection.js +1 -0
  291. package/dist/src/tracing/{local-instrumentation-runtime.d.ts → local/instrumentation-runtime.d.ts} +1 -1
  292. package/dist/src/tracing/local/instrumentation-runtime.js +1 -0
  293. package/dist/src/tracing/{local-trace-analysis.d.ts → local/trace-analysis.d.ts} +2 -2
  294. package/dist/src/tracing/{local-trace-analysis.js → local/trace-analysis.js} +1 -1
  295. package/dist/src/tracing/{local-trace-operations.d.ts → local/trace-operations.d.ts} +1 -1
  296. package/dist/src/tracing/{local-trace-query.d.ts → local/trace-query.d.ts} +1 -1
  297. package/dist/src/tracing/local/trace-reader.js +1 -0
  298. package/dist/src/tracing/{local-trace-retention.js → local/trace-retention.js} +1 -1
  299. package/dist/src/tracing/{local-trace-span-processor.js → local/trace-span-processor.js} +1 -1
  300. package/dist/src/tracing/{local-trace-summary.d.ts → local/trace-summary.d.ts} +1 -1
  301. package/dist/src/tracing/local/trace-summary.js +1 -0
  302. package/dist/src/tracing/{local-traces.d.ts → local/traces.d.ts} +1 -1
  303. package/dist/src/tracing/local/traces.js +1 -0
  304. package/dist/src/vue/index.js +1 -1
  305. package/dist/src/vue/use-eve-agent.d.ts +6 -0
  306. package/dist/src/vue/use-eve-agent.js +1 -1
  307. package/docs/agent-config.md +48 -0
  308. package/docs/channels/eve.mdx +2 -0
  309. package/docs/connections/mcp.mdx +22 -1
  310. package/docs/connections/overview.mdx +9 -6
  311. package/docs/evals/assertions.mdx +50 -3
  312. package/docs/evals/overview.mdx +2 -1
  313. package/docs/evals/reporters.mdx +3 -1
  314. package/docs/guides/frontend/overview.mdx +10 -1
  315. package/docs/guides/hooks.md +2 -2
  316. package/docs/guides/instrumentation/otel.mdx +3 -0
  317. package/docs/reference/cli.md +1 -1
  318. package/docs/reference/typescript-api.md +7 -6
  319. package/docs/sandbox/vercel.mdx +9 -0
  320. package/docs/skills.mdx +1 -1
  321. package/docs/tools/human-in-the-loop.md +44 -1
  322. package/package.json +2 -1
  323. package/dist/src/harness/proxy-input-requests.js +0 -1
  324. package/dist/src/tracing/agent-approval-instrumentation.d.ts +0 -11
  325. package/dist/src/tracing/agent-approval-instrumentation.js +0 -1
  326. package/dist/src/tracing/agent-invocation-coordinator.js +0 -1
  327. package/dist/src/tracing/agent-memory-instrumentation.d.ts +0 -16
  328. package/dist/src/tracing/agent-memory-instrumentation.js +0 -1
  329. package/dist/src/tracing/agent-otel-attributes.d.ts +0 -10
  330. package/dist/src/tracing/agent-otel-attributes.js +0 -1
  331. package/dist/src/tracing/agent-otel-content.js +0 -4
  332. package/dist/src/tracing/agent-otel-provider.js +0 -2
  333. package/dist/src/tracing/agent-otel-runtime-context.d.ts +0 -36
  334. package/dist/src/tracing/agent-otel-runtime-context.js +0 -1
  335. package/dist/src/tracing/agent-otel-session-context.d.ts +0 -22
  336. package/dist/src/tracing/agent-otel-session-context.js +0 -1
  337. package/dist/src/tracing/agent-otel-turn-state.d.ts +0 -6
  338. package/dist/src/tracing/agent-otel-turn-state.js +0 -1
  339. package/dist/src/tracing/agent-otel-usage.d.ts +0 -10
  340. package/dist/src/tracing/agent-otel-usage.js +0 -1
  341. package/dist/src/tracing/agent-span-contract.d.ts +0 -34
  342. package/dist/src/tracing/agent-span-contract.js +0 -1
  343. package/dist/src/tracing/agent-span-error.js +0 -1
  344. package/dist/src/tracing/agent-span-id-generator.js +0 -1
  345. package/dist/src/tracing/agent-span-naming.d.ts +0 -1
  346. package/dist/src/tracing/agent-span-naming.js +0 -1
  347. package/dist/src/tracing/agent-tool-instrumentation.d.ts +0 -40
  348. package/dist/src/tracing/agent-tool-instrumentation.js +0 -1
  349. package/dist/src/tracing/agent-tool-span-context.d.ts +0 -16
  350. package/dist/src/tracing/agent-tool-span-context.js +0 -1
  351. package/dist/src/tracing/agent-trace-context-codec.d.ts +0 -15
  352. package/dist/src/tracing/agent-trace-context-codec.js +0 -1
  353. package/dist/src/tracing/agent-trace-context-store.js +0 -1
  354. package/dist/src/tracing/agent-trace-context.js +0 -1
  355. package/dist/src/tracing/agent-trace-span-processor.js +0 -1
  356. package/dist/src/tracing/agent-trace-state.d.ts +0 -91
  357. package/dist/src/tracing/batch-span-processor.js +0 -1
  358. package/dist/src/tracing/bounded-error.d.ts +0 -1
  359. package/dist/src/tracing/bounded-error.js +0 -1
  360. package/dist/src/tracing/content-attributes.js +0 -1
  361. package/dist/src/tracing/content-span-processor.js +0 -1
  362. package/dist/src/tracing/error-content-context.d.ts +0 -3
  363. package/dist/src/tracing/error-content-context.js +0 -1
  364. package/dist/src/tracing/install-instrumentation-runtime.js +0 -1
  365. package/dist/src/tracing/invoke-tool-span.js +0 -1
  366. package/dist/src/tracing/local-instrumentation-runtime.js +0 -1
  367. package/dist/src/tracing/local-trace-reader.js +0 -1
  368. package/dist/src/tracing/local-trace-summary.js +0 -1
  369. package/dist/src/tracing/local-traces.js +0 -1
  370. package/dist/src/tracing/otel-declaration.js +0 -1
  371. package/dist/src/tracing/otel-registration.js +0 -1
  372. package/dist/src/tracing/sampled-trace.d.ts +0 -4
  373. package/dist/src/tracing/sampled-trace.js +0 -1
  374. package/dist/src/tracing/suppress-tracing.d.ts +0 -2
  375. package/dist/src/tracing/suppress-tracing.js +0 -1
  376. package/dist/src/tracing/telemetry-budget.d.ts +0 -3
  377. package/dist/src/tracing/telemetry-budget.js +0 -1
  378. /package/dist/src/{tracing/agent-span-error.d.ts → compiled/@eve/tracing/adapters/otel-error.d.ts} +0 -0
  379. /package/dist/src/tracing/{agent-invocation-coordinator.d.ts → eve/agent-invocation-coordinator.d.ts} +0 -0
  380. /package/dist/src/tracing/{agent-trace-context.d.ts → eve/agent-trace-context.d.ts} +0 -0
  381. /package/dist/src/tracing/{agent-trace-state.js → eve/agent-trace-state.js} +0 -0
  382. /package/dist/src/tracing/{channel-audience-context.d.ts → eve/channel-audience-context.d.ts} +0 -0
  383. /package/dist/src/tracing/{channel-audience-context.js → eve/channel-audience-context.js} +0 -0
  384. /package/dist/src/tracing/{conversation-context.d.ts → eve/conversation-context.d.ts} +0 -0
  385. /package/dist/src/tracing/{conversation-context.js → eve/conversation-context.js} +0 -0
  386. /package/dist/src/tracing/{invoke-tool-span.d.ts → eve/invoke-tool-span.d.ts} +0 -0
  387. /package/dist/src/tracing/{span-export-policy.d.ts → eve/span-export-policy.d.ts} +0 -0
  388. /package/dist/src/tracing/{span-export-policy.js → eve/span-export-policy.js} +0 -0
  389. /package/dist/src/tracing/{vercel-runtime-span-exporter.js → eve/vercel-runtime-span-exporter.js} +0 -0
  390. /package/dist/src/tracing/{agent-trace-span-processor.d.ts → local/agent-trace-span-processor.d.ts} +0 -0
  391. /package/dist/src/tracing/{local-trace-discovery-index.d.ts → local/trace-discovery-index.d.ts} +0 -0
  392. /package/dist/src/tracing/{local-trace-discovery-index.js → local/trace-discovery-index.js} +0 -0
  393. /package/dist/src/tracing/{local-trace-operations.js → local/trace-operations.js} +0 -0
  394. /package/dist/src/tracing/{local-trace-query.js → local/trace-query.js} +0 -0
  395. /package/dist/src/tracing/{local-trace-reader.d.ts → local/trace-reader.d.ts} +0 -0
  396. /package/dist/src/tracing/{local-trace-retention.d.ts → local/trace-retention.d.ts} +0 -0
  397. /package/dist/src/tracing/{local-trace-span-processor.d.ts → local/trace-span-processor.d.ts} +0 -0
@@ -1 +1 @@
1
- import{joinEveRoutePath}from"#shared/eve-route-path.js";import{EVE_PUBLIC_ROUTE_PREFIX_ENV,normalizePublicRoutePrefix}from"#shared/public-route-prefix.js";function resolveVercelProductionCallbackBaseUrl(){return process.env.VERCEL_ENV===`production`&&process.env.VERCEL_PROJECT_PRODUCTION_URL?`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`:null}function resolveWorkflowCallbackBaseUrl(e){let t=process.env.WORKFLOW_LOCAL_BASE_URL?.trim()||void 0,n=(resolveVercelProductionCallbackBaseUrl()??t??e).replace(/\/$/,``),r=normalizePublicRoutePrefix(process.env[EVE_PUBLIC_ROUTE_PREFIX_ENV]);return r===void 0?n:`${n}${r}`}function createWorkflowCallbackUrl(e,t){let n=new URL(t,`http://eve.local`),r=new URL(e);r.pathname=joinEveRoutePath(r.pathname,n.pathname),r.search=n.search;let i=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();return i&&r.searchParams.set(`x-vercel-protection-bypass`,i),r.toString()}export{createWorkflowCallbackUrl,resolveVercelProductionCallbackBaseUrl,resolveWorkflowCallbackBaseUrl};
1
+ import{joinEveRoutePath}from"#shared/eve-route-path.js";import{EVE_PUBLIC_ROUTE_PREFIX_ENV,normalizePublicRoutePrefix}from"#shared/public-route-prefix.js";function resolveVercelProductionCallbackBaseUrl(){return process.env.VERCEL_ENV===`production`&&process.env.VERCEL_PROJECT_PRODUCTION_URL?`https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`:null}function resolveWorkflowCallbackBaseUrl(e){let t=process.env.WORKFLOW_LOCAL_BASE_URL?.trim()||void 0,n=(resolveVercelProductionCallbackBaseUrl()??t??e).replace(/\/$/,``),r=normalizePublicRoutePrefix(process.env[EVE_PUBLIC_ROUTE_PREFIX_ENV]);return r===void 0?n:`${n}${r}`}function createBrowserCallbackUrl(e,t){let n=new URL(t,`http://eve.local`),r=new URL(e);return r.pathname=joinEveRoutePath(r.pathname,n.pathname),r.search=n.search,r.toString()}function createWorkflowCallbackUrl(e,t){let n=new URL(createBrowserCallbackUrl(e,t)),r=process.env.VERCEL_AUTOMATION_BYPASS_SECRET?.trim();return r&&n.searchParams.set(`x-vercel-protection-bypass`,r),n.toString()}export{createBrowserCallbackUrl,createWorkflowCallbackUrl,resolveVercelProductionCallbackBaseUrl,resolveWorkflowCallbackBaseUrl};
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{SessionPredecessorKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{validateToolStubTargets}from"#tool-stubs/validate-targets.js";import{getHookByToken,getRun,getWorld,start}from"#internal/workflow/runtime.js";import{SessionStrandedError,describeStrandedSession}from"#channel/session-stranded-error.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{serializeContext}from"#context/serialize.js";import{AcceptedSessionIdentityError,SessionHandoffPendingError,logicalSessionToken,resolveSessionInbox,resumeSessionInbox}from"#execution/session-inbox/resume.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{StrandedSessionOwnerError,assertRunnableSessionInbox,findSessionHookHolder}from"#execution/session-inbox/owner.js";import{initializeSessionInstrumentation}from"#instrumentation/runtime.js";import{EVE_VERSION_ATTRIBUTE,buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{endStrandedSession}from"#execution/session-inbox/end-stranded-session.js";import{SESSION_HOOK_HANDOVER_TIMEOUT_MS,waitForSessionHooksRelease}from"#execution/session-inbox/hook-release.js";import{SESSION_TIMEOUT_WORKFLOW_NAME,WORKFLOW_ENTRY_NAME,WORKFLOW_TOOL_RUN_WORKFLOW_NAME}from"#execution/stable-workflow-names.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{readSessionEventHistory,readSessionEventStream,readSessionStreamTailIndex}from"#execution/session-event-stream.js";import{SESSION_HANDOFF_VERSION}from"#execution/session/entry-input.js";import{buildInvocationAttributes}from"#internal/invocation/metadata.js";import{isAgentTraceContext}from"#tracing/agent-trace-context.js";const EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},sessionTimeoutWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${SESSION_TIMEOUT_WORKFLOW_NAME}`},workflowToolRunWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_TOOL_RUN_WORKFLOW_NAME}`};function createWorkflowRuntime(e){let startSession=async(t,n)=>{let r=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId});t.toolStubs!==void 0&&t.toolStubs.rootSessionId===void 0&&validateToolStubTargets(t.toolStubs.rules,r.graph);let i=buildRunContext({bundle:r,dynamicSubagentAgentConfig:e.dynamicSubagentAgentConfig,run:t});n!==void 0&&i.set(SessionPredecessorKey,n);let a=resolveEffectiveAgentRuntime(r,i);initializeSessionInstrumentation({agentName:a.turnAgent.id,ctx:i});let o=a.limits?.sessionTimeoutMs,s=r.resolvedAgent.config?.experimental?.workflow?.retention,c=serializeContext(i),l=readParentLineage(c),u={kind:`initial`,input:t.input,ownerDeploymentId:await resolveCurrentWorkflowDeploymentId(),serializedContext:c};t.limits!==void 0&&(u.limits=t.limits),t.continuationConflictCommand!==void 0&&(u.continuationConflictCommand=t.continuationConflictCommand),o!==void 0&&(u.sessionTimeoutMs=o),s!==void 0&&(u.retention=s);let d={...l.sessionId===void 0?buildSessionAttributes({serializedContext:c}):buildSubagentRootAttributes({identity:{nodeId:r.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:l.callId,parentSessionId:l.sessionId,parentTurnId:l.turnId,rootSessionId:l.rootSessionId??l.sessionId,serializedContext:c}),...t.externalInvocation===void 0?{}:buildInvocationAttributes(t.externalInvocation)},f;try{let e={allowReservedAttributes:!0,attributes:normalizeEveAttributes(d)};s!==void 0&&(e.experimental_retention=s),f=await startWorkflowOnDeployment(workflowEntryReference,[u],u.ownerDeploymentId,e)}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:t.continuationToken}),e}let p,getEvents=()=>(p??=readSessionEventStream(f.runId),p);return{get events(){return getEvents()},sessionId:f.runId}};return{async createSession(e){return await startSession(e)},async dispatchContinuation(e){let{command:t,continuationToken:n,successor:r}=e;try{return await dispatchWorkflowCommand(n,t)}catch(e){if(!(e instanceof StrandedSessionOwnerError))throw e;if(t.kind!==`send`||r===void 0)return await settleStrandedCommand(n,t,e);if((t.payload.inputResponses?.length??0)>0)throw sessionStrandedError(e,`Its pending requests can no longer be answered; send a new message to start a fresh session.`);let i=await endStrandedSession(e,n,`message`);return{sessionId:(await startSession(r,{sessionId:i})).sessionId,status:`accepted`}}},async dispatchSession(e){return await dispatchWorkflowSessionCommand(e)},async getEventStream(e,t){if(t?.follow===!1)return readSessionEventHistory(e,t.startIndex);try{await assertRunnableSessionInbox(sessionInboxHookToken(sessionCommandHookToken(e)))}catch(e){throw e instanceof StrandedSessionOwnerError?sessionStrandedError(e):e}return readSessionEventStream(e,t?.startIndex)},async getStreamTailIndex(e){return await readSessionStreamTailIndex(e)},resolveContinuation}}async function startSessionOwnerStep(e){"use step";let{activationToken:t,anchorRunId:n,checkpoint:r,targetDeploymentId:i,...a}=e,o={...a,activationToken:t,checkpoint:r,handoffVersion:SESSION_HANDOFF_VERSION,kind:`handoff`,ownerDeploymentId:i,sessionWritable:getRun(n).getWritable(),sessionId:n};await startWorkflowOnDeployment(workflowEntryReference,[o],i,r.retention===void 0?void 0:{experimental_retention:r.retention})}async function dispatchWorkflowCommand(e,t){let n;try{let r=await resumeSessionInbox(e,t);n={runId:r.ownerRunId,sessionId:await r.sessionId}}catch(n){if(n instanceof StrandedSessionOwnerError)throw n;let r=t.kind===`send`&&typeof e!=`string`,i={status:`session_not_active`,retryable:!0};if(n instanceof SessionHandoffPendingError){if(r)return i;throw n}if(isInactiveCommandTarget(n))return r&&await isRunActive(e.sessionId)?i:inactiveCommandResult(t);throw logError(log,`failed to dispatch session command`,n,{command:t.kind,token:e}),n}return t.kind===`reset`&&await waitForSessionHooksRelease([sessionCommandHookToken(n.sessionId),logicalSessionToken(e)],n.runId),activeCommandResult(t,n.sessionId)}async function settleStrandedCommand(e,t,n){switch(t.kind){case`reset`:return{previousSessionId:await endStrandedSession(n,e,`reset`),status:`reset`};case`send`:case`clear`:throw sessionStrandedError(n);default:return inactiveCommandResult(t)}}function sessionStrandedError(e,t){let n=e.eveVersion===void 0?{}:{eveVersion:e.eveVersion};return new SessionStrandedError(n,describeStrandedSession(n,t))}function activeCommandResult(e,t){return e.kind===`reset`?{previousSessionId:t,status:`reset`}:e.kind===`send`&&e.delivery!==void 0?{sessionId:t,status:`accepted`,deliveryId:e.delivery.deliveryId}:{sessionId:t,status:`accepted`}}function inactiveCommandResult(e){return e.kind===`send`?{status:`session_not_active`}:e.kind===`cancel`?{status:`no_active_turn`}:{status:`no_active_session`}}async function dispatchWorkflowSessionCommand(e){let t={sessionId:e.sessionId};try{return await dispatchWorkflowCommand(t,e.command)}catch(n){if(!(n instanceof StrandedSessionOwnerError))throw n;return await settleStrandedCommand(t,e.command,n)}}async function isRunActive(e){try{let t=await getRun(e).status;return t===`pending`||t===`running`}catch(e){if(isInactiveCommandTarget(e))return!1;throw e}}function isInactiveCommandTarget(e){if(e instanceof AcceptedSessionIdentityError)return!1;if(HookNotFoundError.is(e))return!0;for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function resolveContinuation(e){try{return await resolveSessionInbox(e)}catch(t){if(HookNotFoundError.is(t))return;throw logError(log,`failed to resolve session by continuation token`,t,{continuationToken:e}),t}}async function waitForCommandHookOwner(e){let t=await pollUntil(async()=>{try{return normalizeWorkflowHook(await getHookByToken(e))}catch(e){if(!HookNotFoundError.is(e))throw e;return}},SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(t===void 0)throw new HookNotFoundError(e);return t}async function waitForSessionInbox(e){let t=sessionInboxHookToken(sessionCommandHookToken(e)),n=await pollUntil(async()=>await findSessionHookHolder(t)!==void 0||!await hasRunEnded(e)&&void 0,SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(n===void 0)throw Error(`Session "${e}" did not start taking commands within ${SESSION_HOOK_HANDOVER_TIMEOUT_MS/1e3} seconds.`);return n}async function pollUntil(e,t){let n=Date.now()+t;for(let t=20;;t=Math.min(t*2,200)){let r=await e();if(r!==void 0||Date.now()>=n)return r;await new Promise(e=>setTimeout(e,t))}}async function hasRunEnded(e){try{let t=await getRun(e).status;return t!==`pending`&&t!==`running`}catch(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t))return!1;if(isInactiveCommandTarget(e))return!0;throw e}}async function startWorkflowOnCurrentDeployment(e,t,n){return await startWorkflowOnDeployment(e,t,await resolveCurrentWorkflowDeploymentId(),n)}async function startWorkflowOnDeployment(e,t,n,r){return await withWorkflowStartContext(async()=>{if(n.length===0||n===`latest`)throw Error(`Workflow starts require an exact deployment id.`);return await start(e,t,{...r,allowReservedAttributes:!0,attributes:{...r?.attributes,[EVE_VERSION_ATTRIBUTE]:EVE_PACKAGE_INFO.version},deploymentId:n})})}async function resolveCurrentWorkflowDeploymentId(){let e=process.env.VERCEL_DEPLOYMENT_ID?.trim()||await(await getWorld()).getDeploymentId();if(e.length===0||e===`latest`)throw Error(`Workflow runtime could not resolve an exact deployment id.`);return e}async function withWorkflowStartContext(e){let t=context.active(),n=isAgentTraceContext(t)?trace.deleteSpan(t):t;return await context.with(n,e)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}export{createWorkflowRuntime,dispatchWorkflowSessionCommand,hasRunEnded,pollUntil,resolveContinuation,sessionTimeoutWorkflowReference,startSessionOwnerStep,startWorkflowOnCurrentDeployment,waitForCommandHookOwner,waitForSessionInbox,workflowEntryReference,workflowToolRunWorkflowReference};
1
+ import{createLogger,logError}from"#internal/logging.js";import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{SessionPredecessorKey}from"#context/keys.js";import{resolveInstalledPackageInfo}from"#internal/application/package.js";import{walkCauseChain}from"#shared/errors.js";import{validateToolStubTargets}from"#tool-stubs/validate-targets.js";import{getHookByToken,getRun,getWorld,start}from"#internal/workflow/runtime.js";import{SessionStrandedError,describeStrandedSession}from"#channel/session-stranded-error.js";import{getCompiledRuntimeAgentBundle}from"#runtime/sessions/compiled-agent-cache.js";import{ROOT_RUNTIME_AGENT_NODE_ID}from"#runtime/graph.js";import{serializeContext}from"#context/serialize.js";import{AcceptedSessionIdentityError,SessionHandoffPendingError,logicalSessionToken,resolveSessionInbox,resumeSessionInbox}from"#execution/session-inbox/resume.js";import{resolveEffectiveAgentRuntime}from"#execution/effective-agent-config.js";import{context,trace}from"#compiled/@opentelemetry/api/index.js";import{EntityConflictError,HookNotFoundError,RunExpiredError,WorkflowRunNotFoundError}from"#compiled/@workflow/errors/index.js";import{StrandedSessionOwnerError,assertRunnableSessionInbox,findSessionHookHolder}from"#execution/session-inbox/owner.js";import{initializeSessionInstrumentation}from"#instrumentation/runtime.js";import{EVE_VERSION_ATTRIBUTE,buildSessionAttributes,buildSubagentRootAttributes,readParentLineage}from"#execution/eve-workflow-attributes.js";import{endStrandedSession}from"#execution/session-inbox/end-stranded-session.js";import{SESSION_HOOK_HANDOVER_TIMEOUT_MS,waitForSessionHooksRelease}from"#execution/session-inbox/hook-release.js";import{SESSION_TIMEOUT_WORKFLOW_NAME,WORKFLOW_ENTRY_NAME,WORKFLOW_TOOL_RUN_WORKFLOW_NAME}from"#execution/stable-workflow-names.js";import{normalizeEveAttributes}from"#runtime/attributes/normalize.js";import{buildRunContext}from"#execution/runtime-context.js";import{readSessionEventHistory,readSessionEventStream,readSessionStreamTailIndex}from"#execution/session-event-stream.js";import{SESSION_HANDOFF_VERSION}from"#execution/session/entry-input.js";import{buildInvocationAttributes}from"#internal/invocation/metadata.js";import{isAgentTraceContext}from"#tracing/eve/agent-trace-context.js";const EVE_PACKAGE_INFO=resolveInstalledPackageInfo(),STABLE_ID_BASE=EVE_PACKAGE_INFO.name,log=createLogger(`execution.workflow-runtime`),workflowEntryReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_ENTRY_NAME}`},sessionTimeoutWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${SESSION_TIMEOUT_WORKFLOW_NAME}`},workflowToolRunWorkflowReference={workflowId:`workflow//${STABLE_ID_BASE}//${WORKFLOW_TOOL_RUN_WORKFLOW_NAME}`};function createWorkflowRuntime(e){let startSession=async(t,n)=>{let r=await getCompiledRuntimeAgentBundle({compiledArtifactsSource:e.compiledArtifactsSource,nodeId:e.nodeId});t.toolStubs!==void 0&&t.toolStubs.rootSessionId===void 0&&validateToolStubTargets(t.toolStubs.rules,r.graph);let i=buildRunContext({bundle:r,dynamicSubagentAgentConfig:e.dynamicSubagentAgentConfig,run:t});n!==void 0&&i.set(SessionPredecessorKey,n);let a=resolveEffectiveAgentRuntime(r,i);initializeSessionInstrumentation({agentName:a.turnAgent.id,ctx:i});let o=a.limits?.sessionTimeoutMs,s=r.resolvedAgent.config?.experimental?.workflow?.retention,c=serializeContext(i),l=readParentLineage(c),u={kind:`initial`,input:t.input,ownerDeploymentId:await resolveCurrentWorkflowDeploymentId(),serializedContext:c};t.limits!==void 0&&(u.limits=t.limits),t.continuationConflictCommand!==void 0&&(u.continuationConflictCommand=t.continuationConflictCommand),o!==void 0&&(u.sessionTimeoutMs=o),s!==void 0&&(u.retention=s);let d={...l.sessionId===void 0?buildSessionAttributes({serializedContext:c}):buildSubagentRootAttributes({identity:{nodeId:r.nodeId??ROOT_RUNTIME_AGENT_NODE_ID},parentCallId:l.callId,parentSessionId:l.sessionId,parentTurnId:l.turnId,rootSessionId:l.rootSessionId??l.sessionId,serializedContext:c}),...t.externalInvocation===void 0?{}:buildInvocationAttributes(t.externalInvocation)},f;try{let e={allowReservedAttributes:!0,attributes:normalizeEveAttributes(d)};s!==void 0&&(e.experimental_retention=s),f=await startWorkflowOnDeployment(workflowEntryReference,[u],u.ownerDeploymentId,e)}catch(e){throw logError(log,`failed to start workflow run`,e,{continuationToken:t.continuationToken}),e}let p,getEvents=()=>(p??=readSessionEventStream(f.runId),p);return{get events(){return getEvents()},sessionId:f.runId}};return{async createSession(e){return await startSession(e)},async dispatchContinuation(e){let{command:t,continuationToken:n,successor:r}=e;try{return await dispatchWorkflowCommand(n,t)}catch(e){if(!(e instanceof StrandedSessionOwnerError))throw e;if(t.kind!==`send`||r===void 0)return await settleStrandedCommand(n,t,e);if((t.payload.inputResponses?.length??0)>0)throw sessionStrandedError(e,`Its pending requests can no longer be answered; send a new message to start a fresh session.`);let i=await endStrandedSession(e,n,`message`);return{sessionId:(await startSession(r,{sessionId:i})).sessionId,status:`accepted`}}},async dispatchSession(e){return await dispatchWorkflowSessionCommand(e)},async getEventStream(e,t){if(t?.follow===!1)return readSessionEventHistory(e,t.startIndex);try{await assertRunnableSessionInbox(sessionInboxHookToken(sessionCommandHookToken(e)))}catch(e){throw e instanceof StrandedSessionOwnerError?sessionStrandedError(e):e}return readSessionEventStream(e,t?.startIndex)},async getStreamTailIndex(e){return await readSessionStreamTailIndex(e)},resolveContinuation}}async function startSessionOwnerStep(e){"use step";let{activationToken:t,anchorRunId:n,checkpoint:r,targetDeploymentId:i,...a}=e,o={...a,activationToken:t,checkpoint:r,handoffVersion:SESSION_HANDOFF_VERSION,kind:`handoff`,ownerDeploymentId:i,sessionWritable:getRun(n).getWritable(),sessionId:n};await startWorkflowOnDeployment(workflowEntryReference,[o],i,r.retention===void 0?void 0:{experimental_retention:r.retention})}async function dispatchWorkflowCommand(e,t){let n;try{let r=await resumeSessionInbox(e,t);n={runId:r.ownerRunId,sessionId:await r.sessionId}}catch(n){if(n instanceof StrandedSessionOwnerError)throw n;let r=t.kind===`send`&&typeof e!=`string`,i={status:`session_not_active`,retryable:!0};if(n instanceof SessionHandoffPendingError){if(r)return i;throw n}if(isInactiveCommandTarget(n))return r&&await isRunActive(e.sessionId)?i:inactiveCommandResult(t);throw logError(log,`failed to dispatch session command`,n,{command:t.kind,token:e}),n}return t.kind===`reset`&&await waitForSessionHooksRelease([sessionCommandHookToken(n.sessionId),logicalSessionToken(e)],n.runId),activeCommandResult(t,n.sessionId)}async function settleStrandedCommand(e,t,n){switch(t.kind){case`reset`:return{previousSessionId:await endStrandedSession(n,e,`reset`),status:`reset`};case`send`:case`clear`:throw sessionStrandedError(n);default:return inactiveCommandResult(t)}}function sessionStrandedError(e,t){let n=e.eveVersion===void 0?{}:{eveVersion:e.eveVersion};return new SessionStrandedError(n,describeStrandedSession(n,t))}function activeCommandResult(e,t){return e.kind===`reset`?{previousSessionId:t,status:`reset`}:e.kind===`send`&&e.delivery!==void 0?{sessionId:t,status:`accepted`,deliveryId:e.delivery.deliveryId}:{sessionId:t,status:`accepted`}}function inactiveCommandResult(e){return e.kind===`send`?{status:`session_not_active`}:e.kind===`cancel`?{status:`no_active_turn`}:{status:`no_active_session`}}async function dispatchWorkflowSessionCommand(e){let t={sessionId:e.sessionId};try{return await dispatchWorkflowCommand(t,e.command)}catch(n){if(!(n instanceof StrandedSessionOwnerError))throw n;return await settleStrandedCommand(t,e.command,n)}}async function isRunActive(e){try{let t=await getRun(e).status;return t===`pending`||t===`running`}catch(e){if(isInactiveCommandTarget(e))return!1;throw e}}function isInactiveCommandTarget(e){if(e instanceof AcceptedSessionIdentityError)return!1;if(HookNotFoundError.is(e))return!0;for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t)||RunExpiredError.is(t)||EntityConflictError.is(t))return!0;return!1}async function resolveContinuation(e){try{return await resolveSessionInbox(e)}catch(t){if(HookNotFoundError.is(t))return;throw logError(log,`failed to resolve session by continuation token`,t,{continuationToken:e}),t}}async function waitForCommandHookOwner(e){let t=await pollUntil(async()=>{try{return normalizeWorkflowHook(await getHookByToken(e))}catch(e){if(!HookNotFoundError.is(e))throw e;return}},SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(t===void 0)throw new HookNotFoundError(e);return t}async function waitForSessionInbox(e){let t=sessionInboxHookToken(sessionCommandHookToken(e)),n=await pollUntil(async()=>await findSessionHookHolder(t)!==void 0||!await hasRunEnded(e)&&void 0,SESSION_HOOK_HANDOVER_TIMEOUT_MS);if(n===void 0)throw Error(`Session "${e}" did not start taking commands within ${SESSION_HOOK_HANDOVER_TIMEOUT_MS/1e3} seconds.`);return n}async function pollUntil(e,t){let n=Date.now()+t;for(let t=20;;t=Math.min(t*2,200)){let r=await e();if(r!==void 0||Date.now()>=n)return r;await new Promise(e=>setTimeout(e,t))}}async function hasRunEnded(e){try{let t=await getRun(e).status;return t!==`pending`&&t!==`running`}catch(e){for(let t of walkCauseChain(e))if(WorkflowRunNotFoundError.is(t))return!1;if(isInactiveCommandTarget(e))return!0;throw e}}async function startWorkflowOnCurrentDeployment(e,t,n){return await startWorkflowOnDeployment(e,t,await resolveCurrentWorkflowDeploymentId(),n)}async function startWorkflowOnDeployment(e,t,n,r){return await withWorkflowStartContext(async()=>{if(n.length===0||n===`latest`)throw Error(`Workflow starts require an exact deployment id.`);return await start(e,t,{...r,allowReservedAttributes:!0,attributes:{...r?.attributes,[EVE_VERSION_ATTRIBUTE]:EVE_PACKAGE_INFO.version},deploymentId:n})})}async function resolveCurrentWorkflowDeploymentId(){let e=process.env.VERCEL_DEPLOYMENT_ID?.trim()||await(await getWorld()).getDeploymentId();if(e.length===0||e===`latest`)throw Error(`Workflow runtime could not resolve an exact deployment id.`);return e}async function withWorkflowStartContext(e){let t=context.active(),n=isAgentTraceContext(t)?trace.deleteSpan(t):t;return await context.with(n,e)}function normalizeWorkflowHook(e){if(typeof e!=`object`||!e||!(`runId`in e))throw Error(`Workflow hook did not include a run id.`);let t=e.runId;if(typeof t!=`string`||t.length===0)throw Error(`Workflow hook did not include a run id.`);return{runId:t}}export{createWorkflowRuntime,dispatchWorkflowSessionCommand,hasRunEnded,pollUntil,resolveContinuation,sessionTimeoutWorkflowReference,startSessionOwnerStep,startWorkflowOnCurrentDeployment,waitForCommandHookOwner,waitForSessionInbox,workflowEntryReference,workflowToolRunWorkflowReference};
@@ -91,6 +91,9 @@ export declare function consumeAuthorizationResult(name: string, instanceId?: st
91
91
  * It is independent of the continuation token, so channel aliasing mid-turn
92
92
  * does not invalidate the callback URL.
93
93
  *
94
+ * The URL reaches the user's browser and the IdP, so it never carries the
95
+ * deployment's protection bypass secret.
96
+ *
94
97
  * Returns `undefined` if no callback address is available.
95
98
  */
96
99
  export declare function getHookUrl(name: string, attemptId: string): string | undefined;
@@ -135,17 +138,4 @@ export declare const PendingAuthorizationResultKey: ContextKey<readonly NamedAut
135
138
  export declare const CallbackBaseUrlKey: ContextKey<string>;
136
139
  /** Hook token of a runtime that owns its callback instead of using the session hook. */
137
140
  export declare const AuthorizationHookKey: ContextKey<string>;
138
- export interface PendingAuthorizationState {
139
- readonly challenges: readonly AuthorizationChallenge[];
140
- }
141
- export declare function setPendingAuthorization(sessionState: Record<string, unknown> | undefined, value: PendingAuthorizationState): Record<string, unknown>;
142
- /** The pending sign-ins once `challenges` are asked for: each replaces the attempt it supersedes. */
143
- export declare function withSignIns(previous: readonly AuthorizationChallenge[], challenges: readonly AuthorizationChallenge[]): readonly AuthorizationChallenge[];
144
- /** Keeps the last challenge for each sign-in and principal. */
145
- export declare function resolveActiveAuthorizationChallenges(challenges: readonly AuthorizationChallenge[]): readonly AuthorizationChallenge[];
146
- /** The attempts in `previous` that `replacements` replace: the same sign-in and principal. */
147
- export declare function supersededChallenges(previous: readonly AuthorizationChallenge[], replacements: readonly AuthorizationChallenge[]): readonly AuthorizationChallenge[];
148
- export declare function clearPendingAuthorization(sessionState: Record<string, unknown> | undefined, attemptIds?: readonly string[]): Record<string, unknown> | undefined;
149
- export declare function getPendingAuthorization(sessionState: Record<string, unknown> | undefined): PendingAuthorizationState | undefined;
150
- export declare function hasPendingAuthorization(sessionState: Record<string, unknown> | undefined): boolean;
151
141
  export {};
@@ -1 +1 @@
1
- import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{loadContext}from"#context/container.js";import{SessionIdKey}from"#context/keys.js";import{createEveConnectionCallbackRoutePath}from"#protocol/routes.js";import{ContextKey}from"#context/key.js";import{createWorkflowCallbackUrl}from"#execution/workflow-callback-url.js";import{createUlid}from"#shared/ulid.js";const AUTHORIZATION_BRAND=`__eveAuthorization`,AUTHORIZATION_PENDING_BRAND=`__eveAuthorizationPending`;function requestAuthorization(e){return{[AUTHORIZATION_BRAND]:!0,challenges:e}}function getAuthorizationResult(e){let t=loadContext().get(PendingAuthorizationResultKey);if(t&&t.length!==0)return e===void 0?t[0]:t.find(t=>t.name===e)}function getAuthorizationResults(){return loadContext().get(PendingAuthorizationResultKey)??[]}function consumeAuthorizationResult(e,t){let n=loadContext(),r=n.get(PendingAuthorizationResultKey);if(!r||r.length===0)return;let i=r.findIndex(n=>n.name===e&&n.instanceId===t);if(i===-1&&t!==void 0&&r.some(t=>t.name===e&&t.instanceId!==void 0))throw Error(`Authorization for "${e}" cannot complete because its resolved connection changed while sign-in was pending. Start sign-in again.`);if(i===-1)return;let a=r[i],o=r.filter((e,t)=>t!==i);return n.delete(PendingAuthorizationResultKey),o.length>0&&n.set(PendingAuthorizationResultKey,o),a}function getHookUrl(e,t){let n=loadContext(),r=n.get(SessionIdKey),i=n.get(CallbackBaseUrlKey),a=n.get(AuthorizationHookKey)??(r?authHookToken(r):void 0);if(a&&i)return createWorkflowCallbackUrl(i,createEveConnectionCallbackRoutePath(e,t,a))}function createAuthorizationAttempt(e){let t=createUlid(),n=getHookUrl(e,t);return n===void 0?void 0:{attemptId:t,hookUrl:n}}function isAuthorizationSignal(e){return typeof e!=`object`||!e?!1:e[AUTHORIZATION_BRAND]===!0}function isAuthorizationPendingModelOutput(e){return typeof e!=`object`||!e?!1:e[AUTHORIZATION_PENDING_BRAND]===!0}function authorizationPendingAsJsonObject(e){return{[AUTHORIZATION_PENDING_BRAND]:!0,connections:[...e.connections]}}function modelFacingAuthorizationOutput(e){return authorizationPendingAsJsonObject({connections:e.challenges.map(e=>e.name)})}function authorizationPendingModelText(e){return e.length===0?`Authorization required. Waiting for the user to sign in.`:e.length===1?`Authorization required for ${e[0]}. Waiting for the user to sign in.`:`Authorization required for ${e.join(`, `)}. Waiting for the user to sign in.`}function isPendingAuthorizationToolOutput(e){return isAuthorizationPendingModelOutput(e)||isAuthorizationSignal(e)}function authHookToken(e){return sessionInboxHookToken(sessionCommandHookToken(e))}const PendingAuthorizationResultKey=new ContextKey(`eve.pendingAuthorizationResult`),CallbackBaseUrlKey=new ContextKey(`eve.callbackBaseUrl`),AuthorizationHookKey=new ContextKey(`eve.authorizationHook`),PENDING_AUTHORIZATION_KEY=`eve.runtime.pendingAuthorization`;function setPendingAuthorization(e,t){return{...e,[PENDING_AUTHORIZATION_KEY]:{challenges:withSignIns(getPendingAuthorization(e)?.challenges??[],t.challenges)}}}function withSignIns(e,t){let n=resolveActiveAuthorizationChallenges(t),r=supersededChallenges(e,n);return[...e.filter(e=>!r.includes(e)),...n]}function resolveActiveAuthorizationChallenges(e){return e.filter((t,n)=>!e.slice(n+1).some(e=>sameSignIn(t,e)))}function supersededChallenges(e,t){return e.filter(e=>t.some(t=>sameSignIn(e,t)))}function sameSignIn(e,t){let n=e.grant!==void 0&&e.grant===t.grant&&e.candidateId===t.candidateId;return(e.name===t.name||n)&&samePrincipal(e.principal,t.principal)}function samePrincipal(e,t){return e===void 0||t===void 0?e===t:e.type===`app`||t.type===`app`?e.type===t.type:e.id===t.id&&e.issuer===t.issuer}function clearPendingAuthorization(e,t){if(e===void 0||e[PENDING_AUTHORIZATION_KEY]===void 0)return e;if(t!==void 0){if(t.length===0)return e;let n=getPendingAuthorization(e);if(n!==void 0){let r=new Set(t),i=n.challenges.filter(e=>!r.has(authorizationAttemptKey(e)));if(i.length>0)return{...e,[PENDING_AUTHORIZATION_KEY]:{challenges:i}}}}let n={...e};return delete n[PENDING_AUTHORIZATION_KEY],Object.keys(n).length>0?n:void 0}function authorizationAttemptKey(e){return e.attemptId??e.candidateId??e.name}function getPendingAuthorization(e){if(!e)return;let t=e[PENDING_AUTHORIZATION_KEY];if(typeof t==`object`&&t)return t}function hasPendingAuthorization(e){return getPendingAuthorization(e)!==void 0}export{AuthorizationHookKey,CallbackBaseUrlKey,PendingAuthorizationResultKey,authHookToken,authorizationPendingAsJsonObject,authorizationPendingModelText,clearPendingAuthorization,consumeAuthorizationResult,createAuthorizationAttempt,getAuthorizationResult,getAuthorizationResults,getHookUrl,getPendingAuthorization,hasPendingAuthorization,isAuthorizationPendingModelOutput,isAuthorizationSignal,isPendingAuthorizationToolOutput,modelFacingAuthorizationOutput,requestAuthorization,resolveActiveAuthorizationChallenges,setPendingAuthorization,supersededChallenges,withSignIns};
1
+ import{sessionCommandHookToken,sessionInboxHookToken}from"#execution/session-inbox/address.js";import{loadContext}from"#context/container.js";import{SessionIdKey}from"#context/keys.js";import{createEveConnectionCallbackRoutePath}from"#protocol/routes.js";import{ContextKey}from"#context/key.js";import{createBrowserCallbackUrl}from"#execution/workflow-callback-url.js";import{createUlid}from"#shared/ulid.js";const AUTHORIZATION_BRAND=`__eveAuthorization`,AUTHORIZATION_PENDING_BRAND=`__eveAuthorizationPending`;function requestAuthorization(e){return{[AUTHORIZATION_BRAND]:!0,challenges:e}}function getAuthorizationResult(e){let t=loadContext().get(PendingAuthorizationResultKey);if(t&&t.length!==0)return e===void 0?t[0]:t.find(t=>t.name===e)}function getAuthorizationResults(){return loadContext().get(PendingAuthorizationResultKey)??[]}function consumeAuthorizationResult(e,t){let n=loadContext(),r=n.get(PendingAuthorizationResultKey);if(!r||r.length===0)return;let i=r.findIndex(n=>n.name===e&&n.instanceId===t);if(i===-1&&t!==void 0&&r.some(t=>t.name===e&&t.instanceId!==void 0))throw Error(`Authorization for "${e}" cannot complete because its resolved connection changed while sign-in was pending. Start sign-in again.`);if(i===-1)return;let a=r[i],o=r.filter((e,t)=>t!==i);return n.delete(PendingAuthorizationResultKey),o.length>0&&n.set(PendingAuthorizationResultKey,o),a}function getHookUrl(e,t){let n=loadContext(),r=n.get(SessionIdKey),i=n.get(CallbackBaseUrlKey),a=n.get(AuthorizationHookKey)??(r?authHookToken(r):void 0);if(a&&i)return createBrowserCallbackUrl(i,createEveConnectionCallbackRoutePath(e,t,a))}function createAuthorizationAttempt(e){let t=createUlid(),n=getHookUrl(e,t);return n===void 0?void 0:{attemptId:t,hookUrl:n}}function isAuthorizationSignal(e){return typeof e!=`object`||!e?!1:e[AUTHORIZATION_BRAND]===!0}function isAuthorizationPendingModelOutput(e){return typeof e!=`object`||!e?!1:e[AUTHORIZATION_PENDING_BRAND]===!0}function authorizationPendingAsJsonObject(e){return{[AUTHORIZATION_PENDING_BRAND]:!0,connections:[...e.connections]}}function modelFacingAuthorizationOutput(e){return authorizationPendingAsJsonObject({connections:e.challenges.map(e=>e.name)})}function authorizationPendingModelText(e){return e.length===0?`Authorization required. Waiting for the user to sign in.`:e.length===1?`Authorization required for ${e[0]}. Waiting for the user to sign in.`:`Authorization required for ${e.join(`, `)}. Waiting for the user to sign in.`}function isPendingAuthorizationToolOutput(e){return isAuthorizationPendingModelOutput(e)||isAuthorizationSignal(e)}function authHookToken(e){return sessionInboxHookToken(sessionCommandHookToken(e))}const PendingAuthorizationResultKey=new ContextKey(`eve.pendingAuthorizationResult`),CallbackBaseUrlKey=new ContextKey(`eve.callbackBaseUrl`),AuthorizationHookKey=new ContextKey(`eve.authorizationHook`);export{AuthorizationHookKey,CallbackBaseUrlKey,PendingAuthorizationResultKey,authHookToken,authorizationPendingAsJsonObject,authorizationPendingModelText,consumeAuthorizationResult,createAuthorizationAttempt,getAuthorizationResult,getAuthorizationResults,getHookUrl,isAuthorizationPendingModelOutput,isAuthorizationSignal,isPendingAuthorizationToolOutput,modelFacingAuthorizationOutput,requestAuthorization};
@@ -41,6 +41,7 @@ export declare function maybeCompact(input: {
41
41
  readonly runtimeIdentity?: ToolLoopHarnessConfig["runtimeIdentity"];
42
42
  readonly session: HarnessSession;
43
43
  readonly telemetry?: TelemetryOptions;
44
+ readonly traceContextHeaders?: () => Record<string, string> | undefined;
44
45
  }): Promise<{
45
46
  readonly compacted: boolean;
46
47
  /** The summary failed; `session` still counts the summary calls that finished. */
@@ -1 +1 @@
1
- import{streamText}from"ai";import{createLogger,logError}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{AuthKey,HistoryStateKey}from"#context/keys.js";import{createCompactionCompletedEvent,createCompactionRequestedEvent}from"#protocol/message.js";import{isUserModelMessage,validateHarnessModelMessages}from"#harness/messages.js";import{drainMemoryCommit,prepareMemoryCompaction}from"#context/memory-lifecycle.js";import{canonicalizeMemoryRecords,shouldCanonicalizeMemory}from"#shared/memory-state.js";import{activeTurnId}from"#harness/session-machine/view.js";import{addTurnUsage,addUsageOutsideTurns}from"#harness/turn-tag-state.js";import{idle}from"#harness/session-machine/transitions.js";import{stepStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{requireSessionModelReference}from"#harness/types.js";import{buildGatewayAttributionHeaders,resolveEffectiveRuntimeModel}from"#harness/model-call/model.js";import{compactMessages,getInputTokenCount,shouldCompact}from"#harness/compaction/engine.js";import{normalizeModelStreamError}from"#harness/model-call/errors.js";import{runModelCallWithRetries}from"#harness/model-call/retry.js";import{extractGatewayCostUsd,extractTokenUsageDelta,gatewayModelId}from"#harness/model-call/usage.js";import{resolveModelProfile}from"#harness/model-profile.js";import{getRequestEnvelopeTokens}from"#harness/request-envelope.js";import{resolveCallProviderOptions}from"#harness/provider-safety.js";const log=createLogger(`harness.tool-loop`);async function compactHistory(e){let{config:t}=e;if(e.session.history.length>0)try{if(e.ctx!==void 0&&t.dispatchDynamicModelEvent!==void 0){let n=e.position();await t.dispatchDynamicModelEvent({ctx:e.ctx,event:stepStartedForResolvers({modelId:e.session.agent.modelReference?.id??`dynamic`,sequence:n.sequence,stepIndex:n.stepIndex,turnId:activeTurnId(n)}),messages:validateHarnessModelMessages(e.projectHistory(e.session.history))})}let n=await resolveEffectiveRuntimeModel({config:t,ctx:e.ctx,session:e.session});e.session=n.session;let r=e.position(),i=await maybeCompact({abortSignal:t.abortSignal,auth:e.ctx?.get(AuthKey)??null,betweenTurns:!0,emissionState:{...r,turnId:activeTurnId(r)},force:!0,historyProjector:t.historyProjector,messages:[...e.session.history],model:n.model,publish:e.publish,requestEnvelopeTokens:getRequestEnvelopeTokens(e.session),resolveModel:t.resolveModel,runtimeIdentity:t.runtimeIdentity,session:e.session,telemetry:e.instrumentation?.telemetry()});if(e.session=i.session,i.failure!==void 0)throw i.failure.error}catch(t){logError(log,`manual session compaction failed`,t,{sessionId:e.session.sessionId})}return await e.apply(idle(e.view())),{next:null,session:e.session}}function replaceSessionHistory(e,t){return contextStorage.getStore()?.delete(HistoryStateKey),{...e,history:t,compaction:{recentWindowSize:e.compaction.recentWindowSize,threshold:e.compaction.threshold,thresholdPercent:e.compaction.thresholdPercent}}}async function maybeCompact(e){let{emissionState:t,publish:n}=e,r=e.messages,i=e.session,a=e.promptMessages??r,o=validateHarnessModelMessages(e.historyProjector?.({messages:a,state:i.state})??a),s=e.force===!0||shouldCompact(o,i.compaction,e.requestEnvelopeTokens,getRequestEnvelopeTokens(i)),c=shouldCanonicalizeMemory(r);if(!s&&!c)return{compacted:!1,messages:r,session:i};let l=requireSessionModelReference(i),u=i.agent.compactionModelReference??l,d=u===l?e.model:await e.resolveModel(u),f=resolveModelProfile(d),p=resolveCallProviderOptions({auth:e.auth,profile:f,providerOptions:u.providerOptions,session:i}),m={abortSignal:e.abortSignal,headers:buildGatewayAttributionHeaders(f,e.runtimeIdentity),model:d,providerOptions:p,telemetry:e.telemetry&&{...e.telemetry,functionId:`eve.compaction`}},h=[],summarize=async n=>{let r=await runModelCallWithRetries(()=>streamCompactionSummary({...m,...n}),{sessionId:i.sessionId,turnId:t.turnId},e.abortSignal);if(h.push(r.usage),r.text.trim().length===0)throw Error(`The compaction model returned an empty summary. Finish reason: ${r.finishReason}.`);return r.text};{let a=contextStorage.getStore();a!==void 0&&prepareMemoryCompaction(a,{history:r,state:i.state}),await n(createCompactionRequestedEvent({modelId:gatewayModelId(d)??`unknown`,sequence:t.sequence,sessionId:i.sessionId,stepIndex:t.stepIndex,turnId:t.turnId,usageInputTokens:getInputTokenCount(o,i.compaction,e.requestEnvelopeTokens,getRequestEnvelopeTokens(i))}),o)}let g=canonicalizeMemoryRecords(r),_=validateHarnessModelMessages(e.historyProjector?.({messages:g.ordinary,state:i.state})??g.ordinary),v=e.requestEnvelopeTokens??0,y={...i.compaction,threshold:Math.max(1,i.compaction.threshold-v),lastKnownInputTokens:i.compaction.lastKnownInputTokens===void 0?void 0:Math.max(0,i.compaction.lastKnownInputTokens-Math.min(getRequestEnvelopeTokens(i)??0,v))},b=[..._],x;try{s&&(b=await compactMessages([..._],y,summarize,e.force===!0,e.requestEnvelopeTokens===void 0?void 0:Math.max(0,getInputTokenCount(o,i.compaction,v,getRequestEnvelopeTokens(i))-v)))}catch(e){x={error:e}}for(let n of h)i=e.betweenTurns===!0?addUsageOutsideTurns(i,n):addTurnUsage(i,t.turnId,n);if(x!==void 0)return{compacted:!1,failure:x,messages:e.messages,session:i};r=validateHarnessModelMessages([...g.memory,...b]);{let a=contextStorage.getStore();if(a!==void 0&&prepareMemoryCompaction(a,{history:r,state:i.state}),await n(createCompactionCompletedEvent({modelId:gatewayModelId(d)??`unknown`,sequence:t.sequence,sessionId:i.sessionId,stepIndex:t.stepIndex,turnId:t.turnId}),e.historyProjector?.({messages:r,state:i.state})??r),a!==void 0){let t=drainMemoryCommit(a);t!==void 0&&(r=validateHarnessModelMessages(placeRecalledMemory(r,t.recalledMessages,e.betweenTurns===!0)),i={...i,state:t.state})}}return{compacted:!0,messages:r,session:replaceSessionHistory(i,r)}}function placeRecalledMemory(e,t,n){let r=n?-1:e.findLastIndex(e=>isUserModelMessage(e)&&e.kind===`user`);return r===-1?[...e,...t]:[...e.slice(0,r),...t,...e.slice(r)]}async function streamCompactionSummary(e){let t=streamText({...e,onError:()=>{}});for await(let e of t.fullStream)if(e.type===`error`)throw normalizeModelStreamError(e.error);let[n,r,i,a]=await Promise.all([t.text,t.finishReason,t.usage,t.providerMetadata]);return{finishReason:r,text:n,usage:extractTokenUsageDelta({costUsd:extractGatewayCostUsd(a),usage:i})}}export{compactHistory,maybeCompact,replaceSessionHistory};
1
+ import{streamText}from"ai";import{createLogger,logError}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{AuthKey,HistoryStateKey}from"#context/keys.js";import{createCompactionCompletedEvent,createCompactionRequestedEvent}from"#protocol/message.js";import{isUserModelMessage,validateHarnessModelMessages}from"#harness/messages.js";import{drainMemoryCommit,prepareMemoryCompaction}from"#context/memory-lifecycle.js";import{canonicalizeMemoryRecords,shouldCanonicalizeMemory}from"#shared/memory-state.js";import{activeTurnId}from"#harness/session-machine/view.js";import{addTurnUsage,addUsageOutsideTurns}from"#harness/turn-tag-state.js";import{idle}from"#harness/session-machine/transitions.js";import{stepStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{requireSessionModelReference}from"#harness/types.js";import{buildGatewayAttributionHeaders,resolveEffectiveRuntimeModel,withGatewayTraceContext}from"#harness/model-call/model.js";import{compactMessages,getInputTokenCount,shouldCompact}from"#harness/compaction/engine.js";import{normalizeModelStreamError}from"#harness/model-call/errors.js";import{runModelCallWithRetries}from"#harness/model-call/retry.js";import{extractGatewayCostUsd,extractTokenUsageDelta,gatewayModelId}from"#harness/model-call/usage.js";import{resolveModelProfile}from"#harness/model-profile.js";import{getRequestEnvelopeTokens}from"#harness/request-envelope.js";import{resolveCallProviderOptions}from"#harness/provider-safety.js";const log=createLogger(`harness.tool-loop`);async function compactHistory(e){let{config:t}=e;if(e.session.history.length>0)try{if(e.ctx!==void 0&&t.dispatchDynamicModelEvent!==void 0){let n=e.position();await t.dispatchDynamicModelEvent({ctx:e.ctx,event:stepStartedForResolvers({modelId:e.session.agent.modelReference?.id??`dynamic`,sequence:n.sequence,stepIndex:n.stepIndex,turnId:activeTurnId(n)}),messages:validateHarnessModelMessages(e.projectHistory(e.session.history))})}let n=await resolveEffectiveRuntimeModel({config:t,ctx:e.ctx,session:e.session});e.session=n.session;let r=e.position(),i=await maybeCompact({abortSignal:t.abortSignal,auth:e.ctx?.get(AuthKey)??null,betweenTurns:!0,emissionState:{...r,turnId:activeTurnId(r)},force:!0,historyProjector:t.historyProjector,messages:[...e.session.history],model:n.model,publish:e.publish,requestEnvelopeTokens:getRequestEnvelopeTokens(e.session),resolveModel:t.resolveModel,runtimeIdentity:t.runtimeIdentity,session:e.session,telemetry:e.instrumentation?.telemetry(),traceContextHeaders:e.instrumentation?.gatewayTraceContextHeaders});if(e.session=i.session,i.failure!==void 0)throw i.failure.error}catch(t){logError(log,`manual session compaction failed`,t,{sessionId:e.session.sessionId})}return await e.apply(idle(e.view())),{next:null,session:e.session}}function replaceSessionHistory(e,t){return contextStorage.getStore()?.delete(HistoryStateKey),{...e,history:t,compaction:{recentWindowSize:e.compaction.recentWindowSize,threshold:e.compaction.threshold,thresholdPercent:e.compaction.thresholdPercent}}}async function maybeCompact(e){let{emissionState:t,publish:n}=e,r=e.messages,i=e.session,a=e.promptMessages??r,o=validateHarnessModelMessages(e.historyProjector?.({messages:a,state:i.state})??a),s=e.force===!0||shouldCompact(o,i.compaction,e.requestEnvelopeTokens,getRequestEnvelopeTokens(i)),c=shouldCanonicalizeMemory(r);if(!s&&!c)return{compacted:!1,messages:r,session:i};let l=requireSessionModelReference(i),u=i.agent.compactionModelReference??l,d=u===l?e.model:await e.resolveModel(u),f=resolveModelProfile(d),p=resolveCallProviderOptions({auth:e.auth,profile:f,providerOptions:u.providerOptions,session:i}),m={abortSignal:e.abortSignal,headers:buildGatewayAttributionHeaders(f,e.runtimeIdentity),model:withGatewayTraceContext(d,f,e.traceContextHeaders),providerOptions:p,telemetry:e.telemetry&&{...e.telemetry,functionId:`eve.compaction`}},h=[],summarize=async n=>{let r=await runModelCallWithRetries(()=>streamCompactionSummary({...m,...n}),{sessionId:i.sessionId,turnId:t.turnId},e.abortSignal);if(h.push(r.usage),r.text.trim().length===0)throw Error(`The compaction model returned an empty summary. Finish reason: ${r.finishReason}.`);return r.text};{let a=contextStorage.getStore();a!==void 0&&prepareMemoryCompaction(a,{history:r,state:i.state}),await n(createCompactionRequestedEvent({modelId:gatewayModelId(d)??`unknown`,sequence:t.sequence,sessionId:i.sessionId,stepIndex:t.stepIndex,turnId:t.turnId,usageInputTokens:getInputTokenCount(o,i.compaction,e.requestEnvelopeTokens,getRequestEnvelopeTokens(i))}),o)}let g=canonicalizeMemoryRecords(r),_=validateHarnessModelMessages(e.historyProjector?.({messages:g.ordinary,state:i.state})??g.ordinary),v=e.requestEnvelopeTokens??0,y={...i.compaction,threshold:Math.max(1,i.compaction.threshold-v),lastKnownInputTokens:i.compaction.lastKnownInputTokens===void 0?void 0:Math.max(0,i.compaction.lastKnownInputTokens-Math.min(getRequestEnvelopeTokens(i)??0,v))},b=[..._],x;try{s&&(b=await compactMessages([..._],y,summarize,e.force===!0,e.requestEnvelopeTokens===void 0?void 0:Math.max(0,getInputTokenCount(o,i.compaction,v,getRequestEnvelopeTokens(i))-v)))}catch(e){x={error:e}}for(let n of h)i=e.betweenTurns===!0?addUsageOutsideTurns(i,n):addTurnUsage(i,t.turnId,n);if(x!==void 0)return{compacted:!1,failure:x,messages:e.messages,session:i};r=validateHarnessModelMessages([...g.memory,...b]);{let a=contextStorage.getStore();if(a!==void 0&&prepareMemoryCompaction(a,{history:r,state:i.state}),await n(createCompactionCompletedEvent({modelId:gatewayModelId(d)??`unknown`,sequence:t.sequence,sessionId:i.sessionId,stepIndex:t.stepIndex,turnId:t.turnId}),e.historyProjector?.({messages:r,state:i.state})??r),a!==void 0){let t=drainMemoryCommit(a);t!==void 0&&(r=validateHarnessModelMessages(placeRecalledMemory(r,t.recalledMessages,e.betweenTurns===!0)),i={...i,state:t.state})}}return{compacted:!0,messages:r,session:replaceSessionHistory(i,r)}}function placeRecalledMemory(e,t,n){let r=n?-1:e.findLastIndex(e=>isUserModelMessage(e)&&e.kind===`user`);return r===-1?[...e,...t]:[...e.slice(0,r),...t,...e.slice(r)]}async function streamCompactionSummary(e){let t=streamText({...e,onError:()=>{}});for await(let e of t.fullStream)if(e.type===`error`)throw normalizeModelStreamError(e.error);let[n,r,i,a]=await Promise.all([t.text,t.finishReason,t.usage,t.providerMetadata]);return{finishReason:r,text:n,usage:extractTokenUsageDelta({costUsd:extractGatewayCostUsd(a),usage:i})}}export{compactHistory,maybeCompact,replaceSessionHistory};
@@ -1 +1 @@
1
- import{skillTarget}from"#shared/action-request-name.js";import{SKILL_ENTRY_NAME,SKILL_TOOL_NAME}from"#protocol/catalog-tools.js";import{parseJsonObject}from"#shared/json.js";import{findBlockingWorkflowToolRun,removeBlockingWorkflowToolRuns}from"#harness/workflow-tool-runs.js";import{startsTasks}from"#execution/tasks/tool-entry-point.js";import{commitCallEntry,isTaskTool}from"#execution/tasks/model-step.js";import{getProxyInputRequests}from"#harness/proxy-input-requests.js";import{normalizeToolModelOutput}from"#harness/tool-model-output.js";import{observeToolOutput}from"#tool-stubs/execute.js";import{markRuntimeWorkflowToolAction}from"#shared/action-types.js";function assertUniqueCoordinationCallIds(e){let t=new Set;for(let n of e){if(t.has(n.callId))throw Error(`Coordination batch contains duplicate callId "${n.callId}".`);t.add(n.callId)}}function forgetFinishedRuns(e,t,n){let r=e,i=[];for(let e of t){if(e.kind!==`tool-result`)continue;let t=findBlockingWorkflowToolRun(r.state,e.callId,n);if(t!==void 0){for(let[e,n]of getProxyInputRequests(r.state))n.runId===t.address.runId&&i.push(e);r=removeBlockingWorkflowToolRuns(r,n,t.callId)}}return{requestIds:i,session:r}}async function runtimeResultCalls(e,t){let n=[];for(let r of e){switch(r.kind){case`load-skill-result`:n.push({part:toolResult(r,SKILL_TOOL_NAME,toToolResultOutput(r)),result:r});continue;case`subagent-result`:n.push({part:toolResult(r,r.subagentName,toToolResultOutput(r)),result:r});continue;case`tool-result`:n.push({part:toolResult(r,r.toolName,await projectToolResultOutput(r,t?.get(r.toolName))),result:r});continue}throw Error(`Unsupported runtime action result kind "${String(r)}".`)}return n}function toolResult(e,t,n){return{output:n,toolCallId:e.callId,toolName:t,type:`tool-result`}}function collectWorkflowCalls(e){let{session:t}=e,n=[];for(let r of e.toolCalls){let i=e.tools.get(r.toolName);if(isTaskTool(i))continue;let a=commitCallEntry(t,{callId:r.toolCallId,definition:i,input:resolveToolCallInputObject(r.input,{callId:r.toolCallId,toolName:r.toolName}),toolName:r.toolName,turnId:e.turnId});t=a.session,n.push(createCoordinationRequestFromToolCall({entry:a.entry,input:a.input,toolCall:r,tools:e.tools}))}return{session:t,workflowRequests:n}}function createRuntimeActionRequestFromToolCall(e){let t=e.tools.get(e.toolCall.toolName),n=resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),r=e.toolCall.toolName===SKILL_ENTRY_NAME?skillTarget(n):void 0;if(r!==void 0)return{callId:e.toolCall.toolCallId,input:n,kind:`load-skill`,name:r};let i=t?.behavior?.handling;if(t!==void 0&&i?.kind===`dispatch`&&i.target.kind!==`workflow-tool-call`){let r=i.target,a={callId:e.toolCall.toolCallId,description:t.description,input:n,name:e.toolCall.toolName,nodeId:r.nodeId};return r.kind===`remote-agent-call`?{...a,kind:`remote-agent-call`,remoteAgentName:r.remoteAgentName}:{...a,kind:`subagent-call`,subagentName:r.subagentName}}let a={callId:e.toolCall.toolCallId,input:n,kind:`tool-call`,toolName:e.toolCall.toolName};return t?.workflowId===void 0?a:markRuntimeWorkflowToolAction(a)}function createCoordinationRequestFromToolCall(e){let t=e.tools.get(e.toolCall.toolName);if(t?.workflowId===void 0)throw Error(`Workflow tool "${e.toolCall.toolName}" has no workflow.`);return{callId:e.toolCall.toolCallId,entry:e.entry,executeInput:t.executeInput?.(e.input),input:e.input,kind:`workflow-task`,toolName:e.toolCall.toolName,workflowId:t.workflowId}}function resolveToolCallInputObject(e,t){if(e==null||typeof e==`string`&&e.trim()===``)return{};try{return parseJsonObject(typeof e==`string`?parseJsonStringInput(e):e)}catch(e){let n=e instanceof Error?e.message:String(e);throw TypeError(`Failed to parse tool-call arguments for "${t.toolName}" (${t.callId}): ${n}`,{cause:e})}}function parseJsonStringInput(e){return JSON.parse(e)}async function projectToolResultOutput(e,t){return e.isError===!0||t?.toModelOutput===void 0||startsTasks(t)?toToolResultOutput(e):await observeToolOutput(e.toolName,[{callId:e.callId}],async()=>normalizeToolModelOutput({output:await t.toModelOutput(e.output),toolCallId:e.callId,toolName:e.toolName}))}function toToolResultOutput(e){return typeof e.output==`string`?e.isError===!0?{type:`error-text`,value:e.output}:{type:`text`,value:e.output}:e.isError===!0?{type:`error-json`,value:toMutableJsonValue(e.output)}:{type:`json`,value:toMutableJsonValue(e.output)}}function toMutableJsonValue(e){if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(Array.isArray(e))return e.map(e=>toMutableJsonValue(e));let t={};for(let[n,r]of Object.entries(e))t[n]=toMutableJsonValue(r);return t}export{assertUniqueCoordinationCallIds,collectWorkflowCalls,createCoordinationRequestFromToolCall,createRuntimeActionRequestFromToolCall,forgetFinishedRuns,resolveToolCallInputObject,runtimeResultCalls};
1
+ import{skillTarget}from"#shared/action-request-name.js";import{SKILL_ENTRY_NAME,SKILL_TOOL_NAME}from"#protocol/catalog-tools.js";import{parseJsonObject}from"#shared/json.js";import{findBlockingWorkflowToolRun,removeBlockingWorkflowToolRuns}from"#harness/workflow-tool-runs.js";import{readHitlState}from"#harness/hitl/index.js";import{startsTasks}from"#execution/tasks/tool-entry-point.js";import{commitCallEntry,isTaskTool}from"#execution/tasks/model-step.js";import{normalizeToolModelOutput}from"#harness/tool-model-output.js";import{observeToolOutput}from"#tool-stubs/execute.js";import{markRuntimeWorkflowToolAction}from"#shared/action-types.js";function assertUniqueCoordinationCallIds(e){let t=new Set;for(let n of e){if(t.has(n.callId))throw Error(`Coordination batch contains duplicate callId "${n.callId}".`);t.add(n.callId)}}function forgetFinishedRuns(e,t,n){let r=e,i=[];for(let e of t){if(e.kind!==`tool-result`)continue;let t=findBlockingWorkflowToolRun(r.state,e.callId,n);if(t!==void 0){for(let[e,n]of readHitlState(r.state).relays)n.runId===t.address.runId&&i.push(e);r=removeBlockingWorkflowToolRuns(r,n,t.callId)}}return{requestIds:i,session:r}}async function runtimeResultCalls(e,t){let n=[];for(let r of e){switch(r.kind){case`load-skill-result`:n.push({part:toolResult(r,SKILL_TOOL_NAME,toToolResultOutput(r)),result:r});continue;case`subagent-result`:n.push({part:toolResult(r,r.subagentName,toToolResultOutput(r)),result:r});continue;case`tool-result`:n.push({part:toolResult(r,r.toolName,await projectToolResultOutput(r,t?.get(r.toolName))),result:r});continue}throw Error(`Unsupported runtime action result kind "${String(r)}".`)}return n}function toolResult(e,t,n){return{output:n,toolCallId:e.callId,toolName:t,type:`tool-result`}}function collectWorkflowCalls(e){let{session:t}=e,n=[];for(let r of e.toolCalls){let i=e.tools.get(r.toolName);if(isTaskTool(i))continue;let a=commitCallEntry(t,{callId:r.toolCallId,definition:i,input:resolveToolCallInputObject(r.input,{callId:r.toolCallId,toolName:r.toolName}),toolName:r.toolName,turnId:e.turnId});t=a.session,n.push(createCoordinationRequestFromToolCall({entry:a.entry,input:a.input,toolCall:r,tools:e.tools}))}return{session:t,workflowRequests:n}}function createRuntimeActionRequestFromToolCall(e){let t=e.tools.get(e.toolCall.toolName),n=resolveToolCallInputObject(e.toolCall.input,{callId:e.toolCall.toolCallId,toolName:e.toolCall.toolName}),r=e.toolCall.toolName===SKILL_ENTRY_NAME?skillTarget(n):void 0;if(r!==void 0)return{callId:e.toolCall.toolCallId,input:n,kind:`load-skill`,name:r};let i=t?.behavior?.handling;if(t!==void 0&&i?.kind===`dispatch`&&i.target.kind!==`workflow-tool-call`){let r=i.target,a={callId:e.toolCall.toolCallId,description:t.description,input:n,name:e.toolCall.toolName,nodeId:r.nodeId};return r.kind===`remote-agent-call`?{...a,kind:`remote-agent-call`,remoteAgentName:r.remoteAgentName}:{...a,kind:`subagent-call`,subagentName:r.subagentName}}let a={callId:e.toolCall.toolCallId,input:n,kind:`tool-call`,toolName:e.toolCall.toolName};return t?.workflowId===void 0?a:markRuntimeWorkflowToolAction(a)}function createCoordinationRequestFromToolCall(e){let t=e.tools.get(e.toolCall.toolName);if(t?.workflowId===void 0)throw Error(`Workflow tool "${e.toolCall.toolName}" has no workflow.`);return{callId:e.toolCall.toolCallId,entry:e.entry,executeInput:t.executeInput?.(e.input),input:e.input,kind:`workflow-task`,toolName:e.toolCall.toolName,workflowId:t.workflowId}}function resolveToolCallInputObject(e,t){if(e==null||typeof e==`string`&&e.trim()===``)return{};try{return parseJsonObject(typeof e==`string`?parseJsonStringInput(e):e)}catch(e){let n=e instanceof Error?e.message:String(e);throw TypeError(`Failed to parse tool-call arguments for "${t.toolName}" (${t.callId}): ${n}`,{cause:e})}}function parseJsonStringInput(e){return JSON.parse(e)}async function projectToolResultOutput(e,t){return e.isError===!0||t?.toModelOutput===void 0||startsTasks(t)?toToolResultOutput(e):await observeToolOutput(e.toolName,[{callId:e.callId}],async()=>normalizeToolModelOutput({output:await t.toModelOutput(e.output),toolCallId:e.callId,toolName:e.toolName}))}function toToolResultOutput(e){return typeof e.output==`string`?e.isError===!0?{type:`error-text`,value:e.output}:{type:`text`,value:e.output}:e.isError===!0?{type:`error-json`,value:toMutableJsonValue(e.output)}:{type:`json`,value:toMutableJsonValue(e.output)}}function toMutableJsonValue(e){if(e===null||typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return e;if(Array.isArray(e))return e.map(e=>toMutableJsonValue(e));let t={};for(let[n,r]of Object.entries(e))t[n]=toMutableJsonValue(r);return t}export{assertUniqueCoordinationCallIds,collectWorkflowCalls,createCoordinationRequestFromToolCall,createRuntimeActionRequestFromToolCall,forgetFinishedRuns,resolveToolCallInputObject,runtimeResultCalls};
@@ -1,5 +1,5 @@
1
1
  import type { FlexibleSchema } from "ai";
2
- import type { Approval } from "#approval/definition.js";
2
+ import type { ToolApproval } from "#approval/definition.js";
3
3
  import type { InternalToolDefinition, InternalToolLabelDefinition, ToolExecuteOptions } from "#tools/definition.js";
4
4
  import type { JsonValue } from "#shared/json.js";
5
5
  import type { PreparedToolBehavior } from "#tools/behavior.js";
@@ -23,7 +23,7 @@ export interface HarnessToolDefinition {
23
23
  readonly frameworkAction?: "task-cancel" | "task-wait";
24
24
  readonly inputSchema: FlexibleSchema;
25
25
  readonly name: string;
26
- readonly approval?: Approval;
26
+ readonly approval?: ToolApproval;
27
27
  readonly outputSchema?: FlexibleSchema;
28
28
  /**
29
29
  * Advertise this tool only to the root session, hiding it from subagent
@@ -1,6 +1,6 @@
1
1
  import type { ModelMessage } from "ai";
2
2
  import type { getApprovalAuditState } from "#harness/hitl/candidates.js";
3
- import { type AuthorizationChallenge } from "#harness/authorization.js";
3
+ import type { AuthorizationChallenge } from "#harness/authorization.js";
4
4
  import { type ResolvedInputBatch } from "#harness/input-request-resolution.js";
5
5
  import type { StepInput } from "#harness/types.js";
6
6
  import type { RuntimeWorkflowTaskRequest } from "#shared/action-types.js";
@@ -1 +1 @@
1
- import{canonicalize,compactInput,isEmptyInput,resolveTextInput,withoutResponses}from"./delivery.js";import{openInputs,turnCoordinates}from"#protocol/session-projection.js";import{readClientContext}from"#internal/client-context.js";import{createActionResultEvent,createApprovalCandidateEvent,createApprovalSettledEvent,createAuthorizationCompletedEvent,createAuthorizationRequiredEvent,createInputRequestedEvent,createInputResolvedEvent,createMessageCompletedEvent}from"#protocol/message.js";import{coalesceTurnInputs,createFrameworkUserMessage}from"#harness/messages.js";import{turnPosition}from"#harness/session-machine/view.js";import{renderPendingApprovalsSnippet}from"#harness/hitl/approval-prompt.js";import{supersededChallenges,withSignIns}from"#harness/authorization.js";import{hold,ownOpenRequestIds,settle,stepCallIds,suspend,withResult,withoutApproved}from"#harness/session-machine/transitions.js";import{withoutCalls}from"#harness/inline-tool-authorization.js";import{isApprovalRequest}from"#harness/input-request-class.js";import{authorizationEventFields}from"#harness/authorization-event-fields.js";import{TOOL_EXECUTION_DENIED_MESSAGE,failedCall,resolveApprovalOutcome,resolveInputOutcome,unavailableToolMessage}from"#harness/input-request-resolution.js";import{resolveSessionLimitContinuation}from"#harness/hitl/budget-request.js";import{signInWithdrawn}from"#harness/session-machine/events.js";function parkOnApprovals(e,t){let n=t.requester?.principalType===`anonymous`?null:t.requester,r=t.messages.findIndex(e=>e.role!==`tool`),i=r===-1?t.messages:t.messages.slice(0,r),a=renderPendingApprovalsSnippet(t.requests),o=suspend(e.turn,{event:t.event,messages:t.messages.slice(i.length),requester:n,requests:t.requests,responseAuthRequiredRequestIds:t.responseAuthRequiredRequestIds,tasks:t.tasks});return{commit:[...i,...a===void 0?[]:[createFrameworkUserMessage(`context.state`,a)]],events:t.tasks.length>0?[]:[createInputRequestedEvent({requests:t.requests,...t.event})],turn:o}}function dispatch(e,t){let n=e.turn.suspended.map(e=>{let n=stepCallIds(e),r=t.tasks.filter(e=>n.has(e.callId));return r.length===0?e:{...withoutApproved(e,new Set(r.map(e=>e.callId))),tasks:[...e.tasks,...r]}});return{events:[],turn:{...e.turn,suspended:n}}}function deferInput(e,t){return{events:[],turn:withQueued(e.turn,t)}}function withQueued(e,t){return t===void 0||isEmptyInput(t)?e:{...e,queued:e.queued===void 0?t:coalesceTurnInputs(e.queued,t)}}function answer(e,t){let{policy:n}=t,{projection:r}=e,i=turnPosition(r),a=[...n.feedback.map(e=>createMessageCompletedEvent({message:e,sequence:i.sequence,stepIndex:i.stepIndex,turnId:i.turnId})),...reportApprovalProgress(r,n.audit,n.challengesAtStart)],o=t.takeQueued?{...e.turn,queued:void 0}:e.turn,done=e=>({events:a,resolved:[],turn:o,...e}),queue=e=>{o=withQueued(o,e)};if(n.kind===`park`)return done({next:`park`});if(n.kind===`continue-coordination`)return queue(n.stepInput),done({next:`repeat`});if(n.challenges.length>0)return done({next:`sign-in`});let s=t.delivery,c=openInputs(r).find(t=>t.request.kind===`session-limit`&&ownOpenRequestIds(e).has(t.request.requestId)),l=o.suspended.filter(e=>e.requests.length>0);if(c===void 0&&l.length===0)return done({input:s,next:`continue`});let u=c===void 0?s:resolveTextInput({requests:[c.request]},s),d=canonicalize(u?.inputResponses??[]),f=new Map(d.map(e=>[e.requestId,e])),p=l.filter(e=>e.requests.every(e=>f.has(e.requestId))),leftoverFor=e=>d.filter(t=>e.some(e=>e.requests.some(e=>e.requestId===t.requestId))),park=()=>(queue(compactInput(u)),done({next:`park`}));if(d.length===0&&u?.message===void 0)return park();if(c!==void 0){let e=f.get(c.request.requestId);if(e===void 0)return park();let t={event:{sequence:c.sequence,stepIndex:c.stepIndex,turnId:c.turnId},inputs:[{outcome:resolveInputOutcome(c.request.kind,e),request:c.request,response:e}]};a.push(resolvedEvent(t));let n=leftoverFor(l);return n.length>0&&queue({inputResponses:n}),done({consumedMessage:u?.messageConsumed,input:withoutResponses(u),limit:resolveSessionLimitContinuation({requests:[c.request],responses:d}),next:`continue`,resolved:[t]})}if(p.length===0&&u?.message===void 0)return park();p.length===0&&p.push(l[0]);let m=leftoverFor(l.filter(e=>!p.includes(e)));m.length>0&&queue({inputResponses:m});let h=new Set(o.grants),g=[],_=[],v=new Set(n.audit.settlements.filter(e=>e.outcome===`unavailable`).map(e=>e.requestId)),y=o.suspended.map(e=>{if(!p.includes(e))return e;let n=e.messages,r=[];for(let i of e.requests){let{callId:a,toolName:o}=i.action;if(v.has(i.requestId)){let r=failedCall({callId:a,message:unavailableToolMessage(o,t.searchable(i)),toolName:o});n=withResult(n,r.part),_.push(createActionResultEvent({result:r.result,...e.event}));continue}let{approved:s,reason:c,status:l}=resolveApprovalOutcome(f.get(i.requestId));if(s){h.add(t.approvalKey(i)??o),r.push(i);continue}n=withResult(n,{output:{reason:c,type:`execution-denied`},toolCallId:a,toolName:o,type:`tool-result`}),_.push(createActionResultEvent({rejected:!0,result:{callId:a,isError:!0,kind:`tool-result`,output:{approval:{requestId:i.requestId,status:l},code:`TOOL_EXECUTION_DENIED`,message:c??TOOL_EXECUTION_DENIED_MESSAGE,tool:{result:`not_run`}},toolName:o},...e.event}))}g.push({event:e.event,inputs:e.requests.map(e=>{let t=f.get(e.requestId);return{outcome:resolveInputOutcome(e.kind,t),request:e,response:t}})});let i=[...e.approved??[],...r];return{...e,messages:n,requests:[],...i.length>0&&{approved:i}}});return a.push(...g.map(resolvedEvent),..._),o={...o,grants:[...h],suspended:y},done({consumedMessage:u?.messageConsumed,input:withoutResponses(u),next:`continue`,resolved:g})}function resolvedEvent(e){return createInputResolvedEvent({resolutions:e.inputs.map(e=>{let t={kind:e.request.kind,outcome:e.outcome,requestId:e.request.requestId};return e.response===void 0?t:{...t,response:e.response}}),...e.event})}function reportApprovalProgress(e,t,n){let r=turnCoordinates(e),isOpen=t=>{let n=e.inputs[t];return n!==void 0&&n.status!==`settled`},i=[];for(let a of n){let n=t.candidateHistory.some(e=>e.candidateId===a.candidateId&&e.status===`timed-out`),o=e.authorizations[a.attemptId??a.name];n&&o?.status===`required`&&i.push(createAuthorizationCompletedEvent({...authorizationEventFields(a),outcome:`failed`,reason:`The approval response expired. Please submit a new response.`,...r}))}for(let n of t.activeCandidates)e.candidates[n.candidateId]===void 0&&isOpen(n.requestId)&&i.push(createApprovalCandidateEvent({candidateId:n.candidateId,outcome:`pending`,requestId:n.requestId,responderPrincipalId:n.responder.principalId,...r}));for(let n of t.candidateHistory)n.status!==`allowed`&&n.status!==`authorization-required`&&e.inputs[n.requestId]!==void 0&&e.candidates[n.candidateId]?.outcome!==n.status&&i.push(createApprovalCandidateEvent({candidateId:n.candidateId,outcome:n.status,requestId:n.requestId,responderPrincipalId:n.responder.principalId,reason:n.reason,...r}));for(let e of t.settlements)isOpen(e.requestId)&&e.outcome!==`unavailable`&&i.push(createApprovalSettledEvent({outcome:e.outcome===`allowed`?`approved`:`cancelled`,requestId:e.requestId,responderPrincipalId:e.actor.principalId,...r}));return i}function hasRunnableQueue(e){let t=e.turn.queued;if(t===void 0)return!1;let n=[...t.inputResponses??[],...(t.attributedInputResponses??[]).map(({response:e})=>e)],r=new Set(n.map(e=>e.requestId)),i=openInputs(e.projection).find(e=>e.request.kind===`session-limit`);return i===void 0?t.message!==void 0||(t.context?.length??0)>0||readClientContext(t)!==void 0||t.outputSchema!==void 0||(t.runtimeActionResults?.length??0)>0||n.length!==0&&e.turn.suspended.some(e=>e.requests.length>0&&e.requests.every(e=>r.has(e.requestId))):r.has(i.request.requestId)}function grantedApprovalKeys(e,t){let n=new Set(e.turn.grants);for(let r of e.turn.suspended)for(let e of r.requests)isApprovalRequest(e)&&n.delete(t(e)??e.action.toolName);return n}function approvingSteps(e,t){let n=e.turn.suspended.filter(e=>e.requests.length>0),r=new Map((t?.inputResponses??[]).map(e=>[e.requestId,e.optionId]));return n.filter(e=>e.requests.every(e=>r.has(e.requestId))&&e.requests.some(e=>isApprovalRequest(e)&&r.get(e.requestId)===`approve`))}function stepForRequest(e,t){return e.turn.suspended.find(e=>e.requests.some(e=>e.requestId===t))}function withdrawSignIns(e,t){return{events:e.signIns.flatMap(n=>{let r=e.projection.authorizations[n.attemptId??n.name];return r?.status===`required`?[signInWithdrawn(r,t)]:[]}),signIns:[],turn:e.turn}}function requestLimit(e,t){let n=turnPosition(e.projection);return{events:[createInputRequestedEvent({requests:[t.request],sequence:n.sequence,stepIndex:n.stepIndex,turnId:n.turnId}),...hold(e,{on:`input`}).events],turn:e.turn}}function requireSignIn(e,t){let n=turnPosition(e.projection),r={sequence:n.sequence,stepIndex:n.stepIndex,turnId:n.turnId},i=[...supersededChallenges(e.signIns,t.challenges).map(e=>createAuthorizationCompletedEvent({...authorizationEventFields(e),outcome:`failed`,reason:`Superseded by a newer authorization attempt.`,...r})),...t.challenges.map(e=>createAuthorizationRequiredEvent({...authorizationEventFields(e),description:e.challenge.instructions??`Authorization required for ${e.name}`,webhookUrl:e.hookUrl,...r}))];i.push(...hold(e,{on:`input`}).events);let a=t.queued===void 0?e.turn.queued:e.turn.queued===void 0?t.queued:coalesceTurnInputs(e.turn.queued,t.queued),o=withSignIns(e.signIns,t.challenges),s=new Set([...t.callIdsByName?.values()??[]].flat()),c=e.turn.suspended.map(e=>[...stepCallIds(e)].some(e=>s.has(e))?{...e,messages:withoutCalls(e.messages,s)}:e);if(c.every((t,n)=>t===e.turn.suspended[n]))return{events:i,signIns:o,turn:{...e.turn,queued:a}};let l=settle({...e,turn:{...e.turn,queued:a,suspended:c}},{results:[]});return{commit:l.commit,events:i,signIns:o,turn:l.turn}}export{answer,approvingSteps,deferInput,dispatch,grantedApprovalKeys,hasRunnableQueue,parkOnApprovals,requestLimit,requireSignIn,stepForRequest,withdrawSignIns};
1
+ import{supersededChallenges,withSignIns}from"./sign-ins.js";import{canonicalize,compactInput,isEmptyInput,resolveTextInput,withoutResponses}from"./delivery.js";import{openInputs,turnCoordinates}from"#protocol/session-projection.js";import{readClientContext}from"#internal/client-context.js";import{createActionResultEvent,createApprovalCandidateEvent,createApprovalSettledEvent,createAuthorizationCompletedEvent,createAuthorizationRequiredEvent,createInputRequestedEvent,createInputResolvedEvent,createMessageCompletedEvent}from"#protocol/message.js";import{coalesceTurnInputs,createFrameworkUserMessage}from"#harness/messages.js";import{turnPosition}from"#harness/session-machine/view.js";import{renderPendingApprovalsSnippet}from"#harness/hitl/approval-prompt.js";import{hold,ownOpenRequestIds,settle,stepCallIds,suspend,withResult,withoutApproved}from"#harness/session-machine/transitions.js";import{withoutCalls}from"#harness/inline-tool-authorization.js";import{isApprovalRequest}from"#harness/input-request-class.js";import{authorizationEventFields}from"#harness/authorization-event-fields.js";import{TOOL_EXECUTION_DENIED_MESSAGE,failedCall,resolveApprovalOutcome,resolveInputOutcome,unavailableToolMessage}from"#harness/input-request-resolution.js";import{resolveSessionLimitContinuation}from"#harness/hitl/budget-request.js";import{signInWithdrawn}from"#harness/session-machine/events.js";function parkOnApprovals(e,t){let n=t.requester?.principalType===`anonymous`?null:t.requester,r=t.messages.findIndex(e=>e.role!==`tool`),i=r===-1?t.messages:t.messages.slice(0,r),a=renderPendingApprovalsSnippet(t.requests),o=suspend(e.turn,{event:t.event,messages:t.messages.slice(i.length),requester:n,requests:t.requests,responseAuthRequiredRequestIds:t.responseAuthRequiredRequestIds,tasks:t.tasks});return{commit:[...i,...a===void 0?[]:[createFrameworkUserMessage(`context.state`,a)]],events:t.tasks.length>0?[]:[createInputRequestedEvent({requests:t.requests,...t.event})],turn:o}}function dispatch(e,t){let n=e.turn.suspended.map(e=>{let n=stepCallIds(e),r=t.tasks.filter(e=>n.has(e.callId));return r.length===0?e:{...withoutApproved(e,new Set(r.map(e=>e.callId))),tasks:[...e.tasks,...r]}});return{events:[],turn:{...e.turn,suspended:n}}}function deferInput(e,t){return{events:[],turn:withQueued(e.turn,t)}}function withQueued(e,t){return t===void 0||isEmptyInput(t)?e:{...e,queued:e.queued===void 0?t:coalesceTurnInputs(e.queued,t)}}function answer(e,t){let{policy:n}=t,{projection:r}=e,i=turnPosition(r),a=[...n.feedback.map(e=>createMessageCompletedEvent({message:e,sequence:i.sequence,stepIndex:i.stepIndex,turnId:i.turnId})),...reportApprovalProgress(r,n.audit,n.challengesAtStart)],o=t.takeQueued?{...e.turn,queued:void 0}:e.turn,done=e=>({events:a,resolved:[],turn:o,...e}),queue=e=>{o=withQueued(o,e)};if(n.kind===`park`)return done({next:`park`});if(n.kind===`continue-coordination`)return queue(n.stepInput),done({next:`repeat`});if(n.challenges.length>0)return done({next:`sign-in`});let s=t.delivery,c=openInputs(r).find(t=>t.request.kind===`session-limit`&&ownOpenRequestIds(e).has(t.request.requestId)),l=o.suspended.filter(e=>e.requests.length>0);if(c===void 0&&l.length===0)return done({input:s,next:`continue`});let u=c===void 0?s:resolveTextInput({requests:[c.request]},s),d=canonicalize(u?.inputResponses??[]),f=new Map(d.map(e=>[e.requestId,e])),p=l.filter(e=>e.requests.every(e=>f.has(e.requestId))),leftoverFor=e=>d.filter(t=>e.some(e=>e.requests.some(e=>e.requestId===t.requestId))),park=()=>(queue(compactInput(u)),done({next:`park`}));if(d.length===0&&u?.message===void 0)return park();if(c!==void 0){let e=f.get(c.request.requestId);if(e===void 0)return park();let t={event:{sequence:c.sequence,stepIndex:c.stepIndex,turnId:c.turnId},inputs:[{outcome:resolveInputOutcome(c.request.kind,e),request:c.request,response:e}]};a.push(resolvedEvent(t));let n=leftoverFor(l);return n.length>0&&queue({inputResponses:n}),done({consumedMessage:u?.messageConsumed,input:withoutResponses(u),limit:resolveSessionLimitContinuation({requests:[c.request],responses:d}),next:`continue`,resolved:[t]})}if(p.length===0&&u?.message===void 0)return park();p.length===0&&p.push(l[0]);let m=leftoverFor(l.filter(e=>!p.includes(e)));m.length>0&&queue({inputResponses:m});let h=new Set(o.grants),g=[],_=[],v=new Set(n.audit.settlements.filter(e=>e.outcome===`unavailable`).map(e=>e.requestId)),y=o.suspended.map(e=>{if(!p.includes(e))return e;let n=e.messages,r=[];for(let i of e.requests){let{callId:a,toolName:o}=i.action;if(v.has(i.requestId)){let r=failedCall({callId:a,message:unavailableToolMessage(o,t.searchable(i)),toolName:o});n=withResult(n,r.part),_.push(createActionResultEvent({result:r.result,...e.event}));continue}let{approved:s,reason:c,status:l}=resolveApprovalOutcome(f.get(i.requestId));if(s){h.add(t.approvalKey(i)??o),r.push(i);continue}n=withResult(n,{output:{reason:c,type:`execution-denied`},toolCallId:a,toolName:o,type:`tool-result`}),_.push(createActionResultEvent({rejected:!0,result:{callId:a,isError:!0,kind:`tool-result`,output:{approval:{requestId:i.requestId,status:l},code:`TOOL_EXECUTION_DENIED`,message:c??TOOL_EXECUTION_DENIED_MESSAGE,tool:{result:`not_run`}},toolName:o},...e.event}))}g.push({event:e.event,inputs:e.requests.map(e=>{let t=f.get(e.requestId);return{outcome:resolveInputOutcome(e.kind,t),request:e,response:t}})});let i=[...e.approved??[],...r];return{...e,messages:n,requests:[],...i.length>0&&{approved:i}}});return a.push(...g.map(resolvedEvent),..._),o={...o,grants:[...h],suspended:y},done({consumedMessage:u?.messageConsumed,input:withoutResponses(u),next:`continue`,resolved:g})}function resolvedEvent(e){return createInputResolvedEvent({resolutions:e.inputs.map(e=>{let t={kind:e.request.kind,outcome:e.outcome,requestId:e.request.requestId};return e.response===void 0?t:{...t,response:e.response}}),...e.event})}function reportApprovalProgress(e,t,n){let r=turnCoordinates(e),isOpen=t=>{let n=e.inputs[t];return n!==void 0&&n.status!==`settled`},i=[];for(let a of n){let n=t.candidateHistory.some(e=>e.candidateId===a.candidateId&&e.status===`timed-out`),o=e.authorizations[a.attemptId??a.name];n&&o?.status===`required`&&i.push(createAuthorizationCompletedEvent({...authorizationEventFields(a),outcome:`failed`,reason:`The approval response expired. Please submit a new response.`,...r}))}for(let n of t.activeCandidates)e.candidates[n.candidateId]===void 0&&isOpen(n.requestId)&&i.push(createApprovalCandidateEvent({candidateId:n.candidateId,outcome:`pending`,requestId:n.requestId,responderPrincipalId:n.responder.principalId,...r}));for(let n of t.candidateHistory)n.status!==`allowed`&&n.status!==`authorization-required`&&e.inputs[n.requestId]!==void 0&&e.candidates[n.candidateId]?.outcome!==n.status&&i.push(createApprovalCandidateEvent({candidateId:n.candidateId,outcome:n.status,requestId:n.requestId,responderPrincipalId:n.responder.principalId,reason:n.reason,...r}));for(let e of t.settlements)isOpen(e.requestId)&&e.outcome!==`unavailable`&&i.push(createApprovalSettledEvent({outcome:e.outcome===`allowed`?`approved`:`cancelled`,requestId:e.requestId,responderPrincipalId:e.actor.principalId,...r}));return i}function hasRunnableQueue(e){let t=e.turn.queued;if(t===void 0)return!1;let n=[...t.inputResponses??[],...(t.attributedInputResponses??[]).map(({response:e})=>e)],r=new Set(n.map(e=>e.requestId)),i=openInputs(e.projection).find(e=>e.request.kind===`session-limit`);return i===void 0?t.message!==void 0||(t.context?.length??0)>0||readClientContext(t)!==void 0||t.outputSchema!==void 0||(t.runtimeActionResults?.length??0)>0||n.length!==0&&e.turn.suspended.some(e=>e.requests.length>0&&e.requests.every(e=>r.has(e.requestId))):r.has(i.request.requestId)}function grantedApprovalKeys(e,t){let n=new Set(e.turn.grants);for(let r of e.turn.suspended)for(let e of r.requests)isApprovalRequest(e)&&n.delete(t(e)??e.action.toolName);return n}function approvingSteps(e,t){let n=e.turn.suspended.filter(e=>e.requests.length>0),r=new Map((t?.inputResponses??[]).map(e=>[e.requestId,e.optionId]));return n.filter(e=>e.requests.every(e=>r.has(e.requestId))&&e.requests.some(e=>isApprovalRequest(e)&&r.get(e.requestId)===`approve`))}function stepForRequest(e,t){return e.turn.suspended.find(e=>e.requests.some(e=>e.requestId===t))}function withdrawSignIns(e,t){return{events:e.signIns.flatMap(n=>{let r=e.projection.authorizations[n.attemptId??n.name];return r?.status===`required`?[signInWithdrawn(r,t)]:[]}),signIns:[],turn:e.turn}}function requestLimit(e,t){let n=turnPosition(e.projection);return{events:[createInputRequestedEvent({requests:[t.request],sequence:n.sequence,stepIndex:n.stepIndex,turnId:n.turnId}),...hold(e,{on:`input`}).events],turn:e.turn}}function requireSignIn(e,t){let n=turnPosition(e.projection),r={sequence:n.sequence,stepIndex:n.stepIndex,turnId:n.turnId},i=[...supersededChallenges(e.signIns,t.challenges).map(e=>createAuthorizationCompletedEvent({...authorizationEventFields(e),outcome:`failed`,reason:`Superseded by a newer authorization attempt.`,...r})),...t.challenges.map(e=>createAuthorizationRequiredEvent({...authorizationEventFields(e),description:e.challenge.instructions??`Authorization required for ${e.name}`,webhookUrl:e.hookUrl,...r}))];i.push(...hold(e,{on:`input`}).events);let a=t.queued===void 0?e.turn.queued:e.turn.queued===void 0?t.queued:coalesceTurnInputs(e.turn.queued,t.queued),o=withSignIns(e.signIns,t.challenges),s=new Set([...t.callIdsByName?.values()??[]].flat()),c=e.turn.suspended.map(e=>[...stepCallIds(e)].some(e=>s.has(e))?{...e,messages:withoutCalls(e.messages,s)}:e);if(c.every((t,n)=>t===e.turn.suspended[n]))return{events:i,signIns:o,turn:{...e.turn,queued:a}};let l=settle({...e,turn:{...e.turn,queued:a,suspended:c}},{results:[]});return{commit:l.commit,events:i,signIns:o,turn:l.turn}}export{answer,approvingSteps,deferInput,dispatch,grantedApprovalKeys,hasRunnableQueue,parkOnApprovals,requestLimit,requireSignIn,stepForRequest,withdrawSignIns};
@@ -1,4 +1,5 @@
1
1
  import { type ModelMessage, type TelemetryOptions, type ToolSet, type TypedToolResult } from "ai";
2
+ import type { SessionAuthContext } from "#channel/types.js";
2
3
  import type { HarnessToolLookup } from "#harness/types.js";
3
4
  import type { InputRequest } from "#shared/input.js";
4
5
  import type { HandleEventFn } from "#harness/types.js";
@@ -33,6 +34,8 @@ export declare function runApprovedCalls(input: {
33
34
  readonly abortSignal: AbortSignal | undefined;
34
35
  /** The step attempt's telemetry, which hears each execution as the AI SDK reports it. */
35
36
  readonly telemetry?: TelemetryOptions;
37
+ /** Who approved each request, which the call reads as `ctx.approval`; it still runs as the requester. */
38
+ readonly responderOf: (request: InputRequest) => SessionAuthContext | undefined;
36
39
  }): Promise<{
37
40
  readonly settled: readonly ApprovedCallResult[];
38
41
  readonly toolResults: readonly TypedToolResult<ToolSet>[];
@@ -1 +1 @@
1
- import{asSchema}from"ai";import{createLogger,logError}from"#internal/logging.js";import{toError}from"#shared/errors.js";import{createActionPartialEvent,createActionResultEvent}from"#protocol/message.js";import{SEARCH_TOOL_NAME}from"#protocol/catalog-tools.js";import{toModelSchema}from"#tools/schema.js";import{parseJsonObject}from"#shared/json.js";import{toolCallModelOutput}from"#harness/tool-call-io.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{createRuntimeToolResultFromValue}from"#harness/action-result-helpers.js";import{projectDeltaPresentation,projectResultPresentation}from"#harness/tool-presentation.js";import{isInlineAuthorizationToolResult}from"#harness/inline-tool-authorization.js";import{TOOL_EXECUTION_DENIED_MESSAGE,failedCall,unavailableToolMessage}from"#harness/input-request-resolution.js";import{recheckApprovedCall,wrapToolExecute}from"#harness/tools.js";const log=createLogger(`harness.tool-loop`),APPROVED_CALL_INTERRUPTED_MESSAGE=`The turn was cancelled while this approved tool call was running. It may have partially run; it was not retried.`;async function runApprovedCalls(e){let t={sequence:e.position.sequence,stepIndex:e.position.stepIndex,turnId:e.position.turnId},settleFailure=async(n,r,i)=>{let a=failedCall({callId:n,message:i,toolName:r});return await e.publish(createActionResultEvent({...t,result:a.result})),{part:a.part}},n=await Promise.allSettled(e.requests.map(async n=>{let r=[],i=[],{callId:a,toolName:o,input:s}=n.action,c=e.tools.get(o),l=c===void 0?void 0:wrapToolExecute(c),u=!1,d;try{if(throwIfTurnAborted(e.abortSignal),c===void 0||l===void 0)return{settled:[await settleFailure(a,o,unavailableToolMessage(o,e.tools.get(SEARCH_TOOL_NAME)!==void 0))],toolResults:i};if((await asSchema(toModelSchema(c.inputSchema,`input`)).validate?.(s))?.success===!1){let e=`The approved input is no longer valid for tool "${o}". Request a new tool call and approval.`;return{settled:[await settleFailure(a,o,e)],toolResults:i}}let f=await recheckApprovedCall(c,{abortSignal:e.abortSignal,callId:a,input:s,approvedTools:e.approvedTools});if(f.denied)return r.push(await rejectApprovedCall({request:n,reason:f.reason,position:t,publish:e.publish})),{settled:r,toolResults:i};let p,m=!1,h=toolTelemetry(e.telemetry,{messages:[...e.messages],toolCall:{input:s,toolCallId:a,toolName:o,type:`tool-call`}});await h.started();let g=0;try{await h.execute(async()=>{let n=performance.now();try{u=!0;let n=l(s,{abortSignal:e.abortSignal,messages:[...e.messages],toolCallId:a});if(isAsyncIterable(n))for await(let r of n)p=r,await e.publish(createActionPartialEvent({...t,presentation:projectDeltaPresentation(c,a,parseJsonObject(s),r),result:createRuntimeToolResultFromValue({callId:a,output:r,toolName:o})}));else p=await n}finally{g=performance.now()-n}})}catch(t){await h.ended({error:t,input:s,toolCallId:a,toolName:o,type:`tool-error`},g),throwIfTurnAborted(e.abortSignal),logError(log,`tool execution failed`,t,{toolName:o,toolCallId:a}),m=!0,p=toError(t).message}m||await h.ended({input:s,output:p,toolCallId:a,toolName:o,type:`tool-result`},g);let _={input:s,output:p,toolCallId:a,toolName:o,type:`tool-result`};return i.push(_),isInlineAuthorizationToolResult(_)?{settled:r,toolResults:i}:(d={part:{output:m?{type:`error-text`,value:String(p)}:await toolCallModelOutput(c,p,a),toolCallId:a,toolName:o,type:`tool-result`}},r.push(d),await e.publish(createActionResultEvent({...t,presentation:m?void 0:projectResultPresentation(c,a,parseJsonObject(s),p),result:createRuntimeToolResultFromValue({callId:a,isError:m,output:p,toolName:o})})),{settled:r,toolResults:i})}catch(t){return e.abortSignal?.aborted===!0?(u||throwIfTurnAborted(e.abortSignal),d===void 0?{settled:[interruptedResult(a,o)],toolResults:i}:{settled:[d],toolResults:i}):(logError(log,`approved tool failed`,t,{toolName:o,toolCallId:a}),{settled:[await settleFailure(a,o,toError(t).message)],toolResults:i})}})),r=n.find(e=>e.status===`rejected`);if(r?.status===`rejected`&&e.abortSignal?.aborted!==!0)throw r.reason;let i=n.flatMap(e=>e.status===`fulfilled`?[e.value]:[]);return{settled:i.flatMap(e=>e.settled),toolResults:i.flatMap(e=>e.toolResults)}}function interruptedResult(e,t){return{part:{output:{type:`error-text`,value:APPROVED_CALL_INTERRUPTED_MESSAGE},toolCallId:e,toolName:t,type:`tool-result`}}}async function rejectApprovedCall(e){let{callId:t,toolName:n}=e.request.action;return await e.publish(createActionResultEvent({...e.position,rejected:!0,result:{callId:t,isError:!0,kind:`tool-result`,toolName:n,output:{code:`TOOL_EXECUTION_DENIED`,message:e.reason??TOOL_EXECUTION_DENIED_MESSAGE,tool:{result:`not_run`}}}})),{part:{output:{reason:e.reason,type:`execution-denied`},toolCallId:t,toolName:n,type:`tool-result`}}}function toolTelemetry(e,t){let n=e===void 0||e.isEnabled===!1?[]:[e.integrations??[]].flat(),r={...t,callId:`approved:${t.toolCall.toolCallId}`,functionId:e?.functionId,recordInputs:e?.recordInputs,recordOutputs:e?.recordOutputs,toolContext:void 0},notify=async e=>{await Promise.allSettled(n.map(async t=>await e(t)))};return{started:()=>notify(e=>e.onToolExecutionStart?.(r)),execute:async e=>{let wrapped=e;for(let e of n){if(e.executeTool===void 0)continue;let n=wrapped;wrapped=()=>e.executeTool({...r,execute:n,toolCallId:t.toolCall.toolCallId})}await wrapped()},ended:(e,t)=>notify(n=>n.onToolExecutionEnd?.({...r,toolExecutionMs:t,toolOutput:e}))}}export{APPROVED_CALL_INTERRUPTED_MESSAGE,rejectApprovedCall,runApprovedCalls};
1
+ import{asSchema}from"ai";import{createLogger,logError}from"#internal/logging.js";import{toError}from"#shared/errors.js";import{createActionPartialEvent,createActionResultEvent}from"#protocol/message.js";import{SEARCH_TOOL_NAME}from"#protocol/catalog-tools.js";import{toModelSchema}from"#tools/schema.js";import{parseJsonObject}from"#shared/json.js";import{toolCallModelOutput}from"#harness/tool-call-io.js";import{isAsyncIterable}from"#shared/async-iterable.js";import{throwIfTurnAborted}from"#harness/turn-cancellation.js";import{createRuntimeToolResultFromValue}from"#harness/action-result-helpers.js";import{projectDeltaPresentation,projectResultPresentation}from"#harness/tool-presentation.js";import{isInlineAuthorizationToolResult}from"#harness/inline-tool-authorization.js";import{TOOL_EXECUTION_DENIED_MESSAGE,failedCall,unavailableToolMessage}from"#harness/input-request-resolution.js";import{recheckApprovedCall,wrapToolExecute}from"#harness/tools.js";const log=createLogger(`harness.tool-loop`),APPROVED_CALL_INTERRUPTED_MESSAGE=`The turn was cancelled while this approved tool call was running. It may have partially run; it was not retried.`;async function runApprovedCalls(e){let t={sequence:e.position.sequence,stepIndex:e.position.stepIndex,turnId:e.position.turnId},settleFailure=async(n,r,i)=>{let a=failedCall({callId:n,message:i,toolName:r});return await e.publish(createActionResultEvent({...t,result:a.result})),{part:a.part}},n=await Promise.allSettled(e.requests.map(async n=>{let r=[],i=[],{callId:a,toolName:o,input:s}=n.action,c=e.tools.get(o),l=c===void 0?void 0:wrapToolExecute(c),u=!1,d;try{if(throwIfTurnAborted(e.abortSignal),c===void 0||l===void 0)return{settled:[await settleFailure(a,o,unavailableToolMessage(o,e.tools.get(SEARCH_TOOL_NAME)!==void 0))],toolResults:i};if((await asSchema(toModelSchema(c.inputSchema,`input`)).validate?.(s))?.success===!1){let e=`The approved input is no longer valid for tool "${o}". Request a new tool call and approval.`;return{settled:[await settleFailure(a,o,e)],toolResults:i}}let f=await recheckApprovedCall(c,{abortSignal:e.abortSignal,callId:a,input:s,approvedTools:e.approvedTools});if(f.denied)return r.push(await rejectApprovedCall({request:n,reason:f.reason,position:t,publish:e.publish})),{settled:r,toolResults:i};let p,m=!1,h=toolTelemetry(e.telemetry,{messages:[...e.messages],toolCall:{input:s,toolCallId:a,toolName:o,type:`tool-call`}});await h.started();let g=0;try{await h.execute(async()=>{let r=performance.now();try{u=!0;let r=e.responderOf(n),i=l(s,{...r!==void 0&&{approval:{responder:r}},abortSignal:e.abortSignal,messages:[...e.messages],toolCallId:a});if(isAsyncIterable(i))for await(let n of i)p=n,await e.publish(createActionPartialEvent({...t,presentation:projectDeltaPresentation(c,a,parseJsonObject(s),n),result:createRuntimeToolResultFromValue({callId:a,output:n,toolName:o})}));else p=await i}finally{g=performance.now()-r}})}catch(t){await h.ended({error:t,input:s,toolCallId:a,toolName:o,type:`tool-error`},g),throwIfTurnAborted(e.abortSignal),logError(log,`tool execution failed`,t,{toolName:o,toolCallId:a}),m=!0,p=toError(t).message}m||await h.ended({input:s,output:p,toolCallId:a,toolName:o,type:`tool-result`},g);let _={input:s,output:p,toolCallId:a,toolName:o,type:`tool-result`};return i.push(_),isInlineAuthorizationToolResult(_)?{settled:r,toolResults:i}:(d={part:{output:m?{type:`error-text`,value:String(p)}:await toolCallModelOutput(c,p,a),toolCallId:a,toolName:o,type:`tool-result`}},r.push(d),await e.publish(createActionResultEvent({...t,presentation:m?void 0:projectResultPresentation(c,a,parseJsonObject(s),p),result:createRuntimeToolResultFromValue({callId:a,isError:m,output:p,toolName:o})})),{settled:r,toolResults:i})}catch(t){return e.abortSignal?.aborted===!0?(u||throwIfTurnAborted(e.abortSignal),d===void 0?{settled:[interruptedResult(a,o)],toolResults:i}:{settled:[d],toolResults:i}):(logError(log,`approved tool failed`,t,{toolName:o,toolCallId:a}),{settled:[await settleFailure(a,o,toError(t).message)],toolResults:i})}})),r=n.find(e=>e.status===`rejected`);if(r?.status===`rejected`&&e.abortSignal?.aborted!==!0)throw r.reason;let i=n.flatMap(e=>e.status===`fulfilled`?[e.value]:[]);return{settled:i.flatMap(e=>e.settled),toolResults:i.flatMap(e=>e.toolResults)}}function interruptedResult(e,t){return{part:{output:{type:`error-text`,value:APPROVED_CALL_INTERRUPTED_MESSAGE},toolCallId:e,toolName:t,type:`tool-result`}}}async function rejectApprovedCall(e){let{callId:t,toolName:n}=e.request.action;return await e.publish(createActionResultEvent({...e.position,rejected:!0,result:{callId:t,isError:!0,kind:`tool-result`,toolName:n,output:{code:`TOOL_EXECUTION_DENIED`,message:e.reason??TOOL_EXECUTION_DENIED_MESSAGE,tool:{result:`not_run`}}}})),{part:{output:{reason:e.reason,type:`execution-denied`},toolCallId:t,toolName:n,type:`tool-result`}}}function toolTelemetry(e,t){let n=e===void 0||e.isEnabled===!1?[]:[e.integrations??[]].flat(),r={...t,callId:`approved:${t.toolCall.toolCallId}`,functionId:e?.functionId,recordInputs:e?.recordInputs,recordOutputs:e?.recordOutputs,toolContext:void 0},notify=async e=>{await Promise.allSettled(n.map(async t=>await e(t)))};return{started:()=>notify(e=>e.onToolExecutionStart?.(r)),execute:async e=>{let wrapped=e;for(let e of n){if(e.executeTool===void 0)continue;let n=wrapped;wrapped=()=>e.executeTool({...r,execute:n,toolCallId:t.toolCall.toolCallId})}await wrapped()},ended:(e,t)=>notify(n=>n.onToolExecutionEnd?.({...r,toolExecutionMs:t,toolOutput:e}))}}export{APPROVED_CALL_INTERRUPTED_MESSAGE,rejectApprovedCall,runApprovedCalls};
@@ -23,6 +23,11 @@ export interface ApprovalResponderIdentity {
23
23
  }
24
24
  export interface ApprovalSettlementAuditRecord {
25
25
  readonly actor: ApprovalResponderIdentity;
26
+ /**
27
+ * The full auth of the person who approved, present only when allowed. The approved call reads
28
+ * it as `ctx.approval.responder`; it never runs as it.
29
+ */
30
+ readonly responder?: SessionAuthContext;
26
31
  /** `unavailable`: the request's entry was gone, so its call is reported unavailable, never run. */
27
32
  readonly outcome: "allowed" | "cancelled" | "unavailable";
28
33
  readonly requestId: string;
@@ -39,6 +44,12 @@ export interface ActiveApprovalCandidate {
39
44
  readonly expiresAt: number;
40
45
  readonly authorizationChallenges?: readonly AuthorizationChallenge[];
41
46
  }
47
+ export interface DurableApprovalState {
48
+ readonly activeCandidates: Readonly<Record<string, ActiveApprovalCandidate>>;
49
+ readonly nextCandidateSequence: number;
50
+ readonly candidateHistory: readonly ApprovalCandidateAuditRecord[];
51
+ readonly settlements: Readonly<Record<string, ApprovalSettlementAuditRecord>>;
52
+ }
42
53
  interface ApprovalStateTransition {
43
54
  readonly changed: boolean;
44
55
  readonly state: SessionStateMap | undefined;
@@ -117,4 +128,6 @@ export declare function retireActiveCandidates(state: SessionStateMap | undefine
117
128
  readonly completedAt: number;
118
129
  readonly reason: string;
119
130
  }): SessionStateMap | undefined;
131
+ /** The full auth of whoever approved `requestId`, when a person allowed it. */
132
+ export declare function responderOfRequest(state: SessionStateMap | undefined, requestId: string): SessionAuthContext | undefined;
120
133
  export {};
@@ -1 +1 @@
1
- const APPROVAL_STATE_KEY=`eve.runtime.hitl.approvalState`;function createApprovalCandidate(e){let t=expireApprovalCandidates({now:e.createdAt,state:e.state}),n=readApprovalState(t);if(n.settlements[e.requestId]!==void 0)return{changed:!1,state:t};let r=e.responder;if(Object.values(n.activeCandidates).find(t=>t.requestId===e.requestId&&t.decision===e.decision&&sameResponder(t.responder,r))!==void 0)return{changed:!1,state:t};let i=n.activeCandidates[e.candidateIdPrefix]!==void 0||n.candidateHistory.some(t=>t.candidateId===e.candidateIdPrefix)?`${e.candidateIdPrefix}.${n.nextCandidateSequence.toString(36)}`:e.candidateIdPrefix;if(n.activeCandidates[i]!==void 0||n.candidateHistory.some(e=>e.candidateId===i))throw Error(`Approval candidate id collision: "${i}".`);let a={candidateId:i,createdAt:e.createdAt,decision:e.decision,expiresAt:e.expiresAt,requestId:e.requestId,responder:r,status:`pending`};return{changed:!0,state:writeApprovalState(t,{...n,activeCandidates:{...n.activeCandidates,[a.candidateId]:a},nextCandidateSequence:n.nextCandidateSequence+1})}}function markApprovalCandidateAuthorizationRequired(e){let t=readApprovalState(e.state),n=t.activeCandidates[e.candidateId];if(n===void 0)return e.state;let r={...n,authorizationChallenges:e.authorizationChallenges,expiresAt:e.expiresAt??n.expiresAt,status:`authorization-required`};return writeApprovalState(e.state,{...t,activeCandidates:{...t.activeCandidates,[e.candidateId]:r}})}function finishApprovalCandidate(e){let t=readApprovalState(e.state),n=t.activeCandidates[e.candidateId];if(n===void 0)return e.state;let r={...t.activeCandidates};return delete r[e.candidateId],writeApprovalState(e.state,{...t,activeCandidates:r,candidateHistory:[...t.candidateHistory,toCandidateAuditRecord({candidate:n,completedAt:e.completedAt,reason:e.reason,status:e.status})]})}function expireApprovalCandidates(e){let t=e.state,n=Object.values(readApprovalState(t).activeCandidates);for(let r of n)r.expiresAt>e.now||(t=finishApprovalCandidate({candidateId:r.candidateId,completedAt:e.now,state:t,status:`timed-out`}));return t}function settleAllowedCandidate(e){let t=expireApprovalCandidates({now:e.settledAt,state:e.state}),n=readApprovalState(t),r=n.activeCandidates[e.candidateId];if(r===void 0){let r=n.candidateHistory.find(t=>t.candidateId===e.candidateId);if((r&&n.settlements[r.requestId])!==void 0)return{changed:!1,state:t};throw Error(`Unknown approval candidate "${e.candidateId}".`)}return settleRequest({candidateId:r.candidateId,outcome:r.decision===`cancel`?`cancelled`:`allowed`,requestId:r.requestId,responder:r.responder,settledAt:e.settledAt,state:t})}function settleUnavailableCandidate(e){let t=expireApprovalCandidates({now:e.settledAt,state:e.state}),n=readApprovalState(t).activeCandidates[e.candidateId];return n===void 0?{changed:!1,state:t}:settleRequest({candidateId:n.candidateId,outcome:`unavailable`,reason:e.reason,requestId:n.requestId,responder:n.responder,settledAt:e.settledAt,state:t})}function settleDirectApprovalResponse(e){let t=expireApprovalCandidates({now:e.settledAt,state:e.state});return settleRequest({outcome:e.outcome,requestId:e.requestId,responder:e.actor,settledAt:e.settledAt,state:t})}function getActiveApprovalCandidate(e,t){return readApprovalState(e).activeCandidates[t]}function getApprovalAuditState(e){let t=readApprovalState(e);return{activeCandidates:Object.values(t.activeCandidates),candidateHistory:t.candidateHistory,settlements:Object.values(t.settlements)}}function settleRequest(e){let t=readApprovalState(e.state);if(t.settlements[e.requestId]!==void 0)return{changed:!1,state:e.state};let n={actor:projectResponder(e.responder),candidateId:e.candidateId,outcome:e.outcome,requestId:e.requestId,settledAt:e.settledAt},r={},i=[...t.candidateHistory];for(let n of Object.values(t.activeCandidates)){if(n.requestId!==e.requestId){r[n.candidateId]=n;continue}let t=n.candidateId===e.candidateId;i.push(toCandidateAuditRecord({candidate:n,completedAt:e.settledAt,reason:t?e.reason:void 0,status:t?e.outcome===`unavailable`?`failed`:`allowed`:`stale`}))}let a={activeCandidates:r,candidateHistory:i,nextCandidateSequence:t.nextCandidateSequence,settlements:{...t.settlements,[e.requestId]:n}};return{changed:!0,state:writeApprovalState(e.state,a)}}function toCandidateAuditRecord(e){let{authorizationChallenges:t,responder:n,...r}=e.candidate;return{...r,completedAt:e.completedAt,responder:projectResponder(n),reason:e.reason,status:e.status}}function projectResponder(e){return{authenticator:e.authenticator,issuer:e.issuer,principalId:e.principalId,principalType:e.principalType}}function sameResponder(e,t){return e.authenticator===t.authenticator&&e.issuer===t.issuer&&e.principalId===t.principalId&&e.principalType===t.principalType}function readActiveCandidates(e){return Object.fromEntries(Object.entries(e).map(([e,t])=>[e,{...t,decision:t.decision===`cancel`?`cancel`:`approve`}]))}function readApprovalState(e){let t=e?.[APPROVAL_STATE_KEY];if(typeof t!=`object`||!t)return{activeCandidates:{},candidateHistory:[],nextCandidateSequence:0,settlements:{}};let n=t;return{activeCandidates:typeof n.activeCandidates==`object`&&n.activeCandidates!==null?readActiveCandidates(n.activeCandidates):{},candidateHistory:Array.isArray(n.candidateHistory)?n.candidateHistory:[],nextCandidateSequence:typeof n.nextCandidateSequence==`number`&&Number.isSafeInteger(n.nextCandidateSequence)&&n.nextCandidateSequence>=0?n.nextCandidateSequence:deriveNextCandidateSequence(n),settlements:typeof n.settlements==`object`&&n.settlements!==null?n.settlements:{}}}function deriveNextCandidateSequence(e){return Object.keys(e.activeCandidates??{}).length+(Array.isArray(e.candidateHistory)?e.candidateHistory.length:0)}function writeApprovalState(e,t){return{...e,[APPROVAL_STATE_KEY]:t}}function retireActiveCandidates(e,t){let n=e;for(let e of getApprovalAuditState(n).activeCandidates)n=finishApprovalCandidate({candidateId:e.candidateId,completedAt:t.completedAt,reason:t.reason,state:n,status:`stale`});return n}export{createApprovalCandidate,expireApprovalCandidates,finishApprovalCandidate,getActiveApprovalCandidate,getApprovalAuditState,markApprovalCandidateAuthorizationRequired,retireActiveCandidates,sameResponder,settleAllowedCandidate,settleDirectApprovalResponse,settleUnavailableCandidate};
1
+ import{readApprovalState,writeApprovalState}from"./requests.js";function createApprovalCandidate(e){let t=expireApprovalCandidates({now:e.createdAt,state:e.state}),n=readApprovalState(t);if(n.settlements[e.requestId]!==void 0)return{changed:!1,state:t};let r=e.responder;if(Object.values(n.activeCandidates).find(t=>t.requestId===e.requestId&&t.decision===e.decision&&sameResponder(t.responder,r))!==void 0)return{changed:!1,state:t};let i=n.activeCandidates[e.candidateIdPrefix]!==void 0||n.candidateHistory.some(t=>t.candidateId===e.candidateIdPrefix)?`${e.candidateIdPrefix}.${n.nextCandidateSequence.toString(36)}`:e.candidateIdPrefix;if(n.activeCandidates[i]!==void 0||n.candidateHistory.some(e=>e.candidateId===i))throw Error(`Approval candidate id collision: "${i}".`);let a={candidateId:i,createdAt:e.createdAt,decision:e.decision,expiresAt:e.expiresAt,requestId:e.requestId,responder:r,status:`pending`},o={...n,activeCandidates:{...n.activeCandidates,[a.candidateId]:a},nextCandidateSequence:n.nextCandidateSequence+1};return{changed:!0,state:writeApprovalState(t,o)}}function markApprovalCandidateAuthorizationRequired(e){let t=readApprovalState(e.state),n=t.activeCandidates[e.candidateId];if(n===void 0)return e.state;let r={...n,authorizationChallenges:e.authorizationChallenges,expiresAt:e.expiresAt??n.expiresAt,status:`authorization-required`};return writeApprovalState(e.state,{...t,activeCandidates:{...t.activeCandidates,[e.candidateId]:r}})}function finishApprovalCandidate(e){let t=readApprovalState(e.state),n=t.activeCandidates[e.candidateId];if(n===void 0)return e.state;let r={...t.activeCandidates};return delete r[e.candidateId],writeApprovalState(e.state,{...t,activeCandidates:r,candidateHistory:[...t.candidateHistory,toCandidateAuditRecord({candidate:n,completedAt:e.completedAt,reason:e.reason,status:e.status})]})}function expireApprovalCandidates(e){let t=e.state,n=Object.values(readApprovalState(t).activeCandidates);for(let r of n)r.expiresAt>e.now||(t=finishApprovalCandidate({candidateId:r.candidateId,completedAt:e.now,state:t,status:`timed-out`}));return t}function settleAllowedCandidate(e){let t=expireApprovalCandidates({now:e.settledAt,state:e.state}),n=readApprovalState(t),r=n.activeCandidates[e.candidateId];if(r===void 0){let r=n.candidateHistory.find(t=>t.candidateId===e.candidateId);if((r&&n.settlements[r.requestId])!==void 0)return{changed:!1,state:t};throw Error(`Unknown approval candidate "${e.candidateId}".`)}return settleRequest({candidateId:r.candidateId,outcome:r.decision===`cancel`?`cancelled`:`allowed`,requestId:r.requestId,responder:r.responder,settledAt:e.settledAt,state:t})}function settleUnavailableCandidate(e){let t=expireApprovalCandidates({now:e.settledAt,state:e.state}),n=readApprovalState(t).activeCandidates[e.candidateId];return n===void 0?{changed:!1,state:t}:settleRequest({candidateId:n.candidateId,outcome:`unavailable`,reason:e.reason,requestId:n.requestId,responder:n.responder,settledAt:e.settledAt,state:t})}function settleDirectApprovalResponse(e){let t=expireApprovalCandidates({now:e.settledAt,state:e.state});return settleRequest({outcome:e.outcome,requestId:e.requestId,responder:e.actor,settledAt:e.settledAt,state:t})}function getActiveApprovalCandidate(e,t){return readApprovalState(e).activeCandidates[t]}function getApprovalAuditState(e){let t=readApprovalState(e);return{activeCandidates:Object.values(t.activeCandidates),candidateHistory:t.candidateHistory,settlements:Object.values(t.settlements)}}function settleRequest(e){let t=readApprovalState(e.state);if(t.settlements[e.requestId]!==void 0)return{changed:!1,state:e.state};let n={actor:projectResponder(e.responder),...e.outcome===`allowed`&&{responder:e.responder},candidateId:e.candidateId,outcome:e.outcome,requestId:e.requestId,settledAt:e.settledAt},r={},i=[...t.candidateHistory];for(let n of Object.values(t.activeCandidates)){if(n.requestId!==e.requestId){r[n.candidateId]=n;continue}let t=n.candidateId===e.candidateId;i.push(toCandidateAuditRecord({candidate:n,completedAt:e.settledAt,reason:t?e.reason:void 0,status:t?e.outcome===`unavailable`?`failed`:`allowed`:`stale`}))}let a={activeCandidates:r,candidateHistory:i,nextCandidateSequence:t.nextCandidateSequence,settlements:{...t.settlements,[e.requestId]:n}};return{changed:!0,state:writeApprovalState(e.state,a)}}function toCandidateAuditRecord(e){let{authorizationChallenges:t,responder:n,...r}=e.candidate;return{...r,completedAt:e.completedAt,responder:projectResponder(n),reason:e.reason,status:e.status}}function projectResponder(e){return{authenticator:e.authenticator,issuer:e.issuer,principalId:e.principalId,principalType:e.principalType}}function sameResponder(e,t){return e.authenticator===t.authenticator&&e.issuer===t.issuer&&e.principalId===t.principalId&&e.principalType===t.principalType}function retireActiveCandidates(e,t){let n=e;for(let e of getApprovalAuditState(n).activeCandidates)n=finishApprovalCandidate({candidateId:e.candidateId,completedAt:t.completedAt,reason:t.reason,state:n,status:`stale`});return n}function responderOfRequest(e,t){return readApprovalState(e).settlements[t]?.responder}export{createApprovalCandidate,expireApprovalCandidates,finishApprovalCandidate,getActiveApprovalCandidate,getApprovalAuditState,markApprovalCandidateAuthorizationRequired,responderOfRequest,retireActiveCandidates,sameResponder,settleAllowedCandidate,settleDirectApprovalResponse,settleUnavailableCandidate};
@@ -1 +1 @@
1
- import{createLogger,logError}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{AuthKey,SessionKey}from"#context/keys.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{buildApprovalResponseAuth,handleApprovalResponsePolicyError}from"#execution/tool-auth.js";import{suspendedSteps}from"#harness/session-machine/view.js";import{clearPendingAuthorization,getAuthorizationResult,getPendingAuthorization,isAuthorizationSignal}from"#harness/authorization.js";import{isApprovalRequest}from"#harness/input-request-class.js";import{createApprovalCandidate,expireApprovalCandidates,finishApprovalCandidate,getActiveApprovalCandidate,getApprovalAuditState,markApprovalCandidateAuthorizationRequired,sameResponder,settleAllowedCandidate,settleDirectApprovalResponse,settleUnavailableCandidate}from"#harness/hitl/candidates.js";const TEMPORARILY_UNAVAILABLE_APPROVAL_REASON=`Approval authorization is temporarily unavailable. Please try again.`,log=createLogger(`harness.hitl`);async function coordinateApprovalDelivery(e){let t=e.now??Date.now(),n=getApprovalAuditState(e.session.state).activeCandidates.filter(e=>e.expiresAt<=t),r=n.flatMap(e=>e.authorizationChallenges?.map(e=>e.attemptId??e.candidateId??e.name)??[]),i=expireApprovalCandidates({now:t,state:e.session.state}),a={...e.session,state:clearPendingAuthorization(i,r)},o=getApprovalAuditState(a.state),s=suspendedSteps(a.state).filter(e=>e.requests.length>0),c=new Set(s.flatMap(e=>e.requests.map(e=>e.requestId))),l=o.settlements.filter(e=>c.has(e.requestId)),u=new Set(o.settlements.map(e=>e.requestId)),d=new Set([...u].filter(e=>!c.has(e))),f=hasResponseForRequest(e.stepInput,d),p=f?removeConsumedResponses(e.stepInput,d):e.stepInput;if(f&&l.length===0&&!hasMeaningfulInput(p))return deliveryResult(a,p,`park`);if(s.length===0)return deliveryResult(a,p);let m=p,h=new Set(s.flatMap(e=>e.responseAuthRequiredRequestIds??[])),g=s.flatMap(e=>e.requests),_=new Map(g.map(e=>[e.requestId,e])),v=[],y=[],b=new Set,x=!1,S=getApprovalAuditState(a.state).activeCandidates,C=[...m?.attributedInputResponses??[],...(m?.inputResponses??[]).map(e=>({auth:void 0,response:e}))];for(let{auth:e,response:n}of C){let r=_.get(n.requestId);if(r===void 0||!isApprovalRequest(r))continue;if(!h.has(n.requestId)){let r=contextStorage.getStore(),i=e===void 0?r?.get(AuthKey)??r?.get(SessionKey)?.auth.current??null:e,o=toCandidateDecision(n.optionId),s=suspendedSteps(a.state).find(e=>e.requests.some(e=>e.requestId===n.requestId))?.requester??null;if(i!==null&&o!==void 0&&s!==null&&!sameResponder(s,i)){b.add(n.requestId),y.push(`Only the person who requested this action can respond to this approval.`);continue}if(i!==null&&o!==void 0){let e=settleDirectApprovalResponse({actor:i,outcome:o===`approve`?`allowed`:`cancelled`,requestId:n.requestId,settledAt:t,state:a.state});a={...a,state:e.state},x||=e.changed}continue}b.add(n.requestId);let i=toCandidateDecision(n.optionId);if(i===void 0)continue;let o=e===void 0?buildCallbackContext().session.auth.current:e;if(o===null){y.push(`Authentication is required to respond to this approval.`);continue}let s=createApprovalCandidate({candidateIdPrefix:approvalCandidateIdPrefix(r.requestId,o,i),createdAt:t,decision:i,expiresAt:t+6e5,requestId:r.requestId,responder:o,state:a.state});a={...a,state:s.state},x||=s.changed}let w=removeConsumedResponses(m,b);if(b.size>0)return deliveryResult(a,w,x?`continue-coordination`:`continue`,[],y);if(x)return deliveryResult(a,w,`continue`,[],y);let T=new Set(getPendingAuthorization(a.state)?.challenges.map(e=>e.name)??[]);for(let n of S){if(n.status===`authorization-required`){let e=n.authorizationChallenges??[];if(!e.some(e=>getAuthorizationResult(e.name)!==void 0)){v.push(...e.filter(e=>!T.has(e.name)));continue}}let r=_.get(n.requestId);if(r===void 0||getActiveApprovalCandidate(a.state,n.candidateId)===void 0)continue;let i=await authorizeCandidate({candidateId:n.candidateId,decision:n.decision,now:t,request:r,responder:n.responder,restoreTools:async()=>await e.prepareTools?.(r)??e.tools,session:a});a=i.session,x||=i.didCommit,v.push(...i.challenges);let o=getApprovalAuditState(a.state).settlements.find(e=>e.requestId===n.requestId);o!==void 0&&l.push(o)}let E=appendSettledResponses(w,l);return(x||n.length>0)&&getApprovalAuditState(a.state).activeCandidates.length===0?deliveryResult(a,E,`responses-completed`):l.length>0?deliveryResult(a,E,`continue`):x?deliveryResult(a,E,`continue-coordination`):deliveryResult(a,E,v.length>0?`authorization-required`:`continue`,v)}async function authorizeCandidate(e){let t={...e.session,state:expireApprovalCandidates({now:e.now,state:e.session.state})};if(getActiveApprovalCandidate(t.state,e.candidateId)===void 0)return{challenges:[],didCommit:!1,session:t};let n;try{n=await e.restoreTools()}catch(n){return logError(log,`approval tools could not be restored`,n,{requestId:e.request.requestId}),failCandidate({...e,reason:TEMPORARILY_UNAVAILABLE_APPROVAL_REASON,session:t})}let r=n.get(e.request.action.toolName);if(r===void 0){let n=settleUnavailableCandidate({candidateId:e.candidateId,reason:`The tool this approval was for is no longer available, so the call won't run.`,settledAt:e.now,state:t.state});return{challenges:[],didCommit:n.changed,session:{...t,state:n.state}}}let{approval:i}=r,a=i!==void 0&&typeof i!=`function`?i.response:void 0;if(a===void 0)return failCandidate({...e,reason:TEMPORARILY_UNAVAILABLE_APPROVAL_REASON,session:t});try{let n=buildCallbackContext(),r=await withAuthorizerTimeout(a({auth:buildApprovalResponseAuth({responder:e.responder,scope:e.candidateId}),request:{callId:e.request.action.callId,requestId:e.request.requestId,principal:suspendedSteps(t.state).find(t=>t.requests.some(t=>t.requestId===e.request.requestId))?.requester??null,toolInput:e.request.action.input,toolName:e.request.action.toolName},response:{decision:e.decision,principal:e.responder},session:{id:n.session.id,initiator:n.session.auth.initiator,parent:n.session.parent,turn:n.session.turn}}));if(r.status===`rejected`)return t={...t,state:finishApprovalCandidate({candidateId:e.candidateId,completedAt:e.now,reason:r.reason,state:t.state,status:`rejected`})},{challenges:[],didCommit:!0,session:t};if(r.status!==`allowed`)return failCandidate({...e,session:t});let i=settleAllowedCandidate({candidateId:e.candidateId,settledAt:e.now,state:t.state});return{challenges:[],didCommit:i.changed,session:{...t,state:i.state}}}catch(n){let r=await handleApprovalResponsePolicyError(n).catch(()=>void 0);if(isAuthorizationSignal(r)){let n=r.challenges.map(e=>Date.parse(e.challenge.expiresAt??``)).filter(Number.isFinite).sort((e,t)=>e-t)[0];return t={...t,state:markApprovalCandidateAuthorizationRequired({authorizationChallenges:r.challenges.map(t=>({...t,candidateId:e.candidateId})),candidateId:e.candidateId,expiresAt:n,state:t.state})},{challenges:r.challenges.map(t=>({...t,candidateId:e.candidateId})),didCommit:!0,session:t}}return failCandidate({...e,session:t})}}function failCandidate(e){let t=e.reason??`We couldn’t verify your response. Please try again.`;return{challenges:[],didCommit:!0,session:{...e.session,state:finishApprovalCandidate({candidateId:e.candidateId,completedAt:e.now,reason:t,state:e.session.state,status:`failed`})}}}function hasResponseForRequest(e,t){return e?.attributedInputResponses?.some(({response:e})=>t.has(e.requestId))===!0||e?.inputResponses?.some(e=>t.has(e.requestId))===!0}function hasMeaningfulInput(e){return e?.message!==void 0||(e?.attributedInputResponses?.length??0)>0||(e?.inputResponses?.length??0)>0||(e?.runtimeActionResults?.length??0)>0}function appendSettledResponses(e,t){if(t.length===0)return e;let n=new Set([...(e?.inputResponses??[]).map(e=>e.requestId),...(e?.attributedInputResponses??[]).map(({response:e})=>e.requestId)]),r=t.filter(e=>!n.has(e.requestId));return r.length===0?e:{...e,inputResponses:[...e?.inputResponses??[],...r.map(e=>({optionId:e.outcome===`allowed`?`approve`:`cancel`,requestId:e.requestId}))]}}function removeConsumedResponses(e,t){if(e===void 0)return;let n=(e.attributedInputResponses??[]).filter(({response:e})=>!t.has(e.requestId)),r=[...(e.inputResponses??[]).filter(e=>!t.has(e.requestId)),...n.map(({response:e})=>e)];return{...e,attributedInputResponses:void 0,inputResponses:r}}function deliveryResult(e,t,n=`continue`,r=[],i=[]){return{challenges:r,feedback:i,kind:n,session:e,stepInput:t}}function toCandidateDecision(e){if(e===`approve`)return`approve`;if(e===`cancel`||e===`deny`)return`cancel`}function approvalCandidateIdPrefix(e,t,n){let r=[t.authenticator,t.issuer??``,t.principalType,t.principalId].join(`:`),i=`${encodeCandidateIdPart(e)}.${encodeCandidateIdPart(r)}`;return n===`approve`?i:`${i}.${encodeCandidateIdPart(n)}`}function encodeCandidateIdPart(e){return Array.from(e,e=>e.codePointAt(0).toString(36)).join(`-`)}async function withAuthorizerTimeout(e){let t;try{return await Promise.race([Promise.resolve(e),new Promise((e,n)=>{t=setTimeout(()=>n(Error(`Approval response authorizer timed out.`)),1e4)})])}finally{t!==void 0&&clearTimeout(t)}}export{coordinateApprovalDelivery};
1
+ import{signInAttemptKey}from"./sign-ins.js";import{readHitlState}from"./requests.js";import{createLogger,logError}from"#internal/logging.js";import{contextStorage}from"#context/container.js";import{AuthKey,SessionKey}from"#context/keys.js";import{buildCallbackContext}from"#context/build-callback-context.js";import{buildApprovalResponseAuth,handleApprovalResponsePolicyError}from"#execution/tool-auth.js";import{storedProjection,suspendedSteps}from"#harness/session-machine/view.js";import{getAuthorizationResult,isAuthorizationSignal}from"#harness/authorization.js";import{saveTransition,sessionView}from"#harness/session-machine/commit.js";import{matchSignIns}from"#harness/session-machine/transitions.js";import{isApprovalRequest}from"#harness/input-request-class.js";import{createApprovalCandidate,expireApprovalCandidates,finishApprovalCandidate,getActiveApprovalCandidate,getApprovalAuditState,markApprovalCandidateAuthorizationRequired,sameResponder,settleAllowedCandidate,settleDirectApprovalResponse,settleUnavailableCandidate}from"#harness/hitl/candidates.js";const TEMPORARILY_UNAVAILABLE_APPROVAL_REASON=`Approval authorization is temporarily unavailable. Please try again.`,log=createLogger(`harness.hitl`);async function coordinateApprovalDelivery(e){let t=e.now??Date.now(),n=getApprovalAuditState(e.session.state).activeCandidates.filter(e=>e.expiresAt<=t),r=new Set(n.flatMap(e=>e.authorizationChallenges?.map(signInAttemptKey)??[])),i=expireApprovalCandidates({now:t,state:e.session.state}),a={...e.session,state:i};if(r.size>0){let e=sessionView(storedProjection(a.state),a.state);a=saveTransition(a,matchSignIns(e,{attemptIds:[...r]}))}let o=getApprovalAuditState(a.state),s=suspendedSteps(a.state).filter(e=>e.requests.length>0),c=new Set(s.flatMap(e=>e.requests.map(e=>e.requestId))),l=o.settlements.filter(e=>c.has(e.requestId)),u=new Set(o.settlements.map(e=>e.requestId)),d=new Set([...u].filter(e=>!c.has(e))),f=hasResponseForRequest(e.stepInput,d),p=f?removeConsumedResponses(e.stepInput,d):e.stepInput;if(f&&l.length===0&&!hasMeaningfulInput(p))return deliveryResult(a,p,`park`);if(s.length===0)return deliveryResult(a,p);let m=p,h=new Set(s.flatMap(e=>e.responseAuthRequiredRequestIds??[])),g=s.flatMap(e=>e.requests),_=new Map(g.map(e=>[e.requestId,e])),v=[],y=[],b=new Set,x=!1,S=getApprovalAuditState(a.state).activeCandidates,C=[...m?.attributedInputResponses??[],...(m?.inputResponses??[]).map(e=>({auth:void 0,response:e}))];for(let{auth:e,response:n}of C){let r=_.get(n.requestId);if(r===void 0||!isApprovalRequest(r))continue;if(!h.has(n.requestId)){let r=contextStorage.getStore(),i=e===void 0?r?.get(AuthKey)??r?.get(SessionKey)?.auth.current??null:e,o=toCandidateDecision(n.optionId),s=suspendedSteps(a.state).find(e=>e.requests.some(e=>e.requestId===n.requestId))?.requester??null;if(i!==null&&o!==void 0&&s!==null&&!sameResponder(s,i)){b.add(n.requestId),y.push(`Only the person who requested this action can respond to this approval.`);continue}if(i!==null&&o!==void 0){let e=settleDirectApprovalResponse({actor:i,outcome:o===`approve`?`allowed`:`cancelled`,requestId:n.requestId,settledAt:t,state:a.state});a={...a,state:e.state},x||=e.changed}continue}b.add(n.requestId);let i=toCandidateDecision(n.optionId);if(i===void 0)continue;let o=e===void 0?buildCallbackContext().session.auth.current:e;if(o===null){y.push(`Authentication is required to respond to this approval.`);continue}let s=createApprovalCandidate({candidateIdPrefix:approvalCandidateIdPrefix(r.requestId,o,i),createdAt:t,decision:i,expiresAt:t+6e5,requestId:r.requestId,responder:o,state:a.state});a={...a,state:s.state},x||=s.changed}let w=removeConsumedResponses(m,b);if(b.size>0)return deliveryResult(a,w,x?`continue-coordination`:`continue`,[],y);if(x)return deliveryResult(a,w,`continue`,[],y);let T=new Set(readHitlState(a.state).signIns.map(e=>e.name));for(let n of S){if(n.status===`authorization-required`){let e=n.authorizationChallenges??[];if(!e.some(e=>getAuthorizationResult(e.name)!==void 0)){v.push(...e.filter(e=>!T.has(e.name)));continue}}let r=_.get(n.requestId);if(r===void 0||getActiveApprovalCandidate(a.state,n.candidateId)===void 0)continue;let i=await authorizeCandidate({candidateId:n.candidateId,decision:n.decision,now:t,request:r,responder:n.responder,restoreTools:async()=>await e.prepareTools?.(r)??e.tools,session:a});a=i.session,x||=i.didCommit,v.push(...i.challenges);let o=getApprovalAuditState(a.state).settlements.find(e=>e.requestId===n.requestId);o!==void 0&&l.push(o)}let E=appendSettledResponses(w,l);return(x||n.length>0)&&getApprovalAuditState(a.state).activeCandidates.length===0?deliveryResult(a,E,`responses-completed`):l.length>0?deliveryResult(a,E,`continue`):x?deliveryResult(a,E,`continue-coordination`):deliveryResult(a,E,v.length>0?`authorization-required`:`continue`,v)}async function authorizeCandidate(e){let t={...e.session,state:expireApprovalCandidates({now:e.now,state:e.session.state})};if(getActiveApprovalCandidate(t.state,e.candidateId)===void 0)return{challenges:[],didCommit:!1,session:t};let n;try{n=await e.restoreTools()}catch(n){return logError(log,`approval tools could not be restored`,n,{requestId:e.request.requestId}),failCandidate({...e,reason:TEMPORARILY_UNAVAILABLE_APPROVAL_REASON,session:t})}let r=n.get(e.request.action.toolName);if(r===void 0){let n=settleUnavailableCandidate({candidateId:e.candidateId,reason:`The tool this approval was for is no longer available, so the call won't run.`,settledAt:e.now,state:t.state});return{challenges:[],didCommit:n.changed,session:{...t,state:n.state}}}let{approval:i}=r,a=i!==void 0&&typeof i!=`function`?i.response:void 0;if(a===void 0)return failCandidate({...e,reason:TEMPORARILY_UNAVAILABLE_APPROVAL_REASON,session:t});try{let n=buildCallbackContext(),r=await withAuthorizerTimeout(a({auth:buildApprovalResponseAuth({responder:e.responder,scope:e.candidateId}),request:{callId:e.request.action.callId,requestId:e.request.requestId,principal:suspendedSteps(t.state).find(t=>t.requests.some(t=>t.requestId===e.request.requestId))?.requester??null,toolInput:e.request.action.input,toolName:e.request.action.toolName},response:{decision:e.decision,principal:e.responder},session:{id:n.session.id,initiator:n.session.auth.initiator,parent:n.session.parent,turn:n.session.turn}}));if(r.status===`rejected`)return t={...t,state:finishApprovalCandidate({candidateId:e.candidateId,completedAt:e.now,reason:r.reason,state:t.state,status:`rejected`})},{challenges:[],didCommit:!0,session:t};if(r.status!==`allowed`)return failCandidate({...e,session:t});let i=settleAllowedCandidate({candidateId:e.candidateId,settledAt:e.now,state:t.state});return{challenges:[],didCommit:i.changed,session:{...t,state:i.state}}}catch(n){let r=await handleApprovalResponsePolicyError(n).catch(()=>void 0);if(isAuthorizationSignal(r)){let n=r.challenges.map(e=>Date.parse(e.challenge.expiresAt??``)).filter(Number.isFinite).sort((e,t)=>e-t)[0];return t={...t,state:markApprovalCandidateAuthorizationRequired({authorizationChallenges:r.challenges.map(t=>({...t,candidateId:e.candidateId})),candidateId:e.candidateId,expiresAt:n,state:t.state})},{challenges:r.challenges.map(t=>({...t,candidateId:e.candidateId})),didCommit:!0,session:t}}return failCandidate({...e,session:t})}}function failCandidate(e){let t=e.reason??`We couldn’t verify your response. Please try again.`;return{challenges:[],didCommit:!0,session:{...e.session,state:finishApprovalCandidate({candidateId:e.candidateId,completedAt:e.now,reason:t,state:e.session.state,status:`failed`})}}}function hasResponseForRequest(e,t){return e?.attributedInputResponses?.some(({response:e})=>t.has(e.requestId))===!0||e?.inputResponses?.some(e=>t.has(e.requestId))===!0}function hasMeaningfulInput(e){return e?.message!==void 0||(e?.attributedInputResponses?.length??0)>0||(e?.inputResponses?.length??0)>0||(e?.runtimeActionResults?.length??0)>0}function appendSettledResponses(e,t){if(t.length===0)return e;let n=new Set([...(e?.inputResponses??[]).map(e=>e.requestId),...(e?.attributedInputResponses??[]).map(({response:e})=>e.requestId)]),r=t.filter(e=>!n.has(e.requestId));return r.length===0?e:{...e,inputResponses:[...e?.inputResponses??[],...r.map(e=>({optionId:e.outcome===`allowed`?`approve`:`cancel`,requestId:e.requestId}))]}}function removeConsumedResponses(e,t){if(e===void 0)return;let n=(e.attributedInputResponses??[]).filter(({response:e})=>!t.has(e.requestId)),r=[...(e.inputResponses??[]).filter(e=>!t.has(e.requestId)),...n.map(({response:e})=>e)];return{...e,attributedInputResponses:void 0,inputResponses:r}}function deliveryResult(e,t,n=`continue`,r=[],i=[]){return{challenges:r,feedback:i,kind:n,session:e,stepInput:t}}function toCandidateDecision(e){if(e===`approve`)return`approve`;if(e===`cancel`||e===`deny`)return`cancel`}function approvalCandidateIdPrefix(e,t,n){let r=[t.authenticator,t.issuer??``,t.principalType,t.principalId].join(`:`),i=`${encodeCandidateIdPart(e)}.${encodeCandidateIdPart(r)}`;return n===`approve`?i:`${i}.${encodeCandidateIdPart(n)}`}function encodeCandidateIdPart(e){return Array.from(e,e=>e.codePointAt(0).toString(36)).join(`-`)}async function withAuthorizerTimeout(e){let t;try{return await Promise.race([Promise.resolve(e),new Promise((e,n)=>{t=setTimeout(()=>n(Error(`Approval response authorizer timed out.`)),1e4)})])}finally{t!==void 0&&clearTimeout(t)}}export{coordinateApprovalDelivery};
@@ -8,6 +8,7 @@ import type { InputRequest } from "#shared/input.js";
8
8
  export { acceptHumanInput, admitApprovedWork, dispatchApprovedWorkflows, hasApprovedWork, runApprovedLocalCalls, type ApprovedWork, type HumanInputIntake, } from "./intake.js";
9
9
  export { extractToolApprovalInputRequests } from "#harness/input-extraction.js";
10
10
  export { hasRunnableQueue } from "./approvals.js";
11
+ export { discardClearedHitlState as discardClearedHumanInput } from "./requests.js";
11
12
  /**
12
13
  * A model step made calls that need a person's approval: the step parks on them beside any
13
14
  * runtime calls it made. The turn holds for the answers, unless the runtime runs calls for it
@@ -42,11 +43,6 @@ export declare function humanInputContext(step: Step, tools: HarnessToolLookup):
42
43
  readonly approvedTools: ReadonlySet<string>;
43
44
  readonly pendingApprovalsNote?: string;
44
45
  };
45
- /**
46
- * Drops what a cleared context owned: sign-in attempts and responders' approval progress. `clear`
47
- * reported each close; relay routes for live tasks stay.
48
- */
49
- export declare function discardClearedHumanInput<T extends HarnessSessionBase>(session: T): T;
50
46
  /** The cancelled turn's responders stop checking its approvals: their candidates stale. */
51
47
  export declare function retireCancelledCandidates<T extends HarnessSessionBase>(session: T): T;
52
48
  /**
@@ -57,3 +53,4 @@ export declare function takeDeferredMessage<T extends HarnessSessionBase>(sessio
57
53
  readonly message?: StepInput["message"];
58
54
  readonly session: T;
59
55
  };
56
+ export { readHitlState, holdsHitlRequests } from "./requests.js";
@@ -1 +1 @@
1
- import{renderPendingApprovalsInstruction}from"./approval-prompt.js";import{isEmptyInput}from"./delivery.js";import{grantedApprovalKeys,hasRunnableQueue,parkOnApprovals as parkOnApprovals$1,requestLimit,requireSignIn}from"./approvals.js";import{checkSessionUsageLimit}from"./budget.js";import{retireActiveCandidates}from"./candidates.js";import{acceptHumanInput,admitApprovedWork,dispatchApprovedWorkflows,hasApprovedWork,holdForInput,runApprovedLocalCalls}from"./intake.js";import{AuthKey,SessionKey}from"#context/keys.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{clearPendingAuthorization}from"#harness/authorization.js";import{fail,hold}from"#harness/session-machine/transitions.js";import{readTurnState,writeTurnState}from"#harness/session-machine/state.js";import{extractToolApprovalInputRequests}from"#harness/input-extraction.js";async function parkOnApprovals(e,t){let n=parkOnApprovals$1(e.view(),{event:t.event,messages:t.messages,requests:t.requests,tasks:t.tasks,requester:currentRequester(e),responseAuthRequiredRequestIds:responsePolicyRequestIds(t.tools,t.requests)});return await e.apply(n,[...e.session.history,...n.commit??[]]),t.waitsOn===void 0?hasRunnableQueue(e.view())?{next:e.runStep,session:e.session}:holdForInput(e):(t.waitsOn===`runtime`&&t.tasks.some(e=>e.entry.entryPoint===`execute`)&&await e.apply(hold(e.view(),{on:`tasks`})),{next:null,session:e.session})}async function stopForToolSignIn(e,t){return e.session={...e.session,history:validateHarnessModelMessages(t.history)},await e.apply(requireSignIn(e.view(),{callIdsByName:t.callIdsByName,challenges:t.challenges}),e.session.history),{held:{kind:`request`},next:null,session:e.session}}async function enforceBudget(e,t){let n=checkSessionUsageLimit({canAsk:e.emit!==void 0&&e.config.capabilities?.requestInput===!0,session:e.session,turnSequence:e.position().sequence});if(n.kind!==`within`)return n.kind===`ask`?(e.session={...e.session,history:validateHarnessModelMessages([...t])},await e.apply(requestLimit(e.view(),{request:n.request}),e.session.history),{next:null,session:e.session}):(await e.apply(fail(e.view(),{code:n.code,details:n.details,message:n.message,terminal:{sessionId:e.session.sessionId}})),{next:{done:!0,output:``},session:e.session})}function humanInputContext(e,t){let n=e.view();return{approvedTools:grantedApprovalKeys(n,e=>t.get(e.action.toolName)?.approvalKey?.(e.action.input)),pendingApprovalsNote:renderPendingApprovalsInstruction(n.turn.suspended.flatMap(e=>e.requests))}}function discardClearedHumanInput(e){let{"eve.runtime.hitl.approvalState":t,...n}=clearPendingAuthorization(e.state)??{};return{...e,state:Object.keys(n).length>0?n:void 0}}function responsePolicyRequestIds(e,t){return t.filter(t=>{let n=e.get(t.action.toolName)?.approval;return n!==void 0&&typeof n!=`function`&&n.response!==void 0}).map(e=>e.requestId)}function currentRequester(e){return e.ctx?.get(AuthKey)??e.ctx?.get(SessionKey)?.auth.current??null}function retireCancelledCandidates(e){return{...e,state:retireActiveCandidates(e.state,{completedAt:Date.now(),reason:`Cancelled.`})}}function takeDeferredMessage(e){let{queued:t,...n}=readTurnState(e.state);if(t?.message===void 0)return{session:e};let{message:r,...i}=t;return{message:r,session:writeTurnState(e,isEmptyInput(i)?n:{...n,queued:i})}}export{acceptHumanInput,admitApprovedWork,discardClearedHumanInput,dispatchApprovedWorkflows,enforceBudget,extractToolApprovalInputRequests,hasApprovedWork,hasRunnableQueue,humanInputContext,parkOnApprovals,retireCancelledCandidates,runApprovedLocalCalls,stopForToolSignIn,takeDeferredMessage};
1
+ import{renderPendingApprovalsInstruction}from"./approval-prompt.js";import{isEmptyInput}from"./delivery.js";import{grantedApprovalKeys,hasRunnableQueue,parkOnApprovals as parkOnApprovals$1,requestLimit,requireSignIn}from"./approvals.js";import{checkSessionUsageLimit}from"./budget.js";import{discardClearedHitlState,holdsHitlRequests,readHitlState}from"./requests.js";import{retireActiveCandidates}from"./candidates.js";import{acceptHumanInput,admitApprovedWork,dispatchApprovedWorkflows,hasApprovedWork,holdForInput,runApprovedLocalCalls}from"./intake.js";import{AuthKey,SessionKey}from"#context/keys.js";import{validateHarnessModelMessages}from"#harness/messages.js";import{fail,hold}from"#harness/session-machine/transitions.js";import{readTurnState,writeTurnState}from"#harness/session-machine/state.js";import{extractToolApprovalInputRequests}from"#harness/input-extraction.js";async function parkOnApprovals(e,t){let n=parkOnApprovals$1(e.view(),{event:t.event,messages:t.messages,requests:t.requests,tasks:t.tasks,requester:currentRequester(e),responseAuthRequiredRequestIds:responsePolicyRequestIds(t.tools,t.requests)});return await e.apply(n,[...e.session.history,...n.commit??[]]),t.waitsOn===void 0?hasRunnableQueue(e.view())?{next:e.runStep,session:e.session}:holdForInput(e):(t.waitsOn===`runtime`&&t.tasks.some(e=>e.entry.entryPoint===`execute`)&&await e.apply(hold(e.view(),{on:`tasks`})),{next:null,session:e.session})}async function stopForToolSignIn(e,t){return e.session={...e.session,history:validateHarnessModelMessages(t.history)},await e.apply(requireSignIn(e.view(),{callIdsByName:t.callIdsByName,challenges:t.challenges}),e.session.history),{held:{kind:`request`},next:null,session:e.session}}async function enforceBudget(e,t){let n=checkSessionUsageLimit({canAsk:e.emit!==void 0&&e.config.capabilities?.requestInput===!0,session:e.session,turnSequence:e.position().sequence});if(n.kind!==`within`)return n.kind===`ask`?(e.session={...e.session,history:validateHarnessModelMessages([...t])},await e.apply(requestLimit(e.view(),{request:n.request}),e.session.history),{next:null,session:e.session}):(await e.apply(fail(e.view(),{code:n.code,details:n.details,message:n.message,terminal:{sessionId:e.session.sessionId}})),{next:{done:!0,output:``},session:e.session})}function humanInputContext(e,t){let n=e.view();return{approvedTools:grantedApprovalKeys(n,e=>t.get(e.action.toolName)?.approvalKey?.(e.action.input)),pendingApprovalsNote:renderPendingApprovalsInstruction(n.turn.suspended.flatMap(e=>e.requests))}}function responsePolicyRequestIds(e,t){return t.filter(t=>{let n=e.get(t.action.toolName)?.approval;return n!==void 0&&typeof n!=`function`&&n.response!==void 0}).map(e=>e.requestId)}function currentRequester(e){return e.ctx?.get(AuthKey)??e.ctx?.get(SessionKey)?.auth.current??null}function retireCancelledCandidates(e){return{...e,state:retireActiveCandidates(e.state,{completedAt:Date.now(),reason:`Cancelled.`})}}function takeDeferredMessage(e){let{queued:t,...n}=readTurnState(e.state);if(t?.message===void 0)return{session:e};let{message:r,...i}=t;return{message:r,session:writeTurnState(e,isEmptyInput(i)?n:{...n,queued:i})}}export{acceptHumanInput,admitApprovedWork,discardClearedHitlState as discardClearedHumanInput,dispatchApprovedWorkflows,enforceBudget,extractToolApprovalInputRequests,hasApprovedWork,hasRunnableQueue,holdsHitlRequests,humanInputContext,parkOnApprovals,readHitlState,retireCancelledCandidates,runApprovedLocalCalls,stopForToolSignIn,takeDeferredMessage};
@@ -1 +1 @@
1
- import{deliver,resolveTypedApproval,turnInputOnly,withoutTurnInput}from"./delivery.js";import{answer,approvingSteps,deferInput,dispatch,grantedApprovalKeys,requireSignIn,stepForRequest,withdrawSignIns}from"./approvals.js";import{rejectApprovedCall,runApprovedCalls}from"./approved-calls.js";import{getApprovalAuditState,retireActiveCandidates}from"./candidates.js";import{coordinateApprovalDelivery}from"./coordinator.js";import{SEARCH_TOOL_NAME}from"#protocol/catalog-tools.js";import{activeTurnId}from"#harness/session-machine/view.js";import{bumpSessionRuntimeUsageLimits}from"#harness/turn-tag-state.js";import{collectWorkflowCalls}from"#harness/coordination.js";import{approvedCalls,completeSignIn,hold,settle}from"#harness/session-machine/transitions.js";import{stepStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{SessionLimitDeclinedError,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{resolveInlineAuthorizationInterrupt}from"#harness/inline-tool-authorization.js";import{recheckApprovedCall}from"#harness/tools.js";import{buildStepCatalog}from"#execution/catalog/step-catalog.js";async function acceptHumanInput(e,t,n){let{config:r,ctx:i}=e,a=r.signInCompletions??[];a.length>0&&await e.apply(completeSignIn(e.view(),{completions:a}));let o=deliver(e.view(),t,n),s=resolveTypedApproval(e.view(),o.input),c=t?.message!==void 0&&s?.message!==void 0||o.displayMessage!==void 0?await withdrawSteeredSignIns(e,s):s,l=new Map,u,restoreTools=async t=>{let n=t?.event??e.position(),a=`${n.turnId}:${n.stepIndex}`,o=l.get(a);if(o!==void 0&&u===a)return o;t!==void 0&&await r.prepareApprovalTurn?.(t.event),i!==void 0&&await r.resolveStepDynamicTools?.({ctx:i,event:stepStartedForResolvers({modelId:e.session.agent.modelReference?.id??`dynamic`,sequence:n.sequence,stepIndex:n.stepIndex,turnId:n.turnId}),messages:e.projectHistory(e.session.history)});let s=buildStepCatalog({agentTools:r.tools,ctx:i,endsTurn:!1,session:e.session});return l.set(a,s),u=a,s},toolsOf=e=>(e&&l.get(`${e.event.turnId}:${e.event.stepIndex}`))??r.tools,d=e.view().signIns,f=await coordinateApprovalDelivery({session:e.session,stepInput:c,tools:r.tools,prepareTools:t=>restoreTools(stepForRequest(e.view(),t.requestId))});e.session=f.session;for(let t of approvingSteps(e.view(),f.stepInput))await restoreTools(t);let p=answer(e.view(),{approvalKey:t=>toolsOf(stepForRequest(e.view(),t.requestId)).get(t.action.toolName)?.approvalKey?.(t.action.input),delivery:f.stepInput,searchable:t=>toolsOf(stepForRequest(e.view(),t.requestId)).get(SEARCH_TOOL_NAME)!==void 0,policy:{...f,audit:getApprovalAuditState(e.session.state),challengesAtStart:d},takeQueued:o.takeQueued});for(let t of p.resolved)await e.instrumentation?.publishInputResolutions({batch:t,sessionId:e.session.sessionId});await e.apply(p);let stop=e=>({kind:`stop`,result:e});switch(p.next){case`park`:return e.view().projection.activeTurnId===void 0?stop({next:null,session:e.session}):stop(await holdForInput(e));case`repeat`:return stop({next:e.runStep,session:e.session});case`sign-in`:return await e.apply(requireSignIn(e.view(),{challenges:f.challenges,queued:f.stepInput})),stop(held(e))}for(let t of e.view().turn.suspended)(t.approved?.length??0)>0&&await restoreTools(t);let m=p.resolved.some(e=>e.inputs.some(e=>e.request.kind===`tool-approval`)&&e.inputs.every(e=>e.response!==void 0))||approvedCalls(e.view().turn).length>0?turnInputOnly(p.input):void 0;return m!==void 0&&await e.apply(deferInput(e.view(),m)),{approved:{limit:p.limit,toolsOf},consumedMessage:p.consumedMessage===!0,input:m===void 0?p.input:withoutTurnInput(p.input),message:p.consumedMessage===!0||m!==void 0?void 0:o.displayMessage??o.input?.message,kind:`run`,opensTurn:hasTurnInput(o.input)||hasTurnInput(f.stepInput)}}async function admitApprovedWork(e,t){if(t.limit!==void 0){if(!t.limit.granted)throw new SessionLimitDeclinedError;e.session=bumpSessionRuntimeUsageLimits(e.session)}await e.apply(settle(e.view(),{results:[]}))}function hasApprovedWork(e){return approvedCalls(e.view().turn).length>0}async function dispatchApprovedWorkflows(e,t){let n=[],r=[];for(let i of e.view().turn.suspended){let a=t.toolsOf(i),o=[];for(let t of i.approved??[]){let n=a.get(t.action.toolName);if(n?.workflowId===void 0)continue;let i=await recheckApprovedCall(n,{abortSignal:e.config.abortSignal,callId:t.action.callId,input:t.action.input,approvedTools:grantedApprovalKeys(e.view(),e=>a.get(e.action.toolName)?.approvalKey?.(e.action.input))});i.denied?r.push(await rejectApprovedCall({request:t,reason:i.reason,position:e.position(),publish:e.publish})):o.push(t)}if(o.length===0)continue;let s=collectWorkflowCalls({session:e.session,toolCalls:o.map(({action:e})=>({input:e.input,toolCallId:e.callId,toolName:e.toolName})),tools:a,turnId:i.event.turnId});e.session=s.session,n.push(...s.workflowRequests)}return r.length>0&&await e.apply(settle(e.view(),{results:r})),n.length!==0&&(await e.apply(dispatch(e.view(),{tasks:n})),n.some(e=>e.entry.entryPoint===`execute`)&&await e.apply(hold(e.view(),{on:`tasks`})),!0)}async function runApprovedLocalCalls(e,t,n){let r=e.view().turn.suspended.map(e=>{let n=t.toolsOf(e);return{requests:(e.approved??[]).filter(e=>n.get(e.action.toolName)?.workflowId===void 0),tools:n}}),i=r.flatMap(({requests:e})=>e);e.frameworkToolNames=new Set(r.flatMap(({requests:e,tools:t})=>e.map(e=>e.action.toolName).filter(e=>t.get(e)?.frameworkTool===!0)));let a=e.position(),o=i.length===0?void 0:e.instrumentation?.prepareAttempt({isFrameworkTool:t=>e.frameworkToolNames.has(t),attemptIndex:0,stepIndex:a.stepIndex,turnId:activeTurnId(a)});o!==void 0&&n(o.scope);let s=await Promise.all(r.map(async({requests:t,tools:n})=>t.length===0?{settled:[],toolResults:[]}:await runApprovedCalls({abortSignal:e.config.abortSignal,approvedTools:grantedApprovalKeys(e.view(),e=>n.get(e.action.toolName)?.approvalKey?.(e.action.input)),messages:e.projectHistory(e.session.history),position:e.position(),publish:e.publish,requests:t,telemetry:o?.telemetry,tools:n})));await e.apply(settle(e.view(),{results:s.flatMap(e=>e.settled)})),throwIfTurnAborted(e.config.abortSignal);let c=resolveInlineAuthorizationInterrupt({messages:[],toolResults:s.flatMap(e=>e.toolResults)});if(c!==void 0)return await e.apply(requireSignIn(e.view(),{callIdsByName:c.callIdsByName,challenges:c.challenges}),e.session.history),held(e)}const STEERED_SIGN_IN_REASON=`Cancelled because a new message arrived.`;async function holdForInput(e){return await e.apply(hold(e.view(),{on:`input`})),held(e)}function held(e){return{held:{kind:`request`},next:null,session:e.session}}async function withdrawSteeredSignIns(e,t){let n=[...new Set(e.view().signIns.map(e=>e.name))];return e.session={...e.session,state:retireActiveCandidates(e.session.state,{completedAt:Date.now(),reason:STEERED_SIGN_IN_REASON})},n.length===0?t:(await e.apply(withdrawSignIns(e.view(),STEERED_SIGN_IN_REASON)),{...t,context:[...t?.context??[],`Sign-in to ${n.join(`, `)} was cancelled because the user sent a new message instead. Ask to sign in again only if the new message still needs it.`]})}function hasTurnInput(e){return e===void 0?!1:e.message!==void 0||(e.inputResponses?.length??0)>0}export{acceptHumanInput,admitApprovedWork,dispatchApprovedWorkflows,hasApprovedWork,holdForInput,runApprovedLocalCalls};
1
+ import{deliver,resolveTypedApproval,turnInputOnly,withoutTurnInput}from"./delivery.js";import{answer,approvingSteps,deferInput,dispatch,grantedApprovalKeys,requireSignIn,stepForRequest,withdrawSignIns}from"./approvals.js";import{rejectApprovedCall,runApprovedCalls}from"./approved-calls.js";import{getApprovalAuditState,responderOfRequest,retireActiveCandidates}from"./candidates.js";import{coordinateApprovalDelivery}from"./coordinator.js";import{SEARCH_TOOL_NAME}from"#protocol/catalog-tools.js";import{activeTurnId}from"#harness/session-machine/view.js";import{bumpSessionRuntimeUsageLimits}from"#harness/turn-tag-state.js";import{collectWorkflowCalls}from"#harness/coordination.js";import{approvedCalls,completeSignIn,hold,settle}from"#harness/session-machine/transitions.js";import{stepStartedForResolvers}from"#harness/session-machine/resolver-events.js";import{SessionLimitDeclinedError,throwIfTurnAborted}from"#harness/turn-cancellation.js";import{resolveInlineAuthorizationInterrupt}from"#harness/inline-tool-authorization.js";import{recheckApprovedCall}from"#harness/tools.js";import{buildStepCatalog}from"#execution/catalog/step-catalog.js";async function acceptHumanInput(e,t,n){let{config:r,ctx:i}=e,a=r.signInCompletions??[];a.length>0&&await e.apply(completeSignIn(e.view(),{completions:a}));let o=deliver(e.view(),t,n),s=resolveTypedApproval(e.view(),o.input),c=t?.message!==void 0&&s?.message!==void 0||o.displayMessage!==void 0?await withdrawSteeredSignIns(e,s):s,l=new Map,u,restoreTools=async t=>{let n=t?.event??e.position(),a=`${n.turnId}:${n.stepIndex}`,o=l.get(a);if(o!==void 0&&u===a)return o;t!==void 0&&await r.prepareApprovalTurn?.(t.event),i!==void 0&&await r.resolveStepDynamicTools?.({ctx:i,event:stepStartedForResolvers({modelId:e.session.agent.modelReference?.id??`dynamic`,sequence:n.sequence,stepIndex:n.stepIndex,turnId:n.turnId}),messages:e.projectHistory(e.session.history)});let s=buildStepCatalog({agentTools:r.tools,ctx:i,endsTurn:!1,session:e.session});return l.set(a,s),u=a,s},toolsOf=e=>(e&&l.get(`${e.event.turnId}:${e.event.stepIndex}`))??r.tools,d=e.view().signIns,f=await coordinateApprovalDelivery({session:e.session,stepInput:c,tools:r.tools,prepareTools:t=>restoreTools(stepForRequest(e.view(),t.requestId))});e.session=f.session;for(let t of approvingSteps(e.view(),f.stepInput))await restoreTools(t);let p=answer(e.view(),{approvalKey:t=>toolsOf(stepForRequest(e.view(),t.requestId)).get(t.action.toolName)?.approvalKey?.(t.action.input),delivery:f.stepInput,searchable:t=>toolsOf(stepForRequest(e.view(),t.requestId)).get(SEARCH_TOOL_NAME)!==void 0,policy:{...f,audit:getApprovalAuditState(e.session.state),challengesAtStart:d},takeQueued:o.takeQueued});for(let t of p.resolved)await e.instrumentation?.publishInputResolutions({batch:t,sessionId:e.session.sessionId});await e.apply(p);let stop=e=>({kind:`stop`,result:e});switch(p.next){case`park`:return e.view().projection.activeTurnId===void 0?stop({next:null,session:e.session}):stop(await holdForInput(e));case`repeat`:return stop({next:e.runStep,session:e.session});case`sign-in`:return await e.apply(requireSignIn(e.view(),{challenges:f.challenges,queued:f.stepInput})),stop(held(e))}for(let t of e.view().turn.suspended)(t.approved?.length??0)>0&&await restoreTools(t);let m=p.resolved.some(e=>e.inputs.some(e=>e.request.kind===`tool-approval`)&&e.inputs.every(e=>e.response!==void 0))||approvedCalls(e.view().turn).length>0?turnInputOnly(p.input):void 0;return m!==void 0&&await e.apply(deferInput(e.view(),m)),{approved:{limit:p.limit,toolsOf},consumedMessage:p.consumedMessage===!0,input:m===void 0?p.input:withoutTurnInput(p.input),message:p.consumedMessage===!0||m!==void 0?void 0:o.displayMessage??o.input?.message,kind:`run`,opensTurn:hasTurnInput(o.input)||hasTurnInput(f.stepInput)}}async function admitApprovedWork(e,t){if(t.limit!==void 0){if(!t.limit.granted)throw new SessionLimitDeclinedError;e.session=bumpSessionRuntimeUsageLimits(e.session)}await e.apply(settle(e.view(),{results:[]}))}function hasApprovedWork(e){return approvedCalls(e.view().turn).length>0}async function dispatchApprovedWorkflows(e,t){let n=[],r=[];for(let i of e.view().turn.suspended){let a=t.toolsOf(i),o=[];for(let t of i.approved??[]){let n=a.get(t.action.toolName);if(n?.workflowId===void 0)continue;let i=await recheckApprovedCall(n,{abortSignal:e.config.abortSignal,callId:t.action.callId,input:t.action.input,approvedTools:grantedApprovalKeys(e.view(),e=>a.get(e.action.toolName)?.approvalKey?.(e.action.input))});i.denied?r.push(await rejectApprovedCall({request:t,reason:i.reason,position:e.position(),publish:e.publish})):o.push(t)}if(o.length===0)continue;let s=collectWorkflowCalls({session:e.session,toolCalls:o.map(({action:e})=>({input:e.input,toolCallId:e.callId,toolName:e.toolName})),tools:a,turnId:i.event.turnId});e.session=s.session,n.push(...s.workflowRequests)}return r.length>0&&await e.apply(settle(e.view(),{results:r})),n.length!==0&&(await e.apply(dispatch(e.view(),{tasks:n})),n.some(e=>e.entry.entryPoint===`execute`)&&await e.apply(hold(e.view(),{on:`tasks`})),!0)}async function runApprovedLocalCalls(e,t,n){let r=e.view().turn.suspended.map(e=>{let n=t.toolsOf(e);return{requests:(e.approved??[]).filter(e=>n.get(e.action.toolName)?.workflowId===void 0),tools:n}}),i=r.flatMap(({requests:e})=>e);e.frameworkToolNames=new Set(r.flatMap(({requests:e,tools:t})=>e.map(e=>e.action.toolName).filter(e=>t.get(e)?.frameworkTool===!0)));let a=e.position(),o=i.length===0?void 0:e.instrumentation?.prepareAttempt({isFrameworkTool:t=>e.frameworkToolNames.has(t),attemptIndex:0,stepIndex:a.stepIndex,turnId:activeTurnId(a)});o!==void 0&&n(o.scope);let s=await Promise.all(r.map(async({requests:t,tools:n})=>t.length===0?{settled:[],toolResults:[]}:await runApprovedCalls({abortSignal:e.config.abortSignal,approvedTools:grantedApprovalKeys(e.view(),e=>n.get(e.action.toolName)?.approvalKey?.(e.action.input)),messages:e.projectHistory(e.session.history),position:e.position(),publish:e.publish,requests:t,responderOf:t=>responderOfRequest(e.session.state,t.requestId),telemetry:o?.telemetry,tools:n})));await e.apply(settle(e.view(),{results:s.flatMap(e=>e.settled)})),throwIfTurnAborted(e.config.abortSignal);let c=resolveInlineAuthorizationInterrupt({messages:[],toolResults:s.flatMap(e=>e.toolResults)});if(c!==void 0)return await e.apply(requireSignIn(e.view(),{callIdsByName:c.callIdsByName,challenges:c.challenges}),e.session.history),held(e)}const STEERED_SIGN_IN_REASON=`Cancelled because a new message arrived.`;async function holdForInput(e){return await e.apply(hold(e.view(),{on:`input`})),held(e)}function held(e){return{held:{kind:`request`},next:null,session:e.session}}async function withdrawSteeredSignIns(e,t){let n=[...new Set(e.view().signIns.map(e=>e.name))];return e.session={...e.session,state:retireActiveCandidates(e.session.state,{completedAt:Date.now(),reason:STEERED_SIGN_IN_REASON})},n.length===0?t:(await e.apply(withdrawSignIns(e.view(),STEERED_SIGN_IN_REASON)),{...t,context:[...t?.context??[],`Sign-in to ${n.join(`, `)} was cancelled because the user sent a new message instead. Ask to sign in again only if the new message still needs it.`]})}function hasTurnInput(e){return e===void 0?!1:e.message!==void 0||(e.inputResponses?.length??0)>0}export{acceptHumanInput,admitApprovedWork,dispatchApprovedWorkflows,hasApprovedWork,holdForInput,runApprovedLocalCalls};
@@ -1,8 +1,7 @@
1
1
  import type { SubagentInputRequestHookPayload } from "#channel/types.js";
2
2
  import type { InputResolvedStreamEvent } from "#protocol/message.js";
3
3
  import type { StepCoordinates as PendingInputBatchEvent } from "#harness/session-machine/view.js";
4
- import type { HarnessSessionBase, SessionStateMap } from "#harness/types.js";
5
- import { type InputOption, type InputRequestKind } from "#shared/input.js";
4
+ import type { InputOption, InputRequestKind } from "#shared/input.js";
6
5
  import { type SessionInboxAddress } from "#execution/session-inbox/address.js";
7
6
  import type { RemoteAgentBinding } from "#eve-channel/support.js";
8
7
  /**
@@ -60,45 +59,10 @@ export declare function resolvedByChild(kind: InputRequestKind): boolean;
60
59
  * the child to close. `undefined` when the parent already closed all of them.
61
60
  */
62
61
  export declare function resolvedForParent(data: InputResolvedStreamEvent["data"]): InputResolvedStreamEvent["data"] | undefined;
63
- /**
64
- * Returns the proxy-routing map as a fresh `Map`. Never returns a live
65
- * reference so accidental mutation cannot corrupt session state.
66
- */
67
- export declare function getProxyInputRequests(state: SessionStateMap | undefined): ReadonlyMap<string, ProxyInputRequest>;
68
- /**
69
- * Returns true when the session is currently proxying one or more
70
- * HITL requests on behalf of a descendant subagent.
71
- */
72
- export declare function hasProxyInputRequests(state: SessionStateMap | undefined): boolean;
73
- /**
74
- * Replaces prior entries for the destination and input source with the provided
75
- * ones. A child raising a fresh batch overwrites its prior batch so the
76
- * parent never keeps stale request metadata. Other sources' routes stay
77
- * independently answerable.
78
- */
79
- export declare function upsertProxyInputRequests<S extends HarnessSessionBase>(input: {
80
- readonly inputSource?: string;
81
- readonly entries: readonly (readonly [requestId: string, route: ProxyInputRequest])[];
82
- readonly forChildContinuationToken: string;
83
- readonly session: S;
84
- }): S;
85
- /** State-only variant for control-plane steps that already hold a durable projection. */
86
- export declare function upsertProxyInputRequestState(input: {
87
- readonly inputSource?: string;
88
- readonly entries: readonly (readonly [requestId: string, route: ProxyInputRequest])[];
89
- readonly forChildContinuationToken: string;
90
- readonly state: SessionStateMap | undefined;
91
- }): SessionStateMap | undefined;
92
- /** Removes every proxy route the predicate selects. */
93
- export declare function clearProxyInputRequestsWhere<T extends {
94
- readonly state?: SessionStateMap;
95
- }>(session: T, select: (route: ProxyInputRequest, requestId: string) => boolean): T;
96
- /** Removes only the request IDs whose responses were successfully forwarded. */
97
- export declare function retireProxyInputRequests<T extends {
98
- readonly state?: SessionStateMap;
99
- }>(session: T, requestIds: readonly string[]): T;
100
62
  /**
101
63
  * Projects a {@link SubagentInputRequestHookPayload} into the
102
64
  * `(requestId, route)` tuples the session stores.
103
65
  */
104
66
  export declare function toProxyInputRequestEntries(payload: SubagentInputRequestHookPayload): readonly (readonly [requestId: string, route: ProxyInputRequest])[];
67
+ /** Reads one stored route, or `undefined` when it is malformed. */
68
+ export declare function parseProxyInputRequest(value: unknown, requestId: string): ProxyInputRequest | undefined;
@@ -0,0 +1 @@
1
+ import{isSessionInboxAddress}from"#execution/session-inbox/address.js";const PROXY_INPUT_REQUEST_KINDS={question:!0,"session-limit":!0,"tool-approval":!0};function resolvedByChild(e){return e===`tool-approval`}function resolvedForParent(e){let t=e.resolutions.filter(({kind:e})=>resolvedByChild(e));return t.length===0?void 0:{...e,resolutions:t}}function toProxyInputRequestEntries(e){let t={approvalRequestIds:e.event.requests.flatMap(e=>e.kind===`tool-approval`?[e.requestId]:[]),requestIds:e.event.requests.map(e=>e.requestId)},n={sequence:e.event.sequence,stepIndex:e.event.stepIndex,turnId:e.event.turnId};return e.event.requests.map(r=>{let i={batch:t,childContinuationToken:e.childContinuationToken,...e.inputSource!==void 0&&{inputSource:e.inputSource},...e.remote!==void 0&&{remote:e.remote},event:n,kind:r.kind,reply:{...r.allowFreeform!==void 0&&{allowFreeform:r.allowFreeform},...r.options!==void 0&&{options:[...r.options]}}};return e.childSessionInbox?.sessionId===e.childSessionId&&(i.childSessionInbox=e.childSessionInbox),[r.requestId,i]})}function parseProxyInputRequest(e,t){if(typeof e!=`object`||!e||Array.isArray(e)||!(`childContinuationToken`in e)||!(`kind`in e)||typeof e.childContinuationToken!=`string`||!isInputRequestKind(e.kind))return;let n=`remote`in e?parseRemoteAgentBinding(e.remote):void 0;if(`remote`in e&&n===void 0)return;let r=`inputSource`in e?e.inputSource:void 0;if(r!==void 0&&(typeof r!=`string`||r.length===0))return;let i=`event`in e?parseInputRequestEvent(e.event):void 0;if(i===void 0)return;let a=`batch`in e?parseProxyInputRequestBatch(e.batch):void 0,o=`workflowAsk`in e?parseWorkflowAskRoute(e.workflowAsk):void 0;if(`workflowAsk`in e&&o===void 0)return;let s=`runId`in e?e.runId:void 0;if(s!==void 0&&(typeof s!=`string`||s.length===0))return;let c=`reply`in e?parseProxyInputReply(e.reply):void 0;if(`reply`in e&&c===void 0)return;let l=`childSessionInbox`in e?e.childSessionInbox:void 0;if(l!==void 0&&!isSessionInboxAddress(l))return;let u={childContinuationToken:e.childContinuationToken,event:i,kind:e.kind};return typeof r==`string`&&(u.inputSource=r),n!==void 0&&(u.remote=n),o!==void 0&&(u.workflowAsk=o),typeof s==`string`&&(u.runId=s),l!==void 0&&(u.childSessionInbox=l),a!==void 0&&a.requestIds.includes(t)&&(u.batch=a),c!==void 0&&(u.reply=c),u}function parseInputRequestEvent(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=Reflect.get(e,`sequence`),n=Reflect.get(e,`stepIndex`),r=Reflect.get(e,`turnId`);if(typeof t==`number`&&typeof n==`number`&&typeof r==`string`)return{sequence:t,stepIndex:n,turnId:r}}function parseWorkflowAskRoute(e){if(typeof e!=`object`||!e)return;let t=Reflect.get(e,`control`);if(typeof t==`string`&&t.length!==0)return{control:t}}function parseRemoteAgentBinding(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t=Reflect.get(e,`name`),n=Reflect.get(e,`url`),r=Reflect.get(e,`resolverId`),i=Reflect.get(e,`forwardPrincipal`),a=Reflect.get(e,`sessionId`);if(typeof t==`string`&&t&&typeof n==`string`&&n&&typeof a==`string`&&a&&(r===void 0||typeof r==`string`&&r)&&(i===void 0||typeof i==`boolean`))return{name:t,url:n,sessionId:a,...r!==void 0&&{resolverId:r},...i!==void 0&&{forwardPrincipal:i}}}function parseProxyInputReply(e){if(typeof e!=`object`||!e||Array.isArray(e))return;let t={},n=Reflect.get(e,`allowFreeform`);if(n!==void 0){if(typeof n!=`boolean`)return;t.allowFreeform=n}let r=Reflect.get(e,`options`);if(r!==void 0){if(!Array.isArray(r)||!Array.from(r).every(isInputOption))return;t.options=r}return t}function parseProxyInputRequestBatch(e){if(typeof e!=`object`||!e||Array.isArray(e)||!(`approvalRequestIds`in e)||!(`requestIds`in e)||!isStringArray(e.approvalRequestIds)||!isStringArray(e.requestIds))return;let t=new Set(e.requestIds);if(!(t.size!==e.requestIds.length||e.approvalRequestIds.some(e=>!t.has(e))))return{approvalRequestIds:e.approvalRequestIds,requestIds:e.requestIds}}const INPUT_OPTION_FIELDS={description:e=>e===void 0||typeof e==`string`,id:e=>typeof e==`string`,label:e=>typeof e==`string`,style:e=>e===void 0||e===`primary`||e===`danger`||e==="default"};function isInputOption(e){return typeof e!=`object`||!e||Array.isArray(e)?!1:Object.keys(e).every(e=>Object.hasOwn(INPUT_OPTION_FIELDS,e))&&Object.entries(INPUT_OPTION_FIELDS).every(([t,n])=>n(Reflect.get(e,t)))}function isStringArray(e){return Array.isArray(e)&&e.every(e=>typeof e==`string`)}function isInputRequestKind(e){return typeof e==`string`&&Object.hasOwn(PROXY_INPUT_REQUEST_KINDS,e)}export{parseProxyInputRequest,resolvedByChild,resolvedForParent,toProxyInputRequestEntries};