opencara 0.15.1 → 0.15.2
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 +58 -24
- 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) {
|
|
@@ -928,6 +945,7 @@ ${userMessage}`;
|
|
|
928
945
|
deps.codebaseDir ?? void 0
|
|
929
946
|
);
|
|
930
947
|
const { verdict, review } = extractVerdict(result.stdout);
|
|
948
|
+
const header = buildMetadataHeader(verdict, req.meta);
|
|
931
949
|
const inputTokens = result.tokensParsed ? 0 : estimateTokens(fullPrompt);
|
|
932
950
|
const detail = result.tokenDetail;
|
|
933
951
|
const tokenDetail = result.tokensParsed ? detail : {
|
|
@@ -937,7 +955,7 @@ ${userMessage}`;
|
|
|
937
955
|
parsed: false
|
|
938
956
|
};
|
|
939
957
|
return {
|
|
940
|
-
review,
|
|
958
|
+
review: header + review,
|
|
941
959
|
verdict,
|
|
942
960
|
tokensUsed: result.tokensUsed + inputTokens,
|
|
943
961
|
tokensEstimated: !result.tokensParsed,
|
|
@@ -963,6 +981,22 @@ var InputTooLargeError = class extends Error {
|
|
|
963
981
|
this.name = "InputTooLargeError";
|
|
964
982
|
}
|
|
965
983
|
};
|
|
984
|
+
function buildSummaryMetadataHeader(verdict, meta) {
|
|
985
|
+
if (!meta) return "";
|
|
986
|
+
const emoji = VERDICT_EMOJI[verdict] ?? "";
|
|
987
|
+
const reviewersList = meta.reviewerModels.map((r) => `\`${r}\``).join(", ");
|
|
988
|
+
const lines = [
|
|
989
|
+
`**Reviewers**: ${reviewersList}`,
|
|
990
|
+
`**Synthesizer**: \`${meta.model}/${meta.tool}\``
|
|
991
|
+
];
|
|
992
|
+
if (meta.githubUsername) {
|
|
993
|
+
lines.push(
|
|
994
|
+
`**Contributors**: [@${meta.githubUsername}](https://github.com/${meta.githubUsername})`
|
|
995
|
+
);
|
|
996
|
+
}
|
|
997
|
+
lines.push(`**Verdict**: ${emoji} ${verdict}`);
|
|
998
|
+
return lines.join("\n") + "\n\n";
|
|
999
|
+
}
|
|
966
1000
|
function buildSummarySystemPrompt(owner, repo, reviewCount) {
|
|
967
1001
|
return `You are a senior code reviewer and lead synthesizer for the ${owner}/${repo} repository.
|
|
968
1002
|
|
|
@@ -1042,6 +1076,10 @@ async function executeSummary(req, deps, runTool = executeTool) {
|
|
|
1042
1076
|
abortController.abort();
|
|
1043
1077
|
}, effectiveTimeout);
|
|
1044
1078
|
try {
|
|
1079
|
+
const summaryMeta = req.meta ? {
|
|
1080
|
+
...req.meta,
|
|
1081
|
+
reviewerModels: req.reviews.map((r) => `${r.model}/${r.tool}`)
|
|
1082
|
+
} : void 0;
|
|
1045
1083
|
const systemPrompt = buildSummarySystemPrompt(req.owner, req.repo, req.reviews.length);
|
|
1046
1084
|
const userMessage = buildSummaryUserMessage(
|
|
1047
1085
|
req.prompt,
|
|
@@ -1060,6 +1098,8 @@ ${userMessage}`;
|
|
|
1060
1098
|
void 0,
|
|
1061
1099
|
deps.codebaseDir ?? void 0
|
|
1062
1100
|
);
|
|
1101
|
+
const { verdict, review } = extractVerdict(result.stdout);
|
|
1102
|
+
const header = buildSummaryMetadataHeader(verdict, summaryMeta);
|
|
1063
1103
|
const inputTokens = result.tokensParsed ? 0 : estimateTokens(fullPrompt);
|
|
1064
1104
|
const detail = result.tokenDetail;
|
|
1065
1105
|
const tokenDetail = result.tokensParsed ? detail : {
|
|
@@ -1069,7 +1109,7 @@ ${userMessage}`;
|
|
|
1069
1109
|
parsed: false
|
|
1070
1110
|
};
|
|
1071
1111
|
return {
|
|
1072
|
-
summary:
|
|
1112
|
+
summary: header + review,
|
|
1073
1113
|
tokensUsed: result.tokensUsed + inputTokens,
|
|
1074
1114
|
tokensEstimated: !result.tokensParsed,
|
|
1075
1115
|
tokenDetail
|
|
@@ -1692,13 +1732,6 @@ function concatUint8Arrays(chunks, totalLength) {
|
|
|
1692
1732
|
return result;
|
|
1693
1733
|
}
|
|
1694
1734
|
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
1735
|
async function pollLoop(client, agentId, reviewDeps, consumptionDeps, agentInfo, logger, agentSession, options) {
|
|
1703
1736
|
const {
|
|
1704
1737
|
pollIntervalMs,
|
|
@@ -1926,6 +1959,7 @@ async function handleTask(client, agentId, task, reviewDeps, consumptionDeps, ag
|
|
|
1926
1959
|
taskReviewDeps,
|
|
1927
1960
|
consumptionDeps,
|
|
1928
1961
|
logger,
|
|
1962
|
+
agentInfo,
|
|
1929
1963
|
routerRelay,
|
|
1930
1964
|
signal,
|
|
1931
1965
|
contextBlock,
|
|
@@ -1945,6 +1979,7 @@ async function handleTask(client, agentId, task, reviewDeps, consumptionDeps, ag
|
|
|
1945
1979
|
taskReviewDeps,
|
|
1946
1980
|
consumptionDeps,
|
|
1947
1981
|
logger,
|
|
1982
|
+
agentInfo,
|
|
1948
1983
|
routerRelay,
|
|
1949
1984
|
signal,
|
|
1950
1985
|
contextBlock,
|
|
@@ -1998,7 +2033,7 @@ async function safeError(client, taskId, agentId, error, logger) {
|
|
|
1998
2033
|
);
|
|
1999
2034
|
}
|
|
2000
2035
|
}
|
|
2001
|
-
async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber, diffContent, prompt, timeoutSeconds, reviewDeps, consumptionDeps, logger, routerRelay, signal, contextBlock, githubUsername) {
|
|
2036
|
+
async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber, diffContent, prompt, timeoutSeconds, reviewDeps, consumptionDeps, logger, agentInfo, routerRelay, signal, contextBlock, githubUsername) {
|
|
2002
2037
|
if (consumptionDeps.usageLimits?.maxTokensPerReview != null && consumptionDeps.usageTracker) {
|
|
2003
2038
|
const estimatedInput = estimateTokens(diffContent + prompt + (contextBlock ?? ""));
|
|
2004
2039
|
const perReviewCheck = consumptionDeps.usageTracker.checkPerReviewLimit(
|
|
@@ -2041,6 +2076,7 @@ async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber,
|
|
|
2041
2076
|
};
|
|
2042
2077
|
} else {
|
|
2043
2078
|
logger.log(` ${icons.running} Executing review: ${reviewDeps.commandTemplate}`);
|
|
2079
|
+
const meta = { model: agentInfo.model, tool: agentInfo.tool, githubUsername };
|
|
2044
2080
|
const result = await executeReview(
|
|
2045
2081
|
{
|
|
2046
2082
|
taskId,
|
|
@@ -2051,7 +2087,8 @@ async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber,
|
|
|
2051
2087
|
prNumber,
|
|
2052
2088
|
timeout: timeoutSeconds,
|
|
2053
2089
|
reviewMode: "full",
|
|
2054
|
-
contextBlock
|
|
2090
|
+
contextBlock,
|
|
2091
|
+
meta
|
|
2055
2092
|
},
|
|
2056
2093
|
reviewDeps
|
|
2057
2094
|
);
|
|
@@ -2065,7 +2102,7 @@ async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber,
|
|
|
2065
2102
|
estimated: result.tokensEstimated
|
|
2066
2103
|
};
|
|
2067
2104
|
}
|
|
2068
|
-
const sanitizedReview =
|
|
2105
|
+
const sanitizedReview = sanitizeTokens(reviewText);
|
|
2069
2106
|
await withRetry(
|
|
2070
2107
|
() => client.post(`/api/tasks/${taskId}/result`, {
|
|
2071
2108
|
agent_id: agentId,
|
|
@@ -2088,7 +2125,8 @@ async function executeReviewTask(client, agentId, taskId, owner, repo, prNumber,
|
|
|
2088
2125
|
logger.log(` ${icons.success} Review submitted (${tokensUsed.toLocaleString()} tokens)`);
|
|
2089
2126
|
logger.log(formatPostReviewStats(consumptionDeps.session));
|
|
2090
2127
|
}
|
|
2091
|
-
async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber, diffContent, prompt, timeoutSeconds, reviews, reviewDeps, consumptionDeps, logger, routerRelay, signal, contextBlock, githubUsername) {
|
|
2128
|
+
async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber, diffContent, prompt, timeoutSeconds, reviews, reviewDeps, consumptionDeps, logger, agentInfo, routerRelay, signal, contextBlock, githubUsername) {
|
|
2129
|
+
const meta = { model: agentInfo.model, tool: agentInfo.tool, githubUsername };
|
|
2092
2130
|
if (reviews.length === 0) {
|
|
2093
2131
|
let reviewText;
|
|
2094
2132
|
let verdict;
|
|
@@ -2132,7 +2170,8 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2132
2170
|
prNumber,
|
|
2133
2171
|
timeout: timeoutSeconds,
|
|
2134
2172
|
reviewMode: "full",
|
|
2135
|
-
contextBlock
|
|
2173
|
+
contextBlock,
|
|
2174
|
+
meta
|
|
2136
2175
|
},
|
|
2137
2176
|
reviewDeps
|
|
2138
2177
|
);
|
|
@@ -2146,10 +2185,7 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2146
2185
|
estimated: result.tokensEstimated
|
|
2147
2186
|
};
|
|
2148
2187
|
}
|
|
2149
|
-
const sanitizedReview =
|
|
2150
|
-
sanitizeTokens(reviewText),
|
|
2151
|
-
githubUsername
|
|
2152
|
-
);
|
|
2188
|
+
const sanitizedReview = sanitizeTokens(reviewText);
|
|
2153
2189
|
await withRetry(
|
|
2154
2190
|
() => client.post(`/api/tasks/${taskId}/result`, {
|
|
2155
2191
|
agent_id: agentId,
|
|
@@ -2221,7 +2257,8 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2221
2257
|
prNumber,
|
|
2222
2258
|
timeout: timeoutSeconds,
|
|
2223
2259
|
diffContent,
|
|
2224
|
-
contextBlock
|
|
2260
|
+
contextBlock,
|
|
2261
|
+
meta
|
|
2225
2262
|
},
|
|
2226
2263
|
reviewDeps
|
|
2227
2264
|
);
|
|
@@ -2234,10 +2271,7 @@ async function executeSummaryTask(client, agentId, taskId, owner, repo, prNumber
|
|
|
2234
2271
|
estimated: result.tokensEstimated
|
|
2235
2272
|
};
|
|
2236
2273
|
}
|
|
2237
|
-
const sanitizedSummary =
|
|
2238
|
-
sanitizeTokens(summaryText),
|
|
2239
|
-
githubUsername
|
|
2240
|
-
);
|
|
2274
|
+
const sanitizedSummary = sanitizeTokens(summaryText);
|
|
2241
2275
|
await withRetry(
|
|
2242
2276
|
() => client.post(`/api/tasks/${taskId}/result`, {
|
|
2243
2277
|
agent_id: agentId,
|
|
@@ -2529,7 +2563,7 @@ agentCommand.command("start").description("Start agents in polling mode").option
|
|
|
2529
2563
|
});
|
|
2530
2564
|
|
|
2531
2565
|
// src/index.ts
|
|
2532
|
-
var program = new Command2().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version("0.15.
|
|
2566
|
+
var program = new Command2().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version("0.15.2");
|
|
2533
2567
|
program.addCommand(agentCommand);
|
|
2534
2568
|
program.action(() => {
|
|
2535
2569
|
startAgentRouter();
|