opencara 0.15.1 → 0.15.3
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 +63 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -869,6 +869,23 @@ function buildSystemPrompt(owner, repo, mode = "full") {
|
|
|
869
869
|
const template = mode === "compact" ? COMPACT_SYSTEM_PROMPT_TEMPLATE : FULL_SYSTEM_PROMPT_TEMPLATE;
|
|
870
870
|
return template.replace("{owner}", owner).replace("{repo}", repo);
|
|
871
871
|
}
|
|
872
|
+
var VERDICT_EMOJI = {
|
|
873
|
+
approve: "\u2705",
|
|
874
|
+
request_changes: "\u274C",
|
|
875
|
+
comment: "\u{1F4AC}"
|
|
876
|
+
};
|
|
877
|
+
function buildMetadataHeader(verdict, meta) {
|
|
878
|
+
if (!meta) return "";
|
|
879
|
+
const emoji = VERDICT_EMOJI[verdict] ?? "";
|
|
880
|
+
const lines = [`**Reviewer**: \`${meta.model}/${meta.tool}\``];
|
|
881
|
+
if (meta.githubUsername) {
|
|
882
|
+
lines.push(
|
|
883
|
+
`**Contributors**: [@${meta.githubUsername}](https://github.com/${meta.githubUsername})`
|
|
884
|
+
);
|
|
885
|
+
}
|
|
886
|
+
lines.push(`**Verdict**: ${emoji} ${verdict}`);
|
|
887
|
+
return lines.join("\n") + "\n\n";
|
|
888
|
+
}
|
|
872
889
|
function buildUserMessage(prompt, diffContent, contextBlock) {
|
|
873
890
|
const parts = [prompt];
|
|
874
891
|
if (contextBlock) {
|
|
@@ -963,6 +980,22 @@ var InputTooLargeError = class extends Error {
|
|
|
963
980
|
this.name = "InputTooLargeError";
|
|
964
981
|
}
|
|
965
982
|
};
|
|
983
|
+
function buildSummaryMetadataHeader(verdict, meta) {
|
|
984
|
+
if (!meta) return "";
|
|
985
|
+
const emoji = VERDICT_EMOJI[verdict] ?? "";
|
|
986
|
+
const reviewersList = meta.reviewerModels.map((r) => `\`${r}\``).join(", ");
|
|
987
|
+
const lines = [
|
|
988
|
+
`**Reviewers**: ${reviewersList}`,
|
|
989
|
+
`**Synthesizer**: \`${meta.model}/${meta.tool}\``
|
|
990
|
+
];
|
|
991
|
+
if (meta.githubUsername) {
|
|
992
|
+
lines.push(
|
|
993
|
+
`**Contributors**: [@${meta.githubUsername}](https://github.com/${meta.githubUsername})`
|
|
994
|
+
);
|
|
995
|
+
}
|
|
996
|
+
lines.push(`**Verdict**: ${emoji} ${verdict}`);
|
|
997
|
+
return lines.join("\n") + "\n\n";
|
|
998
|
+
}
|
|
966
999
|
function buildSummarySystemPrompt(owner, repo, reviewCount) {
|
|
967
1000
|
return `You are a senior code reviewer and lead synthesizer for the ${owner}/${repo} repository.
|
|
968
1001
|
|
|
@@ -1060,6 +1093,7 @@ ${userMessage}`;
|
|
|
1060
1093
|
void 0,
|
|
1061
1094
|
deps.codebaseDir ?? void 0
|
|
1062
1095
|
);
|
|
1096
|
+
const { verdict, review } = extractVerdict(result.stdout);
|
|
1063
1097
|
const inputTokens = result.tokensParsed ? 0 : estimateTokens(fullPrompt);
|
|
1064
1098
|
const detail = result.tokenDetail;
|
|
1065
1099
|
const tokenDetail = result.tokensParsed ? detail : {
|
|
@@ -1069,7 +1103,8 @@ ${userMessage}`;
|
|
|
1069
1103
|
parsed: false
|
|
1070
1104
|
};
|
|
1071
1105
|
return {
|
|
1072
|
-
summary:
|
|
1106
|
+
summary: review,
|
|
1107
|
+
verdict,
|
|
1073
1108
|
tokensUsed: result.tokensUsed + inputTokens,
|
|
1074
1109
|
tokensEstimated: !result.tokensParsed,
|
|
1075
1110
|
tokenDetail
|
|
@@ -1692,13 +1727,6 @@ function concatUint8Arrays(chunks, totalLength) {
|
|
|
1692
1727
|
return result;
|
|
1693
1728
|
}
|
|
1694
1729
|
var MAX_DIFF_FETCH_ATTEMPTS = 3;
|
|
1695
|
-
function appendContributorAttribution(text, githubUsername) {
|
|
1696
|
-
if (!githubUsername) return text;
|
|
1697
|
-
return `${text}
|
|
1698
|
-
|
|
1699
|
-
---
|
|
1700
|
-
Contributed by [@${githubUsername}](https://github.com/${githubUsername})`;
|
|
1701
|
-
}
|
|
1702
1730
|
async function pollLoop(client, agentId, reviewDeps, consumptionDeps, agentInfo, logger, agentSession, options) {
|
|
1703
1731
|
const {
|
|
1704
1732
|
pollIntervalMs,
|
|
@@ -1926,6 +1954,7 @@ async function handleTask(client, agentId, task, reviewDeps, consumptionDeps, ag
|
|
|
1926
1954
|
taskReviewDeps,
|
|
1927
1955
|
consumptionDeps,
|
|
1928
1956
|
logger,
|
|
1957
|
+
agentInfo,
|
|
1929
1958
|
routerRelay,
|
|
1930
1959
|
signal,
|
|
1931
1960
|
contextBlock,
|
|
@@ -1945,6 +1974,7 @@ async function handleTask(client, agentId, task, reviewDeps, consumptionDeps, ag
|
|
|
1945
1974
|
taskReviewDeps,
|
|
1946
1975
|
consumptionDeps,
|
|
1947
1976
|
logger,
|
|
1977
|
+
agentInfo,
|
|
1948
1978
|
routerRelay,
|
|
1949
1979
|
signal,
|
|
1950
1980
|
contextBlock,
|
|
@@ -1998,7 +2028,7 @@ async function safeError(client, taskId, agentId, error, logger) {
|
|
|
1998
2028
|
);
|
|
1999
2029
|
}
|
|
2000
2030
|
}
|
|
2001
|
-
async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber, diffContent, prompt, timeoutSeconds, reviewDeps, consumptionDeps, logger, routerRelay, signal, contextBlock, githubUsername) {
|
|
2031
|
+
async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber, diffContent, prompt, timeoutSeconds, reviewDeps, consumptionDeps, logger, agentInfo, routerRelay, signal, contextBlock, githubUsername) {
|
|
2002
2032
|
if (consumptionDeps.usageLimits?.maxTokensPerReview != null && consumptionDeps.usageTracker) {
|
|
2003
2033
|
const estimatedInput = estimateTokens(diffContent + prompt + (contextBlock ?? ""));
|
|
2004
2034
|
const perReviewCheck = consumptionDeps.usageTracker.checkPerReviewLimit(
|
|
@@ -2065,7 +2095,13 @@ async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber,
|
|
|
2065
2095
|
estimated: result.tokensEstimated
|
|
2066
2096
|
};
|
|
2067
2097
|
}
|
|
2068
|
-
const
|
|
2098
|
+
const reviewMeta = {
|
|
2099
|
+
model: agentInfo.model,
|
|
2100
|
+
tool: agentInfo.tool,
|
|
2101
|
+
githubUsername
|
|
2102
|
+
};
|
|
2103
|
+
const headerReview = buildMetadataHeader(verdict, reviewMeta);
|
|
2104
|
+
const sanitizedReview = sanitizeTokens(headerReview + reviewText);
|
|
2069
2105
|
await withRetry(
|
|
2070
2106
|
() => client.post(`/api/tasks/${taskId}/result`, {
|
|
2071
2107
|
agent_id: agentId,
|
|
@@ -2088,7 +2124,8 @@ async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber,
|
|
|
2088
2124
|
logger.log(` ${icons.success} Review submitted (${tokensUsed.toLocaleString()} tokens)`);
|
|
2089
2125
|
logger.log(formatPostReviewStats(consumptionDeps.session));
|
|
2090
2126
|
}
|
|
2091
|
-
async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber, diffContent, prompt, timeoutSeconds, reviews, reviewDeps, consumptionDeps, logger, routerRelay, signal, contextBlock, githubUsername) {
|
|
2127
|
+
async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber, diffContent, prompt, timeoutSeconds, reviews, reviewDeps, consumptionDeps, logger, agentInfo, routerRelay, signal, contextBlock, githubUsername) {
|
|
2128
|
+
const meta = { model: agentInfo.model, tool: agentInfo.tool, githubUsername };
|
|
2092
2129
|
if (reviews.length === 0) {
|
|
2093
2130
|
let reviewText;
|
|
2094
2131
|
let verdict;
|
|
@@ -2146,10 +2183,8 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2146
2183
|
estimated: result.tokensEstimated
|
|
2147
2184
|
};
|
|
2148
2185
|
}
|
|
2149
|
-
const
|
|
2150
|
-
|
|
2151
|
-
githubUsername
|
|
2152
|
-
);
|
|
2186
|
+
const headerSingle = buildMetadataHeader(verdict ?? "comment", meta);
|
|
2187
|
+
const sanitizedReview = sanitizeTokens(headerSingle + reviewText);
|
|
2153
2188
|
await withRetry(
|
|
2154
2189
|
() => client.post(`/api/tasks/${taskId}/result`, {
|
|
2155
2190
|
agent_id: agentId,
|
|
@@ -2183,6 +2218,7 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2183
2218
|
verdict: r.verdict
|
|
2184
2219
|
}));
|
|
2185
2220
|
let summaryText;
|
|
2221
|
+
let summaryVerdict;
|
|
2186
2222
|
let tokensUsed;
|
|
2187
2223
|
let usageOpts;
|
|
2188
2224
|
if (routerRelay) {
|
|
@@ -2201,7 +2237,9 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2201
2237
|
fullPrompt,
|
|
2202
2238
|
timeoutSeconds
|
|
2203
2239
|
);
|
|
2204
|
-
|
|
2240
|
+
const parsed = extractVerdict(response);
|
|
2241
|
+
summaryText = parsed.review;
|
|
2242
|
+
summaryVerdict = parsed.verdict;
|
|
2205
2243
|
tokensUsed = estimateTokens(fullPrompt) + estimateTokens(response);
|
|
2206
2244
|
usageOpts = {
|
|
2207
2245
|
inputTokens: estimateTokens(fullPrompt),
|
|
@@ -2226,6 +2264,7 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2226
2264
|
reviewDeps
|
|
2227
2265
|
);
|
|
2228
2266
|
summaryText = result.summary;
|
|
2267
|
+
summaryVerdict = result.verdict;
|
|
2229
2268
|
tokensUsed = result.tokensUsed;
|
|
2230
2269
|
usageOpts = {
|
|
2231
2270
|
inputTokens: result.tokenDetail.input,
|
|
@@ -2234,15 +2273,18 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2234
2273
|
estimated: result.tokensEstimated
|
|
2235
2274
|
};
|
|
2236
2275
|
}
|
|
2237
|
-
const
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2276
|
+
const summaryMeta = {
|
|
2277
|
+
...meta,
|
|
2278
|
+
reviewerModels: summaryReviews.map((r) => `${r.model}/${r.tool}`)
|
|
2279
|
+
};
|
|
2280
|
+
const headerSummary = buildSummaryMetadataHeader(summaryVerdict, summaryMeta);
|
|
2281
|
+
const sanitizedSummary = sanitizeTokens(headerSummary + summaryText);
|
|
2241
2282
|
await withRetry(
|
|
2242
2283
|
() => client.post(`/api/tasks/${taskId}/result`, {
|
|
2243
2284
|
agent_id: agentId,
|
|
2244
2285
|
type: "summary",
|
|
2245
2286
|
review_text: sanitizedSummary,
|
|
2287
|
+
verdict: summaryVerdict,
|
|
2246
2288
|
tokens_used: tokensUsed
|
|
2247
2289
|
}),
|
|
2248
2290
|
{ maxAttempts: 3 },
|
|
@@ -2529,7 +2571,7 @@ agentCommand.command("start").description("Start agents in polling mode").option
|
|
|
2529
2571
|
});
|
|
2530
2572
|
|
|
2531
2573
|
// src/index.ts
|
|
2532
|
-
var program = new Command2().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version("0.15.
|
|
2574
|
+
var program = new Command2().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version("0.15.3");
|
|
2533
2575
|
program.addCommand(agentCommand);
|
|
2534
2576
|
program.action(() => {
|
|
2535
2577
|
startAgentRouter();
|