task-o-matic 0.0.10 → 0.0.11
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/cli/display/progress.d.ts +1 -1
- package/dist/cli/display/progress.d.ts.map +1 -1
- package/dist/cli/display/progress.js +16 -13
- package/dist/commands/benchmark.js +70 -2
- package/dist/commands/init.js +48 -27
- package/dist/commands/prd.d.ts.map +1 -1
- package/dist/commands/prd.js +201 -0
- package/dist/commands/tasks/execute-loop.d.ts.map +1 -1
- package/dist/commands/tasks/execute-loop.js +10 -0
- package/dist/commands/tasks/execute.d.ts.map +1 -1
- package/dist/commands/tasks/execute.js +4 -0
- package/dist/commands/workflow.d.ts.map +1 -1
- package/dist/commands/workflow.js +56 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lib/ai-service/ai-operations.d.ts +13 -10
- package/dist/lib/ai-service/ai-operations.d.ts.map +1 -1
- package/dist/lib/ai-service/ai-operations.js +35 -995
- package/dist/lib/ai-service/base-operations.d.ts +13 -0
- package/dist/lib/ai-service/base-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/base-operations.js +79 -0
- package/dist/lib/ai-service/documentation-operations.d.ts +18 -0
- package/dist/lib/ai-service/documentation-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/documentation-operations.js +291 -0
- package/dist/lib/ai-service/prd-operations.d.ts +14 -0
- package/dist/lib/ai-service/prd-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/prd-operations.js +405 -0
- package/dist/lib/ai-service/task-operations.d.ts +12 -0
- package/dist/lib/ai-service/task-operations.d.ts.map +1 -0
- package/dist/lib/ai-service/task-operations.js +225 -0
- package/dist/lib/benchmark/registry.d.ts.map +1 -1
- package/dist/lib/benchmark/registry.js +127 -0
- package/dist/lib/better-t-stack-cli.d.ts +4 -1
- package/dist/lib/better-t-stack-cli.d.ts.map +1 -1
- package/dist/lib/better-t-stack-cli.js +126 -5
- package/dist/lib/config.d.ts +13 -6
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +90 -48
- package/dist/lib/context-builder.d.ts +13 -1
- package/dist/lib/context-builder.d.ts.map +1 -1
- package/dist/lib/context-builder.js +68 -36
- package/dist/lib/executors/claude-code-executor.d.ts +5 -2
- package/dist/lib/executors/claude-code-executor.d.ts.map +1 -1
- package/dist/lib/executors/claude-code-executor.js +30 -3
- package/dist/lib/executors/codex-executor.d.ts +5 -2
- package/dist/lib/executors/codex-executor.d.ts.map +1 -1
- package/dist/lib/executors/codex-executor.js +30 -3
- package/dist/lib/executors/executor-factory.d.ts +2 -2
- package/dist/lib/executors/executor-factory.d.ts.map +1 -1
- package/dist/lib/executors/executor-factory.js +5 -5
- package/dist/lib/executors/gemini-executor.d.ts +5 -2
- package/dist/lib/executors/gemini-executor.d.ts.map +1 -1
- package/dist/lib/executors/gemini-executor.js +30 -3
- package/dist/lib/executors/opencode-executor.d.ts +5 -2
- package/dist/lib/executors/opencode-executor.d.ts.map +1 -1
- package/dist/lib/executors/opencode-executor.js +30 -7
- package/dist/lib/prompt-builder.d.ts.map +1 -1
- package/dist/lib/prompt-builder.js +1 -0
- package/dist/lib/storage/file-system.d.ts +3 -7
- package/dist/lib/storage/file-system.d.ts.map +1 -1
- package/dist/lib/storage/file-system.js +50 -230
- package/dist/lib/storage/storage-callbacks.d.ts +17 -0
- package/dist/lib/storage/storage-callbacks.d.ts.map +1 -0
- package/dist/lib/storage/storage-callbacks.js +94 -0
- package/dist/lib/task-execution.d.ts.map +1 -1
- package/dist/lib/task-execution.js +16 -9
- package/dist/lib/task-loop-execution.d.ts.map +1 -1
- package/dist/lib/task-loop-execution.js +207 -8
- package/dist/prompts/index.d.ts +2 -0
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +2 -0
- package/dist/prompts/prd-combination.d.ts +2 -0
- package/dist/prompts/prd-combination.d.ts.map +1 -0
- package/dist/prompts/prd-combination.js +35 -0
- package/dist/prompts/prd-generation.d.ts +2 -0
- package/dist/prompts/prd-generation.d.ts.map +1 -0
- package/dist/prompts/prd-generation.js +49 -0
- package/dist/services/prd.d.ts +43 -0
- package/dist/services/prd.d.ts.map +1 -1
- package/dist/services/prd.js +121 -0
- package/dist/services/workflow-ai-assistant.d.ts.map +1 -1
- package/dist/services/workflow-ai-assistant.js +1 -40
- package/dist/services/workflow.d.ts +10 -0
- package/dist/services/workflow.d.ts.map +1 -1
- package/dist/services/workflow.js +118 -40
- package/dist/test/integration/callbacks.test.d.ts +2 -0
- package/dist/test/integration/callbacks.test.d.ts.map +1 -0
- package/dist/test/integration/callbacks.test.js +64 -0
- package/dist/types/callbacks.d.ts +9 -6
- package/dist/types/callbacks.d.ts.map +1 -1
- package/dist/types/index.d.ts +17 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/workflow-options.d.ts +7 -0
- package/dist/types/workflow-options.d.ts.map +1 -1
- package/dist/utils/ai-service-factory.d.ts +15 -1
- package/dist/utils/ai-service-factory.d.ts.map +1 -1
- package/dist/utils/ai-service-factory.js +29 -1
- package/dist/utils/streaming-options.d.ts +1 -1
- package/dist/utils/streaming-options.d.ts.map +1 -1
- package/dist/utils/streaming-options.js +31 -18
- package/docs/agents/cli.md +191 -0
- package/package.json +3 -2
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AIConfig, StreamingOptions, RetryConfig } from "../../types";
|
|
2
|
+
import { JSONParser } from "./json-parser";
|
|
3
|
+
import { Context7Client } from "./mcp-client";
|
|
4
|
+
import { RetryHandler } from "./retry-handler";
|
|
5
|
+
import { ModelProvider } from "./model-provider";
|
|
6
|
+
export declare class BaseOperations {
|
|
7
|
+
protected jsonParser: JSONParser;
|
|
8
|
+
protected context7Client: Context7Client;
|
|
9
|
+
protected retryHandler: RetryHandler;
|
|
10
|
+
protected modelProvider: ModelProvider;
|
|
11
|
+
streamText(prompt: string, config?: Partial<AIConfig>, systemPrompt?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<string>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=base-operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/base-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,qBAAa,cAAc;IACzB,SAAS,CAAC,UAAU,aAAoB;IACxC,SAAS,CAAC,cAAc,iBAAwB;IAChD,SAAS,CAAC,YAAY,eAAsB;IAC5C,SAAS,CAAC,aAAa,gBAAuB;IAExC,UAAU,CACd,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,YAAY,CAAC,EAAE,MAAM,EACrB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CA+EnB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseOperations = void 0;
|
|
4
|
+
const ai_1 = require("ai");
|
|
5
|
+
const json_parser_1 = require("./json-parser");
|
|
6
|
+
const mcp_client_1 = require("./mcp-client");
|
|
7
|
+
const retry_handler_1 = require("./retry-handler");
|
|
8
|
+
const model_provider_1 = require("./model-provider");
|
|
9
|
+
class BaseOperations {
|
|
10
|
+
jsonParser = new json_parser_1.JSONParser();
|
|
11
|
+
context7Client = new mcp_client_1.Context7Client();
|
|
12
|
+
retryHandler = new retry_handler_1.RetryHandler();
|
|
13
|
+
modelProvider = new model_provider_1.ModelProvider();
|
|
14
|
+
async streamText(prompt, config, systemPrompt, userMessage, streamingOptions, retryConfig) {
|
|
15
|
+
const aiConfig = { ...this.modelProvider.getAIConfig(), ...config };
|
|
16
|
+
return this.retryHandler.executeWithRetry(async () => {
|
|
17
|
+
const model = this.modelProvider.getModel(aiConfig);
|
|
18
|
+
const result = (0, ai_1.streamText)({
|
|
19
|
+
model,
|
|
20
|
+
system: systemPrompt,
|
|
21
|
+
messages: [{ role: "user", content: userMessage || prompt }],
|
|
22
|
+
maxRetries: 0,
|
|
23
|
+
onError: ({ error }) => {
|
|
24
|
+
streamingOptions?.onError?.(error);
|
|
25
|
+
throw error;
|
|
26
|
+
},
|
|
27
|
+
onChunk: streamingOptions?.onChunk
|
|
28
|
+
? ({ chunk }) => {
|
|
29
|
+
if (chunk.type === "text-delta") {
|
|
30
|
+
streamingOptions.onChunk(chunk.text);
|
|
31
|
+
}
|
|
32
|
+
else if (chunk.type === "reasoning-delta") {
|
|
33
|
+
streamingOptions.onReasoning?.(chunk.text);
|
|
34
|
+
}
|
|
35
|
+
else if (chunk.type === "tool-result" &&
|
|
36
|
+
chunk.toolName === "get-library-docs") {
|
|
37
|
+
const docs = chunk.output;
|
|
38
|
+
if (docs && typeof docs === "object" && "content" in docs) {
|
|
39
|
+
this.context7Client.saveContext7Documentation(chunk.input?.context7CompatibleLibraryID || "unknown", docs.content, chunk.input?.topic || "general");
|
|
40
|
+
}
|
|
41
|
+
else if (docs && typeof docs === "string") {
|
|
42
|
+
this.context7Client.saveContext7Documentation(chunk.input?.context7CompatibleLibraryID || "unknown", docs, chunk.input?.topic || "general");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
: undefined,
|
|
47
|
+
onFinish: streamingOptions?.onFinish
|
|
48
|
+
? ({ text, finishReason, usage }) => {
|
|
49
|
+
streamingOptions.onFinish({
|
|
50
|
+
text,
|
|
51
|
+
finishReason,
|
|
52
|
+
usage,
|
|
53
|
+
isAborted: false,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
: undefined,
|
|
57
|
+
...(aiConfig.provider === "openrouter" &&
|
|
58
|
+
aiConfig.reasoning &&
|
|
59
|
+
aiConfig.reasoning.maxTokens
|
|
60
|
+
? {
|
|
61
|
+
providerOptions: {
|
|
62
|
+
openrouter: {
|
|
63
|
+
reasoning: {
|
|
64
|
+
max_tokens: aiConfig.reasoning.maxTokens,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
}
|
|
69
|
+
: {}),
|
|
70
|
+
});
|
|
71
|
+
let fullText = "";
|
|
72
|
+
for await (const textPart of result.textStream) {
|
|
73
|
+
fullText += textPart;
|
|
74
|
+
}
|
|
75
|
+
return fullText;
|
|
76
|
+
}, retryConfig, "AI streaming");
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.BaseOperations = BaseOperations;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AIConfig, DocumentationDetection, StreamingOptions, RetryConfig, TaskDocumentation } from "../../types";
|
|
2
|
+
import { BaseOperations } from "./base-operations";
|
|
3
|
+
export declare class DocumentationOperations extends BaseOperations {
|
|
4
|
+
enhanceTaskWithDocumentation(taskId: string, taskTitle: string, taskDescription: string, stackInfo?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, config?: Partial<AIConfig>, existingResearch?: Record<string, Array<{
|
|
5
|
+
query: string;
|
|
6
|
+
doc: string;
|
|
7
|
+
}>>): Promise<string>;
|
|
8
|
+
analyzeDocumentationNeeds(taskId: string, taskTitle: string, taskDescription: string, stackInfo?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, config?: Partial<AIConfig>, existingResearch?: (TaskDocumentation | undefined)[]): Promise<DocumentationDetection>;
|
|
9
|
+
generateDocumentationRecap(libraries: Array<{
|
|
10
|
+
name: string;
|
|
11
|
+
context7Id: string;
|
|
12
|
+
reason: string;
|
|
13
|
+
}>, documentContents: Array<{
|
|
14
|
+
library: string;
|
|
15
|
+
content: string;
|
|
16
|
+
}>, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=documentation-operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documentation-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/documentation-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,sBAAsB,EACtB,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAKrB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAAa,uBAAwB,SAAQ,cAAc;IACnD,4BAA4B,CAChC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,GACvE,OAAO,CAAC,MAAM,CAAC;IAiJZ,yBAAyB,CAC7B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,gBAAgB,CAAC,EAAE,CAAC,iBAAiB,GAAG,SAAS,CAAC,EAAE,GACnD,OAAO,CAAC,sBAAsB,CAAC;IAiM5B,0BAA0B,CAC9B,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,EACtE,gBAAgB,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7D,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CA8BnB"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DocumentationOperations = void 0;
|
|
4
|
+
const ai_1 = require("ai");
|
|
5
|
+
const prompt_builder_1 = require("../prompt-builder");
|
|
6
|
+
const prompts_1 = require("../../prompts");
|
|
7
|
+
const ai_service_factory_1 = require("../../utils/ai-service-factory");
|
|
8
|
+
const filesystem_tools_1 = require("./filesystem-tools");
|
|
9
|
+
const base_operations_1 = require("./base-operations");
|
|
10
|
+
class DocumentationOperations extends base_operations_1.BaseOperations {
|
|
11
|
+
async enhanceTaskWithDocumentation(taskId, taskTitle, taskDescription, stackInfo, streamingOptions, retryConfig, config, existingResearch) {
|
|
12
|
+
return this.retryHandler
|
|
13
|
+
.executeWithRetry(async () => {
|
|
14
|
+
const mcpTools = await this.context7Client.getMCPTools();
|
|
15
|
+
const defaultAIConfig = this.modelProvider.getAIConfig();
|
|
16
|
+
const aiConfig = config
|
|
17
|
+
? { ...defaultAIConfig, ...config }
|
|
18
|
+
: defaultAIConfig;
|
|
19
|
+
const model = this.modelProvider.getModel(aiConfig);
|
|
20
|
+
const contextBuilder = (0, ai_service_factory_1.getContextBuilder)();
|
|
21
|
+
const builtContext = await contextBuilder.buildContext("1.1");
|
|
22
|
+
const existingResearchContext = existingResearch
|
|
23
|
+
? Object.entries(existingResearch)
|
|
24
|
+
.map(([lib, entries]) => `### ${lib}\n${entries
|
|
25
|
+
.map((e) => `- Query: "${e.query}"`)
|
|
26
|
+
.join("\n")}`)
|
|
27
|
+
.join("\n\n")
|
|
28
|
+
: "No existing research available.";
|
|
29
|
+
const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
|
|
30
|
+
name: "task-enhancement",
|
|
31
|
+
type: "user",
|
|
32
|
+
variables: {
|
|
33
|
+
TASK_TITLE: taskTitle,
|
|
34
|
+
TASK_DESCRIPTION: taskDescription,
|
|
35
|
+
CONTEXT_INFO: `Technology stack: ${stackInfo || "Not specified"}`,
|
|
36
|
+
EXISTING_RESEARCH: existingResearchContext,
|
|
37
|
+
PRD_CONTENT: builtContext.prdContent || "No PRD content available",
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
if (!promptResult.success) {
|
|
41
|
+
throw new Error(`Failed to build task enhancement prompt: ${promptResult.error}`);
|
|
42
|
+
}
|
|
43
|
+
const prompt = promptResult.prompt;
|
|
44
|
+
const allTools = {
|
|
45
|
+
...mcpTools,
|
|
46
|
+
...filesystem_tools_1.filesystemTools,
|
|
47
|
+
};
|
|
48
|
+
const result = await (0, ai_1.streamText)({
|
|
49
|
+
model,
|
|
50
|
+
tools: allTools,
|
|
51
|
+
system: prompts_1.TASK_ENHANCEMENT_SYSTEM_PROMPT +
|
|
52
|
+
`
|
|
53
|
+
|
|
54
|
+
You have access to Context7 documentation tools and filesystem tools.
|
|
55
|
+
|
|
56
|
+
## Available Tools:
|
|
57
|
+
- Context7 MCP tools (context7_resolve_library_id, context7_get_library_docs) for library documentation
|
|
58
|
+
- readFile: Read the contents of any file in the project
|
|
59
|
+
- listDirectory: List contents of directories
|
|
60
|
+
|
|
61
|
+
## Research Strategy:
|
|
62
|
+
1. Use Context7 MCP tools for library documentation research
|
|
63
|
+
2. Use filesystem tools to understand project structure, existing code, and dependencies
|
|
64
|
+
3. Synthesize information from all sources to enhance the task
|
|
65
|
+
|
|
66
|
+
Technology stack context: ${stackInfo || "Not specified"}
|
|
67
|
+
|
|
68
|
+
## Available Cached Research:
|
|
69
|
+
${existingResearchContext}`,
|
|
70
|
+
messages: [
|
|
71
|
+
{
|
|
72
|
+
role: "user",
|
|
73
|
+
content: prompt,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
maxRetries: 0,
|
|
77
|
+
stopWhen: (0, ai_1.stepCountIs)(8),
|
|
78
|
+
onError: ({ error }) => {
|
|
79
|
+
streamingOptions?.onError?.(error);
|
|
80
|
+
throw error;
|
|
81
|
+
},
|
|
82
|
+
onChunk: streamingOptions?.onChunk
|
|
83
|
+
? ({ chunk }) => {
|
|
84
|
+
if (chunk.type === "text-delta") {
|
|
85
|
+
streamingOptions.onChunk(chunk.text);
|
|
86
|
+
}
|
|
87
|
+
else if (chunk.type === "reasoning-delta") {
|
|
88
|
+
streamingOptions.onReasoning?.(chunk.text);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
: undefined,
|
|
92
|
+
onFinish: streamingOptions?.onFinish
|
|
93
|
+
? ({ text, finishReason, usage }) => {
|
|
94
|
+
streamingOptions.onFinish({
|
|
95
|
+
text,
|
|
96
|
+
finishReason,
|
|
97
|
+
usage,
|
|
98
|
+
isAborted: false,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
: undefined,
|
|
102
|
+
});
|
|
103
|
+
const toolCalls = await result.toolCalls;
|
|
104
|
+
const toolResults = await result.toolResults;
|
|
105
|
+
if (toolCalls.length > 0) {
|
|
106
|
+
console.log("AI made tool calls:", toolCalls.map((tc) => ({ tool: tc.toolName, input: tc.input })));
|
|
107
|
+
}
|
|
108
|
+
if (toolResults.length > 0) {
|
|
109
|
+
console.log("Tool results received:", toolResults.map((tr) => ({
|
|
110
|
+
tool: tr.toolName,
|
|
111
|
+
output: tr.output,
|
|
112
|
+
})));
|
|
113
|
+
}
|
|
114
|
+
let fullText = "";
|
|
115
|
+
for await (const textPart of result.textStream) {
|
|
116
|
+
fullText += textPart;
|
|
117
|
+
if (streamingOptions?.onChunk) {
|
|
118
|
+
streamingOptions.onChunk(textPart);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return fullText;
|
|
122
|
+
}, retryConfig, "Task enhancement with documentation")
|
|
123
|
+
.finally(async () => {
|
|
124
|
+
await this.context7Client.closeMCPConnection();
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
async analyzeDocumentationNeeds(taskId, taskTitle, taskDescription, stackInfo, streamingOptions, retryConfig, config, existingResearch) {
|
|
128
|
+
return this.retryHandler
|
|
129
|
+
.executeWithRetry(async () => {
|
|
130
|
+
const mcpTools = await this.context7Client.getMCPTools();
|
|
131
|
+
const defaultAIConfig = this.modelProvider.getAIConfig();
|
|
132
|
+
const aiConfig = config
|
|
133
|
+
? { ...defaultAIConfig, ...config }
|
|
134
|
+
: defaultAIConfig;
|
|
135
|
+
const model = this.modelProvider.getModel(aiConfig);
|
|
136
|
+
const existingResearchContext = existingResearch
|
|
137
|
+
? "## Existing research\n" +
|
|
138
|
+
existingResearch
|
|
139
|
+
.map((rs) => rs &&
|
|
140
|
+
`${rs.recap}\n#### librairies\n${rs.libraries.join(`- \n`)}\n\n#### files:\n${rs.libraries.join(`- \n`)}`)
|
|
141
|
+
.join("\n\n")
|
|
142
|
+
: "No existing research available.";
|
|
143
|
+
const promptResult = prompt_builder_1.PromptBuilder.buildPrompt({
|
|
144
|
+
name: "documentation-detection",
|
|
145
|
+
type: "user",
|
|
146
|
+
variables: {
|
|
147
|
+
TASK_TITLE: taskTitle,
|
|
148
|
+
TASK_DESCRIPTION: taskDescription,
|
|
149
|
+
STACK_INFO: stackInfo || "Not specified",
|
|
150
|
+
EXISTING_RESEARCH: existingResearchContext,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
if (!promptResult.success) {
|
|
154
|
+
throw new Error(`Failed to build documentation detection prompt: ${promptResult.error}`);
|
|
155
|
+
}
|
|
156
|
+
const prompt = promptResult.prompt;
|
|
157
|
+
const libraries = [];
|
|
158
|
+
const files = [];
|
|
159
|
+
const allTools = {
|
|
160
|
+
...mcpTools,
|
|
161
|
+
};
|
|
162
|
+
const result = await (0, ai_1.streamText)({
|
|
163
|
+
model,
|
|
164
|
+
tools: allTools,
|
|
165
|
+
system: `You are an expert developer.\nYou have access to Context7 MCP tools for documentation research.\nFetch documentation relevant to the task in the project context and create a document giving that knowledge to the AI assistant that will implement the task.`,
|
|
166
|
+
messages: [{ role: "user", content: prompt }],
|
|
167
|
+
maxRetries: 0,
|
|
168
|
+
stopWhen: (0, ai_1.stepCountIs)(8),
|
|
169
|
+
onError: ({ error }) => {
|
|
170
|
+
streamingOptions?.onError?.(error);
|
|
171
|
+
throw error;
|
|
172
|
+
},
|
|
173
|
+
onChunk: streamingOptions?.onChunk
|
|
174
|
+
? ({ chunk }) => {
|
|
175
|
+
if (chunk.type === "text-delta") {
|
|
176
|
+
streamingOptions.onChunk(chunk.text);
|
|
177
|
+
}
|
|
178
|
+
else if (chunk.type === "reasoning-delta") {
|
|
179
|
+
streamingOptions.onReasoning?.(chunk.text);
|
|
180
|
+
}
|
|
181
|
+
else if (chunk.type === "tool-result") {
|
|
182
|
+
if (chunk.toolName === "get-library-docs" && chunk.output) {
|
|
183
|
+
(async () => {
|
|
184
|
+
try {
|
|
185
|
+
const input = chunk.input;
|
|
186
|
+
const libraryId = input.context7CompatibleLibraryID;
|
|
187
|
+
const libraryName = libraryId.split("/").pop() || "unknown";
|
|
188
|
+
const timestamp = Date.now();
|
|
189
|
+
const filename = input.topic ?? `${libraryName}-${timestamp}`;
|
|
190
|
+
let content = "";
|
|
191
|
+
if (chunk.output &&
|
|
192
|
+
typeof chunk.output === "object") {
|
|
193
|
+
if ("content" in chunk.output) {
|
|
194
|
+
const contentArray = chunk.output
|
|
195
|
+
.content;
|
|
196
|
+
if (Array.isArray(contentArray)) {
|
|
197
|
+
content = contentArray
|
|
198
|
+
.map((item) => item.text || "")
|
|
199
|
+
.join("\n");
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
content = String(contentArray);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
else if ("text" in chunk.output) {
|
|
206
|
+
content = chunk.output.text;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else if (typeof chunk.output === "string") {
|
|
210
|
+
content = chunk.output;
|
|
211
|
+
}
|
|
212
|
+
if (content) {
|
|
213
|
+
const docFile = await this.context7Client.saveContext7Documentation(libraryName, filename, content);
|
|
214
|
+
libraries.push({
|
|
215
|
+
name: libraryName,
|
|
216
|
+
context7Id: libraryId,
|
|
217
|
+
reason: "Documentation fetched for task implementation",
|
|
218
|
+
searchQuery: filename,
|
|
219
|
+
});
|
|
220
|
+
files.push(docFile);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
console.error("Failed to save Context7 documentation:", error);
|
|
225
|
+
}
|
|
226
|
+
})();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
: undefined,
|
|
231
|
+
onFinish: streamingOptions?.onFinish
|
|
232
|
+
? ({ text, finishReason, usage }) => {
|
|
233
|
+
streamingOptions.onFinish({
|
|
234
|
+
text,
|
|
235
|
+
finishReason,
|
|
236
|
+
usage,
|
|
237
|
+
isAborted: false,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
: undefined,
|
|
241
|
+
});
|
|
242
|
+
let fullText = "";
|
|
243
|
+
for await (const textPart of result.textStream) {
|
|
244
|
+
fullText += textPart;
|
|
245
|
+
}
|
|
246
|
+
const toolResults = await result.toolResults;
|
|
247
|
+
const toolCalls = await result.toolCalls;
|
|
248
|
+
if (fullText.trim()) {
|
|
249
|
+
try {
|
|
250
|
+
const storage = (0, ai_service_factory_1.getStorage)();
|
|
251
|
+
const taskDocFile = await storage.saveTaskDocumentation(taskId, fullText);
|
|
252
|
+
files.push(taskDocFile);
|
|
253
|
+
}
|
|
254
|
+
catch (error) {
|
|
255
|
+
console.error("Failed to save task documentation:", error);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
libraries,
|
|
260
|
+
confidence: libraries.length > 0 ? 0.8 : 0.3,
|
|
261
|
+
toolResults: toolResults.map((tr) => ({
|
|
262
|
+
toolName: tr.toolName,
|
|
263
|
+
output: tr.output,
|
|
264
|
+
})),
|
|
265
|
+
files,
|
|
266
|
+
};
|
|
267
|
+
}, retryConfig, "Documentation needs analysis")
|
|
268
|
+
.finally(async () => {
|
|
269
|
+
await this.context7Client.closeMCPConnection();
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
async generateDocumentationRecap(libraries, documentContents, streamingOptions, retryConfig) {
|
|
273
|
+
const prompt = `Create a concise recap of the documentation fetched for these libraries:
|
|
274
|
+
|
|
275
|
+
Libraries:
|
|
276
|
+
${libraries
|
|
277
|
+
.map((lib) => `- ${lib.name} (${lib.context7Id}): ${lib.reason}`)
|
|
278
|
+
.join("\n")}
|
|
279
|
+
|
|
280
|
+
Documentation Contents:
|
|
281
|
+
${documentContents
|
|
282
|
+
.map((doc) => `## ${doc.library}\n${doc.content.substring(0, 500)}...`)
|
|
283
|
+
.join("\n\n")}
|
|
284
|
+
|
|
285
|
+
Please provide a 2-3 sentence summary of what documentation is available and how it relates to the task.`;
|
|
286
|
+
return this.retryHandler.executeWithRetry(async () => {
|
|
287
|
+
return this.streamText(prompt, undefined, "You are a technical writer who creates concise summaries of documentation collections.", undefined, streamingOptions, { maxAttempts: 1 });
|
|
288
|
+
}, retryConfig, "Documentation recap generation");
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
exports.DocumentationOperations = DocumentationOperations;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AIConfig, AIPRDParseResult, StreamingOptions, RetryConfig } from "../../types";
|
|
2
|
+
import { BaseOperations } from "./base-operations";
|
|
3
|
+
export declare class PRDOperations extends BaseOperations {
|
|
4
|
+
parsePRD(prdContent: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, workingDirectory?: string, enableFilesystemTools?: boolean): Promise<AIPRDParseResult>;
|
|
5
|
+
reworkPRD(prdContent: string, feedback: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, workingDirectory?: string, enableFilesystemTools?: boolean): Promise<string>;
|
|
6
|
+
generatePRDQuestions(prdContent: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>, workingDirectory?: string, enableFilesystemTools?: boolean): Promise<string[]>;
|
|
7
|
+
answerPRDQuestions(prdContent: string, questions: string[], config?: Partial<AIConfig>, contextInfo?: {
|
|
8
|
+
stackInfo?: string;
|
|
9
|
+
projectDescription?: string;
|
|
10
|
+
}, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<Record<string, string>>;
|
|
11
|
+
generatePRD(description: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<string>;
|
|
12
|
+
combinePRDs(prds: string[], originalDescription: string, config?: Partial<AIConfig>, promptOverride?: string, userMessage?: string, streamingOptions?: StreamingOptions, retryConfig?: Partial<RetryConfig>): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=prd-operations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prd-operations.d.ts","sourceRoot":"","sources":["../../../src/lib/ai-service/prd-operations.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EAER,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EAIZ,MAAM,aAAa,CAAC;AAYrB,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,qBAAa,aAAc,SAAQ,cAAc;IACzC,QAAQ,CACZ,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,gBAAgB,CAAC;IAyKtB,SAAS,CACb,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,MAAM,CAAC;IAuGZ,oBAAoB,CACxB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,EAClC,gBAAgB,CAAC,EAAE,MAAM,EACzB,qBAAqB,CAAC,EAAE,OAAO,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC;IAyGd,kBAAkB,CACtB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EAAE,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,WAAW,CAAC,EAAE;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,EACD,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAiF5B,WAAW,CACf,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;IAqBZ,WAAW,CACf,IAAI,EAAE,MAAM,EAAE,EACd,mBAAmB,EAAE,MAAM,EAC3B,MAAM,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,EAC1B,cAAc,CAAC,EAAE,MAAM,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,gBAAgB,EACnC,WAAW,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC;CA0BnB"}
|