@polka-codes/cli 0.9.57 → 0.9.59
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.js +89 -62
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -35579,7 +35579,7 @@ var {
|
|
|
35579
35579
|
Help
|
|
35580
35580
|
} = import__.default;
|
|
35581
35581
|
// package.json
|
|
35582
|
-
var version = "0.9.
|
|
35582
|
+
var version = "0.9.59";
|
|
35583
35583
|
|
|
35584
35584
|
// src/commands/code.ts
|
|
35585
35585
|
import { readFile as readFile3 } from "node:fs/promises";
|
|
@@ -78530,7 +78530,9 @@ async function generateText(input2, context) {
|
|
|
78530
78530
|
const messages = applyCacheControl(input2.messages.map(fromJsonModelMessage), model.provider, model.modelId);
|
|
78531
78531
|
for (let i = 0;i < retryCount; i++) {
|
|
78532
78532
|
const abortController = new AbortController;
|
|
78533
|
-
|
|
78533
|
+
let timeout = setTimeout(() => abortController.abort(), requestTimeoutSeconds * 1000);
|
|
78534
|
+
const lastOutputs = [];
|
|
78535
|
+
let repetitionDetected = false;
|
|
78534
78536
|
const usageMeterOnFinishHandler = context.parameters.usageMeter.onFinishHandler(model);
|
|
78535
78537
|
try {
|
|
78536
78538
|
const stream = streamText({
|
|
@@ -78539,8 +78541,24 @@ async function generateText(input2, context) {
|
|
|
78539
78541
|
messages,
|
|
78540
78542
|
tools: input2.tools,
|
|
78541
78543
|
async onChunk({ chunk }) {
|
|
78544
|
+
clearTimeout(timeout);
|
|
78545
|
+
timeout = setTimeout(() => abortController.abort(), requestTimeoutSeconds * 1000);
|
|
78542
78546
|
switch (chunk.type) {
|
|
78543
78547
|
case "text-delta":
|
|
78548
|
+
lastOutputs.push(chunk.text);
|
|
78549
|
+
if (lastOutputs.length > 20) {
|
|
78550
|
+
lastOutputs.shift();
|
|
78551
|
+
}
|
|
78552
|
+
if (lastOutputs.length === 20) {
|
|
78553
|
+
const firstHalf = lastOutputs.slice(0, 10).join("");
|
|
78554
|
+
const secondHalf = lastOutputs.slice(10).join("");
|
|
78555
|
+
if (firstHalf === secondHalf) {
|
|
78556
|
+
if (firstHalf.length > 20) {
|
|
78557
|
+
repetitionDetected = true;
|
|
78558
|
+
abortController.abort();
|
|
78559
|
+
}
|
|
78560
|
+
}
|
|
78561
|
+
}
|
|
78544
78562
|
agentCallback?.({
|
|
78545
78563
|
kind: "Text" /* Text */,
|
|
78546
78564
|
newText: chunk.text
|
|
@@ -78569,6 +78587,11 @@ async function generateText(input2, context) {
|
|
|
78569
78587
|
return resp.messages;
|
|
78570
78588
|
} catch (error46) {
|
|
78571
78589
|
if (error46.name === "AbortError") {
|
|
78590
|
+
if (repetitionDetected) {
|
|
78591
|
+
console.warn("Repetition detected, retrying...");
|
|
78592
|
+
continue;
|
|
78593
|
+
}
|
|
78594
|
+
console.warn(`Request timed out after ${requestTimeoutSeconds} seconds, retrying...`);
|
|
78572
78595
|
continue;
|
|
78573
78596
|
}
|
|
78574
78597
|
if ("response" in error46) {
|
|
@@ -79656,47 +79679,35 @@ ${createJsonResponseInstruction({
|
|
|
79656
79679
|
}
|
|
79657
79680
|
\`\`\`
|
|
79658
79681
|
`;
|
|
79659
|
-
function
|
|
79660
|
-
|
|
79661
|
-
|
|
79662
|
-
parts.push(`<pr_title>
|
|
79663
|
-
${params.pullRequestTitle}
|
|
79664
|
-
</pr_title>`);
|
|
79665
|
-
}
|
|
79666
|
-
if (params.pullRequestDescription) {
|
|
79667
|
-
parts.push(`<pr_description>
|
|
79668
|
-
${params.pullRequestDescription}
|
|
79669
|
-
</pr_description>`);
|
|
79670
|
-
}
|
|
79671
|
-
if (params.commitMessages) {
|
|
79672
|
-
parts.push(`<commit_messages>
|
|
79673
|
-
${params.commitMessages}
|
|
79674
|
-
</commit_messages>`);
|
|
79675
|
-
}
|
|
79676
|
-
if (params.context) {
|
|
79677
|
-
parts.push(`<user_context>
|
|
79678
|
-
${params.context}
|
|
79679
|
-
</user_context>`);
|
|
79680
|
-
}
|
|
79681
|
-
if (params.changedFiles && params.changedFiles.length > 0) {
|
|
79682
|
-
const fileList = params.changedFiles.map((file2) => `${file2.status}: ${file2.path}`).join(`
|
|
79683
|
-
`);
|
|
79684
|
-
parts.push(`<file_status>
|
|
79685
|
-
${fileList}
|
|
79686
|
-
</file_status>`);
|
|
79682
|
+
function formatContext(tag, value) {
|
|
79683
|
+
if (!value) {
|
|
79684
|
+
return;
|
|
79687
79685
|
}
|
|
79688
|
-
|
|
79686
|
+
return `<${tag}>
|
|
79687
|
+
${value}
|
|
79688
|
+
</${tag}>`;
|
|
79689
|
+
}
|
|
79690
|
+
function getReviewInstructions(params) {
|
|
79689
79691
|
if (params.commitRange) {
|
|
79690
|
-
|
|
79691
|
-
} else if (params.staged) {
|
|
79692
|
-
instructions = "Review the staged changes. Use the gitDiff tool with staged: true, contextLines: 5, and includeLineNumbers: true to inspect the actual code changes. The diff will include line number annotations to help you report accurate line numbers. File status information is already provided above.";
|
|
79693
|
-
} else {
|
|
79694
|
-
instructions = "Review the unstaged changes. Use the gitDiff tool with contextLines: 5, and includeLineNumbers: true to inspect the actual code changes. The diff will include line number annotations to help you report accurate line numbers. File status information is already provided above.";
|
|
79692
|
+
return `Review the pull request. Use the gitDiff tool with commit range '${params.commitRange}' to inspect the actual code changes.`;
|
|
79695
79693
|
}
|
|
79696
|
-
|
|
79697
|
-
|
|
79698
|
-
|
|
79699
|
-
return
|
|
79694
|
+
if (params.staged) {
|
|
79695
|
+
return "Review the staged changes. Use the gitDiff tool with staged: true to inspect the actual code changes.";
|
|
79696
|
+
}
|
|
79697
|
+
return "Review the unstaged changes. Use the gitDiff tool to inspect the actual code changes.";
|
|
79698
|
+
}
|
|
79699
|
+
function formatReviewToolInput(params) {
|
|
79700
|
+
const fileList = params.changedFiles && params.changedFiles.length > 0 ? params.changedFiles.map((file2) => `${file2.status}: ${file2.path}`).join(`
|
|
79701
|
+
`) : undefined;
|
|
79702
|
+
const parts = [
|
|
79703
|
+
formatContext("pr_title", params.pullRequestTitle),
|
|
79704
|
+
formatContext("pr_description", params.pullRequestDescription),
|
|
79705
|
+
formatContext("commit_messages", params.commitMessages),
|
|
79706
|
+
formatContext("user_context", params.context),
|
|
79707
|
+
formatContext("file_status", fileList),
|
|
79708
|
+
formatContext("review_instructions", getReviewInstructions(params))
|
|
79709
|
+
];
|
|
79710
|
+
return parts.filter(Boolean).join(`
|
|
79700
79711
|
`);
|
|
79701
79712
|
}
|
|
79702
79713
|
// src/workflows/fix.workflow.ts
|
|
@@ -80663,7 +80674,7 @@ ${defaultContext}`;
|
|
|
80663
80674
|
outputSchema: EpicPlanSchema
|
|
80664
80675
|
}, context);
|
|
80665
80676
|
}
|
|
80666
|
-
async function createAndApprovePlan(task, context) {
|
|
80677
|
+
async function createAndApprovePlan(task, context, saveUsageSnapshot) {
|
|
80667
80678
|
const { logger, step, tools: tools2 } = context;
|
|
80668
80679
|
logger.info(`Phase 2: Creating high-level plan...
|
|
80669
80680
|
`);
|
|
@@ -80693,6 +80704,7 @@ ${result.plan}`);
|
|
|
80693
80704
|
if (feedback.trim() === "") {
|
|
80694
80705
|
logger.info(`High-level plan approved.
|
|
80695
80706
|
`);
|
|
80707
|
+
await saveUsageSnapshot();
|
|
80696
80708
|
return { plan: result.plan, branchName: result.branchName };
|
|
80697
80709
|
}
|
|
80698
80710
|
break;
|
|
@@ -80924,7 +80936,7 @@ async function findNextTask(tools2) {
|
|
|
80924
80936
|
currentTask = subTasks[0];
|
|
80925
80937
|
}
|
|
80926
80938
|
}
|
|
80927
|
-
async function runImplementationLoop(context, highLevelPlan) {
|
|
80939
|
+
async function runImplementationLoop(context, highLevelPlan, saveUsageSnapshot) {
|
|
80928
80940
|
const { logger, step, tools: tools2 } = context;
|
|
80929
80941
|
const commitMessages = [];
|
|
80930
80942
|
logger.info(`Phase 5: Iterative Implementation Loop...
|
|
@@ -80990,6 +81002,7 @@ Focus only on this item, but use the plan for context.`;
|
|
|
80990
81002
|
}
|
|
80991
81003
|
logger.info(`
|
|
80992
81004
|
Progress: ${progressMessage}`);
|
|
81005
|
+
await saveUsageSnapshot();
|
|
80993
81006
|
if (!nextTaskItem) {
|
|
80994
81007
|
logger.info(`All tasks complete!
|
|
80995
81008
|
`);
|
|
@@ -81101,7 +81114,7 @@ Max retries (${MAX_REVIEW_RETRIES}) reached for final review. Issues might remai
|
|
|
81101
81114
|
}
|
|
81102
81115
|
var epicWorkflow = async (input2, context) => {
|
|
81103
81116
|
const { logger, tools: tools2 } = context;
|
|
81104
|
-
const { task, saveEpicContext } = input2;
|
|
81117
|
+
const { task, saveEpicContext, saveUsageSnapshot } = input2;
|
|
81105
81118
|
const workflowStartTime = Date.now();
|
|
81106
81119
|
if (!task || task.trim() === "") {
|
|
81107
81120
|
logger.error("Error: Task cannot be empty. Please provide a valid task description.");
|
|
@@ -81120,7 +81133,7 @@ var epicWorkflow = async (input2, context) => {
|
|
|
81120
81133
|
logger.error("Error: Task is missing in epic context. Exiting.");
|
|
81121
81134
|
return;
|
|
81122
81135
|
}
|
|
81123
|
-
const planResult = await createAndApprovePlan(input2.task, context);
|
|
81136
|
+
const planResult = await createAndApprovePlan(input2.task, context, saveUsageSnapshot);
|
|
81124
81137
|
if (!planResult)
|
|
81125
81138
|
return;
|
|
81126
81139
|
input2.plan = planResult.plan;
|
|
@@ -81146,8 +81159,9 @@ var epicWorkflow = async (input2, context) => {
|
|
|
81146
81159
|
if (todos.length === 0) {
|
|
81147
81160
|
await addTodoItemsFromPlan(input2.plan, context);
|
|
81148
81161
|
}
|
|
81149
|
-
const commitMessages = await runImplementationLoop(context, input2.plan);
|
|
81162
|
+
const commitMessages = await runImplementationLoop(context, input2.plan, saveUsageSnapshot);
|
|
81150
81163
|
await performFinalReviewAndFix(context, input2.plan, input2.baseBranch ?? undefined);
|
|
81164
|
+
await saveUsageSnapshot();
|
|
81151
81165
|
await tools2.executeCommand({ command: "git", args: ["rm", "-f", ".epic.yml"] });
|
|
81152
81166
|
const statusResult = await tools2.executeCommand({
|
|
81153
81167
|
command: "git",
|
|
@@ -81606,26 +81620,23 @@ async function runEpic(task2, _options, command) {
|
|
|
81606
81620
|
}
|
|
81607
81621
|
epicContext.task = taskInput;
|
|
81608
81622
|
}
|
|
81609
|
-
let
|
|
81623
|
+
let usageMeter;
|
|
81624
|
+
const saveUsageSnapshot = async () => {
|
|
81625
|
+
if (usageMeter) {
|
|
81626
|
+
const currentUsage = usageMeter.usage;
|
|
81627
|
+
if (!epicContext.usages) {
|
|
81628
|
+
epicContext.usages = [];
|
|
81629
|
+
}
|
|
81630
|
+
epicContext.usages.push({ ...currentUsage, timestamp: Date.now() });
|
|
81631
|
+
}
|
|
81632
|
+
};
|
|
81610
81633
|
const workflowInput = {
|
|
81611
81634
|
...epicContext,
|
|
81612
81635
|
async saveEpicContext(context) {
|
|
81613
|
-
if (usageMeter) {
|
|
81614
|
-
const currentUsage = usageMeter.usage;
|
|
81615
|
-
if (!context.usages) {
|
|
81616
|
-
context.usages = [];
|
|
81617
|
-
}
|
|
81618
|
-
if (!usageAppended) {
|
|
81619
|
-
context.usages.push({ ...currentUsage, timestamp: Date.now() });
|
|
81620
|
-
usageAppended = true;
|
|
81621
|
-
} else {
|
|
81622
|
-
context.usages[context.usages.length - 1] = { ...currentUsage, timestamp: Date.now() };
|
|
81623
|
-
}
|
|
81624
|
-
}
|
|
81625
81636
|
await saveEpicContext(context);
|
|
81626
|
-
}
|
|
81637
|
+
},
|
|
81638
|
+
saveUsageSnapshot
|
|
81627
81639
|
};
|
|
81628
|
-
let usageMeter;
|
|
81629
81640
|
await runWorkflow(epicWorkflow, workflowInput, {
|
|
81630
81641
|
commandName: "epic",
|
|
81631
81642
|
command,
|
|
@@ -81698,9 +81709,22 @@ async function runMeta(task2, command) {
|
|
|
81698
81709
|
}
|
|
81699
81710
|
epicContext.task = taskInput;
|
|
81700
81711
|
}
|
|
81712
|
+
let usageMeter;
|
|
81713
|
+
const saveUsageSnapshot = async () => {
|
|
81714
|
+
if (usageMeter) {
|
|
81715
|
+
const currentUsage = usageMeter.usage;
|
|
81716
|
+
if (!epicContext.usages) {
|
|
81717
|
+
epicContext.usages = [];
|
|
81718
|
+
}
|
|
81719
|
+
epicContext.usages.push({ ...currentUsage, timestamp: Date.now() });
|
|
81720
|
+
}
|
|
81721
|
+
};
|
|
81701
81722
|
const workflowInput = {
|
|
81702
81723
|
...epicContext,
|
|
81703
|
-
saveEpicContext
|
|
81724
|
+
async saveEpicContext(context) {
|
|
81725
|
+
await saveEpicContext(context);
|
|
81726
|
+
},
|
|
81727
|
+
saveUsageSnapshot
|
|
81704
81728
|
};
|
|
81705
81729
|
await runWorkflow(metaWorkflow, workflowInput, {
|
|
81706
81730
|
commandName: "meta",
|
|
@@ -81711,7 +81735,10 @@ async function runMeta(task2, command) {
|
|
|
81711
81735
|
...opt,
|
|
81712
81736
|
todoItemStore: new EpicTodoItemStore(workflowInput),
|
|
81713
81737
|
memoryStore: new EpicMemoryStore(workflowInput)
|
|
81714
|
-
})
|
|
81738
|
+
}),
|
|
81739
|
+
onUsageMeterCreated: (meter) => {
|
|
81740
|
+
usageMeter = meter;
|
|
81741
|
+
}
|
|
81715
81742
|
});
|
|
81716
81743
|
}
|
|
81717
81744
|
|