@ouro.bot/cli 0.1.0-alpha.373 → 0.1.0-alpha.374

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,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.374",
6
+ "changes": [
7
+ "SerpentGuide bootstrap now stays in the credential picker when a selected discovered credential fails ping, letting the human choose another saved source or enter a new key without restarting `ouro hatch`.",
8
+ "The stale discovered-credential retry path is covered by a focused SerpentGuide bootstrap test that fails the first provider ping and succeeds after manual replacement credentials.",
9
+ "`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the SerpentGuide credential retry release."
10
+ ]
11
+ },
4
12
  {
5
13
  "version": "0.1.0-alpha.373",
6
14
  "changes": [
@@ -244,6 +244,7 @@ async function defaultRunSerpentGuide() {
244
244
  let providerRaw;
245
245
  let credentials = {};
246
246
  let providerConfig = {};
247
+ let selectedCredentialPayload = {};
247
248
  const tempDir = path.join(os.tmpdir(), `ouro-hatch-${crypto.randomUUID()}`);
248
249
  try {
249
250
  const discovered = [];
@@ -252,6 +253,7 @@ async function defaultRunSerpentGuide() {
252
253
  const hatchVerb = existingBundleCount > 0 ? "let's hatch a new agent." : "let's hatch your first agent.";
253
254
  // Default models per provider (used when entering new credentials)
254
255
  const defaultModels = provider_models_1.DEFAULT_PROVIDER_MODELS;
256
+ const { pingProvider } = await Promise.resolve().then(() => __importStar(require("../provider-ping")));
255
257
  const installedAgentCreds = await (0, provider_discovery_1.discoverInstalledAgentCredentials)(existingBundles);
256
258
  for (const cred of installedAgentCreds) {
257
259
  discovered.push({
@@ -273,26 +275,48 @@ async function defaultRunSerpentGuide() {
273
275
  envDiscovered.push({ ...enriched, envVar: firstEnvVar });
274
276
  discovered.push(enriched);
275
277
  }
276
- if (discovered.length > 0) {
277
- process.stdout.write(`\n\ud83d\udc0d welcome to ouroboros! ${hatchVerb}\n`);
278
- process.stdout.write("i found existing API credentials:\n\n");
279
- const credentialOptions = discovered;
280
- for (let i = 0; i < credentialOptions.length; i++) {
281
- const model = credentialOptions[i].providerConfig.model || credentialOptions[i].providerConfig.deployment || "";
282
- const modelLabel = model ? `, ${model}` : "";
283
- const envMatch = envDiscovered.find((e) => e.provider === credentialOptions[i].provider && credentialOptions[i].agentName === "env");
284
- const sourceLabel = (0, provider_discovery_1.describeDiscoveredCredentialSource)(credentialOptions[i], envMatch?.envVar);
285
- process.stdout.write(` ${i + 1}. ${credentialOptions[i].provider}${modelLabel} (${sourceLabel})\n`);
278
+ let welcomed = false;
279
+ while (true) {
280
+ if (!welcomed) {
281
+ process.stdout.write(`\n\ud83d\udc0d welcome to ouroboros! ${hatchVerb}\n`);
282
+ welcomed = true;
286
283
  }
287
- process.stdout.write("\n");
288
- const choice = await coldPrompt("use one of these? enter number, or 'new' for a different key: ");
289
- const idx = parseInt(choice, 10) - 1;
290
- if (idx >= 0 && idx < credentialOptions.length) {
291
- providerRaw = credentialOptions[idx].provider;
292
- credentials = credentialOptions[idx].credentials;
293
- providerConfig = credentialOptions[idx].providerConfig;
284
+ if (discovered.length > 0) {
285
+ process.stdout.write("i found existing API credentials:\n\n");
286
+ const credentialOptions = discovered;
287
+ for (let i = 0; i < credentialOptions.length; i++) {
288
+ const model = credentialOptions[i].providerConfig.model || credentialOptions[i].providerConfig.deployment || "";
289
+ const modelLabel = model ? `, ${model}` : "";
290
+ const envMatch = envDiscovered.find((e) => e.provider === credentialOptions[i].provider && credentialOptions[i].agentName === "env");
291
+ const sourceLabel = (0, provider_discovery_1.describeDiscoveredCredentialSource)(credentialOptions[i], envMatch?.envVar);
292
+ process.stdout.write(` ${i + 1}. ${credentialOptions[i].provider}${modelLabel} (${sourceLabel})\n`);
293
+ }
294
+ process.stdout.write("\n");
295
+ const choice = await coldPrompt("use one of these? enter number, or 'new' for a different key, or 'q' to cancel: ");
296
+ if (["q", "quit", "cancel"].includes(choice.toLowerCase())) {
297
+ coldRl.close();
298
+ return null;
299
+ }
300
+ const idx = parseInt(choice, 10) - 1;
301
+ if (idx >= 0 && idx < credentialOptions.length) {
302
+ providerRaw = credentialOptions[idx].provider;
303
+ credentials = credentialOptions[idx].credentials;
304
+ providerConfig = credentialOptions[idx].providerConfig;
305
+ }
306
+ else {
307
+ const pRaw = await coldPrompt("provider (anthropic/azure/minimax/openai-codex/github-copilot): ");
308
+ if (!(0, cli_parse_1.isAgentProvider)(pRaw)) {
309
+ process.stdout.write("unknown provider. run `ouro hatch` to try again.\n");
310
+ coldRl.close();
311
+ return null;
312
+ }
313
+ providerRaw = pRaw;
314
+ providerConfig = { model: defaultModels[providerRaw] };
315
+ credentials = await (0, auth_flow_1.collectRuntimeAuthCredentials)({ agentName: "SerpentGuide", provider: providerRaw, promptInput: coldPrompt }, {});
316
+ }
294
317
  }
295
318
  else {
319
+ process.stdout.write("i need an API key to power our conversation.\n\n");
296
320
  const pRaw = await coldPrompt("provider (anthropic/azure/minimax/openai-codex/github-copilot): ");
297
321
  if (!(0, cli_parse_1.isAgentProvider)(pRaw)) {
298
322
  process.stdout.write("unknown provider. run `ouro hatch` to try again.\n");
@@ -303,23 +327,21 @@ async function defaultRunSerpentGuide() {
303
327
  providerConfig = { model: defaultModels[providerRaw] };
304
328
  credentials = await (0, auth_flow_1.collectRuntimeAuthCredentials)({ agentName: "SerpentGuide", provider: providerRaw, promptInput: coldPrompt }, {});
305
329
  }
306
- }
307
- else {
308
- process.stdout.write(`\n\ud83d\udc0d welcome to ouroboros! ${hatchVerb}\n`);
309
- process.stdout.write("i need an API key to power our conversation.\n\n");
310
- const pRaw = await coldPrompt("provider (anthropic/azure/minimax/openai-codex/github-copilot): ");
311
- if (!(0, cli_parse_1.isAgentProvider)(pRaw)) {
312
- process.stdout.write("unknown provider. run `ouro hatch` to try again.\n");
313
- coldRl.close();
314
- return null;
330
+ selectedCredentialPayload = { ...providerConfig, ...credentials };
331
+ const pingResult = await pingProvider(providerRaw, selectedCredentialPayload);
332
+ if (pingResult.ok) {
333
+ break;
334
+ }
335
+ process.stdout.write(`credentials didn't work (${pingResult.message}). `);
336
+ if (discovered.length > 0) {
337
+ process.stdout.write("choose another saved credential or enter 'new'.\n\n");
338
+ }
339
+ else {
340
+ process.stdout.write("let's try again.\n\n");
315
341
  }
316
- providerRaw = pRaw;
317
- providerConfig = { model: defaultModels[providerRaw] };
318
- credentials = await (0, auth_flow_1.collectRuntimeAuthCredentials)({ agentName: "SerpentGuide", provider: providerRaw, promptInput: coldPrompt }, {});
319
342
  }
320
343
  coldRl.close();
321
344
  process.stdout.write("\n");
322
- const selectedCredentialPayload = { ...providerConfig, ...credentials };
323
345
  const split = (0, provider_credentials_1.splitProviderCredentialFields)(providerRaw, selectedCredentialPayload);
324
346
  (0, provider_credentials_1.cacheProviderCredentialRecords)("SerpentGuide", [
325
347
  (0, provider_credentials_1.createProviderCredentialRecord)({
@@ -355,13 +377,6 @@ async function defaultRunSerpentGuide() {
355
377
  agentFacing: { provider: providerRaw, model: resolvedModel },
356
378
  phrases,
357
379
  });
358
- // Ping-verify credentials before entering the serpent guide session
359
- const { pingProvider } = await Promise.resolve().then(() => __importStar(require("../provider-ping")));
360
- const pingResult = await pingProvider(providerRaw, selectedCredentialPayload);
361
- if (!pingResult.ok) {
362
- process.stdout.write(`credentials didn't work (${pingResult.message}). run 'ouro hatch' to try again.\n`);
363
- return null;
364
- }
365
380
  const systemPrompt = (0, specialist_prompt_1.buildSpecialistSystemPrompt)(soulText, identity.content, existingBundles, {
366
381
  tempDir,
367
382
  provider: providerRaw,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.373",
3
+ "version": "0.1.0-alpha.374",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",