@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
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.captureIntention = captureIntention;
|
|
37
|
+
exports.readOpenIntentions = readOpenIntentions;
|
|
38
|
+
exports.resolveIntention = resolveIntention;
|
|
39
|
+
exports.dismissIntention = dismissIntention;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const runtime_1 = require("../nerves/runtime");
|
|
43
|
+
function intentionsDir(agentRoot) {
|
|
44
|
+
return path.join(agentRoot, "state", "intentions");
|
|
45
|
+
}
|
|
46
|
+
function intentionFilePath(agentRoot, id) {
|
|
47
|
+
return path.join(intentionsDir(agentRoot), `${id}.json`);
|
|
48
|
+
}
|
|
49
|
+
function generateId() {
|
|
50
|
+
const timestamp = Date.now();
|
|
51
|
+
const random = Math.random().toString(36).slice(2, 10);
|
|
52
|
+
return `int-${timestamp}-${random}`;
|
|
53
|
+
}
|
|
54
|
+
const SALIENCE_ORDER = {
|
|
55
|
+
high: 3,
|
|
56
|
+
medium: 2,
|
|
57
|
+
low: 1,
|
|
58
|
+
};
|
|
59
|
+
function salienceRank(salience) {
|
|
60
|
+
if (!salience)
|
|
61
|
+
return 0;
|
|
62
|
+
return SALIENCE_ORDER[salience] ?? 0;
|
|
63
|
+
}
|
|
64
|
+
function captureIntention(agentRoot, input) {
|
|
65
|
+
const now = new Date().toISOString();
|
|
66
|
+
const id = generateId();
|
|
67
|
+
const intention = {
|
|
68
|
+
id,
|
|
69
|
+
content: input.content,
|
|
70
|
+
status: "open",
|
|
71
|
+
createdAt: now,
|
|
72
|
+
updatedAt: now,
|
|
73
|
+
...(input.salience ? { salience: input.salience } : {}),
|
|
74
|
+
source: input.source,
|
|
75
|
+
...(input.relatedFriendId ? { relatedFriendId: input.relatedFriendId } : {}),
|
|
76
|
+
...(input.relatedObligationId ? { relatedObligationId: input.relatedObligationId } : {}),
|
|
77
|
+
...(input.relatedCareId ? { relatedCareId: input.relatedCareId } : {}),
|
|
78
|
+
...(input.nudgeAfter ? { nudgeAfter: input.nudgeAfter } : {}),
|
|
79
|
+
};
|
|
80
|
+
const dir = intentionsDir(agentRoot);
|
|
81
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
82
|
+
fs.writeFileSync(intentionFilePath(agentRoot, id), JSON.stringify(intention, null, 2), "utf-8");
|
|
83
|
+
(0, runtime_1.emitNervesEvent)({
|
|
84
|
+
component: "heart",
|
|
85
|
+
event: "heart.intention_captured",
|
|
86
|
+
message: `intention captured: ${input.content.slice(0, 60)}`,
|
|
87
|
+
meta: { intentionId: id, source: input.source, salience: input.salience },
|
|
88
|
+
});
|
|
89
|
+
return intention;
|
|
90
|
+
}
|
|
91
|
+
function readOpenIntentions(agentRoot, options) {
|
|
92
|
+
const dir = intentionsDir(agentRoot);
|
|
93
|
+
if (!fs.existsSync(dir)) {
|
|
94
|
+
(0, runtime_1.emitNervesEvent)({
|
|
95
|
+
component: "heart",
|
|
96
|
+
event: "heart.intentions_read",
|
|
97
|
+
message: "read intentions: directory missing, returning empty",
|
|
98
|
+
meta: { count: 0 },
|
|
99
|
+
});
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
const limit = options?.limit ?? 20;
|
|
103
|
+
const files = fs.readdirSync(dir).filter((f) => f.endsWith(".json"));
|
|
104
|
+
const intentions = [];
|
|
105
|
+
for (const file of files) {
|
|
106
|
+
try {
|
|
107
|
+
const content = fs.readFileSync(path.join(dir, file), "utf-8");
|
|
108
|
+
const intention = JSON.parse(content);
|
|
109
|
+
if (intention.status === "open") {
|
|
110
|
+
intentions.push(intention);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// Skip malformed JSON files
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Sort by salience descending, then createdAt descending
|
|
118
|
+
intentions.sort((a, b) => {
|
|
119
|
+
const salienceDiff = salienceRank(b.salience) - salienceRank(a.salience);
|
|
120
|
+
if (salienceDiff !== 0)
|
|
121
|
+
return salienceDiff;
|
|
122
|
+
return b.createdAt.localeCompare(a.createdAt);
|
|
123
|
+
});
|
|
124
|
+
const result = intentions.slice(0, limit);
|
|
125
|
+
(0, runtime_1.emitNervesEvent)({
|
|
126
|
+
component: "heart",
|
|
127
|
+
event: "heart.intentions_read",
|
|
128
|
+
message: `read ${result.length} open intentions`,
|
|
129
|
+
meta: { count: result.length, total: intentions.length, limit },
|
|
130
|
+
});
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
function readIntentionFile(agentRoot, id) {
|
|
134
|
+
const filePath = intentionFilePath(agentRoot, id);
|
|
135
|
+
if (!fs.existsSync(filePath)) {
|
|
136
|
+
throw new Error(`Intention not found: ${id}`);
|
|
137
|
+
}
|
|
138
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
139
|
+
}
|
|
140
|
+
function writeIntentionFile(agentRoot, intention) {
|
|
141
|
+
fs.writeFileSync(intentionFilePath(agentRoot, intention.id), JSON.stringify(intention, null, 2), "utf-8");
|
|
142
|
+
}
|
|
143
|
+
function resolveIntention(agentRoot, id) {
|
|
144
|
+
const intention = readIntentionFile(agentRoot, id);
|
|
145
|
+
intention.status = "done";
|
|
146
|
+
intention.updatedAt = new Date().toISOString();
|
|
147
|
+
writeIntentionFile(agentRoot, intention);
|
|
148
|
+
(0, runtime_1.emitNervesEvent)({
|
|
149
|
+
component: "heart",
|
|
150
|
+
event: "heart.intention_resolved",
|
|
151
|
+
message: `intention resolved: ${intention.content.slice(0, 60)}`,
|
|
152
|
+
meta: { intentionId: id },
|
|
153
|
+
});
|
|
154
|
+
return intention;
|
|
155
|
+
}
|
|
156
|
+
function dismissIntention(agentRoot, id) {
|
|
157
|
+
const intention = readIntentionFile(agentRoot, id);
|
|
158
|
+
intention.status = "dismissed";
|
|
159
|
+
intention.updatedAt = new Date().toISOString();
|
|
160
|
+
writeIntentionFile(agentRoot, intention);
|
|
161
|
+
(0, runtime_1.emitNervesEvent)({
|
|
162
|
+
component: "heart",
|
|
163
|
+
event: "heart.intention_dismissed",
|
|
164
|
+
message: `intention dismissed: ${intention.content.slice(0, 60)}`,
|
|
165
|
+
meta: { intentionId: id },
|
|
166
|
+
});
|
|
167
|
+
return intention;
|
|
168
|
+
}
|
|
@@ -41,6 +41,7 @@ exports.readPendingObligations = readPendingObligations;
|
|
|
41
41
|
exports.advanceObligation = advanceObligation;
|
|
42
42
|
exports.fulfillObligation = fulfillObligation;
|
|
43
43
|
exports.findPendingObligationForOrigin = findPendingObligationForOrigin;
|
|
44
|
+
exports.enrichObligation = enrichObligation;
|
|
44
45
|
const fs = __importStar(require("fs"));
|
|
45
46
|
const path = __importStar(require("path"));
|
|
46
47
|
const runtime_1 = require("../nerves/runtime");
|
|
@@ -195,3 +196,25 @@ function findPendingObligationForOrigin(agentRoot, origin) {
|
|
|
195
196
|
&& ob.origin.channel === origin.channel
|
|
196
197
|
&& ob.origin.key === origin.key);
|
|
197
198
|
}
|
|
199
|
+
function enrichObligation(agentRoot, id, meaning) {
|
|
200
|
+
const filePath = obligationFilePath(agentRoot, id);
|
|
201
|
+
if (!fs.existsSync(filePath)) {
|
|
202
|
+
throw new Error(`Obligation not found: ${id}`);
|
|
203
|
+
}
|
|
204
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
205
|
+
const obligation = JSON.parse(raw);
|
|
206
|
+
obligation.meaning = meaning;
|
|
207
|
+
obligation.updatedAt = new Date().toISOString();
|
|
208
|
+
fs.writeFileSync(filePath, JSON.stringify(obligation, null, 2), "utf-8");
|
|
209
|
+
(0, runtime_1.emitNervesEvent)({
|
|
210
|
+
component: "engine",
|
|
211
|
+
event: "engine.obligation_enriched",
|
|
212
|
+
message: "obligation enriched with meaning",
|
|
213
|
+
meta: {
|
|
214
|
+
obligationId: id,
|
|
215
|
+
salience: meaning.salience,
|
|
216
|
+
stalenessClass: meaning.stalenessClass,
|
|
217
|
+
},
|
|
218
|
+
});
|
|
219
|
+
return obligation;
|
|
220
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.derivePresence = derivePresence;
|
|
37
|
+
exports.writePresence = writePresence;
|
|
38
|
+
exports.readPresence = readPresence;
|
|
39
|
+
exports.readPeerPresence = readPeerPresence;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const os = __importStar(require("os"));
|
|
43
|
+
const runtime_1 = require("../nerves/runtime");
|
|
44
|
+
function presenceDir(agentRoot) {
|
|
45
|
+
return path.join(agentRoot, "state", "presence");
|
|
46
|
+
}
|
|
47
|
+
function deriveAvailability(inputs) {
|
|
48
|
+
if (inputs.currentTempo === "crisis")
|
|
49
|
+
return "dnd";
|
|
50
|
+
if (inputs.activeSessions > 0)
|
|
51
|
+
return "active";
|
|
52
|
+
if (inputs.openObligations > 0)
|
|
53
|
+
return "idle";
|
|
54
|
+
return "away";
|
|
55
|
+
}
|
|
56
|
+
function deriveLane(inputs) {
|
|
57
|
+
const hasCoding = inputs.codingLanes > 0;
|
|
58
|
+
const hasBridges = inputs.activeBridges > 0;
|
|
59
|
+
if (hasCoding && hasBridges)
|
|
60
|
+
return "mixed";
|
|
61
|
+
if (hasCoding)
|
|
62
|
+
return "coding";
|
|
63
|
+
if (hasBridges)
|
|
64
|
+
return "conversation";
|
|
65
|
+
return "idle";
|
|
66
|
+
}
|
|
67
|
+
function deriveMission(inputs) {
|
|
68
|
+
const parts = [];
|
|
69
|
+
if (inputs.openObligations > 0) {
|
|
70
|
+
parts.push(`${inputs.openObligations} open obligation${inputs.openObligations !== 1 ? "s" : ""}`);
|
|
71
|
+
}
|
|
72
|
+
if (inputs.activeBridges > 0) {
|
|
73
|
+
parts.push(`${inputs.activeBridges} active bridge${inputs.activeBridges !== 1 ? "s" : ""}`);
|
|
74
|
+
}
|
|
75
|
+
if (inputs.codingLanes > 0) {
|
|
76
|
+
parts.push(`${inputs.codingLanes} coding lane${inputs.codingLanes !== 1 ? "s" : ""}`);
|
|
77
|
+
}
|
|
78
|
+
if (parts.length === 0)
|
|
79
|
+
return "no active work";
|
|
80
|
+
return parts.join(", ");
|
|
81
|
+
}
|
|
82
|
+
function derivePresence(_agentRoot, agentName, inputs) {
|
|
83
|
+
const presence = {
|
|
84
|
+
agentName,
|
|
85
|
+
availability: deriveAvailability(inputs),
|
|
86
|
+
lane: deriveLane(inputs),
|
|
87
|
+
mission: deriveMission(inputs),
|
|
88
|
+
tempo: inputs.currentTempo,
|
|
89
|
+
updatedAt: new Date().toISOString(),
|
|
90
|
+
};
|
|
91
|
+
(0, runtime_1.emitNervesEvent)({
|
|
92
|
+
component: "heart",
|
|
93
|
+
event: "heart.presence_derived",
|
|
94
|
+
message: `presence derived: ${presence.availability}/${presence.lane}`,
|
|
95
|
+
meta: {
|
|
96
|
+
agentName,
|
|
97
|
+
availability: presence.availability,
|
|
98
|
+
lane: presence.lane,
|
|
99
|
+
tempo: presence.tempo,
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
return presence;
|
|
103
|
+
}
|
|
104
|
+
function writePresence(agentRoot, _agentName, presence) {
|
|
105
|
+
const dir = presenceDir(agentRoot);
|
|
106
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
107
|
+
fs.writeFileSync(path.join(dir, "self.json"), JSON.stringify(presence, null, 2), "utf-8");
|
|
108
|
+
(0, runtime_1.emitNervesEvent)({
|
|
109
|
+
component: "heart",
|
|
110
|
+
event: "heart.presence_written",
|
|
111
|
+
message: `presence written for ${presence.agentName}`,
|
|
112
|
+
meta: { agentName: presence.agentName },
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
function readPresence(agentRoot, _agentName) {
|
|
116
|
+
const filePath = path.join(presenceDir(agentRoot), "self.json");
|
|
117
|
+
if (!fs.existsSync(filePath)) {
|
|
118
|
+
(0, runtime_1.emitNervesEvent)({
|
|
119
|
+
component: "heart",
|
|
120
|
+
event: "heart.presence_read",
|
|
121
|
+
message: "presence file not found",
|
|
122
|
+
meta: { found: false },
|
|
123
|
+
});
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
try {
|
|
127
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
128
|
+
const presence = JSON.parse(raw);
|
|
129
|
+
(0, runtime_1.emitNervesEvent)({
|
|
130
|
+
component: "heart",
|
|
131
|
+
event: "heart.presence_read",
|
|
132
|
+
message: `presence read: ${presence.availability}`,
|
|
133
|
+
meta: { agentName: presence.agentName, found: true },
|
|
134
|
+
});
|
|
135
|
+
return presence;
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
(0, runtime_1.emitNervesEvent)({
|
|
139
|
+
component: "heart",
|
|
140
|
+
event: "heart.presence_read_error",
|
|
141
|
+
message: "failed to read presence file",
|
|
142
|
+
meta: { error: "parse error" },
|
|
143
|
+
});
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function readPeerPresence(agentRoot) {
|
|
148
|
+
const relDir = path.join(agentRoot, "state", "relationships");
|
|
149
|
+
if (!fs.existsSync(relDir)) {
|
|
150
|
+
(0, runtime_1.emitNervesEvent)({
|
|
151
|
+
component: "heart",
|
|
152
|
+
event: "heart.peer_presence_read",
|
|
153
|
+
message: "no relationships directory, no peers",
|
|
154
|
+
meta: { peerCount: 0 },
|
|
155
|
+
});
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
const files = fs.readdirSync(relDir).filter((f) => f.endsWith(".json"));
|
|
159
|
+
const peers = [];
|
|
160
|
+
for (const file of files) {
|
|
161
|
+
try {
|
|
162
|
+
const raw = fs.readFileSync(path.join(relDir, file), "utf-8");
|
|
163
|
+
const rel = JSON.parse(raw);
|
|
164
|
+
const peerName = rel.agentName;
|
|
165
|
+
// Read peer's presence from their bundle
|
|
166
|
+
const peerRoot = path.join(os.homedir(), "AgentBundles", `${peerName}.ouro`);
|
|
167
|
+
const peerPresencePath = path.join(peerRoot, "state", "presence", "self.json");
|
|
168
|
+
if (fs.existsSync(peerPresencePath)) {
|
|
169
|
+
const presenceRaw = fs.readFileSync(peerPresencePath, "utf-8");
|
|
170
|
+
const presence = JSON.parse(presenceRaw);
|
|
171
|
+
peers.push(presence);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Skip peers with unreadable data
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
(0, runtime_1.emitNervesEvent)({
|
|
179
|
+
component: "heart",
|
|
180
|
+
event: "heart.peer_presence_read",
|
|
181
|
+
message: `read ${peers.length} peer presence records`,
|
|
182
|
+
meta: { peerCount: peers.length },
|
|
183
|
+
});
|
|
184
|
+
return peers;
|
|
185
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TEMPO_BUDGETS = void 0;
|
|
4
|
+
exports.deriveTempo = deriveTempo;
|
|
5
|
+
exports.getTokenBudget = getTokenBudget;
|
|
6
|
+
exports.detectTempoShift = detectTempoShift;
|
|
7
|
+
const runtime_1 = require("../nerves/runtime");
|
|
8
|
+
exports.TEMPO_BUDGETS = {
|
|
9
|
+
brief: { min: 150, max: 250 },
|
|
10
|
+
standard: { min: 450, max: 700 },
|
|
11
|
+
dense: { min: 900, max: 1100 },
|
|
12
|
+
crisis: { min: 700, max: 1000 },
|
|
13
|
+
};
|
|
14
|
+
const FIVE_MINUTES_MS = 5 * 60 * 1000;
|
|
15
|
+
const TWO_HOURS_MS = 2 * 60 * 60 * 1000;
|
|
16
|
+
function deriveMode(inputs) {
|
|
17
|
+
if (inputs.hasBlockers)
|
|
18
|
+
return "crisis";
|
|
19
|
+
if (inputs.openObligations > 3 || inputs.recentEpisodeCount > 10)
|
|
20
|
+
return "dense";
|
|
21
|
+
if (inputs.activeSessions > 0)
|
|
22
|
+
return "standard";
|
|
23
|
+
return "brief";
|
|
24
|
+
}
|
|
25
|
+
function deriveSignificance(inputs) {
|
|
26
|
+
if (inputs.highSalienceEpisodes > 0 || inputs.atRiskCareCount > 0)
|
|
27
|
+
return "high";
|
|
28
|
+
if (inputs.activeCareCount > 0)
|
|
29
|
+
return "medium";
|
|
30
|
+
return "low";
|
|
31
|
+
}
|
|
32
|
+
function deriveReentryDepth(inputs) {
|
|
33
|
+
if (inputs.lastActivityAgeMs < FIVE_MINUTES_MS)
|
|
34
|
+
return "warm";
|
|
35
|
+
if (inputs.lastActivityAgeMs < TWO_HOURS_MS)
|
|
36
|
+
return "cooled";
|
|
37
|
+
return "cold";
|
|
38
|
+
}
|
|
39
|
+
function computeEffectiveBudget(mode, significance, reentryDepth) {
|
|
40
|
+
const base = exports.TEMPO_BUDGETS[mode];
|
|
41
|
+
// Crisis always uses crisis budget regardless
|
|
42
|
+
if (mode === "crisis")
|
|
43
|
+
return { ...base };
|
|
44
|
+
const range = base.max - base.min;
|
|
45
|
+
// Start at the mode minimum
|
|
46
|
+
let effectiveMin = base.min;
|
|
47
|
+
// Significance pushes up within range
|
|
48
|
+
if (significance === "high") {
|
|
49
|
+
effectiveMin += Math.round(range * 0.5);
|
|
50
|
+
}
|
|
51
|
+
else if (significance === "medium") {
|
|
52
|
+
effectiveMin += Math.round(range * 0.25);
|
|
53
|
+
}
|
|
54
|
+
// Cold re-entry pushes up (need more context to re-orient)
|
|
55
|
+
if (reentryDepth === "cold") {
|
|
56
|
+
effectiveMin += Math.round(range * 0.3);
|
|
57
|
+
}
|
|
58
|
+
else if (reentryDepth === "cooled") {
|
|
59
|
+
effectiveMin += Math.round(range * 0.1);
|
|
60
|
+
}
|
|
61
|
+
// Clamp within mode range
|
|
62
|
+
effectiveMin = Math.min(effectiveMin, base.max);
|
|
63
|
+
return { min: effectiveMin, max: base.max };
|
|
64
|
+
}
|
|
65
|
+
function deriveTempo(inputs) {
|
|
66
|
+
const mode = deriveMode(inputs);
|
|
67
|
+
const significance = deriveSignificance(inputs);
|
|
68
|
+
const reentryDepth = deriveReentryDepth(inputs);
|
|
69
|
+
const effectiveBudget = computeEffectiveBudget(mode, significance, reentryDepth);
|
|
70
|
+
(0, runtime_1.emitNervesEvent)({
|
|
71
|
+
component: "heart",
|
|
72
|
+
event: "heart.tempo_derived",
|
|
73
|
+
message: `tempo derived: ${mode}/${significance}/${reentryDepth}`,
|
|
74
|
+
meta: {
|
|
75
|
+
mode,
|
|
76
|
+
significance,
|
|
77
|
+
reentryDepth,
|
|
78
|
+
effectiveMin: effectiveBudget.min,
|
|
79
|
+
effectiveMax: effectiveBudget.max,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
return { mode, significance, reentryDepth, effectiveBudget };
|
|
83
|
+
}
|
|
84
|
+
function getTokenBudget(state) {
|
|
85
|
+
return state.effectiveBudget;
|
|
86
|
+
}
|
|
87
|
+
function detectTempoShift(previous, current) {
|
|
88
|
+
if (!previous)
|
|
89
|
+
return true;
|
|
90
|
+
return (previous.mode !== current.mode
|
|
91
|
+
|| previous.significance !== current.significance
|
|
92
|
+
|| previous.reentryDepth !== current.reentryDepth);
|
|
93
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildTemporalView = buildTemporalView;
|
|
4
|
+
const runtime_1 = require("../nerves/runtime");
|
|
5
|
+
const episodes_1 = require("../mind/episodes");
|
|
6
|
+
const obligations_1 = require("./obligations");
|
|
7
|
+
const cares_1 = require("./cares");
|
|
8
|
+
const intentions_1 = require("./intentions");
|
|
9
|
+
const presence_1 = require("./presence");
|
|
10
|
+
function buildTemporalView(agentRoot, options) {
|
|
11
|
+
const episodeLimit = options?.episodeLimit ?? 20;
|
|
12
|
+
const tempo = options?.tempo ?? "brief";
|
|
13
|
+
const recentEpisodes = options?.preloaded?.recentEpisodes ?? (0, episodes_1.readRecentEpisodes)(agentRoot, { limit: episodeLimit });
|
|
14
|
+
const activeObligations = options?.preloaded?.activeObligations ?? (0, obligations_1.readPendingObligations)(agentRoot);
|
|
15
|
+
const activeCares = options?.preloaded?.activeCares ?? (0, cares_1.readActiveCares)(agentRoot);
|
|
16
|
+
const openIntentions = (0, intentions_1.readOpenIntentions)(agentRoot);
|
|
17
|
+
const peerPresence = (0, presence_1.readPeerPresence)(agentRoot);
|
|
18
|
+
const view = {
|
|
19
|
+
recentEpisodes,
|
|
20
|
+
activeObligations,
|
|
21
|
+
activeCares,
|
|
22
|
+
openIntentions,
|
|
23
|
+
peerPresence,
|
|
24
|
+
tempo,
|
|
25
|
+
assembledAt: new Date().toISOString(),
|
|
26
|
+
};
|
|
27
|
+
(0, runtime_1.emitNervesEvent)({
|
|
28
|
+
component: "heart",
|
|
29
|
+
event: "heart.temporal_view_assembled",
|
|
30
|
+
message: `temporal view assembled: ${recentEpisodes.length} episodes, ${activeObligations.length} obligations, ${activeCares.length} cares, ${openIntentions.length} intentions`,
|
|
31
|
+
meta: {
|
|
32
|
+
episodeCount: recentEpisodes.length,
|
|
33
|
+
obligationCount: activeObligations.length,
|
|
34
|
+
careCount: activeCares.length,
|
|
35
|
+
intentionCount: openIntentions.length,
|
|
36
|
+
peerCount: peerPresence.length,
|
|
37
|
+
tempo,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
return view;
|
|
41
|
+
}
|