@stigmer/runner 3.40.0 → 3.41.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +3 -1
  2. package/dist/.build-fingerprint +1 -1
  3. package/dist/__test-utils__/execution-record-fixture.d.ts +2 -1
  4. package/dist/__test-utils__/execution-record-fixture.js.map +1 -1
  5. package/dist/activities/call-agent.js +1 -1
  6. package/dist/activities/discover-mcp-server.d.ts +7 -1
  7. package/dist/activities/discover-mcp-server.js +13 -29
  8. package/dist/activities/discover-mcp-server.js.map +1 -1
  9. package/dist/activities/execute-cursor/__test-utils__/fold.d.ts +4 -2
  10. package/dist/activities/execute-cursor/__test-utils__/fold.js +3 -4
  11. package/dist/activities/execute-cursor/__test-utils__/fold.js.map +1 -1
  12. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js +1 -0
  13. package/dist/activities/execute-cursor/__test-utils__/hermetic-cursor.js.map +1 -1
  14. package/dist/activities/execute-cursor/approval-policy.d.ts +1 -29
  15. package/dist/activities/execute-cursor/approval-policy.js +11 -35
  16. package/dist/activities/execute-cursor/approval-policy.js.map +1 -1
  17. package/dist/activities/execute-cursor/boundary-rows.js +4 -4
  18. package/dist/activities/execute-cursor/boundary-rows.js.map +1 -1
  19. package/dist/activities/execute-cursor/translator.d.ts +12 -17
  20. package/dist/activities/execute-cursor/translator.js +13 -30
  21. package/dist/activities/execute-cursor/translator.js.map +1 -1
  22. package/dist/activities/execute-cursor/turn-stream.js +4 -2
  23. package/dist/activities/execute-cursor/turn-stream.js.map +1 -1
  24. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.d.ts +11 -1
  25. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js +22 -3
  26. package/dist/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.js.map +1 -1
  27. package/dist/activities/execute-deep-agent/inline-publisher.d.ts +33 -2
  28. package/dist/activities/execute-deep-agent/inline-publisher.js +33 -7
  29. package/dist/activities/execute-deep-agent/inline-publisher.js.map +1 -1
  30. package/dist/activities/execute-deep-agent/platform-route.d.ts +48 -13
  31. package/dist/activities/execute-deep-agent/platform-route.js +87 -19
  32. package/dist/activities/execute-deep-agent/platform-route.js.map +1 -1
  33. package/dist/activities/execute-deep-agent/prompt-builder.d.ts +70 -35
  34. package/dist/activities/execute-deep-agent/prompt-builder.js +70 -55
  35. package/dist/activities/execute-deep-agent/prompt-builder.js.map +1 -1
  36. package/dist/activities/execute-deep-agent/streaming-side-effects.d.ts +20 -3
  37. package/dist/activities/execute-deep-agent/streaming-side-effects.js +26 -4
  38. package/dist/activities/execute-deep-agent/streaming-side-effects.js.map +1 -1
  39. package/dist/activities/execute-deep-agent/translator.d.ts +5 -4
  40. package/dist/activities/execute-deep-agent/translator.js +5 -4
  41. package/dist/activities/execute-deep-agent/translator.js.map +1 -1
  42. package/dist/activities/execute-deep-agent/turn-settle.js +6 -6
  43. package/dist/activities/execute-deep-agent/turn-settle.js.map +1 -1
  44. package/dist/activities/execute-deep-agent/turn-setup.d.ts +18 -13
  45. package/dist/activities/execute-deep-agent/turn-setup.js +42 -36
  46. package/dist/activities/execute-deep-agent/turn-setup.js.map +1 -1
  47. package/dist/activities/execute-deep-agent/turn-stream.d.ts +10 -6
  48. package/dist/activities/execute-deep-agent/turn-stream.js +6 -16
  49. package/dist/activities/execute-deep-agent/turn-stream.js.map +1 -1
  50. package/dist/activities/execute-deep-agent/turn.d.ts +4 -1
  51. package/dist/activities/execute-deep-agent/turn.js +15 -6
  52. package/dist/activities/execute-deep-agent/turn.js.map +1 -1
  53. package/dist/activities/workflow-event-activities.js +2 -0
  54. package/dist/activities/workflow-event-activities.js.map +1 -1
  55. package/dist/config.d.ts +9 -0
  56. package/dist/config.js +2 -0
  57. package/dist/config.js.map +1 -1
  58. package/dist/exit-backstop.d.ts +64 -0
  59. package/dist/exit-backstop.js +79 -0
  60. package/dist/exit-backstop.js.map +1 -0
  61. package/dist/harness/terminal-table.d.ts +12 -5
  62. package/dist/harness/terminal-table.js +13 -13
  63. package/dist/harness/terminal-table.js.map +1 -1
  64. package/dist/harness/transcript/builder.d.ts +21 -0
  65. package/dist/harness/transcript/builder.js +53 -31
  66. package/dist/harness/transcript/builder.js.map +1 -1
  67. package/dist/harness/transcript/events.d.ts +22 -26
  68. package/dist/harness/transcript/events.js +6 -5
  69. package/dist/harness/transcript/events.js.map +1 -1
  70. package/dist/harness/turn-context.d.ts +3 -1
  71. package/dist/harness/turn-context.js +5 -3
  72. package/dist/harness/turn-context.js.map +1 -1
  73. package/dist/main.js +10 -4
  74. package/dist/main.js.map +1 -1
  75. package/dist/middleware/cost-advisory.d.ts +6 -3
  76. package/dist/middleware/cost-advisory.js +6 -3
  77. package/dist/middleware/cost-advisory.js.map +1 -1
  78. package/dist/middleware/execution-budget.d.ts +22 -7
  79. package/dist/middleware/execution-budget.js +57 -35
  80. package/dist/middleware/execution-budget.js.map +1 -1
  81. package/dist/middleware/index.d.ts +10 -7
  82. package/dist/middleware/index.js +10 -7
  83. package/dist/middleware/index.js.map +1 -1
  84. package/dist/middleware/types.d.ts +6 -1
  85. package/dist/runner-manager.js +3 -2
  86. package/dist/runner-manager.js.map +1 -1
  87. package/dist/runner.d.ts +25 -0
  88. package/dist/runner.js +41 -14
  89. package/dist/runner.js.map +1 -1
  90. package/dist/shared/approval-policy.d.ts +23 -13
  91. package/dist/shared/approval-policy.js +47 -14
  92. package/dist/shared/approval-policy.js.map +1 -1
  93. package/dist/shared/caller-identity.d.ts +4 -5
  94. package/dist/shared/caller-identity.js +4 -5
  95. package/dist/shared/caller-identity.js.map +1 -1
  96. package/dist/shared/channel-attachment.js +3 -2
  97. package/dist/shared/channel-attachment.js.map +1 -1
  98. package/dist/shared/connect-backfill.d.ts +2 -1
  99. package/dist/shared/connect-backfill.js +2 -2
  100. package/dist/shared/connect-backfill.js.map +1 -1
  101. package/dist/shared/mcp-resolver.d.ts +10 -1
  102. package/dist/shared/mcp-resolver.js +11 -2
  103. package/dist/shared/mcp-resolver.js.map +1 -1
  104. package/dist/shared/memory-attachment.js +3 -2
  105. package/dist/shared/memory-attachment.js.map +1 -1
  106. package/dist/shared/model-error.d.ts +25 -3
  107. package/dist/shared/model-error.js +78 -10
  108. package/dist/shared/model-error.js.map +1 -1
  109. package/dist/shared/platform-server-address.d.ts +71 -0
  110. package/dist/shared/platform-server-address.js +103 -0
  111. package/dist/shared/platform-server-address.js.map +1 -0
  112. package/dist/shared/prompt-sections.d.ts +6 -28
  113. package/dist/shared/prompt-sections.js +6 -35
  114. package/dist/shared/prompt-sections.js.map +1 -1
  115. package/dist/shared/skill-resolver.d.ts +2 -3
  116. package/dist/shared/skill-resolver.js +2 -3
  117. package/dist/shared/skill-resolver.js.map +1 -1
  118. package/dist/shared/synthesized-attachment.d.ts +0 -5
  119. package/dist/shared/synthesized-attachment.js +0 -12
  120. package/dist/shared/synthesized-attachment.js.map +1 -1
  121. package/dist/shared/tool-rounds.d.ts +51 -23
  122. package/dist/shared/tool-rounds.js +67 -24
  123. package/dist/shared/tool-rounds.js.map +1 -1
  124. package/dist/shared/workspace/platform-dir.d.ts +15 -0
  125. package/dist/shared/workspace/platform-dir.js +18 -1
  126. package/dist/shared/workspace/platform-dir.js.map +1 -1
  127. package/dist/shared/workspace/sources/git.js +13 -6
  128. package/dist/shared/workspace/sources/git.js.map +1 -1
  129. package/dist/shared/workspace/stigmer-link.d.ts +21 -14
  130. package/dist/shared/workspace/stigmer-link.js +91 -29
  131. package/dist/shared/workspace/stigmer-link.js.map +1 -1
  132. package/dist/tools/url-guard.d.ts +5 -1
  133. package/dist/tools/url-guard.js +9 -2
  134. package/dist/tools/url-guard.js.map +1 -1
  135. package/dist/worker.d.ts +11 -2
  136. package/dist/worker.js +1 -1
  137. package/dist/worker.js.map +1 -1
  138. package/dist/workflow-engine/tasks/human-input.d.ts +16 -0
  139. package/dist/workflow-engine/tasks/human-input.js +79 -37
  140. package/dist/workflow-engine/tasks/human-input.js.map +1 -1
  141. package/dist/workflow-engine/types.d.ts +14 -4
  142. package/dist/workflow-engine/types.js.map +1 -1
  143. package/dist/workflows/call-agent-orchestrator.d.ts +13 -0
  144. package/dist/workflows/call-agent-orchestrator.js.map +1 -1
  145. package/dist/workflows/engine-core.d.ts +25 -0
  146. package/dist/workflows/engine-core.js.map +1 -1
  147. package/dist/workflows/execute-from-execution.d.ts +3 -0
  148. package/dist/workflows/execute-from-execution.js.map +1 -1
  149. package/dist/workflows/human-input-orchestrator.d.ts +9 -12
  150. package/dist/workflows/human-input-orchestrator.js +12 -44
  151. package/dist/workflows/human-input-orchestrator.js.map +1 -1
  152. package/package.json +5 -5
  153. package/src/__test-utils__/config-fixture.ts +1 -0
  154. package/src/__test-utils__/execution-record-fixture.ts +2 -1
  155. package/src/__test-utils__/harness-contract/runtime-contract.ts +5 -3
  156. package/src/__test-utils__/test-gate.ts +8 -0
  157. package/src/__tests__/exit-backstop.test.ts +91 -0
  158. package/src/__tests__/golden-e2e.test.ts +80 -62
  159. package/src/__tests__/history-encryption-e2e.test.ts +51 -27
  160. package/src/__tests__/runner.test.ts +60 -2
  161. package/src/activities/__tests__/classify-tool-approvals.test.ts +1 -0
  162. package/src/activities/__tests__/discover-mcp-server.hang.test.ts +5 -1
  163. package/src/activities/__tests__/discover-mcp-server.test.ts +90 -49
  164. package/src/activities/__tests__/workflow-event-activities.test.ts +28 -7
  165. package/src/activities/call-agent.ts +1 -1
  166. package/src/activities/discover-mcp-server.ts +27 -37
  167. package/src/activities/execute-cursor/__test-utils__/fold.ts +6 -4
  168. package/src/activities/execute-cursor/__test-utils__/hermetic-cursor.ts +1 -0
  169. package/src/activities/execute-cursor/__tests__/approval-gate.test.ts +4 -29
  170. package/src/activities/execute-cursor/__tests__/hermetic/bypassed-tool-call.test.ts +120 -0
  171. package/src/activities/execute-cursor/__tests__/hermetic/file-review-capture.test.ts +5 -5
  172. package/src/activities/execute-cursor/__tests__/hermetic/goldens/file-review-capture.status.json +0 -2
  173. package/src/activities/execute-cursor/__tests__/hermetic/goldens/resolution-error.status.json +1 -1
  174. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.error-delta.status.json +0 -3
  175. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.output-first.status.json +0 -2
  176. package/src/activities/execute-cursor/__tests__/hermetic/goldens/shell-output-delta.status.json +0 -2
  177. package/src/activities/execute-cursor/__tests__/hermetic/goldens/stall.status.json +0 -2
  178. package/src/activities/execute-cursor/__tests__/hermetic/goldens/unattributed-hook-block.status.json +0 -3
  179. package/src/activities/execute-cursor/__tests__/hermetic/shell-output-delta.test.ts +9 -7
  180. package/src/activities/execute-cursor/__tests__/hermetic/thrown-error-arms.test.ts +6 -1
  181. package/src/activities/execute-cursor/__tests__/hitl-resume-history.test.ts +8 -11
  182. package/src/activities/execute-cursor/__tests__/sequential-gate-resume.test.ts +1 -3
  183. package/src/activities/execute-cursor/__tests__/translator.test.ts +68 -15
  184. package/src/activities/execute-cursor/approval-policy.ts +11 -36
  185. package/src/activities/execute-cursor/boundary-rows.ts +3 -3
  186. package/src/activities/execute-cursor/translator.ts +15 -32
  187. package/src/activities/execute-cursor/turn-stream.ts +4 -1
  188. package/src/activities/execute-deep-agent/__test-utils__/hermetic-deep-agent.ts +33 -2
  189. package/src/activities/execute-deep-agent/__tests__/adapter.test.ts +1 -0
  190. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.build-from-plan.prompt.md +1 -27
  191. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.everything.prompt.md +26 -30
  192. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.plan-mode.prompt.md +1 -26
  193. package/src/activities/execute-deep-agent/__tests__/goldens/user-message.everything.md +36 -0
  194. package/src/activities/execute-deep-agent/__tests__/hermetic/file-review-capture.test.ts +4 -0
  195. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/file-review-capture.status.json +1 -1
  196. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn1.status.json +1 -1
  197. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/inline-artifact.turn2.status.json +1 -1
  198. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/recursion-limit.persisted.status.json +8 -73
  199. package/src/activities/execute-deep-agent/__tests__/hermetic/goldens/resolution-error.status.json +1 -1
  200. package/src/activities/execute-deep-agent/__tests__/hermetic/inline-artifact-across-gate.test.ts +17 -0
  201. package/src/activities/execute-deep-agent/__tests__/hermetic/recursion-limit.test.ts +86 -26
  202. package/src/activities/execute-deep-agent/__tests__/hermetic/resolution-error.test.ts +9 -5
  203. package/src/activities/execute-deep-agent/__tests__/hermetic/thrown-turn-drains-publishes.test.ts +159 -0
  204. package/src/activities/execute-deep-agent/__tests__/inline-publisher.test.ts +84 -0
  205. package/src/activities/execute-deep-agent/__tests__/platform-route.test.ts +47 -10
  206. package/src/activities/execute-deep-agent/__tests__/prompt-builder.test.ts +127 -199
  207. package/src/activities/execute-deep-agent/__tests__/prompt-goldens.test.ts +31 -26
  208. package/src/activities/execute-deep-agent/__tests__/streaming-side-effects.test.ts +34 -0
  209. package/src/activities/execute-deep-agent/__tests__/turn-stream.test.ts +13 -5
  210. package/src/activities/execute-deep-agent/inline-publisher.ts +47 -7
  211. package/src/activities/execute-deep-agent/platform-route.ts +109 -20
  212. package/src/activities/execute-deep-agent/prompt-builder.ts +104 -92
  213. package/src/activities/execute-deep-agent/streaming-side-effects.ts +27 -4
  214. package/src/activities/execute-deep-agent/translator.ts +5 -4
  215. package/src/activities/execute-deep-agent/turn-settle.ts +6 -6
  216. package/src/activities/execute-deep-agent/turn-setup.ts +43 -38
  217. package/src/activities/execute-deep-agent/turn-stream.ts +15 -22
  218. package/src/activities/execute-deep-agent/turn.ts +16 -7
  219. package/src/activities/workflow-event-activities.ts +2 -0
  220. package/src/config.ts +11 -0
  221. package/src/exit-backstop.ts +97 -0
  222. package/src/harness/README.md +5 -5
  223. package/src/harness/terminal-table.ts +13 -13
  224. package/src/harness/transcript/__tests__/builder.test.ts +93 -21
  225. package/src/harness/transcript/builder.ts +53 -30
  226. package/src/harness/transcript/events.ts +22 -27
  227. package/src/harness/turn-context.ts +5 -3
  228. package/src/main.ts +9 -5
  229. package/src/middleware/__tests__/execution-budget.test.ts +181 -103
  230. package/src/middleware/cost-advisory.ts +6 -3
  231. package/src/middleware/execution-budget.ts +60 -34
  232. package/src/middleware/index.ts +10 -7
  233. package/src/middleware/types.ts +6 -1
  234. package/src/runner-manager.ts +3 -2
  235. package/src/runner.ts +57 -15
  236. package/src/shared/__tests__/approval-policy.test.ts +41 -0
  237. package/src/shared/__tests__/artifact-storage.test.ts +1 -0
  238. package/src/shared/__tests__/connect-backfill.test.ts +15 -11
  239. package/src/shared/__tests__/mcp-resolver.test.ts +72 -10
  240. package/src/shared/__tests__/model-error.test.ts +71 -3
  241. package/src/shared/__tests__/platform-server-address.test.ts +122 -0
  242. package/src/shared/__tests__/prompt-sections.test.ts +2 -54
  243. package/src/shared/__tests__/tool-rounds.test.ts +64 -14
  244. package/src/shared/approval-policy.ts +57 -14
  245. package/src/shared/caller-identity.ts +4 -5
  246. package/src/shared/channel-attachment.ts +2 -2
  247. package/src/shared/connect-backfill.ts +5 -1
  248. package/src/shared/mcp-resolver.ts +11 -1
  249. package/src/shared/memory-attachment.ts +2 -2
  250. package/src/shared/model-error.ts +87 -9
  251. package/src/shared/platform-server-address.ts +123 -0
  252. package/src/shared/prompt-sections.ts +6 -55
  253. package/src/shared/skill-resolver.ts +2 -3
  254. package/src/shared/synthesized-attachment.ts +0 -12
  255. package/src/shared/tool-rounds.ts +70 -24
  256. package/src/shared/workspace/__tests__/git-source.test.ts +11 -5
  257. package/src/shared/workspace/__tests__/stigmer-link.test.ts +107 -10
  258. package/src/shared/workspace/platform-dir.ts +19 -1
  259. package/src/shared/workspace/sources/git.ts +14 -8
  260. package/src/shared/workspace/stigmer-link.ts +99 -29
  261. package/src/tools/__tests__/url-guard.test.ts +19 -1
  262. package/src/tools/url-guard.ts +9 -1
  263. package/src/worker.ts +12 -2
  264. package/src/workflow-engine/__tests__/golden-execution.test.ts +2 -1
  265. package/src/workflow-engine/__tests__/loader.test.ts +1 -1
  266. package/src/workflow-engine/__tests__/tasks/human-input.test.ts +133 -57
  267. package/src/workflow-engine/tasks/human-input.ts +92 -42
  268. package/src/workflow-engine/types.ts +16 -4
  269. package/src/workflows/call-agent-orchestrator.ts +7 -0
  270. package/src/workflows/engine-core.ts +18 -0
  271. package/src/workflows/execute-from-execution.ts +2 -1
  272. package/src/workflows/human-input-orchestrator.ts +15 -56
  273. package/dist/shared/skill-relevance.d.ts +0 -65
  274. package/dist/shared/skill-relevance.js +0 -175
  275. package/dist/shared/skill-relevance.js.map +0 -1
  276. package/src/activities/execute-deep-agent/__tests__/goldens/system-prompt.skills-below-threshold.prompt.md +0 -146
  277. package/src/shared/__tests__/skill-relevance.test.ts +0 -292
  278. package/src/shared/skill-relevance.ts +0 -222
@@ -32,6 +32,16 @@
32
32
  * activation and attached to the approval_requested event — inline when
33
33
  * small, as an artifact reference when at/above the promotion threshold —
34
34
  * so the approval record captures exactly what the reviewer saw.
35
+ *
36
+ * Timeout policy lives here, whole. `ctx.awaitHumanInput()` only reports
37
+ * that the timer won; this module decides what that means. approve, deny and
38
+ * escalate resolve the gate to a declared outcome. fail logs an
39
+ * approval_resolved with `auto_resolved` set and no outcome, then fails the
40
+ * task with the error it has always raised, so every approval_requested in
41
+ * the event log is closed by an approval_resolved (stigmer/stigmer#1442).
42
+ * That emit is a new workflow command on an existing path, so it runs behind
43
+ * {@link HUMAN_INPUT_FAIL_TIMEOUT_RESOLVED_PATCH}: a history recorded before
44
+ * it replays the old order (no emit, then the throw).
35
45
  */
36
46
 
37
47
  import type {
@@ -41,6 +51,9 @@ import type {
41
51
  WorkflowState,
42
52
  TaskExecutionContext,
43
53
  HumanInputResult,
54
+ HumanInputResponse,
55
+ HumanInputTimeout,
56
+ HumanInputTimeoutPolicy,
44
57
  } from "../types.js";
45
58
  import { resolveConfigExpressions, resolveEmbeddedExpressions } from "../resolve.js";
46
59
  import { isStrictExpr } from "../expression-utils.js";
@@ -49,6 +62,13 @@ const SIGNAL_PREFIX = "human_input_";
49
62
  const DEFAULT_TIMEOUT_SECONDS = 0;
50
63
  const DEFAULT_ON_TIMEOUT = "fail" as const;
51
64
 
65
+ /**
66
+ * Temporal patch id for logging approval_resolved before a fail-policy
67
+ * timeout fails the task. Wire bytes: a rename makes every history that
68
+ * carries the marker replay down the old path.
69
+ */
70
+ export const HUMAN_INPUT_FAIL_TIMEOUT_RESOLVED_PATCH = "human-input-fail-timeout-resolved";
71
+
52
72
  /**
53
73
  * Executes a human_input task. Called from `runSingleTask` in do-executor
54
74
  * when the task kind is "human_input".
@@ -97,29 +117,22 @@ export async function executeHumanInputTask(
97
117
  ]);
98
118
  }
99
119
 
100
- const result: HumanInputResult = applyTimeoutOutcomeContract(
101
- await ctx.awaitHumanInput({
102
- signalName,
103
- timeoutSeconds,
104
- onTimeout,
105
- }),
106
- config.outcomes,
107
- );
120
+ const response = await ctx.awaitHumanInput({ signalName, timeoutSeconds });
121
+ const result = isTimeout(response)
122
+ ? resolveTimeout(onTimeout, config.outcomes)
123
+ : response;
108
124
 
109
- if (ctx.emitEvents) {
110
- await ctx.emitEvents([{
111
- type: "approval_resolved",
112
- taskName,
113
- occurredAt: new Date().toISOString(),
114
- outcome: result.outcome,
115
- resolvedBy: result.reviewer ?? "",
116
- resolvedByActor: result.reviewer_actor,
117
- comment: "",
118
- waitDurationMs: Date.now() - approvalRequestedAt,
119
- autoResolved: result.auto_resolved ?? false,
120
- }]);
125
+ if (result === undefined) {
126
+ if (ctx.isPatched?.(HUMAN_INPUT_FAIL_TIMEOUT_RESOLVED_PATCH) ?? true) {
127
+ await emitApprovalResolved(ctx, taskName, approvalRequestedAt, {
128
+ outcome: "", auto_resolved: true, reason: "timeout",
129
+ });
130
+ }
131
+ throw new Error(`human_input task timed out waiting for signal '${signalName}'`);
121
132
  }
122
133
 
134
+ await emitApprovalResolved(ctx, taskName, approvalRequestedAt, result);
135
+
123
136
  state.addData({ [taskName]: result });
124
137
 
125
138
  const selectedOutcome = config.outcomes?.find(o => o.name === result.outcome);
@@ -136,35 +149,72 @@ function validateConfig(config: HumanInputConfig, taskName: string): void {
136
149
  }
137
150
  }
138
151
 
152
+ function isTimeout(response: HumanInputResponse): response is HumanInputTimeout {
153
+ return "timedOut" in response;
154
+ }
155
+
139
156
  /**
140
- * Applies the proto contract for timeout auto-resolution with custom
141
- * outcomes (HumanInputTaskConfig.outcomes doc): auto-approve resolves to
142
- * the FIRST declared outcome and auto-deny to the LAST, so `then` routing
143
- * and downstream outcome switches see declared outcome names — never the
144
- * orchestrator's internal approve/deny words, which a reviewer of a
145
- * custom-outcome gate was never offered. Binary gates (no custom outcomes)
146
- * keep the plain approve/deny result.
157
+ * The decision a timeout policy makes, or `undefined` when the policy is
158
+ * fail and the gate ends without one.
159
+ *
160
+ * With custom outcomes the proto contract (HumanInputTaskConfig.outcomes doc)
161
+ * applies: auto-approve resolves to the FIRST declared outcome and auto-deny
162
+ * to the LAST, so `then` routing and downstream outcome switches see declared
163
+ * outcome names, never approve/deny words a reviewer of a custom-outcome gate
164
+ * was never offered. Binary gates (no custom outcomes) keep plain approve/deny.
147
165
  *
148
166
  * Escalate needs no remapping by construction (stigmer/stigmer#781): its
149
- * policy word IS the declared outcome's name — the loader (and the server
167
+ * policy word IS the declared outcome's name. The loader (and the server
150
168
  * validator) only accept the escalate policy when an outcome named
151
- * "escalate" with `then` exists, so the caller's ordinary name lookup
152
- * routes the escalation branch.
169
+ * "escalate" with `then` exists, so the caller's ordinary name lookup routes
170
+ * the escalation branch.
153
171
  */
154
- function applyTimeoutOutcomeContract(
155
- result: HumanInputResult,
172
+ function resolveTimeout(
173
+ policy: HumanInputTimeoutPolicy,
156
174
  outcomes: HumanInputConfig["outcomes"],
157
- ): HumanInputResult {
158
- if (!result.auto_resolved || result.reason !== "timeout" || !outcomes?.length) {
159
- return result;
160
- }
161
- if (result.outcome === "approve") {
162
- return { ...result, outcome: outcomes[0].name };
163
- }
164
- if (result.outcome === "deny") {
165
- return { ...result, outcome: outcomes[outcomes.length - 1].name };
175
+ ): HumanInputResult | undefined {
176
+ const decided = (outcome: string): HumanInputResult => ({
177
+ outcome, auto_resolved: true, reason: "timeout",
178
+ });
179
+ switch (policy) {
180
+ case "approve":
181
+ return decided(outcomes?.length ? outcomes[0].name : "approve");
182
+ case "deny":
183
+ return decided(outcomes?.length ? outcomes[outcomes.length - 1].name : "deny");
184
+ case "escalate":
185
+ return decided("escalate");
186
+ case "fail":
187
+ return undefined;
188
+ default: {
189
+ const unreachable: never = policy;
190
+ throw new Error(`human_input: unknown timeout policy '${String(unreachable)}'`);
191
+ }
166
192
  }
167
- return result;
193
+ }
194
+
195
+ /**
196
+ * Logs how the gate's approval ended. A timeout's decision carries no
197
+ * reviewer, no comment and `auto_resolved`; a fail timeout's carries no
198
+ * outcome either.
199
+ */
200
+ async function emitApprovalResolved(
201
+ ctx: TaskExecutionContext,
202
+ taskName: string,
203
+ approvalRequestedAt: number,
204
+ result: HumanInputResult,
205
+ ): Promise<void> {
206
+ if (!ctx.emitEvents) return;
207
+ await ctx.emitEvents([{
208
+ type: "approval_resolved",
209
+ taskName,
210
+ occurredAt: new Date().toISOString(),
211
+ outcome: result.outcome,
212
+ resolvedBy: result.reviewer ?? "",
213
+ resolvedByActor: result.reviewer_actor,
214
+ comment: result.comment ?? "",
215
+ waitDurationMs: Date.now() - approvalRequestedAt,
216
+ autoResolved: result.auto_resolved ?? false,
217
+ }]);
168
218
  }
169
219
 
170
220
  interface ResolvedReviewPayload {
@@ -561,10 +561,20 @@ export interface RunWorkflowExecutionConfig {
561
561
  }
562
562
 
563
563
  /**
564
- * Blocks workflow execution until a human provides input via signal.
565
- * Supports configurable timeout with policies (fail, approve, deny, escalate).
564
+ * Blocks workflow execution until a human provides input via signal, or
565
+ * until the timeout elapses. Reports which happened and nothing more: the
566
+ * timeout policy (fail, approve, deny, escalate) is the kernel's to apply
567
+ * (`tasks/human-input.ts`), so one module owns every way a gate can end.
566
568
  */
567
- export type AwaitHumanInputFn = (config: HumanInputExecutionConfig) => Promise<HumanInputResult>;
569
+ export type AwaitHumanInputFn = (config: HumanInputExecutionConfig) => Promise<HumanInputResponse>;
570
+
571
+ /** What a wait at a human_input gate ended with: the reviewer's decision, or the timeout. */
572
+ export type HumanInputResponse = HumanInputResult | HumanInputTimeout;
573
+
574
+ /** The gate's timeout elapsed before any decision arrived. */
575
+ export interface HumanInputTimeout {
576
+ readonly timedOut: true;
577
+ }
568
578
 
569
579
  /**
570
580
  * Internal timeout-policy vocabulary — the loader-normalized form of the
@@ -577,8 +587,8 @@ export type HumanInputTimeoutPolicy = "fail" | "approve" | "deny" | "escalate";
577
587
 
578
588
  export interface HumanInputExecutionConfig {
579
589
  readonly signalName: string;
590
+ /** Seconds to wait before reporting a {@link HumanInputTimeout}; 0 waits indefinitely. */
580
591
  readonly timeoutSeconds: number;
581
- readonly onTimeout: HumanInputTimeoutPolicy;
582
592
  }
583
593
 
584
594
  export interface HumanInputResult {
@@ -594,6 +604,8 @@ export interface HumanInputResult {
594
604
  readonly reviewer_actor?: HumanInputReviewerActor;
595
605
  readonly responded_at?: string;
596
606
  readonly form_data?: Record<string, unknown>;
607
+ /** Free-text comment the reviewer attached. Absent when none was written, and always on a timeout. */
608
+ readonly comment?: string;
597
609
  readonly auto_resolved?: boolean;
598
610
  readonly reason?: string;
599
611
  }
@@ -65,6 +65,13 @@ type AgentActivities = ReturnType<typeof createCallAgentActivities>;
65
65
  type StatusActivities = ReturnType<typeof createCallAgentStatusActivities>;
66
66
  type EventActivities = ReturnType<typeof createWorkflowEventActivities>;
67
67
 
68
+ /**
69
+ * Every activity an agent call schedules. The engine's own activity type
70
+ * includes it, so a worker (or a test mock) that registers the engine's
71
+ * activities is checked against this list by the compiler.
72
+ */
73
+ export type AgentCallActivities = AgentActivities & StatusActivities & EventActivities;
74
+
68
75
  // The 1h ceiling is a deliberate platform constant, not a user knob: the
69
76
  // old AgentCallTaskConfig declared a per-task `timeout` that nothing ever
70
77
  // read, and #358 deleted it rather than declaring what isn't honored. The
@@ -28,6 +28,7 @@ import type { createRunCommandActivities } from "../activities/run-command.js";
28
28
  import type { createWorkflowEventActivities } from "../activities/workflow-event-activities.js";
29
29
  import type { createPromoteTaskOutputActivities } from "../activities/promote-task-output.js";
30
30
  import { orchestrateAgentCall } from "./call-agent-orchestrator.js";
31
+ import type { AgentCallActivities } from "./call-agent-orchestrator.js";
31
32
  import { orchestrateListenTask } from "./listen-orchestrator.js";
32
33
  import { orchestrateRunWorkflow } from "./run-orchestrator.js";
33
34
  import { orchestrateHumanInput } from "./human-input-orchestrator.js";
@@ -65,6 +66,23 @@ type RunActivities = ReturnType<typeof createRunCommandActivities>;
65
66
  type EventActivities = ReturnType<typeof createWorkflowEventActivities>;
66
67
  type PromoteActivities = ReturnType<typeof createPromoteTaskOutputActivities>;
67
68
 
69
+ /**
70
+ * Every activity the engine can schedule, by name. A worker that runs the
71
+ * engine must register each one; the test mocks declare
72
+ * `satisfies Record<keyof EngineActivities, unknown>` so a new activity
73
+ * without a mock fails the typecheck instead of failing the smoke run at
74
+ * run time (stigmer#1300: four missing local activities made the golden
75
+ * suite report passes for months without running a golden).
76
+ */
77
+ export type EngineActivities = EvalActivities &
78
+ HttpActivities &
79
+ GrpcActivities &
80
+ FunctionActivities &
81
+ RunActivities &
82
+ EventActivities &
83
+ PromoteActivities &
84
+ AgentCallActivities;
85
+
68
86
  const evalProxy = proxyLocalActivities<EvalActivities>({
69
87
  startToCloseTimeout: "10s",
70
88
  });
@@ -31,7 +31,8 @@ import type { createHydrateWorkflowActivities } from "../activities/hydrate-work
31
31
  // Hydration Activity Proxy
32
32
  // ─────────────────────────────────────────────────────────────────────────────
33
33
 
34
- type HydrateActivities = ReturnType<typeof createHydrateWorkflowActivities>;
34
+ /** The activity this entry point schedules before it hands the model to the engine. */
35
+ export type HydrateActivities = ReturnType<typeof createHydrateWorkflowActivities>;
35
36
 
36
37
  const hydrateProxy = proxyActivities<HydrateActivities>({
37
38
  startToCloseTimeout: "2m",
@@ -2,18 +2,15 @@
2
2
  * Human input orchestrator — Temporal workflow-layer HITL signal handler.
3
3
  *
4
4
  * Registers a signal handler for the human_input task, then blocks until
5
- * either the signal arrives or the timeout fires. Timeout behavior is
6
- * determined by the `onTimeout` policy:
7
- * - "fail": throws an error
8
- * - "approve": returns auto-approved output
9
- * - "deny": returns auto-denied output
10
- * - "escalate": returns the "escalate" outcome — by the outcome-by-name
11
- * contract (stigmer/stigmer#781) the loader guarantees the gate declares
12
- * an outcome with that exact name and a `then` branch, so the executor's
13
- * ordinary outcome routing takes the escalation path.
5
+ * either the signal arrives or the timeout fires, and reports which one
6
+ * happened: the reviewer's payload, or a timeout. It applies no timeout
7
+ * policy. What a timeout means (fail the task, or resolve the gate to a
8
+ * declared outcome) is decided in the kernel (`workflow-engine/tasks/
9
+ * human-input.ts`), which also logs how the approval ended, so the two
10
+ * cannot drift apart across layers.
14
11
  *
15
12
  * Signal payload shape:
16
- * { outcome, form_data?, reviewer, reviewer_actor?, responded_at }
13
+ * { outcome, form_data?, comment?, reviewer, reviewer_actor?, responded_at }
17
14
  *
18
15
  * TEMPORAL SANDBOX: This file runs inside the deterministic workflow isolate.
19
16
  */
@@ -22,17 +19,20 @@ import { defineSignal, setHandler, condition } from "@temporalio/workflow";
22
19
 
23
20
  import type {
24
21
  HumanInputExecutionConfig,
22
+ HumanInputResponse,
25
23
  HumanInputResult,
26
- HumanInputTimeoutPolicy,
24
+ HumanInputTimeout,
27
25
  } from "../workflow-engine/types.js";
28
26
 
27
+ const TIMED_OUT: HumanInputTimeout = { timedOut: true };
28
+
29
29
  /**
30
30
  * Orchestrates a human_input task — blocks until signal or timeout.
31
31
  */
32
32
  export async function orchestrateHumanInput(
33
33
  config: HumanInputExecutionConfig,
34
- ): Promise<HumanInputResult> {
35
- const { signalName, timeoutSeconds, onTimeout } = config;
34
+ ): Promise<HumanInputResponse> {
35
+ const { signalName, timeoutSeconds } = config;
36
36
 
37
37
  let payload: HumanInputResult | undefined;
38
38
  let received = false;
@@ -44,52 +44,11 @@ export async function orchestrateHumanInput(
44
44
  });
45
45
 
46
46
  if (timeoutSeconds > 0) {
47
- const timeoutMs = timeoutSeconds * 1000;
48
- const completed = await condition(() => received, timeoutMs);
49
-
50
- if (!completed) {
51
- return handleTimeout(signalName, onTimeout);
52
- }
47
+ const completed = await condition(() => received, timeoutSeconds * 1000);
48
+ if (!completed) return TIMED_OUT;
53
49
  } else {
54
50
  await condition(() => received);
55
51
  }
56
52
 
57
53
  return payload!;
58
54
  }
59
-
60
- function handleTimeout(
61
- signalName: string,
62
- policy: HumanInputTimeoutPolicy,
63
- ): HumanInputResult {
64
- switch (policy) {
65
- case "approve":
66
- return {
67
- outcome: "approve",
68
- auto_resolved: true,
69
- reason: "timeout",
70
- };
71
-
72
- case "deny":
73
- return {
74
- outcome: "deny",
75
- auto_resolved: true,
76
- reason: "timeout",
77
- };
78
-
79
- case "escalate":
80
- // The outcome word IS the declared outcome's name (loader-enforced),
81
- // so no positional remapping happens downstream — the executor's name
82
- // lookup routes the escalation branch directly.
83
- return {
84
- outcome: "escalate",
85
- auto_resolved: true,
86
- reason: "timeout",
87
- };
88
-
89
- case "fail":
90
- default:
91
- throw new Error(
92
- `human_input task timed out waiting for signal '${signalName}'`,
93
- );
94
- }
95
- }
@@ -1,65 +0,0 @@
1
- /**
2
- * Skill relevance scoring for smart context filtering.
3
- *
4
- * Uses a BM25-inspired algorithm to score each skill's relevance
5
- * against the user message. When an agent has many skills configured,
6
- * low-relevance skills are excluded from the system prompt to improve
7
- * signal quality.
8
- *
9
- * The progressive disclosure model means only skill metadata
10
- * (~50-70 tokens per skill) lives in the prompt, so filtering
11
- * primarily reduces noise rather than saving tokens.
12
- *
13
- * BM25 (Best Matching 25) is a lightweight, well-understood ranking
14
- * function from information retrieval. It uses term frequency saturation
15
- * and document length normalisation — both important when matching a
16
- * short user message (query) against short skill metadata (documents of
17
- * 5-20 tokens each).
18
- *
19
- * No external dependencies required.
20
- */
21
- /** Relevance filtering activates only when the agent has at least this many skills. */
22
- export declare const SKILL_COUNT_THRESHOLD = 8;
23
- /**
24
- * Split text into lowercase tokens, dropping stop words and
25
- * single-character fragments.
26
- */
27
- export declare function tokenize(text: string): string[];
28
- export interface ScoredSkill {
29
- readonly index: number;
30
- readonly name: string;
31
- readonly score: number;
32
- }
33
- export interface SkillFilterResult {
34
- /** Indices of skills to include in the prompt (original order). */
35
- readonly includedIndices: number[];
36
- /** Indices of skills excluded from the prompt (original order). */
37
- readonly excludedIndices: number[];
38
- /** Names of excluded skills (sorted alphabetically). */
39
- readonly excludedNames: string[];
40
- }
41
- /**
42
- * Score each skill's relevance to the user message using BM25.
43
- *
44
- * Each skill's name and description are concatenated into a document
45
- * and scored against the query terms extracted from the user message.
46
- *
47
- * Returns ScoredSkill list ordered by descending score (ties broken alphabetically).
48
- */
49
- export declare function scoreSkills(userMessage: string, skillNames: readonly string[], skillDescriptions: readonly string[], options?: {
50
- k1?: number;
51
- b?: number;
52
- }): ScoredSkill[];
53
- /**
54
- * Partition skills into included / excluded based on relevance.
55
- *
56
- * Below the threshold, every skill is included unconditionally.
57
- * Above the threshold, skills whose BM25 score is zero (no query
58
- * term overlap at all) are moved to the excluded set.
59
- *
60
- * A safety floor guarantees that at least half the skills are
61
- * always included, regardless of scores.
62
- */
63
- export declare function filterSkills(userMessage: string, skillNames: readonly string[], skillDescriptions: readonly string[], options?: {
64
- threshold?: number;
65
- }): SkillFilterResult;
@@ -1,175 +0,0 @@
1
- /**
2
- * Skill relevance scoring for smart context filtering.
3
- *
4
- * Uses a BM25-inspired algorithm to score each skill's relevance
5
- * against the user message. When an agent has many skills configured,
6
- * low-relevance skills are excluded from the system prompt to improve
7
- * signal quality.
8
- *
9
- * The progressive disclosure model means only skill metadata
10
- * (~50-70 tokens per skill) lives in the prompt, so filtering
11
- * primarily reduces noise rather than saving tokens.
12
- *
13
- * BM25 (Best Matching 25) is a lightweight, well-understood ranking
14
- * function from information retrieval. It uses term frequency saturation
15
- * and document length normalisation — both important when matching a
16
- * short user message (query) against short skill metadata (documents of
17
- * 5-20 tokens each).
18
- *
19
- * No external dependencies required.
20
- */
21
- /** Relevance filtering activates only when the agent has at least this many skills. */
22
- export const SKILL_COUNT_THRESHOLD = 8;
23
- /** Term-frequency saturation. Higher values weight repeated terms more. */
24
- const BM25_K1 = 1.5;
25
- /** Length normalisation. 0 = none, 1 = full relative to average doc length. */
26
- const BM25_B = 0.75;
27
- const STOP_WORDS = new Set([
28
- "a", "an", "the", "is", "are", "was", "were", "be", "been",
29
- "being", "have", "has", "had", "do", "does", "did", "will",
30
- "would", "could", "should", "may", "might", "shall", "can",
31
- "to", "of", "in", "for", "on", "with", "at", "by", "from",
32
- "as", "into", "through", "during", "before", "after", "above",
33
- "below", "between", "and", "but", "or", "nor", "not", "so",
34
- "yet", "both", "either", "neither", "each", "every", "all",
35
- "any", "few", "more", "most", "some", "such", "no", "only",
36
- "own", "same", "than", "too", "very", "just", "because",
37
- "about", "up", "out", "if", "then", "that", "this", "these",
38
- "those", "it", "its", "i", "me", "my", "we", "our", "you",
39
- "your", "he", "she", "they", "them", "their", "what", "which",
40
- "who", "whom", "how", "when", "where", "why",
41
- ]);
42
- const TOKEN_PATTERN = /[a-z0-9]+/g;
43
- // ─── Tokenisation ────────────────────────────────────────────────────────
44
- /**
45
- * Split text into lowercase tokens, dropping stop words and
46
- * single-character fragments.
47
- */
48
- export function tokenize(text) {
49
- const matches = text.toLowerCase().match(TOKEN_PATTERN);
50
- if (!matches)
51
- return [];
52
- return matches.filter(tok => !STOP_WORDS.has(tok) && tok.length > 1);
53
- }
54
- // ─── BM25 scoring ────────────────────────────────────────────────────────
55
- /**
56
- * Score each skill's relevance to the user message using BM25.
57
- *
58
- * Each skill's name and description are concatenated into a document
59
- * and scored against the query terms extracted from the user message.
60
- *
61
- * Returns ScoredSkill list ordered by descending score (ties broken alphabetically).
62
- */
63
- export function scoreSkills(userMessage, skillNames, skillDescriptions, options) {
64
- const k1 = options?.k1 ?? BM25_K1;
65
- const b = options?.b ?? BM25_B;
66
- const queryTerms = tokenize(userMessage);
67
- const n = skillNames.length;
68
- if (n === 0)
69
- return [];
70
- if (queryTerms.length === 0) {
71
- return skillNames.map((name, index) => ({ index, name, score: 0.0 }));
72
- }
73
- // Build per-skill term-frequency maps.
74
- const docs = [];
75
- const docLengths = [];
76
- for (let i = 0; i < n; i++) {
77
- const tokens = tokenize(`${skillNames[i]} ${skillDescriptions[i]}`);
78
- const tf = new Map();
79
- for (const tok of tokens) {
80
- tf.set(tok, (tf.get(tok) ?? 0) + 1);
81
- }
82
- docs.push(tf);
83
- docLengths.push(tokens.length);
84
- }
85
- const avgdl = docLengths.reduce((sum, l) => sum + l, 0) / n;
86
- // IDF per unique query term.
87
- const uniqueQueryTerms = new Set(queryTerms);
88
- const idf = new Map();
89
- for (const term of uniqueQueryTerms) {
90
- let df = 0;
91
- for (const doc of docs) {
92
- if (doc.has(term))
93
- df++;
94
- }
95
- idf.set(term, Math.max(0.0, Math.log((n - df + 0.5) / (df + 0.5) + 1.0)));
96
- }
97
- // Score each document.
98
- const results = [];
99
- for (let i = 0; i < n; i++) {
100
- const docTf = docs[i];
101
- const dl = docLengths[i];
102
- let score = 0.0;
103
- for (const term of queryTerms) {
104
- const tfVal = docTf.get(term);
105
- if (tfVal === undefined)
106
- continue;
107
- const numerator = tfVal * (k1 + 1);
108
- const denominator = tfVal + k1 * (1 - b + b * dl / avgdl);
109
- score += (idf.get(term) ?? 0.0) * numerator / denominator;
110
- }
111
- results.push({ index: i, name: skillNames[i], score });
112
- }
113
- results.sort((a, b_) => {
114
- if (b_.score !== a.score)
115
- return b_.score - a.score;
116
- return a.name.localeCompare(b_.name);
117
- });
118
- return results;
119
- }
120
- // ─── Filtering ───────────────────────────────────────────────────────────
121
- /**
122
- * Partition skills into included / excluded based on relevance.
123
- *
124
- * Below the threshold, every skill is included unconditionally.
125
- * Above the threshold, skills whose BM25 score is zero (no query
126
- * term overlap at all) are moved to the excluded set.
127
- *
128
- * A safety floor guarantees that at least half the skills are
129
- * always included, regardless of scores.
130
- */
131
- export function filterSkills(userMessage, skillNames, skillDescriptions, options) {
132
- const threshold = options?.threshold ?? SKILL_COUNT_THRESHOLD;
133
- const n = skillNames.length;
134
- const allIndices = Array.from({ length: n }, (_, i) => i);
135
- if (n < threshold) {
136
- return {
137
- includedIndices: allIndices,
138
- excludedIndices: [],
139
- excludedNames: [],
140
- };
141
- }
142
- const scored = scoreSkills(userMessage, skillNames, skillDescriptions);
143
- const included = [];
144
- const excluded = [];
145
- const excludedNames = [];
146
- for (const s of scored) {
147
- if (s.score > 0.0) {
148
- included.push(s.index);
149
- }
150
- else {
151
- excluded.push(s.index);
152
- excludedNames.push(s.name);
153
- }
154
- }
155
- // Safety: always keep at least half the skills.
156
- const minIncluded = Math.max(1, Math.floor(n / 2));
157
- if (included.length < minIncluded) {
158
- const deficit = minIncluded - included.length;
159
- const reInclude = excluded.splice(0, deficit);
160
- included.push(...reInclude);
161
- for (const idx of reInclude) {
162
- const nameIdx = excludedNames.indexOf(skillNames[idx]);
163
- if (nameIdx !== -1)
164
- excludedNames.splice(nameIdx, 1);
165
- }
166
- }
167
- included.sort((a, b) => a - b);
168
- excluded.sort((a, b) => a - b);
169
- return {
170
- includedIndices: included,
171
- excludedIndices: excluded,
172
- excludedNames: excludedNames.sort(),
173
- };
174
- }
175
- //# sourceMappingURL=skill-relevance.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"skill-relevance.js","sourceRoot":"","sources":["../../src/shared/skill-relevance.ts"],"names":[],"mappings":"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"}