@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:
|
|
456
|
-
async function verifyProviderCredentials(provider, providers
|
|
457
|
-
const
|
|
458
|
-
if (!
|
|
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
|
-
|
|
461
|
-
const
|
|
462
|
-
|
|
463
|
-
|
|
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
|
-
|
|
487
|
-
|
|
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
|
|
2078
|
-
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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
|
-
|
|
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 {
|
package/dist/nerves/runtime.js
CHANGED
|
@@ -6,7 +6,11 @@ const index_1 = require("./index");
|
|
|
6
6
|
let runtimeLogger = null;
|
|
7
7
|
function getRuntimeLogger() {
|
|
8
8
|
if (!runtimeLogger) {
|
|
9
|
-
|
|
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
|
|
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
|
-
|
|
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
|
}
|