opencara 0.23.2 → 0.23.4
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 +99 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3754,7 +3754,7 @@ async function executeIssueReviewTask(client, agentId, task, deps, timeoutSecond
|
|
|
3754
3754
|
}
|
|
3755
3755
|
|
|
3756
3756
|
// src/implement.ts
|
|
3757
|
-
import { execFileSync as execFileSync6 } from "child_process";
|
|
3757
|
+
import { execFileSync as execFileSync6, spawn as spawn2 } from "child_process";
|
|
3758
3758
|
import * as fs8 from "fs";
|
|
3759
3759
|
import * as path8 from "path";
|
|
3760
3760
|
var TIMEOUT_SAFETY_MARGIN_MS6 = 3e4;
|
|
@@ -3869,10 +3869,7 @@ function checkoutForImplement(owner, repo, issueNumber, branchName, baseDir) {
|
|
|
3869
3869
|
}
|
|
3870
3870
|
}
|
|
3871
3871
|
const credArgs = ghAvailable ? ["-c", `credential.helper=${GH_CREDENTIAL_HELPER2}`] : [];
|
|
3872
|
-
gitExec2(
|
|
3873
|
-
[...credArgs, "fetch", "--force", "origin", "+refs/heads/*:refs/heads/*"],
|
|
3874
|
-
bareRepoPath
|
|
3875
|
-
);
|
|
3872
|
+
gitExec2([...credArgs, "fetch", "--force", "origin", "+refs/heads/*:refs/heads/*"], bareRepoPath);
|
|
3876
3873
|
let defaultBranch;
|
|
3877
3874
|
try {
|
|
3878
3875
|
defaultBranch = gitExec2(
|
|
@@ -3956,6 +3953,57 @@ function createPR(worktreePath, issueNumber, issueTitle, summary, branchName) {
|
|
|
3956
3953
|
const prNumber = parseInt(prNumberMatch[1], 10);
|
|
3957
3954
|
return { prNumber, prUrl };
|
|
3958
3955
|
}
|
|
3956
|
+
function isAgenticCommand(commandTemplate) {
|
|
3957
|
+
return commandTemplate.includes("${PROMPT}") && !commandTemplate.includes("--print");
|
|
3958
|
+
}
|
|
3959
|
+
function executeAgentic(commandTemplate, prompt2, timeoutMs, cwd, signal) {
|
|
3960
|
+
const allVars = { PROMPT: prompt2, CODEBASE_DIR: cwd };
|
|
3961
|
+
const { command, args } = parseCommandTemplate(commandTemplate, allVars);
|
|
3962
|
+
return new Promise((resolve2, reject) => {
|
|
3963
|
+
if (signal?.aborted) {
|
|
3964
|
+
reject(new ToolTimeoutError("Tool execution aborted"));
|
|
3965
|
+
return;
|
|
3966
|
+
}
|
|
3967
|
+
const child = spawn2(command, args, {
|
|
3968
|
+
stdio: "inherit",
|
|
3969
|
+
cwd
|
|
3970
|
+
});
|
|
3971
|
+
let settled = false;
|
|
3972
|
+
const timer = setTimeout(() => {
|
|
3973
|
+
if (!settled) {
|
|
3974
|
+
child.kill("SIGTERM");
|
|
3975
|
+
setTimeout(() => {
|
|
3976
|
+
if (!settled) child.kill("SIGKILL");
|
|
3977
|
+
}, 5e3);
|
|
3978
|
+
}
|
|
3979
|
+
}, timeoutMs);
|
|
3980
|
+
let onAbort;
|
|
3981
|
+
if (signal) {
|
|
3982
|
+
onAbort = () => {
|
|
3983
|
+
if (!settled) child.kill("SIGTERM");
|
|
3984
|
+
};
|
|
3985
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
3986
|
+
}
|
|
3987
|
+
child.on("error", (err) => {
|
|
3988
|
+
clearTimeout(timer);
|
|
3989
|
+
if (onAbort && signal) signal.removeEventListener("abort", onAbort);
|
|
3990
|
+
if (settled) return;
|
|
3991
|
+
settled = true;
|
|
3992
|
+
reject(err);
|
|
3993
|
+
});
|
|
3994
|
+
child.on("close", (code, sig) => {
|
|
3995
|
+
clearTimeout(timer);
|
|
3996
|
+
if (onAbort && signal) signal.removeEventListener("abort", onAbort);
|
|
3997
|
+
if (settled) return;
|
|
3998
|
+
settled = true;
|
|
3999
|
+
if (sig === "SIGTERM" || sig === "SIGKILL") {
|
|
4000
|
+
reject(new ToolTimeoutError(`Tool timed out after ${Math.round(timeoutMs / 1e3)}s`));
|
|
4001
|
+
return;
|
|
4002
|
+
}
|
|
4003
|
+
resolve2({ exitCode: code ?? 1 });
|
|
4004
|
+
});
|
|
4005
|
+
});
|
|
4006
|
+
}
|
|
3959
4007
|
async function executeImplement(task, worktreePath, deps, timeoutSeconds, signal, runTool = executeTool) {
|
|
3960
4008
|
const timeoutMs = timeoutSeconds * 1e3;
|
|
3961
4009
|
if (timeoutMs <= TIMEOUT_SAFETY_MARGIN_MS6) {
|
|
@@ -3963,6 +4011,25 @@ async function executeImplement(task, worktreePath, deps, timeoutSeconds, signal
|
|
|
3963
4011
|
}
|
|
3964
4012
|
const effectiveTimeout = timeoutMs - TIMEOUT_SAFETY_MARGIN_MS6;
|
|
3965
4013
|
const prompt2 = buildImplementPrompt(task);
|
|
4014
|
+
if (isAgenticCommand(deps.commandTemplate)) {
|
|
4015
|
+
const result2 = await executeAgentic(
|
|
4016
|
+
deps.commandTemplate,
|
|
4017
|
+
prompt2,
|
|
4018
|
+
effectiveTimeout,
|
|
4019
|
+
worktreePath,
|
|
4020
|
+
signal
|
|
4021
|
+
);
|
|
4022
|
+
return {
|
|
4023
|
+
output: {
|
|
4024
|
+
summary: result2.exitCode === 0 ? "Implementation completed" : "Implementation failed",
|
|
4025
|
+
filesChanged: []
|
|
4026
|
+
},
|
|
4027
|
+
tokensUsed: 0,
|
|
4028
|
+
tokensEstimated: true,
|
|
4029
|
+
tokenDetail: { input: 0, output: 0, total: 0, parsed: false },
|
|
4030
|
+
agentic: true
|
|
4031
|
+
};
|
|
4032
|
+
}
|
|
3966
4033
|
const result = await runTool(
|
|
3967
4034
|
deps.commandTemplate,
|
|
3968
4035
|
prompt2,
|
|
@@ -3983,7 +4050,8 @@ async function executeImplement(task, worktreePath, deps, timeoutSeconds, signal
|
|
|
3983
4050
|
output,
|
|
3984
4051
|
tokensUsed: result.tokensUsed + inputTokens,
|
|
3985
4052
|
tokensEstimated: !result.tokensParsed,
|
|
3986
|
-
tokenDetail
|
|
4053
|
+
tokenDetail,
|
|
4054
|
+
agentic: false
|
|
3987
4055
|
};
|
|
3988
4056
|
}
|
|
3989
4057
|
async function executeImplementTask(client, agentId, task, deps, timeoutSeconds, logger, signal, runTool, role = "implement", gitOps = { checkoutForImplement, commitAndPush, createPR, cleanupImplementWorktree }) {
|
|
@@ -4014,6 +4082,27 @@ async function executeImplementTask(client, agentId, task, deps, timeoutSeconds,
|
|
|
4014
4082
|
runTool
|
|
4015
4083
|
);
|
|
4016
4084
|
logger.log(` AI completed (${aiResult.tokensUsed.toLocaleString()} tokens)`);
|
|
4085
|
+
if (aiResult.agentic) {
|
|
4086
|
+
logger.log(" Agentic mode \u2014 AI handled commit/push/PR/review/merge");
|
|
4087
|
+
try {
|
|
4088
|
+
await client.post(`/api/tasks/${task.task_id}/result`, {
|
|
4089
|
+
agent_id: agentId,
|
|
4090
|
+
type: role,
|
|
4091
|
+
review_text: sanitizeTokens(aiResult.output.summary),
|
|
4092
|
+
tokens_used: aiResult.tokensUsed
|
|
4093
|
+
});
|
|
4094
|
+
logger.log(" Result submitted");
|
|
4095
|
+
} catch {
|
|
4096
|
+
logger.log(
|
|
4097
|
+
" Result submission skipped (claim may have expired \u2014 normal for agentic mode)"
|
|
4098
|
+
);
|
|
4099
|
+
}
|
|
4100
|
+
return {
|
|
4101
|
+
tokensUsed: aiResult.tokensUsed,
|
|
4102
|
+
tokensEstimated: aiResult.tokensEstimated,
|
|
4103
|
+
tokenDetail: aiResult.tokenDetail
|
|
4104
|
+
};
|
|
4105
|
+
}
|
|
4017
4106
|
let filesChanged = 0;
|
|
4018
4107
|
let uncommitted = 0;
|
|
4019
4108
|
try {
|
|
@@ -5574,7 +5663,7 @@ function sleep2(ms, signal) {
|
|
|
5574
5663
|
async function startAgent(agentId, platformUrl, agentInfo, reviewDeps, consumptionDeps, options) {
|
|
5575
5664
|
const client = new ApiClient(platformUrl, {
|
|
5576
5665
|
authToken: options?.authToken,
|
|
5577
|
-
cliVersion: "0.23.
|
|
5666
|
+
cliVersion: "0.23.4",
|
|
5578
5667
|
versionOverride: options?.versionOverride,
|
|
5579
5668
|
onTokenRefresh: options?.onTokenRefresh
|
|
5580
5669
|
});
|
|
@@ -5860,7 +5949,7 @@ async function startBatchAgents(config, agents, pollIntervalMs, oauthToken, opti
|
|
|
5860
5949
|
const { versionOverride, verbose, instancesOverride, agentOwner, userOrgs } = options;
|
|
5861
5950
|
const client = new ApiClient(config.platformUrl, {
|
|
5862
5951
|
authToken: oauthToken,
|
|
5863
|
-
cliVersion: "0.23.
|
|
5952
|
+
cliVersion: "0.23.4",
|
|
5864
5953
|
versionOverride,
|
|
5865
5954
|
onTokenRefresh: () => getValidToken(config.platformUrl, { configPath: config.authFile })
|
|
5866
5955
|
});
|
|
@@ -6203,7 +6292,7 @@ agentCommand.command("start").description("Start agents in polling mode").option
|
|
|
6203
6292
|
}
|
|
6204
6293
|
config = loadConfig();
|
|
6205
6294
|
}
|
|
6206
|
-
console.log(formatVersionBanner("0.23.
|
|
6295
|
+
console.log(formatVersionBanner("0.23.4", "219b329"));
|
|
6207
6296
|
if (config.agents && config.agents.length > 0) {
|
|
6208
6297
|
const toolEntries = config.agents.map((a) => ({
|
|
6209
6298
|
tool: a.tool,
|
|
@@ -7026,7 +7115,7 @@ var statusCommand = new Command4("status").description("Show agent config, conne
|
|
|
7026
7115
|
});
|
|
7027
7116
|
|
|
7028
7117
|
// src/index.ts
|
|
7029
|
-
var program = new Command5().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version(`${"0.23.
|
|
7118
|
+
var program = new Command5().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version(`${"0.23.4"} (${"219b329"})`);
|
|
7030
7119
|
program.addCommand(agentCommand);
|
|
7031
7120
|
program.addCommand(authCommand());
|
|
7032
7121
|
program.addCommand(dedupCommand());
|