@ouro.bot/cli 0.1.0-alpha.371 → 0.1.0-alpha.373
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,22 @@
|
|
|
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.373",
|
|
6
|
+
"changes": [
|
|
7
|
+
"SerpentGuide bootstrap now discovers provider credentials from unlockable installed agent vaults, so a new hatch can reuse sources such as `minimax from slugger's vault` without creating persistent SerpentGuide credentials.",
|
|
8
|
+
"SerpentGuide credential options now preserve provenance for installed-agent vault sources and env sources while keeping secret values out of terminal labels.",
|
|
9
|
+
"`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the SerpentGuide installed-agent credential discovery release."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"version": "0.1.0-alpha.372",
|
|
14
|
+
"changes": [
|
|
15
|
+
"Locked-vault errors now explain that provider credentials are still stored in the agent vault and that this computer is missing usable local unlock material.",
|
|
16
|
+
"The locked-vault guidance now names common machine-local causes, including a new computer, local profile or hostname migration, and removed local unlock entries.",
|
|
17
|
+
"`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the locked-vault bootstrap copy release."
|
|
18
|
+
]
|
|
19
|
+
},
|
|
4
20
|
{
|
|
5
21
|
"version": "0.1.0-alpha.371",
|
|
6
22
|
"changes": [
|
|
@@ -247,10 +247,18 @@ async function defaultRunSerpentGuide() {
|
|
|
247
247
|
const tempDir = path.join(os.tmpdir(), `ouro-hatch-${crypto.randomUUID()}`);
|
|
248
248
|
try {
|
|
249
249
|
const discovered = [];
|
|
250
|
-
const
|
|
250
|
+
const existingBundles = (0, specialist_orchestrator_1.listExistingBundles)((0, identity_1.getAgentBundlesRoot)());
|
|
251
|
+
const existingBundleCount = existingBundles.length;
|
|
251
252
|
const hatchVerb = existingBundleCount > 0 ? "let's hatch a new agent." : "let's hatch your first agent.";
|
|
252
253
|
// Default models per provider (used when entering new credentials)
|
|
253
254
|
const defaultModels = provider_models_1.DEFAULT_PROVIDER_MODELS;
|
|
255
|
+
const installedAgentCreds = await (0, provider_discovery_1.discoverInstalledAgentCredentials)(existingBundles);
|
|
256
|
+
for (const cred of installedAgentCreds) {
|
|
257
|
+
discovered.push({
|
|
258
|
+
...cred,
|
|
259
|
+
providerConfig: { model: defaultModels[cred.provider], ...cred.providerConfig },
|
|
260
|
+
});
|
|
261
|
+
}
|
|
254
262
|
// Scan environment variables for API keys using the shared helper
|
|
255
263
|
const envCreds = (0, provider_discovery_1.scanEnvVarCredentials)(process.env);
|
|
256
264
|
const envDiscovered = [];
|
|
@@ -268,21 +276,21 @@ async function defaultRunSerpentGuide() {
|
|
|
268
276
|
if (discovered.length > 0) {
|
|
269
277
|
process.stdout.write(`\n\ud83d\udc0d welcome to ouroboros! ${hatchVerb}\n`);
|
|
270
278
|
process.stdout.write("i found existing API credentials:\n\n");
|
|
271
|
-
const
|
|
272
|
-
for (let i = 0; i <
|
|
273
|
-
const model =
|
|
279
|
+
const credentialOptions = discovered;
|
|
280
|
+
for (let i = 0; i < credentialOptions.length; i++) {
|
|
281
|
+
const model = credentialOptions[i].providerConfig.model || credentialOptions[i].providerConfig.deployment || "";
|
|
274
282
|
const modelLabel = model ? `, ${model}` : "";
|
|
275
|
-
const envMatch = envDiscovered.find((e) => e.provider ===
|
|
276
|
-
const sourceLabel =
|
|
277
|
-
process.stdout.write(` ${i + 1}. ${
|
|
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
286
|
}
|
|
279
287
|
process.stdout.write("\n");
|
|
280
288
|
const choice = await coldPrompt("use one of these? enter number, or 'new' for a different key: ");
|
|
281
289
|
const idx = parseInt(choice, 10) - 1;
|
|
282
|
-
if (idx >= 0 && idx <
|
|
283
|
-
providerRaw =
|
|
284
|
-
credentials =
|
|
285
|
-
providerConfig =
|
|
290
|
+
if (idx >= 0 && idx < credentialOptions.length) {
|
|
291
|
+
providerRaw = credentialOptions[idx].provider;
|
|
292
|
+
credentials = credentialOptions[idx].credentials;
|
|
293
|
+
providerConfig = credentialOptions[idx].providerConfig;
|
|
286
294
|
}
|
|
287
295
|
else {
|
|
288
296
|
const pRaw = await coldPrompt("provider (anthropic/azure/minimax/openai-codex/github-copilot): ");
|
|
@@ -354,7 +362,6 @@ async function defaultRunSerpentGuide() {
|
|
|
354
362
|
process.stdout.write(`credentials didn't work (${pingResult.message}). run 'ouro hatch' to try again.\n`);
|
|
355
363
|
return null;
|
|
356
364
|
}
|
|
357
|
-
const existingBundles = (0, specialist_orchestrator_1.listExistingBundles)(bundlesRoot);
|
|
358
365
|
const systemPrompt = (0, specialist_prompt_1.buildSpecialistSystemPrompt)(soulText, identity.content, existingBundles, {
|
|
359
366
|
tempDir,
|
|
360
367
|
provider: providerRaw,
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.scanEnvVarCredentials = scanEnvVarCredentials;
|
|
11
|
+
exports.discoverInstalledAgentCredentials = discoverInstalledAgentCredentials;
|
|
12
|
+
exports.describeDiscoveredCredentialSource = describeDiscoveredCredentialSource;
|
|
11
13
|
exports.discoverWorkingProvider = discoverWorkingProvider;
|
|
12
14
|
const identity_1 = require("../identity");
|
|
13
15
|
const provider_credentials_1 = require("../provider-credentials");
|
|
@@ -45,14 +47,36 @@ function stringifyProviderFields(fields) {
|
|
|
45
47
|
}
|
|
46
48
|
return result;
|
|
47
49
|
}
|
|
48
|
-
function discoveredFromVaultRecord(record) {
|
|
50
|
+
function discoveredFromVaultRecord(record, agentName = "vault") {
|
|
49
51
|
return {
|
|
50
52
|
provider: record.provider,
|
|
51
|
-
agentName
|
|
53
|
+
agentName,
|
|
52
54
|
credentials: stringifyProviderFields(record.credentials),
|
|
53
55
|
providerConfig: stringifyProviderFields(record.config),
|
|
54
56
|
};
|
|
55
57
|
}
|
|
58
|
+
async function discoverInstalledAgentCredentials(agentNames) {
|
|
59
|
+
const discovered = [];
|
|
60
|
+
for (const agentName of agentNames) {
|
|
61
|
+
if (agentName === "SerpentGuide")
|
|
62
|
+
continue;
|
|
63
|
+
const poolResult = await (0, provider_credentials_1.refreshProviderCredentialPool)(agentName, { preserveCachedOnFailure: true });
|
|
64
|
+
if (!poolResult.ok)
|
|
65
|
+
continue;
|
|
66
|
+
for (const record of Object.values(poolResult.pool.providers)) {
|
|
67
|
+
if (!record)
|
|
68
|
+
continue;
|
|
69
|
+
discovered.push(discoveredFromVaultRecord(record, agentName));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return discovered;
|
|
73
|
+
}
|
|
74
|
+
function describeDiscoveredCredentialSource(credential, envVar) {
|
|
75
|
+
if (credential.agentName === "env") {
|
|
76
|
+
return envVar ? `from env: $${envVar}` : "from env";
|
|
77
|
+
}
|
|
78
|
+
return `from ${credential.agentName}'s vault`;
|
|
79
|
+
}
|
|
56
80
|
async function discoverWorkingProvider(deps) {
|
|
57
81
|
const poolResult = await (0, provider_credentials_1.refreshProviderCredentialPool)(deps.agentName);
|
|
58
82
|
if (!poolResult.ok) {
|
|
@@ -106,6 +106,10 @@ function lockedMessage(config, store) {
|
|
|
106
106
|
`Vault: ${vaultLabel(config)}`,
|
|
107
107
|
`Local unlock store: ${store.kind} (${store.location})`,
|
|
108
108
|
"",
|
|
109
|
+
"Provider credentials are still stored in the agent vault.",
|
|
110
|
+
"This computer does not currently have usable local unlock material for that vault.",
|
|
111
|
+
"This can happen on a new computer, after a local profile or hostname migration, or if the local unlock entry was removed.",
|
|
112
|
+
"",
|
|
109
113
|
`Run \`${command}\` and enter the vault unlock secret from the operator password manager.`,
|
|
110
114
|
].join("\n");
|
|
111
115
|
}
|