opencara 0.23.11 → 0.23.13

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.
Files changed (2) hide show
  1. package/dist/index.js +52 -10
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4576,21 +4576,39 @@ function buildBatchPollRequest(agents) {
4576
4576
  });
4577
4577
  return { agents: batchAgents };
4578
4578
  }
4579
- function filterTasksForAgent(tasks, agent, maxDiffSizeKb, diffFailCounts, maxDiffFetchAttempts = 3, accessibleRepos) {
4579
+ function filterTasksForAgent(tasks, agent, maxDiffSizeKb, diffFailCounts, maxDiffFetchAttempts = 3, accessibleRepos, log) {
4580
4580
  return tasks.filter((t) => {
4581
- if (accessibleRepos && !accessibleRepos.has(`${t.owner}/${t.repo}`)) {
4581
+ const repo = `${t.owner}/${t.repo}`;
4582
+ if (accessibleRepos && !accessibleRepos.has(repo)) {
4583
+ log?.(
4584
+ `Skipping task ${t.task_id.slice(0, 8)}\u2026 (${repo} PR#${t.pr_number}) \u2014 repo not in accessible set`
4585
+ );
4582
4586
  return false;
4583
4587
  }
4584
4588
  if (agent.repoConfig && !isRepoAllowed(agent.repoConfig, t.owner, t.repo, agent.agentOwner, agent.userOrgs)) {
4589
+ log?.(
4590
+ `Skipping task ${t.task_id.slice(0, 8)}\u2026 (${repo} PR#${t.pr_number}) \u2014 repo not allowed by config (mode=${agent.repoConfig.mode})`
4591
+ );
4585
4592
  return false;
4586
4593
  }
4587
4594
  if (agent.synthesizeRepos && !isRepoAllowed(agent.synthesizeRepos, t.owner, t.repo, agent.agentOwner, agent.userOrgs)) {
4595
+ log?.(
4596
+ `Skipping task ${t.task_id.slice(0, 8)}\u2026 (${repo} PR#${t.pr_number}) \u2014 repo not allowed by synthesize_repos config`
4597
+ );
4588
4598
  return false;
4589
4599
  }
4590
- if (maxDiffSizeKb && t.diff_size != null && t.diff_size * ESTIMATED_BYTES_PER_DIFF_LINE / 1024 > maxDiffSizeKb) {
4600
+ const isExplicitlyListed = agent.repoConfig?.list?.includes(repo) ?? false;
4601
+ if (!isExplicitlyListed && maxDiffSizeKb && t.diff_size != null && t.diff_size * ESTIMATED_BYTES_PER_DIFF_LINE / 1024 > maxDiffSizeKb) {
4602
+ const estimatedKb = Math.round(t.diff_size * ESTIMATED_BYTES_PER_DIFF_LINE / 1024);
4603
+ log?.(
4604
+ `Skipping task ${t.task_id.slice(0, 8)}\u2026 (${repo} PR#${t.pr_number}) \u2014 estimated diff ${estimatedKb}KB exceeds max_diff_size_kb (${maxDiffSizeKb}KB)`
4605
+ );
4591
4606
  return false;
4592
4607
  }
4593
4608
  if (diffFailCounts && (diffFailCounts.get(t.task_id) ?? 0) >= maxDiffFetchAttempts) {
4609
+ log?.(
4610
+ `Skipping task ${t.task_id.slice(0, 8)}\u2026 (${repo} PR#${t.pr_number}) \u2014 diff fetch failed ${maxDiffFetchAttempts} times`
4611
+ );
4594
4612
  return false;
4595
4613
  }
4596
4614
  return true;
@@ -4807,6 +4825,9 @@ function concatUint8Arrays(chunks, totalLength) {
4807
4825
  return result;
4808
4826
  }
4809
4827
  var MAX_DIFF_FETCH_ATTEMPTS = 3;
4828
+ var WEIGHT_PENALTY_FACTOR = 0.5;
4829
+ var MIN_DISPATCH_WEIGHT = 0.1;
4830
+ var WEIGHT_RECOVERY = 0.25;
4810
4831
  async function pollLoop(client, agentId, reviewDeps, consumptionDeps, agentInfo, logger, agentSession, options) {
4811
4832
  const {
4812
4833
  pollIntervalMs,
@@ -5677,7 +5698,7 @@ function sleep2(ms, signal) {
5677
5698
  async function startAgent(agentId, platformUrl, agentInfo, reviewDeps, consumptionDeps, options) {
5678
5699
  const client = new ApiClient(platformUrl, {
5679
5700
  authToken: options?.authToken,
5680
- cliVersion: "0.23.11",
5701
+ cliVersion: "0.23.13",
5681
5702
  versionOverride: options?.versionOverride,
5682
5703
  onTokenRefresh: options?.onTokenRefresh
5683
5704
  });
@@ -5852,7 +5873,16 @@ async function batchPollLoop(client, agentStates, options) {
5852
5873
  const response = await client.post("/api/tasks/poll/batch", request);
5853
5874
  consecutiveAuthErrors = 0;
5854
5875
  consecutiveErrors = 0;
5855
- for (const state of availableStates) {
5876
+ const eligibleStates = availableStates.filter((s) => s.weight >= MIN_DISPATCH_WEIGHT);
5877
+ const dispatchOrder = eligibleStates.map((s) => ({ state: s, score: s.weight * Math.random() })).sort((a, b) => b.score - a.score).map((e) => e.state);
5878
+ for (const s of availableStates) {
5879
+ if (s.weight < MIN_DISPATCH_WEIGHT) {
5880
+ s.logger.logWarn(
5881
+ `${icons.warn} Agent paused (weight ${s.weight.toFixed(2)} < ${MIN_DISPATCH_WEIGHT})`
5882
+ );
5883
+ }
5884
+ }
5885
+ for (const state of dispatchOrder) {
5856
5886
  const agentName = state.descriptor.name;
5857
5887
  const pollResponse = response.assignments[agentName];
5858
5888
  if (!pollResponse || pollResponse.tasks.length === 0) continue;
@@ -5862,7 +5892,8 @@ async function batchPollLoop(client, agentStates, options) {
5862
5892
  state.reviewDeps.maxDiffSizeKb,
5863
5893
  state.diffFailCounts,
5864
5894
  MAX_DIFF_FETCH_ATTEMPTS,
5865
- accessibleRepos
5895
+ accessibleRepos,
5896
+ (msg) => state.logger.logWarn(`${icons.warn} ${msg}`)
5866
5897
  );
5867
5898
  const task = eligible[0];
5868
5899
  if (!task) continue;
@@ -5896,10 +5927,20 @@ async function batchPollLoop(client, agentStates, options) {
5896
5927
  ` Skipping task ${task.task_id} after ${count} diff fetch failures`
5897
5928
  );
5898
5929
  }
5930
+ state.weight = Math.max(0, state.weight * WEIGHT_PENALTY_FACTOR);
5931
+ state.logger.logWarn(
5932
+ `${icons.warn} Weight reduced to ${state.weight.toFixed(2)} after diff fetch failure`
5933
+ );
5934
+ } else {
5935
+ state.weight = Math.min(1, state.weight + WEIGHT_RECOVERY);
5899
5936
  }
5900
5937
  } catch (err) {
5901
5938
  logError(`${icons.error} Task handler failed: ${err.message}`);
5902
5939
  consecutiveErrors++;
5940
+ state.weight = Math.max(0, state.weight * WEIGHT_PENALTY_FACTOR);
5941
+ state.logger.logWarn(
5942
+ `${icons.warn} Weight reduced to ${state.weight.toFixed(2)} after task error`
5943
+ );
5903
5944
  } finally {
5904
5945
  busyAgents.delete(state);
5905
5946
  if (state.cleanupTracker) {
@@ -5973,7 +6014,7 @@ async function startBatchAgents(config, agents, pollIntervalMs, oauthToken, opti
5973
6014
  const { versionOverride, verbose, instancesOverride, agentOwner, userOrgs } = options;
5974
6015
  const client = new ApiClient(config.platformUrl, {
5975
6016
  authToken: oauthToken,
5976
- cliVersion: "0.23.11",
6017
+ cliVersion: "0.23.13",
5977
6018
  versionOverride,
5978
6019
  onTokenRefresh: () => getValidToken(config.platformUrl, { configPath: config.authFile })
5979
6020
  });
@@ -6052,7 +6093,8 @@ async function startBatchAgents(config, agents, pollIntervalMs, oauthToken, opti
6052
6093
  routerRelay,
6053
6094
  cleanupTracker,
6054
6095
  verbose,
6055
- diffFailCounts: /* @__PURE__ */ new Map()
6096
+ diffFailCounts: /* @__PURE__ */ new Map(),
6097
+ weight: 1
6056
6098
  });
6057
6099
  }
6058
6100
  }
@@ -6318,7 +6360,7 @@ agentCommand.command("start").description("Start agents in polling mode").option
6318
6360
  }
6319
6361
  config = loadConfig();
6320
6362
  }
6321
- console.log(formatVersionBanner("0.23.11", "1ab6f70"));
6363
+ console.log(formatVersionBanner("0.23.13", "791981e"));
6322
6364
  if (config.agents && config.agents.length > 0) {
6323
6365
  const toolEntries = config.agents.map((a) => ({
6324
6366
  tool: a.tool,
@@ -7140,7 +7182,7 @@ var statusCommand = new Command4("status").description("Show agent config, conne
7140
7182
  });
7141
7183
 
7142
7184
  // src/index.ts
7143
- var program = new Command5().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version(`${"0.23.11"} (${"1ab6f70"})`);
7185
+ var program = new Command5().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version(`${"0.23.13"} (${"791981e"})`);
7144
7186
  program.addCommand(agentCommand);
7145
7187
  program.addCommand(authCommand());
7146
7188
  program.addCommand(dedupCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencara",
3
- "version": "0.23.11",
3
+ "version": "0.23.13",
4
4
  "description": "Distributed AI code review agent — poll, review, and submit PR reviews using your own AI tools",
5
5
  "type": "module",
6
6
  "license": "MIT",