opencara 0.23.8 → 0.23.10

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 +58 -19
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -562,6 +562,15 @@ function ensureConfigDir() {
562
562
  var DEFAULT_MAX_DIFF_SIZE_KB = 100;
563
563
  var DEFAULT_MAX_CONSECUTIVE_ERRORS = 10;
564
564
  var DEFAULT_MAX_REPO_SIZE_MB = 100;
565
+ var DEFAULT_COMMAND_TEST_TIMEOUT_MS = 1e4;
566
+ function parseDurationMs(value) {
567
+ if (typeof value !== "string") return null;
568
+ const secMatch = value.match(/^(\d+)s$/);
569
+ if (secMatch) return parseInt(secMatch[1], 10) * 1e3;
570
+ const minMatch = value.match(/^(\d+)m$/);
571
+ if (minMatch) return parseInt(minMatch[1], 10) * 6e4;
572
+ return null;
573
+ }
565
574
  var VALID_REPO_MODES = ["public", "private", "whitelist", "blacklist"];
566
575
  var REPO_PATTERN = /^[^/]+\/[^/]+$/;
567
576
  var REPO_MODE_ALIASES = {
@@ -797,6 +806,7 @@ function loadConfig() {
797
806
  maxRepoSizeMb: DEFAULT_MAX_REPO_SIZE_MB,
798
807
  codebaseDir: null,
799
808
  codebaseTtl: null,
809
+ commandTestTimeoutMs: DEFAULT_COMMAND_TEST_TIMEOUT_MS,
800
810
  agentCommand: null,
801
811
  agents: null,
802
812
  usageLimits: {
@@ -855,6 +865,23 @@ function loadConfig() {
855
865
  maxRepoSizeMb: overrides.maxRepoSizeMb ?? (typeof data.max_repo_size_mb === "number" ? data.max_repo_size_mb : DEFAULT_MAX_REPO_SIZE_MB),
856
866
  codebaseDir: typeof data.codebase_dir === "string" ? data.codebase_dir : null,
857
867
  codebaseTtl: typeof data.codebase_ttl === "string" ? data.codebase_ttl : null,
868
+ commandTestTimeoutMs: (() => {
869
+ if (data.command_test_timeout === void 0) return DEFAULT_COMMAND_TEST_TIMEOUT_MS;
870
+ const ms = parseDurationMs(data.command_test_timeout);
871
+ if (ms === null) {
872
+ console.warn(
873
+ `\u26A0 Config warning: command_test_timeout must be a duration string like "10s" or "1m", got "${data.command_test_timeout}", using default (${DEFAULT_COMMAND_TEST_TIMEOUT_MS / 1e3}s)`
874
+ );
875
+ return DEFAULT_COMMAND_TEST_TIMEOUT_MS;
876
+ }
877
+ if (ms <= 0) {
878
+ console.warn(
879
+ `\u26A0 Config warning: command_test_timeout must be a positive duration, got "${data.command_test_timeout}", using default (${DEFAULT_COMMAND_TEST_TIMEOUT_MS / 1e3}s)`
880
+ );
881
+ return DEFAULT_COMMAND_TEST_TIMEOUT_MS;
882
+ }
883
+ return ms;
884
+ })(),
858
885
  agentCommand: typeof data.agent_command === "string" ? data.agent_command : null,
859
886
  agents: parseAgents(data),
860
887
  usageLimits: {
@@ -2015,11 +2042,11 @@ function executeTool(commandTemplate, prompt2, timeoutMs, signal, vars, cwd, liv
2015
2042
  });
2016
2043
  }
2017
2044
  var TEST_COMMAND_PROMPT = "Respond with: OK";
2018
- var TEST_COMMAND_TIMEOUT_MS = 1e4;
2019
- async function testCommand(commandTemplate) {
2045
+ var DEFAULT_TEST_COMMAND_TIMEOUT_MS = 1e4;
2046
+ async function testCommand(commandTemplate, timeoutMs = DEFAULT_TEST_COMMAND_TIMEOUT_MS) {
2020
2047
  const start = Date.now();
2021
2048
  try {
2022
- await executeTool(commandTemplate, TEST_COMMAND_PROMPT, TEST_COMMAND_TIMEOUT_MS);
2049
+ await executeTool(commandTemplate, TEST_COMMAND_PROMPT, timeoutMs);
2023
2050
  return { ok: true, elapsedMs: Date.now() - start };
2024
2051
  } catch (err) {
2025
2052
  const elapsed = Date.now() - start;
@@ -2027,7 +2054,7 @@ async function testCommand(commandTemplate) {
2027
2054
  return {
2028
2055
  ok: false,
2029
2056
  elapsedMs: elapsed,
2030
- error: `command timed out after ${TEST_COMMAND_TIMEOUT_MS / 1e3}s`
2057
+ error: `command timed out after ${timeoutMs / 1e3}s`
2031
2058
  };
2032
2059
  }
2033
2060
  const msg = err instanceof Error ? err.message : String(err);
@@ -4659,6 +4686,17 @@ function agentConfigToDescriptor(config, agentId, index, agentOwner, userOrgs) {
4659
4686
  var DEFAULT_RECHECK_INTERVAL = 50;
4660
4687
 
4661
4688
  // src/commands/agent.ts
4689
+ function resolveCommandTemplate(agentConfig, globalCommand) {
4690
+ if (agentConfig?.command) return agentConfig.command;
4691
+ if (globalCommand) return globalCommand;
4692
+ if (agentConfig?.tool) {
4693
+ const registryTool = DEFAULT_REGISTRY.tools.find((t) => t.name === agentConfig.tool);
4694
+ if (registryTool) {
4695
+ return registryTool.commandTemplate.replaceAll("${MODEL}", agentConfig.model ?? "");
4696
+ }
4697
+ }
4698
+ return void 0;
4699
+ }
4662
4700
  var DEFAULT_POLL_INTERVAL_MS = 1e4;
4663
4701
  var MAX_CONSECUTIVE_AUTH_ERRORS = 3;
4664
4702
  var MAX_POLL_BACKOFF_MS = 3e5;
@@ -5712,7 +5750,7 @@ function sleep2(ms, signal) {
5712
5750
  async function startAgent(agentId, platformUrl, agentInfo, reviewDeps, consumptionDeps, options) {
5713
5751
  const client = new ApiClient(platformUrl, {
5714
5752
  authToken: options?.authToken,
5715
- cliVersion: "0.23.8",
5753
+ cliVersion: "0.23.10",
5716
5754
  versionOverride: options?.versionOverride,
5717
5755
  onTokenRefresh: options?.onTokenRefresh
5718
5756
  });
@@ -5746,7 +5784,7 @@ async function startAgent(agentId, platformUrl, agentInfo, reviewDeps, consumpti
5746
5784
  }
5747
5785
  if (reviewDeps.commandTemplate && !options?.routerRelay) {
5748
5786
  log("Testing command...");
5749
- const result = await testCommand(reviewDeps.commandTemplate);
5787
+ const result = await testCommand(reviewDeps.commandTemplate, options?.commandTestTimeoutMs);
5750
5788
  if (result.ok) {
5751
5789
  log(`${icons.success} Command test ok (${(result.elapsedMs / 1e3).toFixed(1)}s)`);
5752
5790
  } else {
@@ -6008,7 +6046,7 @@ async function startBatchAgents(config, agents, pollIntervalMs, oauthToken, opti
6008
6046
  const { versionOverride, verbose, instancesOverride, agentOwner, userOrgs } = options;
6009
6047
  const client = new ApiClient(config.platformUrl, {
6010
6048
  authToken: oauthToken,
6011
- cliVersion: "0.23.8",
6049
+ cliVersion: "0.23.10",
6012
6050
  versionOverride,
6013
6051
  onTokenRefresh: () => getValidToken(config.platformUrl, { configPath: config.authFile })
6014
6052
  });
@@ -6036,7 +6074,7 @@ async function startBatchAgents(config, agents, pollIntervalMs, oauthToken, opti
6036
6074
  let skipped = 0;
6037
6075
  for (let i = 0; i < agents.length; i++) {
6038
6076
  const agentConfig = agents[i];
6039
- const commandTemplate = agentConfig.command ?? config.agentCommand ?? void 0;
6077
+ const commandTemplate = resolveCommandTemplate(agentConfig, config.agentCommand);
6040
6078
  const label = agentConfig.name ?? `agent[${i}]`;
6041
6079
  if (!commandTemplate) {
6042
6080
  logError(`[${label}] No command configured. Skipping.`);
@@ -6104,7 +6142,10 @@ async function startBatchAgents(config, agents, pollIntervalMs, oauthToken, opti
6104
6142
  await Promise.all(
6105
6143
  agentStates.filter((state) => state.reviewDeps.commandTemplate && !state.routerRelay).map(async (state) => {
6106
6144
  state.logger.log("Testing command...");
6107
- const result = await testCommand(state.reviewDeps.commandTemplate);
6145
+ const result = await testCommand(
6146
+ state.reviewDeps.commandTemplate,
6147
+ config.commandTestTimeoutMs
6148
+ );
6108
6149
  if (result.ok) {
6109
6150
  state.logger.log(
6110
6151
  `${icons.success} Command test ok (${(result.elapsedMs / 1e3).toFixed(1)}s)`
@@ -6180,10 +6221,8 @@ async function startAgentRouter() {
6180
6221
  let agentConfig;
6181
6222
  if (config.agents && config.agents.length > 0) {
6182
6223
  agentConfig = config.agents.find((a) => a.router) ?? config.agents[0];
6183
- commandTemplate = agentConfig.command ?? config.agentCommand ?? void 0;
6184
- } else {
6185
- commandTemplate = config.agentCommand ?? void 0;
6186
6224
  }
6225
+ commandTemplate = resolveCommandTemplate(agentConfig, config.agentCommand);
6187
6226
  const router = new RouterRelay();
6188
6227
  router.start();
6189
6228
  const logger = createLogger(agentConfig?.name ?? "agent[0]");
@@ -6248,7 +6287,8 @@ async function startAgentRouter() {
6248
6287
  userOrgs,
6249
6288
  usageLimits: config.usageLimits,
6250
6289
  versionOverride,
6251
- codebaseTtl: config.codebaseTtl
6290
+ codebaseTtl: config.codebaseTtl,
6291
+ commandTestTimeoutMs: config.commandTestTimeoutMs
6252
6292
  }
6253
6293
  );
6254
6294
  router.stop();
@@ -6258,10 +6298,8 @@ function startAgentByIndex(config, agentIndex, pollIntervalMs, oauthToken, versi
6258
6298
  let agentConfig;
6259
6299
  if (config.agents && config.agents.length > agentIndex) {
6260
6300
  agentConfig = config.agents[agentIndex];
6261
- commandTemplate = agentConfig.command ?? config.agentCommand ?? void 0;
6262
- } else {
6263
- commandTemplate = config.agentCommand ?? void 0;
6264
6301
  }
6302
+ commandTemplate = resolveCommandTemplate(agentConfig, config.agentCommand);
6265
6303
  const label = agentConfig?.name ?? `agent[${agentIndex}]`;
6266
6304
  if (!commandTemplate) {
6267
6305
  console.error(`[${label}] No command configured. Skipping.`);
@@ -6326,7 +6364,8 @@ function startAgentByIndex(config, agentIndex, pollIntervalMs, oauthToken, versi
6326
6364
  codebaseTtl: config.codebaseTtl,
6327
6365
  verbose,
6328
6366
  agentOwner,
6329
- userOrgs
6367
+ userOrgs,
6368
+ commandTestTimeoutMs: config.commandTestTimeoutMs
6330
6369
  }
6331
6370
  ).finally(() => {
6332
6371
  routerRelay?.stop();
@@ -6354,7 +6393,7 @@ agentCommand.command("start").description("Start agents in polling mode").option
6354
6393
  }
6355
6394
  config = loadConfig();
6356
6395
  }
6357
- console.log(formatVersionBanner("0.23.8", "4d448ed"));
6396
+ console.log(formatVersionBanner("0.23.10", "3fd8827"));
6358
6397
  if (config.agents && config.agents.length > 0) {
6359
6398
  const toolEntries = config.agents.map((a) => ({
6360
6399
  tool: a.tool,
@@ -7177,7 +7216,7 @@ var statusCommand = new Command4("status").description("Show agent config, conne
7177
7216
  });
7178
7217
 
7179
7218
  // src/index.ts
7180
- var program = new Command5().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version(`${"0.23.8"} (${"4d448ed"})`);
7219
+ var program = new Command5().name("opencara").description("OpenCara \u2014 distributed AI code review agent").version(`${"0.23.10"} (${"3fd8827"})`);
7181
7220
  program.addCommand(agentCommand);
7182
7221
  program.addCommand(authCommand());
7183
7222
  program.addCommand(dedupCommand());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencara",
3
- "version": "0.23.8",
3
+ "version": "0.23.10",
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",