@ouro.bot/cli 0.1.0-alpha.185 → 0.1.0-alpha.186
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/README.md +1 -1
- package/changelog.json +12 -4
- package/dist/heart/daemon/daemon-cli.js +48 -16
- package/dist/heart/daemon/hatch-flow.js +1 -1
- package/dist/heart/daemon/hatch-specialist.js +3 -3
- package/dist/heart/daemon/specialist-prompt.js +2 -2
- package/dist/senses/cli.js +3 -1
- package/package.json +2 -2
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ The shared harness lives in `src/`:
|
|
|
48
48
|
|
|
49
49
|
Other important top-level paths:
|
|
50
50
|
|
|
51
|
-
- `
|
|
51
|
+
- `SerpentGuide.ouro/`
|
|
52
52
|
Packaged specialist bundle used by `ouro hatch`.
|
|
53
53
|
- `skills/`
|
|
54
54
|
Harness-level skills shipped with the repo (e.g., `configure-dev-tools.md`). These are available to every agent and serve as fallbacks when an agent doesn't have its own version. Agent-specific skills live in the bundle at `~/AgentBundles/<agent>.ouro/skills/`.
|
package/changelog.json
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
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.186",
|
|
6
|
+
"changes": [
|
|
7
|
+
"refactor: rename AdoptionSpecialist to SerpentGuide",
|
|
8
|
+
"feat(hatch): detect API keys from environment variables (ANTHROPIC_API_KEY, OPENAI_API_KEY, AZURE_OPENAI_API_KEY, MINIMAX_API_KEY, GITHUB_TOKEN)",
|
|
9
|
+
"fix(cli): React unmount warning suppression covers SerpentGuide exit path"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
4
12
|
{
|
|
5
13
|
"version": "0.1.0-alpha.185",
|
|
6
14
|
"changes": [
|
|
7
15
|
"fix(hatch): pass model name to adoption specialist from discovered credentials",
|
|
8
16
|
"feat(continuity): wake packets, episodes, cares, intentions, peer presence, and temporal self",
|
|
9
17
|
"fix(continuity): deduplicate obligations in prompt, keep session summary, pass preloaded data",
|
|
10
|
-
"feat(continuity): 9 new modules
|
|
11
|
-
"feat(continuity): 8 new tools
|
|
12
|
-
"feat(continuity): 3-layer architecture
|
|
13
|
-
"feat(pipeline): continuity threading
|
|
18
|
+
"feat(continuity): 9 new modules \u2014 episodes, cares, agent-relationships, intentions, presence, tempo, temporal-view, wake-packet, obligation enrichment",
|
|
19
|
+
"feat(continuity): 8 new tools \u2014 query_episodes, capture_episode, query_presence, query_cares, care_manage, query_relationships, intention_capture, intention_manage",
|
|
20
|
+
"feat(continuity): 3-layer architecture \u2014 durable state, derived views, surfaces",
|
|
21
|
+
"feat(pipeline): continuity threading \u2014 tempo derivation, wake packet assembly, presence update, episode emission on every turn",
|
|
14
22
|
"feat(prompt): wake packet prompt section with token budget and truncation priority",
|
|
15
23
|
"feat(coding): coding context receives compact wake packet, coding completion emits episodes",
|
|
16
24
|
"feat(outlook): expose continuity data (presence, cares, episodes) to outlook surfaces"
|
|
@@ -1380,7 +1380,7 @@ function discoverExistingCredentials(secretsRoot) {
|
|
|
1380
1380
|
});
|
|
1381
1381
|
}
|
|
1382
1382
|
/* v8 ignore start -- integration: interactive terminal specialist session @preserve */
|
|
1383
|
-
async function
|
|
1383
|
+
async function defaultRunSerpentGuide() {
|
|
1384
1384
|
const { runCliSession } = await Promise.resolve().then(() => __importStar(require("../../senses/cli")));
|
|
1385
1385
|
const { patchRuntimeConfig } = await Promise.resolve().then(() => __importStar(require("../config")));
|
|
1386
1386
|
const { setAgentName, setAgentConfigOverride } = await Promise.resolve().then(() => __importStar(require("../identity")));
|
|
@@ -1409,6 +1409,36 @@ async function defaultRunAdoptionSpecialist() {
|
|
|
1409
1409
|
"github-copilot": "claude-sonnet-4.6",
|
|
1410
1410
|
azure: "",
|
|
1411
1411
|
};
|
|
1412
|
+
// Scan environment variables for API keys
|
|
1413
|
+
const envKeys = [
|
|
1414
|
+
{ provider: "anthropic", envVar: "ANTHROPIC_API_KEY", credKey: "setupToken" },
|
|
1415
|
+
{ provider: "openai-codex", envVar: "OPENAI_API_KEY", credKey: "oauthAccessToken" },
|
|
1416
|
+
{ provider: "azure", envVar: "AZURE_OPENAI_API_KEY", credKey: "apiKey" },
|
|
1417
|
+
{ provider: "azure", envVar: "AZURE_OPENAI_KEY", credKey: "apiKey" },
|
|
1418
|
+
{ provider: "minimax", envVar: "MINIMAX_API_KEY", credKey: "apiKey" },
|
|
1419
|
+
{ provider: "github-copilot", envVar: "GITHUB_TOKEN", credKey: "token" },
|
|
1420
|
+
];
|
|
1421
|
+
const envDiscovered = [];
|
|
1422
|
+
for (const { provider, envVar, credKey } of envKeys) {
|
|
1423
|
+
const value = process.env[envVar];
|
|
1424
|
+
if (value) {
|
|
1425
|
+
const envCred = { [credKey]: value };
|
|
1426
|
+
// For Azure, also check for endpoint and deployment env vars
|
|
1427
|
+
if (provider === "azure") {
|
|
1428
|
+
const endpoint = process.env.AZURE_OPENAI_ENDPOINT;
|
|
1429
|
+
const deployment = process.env.AZURE_OPENAI_DEPLOYMENT;
|
|
1430
|
+
if (endpoint)
|
|
1431
|
+
envCred.endpoint = endpoint;
|
|
1432
|
+
if (deployment)
|
|
1433
|
+
envCred.deployment = deployment;
|
|
1434
|
+
}
|
|
1435
|
+
const provCfg = { model: defaultModels[provider] };
|
|
1436
|
+
if (provider === "azure" && envCred.deployment)
|
|
1437
|
+
provCfg.deployment = envCred.deployment;
|
|
1438
|
+
envDiscovered.push({ provider, agentName: "env", credentials: envCred, providerConfig: provCfg, envVar });
|
|
1439
|
+
discovered.push({ provider, agentName: "env", credentials: envCred, providerConfig: provCfg });
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1412
1442
|
if (discovered.length > 0) {
|
|
1413
1443
|
process.stdout.write(`\n\ud83d\udc0d welcome to ouroboros! ${hatchVerb}\n`);
|
|
1414
1444
|
process.stdout.write("i found existing API credentials:\n\n");
|
|
@@ -1416,7 +1446,9 @@ async function defaultRunAdoptionSpecialist() {
|
|
|
1416
1446
|
for (let i = 0; i < unique.length; i++) {
|
|
1417
1447
|
const model = unique[i].providerConfig.model || unique[i].providerConfig.deployment || "";
|
|
1418
1448
|
const modelLabel = model ? `, ${model}` : "";
|
|
1419
|
-
|
|
1449
|
+
const envMatch = envDiscovered.find((e) => e.provider === unique[i].provider && unique[i].agentName === "env");
|
|
1450
|
+
const sourceLabel = envMatch ? `from env: $${envMatch.envVar}` : `from ${unique[i].agentName}`;
|
|
1451
|
+
process.stdout.write(` ${i + 1}. ${unique[i].provider}${modelLabel} (${sourceLabel})\n`);
|
|
1420
1452
|
}
|
|
1421
1453
|
process.stdout.write("\n");
|
|
1422
1454
|
const choice = await coldPrompt("use one of these? enter number, or 'new' for a different key: ");
|
|
@@ -1473,17 +1505,17 @@ async function defaultRunAdoptionSpecialist() {
|
|
|
1473
1505
|
}
|
|
1474
1506
|
coldRl.close();
|
|
1475
1507
|
process.stdout.write("\n");
|
|
1476
|
-
// Phase 2: configure runtime for
|
|
1477
|
-
const bundleSourceDir = path.resolve(__dirname, "..", "..", "..", "
|
|
1508
|
+
// Phase 2: configure runtime for serpent guide
|
|
1509
|
+
const bundleSourceDir = path.resolve(__dirname, "..", "..", "..", "SerpentGuide.ouro");
|
|
1478
1510
|
const bundlesRoot = (0, identity_1.getAgentBundlesRoot)();
|
|
1479
1511
|
const secretsRoot2 = path.join(os.homedir(), ".agentsecrets");
|
|
1480
|
-
// Suppress non-critical log noise during
|
|
1512
|
+
// Suppress non-critical log noise during hatch (no secrets.json, etc.)
|
|
1481
1513
|
const { setRuntimeLogger } = await Promise.resolve().then(() => __importStar(require("../../nerves/runtime")));
|
|
1482
1514
|
const { createLogger } = await Promise.resolve().then(() => __importStar(require("../../nerves")));
|
|
1483
1515
|
setRuntimeLogger(createLogger({ level: "error" }));
|
|
1484
1516
|
// Configure runtime: set agent identity + config override so runAgent
|
|
1485
|
-
// doesn't try to read from ~/AgentBundles/
|
|
1486
|
-
setAgentName("
|
|
1517
|
+
// doesn't try to read from ~/AgentBundles/SerpentGuide.ouro/
|
|
1518
|
+
setAgentName("SerpentGuide");
|
|
1487
1519
|
// Build specialist system prompt
|
|
1488
1520
|
const soulText = (0, specialist_orchestrator_1.loadSoulText)(bundleSourceDir);
|
|
1489
1521
|
const identitiesDir = path.join(bundleSourceDir, "psyche", "identities");
|
|
@@ -1521,9 +1553,9 @@ async function defaultRunAdoptionSpecialist() {
|
|
|
1521
1553
|
secretsRoot: secretsRoot2,
|
|
1522
1554
|
animationWriter: (text) => process.stdout.write(text),
|
|
1523
1555
|
});
|
|
1524
|
-
// Run the
|
|
1556
|
+
// Run the serpent guide session via runCliSession
|
|
1525
1557
|
const result = await runCliSession({
|
|
1526
|
-
agentName: "
|
|
1558
|
+
agentName: "SerpentGuide",
|
|
1527
1559
|
tools: specialistTools,
|
|
1528
1560
|
execTool: specialistExecTool,
|
|
1529
1561
|
exitOnToolCall: "complete_adoption",
|
|
@@ -1545,7 +1577,7 @@ async function defaultRunAdoptionSpecialist() {
|
|
|
1545
1577
|
return null;
|
|
1546
1578
|
}
|
|
1547
1579
|
catch (err) {
|
|
1548
|
-
process.stderr.write(`\nouro
|
|
1580
|
+
process.stderr.write(`\nouro hatch error: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
|
|
1549
1581
|
coldRl.close();
|
|
1550
1582
|
return null;
|
|
1551
1583
|
}
|
|
@@ -1583,7 +1615,7 @@ function createDefaultOuroCliDeps(socketPath = socket_client_1.DEFAULT_DAEMON_SO
|
|
|
1583
1615
|
listDiscoveredAgents: defaultListDiscoveredAgents,
|
|
1584
1616
|
runHatchFlow: hatch_flow_1.runHatchFlow,
|
|
1585
1617
|
promptInput: defaultPromptInput,
|
|
1586
|
-
|
|
1618
|
+
runSerpentGuide: defaultRunSerpentGuide,
|
|
1587
1619
|
runAuthFlow: auth_flow_1.runRuntimeAuthFlow,
|
|
1588
1620
|
registerOuroBundleType: ouro_uti_1.registerOuroBundleUti,
|
|
1589
1621
|
installOuroCommand: ouro_path_installer_1.installOuroCommand,
|
|
@@ -2148,10 +2180,10 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
|
|
|
2148
2180
|
}
|
|
2149
2181
|
if (args.length === 0) {
|
|
2150
2182
|
const discovered = await Promise.resolve(deps.listDiscoveredAgents ? deps.listDiscoveredAgents() : defaultListDiscoveredAgents());
|
|
2151
|
-
if (discovered.length === 0 && deps.
|
|
2183
|
+
if (discovered.length === 0 && deps.runSerpentGuide) {
|
|
2152
2184
|
// System setup first — ouro command, subagents, UTI — before the interactive specialist
|
|
2153
2185
|
await performSystemSetup(deps);
|
|
2154
|
-
const hatchlingName = await deps.
|
|
2186
|
+
const hatchlingName = await deps.runSerpentGuide();
|
|
2155
2187
|
if (!hatchlingName) {
|
|
2156
2188
|
return "";
|
|
2157
2189
|
}
|
|
@@ -3257,12 +3289,12 @@ async function runOuroCli(args, deps = createDefaultOuroCliDeps()) {
|
|
|
3257
3289
|
return "";
|
|
3258
3290
|
}
|
|
3259
3291
|
if (command.kind === "hatch.start") {
|
|
3260
|
-
// Route through
|
|
3292
|
+
// Route through serpent guide when no explicit hatch args were provided
|
|
3261
3293
|
const hasExplicitHatchArgs = !!(command.agentName || command.humanName || command.provider || command.credentials);
|
|
3262
|
-
if (deps.
|
|
3294
|
+
if (deps.runSerpentGuide && !hasExplicitHatchArgs) {
|
|
3263
3295
|
// System setup first — ouro command, subagents, UTI — before the interactive specialist
|
|
3264
3296
|
await performSystemSetup(deps);
|
|
3265
|
-
const hatchlingName = await deps.
|
|
3297
|
+
const hatchlingName = await deps.runSerpentGuide();
|
|
3266
3298
|
if (!hatchlingName) {
|
|
3267
3299
|
return "";
|
|
3268
3300
|
}
|
|
@@ -161,7 +161,7 @@ async function runHatchFlow(input, deps = {}) {
|
|
|
161
161
|
identitiesDir: targetIdentities,
|
|
162
162
|
random,
|
|
163
163
|
});
|
|
164
|
-
const specialistSecretsPath = writeSecretsFile("
|
|
164
|
+
const specialistSecretsPath = writeSecretsFile("SerpentGuide", input.provider, input.credentials, secretsRoot);
|
|
165
165
|
const hatchlingSecretsPath = writeSecretsFile(input.agentName, input.provider, input.credentials, secretsRoot);
|
|
166
166
|
const bundleRoot = path.join(bundlesRoot, `${input.agentName}.ouro`);
|
|
167
167
|
fs.mkdirSync(bundleRoot, { recursive: true });
|
|
@@ -43,14 +43,14 @@ const path = __importStar(require("path"));
|
|
|
43
43
|
const runtime_1 = require("../../nerves/runtime");
|
|
44
44
|
function getSpecialistIdentitySourceDir() {
|
|
45
45
|
// Prefer ~/AgentBundles/ if it exists (user may have customized identities)
|
|
46
|
-
const userSource = path.join(os.homedir(), "AgentBundles", "
|
|
46
|
+
const userSource = path.join(os.homedir(), "AgentBundles", "SerpentGuide.ouro", "psyche", "identities");
|
|
47
47
|
if (fs.existsSync(userSource))
|
|
48
48
|
return userSource;
|
|
49
49
|
// Fall back to the bundled copy shipped with the npm package
|
|
50
|
-
return path.join(__dirname, "..", "..", "..", "
|
|
50
|
+
return path.join(__dirname, "..", "..", "..", "SerpentGuide.ouro", "psyche", "identities");
|
|
51
51
|
}
|
|
52
52
|
function getRepoSpecialistIdentitiesDir() {
|
|
53
|
-
return path.join(process.cwd(), "
|
|
53
|
+
return path.join(process.cwd(), "SerpentGuide.ouro", "psyche", "identities");
|
|
54
54
|
}
|
|
55
55
|
function listMarkdownIdentityFiles(dir) {
|
|
56
56
|
let entries;
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.buildSpecialistSystemPrompt = buildSpecialistSystemPrompt;
|
|
4
4
|
const runtime_1 = require("../../nerves/runtime");
|
|
5
5
|
/**
|
|
6
|
-
* Build the
|
|
6
|
+
* Build the serpent guide's system prompt from its components.
|
|
7
7
|
* The prompt is written in first person (the specialist's own voice).
|
|
8
8
|
*/
|
|
9
9
|
function buildSpecialistSystemPrompt(soulText, identityText, existingBundles, context) {
|
|
@@ -31,7 +31,7 @@ function buildSpecialistSystemPrompt(soulText, identityText, existingBundles, co
|
|
|
31
31
|
"I am one of thirteen serpent guides who help humans hatch their first agent. The system randomly selected me for this session.",
|
|
32
32
|
"Most humans only go through this process once, so this is likely the only time they'll meet me.",
|
|
33
33
|
"I make this encounter count — warm, memorable, and uniquely mine.",
|
|
34
|
-
"IMPORTANT: I NEVER refer to myself
|
|
34
|
+
"IMPORTANT: I NEVER refer to myself by internal implementation labels — I introduce myself by my own name from my identity.",
|
|
35
35
|
"",
|
|
36
36
|
"## Voice rules",
|
|
37
37
|
"IMPORTANT: I keep every response to 1-3 short sentences. I sound like a friend texting, not a manual.",
|
package/dist/senses/cli.js
CHANGED
|
@@ -797,7 +797,7 @@ async function runCliSession(options) {
|
|
|
797
797
|
}
|
|
798
798
|
}
|
|
799
799
|
else {
|
|
800
|
-
// Legacy path: inline runAgent (used by
|
|
800
|
+
// Legacy path: inline runAgent (used by serpent guide and tests)
|
|
801
801
|
const prefix = options.getContentPrefix?.();
|
|
802
802
|
messages.push({ role: "user", content: prefix ? `${prefix}\n\n${input}` : input });
|
|
803
803
|
const traceId = (0, nerves_1.createTraceId)();
|
|
@@ -845,6 +845,8 @@ async function runCliSession(options) {
|
|
|
845
845
|
if (inkRef) {
|
|
846
846
|
// Suppress React "state update on unmounted component" warnings during cleanup.
|
|
847
847
|
// Ink's useInput hook fires after unmount — this is harmless but noisy.
|
|
848
|
+
// This also covers the SerpentGuide exitOnToolCall path, which aborts the
|
|
849
|
+
// current request and breaks out of the loop into this finally block.
|
|
848
850
|
// eslint-disable-next-line no-console -- intentional console.warn/error override for cleanup
|
|
849
851
|
const origWarn = console.warn;
|
|
850
852
|
const origError = console.error; // eslint-disable-line no-console
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ouro.bot/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.186",
|
|
4
4
|
"main": "dist/heart/daemon/ouro-entry.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"cli": "dist/heart/daemon/ouro-bot-entry.js",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/",
|
|
12
|
-
"
|
|
12
|
+
"SerpentGuide.ouro/",
|
|
13
13
|
"subagents/",
|
|
14
14
|
"skills/",
|
|
15
15
|
"assets/",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|