counselors 0.4.8 → 0.4.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.
package/dist/cli.js CHANGED
@@ -218,7 +218,7 @@ var SAFE_ID_RE = /^[a-zA-Z0-9._-]+$/;
218
218
  function sanitizePath(p) {
219
219
  return p.replace(/[\x00-\x08\x0A-\x1F]/g, "");
220
220
  }
221
- var VERSION = true ? "0.4.8" : "0.0.0-dev";
221
+ var VERSION = true ? "0.4.10" : "0.0.0-dev";
222
222
 
223
223
  // src/types.ts
224
224
  import { z } from "zod";
@@ -397,10 +397,14 @@ async function selectModelDetails(toolId, models) {
397
397
  name: m.recommended ? `${m.name} (Recommended)` : m.name,
398
398
  value: String(i)
399
399
  }));
400
+ choices.push({ name: "Custom model...", value: "__custom__" });
400
401
  const idx = await select({
401
402
  message: `Select model for ${toolId}:`,
402
403
  choices
403
404
  });
405
+ if (idx === "__custom__") {
406
+ return { id: "__custom__" };
407
+ }
404
408
  const model = models[Number(idx)];
405
409
  return {
406
410
  id: model.id,
@@ -615,6 +619,7 @@ import { existsSync as existsSync3 } from "fs";
615
619
 
616
620
  // src/adapters/base.ts
617
621
  var BaseAdapter = class {
622
+ modelFlag = "-m";
618
623
  getEffectiveReadOnlyLevel(_toolConfig) {
619
624
  return this.readOnly.level;
620
625
  }
@@ -713,6 +718,7 @@ var ClaudeAdapter = class extends BaseAdapter {
713
718
  commands = ["claude"];
714
719
  installUrl = "https://docs.anthropic.com/en/docs/claude-code";
715
720
  readOnly = { level: "enforced" };
721
+ modelFlag = "--model";
716
722
  models = [
717
723
  {
718
724
  id: "opus",
@@ -2127,6 +2133,8 @@ var ENV_ALLOWLIST = [
2127
2133
  "GEMINI_API_KEY",
2128
2134
  "GOOGLE_API_KEY",
2129
2135
  "GOOGLE_APPLICATION_CREDENTIALS",
2136
+ "GOOGLE_CLOUD_PROJECT",
2137
+ "GOOGLE_CLOUD_LOCATION",
2130
2138
  "AMP_API_KEY",
2131
2139
  // Proxy
2132
2140
  "HTTP_PROXY",
@@ -2314,11 +2322,16 @@ async function executeTest(adapter, toolConfig, toolName) {
2314
2322
  const cmdStr = [invocation.cmd, ...invocation.args].map(quote).join(" ");
2315
2323
  const command = invocation.stdin != null ? `echo ${quote(invocation.stdin)} | ${cmdStr}` : cmdStr;
2316
2324
  const result = await execute(invocation, TEST_TIMEOUT);
2317
- const passed = result.stdout.includes("OK");
2325
+ const echoedPrompt = result.stdout.includes("User instructions");
2326
+ const passed = result.exitCode === 0 && result.stdout.includes("OK") && !echoedPrompt;
2318
2327
  let error2;
2319
2328
  if (!passed) {
2320
2329
  if (result.timedOut) {
2321
2330
  error2 = `Timed out after ${TEST_TIMEOUT / 1e3}s`;
2331
+ } else if (result.exitCode !== 0) {
2332
+ error2 = result.stderr.trim() || `Process exited with code ${result.exitCode}`;
2333
+ } else if (echoedPrompt) {
2334
+ error2 = "Tool echoed the prompt instead of a model response (check model access)";
2322
2335
  } else if (result.stderr.trim()) {
2323
2336
  error2 = result.stderr.slice(0, 500);
2324
2337
  } else {
@@ -3433,8 +3446,26 @@ async function addBuiltInTool(toolId, config, nameOverride) {
3433
3446
  return;
3434
3447
  }
3435
3448
  const selectedModel = await selectModelDetails(toolId, adapter.models);
3436
- const fallbackName = selectedModel.id.startsWith(`${toolId}-`) ? selectedModel.id : `${toolId}-${selectedModel.id}`;
3437
- const defaultName = nameOverride ?? selectedModel.compoundId ?? fallbackName;
3449
+ let extraFlags;
3450
+ let defaultName;
3451
+ if (selectedModel.id === "__custom__") {
3452
+ const modelId = await promptInput("Model identifier:");
3453
+ if (!modelId.trim()) {
3454
+ error("No model identifier provided.");
3455
+ process.exitCode = 1;
3456
+ return;
3457
+ }
3458
+ const extraInput = await promptInput(
3459
+ "Extra flags (optional, space-separated):"
3460
+ );
3461
+ const parsedExtra = extraInput.trim() ? extraInput.trim().split(/\s+/) : [];
3462
+ extraFlags = [adapter.modelFlag ?? "-m", modelId.trim(), ...parsedExtra];
3463
+ defaultName = nameOverride ?? `${toolId}-${sanitizeId(modelId.trim())}`;
3464
+ } else {
3465
+ extraFlags = selectedModel.extraFlags;
3466
+ const fallbackName = selectedModel.id.startsWith(`${toolId}-`) ? selectedModel.id : `${toolId}-${selectedModel.id}`;
3467
+ defaultName = nameOverride ?? selectedModel.compoundId ?? fallbackName;
3468
+ }
3438
3469
  let name = nameOverride ?? await promptInput("Tool name:", defaultName);
3439
3470
  if (!SAFE_ID_RE.test(name)) {
3440
3471
  error(
@@ -3465,7 +3496,7 @@ async function addBuiltInTool(toolId, config, nameOverride) {
3465
3496
  binary: discovery.path,
3466
3497
  readOnly: { level: adapter.readOnly.level },
3467
3498
  adapter: toolId,
3468
- ...selectedModel.extraFlags ? { extraFlags: selectedModel.extraFlags } : {}
3499
+ ...extraFlags ? { extraFlags } : {}
3469
3500
  };
3470
3501
  const updated = addToolToConfig(config, name, toolConfig);
3471
3502
  saveConfig(updated);
@@ -3473,6 +3504,17 @@ async function addBuiltInTool(toolId, config, nameOverride) {
3473
3504
  copyAmpSettings();
3474
3505
  }
3475
3506
  success(`Added "${name}" to config.`);
3507
+ if (selectedModel.id === "__custom__") {
3508
+ info("Testing tool configuration...");
3509
+ const testAdapter = resolveAdapter(name, toolConfig);
3510
+ const result = await executeTest(testAdapter, toolConfig, name);
3511
+ info(formatTestResults([result]));
3512
+ if (!result.passed) {
3513
+ warn(
3514
+ "The tool was saved to your config but the test failed. You may need to check your API access or flags."
3515
+ );
3516
+ }
3517
+ }
3476
3518
  }
3477
3519
  async function collectCustomConfig(config, presetId) {
3478
3520
  let binaryPath = null;