@posthog/agent 1.16.6 → 1.18.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 (227) hide show
  1. package/README.md +6 -2
  2. package/dist/claude-cli/cli.js +3617 -0
  3. package/dist/claude-cli/package.json +3 -0
  4. package/dist/index.d.ts +1 -3
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/src/agent.d.ts +0 -3
  7. package/dist/src/agent.d.ts.map +1 -1
  8. package/dist/src/agent.js +6 -27
  9. package/dist/src/agent.js.map +1 -1
  10. package/dist/src/agents/research.d.ts +1 -1
  11. package/dist/src/agents/research.d.ts.map +1 -1
  12. package/dist/src/agents/research.js +84 -53
  13. package/dist/src/agents/research.js.map +1 -1
  14. package/dist/src/file-manager.d.ts +3 -21
  15. package/dist/src/file-manager.d.ts.map +1 -1
  16. package/dist/src/file-manager.js +15 -47
  17. package/dist/src/file-manager.js.map +1 -1
  18. package/dist/src/git-manager.d.ts.map +1 -1
  19. package/dist/src/git-manager.js +8 -1
  20. package/dist/src/git-manager.js.map +1 -1
  21. package/dist/src/posthog-api.d.ts +6 -1
  22. package/dist/src/posthog-api.d.ts.map +1 -1
  23. package/dist/src/posthog-api.js +28 -0
  24. package/dist/src/posthog-api.js.map +1 -1
  25. package/dist/src/task-progress-reporter.d.ts.map +1 -1
  26. package/dist/src/task-progress-reporter.js +0 -1
  27. package/dist/src/task-progress-reporter.js.map +1 -1
  28. package/dist/src/types.d.ts +21 -2
  29. package/dist/src/types.d.ts.map +1 -1
  30. package/dist/src/types.js.map +1 -1
  31. package/dist/src/workflow/steps/plan.d.ts.map +1 -1
  32. package/dist/src/workflow/steps/plan.js +26 -18
  33. package/dist/src/workflow/steps/plan.js.map +1 -1
  34. package/dist/src/workflow/steps/research.d.ts.map +1 -1
  35. package/dist/src/workflow/steps/research.js +100 -66
  36. package/dist/src/workflow/steps/research.js.map +1 -1
  37. package/dist/src/workflow/types.d.ts +0 -2
  38. package/dist/src/workflow/types.d.ts.map +1 -1
  39. package/dist/templates/plan-template.md +1 -5
  40. package/package.json +2 -6
  41. package/src/agent.ts +7 -31
  42. package/src/agents/research.ts +84 -53
  43. package/src/file-manager.ts +18 -73
  44. package/src/git-manager.ts +7 -1
  45. package/src/posthog-api.ts +33 -1
  46. package/src/task-progress-reporter.ts +0 -1
  47. package/src/templates/plan-template.md +1 -5
  48. package/src/types.ts +25 -2
  49. package/src/workflow/steps/plan.ts +28 -21
  50. package/src/workflow/steps/research.ts +109 -74
  51. package/src/workflow/types.ts +0 -2
  52. package/dist/_virtual/_commonjsHelpers.js +0 -6
  53. package/dist/_virtual/_commonjsHelpers.js.map +0 -1
  54. package/dist/_virtual/index.js +0 -4
  55. package/dist/_virtual/index.js.map +0 -1
  56. package/dist/node_modules/@ai-sdk/anthropic/dist/index.js +0 -1154
  57. package/dist/node_modules/@ai-sdk/anthropic/dist/index.js.map +0 -1
  58. package/dist/node_modules/@ai-sdk/provider/dist/index.js +0 -296
  59. package/dist/node_modules/@ai-sdk/provider/dist/index.js.map +0 -1
  60. package/dist/node_modules/@ai-sdk/provider-utils/dist/index.js +0 -576
  61. package/dist/node_modules/@ai-sdk/provider-utils/dist/index.js.map +0 -1
  62. package/dist/node_modules/@ai-sdk/ui-utils/dist/index.js +0 -741
  63. package/dist/node_modules/@ai-sdk/ui-utils/dist/index.js.map +0 -1
  64. package/dist/node_modules/@opentelemetry/api/build/esm/api/context.js +0 -112
  65. package/dist/node_modules/@opentelemetry/api/build/esm/api/context.js.map +0 -1
  66. package/dist/node_modules/@opentelemetry/api/build/esm/api/diag.js +0 -123
  67. package/dist/node_modules/@opentelemetry/api/build/esm/api/diag.js.map +0 -1
  68. package/dist/node_modules/@opentelemetry/api/build/esm/api/metrics.js +0 -62
  69. package/dist/node_modules/@opentelemetry/api/build/esm/api/metrics.js.map +0 -1
  70. package/dist/node_modules/@opentelemetry/api/build/esm/api/propagation.js +0 -91
  71. package/dist/node_modules/@opentelemetry/api/build/esm/api/propagation.js.map +0 -1
  72. package/dist/node_modules/@opentelemetry/api/build/esm/api/trace.js +0 -79
  73. package/dist/node_modules/@opentelemetry/api/build/esm/api/trace.js.map +0 -1
  74. package/dist/node_modules/@opentelemetry/api/build/esm/baggage/context-helpers.js +0 -59
  75. package/dist/node_modules/@opentelemetry/api/build/esm/baggage/context-helpers.js.map +0 -1
  76. package/dist/node_modules/@opentelemetry/api/build/esm/baggage/internal/baggage-impl.js +0 -99
  77. package/dist/node_modules/@opentelemetry/api/build/esm/baggage/internal/baggage-impl.js.map +0 -1
  78. package/dist/node_modules/@opentelemetry/api/build/esm/baggage/utils.js +0 -31
  79. package/dist/node_modules/@opentelemetry/api/build/esm/baggage/utils.js.map +0 -1
  80. package/dist/node_modules/@opentelemetry/api/build/esm/context/NoopContextManager.js +0 -69
  81. package/dist/node_modules/@opentelemetry/api/build/esm/context/NoopContextManager.js.map +0 -1
  82. package/dist/node_modules/@opentelemetry/api/build/esm/context/context.js +0 -54
  83. package/dist/node_modules/@opentelemetry/api/build/esm/context/context.js.map +0 -1
  84. package/dist/node_modules/@opentelemetry/api/build/esm/context-api.js +0 -22
  85. package/dist/node_modules/@opentelemetry/api/build/esm/context-api.js.map +0 -1
  86. package/dist/node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js +0 -104
  87. package/dist/node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js.map +0 -1
  88. package/dist/node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js +0 -44
  89. package/dist/node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js.map +0 -1
  90. package/dist/node_modules/@opentelemetry/api/build/esm/diag/types.js +0 -43
  91. package/dist/node_modules/@opentelemetry/api/build/esm/diag/types.js.map +0 -1
  92. package/dist/node_modules/@opentelemetry/api/build/esm/diag-api.js +0 -27
  93. package/dist/node_modules/@opentelemetry/api/build/esm/diag-api.js.map +0 -1
  94. package/dist/node_modules/@opentelemetry/api/build/esm/internal/global-utils.js +0 -62
  95. package/dist/node_modules/@opentelemetry/api/build/esm/internal/global-utils.js.map +0 -1
  96. package/dist/node_modules/@opentelemetry/api/build/esm/internal/semver.js +0 -121
  97. package/dist/node_modules/@opentelemetry/api/build/esm/internal/semver.js.map +0 -1
  98. package/dist/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeter.js +0 -167
  99. package/dist/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeter.js.map +0 -1
  100. package/dist/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeterProvider.js +0 -33
  101. package/dist/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeterProvider.js.map +0 -1
  102. package/dist/node_modules/@opentelemetry/api/build/esm/metrics-api.js +0 -22
  103. package/dist/node_modules/@opentelemetry/api/build/esm/metrics-api.js.map +0 -1
  104. package/dist/node_modules/@opentelemetry/api/build/esm/platform/node/globalThis.js +0 -21
  105. package/dist/node_modules/@opentelemetry/api/build/esm/platform/node/globalThis.js.map +0 -1
  106. package/dist/node_modules/@opentelemetry/api/build/esm/propagation/NoopTextMapPropagator.js +0 -35
  107. package/dist/node_modules/@opentelemetry/api/build/esm/propagation/NoopTextMapPropagator.js.map +0 -1
  108. package/dist/node_modules/@opentelemetry/api/build/esm/propagation/TextMapPropagator.js +0 -40
  109. package/dist/node_modules/@opentelemetry/api/build/esm/propagation/TextMapPropagator.js.map +0 -1
  110. package/dist/node_modules/@opentelemetry/api/build/esm/propagation-api.js +0 -22
  111. package/dist/node_modules/@opentelemetry/api/build/esm/propagation-api.js.map +0 -1
  112. package/dist/node_modules/@opentelemetry/api/build/esm/trace/NonRecordingSpan.js +0 -70
  113. package/dist/node_modules/@opentelemetry/api/build/esm/trace/NonRecordingSpan.js.map +0 -1
  114. package/dist/node_modules/@opentelemetry/api/build/esm/trace/NoopTracer.js +0 -78
  115. package/dist/node_modules/@opentelemetry/api/build/esm/trace/NoopTracer.js.map +0 -1
  116. package/dist/node_modules/@opentelemetry/api/build/esm/trace/NoopTracerProvider.js +0 -34
  117. package/dist/node_modules/@opentelemetry/api/build/esm/trace/NoopTracerProvider.js.map +0 -1
  118. package/dist/node_modules/@opentelemetry/api/build/esm/trace/ProxyTracer.js +0 -55
  119. package/dist/node_modules/@opentelemetry/api/build/esm/trace/ProxyTracer.js.map +0 -1
  120. package/dist/node_modules/@opentelemetry/api/build/esm/trace/ProxyTracerProvider.js +0 -56
  121. package/dist/node_modules/@opentelemetry/api/build/esm/trace/ProxyTracerProvider.js.map +0 -1
  122. package/dist/node_modules/@opentelemetry/api/build/esm/trace/context-utils.js +0 -76
  123. package/dist/node_modules/@opentelemetry/api/build/esm/trace/context-utils.js.map +0 -1
  124. package/dist/node_modules/@opentelemetry/api/build/esm/trace/invalid-span-constants.js +0 -27
  125. package/dist/node_modules/@opentelemetry/api/build/esm/trace/invalid-span-constants.js.map +0 -1
  126. package/dist/node_modules/@opentelemetry/api/build/esm/trace/spancontext-utils.js +0 -45
  127. package/dist/node_modules/@opentelemetry/api/build/esm/trace/spancontext-utils.js.map +0 -1
  128. package/dist/node_modules/@opentelemetry/api/build/esm/trace/status.js +0 -22
  129. package/dist/node_modules/@opentelemetry/api/build/esm/trace/status.js.map +0 -1
  130. package/dist/node_modules/@opentelemetry/api/build/esm/trace/trace_flags.js +0 -25
  131. package/dist/node_modules/@opentelemetry/api/build/esm/trace/trace_flags.js.map +0 -1
  132. package/dist/node_modules/@opentelemetry/api/build/esm/trace-api.js +0 -24
  133. package/dist/node_modules/@opentelemetry/api/build/esm/trace-api.js.map +0 -1
  134. package/dist/node_modules/@opentelemetry/api/build/esm/version.js +0 -20
  135. package/dist/node_modules/@opentelemetry/api/build/esm/version.js.map +0 -1
  136. package/dist/node_modules/ai/dist/index.js +0 -2870
  137. package/dist/node_modules/ai/dist/index.js.map +0 -1
  138. package/dist/node_modules/nanoid/non-secure/index.js +0 -13
  139. package/dist/node_modules/nanoid/non-secure/index.js.map +0 -1
  140. package/dist/node_modules/secure-json-parse/index.js +0 -133
  141. package/dist/node_modules/secure-json-parse/index.js.map +0 -1
  142. package/dist/node_modules/zod-to-json-schema/dist/esm/Options.js +0 -37
  143. package/dist/node_modules/zod-to-json-schema/dist/esm/Options.js.map +0 -1
  144. package/dist/node_modules/zod-to-json-schema/dist/esm/Refs.js +0 -26
  145. package/dist/node_modules/zod-to-json-schema/dist/esm/Refs.js.map +0 -1
  146. package/dist/node_modules/zod-to-json-schema/dist/esm/errorMessages.js +0 -17
  147. package/dist/node_modules/zod-to-json-schema/dist/esm/errorMessages.js.map +0 -1
  148. package/dist/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js +0 -11
  149. package/dist/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js.map +0 -1
  150. package/dist/node_modules/zod-to-json-schema/dist/esm/index.js +0 -8
  151. package/dist/node_modules/zod-to-json-schema/dist/esm/index.js.map +0 -1
  152. package/dist/node_modules/zod-to-json-schema/dist/esm/parseDef.js +0 -66
  153. package/dist/node_modules/zod-to-json-schema/dist/esm/parseDef.js.map +0 -1
  154. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/any.js +0 -21
  155. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/any.js.map +0 -1
  156. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/array.js +0 -30
  157. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/array.js.map +0 -1
  158. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js +0 -53
  159. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js.map +0 -1
  160. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js +0 -8
  161. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js.map +0 -1
  162. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js +0 -8
  163. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js.map +0 -1
  164. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js +0 -8
  165. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js.map +0 -1
  166. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/date.js +0 -50
  167. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/date.js.map +0 -1
  168. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/default.js +0 -11
  169. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/default.js.map +0 -1
  170. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js +0 -11
  171. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js.map +0 -1
  172. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js +0 -9
  173. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js.map +0 -1
  174. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js +0 -56
  175. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js.map +0 -1
  176. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js +0 -24
  177. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js.map +0 -1
  178. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/map.js +0 -30
  179. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/map.js.map +0 -1
  180. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js +0 -19
  181. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js.map +0 -1
  182. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/never.js +0 -15
  183. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/never.js.map +0 -1
  184. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/null.js +0 -13
  185. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/null.js.map +0 -1
  186. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js +0 -37
  187. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js.map +0 -1
  188. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/number.js +0 -56
  189. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/number.js.map +0 -1
  190. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/object.js +0 -76
  191. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/object.js.map +0 -1
  192. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js +0 -25
  193. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js.map +0 -1
  194. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js +0 -24
  195. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js.map +0 -1
  196. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js +0 -8
  197. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js.map +0 -1
  198. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js +0 -8
  199. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js.map +0 -1
  200. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/record.js +0 -65
  201. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/record.js.map +0 -1
  202. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/set.js +0 -24
  203. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/set.js.map +0 -1
  204. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/string.js +0 -350
  205. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/string.js.map +0 -1
  206. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js +0 -36
  207. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js.map +0 -1
  208. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js +0 -10
  209. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js.map +0 -1
  210. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/union.js +0 -84
  211. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/union.js.map +0 -1
  212. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js +0 -8
  213. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js.map +0 -1
  214. package/dist/node_modules/zod-to-json-schema/dist/esm/selectParser.js +0 -110
  215. package/dist/node_modules/zod-to-json-schema/dist/esm/selectParser.js.map +0 -1
  216. package/dist/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js +0 -90
  217. package/dist/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js.map +0 -1
  218. package/dist/src/structured-extraction.d.ts +0 -28
  219. package/dist/src/structured-extraction.d.ts.map +0 -1
  220. package/dist/src/structured-extraction.js +0 -77
  221. package/dist/src/structured-extraction.js.map +0 -1
  222. package/dist/src/utils/ai-sdk.d.ts +0 -14
  223. package/dist/src/utils/ai-sdk.d.ts.map +0 -1
  224. package/dist/src/utils/ai-sdk.js +0 -38
  225. package/dist/src/utils/ai-sdk.js.map +0 -1
  226. package/src/structured-extraction.ts +0 -117
  227. package/src/utils/ai-sdk.ts +0 -47
@@ -1,7 +1,7 @@
1
1
  import { query } from '@anthropic-ai/claude-agent-sdk';
2
2
  import { RESEARCH_SYSTEM_PROMPT } from '../../agents/research.js';
3
- import type { ExtractedQuestionWithAnswer } from '../../structured-extraction.js';
4
3
  import type { WorkflowStepRunner } from '../types.js';
4
+ import type { ResearchEvaluation } from '../../types.js';
5
5
  import { finalizeStepGitActions } from '../utils.js';
6
6
 
7
7
  export const researchStep: WorkflowStepRunner = async ({ step, context }) => {
@@ -16,7 +16,6 @@ export const researchStep: WorkflowStepRunner = async ({ step, context }) => {
16
16
  promptBuilder,
17
17
  adapter,
18
18
  mcpServers,
19
- extractor,
20
19
  emitEvent,
21
20
  } = context;
22
21
 
@@ -24,7 +23,29 @@ export const researchStep: WorkflowStepRunner = async ({ step, context }) => {
24
23
 
25
24
  const existingResearch = await fileManager.readResearch(task.id);
26
25
  if (existingResearch) {
27
- stepLogger.info('Research already exists, skipping step', { taskId: task.id });
26
+ stepLogger.info('Research already exists', { taskId: task.id, hasQuestions: !!existingResearch.questions, answered: existingResearch.answered });
27
+
28
+ // If there are unanswered questions, re-emit them so UI can prompt user
29
+ if (existingResearch.questions && !existingResearch.answered) {
30
+ stepLogger.info('Re-emitting unanswered research questions', {
31
+ taskId: task.id,
32
+ questionCount: existingResearch.questions.length
33
+ });
34
+
35
+ emitEvent({
36
+ type: 'artifact',
37
+ ts: Date.now(),
38
+ kind: 'research_questions',
39
+ content: existingResearch.questions,
40
+ });
41
+
42
+ // In local mode, halt to allow user to answer
43
+ if (!isCloudMode) {
44
+ emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));
45
+ return { status: 'skipped', halt: true };
46
+ }
47
+ }
48
+
28
49
  return { status: 'skipped' };
29
50
  }
30
51
 
@@ -59,7 +80,7 @@ export const researchStep: WorkflowStepRunner = async ({ step, context }) => {
59
80
  options: { ...baseOptions, ...(options.queryOverrides || {}) },
60
81
  });
61
82
 
62
- let researchContent = '';
83
+ let jsonContent = '';
63
84
  for await (const message of response) {
64
85
  emitEvent(adapter.createRawSDKEvent(message));
65
86
  const transformed = adapter.transform(message);
@@ -69,100 +90,114 @@ export const researchStep: WorkflowStepRunner = async ({ step, context }) => {
69
90
  if (message.type === 'assistant' && message.message?.content) {
70
91
  for (const c of message.message.content) {
71
92
  if (c.type === 'text' && c.text) {
72
- researchContent += `${c.text}\n`;
93
+ jsonContent += c.text;
73
94
  }
74
95
  }
75
96
  }
76
97
  }
77
98
 
78
- if (researchContent.trim()) {
79
- await fileManager.writeResearch(task.id, researchContent.trim());
80
- stepLogger.info('Research completed', { taskId: task.id });
99
+ if (!jsonContent.trim()) {
100
+ stepLogger.error('No JSON output from research agent', { taskId: task.id });
101
+ emitEvent({
102
+ type: 'error',
103
+ ts: Date.now(),
104
+ message: 'Research agent returned no output',
105
+ });
106
+ return { status: 'completed', halt: true };
107
+ }
108
+
109
+ // Parse JSON response
110
+ let evaluation: ResearchEvaluation;
111
+ try {
112
+ // Extract JSON from potential markdown code blocks or other wrapping
113
+ const jsonMatch = jsonContent.match(/\{[\s\S]*\}/);
114
+ if (!jsonMatch) {
115
+ throw new Error('No JSON object found in response');
116
+ }
117
+ evaluation = JSON.parse(jsonMatch[0]);
118
+ stepLogger.info('Parsed research evaluation', {
119
+ taskId: task.id,
120
+ score: evaluation.actionabilityScore,
121
+ hasQuestions: !!evaluation.questions,
122
+ });
123
+ } catch (error) {
124
+ stepLogger.error('Failed to parse research JSON', {
125
+ taskId: task.id,
126
+ error: error instanceof Error ? error.message : String(error),
127
+ content: jsonContent.substring(0, 500),
128
+ });
129
+ emitEvent({
130
+ type: 'error',
131
+ ts: Date.now(),
132
+ message: `Failed to parse research JSON: ${
133
+ error instanceof Error ? error.message : String(error)
134
+ }`,
135
+ });
136
+ return { status: 'completed', halt: true };
137
+ }
138
+
139
+ // Add answered/answers fields to evaluation
140
+ if (evaluation.questions && evaluation.questions.length > 0) {
141
+ evaluation.answered = false;
142
+ evaluation.answers = undefined;
81
143
  }
82
144
 
145
+ // Always write research.json
146
+ await fileManager.writeResearch(task.id, evaluation);
147
+ stepLogger.info('Research evaluation written', {
148
+ taskId: task.id,
149
+ score: evaluation.actionabilityScore,
150
+ hasQuestions: !!evaluation.questions,
151
+ });
152
+
153
+ emitEvent({
154
+ type: 'artifact',
155
+ ts: Date.now(),
156
+ kind: 'research_evaluation',
157
+ content: evaluation,
158
+ });
159
+
83
160
  await gitManager.addAllPostHogFiles();
84
161
  await finalizeStepGitActions(context, step, {
85
162
  commitMessage: `Research phase for ${task.title}`,
86
163
  });
87
164
 
88
- if (extractor && researchContent.trim()) {
89
- try {
90
- stepLogger.info('Extracting questions from research.md', { taskId: task.id });
91
- const parsedQuestions = await extractor.extractQuestions(researchContent);
92
-
93
- await fileManager.writeQuestions(task.id, {
94
- questions: parsedQuestions,
95
- answered: false,
96
- answers: null,
97
- });
98
-
99
- emitEvent({
100
- type: 'artifact',
101
- ts: Date.now(),
102
- kind: 'research_questions',
103
- content: parsedQuestions,
104
- });
105
-
106
- stepLogger.info('Questions extracted successfully', {
107
- taskId: task.id,
108
- count: parsedQuestions.length,
109
- });
110
- } catch (error) {
111
- stepLogger.error('Failed to extract questions', {
112
- taskId: task.id,
113
- error: error instanceof Error ? error.message : String(error),
114
- });
115
- emitEvent({
116
- type: 'error',
117
- ts: Date.now(),
118
- message: `Failed to extract questions: ${
119
- error instanceof Error ? error.message : String(error)
120
- }`,
121
- });
122
- }
123
- } else if (!extractor) {
124
- stepLogger.warn(
125
- 'Question extractor not available, skipping question extraction. Ensure LLM gateway is configured.'
126
- );
165
+ // Log whether questions need answering
166
+ if (evaluation.actionabilityScore < 0.7 && evaluation.questions && evaluation.questions.length > 0) {
167
+ stepLogger.info('Actionability score below threshold, questions needed', {
168
+ taskId: task.id,
169
+ score: evaluation.actionabilityScore,
170
+ questionCount: evaluation.questions.length,
171
+ });
172
+
127
173
  emitEvent({
128
- type: 'status',
174
+ type: 'artifact',
129
175
  ts: Date.now(),
130
- phase: 'extraction_skipped',
131
- message: 'Question extraction skipped - extractor not configured',
176
+ kind: 'research_questions',
177
+ content: evaluation.questions,
178
+ });
179
+ } else {
180
+ stepLogger.info('Actionability score acceptable, proceeding to planning', {
181
+ taskId: task.id,
182
+ score: evaluation.actionabilityScore,
132
183
  });
133
184
  }
134
185
 
186
+ // In local mode, always halt after research for user review
135
187
  if (!isCloudMode) {
136
188
  emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));
137
189
  return { status: 'completed', halt: true };
138
190
  }
139
191
 
140
- const questionsData = await fileManager.readQuestions(task.id);
141
- if (questionsData && !questionsData.answered && extractor && researchContent.trim()) {
142
- const researchQuestions = await extractor.extractQuestionsWithAnswers(researchContent);
143
- const answers = (researchQuestions as ExtractedQuestionWithAnswer[]).map((qa) => ({
144
- questionId: qa.id,
145
- selectedOption: qa.recommendedAnswer,
146
- customInput: qa.justification,
147
- }));
148
-
149
- await fileManager.writeQuestions(task.id, {
150
- questions: researchQuestions.map((qa) => ({
151
- id: qa.id,
152
- question: qa.question,
153
- options: qa.options,
154
- })),
155
- answered: true,
156
- answers,
157
- });
158
-
159
- await gitManager.addAllPostHogFiles();
160
- await finalizeStepGitActions(context, step, {
161
- commitMessage: `Answer research questions for ${task.title}`,
162
- });
163
- stepLogger.info('Auto-answered research questions', { taskId: task.id });
192
+ // In cloud mode, check if questions need answering
193
+ const researchData = await fileManager.readResearch(task.id);
194
+ if (researchData?.questions && !researchData.answered) {
195
+ // Questions need answering - halt for user input in cloud mode too
196
+ emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));
197
+ return { status: 'completed', halt: true };
164
198
  }
165
199
 
200
+ // No questions or questions already answered - proceed to planning
166
201
  emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research' }));
167
202
  return { status: 'completed' };
168
203
  };
@@ -6,7 +6,6 @@ import type { PromptBuilder } from '../prompt-builder.js';
6
6
  import type { TaskProgressReporter } from '../task-progress-reporter.js';
7
7
  import type { ProviderAdapter } from '../adapters/types.js';
8
8
  import type { PostHogAPIClient } from '../posthog-api.js';
9
- import type { StructuredExtractor } from '../structured-extraction.js';
10
9
 
11
10
  export interface WorkflowRuntime {
12
11
  task: Task;
@@ -22,7 +21,6 @@ export interface WorkflowRuntime {
22
21
  adapter: ProviderAdapter;
23
22
  mcpServers?: Record<string, any>;
24
23
  posthogAPI?: PostHogAPIClient;
25
- extractor?: StructuredExtractor;
26
24
  emitEvent: (event: any) => void;
27
25
  stepResults: Record<string, any>;
28
26
  }
@@ -1,6 +0,0 @@
1
- function getDefaultExportFromCjs (x) {
2
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
3
- }
4
-
5
- export { getDefaultExportFromCjs };
6
- //# sourceMappingURL=_commonjsHelpers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_commonjsHelpers.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
@@ -1,4 +0,0 @@
1
- var secureJsonParse = {exports: {}};
2
-
3
- export { secureJsonParse as __module };
4
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}