@ouro.bot/cli 0.1.0-alpha.184 → 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 +19 -2
- package/dist/heart/active-work.js +19 -10
- package/dist/heart/agent-relationships.js +161 -0
- package/dist/heart/cares.js +174 -0
- 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/outlook-read.js +40 -0
- package/dist/heart/daemon/specialist-prompt.js +2 -2
- package/dist/heart/intentions.js +168 -0
- package/dist/heart/obligations.js +23 -0
- package/dist/heart/presence.js +185 -0
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/wake-packet.js +226 -0
- package/dist/mind/episodes.js +116 -0
- package/dist/mind/prompt.js +10 -1
- package/dist/repertoire/coding/context-pack.js +25 -2
- package/dist/repertoire/tools-base.js +240 -0
- package/dist/senses/cli.js +3 -1
- package/dist/senses/pipeline.js +88 -0
- 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
|
@@ -62,6 +62,11 @@ const obligations_1 = require("../mind/obligations");
|
|
|
62
62
|
const progress_story_1 = require("../heart/progress-story");
|
|
63
63
|
const cross_chat_delivery_1 = require("../heart/cross-chat-delivery");
|
|
64
64
|
const obligations_2 = require("../heart/obligations");
|
|
65
|
+
const episodes_1 = require("../mind/episodes");
|
|
66
|
+
const cares_1 = require("../heart/cares");
|
|
67
|
+
const agent_relationships_1 = require("../heart/agent-relationships");
|
|
68
|
+
const presence_1 = require("../heart/presence");
|
|
69
|
+
const intentions_1 = require("../heart/intentions");
|
|
65
70
|
// Tracks which file paths have been read via read_file in this session.
|
|
66
71
|
// edit_file requires a file to be read first (must-read-first guard).
|
|
67
72
|
exports.editFileReadTracker = new Set();
|
|
@@ -1498,6 +1503,241 @@ exports.baseToolDefinitions = [
|
|
|
1498
1503
|
requiredCapability: "reasoning-effort",
|
|
1499
1504
|
summaryKeys: ["level"],
|
|
1500
1505
|
},
|
|
1506
|
+
// ── Continuity tools ──────────────────────────────────────────────
|
|
1507
|
+
{
|
|
1508
|
+
tool: {
|
|
1509
|
+
type: "function",
|
|
1510
|
+
function: {
|
|
1511
|
+
name: "query_episodes",
|
|
1512
|
+
description: "Query recent episodes from my continuity memory. Returns timestamped records of significant events (obligation shifts, coding milestones, bridge events, care events, turning points).",
|
|
1513
|
+
parameters: {
|
|
1514
|
+
type: "object",
|
|
1515
|
+
properties: {
|
|
1516
|
+
limit: { type: "number", description: "Maximum episodes to return (default 20)" },
|
|
1517
|
+
kind: { type: "string", description: "Filter by episode kind: obligation_shift, coding_milestone, bridge_event, care_event, tempo_shift, turning_point" },
|
|
1518
|
+
since: { type: "string", description: "ISO timestamp — only return episodes after this time" },
|
|
1519
|
+
},
|
|
1520
|
+
},
|
|
1521
|
+
},
|
|
1522
|
+
},
|
|
1523
|
+
handler: (a) => {
|
|
1524
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
1525
|
+
const options = {};
|
|
1526
|
+
if (a.limit)
|
|
1527
|
+
options.limit = parseInt(a.limit, 10);
|
|
1528
|
+
if (a.kind)
|
|
1529
|
+
options.kinds = [a.kind];
|
|
1530
|
+
if (a.since)
|
|
1531
|
+
options.since = a.since;
|
|
1532
|
+
const episodes = (0, episodes_1.readRecentEpisodes)(agentRoot, options);
|
|
1533
|
+
(0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.query_episodes", message: `queried ${episodes.length} episodes`, meta: { count: episodes.length } });
|
|
1534
|
+
return JSON.stringify(episodes, null, 2);
|
|
1535
|
+
},
|
|
1536
|
+
},
|
|
1537
|
+
{
|
|
1538
|
+
tool: {
|
|
1539
|
+
type: "function",
|
|
1540
|
+
function: {
|
|
1541
|
+
name: "capture_episode",
|
|
1542
|
+
description: "Record a turning point or significant moment. This is my tool for saying 'that was important — keep it.' Nearly frictionless: only summary and whyItMattered required.",
|
|
1543
|
+
parameters: {
|
|
1544
|
+
type: "object",
|
|
1545
|
+
properties: {
|
|
1546
|
+
summary: { type: "string", description: "What happened" },
|
|
1547
|
+
whyItMattered: { type: "string", description: "Why this was significant" },
|
|
1548
|
+
kind: { type: "string", description: "Episode kind (default: turning_point)" },
|
|
1549
|
+
salience: { type: "string", description: "low, medium, high, or critical (default: medium)" },
|
|
1550
|
+
},
|
|
1551
|
+
required: ["summary", "whyItMattered"],
|
|
1552
|
+
},
|
|
1553
|
+
},
|
|
1554
|
+
},
|
|
1555
|
+
handler: (a) => {
|
|
1556
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
1557
|
+
const episode = (0, episodes_1.emitEpisode)(agentRoot, {
|
|
1558
|
+
kind: a.kind ?? "turning_point",
|
|
1559
|
+
summary: a.summary,
|
|
1560
|
+
whyItMattered: a.whyItMattered,
|
|
1561
|
+
relatedEntities: [],
|
|
1562
|
+
salience: a.salience ?? "medium",
|
|
1563
|
+
});
|
|
1564
|
+
(0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.capture_episode", message: `captured episode ${episode.id}`, meta: { id: episode.id } });
|
|
1565
|
+
return JSON.stringify(episode, null, 2);
|
|
1566
|
+
},
|
|
1567
|
+
},
|
|
1568
|
+
{
|
|
1569
|
+
tool: {
|
|
1570
|
+
type: "function",
|
|
1571
|
+
function: {
|
|
1572
|
+
name: "query_presence",
|
|
1573
|
+
description: "Check who's around — my own availability/lane and known peer agents.",
|
|
1574
|
+
parameters: { type: "object", properties: {} },
|
|
1575
|
+
},
|
|
1576
|
+
},
|
|
1577
|
+
handler: () => {
|
|
1578
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
1579
|
+
const agentName = (0, identity_1.getAgentName)();
|
|
1580
|
+
const self = (0, presence_1.readPresence)(agentRoot, agentName);
|
|
1581
|
+
const peers = (0, presence_1.readPeerPresence)(agentRoot);
|
|
1582
|
+
(0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.query_presence", message: `presence: self + ${peers.length} peers`, meta: { peerCount: peers.length } });
|
|
1583
|
+
return JSON.stringify({ self, peers }, null, 2);
|
|
1584
|
+
},
|
|
1585
|
+
},
|
|
1586
|
+
{
|
|
1587
|
+
tool: {
|
|
1588
|
+
type: "function",
|
|
1589
|
+
function: {
|
|
1590
|
+
name: "query_cares",
|
|
1591
|
+
description: "Query things I care about — ongoing concerns, watched situations, projects, people.",
|
|
1592
|
+
parameters: {
|
|
1593
|
+
type: "object",
|
|
1594
|
+
properties: {
|
|
1595
|
+
status: { type: "string", description: "Filter by status: 'active', 'watching', 'resolved', 'dormant', or 'all' (default: active cares only)" },
|
|
1596
|
+
},
|
|
1597
|
+
},
|
|
1598
|
+
},
|
|
1599
|
+
},
|
|
1600
|
+
handler: (a) => {
|
|
1601
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
1602
|
+
const cares = a.status === "all" ? (0, cares_1.readCares)(agentRoot) : (0, cares_1.readActiveCares)(agentRoot);
|
|
1603
|
+
(0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.query_cares", message: `queried ${cares.length} cares`, meta: { count: cares.length } });
|
|
1604
|
+
return JSON.stringify(cares, null, 2);
|
|
1605
|
+
},
|
|
1606
|
+
},
|
|
1607
|
+
{
|
|
1608
|
+
tool: {
|
|
1609
|
+
type: "function",
|
|
1610
|
+
function: {
|
|
1611
|
+
name: "care_manage",
|
|
1612
|
+
description: "Create, update, or resolve a care. Cares are things I watch over — people, projects, missions, system health.",
|
|
1613
|
+
parameters: {
|
|
1614
|
+
type: "object",
|
|
1615
|
+
properties: {
|
|
1616
|
+
action: { type: "string", enum: ["create", "update", "resolve"], description: "What to do" },
|
|
1617
|
+
id: { type: "string", description: "Care ID (required for update/resolve)" },
|
|
1618
|
+
label: { type: "string", description: "Short label for the care" },
|
|
1619
|
+
why: { type: "string", description: "Why this matters" },
|
|
1620
|
+
salience: { type: "string", description: "low, medium, high, or critical" },
|
|
1621
|
+
kind: { type: "string", description: "person, agent, project, mission, or system" },
|
|
1622
|
+
stewardship: { type: "string", description: "mine, shared, or delegated" },
|
|
1623
|
+
},
|
|
1624
|
+
required: ["action"],
|
|
1625
|
+
},
|
|
1626
|
+
},
|
|
1627
|
+
},
|
|
1628
|
+
handler: (a) => {
|
|
1629
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
1630
|
+
let result;
|
|
1631
|
+
if (a.action === "create") {
|
|
1632
|
+
result = (0, cares_1.createCare)(agentRoot, {
|
|
1633
|
+
label: a.label ?? "untitled",
|
|
1634
|
+
why: a.why ?? "",
|
|
1635
|
+
kind: a.kind ?? "project",
|
|
1636
|
+
status: "active",
|
|
1637
|
+
salience: a.salience ?? "medium",
|
|
1638
|
+
steward: a.stewardship ?? "mine",
|
|
1639
|
+
relatedFriendIds: [],
|
|
1640
|
+
relatedAgentIds: [],
|
|
1641
|
+
relatedObligationIds: [],
|
|
1642
|
+
relatedEpisodeIds: [],
|
|
1643
|
+
currentRisk: null,
|
|
1644
|
+
nextCheckAt: null,
|
|
1645
|
+
});
|
|
1646
|
+
}
|
|
1647
|
+
else if (a.action === "update") {
|
|
1648
|
+
const updates = {};
|
|
1649
|
+
if (a.label)
|
|
1650
|
+
updates.label = a.label;
|
|
1651
|
+
if (a.why)
|
|
1652
|
+
updates.why = a.why;
|
|
1653
|
+
if (a.salience)
|
|
1654
|
+
updates.salience = a.salience;
|
|
1655
|
+
result = (0, cares_1.updateCare)(agentRoot, a.id, updates);
|
|
1656
|
+
}
|
|
1657
|
+
else if (a.action === "resolve") {
|
|
1658
|
+
result = (0, cares_1.resolveCare)(agentRoot, a.id);
|
|
1659
|
+
}
|
|
1660
|
+
(0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.care_manage", message: `care ${a.action}`, meta: { action: a.action, id: a.id } });
|
|
1661
|
+
return JSON.stringify(result, null, 2);
|
|
1662
|
+
},
|
|
1663
|
+
},
|
|
1664
|
+
{
|
|
1665
|
+
tool: {
|
|
1666
|
+
type: "function",
|
|
1667
|
+
function: {
|
|
1668
|
+
name: "query_relationships",
|
|
1669
|
+
description: "Query known agent relationships — familiarity, trust, shared missions, interaction history.",
|
|
1670
|
+
parameters: {
|
|
1671
|
+
type: "object",
|
|
1672
|
+
properties: {
|
|
1673
|
+
agentName: { type: "string", description: "Specific agent name to query (omit for all)" },
|
|
1674
|
+
},
|
|
1675
|
+
},
|
|
1676
|
+
},
|
|
1677
|
+
},
|
|
1678
|
+
handler: (a) => {
|
|
1679
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
1680
|
+
const result = a.agentName
|
|
1681
|
+
? (0, agent_relationships_1.readRelationship)(agentRoot, a.agentName)
|
|
1682
|
+
: (0, agent_relationships_1.readRelationships)(agentRoot);
|
|
1683
|
+
(0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.query_relationships", message: `queried relationships`, meta: { agentName: a.agentName ?? "all" } });
|
|
1684
|
+
return JSON.stringify(result, null, 2);
|
|
1685
|
+
},
|
|
1686
|
+
},
|
|
1687
|
+
{
|
|
1688
|
+
tool: {
|
|
1689
|
+
type: "function",
|
|
1690
|
+
function: {
|
|
1691
|
+
name: "intention_capture",
|
|
1692
|
+
description: "File a lightweight mental note — something I want to do or check later, below the ceremony threshold of tasks or cares. Cheap to create, easy to close.",
|
|
1693
|
+
parameters: {
|
|
1694
|
+
type: "object",
|
|
1695
|
+
properties: {
|
|
1696
|
+
content: { type: "string", description: "What I want to remember to do" },
|
|
1697
|
+
salience: { type: "string", description: "low, medium, or high (default: low)" },
|
|
1698
|
+
nudgeAfter: { type: "string", description: "ISO timestamp — nudge me after this time" },
|
|
1699
|
+
},
|
|
1700
|
+
required: ["content"],
|
|
1701
|
+
},
|
|
1702
|
+
},
|
|
1703
|
+
},
|
|
1704
|
+
handler: (a) => {
|
|
1705
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
1706
|
+
const intention = (0, intentions_1.captureIntention)(agentRoot, {
|
|
1707
|
+
content: a.content,
|
|
1708
|
+
salience: a.salience ?? "low",
|
|
1709
|
+
source: "tool",
|
|
1710
|
+
...(a.nudgeAfter ? { nudgeAfter: a.nudgeAfter } : {}),
|
|
1711
|
+
});
|
|
1712
|
+
(0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.intention_capture", message: `captured intention ${intention.id}`, meta: { id: intention.id } });
|
|
1713
|
+
return JSON.stringify(intention, null, 2);
|
|
1714
|
+
},
|
|
1715
|
+
},
|
|
1716
|
+
{
|
|
1717
|
+
tool: {
|
|
1718
|
+
type: "function",
|
|
1719
|
+
function: {
|
|
1720
|
+
name: "intention_manage",
|
|
1721
|
+
description: "Resolve or dismiss an intention. Resolve = done. Dismiss = no longer relevant. Both remove it from active list.",
|
|
1722
|
+
parameters: {
|
|
1723
|
+
type: "object",
|
|
1724
|
+
properties: {
|
|
1725
|
+
action: { type: "string", enum: ["resolve", "dismiss"], description: "What to do" },
|
|
1726
|
+
id: { type: "string", description: "Intention ID" },
|
|
1727
|
+
},
|
|
1728
|
+
required: ["action", "id"],
|
|
1729
|
+
},
|
|
1730
|
+
},
|
|
1731
|
+
},
|
|
1732
|
+
handler: (a) => {
|
|
1733
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
1734
|
+
const result = a.action === "resolve"
|
|
1735
|
+
? (0, intentions_1.resolveIntention)(agentRoot, a.id)
|
|
1736
|
+
: (0, intentions_1.dismissIntention)(agentRoot, a.id);
|
|
1737
|
+
(0, runtime_1.emitNervesEvent)({ component: "repertoire", event: "repertoire.intention_manage", message: `intention ${a.action}: ${a.id}`, meta: { action: a.action, id: a.id } });
|
|
1738
|
+
return JSON.stringify(result, null, 2);
|
|
1739
|
+
},
|
|
1740
|
+
},
|
|
1501
1741
|
...tools_1.codingToolDefinitions,
|
|
1502
1742
|
];
|
|
1503
1743
|
exports.tools = exports.baseToolDefinitions.map((d) => d.tool);
|
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/dist/senses/pipeline.js
CHANGED
|
@@ -38,6 +38,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
38
38
|
};
|
|
39
39
|
})();
|
|
40
40
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
+
exports.emitObligationTransitionEpisodes = emitObligationTransitionEpisodes;
|
|
41
42
|
exports.handleInboundTurn = handleInboundTurn;
|
|
42
43
|
const runtime_1 = require("../nerves/runtime");
|
|
43
44
|
const commands_1 = require("./commands");
|
|
@@ -58,6 +59,32 @@ const obligations_2 = require("../mind/obligations");
|
|
|
58
59
|
const provider_failover_1 = require("../heart/provider-failover");
|
|
59
60
|
const provider_ping_1 = require("../heart/provider-ping");
|
|
60
61
|
const auth_flow_1 = require("../heart/daemon/auth-flow");
|
|
62
|
+
const tempo_1 = require("../heart/tempo");
|
|
63
|
+
const temporal_view_1 = require("../heart/temporal-view");
|
|
64
|
+
const wake_packet_1 = require("../heart/wake-packet");
|
|
65
|
+
const presence_1 = require("../heart/presence");
|
|
66
|
+
const episodes_1 = require("../mind/episodes");
|
|
67
|
+
const cares_1 = require("../heart/cares");
|
|
68
|
+
/**
|
|
69
|
+
* Emit episodes for obligation state transitions detected during a turn.
|
|
70
|
+
* Exported for direct testability (avoids v8 coverage merge issues in multi-file test suites).
|
|
71
|
+
*/
|
|
72
|
+
function emitObligationTransitionEpisodes(agentRoot, preTurnObligationIds, postTurnObligations, preTurnObligations) {
|
|
73
|
+
const postTurnObligationIds = new Set(postTurnObligations.map((ob) => `${ob.id}:${ob.status}`));
|
|
74
|
+
for (const key of preTurnObligationIds) {
|
|
75
|
+
if (!postTurnObligationIds.has(key)) {
|
|
76
|
+
const [obId] = key.split(":");
|
|
77
|
+
const matchedOb = postTurnObligations.find((ob) => ob.id === obId) ?? preTurnObligations.find((ob) => ob.id === obId);
|
|
78
|
+
(0, episodes_1.emitEpisode)(agentRoot, {
|
|
79
|
+
kind: "obligation_shift",
|
|
80
|
+
summary: `obligation "${matchedOb?.content ?? obId}" status changed`,
|
|
81
|
+
whyItMattered: "obligation state transition detected during turn",
|
|
82
|
+
relatedEntities: [`obligation:${obId}`],
|
|
83
|
+
salience: "medium",
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
61
88
|
function emptyTaskBoard() {
|
|
62
89
|
return {
|
|
63
90
|
compact: "",
|
|
@@ -430,6 +457,57 @@ async function handleInboundTurn(input) {
|
|
|
430
457
|
for (const msg of input.messages) {
|
|
431
458
|
sessionMessages.push(msg);
|
|
432
459
|
}
|
|
460
|
+
// Step 4b: Continuity pipeline — derive tempo, build wake packet, snapshot obligations
|
|
461
|
+
let renderedWakePacket;
|
|
462
|
+
const preTurnObligationIds = new Set(pendingObligations.map((ob) => `${ob.id}:${ob.status}`));
|
|
463
|
+
try {
|
|
464
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
465
|
+
const agentName = (0, identity_1.getAgentName)();
|
|
466
|
+
const recentEpisodes = (0, episodes_1.readRecentEpisodes)(agentRoot, { limit: 20 });
|
|
467
|
+
const activeCares = (0, cares_1.readActiveCares)(agentRoot);
|
|
468
|
+
const tempoState = (0, tempo_1.deriveTempo)({
|
|
469
|
+
activeSessions: sessionActivity.length + 1,
|
|
470
|
+
openObligations: pendingObligations.length,
|
|
471
|
+
recentEpisodeCount: recentEpisodes.length,
|
|
472
|
+
lastActivityAgeMs: sessionActivity.length > 0
|
|
473
|
+
? Date.now() - new Date(sessionActivity[0].lastActivityAt).getTime()
|
|
474
|
+
: 0,
|
|
475
|
+
hasBlockers: false, // obligations use specific statuses, not "blocked"
|
|
476
|
+
highSalienceEpisodes: recentEpisodes.filter((ep) => ep.salience === "high" || ep.salience === "critical").length,
|
|
477
|
+
activeCareCount: activeCares.length,
|
|
478
|
+
atRiskCareCount: activeCares.filter((c) => c.currentRisk != null).length,
|
|
479
|
+
});
|
|
480
|
+
const temporalView = (0, temporal_view_1.buildTemporalView)(agentRoot, {
|
|
481
|
+
tempo: tempoState.mode,
|
|
482
|
+
preloaded: {
|
|
483
|
+
recentEpisodes,
|
|
484
|
+
activeObligations: pendingObligations,
|
|
485
|
+
activeCares,
|
|
486
|
+
},
|
|
487
|
+
});
|
|
488
|
+
const wakePacket = (0, wake_packet_1.buildWakePacket)(temporalView);
|
|
489
|
+
renderedWakePacket = (0, wake_packet_1.renderWakePacket)(wakePacket);
|
|
490
|
+
if (!renderedWakePacket)
|
|
491
|
+
renderedWakePacket = undefined;
|
|
492
|
+
// Update self-presence
|
|
493
|
+
const presence = (0, presence_1.derivePresence)(agentRoot, agentName, {
|
|
494
|
+
activeSessions: sessionActivity.length + 1,
|
|
495
|
+
openObligations: pendingObligations.length,
|
|
496
|
+
activeBridges: activeBridges.length,
|
|
497
|
+
codingLanes: codingSessions.length,
|
|
498
|
+
currentTempo: tempoState.mode,
|
|
499
|
+
});
|
|
500
|
+
(0, presence_1.writePresence)(agentRoot, agentName, presence);
|
|
501
|
+
}
|
|
502
|
+
catch (continuityError) {
|
|
503
|
+
(0, runtime_1.emitNervesEvent)({
|
|
504
|
+
level: "warn",
|
|
505
|
+
component: "senses",
|
|
506
|
+
event: "senses.continuity_error",
|
|
507
|
+
message: "continuity pipeline failed, continuing without wake packet",
|
|
508
|
+
meta: { error: continuityError instanceof Error ? continuityError.message : String(continuityError) },
|
|
509
|
+
});
|
|
510
|
+
}
|
|
433
511
|
// Step 5: runAgent
|
|
434
512
|
const existingToolContext = input.runAgentOptions?.toolContext;
|
|
435
513
|
const runAgentOptions = {
|
|
@@ -437,6 +515,7 @@ async function handleInboundTurn(input) {
|
|
|
437
515
|
bridgeContext,
|
|
438
516
|
activeWorkFrame,
|
|
439
517
|
delegationDecision,
|
|
518
|
+
wakePacket: renderedWakePacket,
|
|
440
519
|
pendingMessages: pending.length > 0 ? pending.map((msg) => ({ from: msg.from, content: msg.content })) : undefined,
|
|
441
520
|
currentSessionKey: currentSession.key,
|
|
442
521
|
currentObligation,
|
|
@@ -501,6 +580,15 @@ async function handleInboundTurn(input) {
|
|
|
501
580
|
}
|
|
502
581
|
/* v8 ignore stop */
|
|
503
582
|
}
|
|
583
|
+
// Step 5c: Emit episodes for obligation state transitions
|
|
584
|
+
try {
|
|
585
|
+
const agentRoot = (0, identity_1.getAgentRoot)();
|
|
586
|
+
const postTurnObligations = (0, obligations_1.readPendingObligations)(agentRoot);
|
|
587
|
+
emitObligationTransitionEpisodes(agentRoot, preTurnObligationIds, postTurnObligations, pendingObligations);
|
|
588
|
+
}
|
|
589
|
+
catch {
|
|
590
|
+
// Episode emission is non-fatal
|
|
591
|
+
}
|
|
504
592
|
// Step 6: postTurn
|
|
505
593
|
const continuingState = {
|
|
506
594
|
...(mustResolveBeforeHandoff ? { mustResolveBeforeHandoff: true } : {}),
|
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
|