@posthog/agent 1.16.6 → 1.17.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.
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/src/agent.d.ts +0 -3
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +6 -27
- package/dist/src/agent.js.map +1 -1
- package/dist/src/agents/research.d.ts +1 -1
- package/dist/src/agents/research.d.ts.map +1 -1
- package/dist/src/agents/research.js +84 -53
- package/dist/src/agents/research.js.map +1 -1
- package/dist/src/file-manager.d.ts +3 -21
- package/dist/src/file-manager.d.ts.map +1 -1
- package/dist/src/file-manager.js +15 -47
- package/dist/src/file-manager.js.map +1 -1
- package/dist/src/git-manager.d.ts.map +1 -1
- package/dist/src/git-manager.js +8 -1
- package/dist/src/git-manager.js.map +1 -1
- package/dist/src/types.d.ts +20 -1
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/workflow/steps/plan.d.ts.map +1 -1
- package/dist/src/workflow/steps/plan.js +26 -18
- package/dist/src/workflow/steps/plan.js.map +1 -1
- package/dist/src/workflow/steps/research.d.ts.map +1 -1
- package/dist/src/workflow/steps/research.js +100 -66
- package/dist/src/workflow/steps/research.js.map +1 -1
- package/dist/src/workflow/types.d.ts +0 -2
- package/dist/src/workflow/types.d.ts.map +1 -1
- package/dist/templates/plan-template.md +1 -5
- package/package.json +2 -6
- package/src/agent.ts +7 -31
- package/src/agents/research.ts +84 -53
- package/src/file-manager.ts +18 -73
- package/src/git-manager.ts +7 -1
- package/src/templates/plan-template.md +1 -5
- package/src/types.ts +24 -1
- package/src/workflow/steps/plan.ts +28 -21
- package/src/workflow/steps/research.ts +109 -74
- package/src/workflow/types.ts +0 -2
- package/dist/_virtual/_commonjsHelpers.js +0 -6
- package/dist/_virtual/_commonjsHelpers.js.map +0 -1
- package/dist/_virtual/index.js +0 -4
- package/dist/_virtual/index.js.map +0 -1
- package/dist/node_modules/@ai-sdk/anthropic/dist/index.js +0 -1154
- package/dist/node_modules/@ai-sdk/anthropic/dist/index.js.map +0 -1
- package/dist/node_modules/@ai-sdk/provider/dist/index.js +0 -296
- package/dist/node_modules/@ai-sdk/provider/dist/index.js.map +0 -1
- package/dist/node_modules/@ai-sdk/provider-utils/dist/index.js +0 -576
- package/dist/node_modules/@ai-sdk/provider-utils/dist/index.js.map +0 -1
- package/dist/node_modules/@ai-sdk/ui-utils/dist/index.js +0 -741
- package/dist/node_modules/@ai-sdk/ui-utils/dist/index.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/api/context.js +0 -112
- package/dist/node_modules/@opentelemetry/api/build/esm/api/context.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/api/diag.js +0 -123
- package/dist/node_modules/@opentelemetry/api/build/esm/api/diag.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/api/metrics.js +0 -62
- package/dist/node_modules/@opentelemetry/api/build/esm/api/metrics.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/api/propagation.js +0 -91
- package/dist/node_modules/@opentelemetry/api/build/esm/api/propagation.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/api/trace.js +0 -79
- package/dist/node_modules/@opentelemetry/api/build/esm/api/trace.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/baggage/context-helpers.js +0 -59
- package/dist/node_modules/@opentelemetry/api/build/esm/baggage/context-helpers.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/baggage/internal/baggage-impl.js +0 -99
- package/dist/node_modules/@opentelemetry/api/build/esm/baggage/internal/baggage-impl.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/baggage/utils.js +0 -31
- package/dist/node_modules/@opentelemetry/api/build/esm/baggage/utils.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/context/NoopContextManager.js +0 -69
- package/dist/node_modules/@opentelemetry/api/build/esm/context/NoopContextManager.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/context/context.js +0 -54
- package/dist/node_modules/@opentelemetry/api/build/esm/context/context.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/context-api.js +0 -22
- package/dist/node_modules/@opentelemetry/api/build/esm/context-api.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js +0 -104
- package/dist/node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js +0 -44
- package/dist/node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/diag/types.js +0 -43
- package/dist/node_modules/@opentelemetry/api/build/esm/diag/types.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/diag-api.js +0 -27
- package/dist/node_modules/@opentelemetry/api/build/esm/diag-api.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/internal/global-utils.js +0 -62
- package/dist/node_modules/@opentelemetry/api/build/esm/internal/global-utils.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/internal/semver.js +0 -121
- package/dist/node_modules/@opentelemetry/api/build/esm/internal/semver.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeter.js +0 -167
- package/dist/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeter.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeterProvider.js +0 -33
- package/dist/node_modules/@opentelemetry/api/build/esm/metrics/NoopMeterProvider.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/metrics-api.js +0 -22
- package/dist/node_modules/@opentelemetry/api/build/esm/metrics-api.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/platform/node/globalThis.js +0 -21
- package/dist/node_modules/@opentelemetry/api/build/esm/platform/node/globalThis.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/propagation/NoopTextMapPropagator.js +0 -35
- package/dist/node_modules/@opentelemetry/api/build/esm/propagation/NoopTextMapPropagator.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/propagation/TextMapPropagator.js +0 -40
- package/dist/node_modules/@opentelemetry/api/build/esm/propagation/TextMapPropagator.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/propagation-api.js +0 -22
- package/dist/node_modules/@opentelemetry/api/build/esm/propagation-api.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/NonRecordingSpan.js +0 -70
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/NonRecordingSpan.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/NoopTracer.js +0 -78
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/NoopTracer.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/NoopTracerProvider.js +0 -34
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/NoopTracerProvider.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/ProxyTracer.js +0 -55
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/ProxyTracer.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/ProxyTracerProvider.js +0 -56
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/ProxyTracerProvider.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/context-utils.js +0 -76
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/context-utils.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/invalid-span-constants.js +0 -27
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/invalid-span-constants.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/spancontext-utils.js +0 -45
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/spancontext-utils.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/status.js +0 -22
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/status.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/trace_flags.js +0 -25
- package/dist/node_modules/@opentelemetry/api/build/esm/trace/trace_flags.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/trace-api.js +0 -24
- package/dist/node_modules/@opentelemetry/api/build/esm/trace-api.js.map +0 -1
- package/dist/node_modules/@opentelemetry/api/build/esm/version.js +0 -20
- package/dist/node_modules/@opentelemetry/api/build/esm/version.js.map +0 -1
- package/dist/node_modules/ai/dist/index.js +0 -2870
- package/dist/node_modules/ai/dist/index.js.map +0 -1
- package/dist/node_modules/nanoid/non-secure/index.js +0 -13
- package/dist/node_modules/nanoid/non-secure/index.js.map +0 -1
- package/dist/node_modules/secure-json-parse/index.js +0 -133
- package/dist/node_modules/secure-json-parse/index.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/Options.js +0 -37
- package/dist/node_modules/zod-to-json-schema/dist/esm/Options.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/Refs.js +0 -26
- package/dist/node_modules/zod-to-json-schema/dist/esm/Refs.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/errorMessages.js +0 -17
- package/dist/node_modules/zod-to-json-schema/dist/esm/errorMessages.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js +0 -11
- package/dist/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/index.js +0 -8
- package/dist/node_modules/zod-to-json-schema/dist/esm/index.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parseDef.js +0 -66
- package/dist/node_modules/zod-to-json-schema/dist/esm/parseDef.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/any.js +0 -21
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/any.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/array.js +0 -30
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/array.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js +0 -53
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js +0 -8
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js +0 -8
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js +0 -8
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/date.js +0 -50
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/date.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/default.js +0 -11
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/default.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js +0 -11
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js +0 -9
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js +0 -56
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js +0 -24
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/map.js +0 -30
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/map.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js +0 -19
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/never.js +0 -15
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/never.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/null.js +0 -13
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/null.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js +0 -37
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/number.js +0 -56
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/number.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/object.js +0 -76
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/object.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js +0 -25
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js +0 -24
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js +0 -8
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js +0 -8
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/record.js +0 -65
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/record.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/set.js +0 -24
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/set.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/string.js +0 -350
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/string.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js +0 -36
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js +0 -10
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/union.js +0 -84
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/union.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js +0 -8
- package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/selectParser.js +0 -110
- package/dist/node_modules/zod-to-json-schema/dist/esm/selectParser.js.map +0 -1
- package/dist/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js +0 -90
- package/dist/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js.map +0 -1
- package/dist/src/structured-extraction.d.ts +0 -28
- package/dist/src/structured-extraction.d.ts.map +0 -1
- package/dist/src/structured-extraction.js +0 -77
- package/dist/src/structured-extraction.js.map +0 -1
- package/dist/src/utils/ai-sdk.d.ts +0 -14
- package/dist/src/utils/ai-sdk.d.ts.map +0 -1
- package/dist/src/utils/ai-sdk.js +0 -38
- package/dist/src/utils/ai-sdk.js.map +0 -1
- package/src/structured-extraction.ts +0 -117
- package/src/utils/ai-sdk.ts +0 -47
package/src/file-manager.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
|
-
import { join
|
|
3
|
-
import type { SupportingFile } from './types.js';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import type { SupportingFile, ResearchEvaluation } from './types.js';
|
|
4
4
|
import { Logger } from './utils/logger.js';
|
|
5
5
|
|
|
6
6
|
export interface TaskFile {
|
|
@@ -9,24 +9,6 @@ export interface TaskFile {
|
|
|
9
9
|
type: 'plan' | 'context' | 'reference' | 'output' | 'artifact';
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
export interface QuestionData {
|
|
13
|
-
id: string;
|
|
14
|
-
question: string;
|
|
15
|
-
options: string[];
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface AnswerData {
|
|
19
|
-
questionId: string;
|
|
20
|
-
selectedOption: string;
|
|
21
|
-
customInput?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface QuestionsFile {
|
|
25
|
-
questions: QuestionData[];
|
|
26
|
-
answered: boolean;
|
|
27
|
-
answers: AnswerData[] | null;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
12
|
export class PostHogFileManager {
|
|
31
13
|
private repositoryPath: string;
|
|
32
14
|
private logger: Logger;
|
|
@@ -170,48 +152,35 @@ export class PostHogFileManager {
|
|
|
170
152
|
return await this.readTaskFile(taskId, 'requirements.md');
|
|
171
153
|
}
|
|
172
154
|
|
|
173
|
-
async writeResearch(taskId: string,
|
|
155
|
+
async writeResearch(taskId: string, data: ResearchEvaluation): Promise<void> {
|
|
174
156
|
this.logger.debug('Writing research', {
|
|
175
157
|
taskId,
|
|
176
|
-
|
|
177
|
-
|
|
158
|
+
score: data.actionabilityScore,
|
|
159
|
+
hasQuestions: !!data.questions,
|
|
160
|
+
questionCount: data.questions?.length ?? 0,
|
|
161
|
+
answered: data.answered ?? false,
|
|
178
162
|
});
|
|
179
163
|
|
|
180
164
|
await this.writeTaskFile(taskId, {
|
|
181
|
-
name: 'research.
|
|
182
|
-
content: content,
|
|
183
|
-
type: 'artifact'
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
this.logger.info('Research file written', { taskId });
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async readResearch(taskId: string): Promise<string | null> {
|
|
190
|
-
return await this.readTaskFile(taskId, 'research.md');
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
async writeQuestions(taskId: string, data: QuestionsFile): Promise<void> {
|
|
194
|
-
this.logger.debug('Writing questions', {
|
|
195
|
-
taskId,
|
|
196
|
-
questionCount: data.questions.length,
|
|
197
|
-
answered: data.answered,
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
await this.writeTaskFile(taskId, {
|
|
201
|
-
name: 'questions.json',
|
|
165
|
+
name: 'research.json',
|
|
202
166
|
content: JSON.stringify(data, null, 2),
|
|
203
167
|
type: 'artifact'
|
|
204
168
|
});
|
|
205
169
|
|
|
206
|
-
this.logger.info('
|
|
170
|
+
this.logger.info('Research file written', {
|
|
171
|
+
taskId,
|
|
172
|
+
score: data.actionabilityScore,
|
|
173
|
+
hasQuestions: !!data.questions,
|
|
174
|
+
answered: data.answered ?? false,
|
|
175
|
+
});
|
|
207
176
|
}
|
|
208
177
|
|
|
209
|
-
async
|
|
178
|
+
async readResearch(taskId: string): Promise<ResearchEvaluation | null> {
|
|
210
179
|
try {
|
|
211
|
-
const content = await this.readTaskFile(taskId, '
|
|
212
|
-
return content ? JSON.parse(content) as
|
|
180
|
+
const content = await this.readTaskFile(taskId, 'research.json');
|
|
181
|
+
return content ? JSON.parse(content) as ResearchEvaluation : null;
|
|
213
182
|
} catch (error) {
|
|
214
|
-
this.logger.debug('Failed to parse
|
|
183
|
+
this.logger.debug('Failed to parse research.json', { error });
|
|
215
184
|
return null;
|
|
216
185
|
}
|
|
217
186
|
}
|
|
@@ -241,28 +210,4 @@ export class PostHogFileManager {
|
|
|
241
210
|
|
|
242
211
|
return files;
|
|
243
212
|
}
|
|
244
|
-
|
|
245
|
-
async ensureGitignore(): Promise<void> {
|
|
246
|
-
const gitignorePath = join(this.repositoryPath, '.posthog', '.gitignore');
|
|
247
|
-
const gitignoreContent = `# PostHog task artifacts - customize as needed
|
|
248
|
-
# Exclude temporary files
|
|
249
|
-
*/temp/
|
|
250
|
-
*/cache/
|
|
251
|
-
*/.env
|
|
252
|
-
*/.secrets
|
|
253
|
-
|
|
254
|
-
# Include plans and documentation by default
|
|
255
|
-
!*/plan.md
|
|
256
|
-
!*/context.md
|
|
257
|
-
!*/requirements.md
|
|
258
|
-
!*/README.md
|
|
259
|
-
`;
|
|
260
|
-
|
|
261
|
-
try {
|
|
262
|
-
await fs.access(gitignorePath);
|
|
263
|
-
} catch {
|
|
264
|
-
await fs.mkdir(dirname(gitignorePath), { recursive: true });
|
|
265
|
-
await fs.writeFile(gitignorePath, gitignoreContent, 'utf8');
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
213
|
}
|
package/src/git-manager.ts
CHANGED
|
@@ -135,7 +135,13 @@ export class GitManager {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
async addAllPostHogFiles(): Promise<void> {
|
|
138
|
-
|
|
138
|
+
try {
|
|
139
|
+
// Use -A flag to add all changes (including new files) and ignore errors if directory is empty
|
|
140
|
+
await this.runGitCommand('add -A .posthog/');
|
|
141
|
+
} catch (error) {
|
|
142
|
+
// If the directory doesn't exist or has no files, that's fine - just log and continue
|
|
143
|
+
this.logger.debug('No PostHog files to add', { error });
|
|
144
|
+
}
|
|
139
145
|
}
|
|
140
146
|
|
|
141
147
|
async commitChanges(message: string, options?: {
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
// import and export to keep a single type file
|
|
3
|
-
import type { CanUseTool, PermissionResult } from '@anthropic-ai/claude-agent-sdk
|
|
3
|
+
import type { CanUseTool, PermissionResult } from '@anthropic-ai/claude-agent-sdk';
|
|
4
4
|
export type { CanUseTool, PermissionResult };
|
|
5
5
|
|
|
6
6
|
// PostHog Task model (matches Array's OpenAPI schema)
|
|
@@ -345,4 +345,27 @@ export interface UrlMention {
|
|
|
345
345
|
type: ResourceType;
|
|
346
346
|
id?: string;
|
|
347
347
|
label?: string;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Research evaluation types
|
|
351
|
+
export interface ResearchQuestion {
|
|
352
|
+
id: string;
|
|
353
|
+
question: string;
|
|
354
|
+
options: string[];
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export interface ResearchAnswer {
|
|
358
|
+
questionId: string;
|
|
359
|
+
selectedOption: string;
|
|
360
|
+
customInput?: string;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
export interface ResearchEvaluation {
|
|
364
|
+
actionabilityScore: number; // 0-1 confidence score
|
|
365
|
+
context: string; // brief summary for planning
|
|
366
|
+
keyFiles: string[]; // files needing modification
|
|
367
|
+
blockers?: string[]; // what's preventing full confidence
|
|
368
|
+
questions?: ResearchQuestion[]; // only if score < 0.7
|
|
369
|
+
answered?: boolean; // whether questions have been answered
|
|
370
|
+
answers?: ResearchAnswer[]; // user's answers to questions
|
|
348
371
|
}
|
|
@@ -26,8 +26,8 @@ export const planStep: WorkflowStepRunner = async ({ step, context }) => {
|
|
|
26
26
|
return { status: 'skipped' };
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
29
|
+
const researchData = await fileManager.readResearch(task.id);
|
|
30
|
+
if (researchData?.questions && !researchData.answered) {
|
|
31
31
|
stepLogger.info('Waiting for answered research questions', { taskId: task.id });
|
|
32
32
|
emitEvent(adapter.createStatusEvent('phase_complete', { phase: 'research_questions' }));
|
|
33
33
|
return { status: 'skipped', halt: true };
|
|
@@ -35,29 +35,36 @@ export const planStep: WorkflowStepRunner = async ({ step, context }) => {
|
|
|
35
35
|
|
|
36
36
|
stepLogger.info('Starting planning phase', { taskId: task.id });
|
|
37
37
|
emitEvent(adapter.createStatusEvent('phase_start', { phase: 'planning' }));
|
|
38
|
-
|
|
39
|
-
const researchContent = await fileManager.readResearch(task.id);
|
|
40
38
|
let researchContext = '';
|
|
41
|
-
if (
|
|
42
|
-
researchContext += `## Research
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
);
|
|
39
|
+
if (researchData) {
|
|
40
|
+
researchContext += `## Research Context\n\n${researchData.context}\n\n`;
|
|
41
|
+
if (researchData.keyFiles.length > 0) {
|
|
42
|
+
researchContext += `**Key Files:**\n${researchData.keyFiles.map(f => `- ${f}`).join('\n')}\n\n`;
|
|
43
|
+
}
|
|
44
|
+
if (researchData.blockers && researchData.blockers.length > 0) {
|
|
45
|
+
researchContext += `**Considerations:**\n${researchData.blockers.map(b => `- ${b}`).join('\n')}\n\n`;
|
|
46
|
+
}
|
|
50
47
|
|
|
51
|
-
|
|
52
|
-
if (
|
|
53
|
-
researchContext +=
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
// Add answered questions if they exist
|
|
49
|
+
if (researchData.questions && researchData.answers && researchData.answered) {
|
|
50
|
+
researchContext += `## Implementation Decisions\n\n`;
|
|
51
|
+
for (const question of researchData.questions) {
|
|
52
|
+
const answer = researchData.answers.find(
|
|
53
|
+
(a) => a.questionId === question.id
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
researchContext += `### ${question.question}\n\n`;
|
|
57
|
+
if (answer) {
|
|
58
|
+
researchContext += `**Selected:** ${answer.selectedOption}\n`;
|
|
59
|
+
if (answer.customInput) {
|
|
60
|
+
researchContext += `**Details:** ${answer.customInput}\n`;
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
researchContext += `**Selected:** Not answered\n`;
|
|
64
|
+
}
|
|
65
|
+
researchContext += `\n`;
|
|
56
66
|
}
|
|
57
|
-
} else {
|
|
58
|
-
researchContext += `**Selected:** Not answered\n`;
|
|
59
67
|
}
|
|
60
|
-
researchContext += `\n`;
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
const planningPrompt = await promptBuilder.buildPlanningPrompt(task, cwd);
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
93
|
+
jsonContent += c.text;
|
|
73
94
|
}
|
|
74
95
|
}
|
|
75
96
|
}
|
|
76
97
|
}
|
|
77
98
|
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
|
|
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
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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: '
|
|
174
|
+
type: 'artifact',
|
|
129
175
|
ts: Date.now(),
|
|
130
|
-
|
|
131
|
-
|
|
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
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
};
|
package/src/workflow/types.ts
CHANGED
|
@@ -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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_commonjsHelpers.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
package/dist/_virtual/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|