@ouro.bot/cli 0.1.0-alpha.439 → 0.1.0-alpha.440
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 +8 -0
- package/dist/heart/daemon/agent-config-check.js +7 -2
- package/dist/heart/daemon/cli-exec.js +14 -2
- package/dist/heart/daemon/provider-ping-progress.js +76 -0
- package/dist/heart/provider-attempt.js +1 -0
- package/dist/heart/provider-ping.js +2 -0
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
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.440",
|
|
6
|
+
"changes": [
|
|
7
|
+
"Shared live provider checks now narrate each real attempt and retry across `ouro up`, the connect bay, `ouro check`, `ouro use`, and auth verification, so a slow or busy provider no longer feels like one frozen `checking <provider>` line.",
|
|
8
|
+
"One shared retry-progress formatter translates the real failure class into plain language like `provider is busy right now` or `provider asked us to slow down`, while the shared provider attempt runner now exposes attempt-start callbacks for every human-facing verification surface.",
|
|
9
|
+
"New daemon/provider progress coverage locks in the shared callback contract and the human-facing retry narration, with the full coverage, integration, package-e2e, and installed-product verification stack carried through for the published release."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
4
12
|
{
|
|
5
13
|
"version": "0.1.0-alpha.439",
|
|
6
14
|
"changes": [
|
|
@@ -46,6 +46,7 @@ const provider_state_1 = require("../provider-state");
|
|
|
46
46
|
const provider_credentials_1 = require("../provider-credentials");
|
|
47
47
|
const vault_unlock_1 = require("../../repertoire/vault-unlock");
|
|
48
48
|
const readiness_repair_1 = require("./readiness-repair");
|
|
49
|
+
const provider_ping_progress_1 = require("./provider-ping-progress");
|
|
49
50
|
function isAgentProvider(value) {
|
|
50
51
|
return Object.prototype.hasOwnProperty.call(identity_1.PROVIDER_CREDENTIALS, value);
|
|
51
52
|
}
|
|
@@ -386,8 +387,12 @@ async function checkAgentConfigWithProviderHealth(agentName, bundlesRoot, deps =
|
|
|
386
387
|
}
|
|
387
388
|
const groups = [...pingGroups.values()];
|
|
388
389
|
const pingResults = await Promise.all(groups.map(async (group) => {
|
|
389
|
-
|
|
390
|
-
|
|
390
|
+
const result = await ping(group.provider, providerCredentialConfig(group.record), {
|
|
391
|
+
model: group.model,
|
|
392
|
+
...(deps.onProgress
|
|
393
|
+
? (0, provider_ping_progress_1.createProviderPingProgressReporter)({ provider: group.provider, model: group.model }, deps.onProgress)
|
|
394
|
+
: {}),
|
|
395
|
+
});
|
|
391
396
|
return { group, result };
|
|
392
397
|
}));
|
|
393
398
|
let firstFailure = null;
|
|
@@ -95,6 +95,7 @@ const terminal_ui_1 = require("./terminal-ui");
|
|
|
95
95
|
const startup_tui_1 = require("./startup-tui");
|
|
96
96
|
const stale_bundle_prune_1 = require("./stale-bundle-prune");
|
|
97
97
|
const up_progress_1 = require("./up-progress");
|
|
98
|
+
const provider_ping_progress_1 = require("./provider-ping-progress");
|
|
98
99
|
const provider_ping_1 = require("../provider-ping");
|
|
99
100
|
const agent_discovery_1 = require("./agent-discovery");
|
|
100
101
|
const connect_bay_1 = require("./connect-bay");
|
|
@@ -845,13 +846,13 @@ async function listGithubCopilotModels(baseUrl, token, fetchImpl = fetch) {
|
|
|
845
846
|
}
|
|
846
847
|
// ── Provider credential verification ──
|
|
847
848
|
/* v8 ignore start -- verifyProviderCredentials: delegates to pingProvider @preserve */
|
|
848
|
-
async function verifyProviderCredentials(provider, providers) {
|
|
849
|
+
async function verifyProviderCredentials(provider, providers, options = {}) {
|
|
849
850
|
const config = providers[provider];
|
|
850
851
|
if (!config)
|
|
851
852
|
return "not configured";
|
|
852
853
|
try {
|
|
853
854
|
const { pingProvider } = await Promise.resolve().then(() => __importStar(require("../../heart/provider-ping")));
|
|
854
|
-
const result = await pingProvider(provider, config);
|
|
855
|
+
const result = await pingProvider(provider, config, options);
|
|
855
856
|
return result.ok ? "ok" : `failed (${result.message})`;
|
|
856
857
|
}
|
|
857
858
|
catch (error) {
|
|
@@ -2728,6 +2729,7 @@ async function executeProviderUse(command, deps, options = {}) {
|
|
|
2728
2729
|
model: command.model,
|
|
2729
2730
|
attemptPolicy: { baseDelayMs: 0 },
|
|
2730
2731
|
sleep: deps.sleep,
|
|
2732
|
+
...(0, provider_ping_progress_1.createProviderPingProgressReporter)({ provider: command.provider, model: command.model }, (message) => progress?.updateDetail(message)),
|
|
2731
2733
|
});
|
|
2732
2734
|
const attempts = pingAttemptCount(pingResult);
|
|
2733
2735
|
const status = pingResult.ok ? "ready" : `failed (${pingResult.message})`;
|
|
@@ -2793,6 +2795,7 @@ async function executeProviderCheck(command, deps) {
|
|
|
2793
2795
|
model: binding.model,
|
|
2794
2796
|
attemptPolicy: { baseDelayMs: 0 },
|
|
2795
2797
|
sleep: deps.sleep,
|
|
2798
|
+
...(0, provider_ping_progress_1.createProviderPingProgressReporter)({ provider: binding.provider, model: binding.model }, (message) => progress.updateDetail(message)),
|
|
2796
2799
|
});
|
|
2797
2800
|
const attempts = pingAttemptCount(pingResult);
|
|
2798
2801
|
const status = pingResult.ok ? "ready" : `failed (${pingResult.message})`;
|
|
@@ -2949,6 +2952,9 @@ async function executeAuthRun(command, deps) {
|
|
|
2949
2952
|
verificationStatus = credential.ok
|
|
2950
2953
|
? await verifyProviderCredentials(provider, {
|
|
2951
2954
|
[provider]: { ...credential.record.config, ...credential.record.credentials },
|
|
2955
|
+
}, {
|
|
2956
|
+
sleep: deps.sleep,
|
|
2957
|
+
...(0, provider_ping_progress_1.createProviderPingProgressReporter)({ provider }, (message) => progress.updateDetail(message)),
|
|
2952
2958
|
})
|
|
2953
2959
|
: `stored but could not be re-read from vault (${credential.error})`;
|
|
2954
2960
|
progress.completePhase(`verifying ${provider}`, verificationStatus);
|
|
@@ -4918,6 +4924,9 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
4918
4924
|
progress.startPhase(`verifying ${command.provider}`);
|
|
4919
4925
|
const status = await verifyProviderCredentials(command.provider, {
|
|
4920
4926
|
[command.provider]: { ...record.config, ...record.credentials },
|
|
4927
|
+
}, {
|
|
4928
|
+
sleep: deps.sleep,
|
|
4929
|
+
...(0, provider_ping_progress_1.createProviderPingProgressReporter)({ provider: command.provider }, (message) => progress.updateDetail(message)),
|
|
4921
4930
|
});
|
|
4922
4931
|
progress.completePhase(`verifying ${command.provider}`, status);
|
|
4923
4932
|
const message = useTTYBoard
|
|
@@ -4934,6 +4943,9 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
4934
4943
|
for (const [p, record] of entries) {
|
|
4935
4944
|
const status = await verifyProviderCredentials(p, {
|
|
4936
4945
|
[p]: { ...record.config, ...record.credentials },
|
|
4946
|
+
}, {
|
|
4947
|
+
sleep: deps.sleep,
|
|
4948
|
+
...(0, provider_ping_progress_1.createProviderPingProgressReporter)({ provider: p }, (message) => progress.updateDetail(message)),
|
|
4937
4949
|
});
|
|
4938
4950
|
const line = `${p}: ${status}`;
|
|
4939
4951
|
lines.push(line);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatProviderAttemptProgress = formatProviderAttemptProgress;
|
|
4
|
+
exports.formatProviderRetryProgress = formatProviderRetryProgress;
|
|
5
|
+
exports.createProviderPingProgressReporter = createProviderPingProgressReporter;
|
|
6
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
7
|
+
function formatProviderPingLabel(context) {
|
|
8
|
+
return context.model ? `${context.provider} / ${context.model}` : context.provider;
|
|
9
|
+
}
|
|
10
|
+
function providerRetryReason(record) {
|
|
11
|
+
switch (record.classification) {
|
|
12
|
+
case "auth-failure":
|
|
13
|
+
return "credentials were rejected";
|
|
14
|
+
case "usage-limit":
|
|
15
|
+
return "usage limit hit";
|
|
16
|
+
case "rate-limit":
|
|
17
|
+
return "provider asked us to slow down";
|
|
18
|
+
case "server-error":
|
|
19
|
+
return record.httpStatus === 529 ? "provider is busy right now" : "provider is having trouble right now";
|
|
20
|
+
case "network-error":
|
|
21
|
+
return "network connection dropped";
|
|
22
|
+
case "unknown":
|
|
23
|
+
return "last check failed";
|
|
24
|
+
default:
|
|
25
|
+
return "last check failed";
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function providerRetryTiming(delayMs) {
|
|
29
|
+
if (!delayMs || delayMs <= 0)
|
|
30
|
+
return "now";
|
|
31
|
+
const seconds = delayMs / 1000;
|
|
32
|
+
const rounded = Number.isInteger(seconds) ? `${seconds.toFixed(0)}s` : `${seconds.toFixed(1).replace(/\.0$/, "")}s`;
|
|
33
|
+
return `in ${rounded}`;
|
|
34
|
+
}
|
|
35
|
+
function formatProviderAttemptProgress(context, attempt, maxAttempts) {
|
|
36
|
+
return `checking ${formatProviderPingLabel(context)} (attempt ${attempt} of ${maxAttempts})...`;
|
|
37
|
+
}
|
|
38
|
+
function formatProviderRetryProgress(record, maxAttempts) {
|
|
39
|
+
const nextAttempt = Math.min(record.attempt + 1, maxAttempts);
|
|
40
|
+
return `${formatProviderPingLabel(record)}: ${providerRetryReason(record)}; retrying ${providerRetryTiming(record.delayMs)} (attempt ${nextAttempt} of ${maxAttempts})`;
|
|
41
|
+
}
|
|
42
|
+
function createProviderPingProgressReporter(context, onProgress) {
|
|
43
|
+
return {
|
|
44
|
+
onAttemptStart: async (attempt, maxAttempts) => {
|
|
45
|
+
(0, runtime_1.emitNervesEvent)({
|
|
46
|
+
component: "daemon",
|
|
47
|
+
event: "daemon.provider_ping_progress_reported",
|
|
48
|
+
message: "reported provider ping attempt progress",
|
|
49
|
+
meta: {
|
|
50
|
+
provider: context.provider,
|
|
51
|
+
model: context.model ?? null,
|
|
52
|
+
kind: "attempt",
|
|
53
|
+
attempt,
|
|
54
|
+
maxAttempts,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
onProgress(formatProviderAttemptProgress(context, attempt, maxAttempts));
|
|
58
|
+
},
|
|
59
|
+
onRetry: async (record, maxAttempts) => {
|
|
60
|
+
(0, runtime_1.emitNervesEvent)({
|
|
61
|
+
component: "daemon",
|
|
62
|
+
event: "daemon.provider_ping_progress_reported",
|
|
63
|
+
message: "reported provider ping retry progress",
|
|
64
|
+
meta: {
|
|
65
|
+
provider: record.provider,
|
|
66
|
+
model: record.model,
|
|
67
|
+
kind: "retry",
|
|
68
|
+
attempt: record.attempt,
|
|
69
|
+
maxAttempts,
|
|
70
|
+
classification: record.classification ?? "unknown",
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
onProgress(formatProviderRetryProgress(record, maxAttempts));
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -51,6 +51,7 @@ async function runProviderAttempt(input) {
|
|
|
51
51
|
const attempts = [];
|
|
52
52
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
53
53
|
try {
|
|
54
|
+
await input.onAttemptStart?.(attempt, maxAttempts);
|
|
54
55
|
const value = await input.run();
|
|
55
56
|
attempts.push({
|
|
56
57
|
attempt,
|
|
@@ -180,6 +180,8 @@ async function pingProvider(provider, config, options = {}) {
|
|
|
180
180
|
...options.attemptPolicy,
|
|
181
181
|
},
|
|
182
182
|
sleep: options.sleep,
|
|
183
|
+
onAttemptStart: options.onAttemptStart,
|
|
184
|
+
onRetry: options.onRetry,
|
|
183
185
|
run: async () => {
|
|
184
186
|
const controller = new AbortController();
|
|
185
187
|
/* v8 ignore next -- timeout callback: only fires after 10s, tests resolve faster @preserve */
|