@ouro.bot/cli 0.1.0-alpha.124 → 0.1.0-alpha.126

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/changelog.json CHANGED
@@ -1,6 +1,27 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.126",
6
+ "changes": [
7
+ "Fixed Anthropic tool_choice incompatibility with thinking \u2014 uses auto instead of any when thinking is enabled.",
8
+ "auth verify and auth switch now use pingProvider for real API verification instead of format-only checks. auth switch verifies credentials work before switching."
9
+ ]
10
+ },
11
+ {
12
+ "version": "0.1.0-alpha.125",
13
+ "changes": [
14
+ "Fixed Anthropic tool_choice incompatibility with thinking \u2014 uses auto instead of any when thinking is enabled.",
15
+ "auth verify and auth switch now use pingProvider for real API verification instead of format-only checks. auth switch verifies credentials work before switching."
16
+ ]
17
+ },
18
+ {
19
+ "version": "0.1.0-alpha.125",
20
+ "changes": [
21
+ "Fix: Default runtime logger is now silent (no stderr sink) so nerves events emitted before logger configuration no longer interleave with the CLI spinner animation.",
22
+ "Fix: MCP server connect failures now include the command name, args, and a hint to check agent.json mcpServers configuration."
23
+ ]
24
+ },
4
25
  {
5
26
  "version": "0.1.0-alpha.124",
6
27
  "changes": [
@@ -67,6 +88,9 @@
67
88
  {
68
89
  "version": "0.1.0-alpha.114",
69
90
  "changes": [
91
+ "Fix: Default runtime logger is now silent (no stderr sink) so nerves events emitted before logger configuration no longer interleave with the CLI spinner animation.",
92
+ "Fix: MCP server connect failures now include the command name, args, and a hint to check agent.json mcpServers configuration. Retry-exhaustion messages also identify the failing command.",
93
+ "Verification: StreamingWordWrapper integration in CLI chat confirmed working \u2014 wraps at word boundaries during streaming output.",
70
94
  "When a model provider fails mid-conversation (auth error, usage limit, outage), the harness now classifies the error, pings alternative configured providers, and surfaces validated failover options to the user in-channel. Reply 'switch to <provider>' to continue on a working provider.",
71
95
  "Each provider now has a `classifyError` method that distinguishes auth failures, usage/subscription limits, rate limits, server errors, and network errors. The old auth guidance wrappers are replaced by this unified classification system.",
72
96
  "New `pingProvider` function makes a real heartbeat completion call to verify provider credentials and quota are live \u2014 no more format-only checks.",
@@ -452,49 +452,19 @@ function hasStoredCredentials(provider, providerSecrets) {
452
452
  return !!providerSecrets.endpoint && !!providerSecrets.apiKey;
453
453
  }
454
454
  /* v8 ignore stop */
455
- /* v8 ignore start -- verifyProviderCredentials: per-provider branches tested via auth verify tests @preserve */
456
- async function verifyProviderCredentials(provider, providers, fetchImpl = fetch) {
457
- const p = providers[provider];
458
- if (!p)
455
+ /* v8 ignore start -- verifyProviderCredentials: delegates to pingProvider @preserve */
456
+ async function verifyProviderCredentials(provider, providers) {
457
+ const config = providers[provider];
458
+ if (!config)
459
459
  return "not configured";
460
- if (provider === "anthropic") {
461
- const token = p.setupToken || "";
462
- if (!token)
463
- return "failed (no token)";
464
- if (token.startsWith("sk-ant-"))
465
- return "ok";
466
- return "failed (invalid token format)";
467
- }
468
- if (provider === "openai-codex") {
469
- const token = p.oauthAccessToken || "";
470
- return token ? "ok" : "failed (no token)";
471
- }
472
- if (provider === "github-copilot") {
473
- const token = p.githubToken || "";
474
- if (!token)
475
- return "failed (no token)";
476
- try {
477
- const response = await fetchImpl("https://api.github.com/copilot_internal/user", {
478
- headers: { Authorization: `Bearer ${token}` },
479
- });
480
- return response.ok ? "ok" : `failed (HTTP ${response.status})`;
481
- }
482
- catch (error) {
483
- return `failed (${error.message})`;
484
- }
460
+ try {
461
+ const { pingProvider } = await Promise.resolve().then(() => __importStar(require("../../heart/provider-ping")));
462
+ const result = await pingProvider(provider, config);
463
+ return result.ok ? "ok" : `failed (${result.message})`;
485
464
  }
486
- if (provider === "minimax") {
487
- const apiKey = p.apiKey || "";
488
- return apiKey ? "ok" : "failed (no api key)";
465
+ catch (error) {
466
+ return `failed (${error instanceof Error ? error.message : String(error)})`;
489
467
  }
490
- // azure
491
- const endpoint = p.endpoint || "";
492
- const apiKey = p.apiKey || "";
493
- if (!endpoint)
494
- return "failed (no endpoint)";
495
- if (!apiKey)
496
- return "failed (no api key)";
497
- return "ok";
498
468
  }
499
469
  async function listGithubCopilotModels(baseUrl, token, fetchImpl = fetch) {
500
470
  const url = `${baseUrl.replace(/\/+$/, "")}/models`;
@@ -1352,12 +1322,6 @@ function createDefaultOuroCliDeps(socketPath = socket_client_1.DEFAULT_DAEMON_SO
1352
1322
  promptInput: defaultPromptInput,
1353
1323
  runAdoptionSpecialist: defaultRunAdoptionSpecialist,
1354
1324
  runAuthFlow: auth_flow_1.runRuntimeAuthFlow,
1355
- /* v8 ignore start -- integration: real API ping @preserve */
1356
- pingProvider: async (provider, config) => {
1357
- const { pingProvider: ping } = await Promise.resolve().then(() => __importStar(require("../../heart/provider-ping")));
1358
- return ping(provider, config);
1359
- },
1360
- /* v8 ignore stop */
1361
1325
  registerOuroBundleType: ouro_uti_1.registerOuroBundleUti,
1362
1326
  installOuroCommand: ouro_path_installer_1.installOuroCommand,
1363
1327
  /* v8 ignore start -- self-healing: ensures active symlink matches running runtime version @preserve */
@@ -2074,17 +2038,11 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
2074
2038
  /* v8 ignore start -- integration: real API ping after auth @preserve */
2075
2039
  try {
2076
2040
  const { secrets } = (0, auth_flow_1.loadAgentSecrets)(command.agent);
2077
- const config = secrets.providers[provider];
2078
- const pingResult = await deps.pingProvider(provider, config);
2079
- if (pingResult.ok) {
2080
- deps.writeStdout(`verified: ${provider} credentials are working.`);
2081
- }
2082
- else {
2083
- deps.writeStdout(`warning: ${provider} credentials were saved but verification failed. you may need to re-run auth.`);
2084
- }
2041
+ const status = await verifyProviderCredentials(provider, secrets.providers);
2042
+ deps.writeStdout(`${provider}: ${status}`);
2085
2043
  }
2086
2044
  catch {
2087
- // Ping failure is non-blocking — credentials were saved regardless
2045
+ // Verification failure is non-blocking — credentials were saved regardless
2088
2046
  }
2089
2047
  /* v8 ignore stop */
2090
2048
  return result.message;
@@ -2094,16 +2052,15 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
2094
2052
  if (command.kind === "auth.verify") {
2095
2053
  const { secrets } = (0, auth_flow_1.loadAgentSecrets)(command.agent);
2096
2054
  const providers = secrets.providers;
2097
- const fetchFn = deps.fetchImpl ?? fetch;
2098
2055
  if (command.provider) {
2099
- const status = await verifyProviderCredentials(command.provider, providers, fetchFn);
2056
+ const status = await verifyProviderCredentials(command.provider, providers);
2100
2057
  const message = `${command.provider}: ${status}`;
2101
2058
  deps.writeStdout(message);
2102
2059
  return message;
2103
2060
  }
2104
2061
  const lines = [];
2105
2062
  for (const p of Object.keys(providers)) {
2106
- const status = await verifyProviderCredentials(p, providers, fetchFn);
2063
+ const status = await verifyProviderCredentials(p, providers);
2107
2064
  lines.push(`${p}: ${status}`);
2108
2065
  }
2109
2066
  const message = lines.join("\n");
@@ -2119,8 +2076,15 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
2119
2076
  deps.writeStdout(message);
2120
2077
  return message;
2121
2078
  }
2079
+ // Verify credentials actually work before switching
2080
+ const status = await verifyProviderCredentials(command.provider, secrets.providers);
2081
+ if (!status.startsWith("ok")) {
2082
+ const message = `${command.provider}: ${status}. fix credentials with \`ouro auth --agent ${command.agent} --provider ${command.provider}\` before switching.`;
2083
+ deps.writeStdout(message);
2084
+ return message;
2085
+ }
2122
2086
  (0, auth_flow_1.writeAgentProviderSelection)(command.agent, command.provider);
2123
- const message = `switched ${command.agent} to ${command.provider}`;
2087
+ const message = `switched ${command.agent} to ${command.provider} (verified working)`;
2124
2088
  deps.writeStdout(message);
2125
2089
  return message;
2126
2090
  }
@@ -275,7 +275,9 @@ async function streamAnthropicMessages(client, model, request) {
275
275
  if (anthropicTools.length > 0)
276
276
  params.tools = anthropicTools;
277
277
  if (request.toolChoiceRequired && anthropicTools.length > 0) {
278
- params.tool_choice = { type: "any" };
278
+ // Thinking (adaptive or enabled) only supports tool_choice "auto" or "none".
279
+ // "any" forces tool use which is incompatible with extended thinking.
280
+ params.tool_choice = params.thinking ? { type: "auto" } : /* v8 ignore next -- no-thinking path: thinking always set for 4.6 models @preserve */ { type: "any" };
279
281
  }
280
282
  let response;
281
283
  try {
@@ -6,7 +6,11 @@ const index_1 = require("./index");
6
6
  let runtimeLogger = null;
7
7
  function getRuntimeLogger() {
8
8
  if (!runtimeLogger) {
9
- runtimeLogger = (0, index_1.createLogger)({ level: "info" });
9
+ // Default logger has no sinks — events emitted before the real logger is
10
+ // configured (e.g. identity resolution during startup) are silently dropped.
11
+ // This prevents INFO lines from leaking to stderr and interleaving with
12
+ // the CLI spinner when the ouro subprocess hasn't configured its logger yet.
13
+ runtimeLogger = (0, index_1.createLogger)({ level: "info", sinks: [] });
10
14
  }
11
15
  return runtimeLogger;
12
16
  }
@@ -76,14 +76,17 @@ class McpManager {
76
76
  entry.consecutiveFailures = 0;
77
77
  }
78
78
  catch (error) {
79
+ const reason = error instanceof Error ? error.message : String(error);
79
80
  (0, runtime_1.emitNervesEvent)({
80
81
  level: "error",
81
82
  event: "mcp.connect_error",
82
83
  component: "repertoire",
83
- message: `failed to connect MCP server: ${name}`,
84
+ message: `failed to connect MCP server "${name}" (command: ${config.command}). Check that the command exists and is properly configured. Reason: ${reason}`,
84
85
  meta: {
85
86
  server: name,
86
- reason: error instanceof Error ? error.message : String(error),
87
+ command: config.command,
88
+ args: config.args,
89
+ reason,
87
90
  },
88
91
  });
89
92
  }
@@ -99,8 +102,8 @@ class McpManager {
99
102
  level: "error",
100
103
  event: "mcp.connect_error",
101
104
  component: "repertoire",
102
- message: `MCP server "${name}" exceeded max restart retries (${MAX_RESTART_RETRIES})`,
103
- meta: { server: name, failures: entry.consecutiveFailures },
105
+ message: `MCP server "${name}" exceeded max restart retries (${MAX_RESTART_RETRIES}). Giving up — check that "${entry.config.command}" exists and is properly configured in agent.json mcpServers.`,
106
+ meta: { server: name, command: entry.config.command, failures: entry.consecutiveFailures },
104
107
  });
105
108
  return;
106
109
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.124",
3
+ "version": "0.1.0-alpha.126",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",