@ouro.bot/cli 0.1.0-alpha.342 → 0.1.0-alpha.344
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 +5 -5
- package/SerpentGuide.ouro/psyche/identities/the-serpent.md +1 -1
- package/changelog.json +14 -0
- package/dist/heart/attachments/sources/bluebubbles.js +1 -1
- package/dist/heart/attachments/store.js +2 -2
- package/dist/heart/bundle-state.js +1 -1
- package/dist/heart/config-registry.js +2 -2
- package/dist/heart/core.js +10 -2
- package/dist/heart/daemon/agent-service.js +18 -18
- package/dist/heart/daemon/daemon-tombstone.js +1 -1
- package/dist/heart/daemon/daemon.js +2 -2
- package/dist/heart/daemon/hooks/bundle-meta.js +4 -4
- package/dist/heart/hatch/hatch-flow.js +1 -1
- package/dist/heart/hatch/specialist-prompt.js +1 -1
- package/dist/heart/hatch/specialist-tools.js +7 -7
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mcp/mcp-server.js +10 -10
- package/dist/heart/outlook/outlook-http-hooks.js +2 -2
- package/dist/heart/outlook/outlook-http-routes.js +4 -4
- package/dist/heart/outlook/outlook-read.js +3 -3
- package/dist/heart/outlook/readers/continuity-readers.js +3 -3
- package/dist/heart/outlook/readers/runtime-readers.js +2 -2
- package/dist/heart/provider-state.js +208 -0
- package/dist/heart/session-events.js +3 -2
- package/dist/heart/{session-recall.js → session-transcript.js} +4 -4
- package/dist/heart/target-resolution.js +5 -5
- package/dist/heart/tool-description.js +4 -4
- package/dist/mind/diary.js +3 -3
- package/dist/mind/embedding-provider.js +1 -1
- package/dist/mind/file-state.js +1 -1
- package/dist/mind/friends/resolver.js +1 -1
- package/dist/mind/friends/types.js +1 -1
- package/dist/mind/{associative-recall.js → note-search.js} +17 -17
- package/dist/mind/prompt.js +12 -12
- package/dist/nerves/coverage/file-completeness.js +2 -2
- package/dist/outlook-ui/assets/{index-DC7sZefn.js → index-xTdv64BV.js} +2 -2
- package/dist/outlook-ui/index.html +1 -1
- package/dist/repertoire/bitwarden-store.js +1 -1
- package/dist/repertoire/bundle-templates.js +1 -1
- package/dist/repertoire/skills.js +1 -1
- package/dist/repertoire/tools-base.js +3 -3
- package/dist/repertoire/tools-bridge.js +9 -9
- package/dist/repertoire/tools-continuity.js +2 -2
- package/dist/repertoire/{tools-memory.js → tools-notes.js} +6 -6
- package/dist/repertoire/tools-session.js +12 -12
- package/dist/senses/bluebubbles/attachment-cache.js +3 -3
- package/dist/senses/bluebubbles/index.js +1 -1
- package/dist/senses/bluebubbles/media.js +1 -1
- package/dist/senses/cli/image-paste.js +4 -4
- package/dist/senses/inner-dialog.js +2 -2
- package/dist/senses/surface-tool.js +1 -1
- package/package.json +1 -1
- package/skills/agent-commerce.md +1 -1
- package/skills/configure-dev-tools.md +2 -2
|
@@ -0,0 +1,357 @@
|
|
|
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.gatherKeptNotesCandidates = gatherKeptNotesCandidates;
|
|
37
|
+
exports.renderKeptNotesOutcome = renderKeptNotesOutcome;
|
|
38
|
+
exports.injectKeptNotes = injectKeptNotes;
|
|
39
|
+
exports.createKeptNotesJudge = createKeptNotesJudge;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const diary_1 = require("../mind/diary");
|
|
43
|
+
const runtime_1 = require("../nerves/runtime");
|
|
44
|
+
const DEFAULT_TIMEOUT_MS = 2500;
|
|
45
|
+
const MAX_CANDIDATES = 8;
|
|
46
|
+
const NOOP_CALLBACKS = {
|
|
47
|
+
onModelStart() { },
|
|
48
|
+
onModelStreamStart() { },
|
|
49
|
+
onTextChunk() { },
|
|
50
|
+
onReasoningChunk() { },
|
|
51
|
+
onToolStart() { },
|
|
52
|
+
onToolEnd() { },
|
|
53
|
+
onError() { },
|
|
54
|
+
};
|
|
55
|
+
function elapsedSince(startedAt) {
|
|
56
|
+
return Math.max(0, Date.now() - startedAt);
|
|
57
|
+
}
|
|
58
|
+
function latestUserText(messages) {
|
|
59
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
60
|
+
const message = messages[i];
|
|
61
|
+
if (message.role !== "user" || typeof message.content !== "string")
|
|
62
|
+
continue;
|
|
63
|
+
const text = message.content.trim();
|
|
64
|
+
if (text)
|
|
65
|
+
return text;
|
|
66
|
+
}
|
|
67
|
+
return "";
|
|
68
|
+
}
|
|
69
|
+
function tokenize(text) {
|
|
70
|
+
return new Set(text
|
|
71
|
+
.toLowerCase()
|
|
72
|
+
.split(/[^a-z0-9]+/g)
|
|
73
|
+
.map((token) => token.trim())
|
|
74
|
+
.filter((token) => token.length > 2));
|
|
75
|
+
}
|
|
76
|
+
function scoreText(queryTerms, text) {
|
|
77
|
+
const textTerms = tokenize(text);
|
|
78
|
+
let matches = 0;
|
|
79
|
+
for (const term of queryTerms) {
|
|
80
|
+
if (textTerms.has(term))
|
|
81
|
+
matches += 1;
|
|
82
|
+
}
|
|
83
|
+
return matches / queryTerms.size;
|
|
84
|
+
}
|
|
85
|
+
function readJournalIndex(journalDir) {
|
|
86
|
+
try {
|
|
87
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(journalDir, ".index.json"), "utf8"));
|
|
88
|
+
if (!Array.isArray(parsed))
|
|
89
|
+
return [];
|
|
90
|
+
return parsed
|
|
91
|
+
.filter((entry) => (typeof entry === "object" &&
|
|
92
|
+
entry !== null &&
|
|
93
|
+
typeof entry.filename === "string" &&
|
|
94
|
+
typeof entry.preview === "string"));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function journalDirForDiaryRoot(diaryRoot, explicitJournalDir) {
|
|
101
|
+
if (explicitJournalDir)
|
|
102
|
+
return explicitJournalDir;
|
|
103
|
+
return path.join(path.dirname(diaryRoot), "journal");
|
|
104
|
+
}
|
|
105
|
+
function diaryCandidate(fact) {
|
|
106
|
+
return {
|
|
107
|
+
text: fact.text,
|
|
108
|
+
source: { kind: "diary", label: "diary", ref: fact.id },
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function friendNoteCandidates(friend, queryTerms) {
|
|
112
|
+
if (!friend)
|
|
113
|
+
return [];
|
|
114
|
+
return Object.entries(friend.notes ?? {})
|
|
115
|
+
.map(([key, note]) => {
|
|
116
|
+
const text = `${friend.name} / ${key}: ${note.value}`;
|
|
117
|
+
return {
|
|
118
|
+
candidate: {
|
|
119
|
+
text,
|
|
120
|
+
source: { kind: "friend-note", label: `friend note: ${friend.name}`, ref: key },
|
|
121
|
+
},
|
|
122
|
+
score: scoreText(queryTerms, `${key} ${note.value}`),
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
.filter((entry) => entry.score > 0);
|
|
126
|
+
}
|
|
127
|
+
function gatherKeptNotesCandidates(query, options = {}) {
|
|
128
|
+
const queryTerms = tokenize(query);
|
|
129
|
+
if (queryTerms.size === 0)
|
|
130
|
+
return [];
|
|
131
|
+
const diaryRoot = (0, diary_1.resolveDiaryRoot)(options.diaryRoot);
|
|
132
|
+
const diaryEntries = (0, diary_1.readDiaryEntries)(diaryRoot);
|
|
133
|
+
const diaryCandidates = diaryEntries
|
|
134
|
+
.map((fact) => ({ candidate: diaryCandidate(fact), score: scoreText(queryTerms, fact.text) }))
|
|
135
|
+
.filter((entry) => entry.score > 0);
|
|
136
|
+
const journalDir = journalDirForDiaryRoot(diaryRoot, options.journalDir);
|
|
137
|
+
const journalCandidates = readJournalIndex(journalDir)
|
|
138
|
+
.map((entry) => ({
|
|
139
|
+
candidate: {
|
|
140
|
+
text: `${entry.filename}: ${entry.preview}`,
|
|
141
|
+
source: { kind: "journal", label: "journal", ref: entry.filename },
|
|
142
|
+
},
|
|
143
|
+
score: scoreText(queryTerms, `${entry.filename} ${entry.preview}`),
|
|
144
|
+
}))
|
|
145
|
+
.filter((entry) => entry.score > 0);
|
|
146
|
+
return [...diaryCandidates, ...journalCandidates, ...friendNoteCandidates(options.friend, queryTerms)]
|
|
147
|
+
.sort((left, right) => right.score - left.score)
|
|
148
|
+
.slice(0, MAX_CANDIDATES)
|
|
149
|
+
.map((entry) => entry.candidate);
|
|
150
|
+
}
|
|
151
|
+
function selectedSources(candidates, indexes) {
|
|
152
|
+
if (!indexes || indexes.length === 0)
|
|
153
|
+
return [];
|
|
154
|
+
const sources = [];
|
|
155
|
+
for (const index of indexes) {
|
|
156
|
+
if (!Number.isInteger(index))
|
|
157
|
+
continue;
|
|
158
|
+
const candidate = candidates[index];
|
|
159
|
+
if (candidate)
|
|
160
|
+
sources.push(candidate.source);
|
|
161
|
+
}
|
|
162
|
+
return sources;
|
|
163
|
+
}
|
|
164
|
+
function isFirstPerson(text) {
|
|
165
|
+
return /^(i|i'm|i’ve|i've|my|me)\b/i.test(text.trim());
|
|
166
|
+
}
|
|
167
|
+
function foundLine(text) {
|
|
168
|
+
const trimmed = text.trim();
|
|
169
|
+
if (isFirstPerson(trimmed))
|
|
170
|
+
return trimmed;
|
|
171
|
+
return `I kept this: ${trimmed}`;
|
|
172
|
+
}
|
|
173
|
+
function fuzzyLine(text) {
|
|
174
|
+
const trimmed = text.trim();
|
|
175
|
+
if (isFirstPerson(trimmed))
|
|
176
|
+
return trimmed;
|
|
177
|
+
return `I may have kept something related: ${trimmed}`;
|
|
178
|
+
}
|
|
179
|
+
const SOURCE_KIND_ORDER = ["diary", "journal", "friend-note"];
|
|
180
|
+
const SOURCE_KIND_LABELS = {
|
|
181
|
+
diary: "my diary",
|
|
182
|
+
journal: "my journal",
|
|
183
|
+
"friend-note": "my friend notes",
|
|
184
|
+
};
|
|
185
|
+
function joinLabels(labels) {
|
|
186
|
+
if (labels.length === 1)
|
|
187
|
+
return labels[0];
|
|
188
|
+
if (labels.length === 2)
|
|
189
|
+
return `${labels[0]} and ${labels[1]}`;
|
|
190
|
+
return `${labels.slice(0, -1).join(", ")}, and ${labels[labels.length - 1]}`;
|
|
191
|
+
}
|
|
192
|
+
function sourceHeading(sources) {
|
|
193
|
+
const sourceKinds = new Set(sources.map((source) => source.kind));
|
|
194
|
+
const labels = SOURCE_KIND_ORDER
|
|
195
|
+
.filter((kind) => sourceKinds.has(kind))
|
|
196
|
+
.map((kind) => SOURCE_KIND_LABELS[kind]);
|
|
197
|
+
if (labels.length === 0)
|
|
198
|
+
return "## from notes i chose to keep";
|
|
199
|
+
return `## from ${joinLabels(labels)}`;
|
|
200
|
+
}
|
|
201
|
+
function renderKeptNotesOutcome(outcome) {
|
|
202
|
+
if (outcome.status === "found") {
|
|
203
|
+
return `${sourceHeading(outcome.sources)}\nThis may matter now:\n${foundLine(outcome.note)}`;
|
|
204
|
+
}
|
|
205
|
+
if (outcome.status === "fuzzy") {
|
|
206
|
+
return `${sourceHeading(outcome.sources)}\nThis is only a possible match; I should verify it before relying on it:\n${fuzzyLine(outcome.hint)}`;
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
function finish(outcome, traceId) {
|
|
211
|
+
(0, runtime_1.emitNervesEvent)({
|
|
212
|
+
component: "mind",
|
|
213
|
+
event: "mind.kept_notes_end",
|
|
214
|
+
trace_id: traceId,
|
|
215
|
+
message: "kept notes completed",
|
|
216
|
+
meta: { status: outcome.status, elapsedMs: outcome.elapsedMs },
|
|
217
|
+
});
|
|
218
|
+
return outcome;
|
|
219
|
+
}
|
|
220
|
+
async function withTimeout(promise, timeoutMs) {
|
|
221
|
+
return await new Promise((resolve, reject) => {
|
|
222
|
+
const timeout = setTimeout(() => resolve("timeout"), timeoutMs);
|
|
223
|
+
promise
|
|
224
|
+
.then((value) => {
|
|
225
|
+
clearTimeout(timeout);
|
|
226
|
+
resolve(value);
|
|
227
|
+
})
|
|
228
|
+
.catch((error) => {
|
|
229
|
+
clearTimeout(timeout);
|
|
230
|
+
reject(error);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
async function injectKeptNotes(messages, options = {}) {
|
|
235
|
+
const startedAt = Date.now();
|
|
236
|
+
const systemMessage = messages[0];
|
|
237
|
+
const query = latestUserText(messages);
|
|
238
|
+
if (systemMessage?.role !== "system" || typeof systemMessage.content !== "string" || !query) {
|
|
239
|
+
return { status: "none", elapsedMs: elapsedSince(startedAt), pressure: [] };
|
|
240
|
+
}
|
|
241
|
+
(0, runtime_1.emitNervesEvent)({
|
|
242
|
+
component: "mind",
|
|
243
|
+
event: "mind.kept_notes_start",
|
|
244
|
+
trace_id: options.traceId,
|
|
245
|
+
message: "kept notes started",
|
|
246
|
+
meta: { channel: options.channel ?? "unknown" },
|
|
247
|
+
});
|
|
248
|
+
try {
|
|
249
|
+
const candidates = gatherKeptNotesCandidates(query, options);
|
|
250
|
+
if (candidates.length === 0 || !options.judge) {
|
|
251
|
+
return finish({ status: "none", elapsedMs: elapsedSince(startedAt), pressure: [] }, options.traceId);
|
|
252
|
+
}
|
|
253
|
+
const judged = await withTimeout(options.judge({ query, candidates }), options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
254
|
+
if (judged === "timeout") {
|
|
255
|
+
return finish({ status: "timeout", elapsedMs: elapsedSince(startedAt) }, options.traceId);
|
|
256
|
+
}
|
|
257
|
+
const elapsedMs = elapsedSince(startedAt);
|
|
258
|
+
const outcome = judged.status === "found"
|
|
259
|
+
? { status: "found", note: judged.note, sources: selectedSources(candidates, judged.sourceIndexes), elapsedMs }
|
|
260
|
+
: judged.status === "fuzzy"
|
|
261
|
+
? { status: "fuzzy", hint: judged.hint, sources: selectedSources(candidates, judged.sourceIndexes), elapsedMs }
|
|
262
|
+
: { status: "none", pressure: judged.pressure, elapsedMs };
|
|
263
|
+
if (outcome.status === "found" || outcome.status === "fuzzy") {
|
|
264
|
+
const rendered = renderKeptNotesOutcome(outcome);
|
|
265
|
+
messages[0] = { role: "system", content: `${systemMessage.content}\n\n${rendered}` };
|
|
266
|
+
(0, runtime_1.emitNervesEvent)({
|
|
267
|
+
component: "mind",
|
|
268
|
+
event: "mind.kept_notes_injected",
|
|
269
|
+
trace_id: options.traceId,
|
|
270
|
+
message: "kept notes injected",
|
|
271
|
+
meta: { status: outcome.status, sourceCount: outcome.sources.length },
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
return finish(outcome, options.traceId);
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
278
|
+
const outcome = { status: "error", reason, elapsedMs: elapsedSince(startedAt) };
|
|
279
|
+
(0, runtime_1.emitNervesEvent)({
|
|
280
|
+
level: "warn",
|
|
281
|
+
component: "mind",
|
|
282
|
+
event: "mind.kept_notes_error",
|
|
283
|
+
trace_id: options.traceId,
|
|
284
|
+
message: "kept notes failed",
|
|
285
|
+
meta: { reason },
|
|
286
|
+
});
|
|
287
|
+
return finish(outcome, options.traceId);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function parseJudgeResult(content) {
|
|
291
|
+
try {
|
|
292
|
+
const parsed = JSON.parse(content);
|
|
293
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
294
|
+
return { status: "none", pressure: ["invalid kept notes judge output"] };
|
|
295
|
+
}
|
|
296
|
+
const record = parsed;
|
|
297
|
+
if (record.status === "found" && typeof record.note === "string" && record.note.trim()) {
|
|
298
|
+
return {
|
|
299
|
+
status: "found",
|
|
300
|
+
note: record.note.trim(),
|
|
301
|
+
sourceIndexes: Array.isArray(record.sourceIndexes) ? record.sourceIndexes.filter((index) => typeof index === "number") : undefined,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
if (record.status === "fuzzy" && typeof record.hint === "string" && record.hint.trim()) {
|
|
305
|
+
return {
|
|
306
|
+
status: "fuzzy",
|
|
307
|
+
hint: record.hint.trim(),
|
|
308
|
+
sourceIndexes: Array.isArray(record.sourceIndexes) ? record.sourceIndexes.filter((index) => typeof index === "number") : undefined,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
if (record.status === "none") {
|
|
312
|
+
return {
|
|
313
|
+
status: "none",
|
|
314
|
+
pressure: Array.isArray(record.pressure) ? record.pressure.filter((value) => typeof value === "string") : [],
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
return { status: "none", pressure: ["invalid kept notes judge output"] };
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
return { status: "none", pressure: ["invalid kept notes judge output"] };
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function createJudgePrompt(input) {
|
|
324
|
+
const candidates = input.candidates
|
|
325
|
+
.map((candidate, index) => `${index}. [${candidate.source.kind}] ${candidate.text}`)
|
|
326
|
+
.join("\n");
|
|
327
|
+
return [
|
|
328
|
+
{
|
|
329
|
+
role: "system",
|
|
330
|
+
content: [
|
|
331
|
+
"Decide whether these intentionally kept notes matter to the user's current turn.",
|
|
332
|
+
"Return only JSON.",
|
|
333
|
+
"Use found when a note clearly helps, fuzzy when a note is close but uncertain, and none when nothing should be surfaced.",
|
|
334
|
+
"Shapes: {\"status\":\"found\",\"note\":\"...\",\"sourceIndexes\":[0]}, {\"status\":\"fuzzy\",\"hint\":\"...\",\"sourceIndexes\":[0]}, or {\"status\":\"none\",\"pressure\":[]}.",
|
|
335
|
+
].join("\n"),
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
role: "user",
|
|
339
|
+
content: `Current turn:\n${input.query}\n\nCandidates:\n${candidates}`,
|
|
340
|
+
},
|
|
341
|
+
];
|
|
342
|
+
}
|
|
343
|
+
function createKeptNotesJudge(runtime, signal) {
|
|
344
|
+
return async (input) => {
|
|
345
|
+
const messages = createJudgePrompt(input);
|
|
346
|
+
runtime.resetTurnState?.(messages);
|
|
347
|
+
const result = await runtime.streamTurn({
|
|
348
|
+
messages,
|
|
349
|
+
activeTools: [],
|
|
350
|
+
callbacks: NOOP_CALLBACKS,
|
|
351
|
+
signal,
|
|
352
|
+
toolChoiceRequired: false,
|
|
353
|
+
reasoningEffort: "low",
|
|
354
|
+
});
|
|
355
|
+
return parseJudgeResult(result.content ?? "");
|
|
356
|
+
};
|
|
357
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
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.getMachineIdentityPath = getMachineIdentityPath;
|
|
37
|
+
exports.loadOrCreateMachineIdentity = loadOrCreateMachineIdentity;
|
|
38
|
+
const crypto = __importStar(require("crypto"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const os = __importStar(require("os"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const runtime_1 = require("../nerves/runtime");
|
|
43
|
+
function nowIso(deps) {
|
|
44
|
+
return (deps.now?.() ?? new Date()).toISOString();
|
|
45
|
+
}
|
|
46
|
+
function currentHostname(deps) {
|
|
47
|
+
return (deps.hostname?.() ?? os.hostname()).trim();
|
|
48
|
+
}
|
|
49
|
+
function defaultRandomId() {
|
|
50
|
+
return `machine_${crypto.randomUUID()}`;
|
|
51
|
+
}
|
|
52
|
+
function normalizeAliases(value) {
|
|
53
|
+
if (!Array.isArray(value))
|
|
54
|
+
return [];
|
|
55
|
+
const aliases = [];
|
|
56
|
+
for (const alias of value) {
|
|
57
|
+
if (typeof alias !== "string")
|
|
58
|
+
continue;
|
|
59
|
+
const trimmed = alias.trim();
|
|
60
|
+
if (trimmed && !aliases.includes(trimmed))
|
|
61
|
+
aliases.push(trimmed);
|
|
62
|
+
}
|
|
63
|
+
return aliases;
|
|
64
|
+
}
|
|
65
|
+
function parseMachineIdentity(value) {
|
|
66
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
67
|
+
return null;
|
|
68
|
+
const record = value;
|
|
69
|
+
const aliases = normalizeAliases(record.hostnameAliases);
|
|
70
|
+
if (record.schemaVersion !== 1 ||
|
|
71
|
+
typeof record.machineId !== "string" ||
|
|
72
|
+
record.machineId.trim().length === 0 ||
|
|
73
|
+
typeof record.createdAt !== "string" ||
|
|
74
|
+
record.createdAt.trim().length === 0 ||
|
|
75
|
+
typeof record.updatedAt !== "string" ||
|
|
76
|
+
record.updatedAt.trim().length === 0) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
schemaVersion: 1,
|
|
81
|
+
machineId: record.machineId,
|
|
82
|
+
createdAt: record.createdAt,
|
|
83
|
+
updatedAt: record.updatedAt,
|
|
84
|
+
hostnameAliases: aliases,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function writeMachineIdentity(machinePath, identity) {
|
|
88
|
+
fs.mkdirSync(path.dirname(machinePath), { recursive: true, mode: 0o700 });
|
|
89
|
+
fs.writeFileSync(machinePath, `${JSON.stringify(identity, null, 2)}\n`, { encoding: "utf-8", mode: 0o600 });
|
|
90
|
+
}
|
|
91
|
+
function getMachineIdentityPath(homeDir = os.homedir()) {
|
|
92
|
+
return path.join(homeDir, ".ouro-cli", "machine.json");
|
|
93
|
+
}
|
|
94
|
+
function loadOrCreateMachineIdentity(deps = {}) {
|
|
95
|
+
const homeDir = deps.homeDir ?? os.homedir();
|
|
96
|
+
const machinePath = getMachineIdentityPath(homeDir);
|
|
97
|
+
const hostname = currentHostname(deps);
|
|
98
|
+
let existing = null;
|
|
99
|
+
let hadInvalidFile = false;
|
|
100
|
+
try {
|
|
101
|
+
existing = parseMachineIdentity(JSON.parse(fs.readFileSync(machinePath, "utf-8")));
|
|
102
|
+
if (!existing)
|
|
103
|
+
hadInvalidFile = true;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
const code = error && typeof error === "object" && "code" in error
|
|
107
|
+
? error.code
|
|
108
|
+
: undefined;
|
|
109
|
+
if (code !== "ENOENT")
|
|
110
|
+
hadInvalidFile = true;
|
|
111
|
+
}
|
|
112
|
+
if (hadInvalidFile) {
|
|
113
|
+
(0, runtime_1.emitNervesEvent)({
|
|
114
|
+
level: "warn",
|
|
115
|
+
component: "config/identity",
|
|
116
|
+
event: "config.machine_identity_invalid",
|
|
117
|
+
message: "machine identity file is invalid; replacing it",
|
|
118
|
+
meta: { path: machinePath },
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (existing) {
|
|
122
|
+
if (hostname && !existing.hostnameAliases.includes(hostname)) {
|
|
123
|
+
const updated = {
|
|
124
|
+
...existing,
|
|
125
|
+
updatedAt: nowIso(deps),
|
|
126
|
+
hostnameAliases: [...existing.hostnameAliases, hostname],
|
|
127
|
+
};
|
|
128
|
+
writeMachineIdentity(machinePath, updated);
|
|
129
|
+
(0, runtime_1.emitNervesEvent)({
|
|
130
|
+
component: "config/identity",
|
|
131
|
+
event: "config.machine_identity_alias_added",
|
|
132
|
+
message: "recorded hostname alias for stable machine identity",
|
|
133
|
+
meta: { machineId: updated.machineId, hostname },
|
|
134
|
+
});
|
|
135
|
+
return updated;
|
|
136
|
+
}
|
|
137
|
+
(0, runtime_1.emitNervesEvent)({
|
|
138
|
+
component: "config/identity",
|
|
139
|
+
event: "config.machine_identity_loaded",
|
|
140
|
+
message: "loaded stable machine identity",
|
|
141
|
+
meta: { machineId: existing.machineId },
|
|
142
|
+
});
|
|
143
|
+
return existing;
|
|
144
|
+
}
|
|
145
|
+
const timestamp = nowIso(deps);
|
|
146
|
+
const identity = {
|
|
147
|
+
schemaVersion: 1,
|
|
148
|
+
machineId: (deps.randomId?.() ?? defaultRandomId()).trim() || defaultRandomId(),
|
|
149
|
+
createdAt: timestamp,
|
|
150
|
+
updatedAt: timestamp,
|
|
151
|
+
hostnameAliases: hostname ? [hostname] : [],
|
|
152
|
+
};
|
|
153
|
+
writeMachineIdentity(machinePath, identity);
|
|
154
|
+
(0, runtime_1.emitNervesEvent)({
|
|
155
|
+
component: "config/identity",
|
|
156
|
+
event: "config.machine_identity_created",
|
|
157
|
+
message: "created stable machine identity",
|
|
158
|
+
meta: { machineId: identity.machineId },
|
|
159
|
+
});
|
|
160
|
+
return identity;
|
|
161
|
+
}
|
|
@@ -92,7 +92,7 @@ const TOOL_TO_COMMAND = {
|
|
|
92
92
|
catchup: "agent.catchup",
|
|
93
93
|
delegate: "agent.delegate",
|
|
94
94
|
get_context: "agent.getContext",
|
|
95
|
-
|
|
95
|
+
search_notes: "agent.searchNotes",
|
|
96
96
|
get_task: "agent.getTask",
|
|
97
97
|
check_scope: "agent.checkScope",
|
|
98
98
|
request_decision: "agent.requestDecision",
|
|
@@ -270,7 +270,7 @@ function createMcpServer(options) {
|
|
|
270
270
|
catchup: "handleAgentCatchup",
|
|
271
271
|
delegate: "handleAgentDelegate",
|
|
272
272
|
get_context: "handleAgentGetContext",
|
|
273
|
-
|
|
273
|
+
search_notes: "handleAgentSearchNotes",
|
|
274
274
|
get_task: "handleAgentGetTask",
|
|
275
275
|
check_scope: "handleAgentCheckScope",
|
|
276
276
|
request_decision: "handleAgentRequestDecision",
|
|
@@ -498,7 +498,7 @@ function getToolSchemas() {
|
|
|
498
498
|
return [
|
|
499
499
|
{
|
|
500
500
|
name: "ask",
|
|
501
|
-
description: "Ask the agent a question. The agent uses its
|
|
501
|
+
description: "Ask the agent a question. The agent uses its diary, journal, and recent session context to provide a useful answer.",
|
|
502
502
|
inputSchema: {
|
|
503
503
|
type: "object",
|
|
504
504
|
properties: {
|
|
@@ -509,7 +509,7 @@ function getToolSchemas() {
|
|
|
509
509
|
},
|
|
510
510
|
{
|
|
511
511
|
name: "status",
|
|
512
|
-
description: "Get the agent's current status including active sessions,
|
|
512
|
+
description: "Get the agent's current status including active sessions, diary and journal state, and activity level.",
|
|
513
513
|
inputSchema: {
|
|
514
514
|
type: "object",
|
|
515
515
|
properties: {},
|
|
@@ -537,19 +537,19 @@ function getToolSchemas() {
|
|
|
537
537
|
},
|
|
538
538
|
{
|
|
539
539
|
name: "get_context",
|
|
540
|
-
description: "Get the agent's current working context including
|
|
540
|
+
description: "Get the agent's current working context including note summary, active tasks, and relevant state.",
|
|
541
541
|
inputSchema: {
|
|
542
542
|
type: "object",
|
|
543
543
|
properties: {},
|
|
544
544
|
},
|
|
545
545
|
},
|
|
546
546
|
{
|
|
547
|
-
name: "
|
|
548
|
-
description: "Search the agent's
|
|
547
|
+
name: "search_notes",
|
|
548
|
+
description: "Search the agent's diary for information about a specific topic. Returns matching diary lines.",
|
|
549
549
|
inputSchema: {
|
|
550
550
|
type: "object",
|
|
551
551
|
properties: {
|
|
552
|
-
query: { type: "string", description: "Search term to look for in agent
|
|
552
|
+
query: { type: "string", description: "Search term to look for in agent notes" },
|
|
553
553
|
},
|
|
554
554
|
required: ["query"],
|
|
555
555
|
},
|
|
@@ -587,7 +587,7 @@ function getToolSchemas() {
|
|
|
587
587
|
},
|
|
588
588
|
{
|
|
589
589
|
name: "check_guidance",
|
|
590
|
-
description: "Get guidance from the agent on how to approach a topic. The agent searches its
|
|
590
|
+
description: "Get guidance from the agent on how to approach a topic. The agent searches its diary, journal, and session context for relevant guidance.",
|
|
591
591
|
inputSchema: {
|
|
592
592
|
type: "object",
|
|
593
593
|
properties: {
|
|
@@ -631,7 +631,7 @@ function getToolSchemas() {
|
|
|
631
631
|
},
|
|
632
632
|
{
|
|
633
633
|
name: "send_message",
|
|
634
|
-
description: "Send a message to the agent and get a synchronous response. This runs a full agent turn — the agent can use tools, think, and respond. For multi-turn conversations, call repeatedly — the agent
|
|
634
|
+
description: "Send a message to the agent and get a synchronous response. This runs a full agent turn — the agent can use tools, think, and respond. For multi-turn conversations, call repeatedly — the agent keeps prior turns in this session.",
|
|
635
635
|
inputSchema: {
|
|
636
636
|
type: "object",
|
|
637
637
|
properties: {
|
|
@@ -47,14 +47,14 @@ function createOutlookHttpReadHooks(options) {
|
|
|
47
47
|
readAgentCoding: options.readAgentCoding ?? ((agentName) => (0, outlook_read_1.readCodingDeep)(agentRoot(agentName))),
|
|
48
48
|
readAgentAttention: options.readAgentAttention ?? ((agentName) => (0, outlook_read_1.readAttentionView)(agentName, readOptions)),
|
|
49
49
|
readAgentBridges: options.readAgentBridges ?? ((agentName) => (0, outlook_read_1.readBridgeInventory)(agentRoot(agentName))),
|
|
50
|
-
|
|
50
|
+
readAgentNotes: options.readAgentNotes ?? ((agentName) => (0, outlook_read_1.readNotesView)(agentRoot(agentName))),
|
|
51
51
|
readAgentFriends: options.readAgentFriends ?? ((agentName) => (0, outlook_read_1.readFriendView)(agentName, readOptions)),
|
|
52
52
|
readAgentContinuity: options.readAgentContinuity ?? ((agentName) => (0, outlook_read_1.readOutlookContinuity)(agentRoot(agentName), agentName)),
|
|
53
53
|
readAgentOrientation: options.readAgentOrientation ?? ((agentName) => (0, outlook_read_1.readOrientationView)(agentRoot(agentName), agentName)),
|
|
54
54
|
readAgentObligations: options.readAgentObligations ?? ((agentName) => (0, outlook_read_1.readObligationDetailView)(agentRoot(agentName))),
|
|
55
55
|
readAgentChanges: options.readAgentChanges ?? ((agentName) => (0, outlook_read_1.readChangesView)(agentRoot(agentName))),
|
|
56
56
|
readAgentSelfFix: options.readAgentSelfFix ?? ((agentName) => (0, outlook_read_1.readSelfFixView)(agentRoot(agentName))),
|
|
57
|
-
|
|
57
|
+
readAgentNoteDecisions: options.readAgentNoteDecisions ?? ((agentName) => (0, outlook_read_1.readNoteDecisionView)(agentRoot(agentName))),
|
|
58
58
|
readAgentHabits: options.readAgentHabits ?? ((agentName) => (0, outlook_read_1.readHabitView)(agentRoot(agentName))),
|
|
59
59
|
readDaemonHealth: options.readDaemonHealth ?? (() => (0, outlook_read_1.readDaemonHealthDeep)(options.healthPath)),
|
|
60
60
|
readLogs: options.readLogs ?? (() => (0, outlook_read_1.readLogView)(options.logPath ?? null)),
|
|
@@ -142,8 +142,8 @@ function handleAgentRoute(request, response, context) {
|
|
|
142
142
|
(0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentBridges(agent));
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
145
|
-
if (surface === "
|
|
146
|
-
(0, outlook_http_response_1.writeJson)(response, 200, options.hooks.
|
|
145
|
+
if (surface === "notes") {
|
|
146
|
+
(0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentNotes(agent));
|
|
147
147
|
return;
|
|
148
148
|
}
|
|
149
149
|
if (surface === "friends") {
|
|
@@ -170,8 +170,8 @@ function handleAgentRoute(request, response, context) {
|
|
|
170
170
|
(0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentSelfFix(agent));
|
|
171
171
|
return;
|
|
172
172
|
}
|
|
173
|
-
if (surface === "
|
|
174
|
-
(0, outlook_http_response_1.writeJson)(response, 200, options.hooks.
|
|
173
|
+
if (surface === "note-decisions") {
|
|
174
|
+
(0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentNoteDecisions(agent));
|
|
175
175
|
return;
|
|
176
176
|
}
|
|
177
177
|
if (surface === "dismiss-obligation" && request.method === "POST") {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readSelfFixView = exports.readOutlookContinuity = exports.readOrientationView = exports.readObligationDetailView = exports.
|
|
3
|
+
exports.readSelfFixView = exports.readOutlookContinuity = exports.readOrientationView = exports.readObligationDetailView = exports.readNoteDecisionView = exports.readChangesView = exports.readNeedsMeView = exports.readNotesView = exports.readLogView = exports.readHabitView = exports.readFriendView = exports.readDeskPrefs = exports.readDaemonHealthDeep = exports.readCodingDeep = exports.readBridgeInventory = exports.readAttentionView = exports.readSessionTranscript = exports.readSessionInventory = exports.readOutlookMachineState = exports.readOutlookAgentState = exports.readObligationSummary = void 0;
|
|
4
4
|
var agent_machine_1 = require("./readers/agent-machine");
|
|
5
5
|
Object.defineProperty(exports, "readObligationSummary", { enumerable: true, get: function () { return agent_machine_1.readObligationSummary; } });
|
|
6
6
|
Object.defineProperty(exports, "readOutlookAgentState", { enumerable: true, get: function () { return agent_machine_1.readOutlookAgentState; } });
|
|
@@ -17,11 +17,11 @@ Object.defineProperty(exports, "readDeskPrefs", { enumerable: true, get: functio
|
|
|
17
17
|
Object.defineProperty(exports, "readFriendView", { enumerable: true, get: function () { return runtime_readers_1.readFriendView; } });
|
|
18
18
|
Object.defineProperty(exports, "readHabitView", { enumerable: true, get: function () { return runtime_readers_1.readHabitView; } });
|
|
19
19
|
Object.defineProperty(exports, "readLogView", { enumerable: true, get: function () { return runtime_readers_1.readLogView; } });
|
|
20
|
-
Object.defineProperty(exports, "
|
|
20
|
+
Object.defineProperty(exports, "readNotesView", { enumerable: true, get: function () { return runtime_readers_1.readNotesView; } });
|
|
21
21
|
Object.defineProperty(exports, "readNeedsMeView", { enumerable: true, get: function () { return runtime_readers_1.readNeedsMeView; } });
|
|
22
22
|
var continuity_readers_1 = require("./readers/continuity-readers");
|
|
23
23
|
Object.defineProperty(exports, "readChangesView", { enumerable: true, get: function () { return continuity_readers_1.readChangesView; } });
|
|
24
|
-
Object.defineProperty(exports, "
|
|
24
|
+
Object.defineProperty(exports, "readNoteDecisionView", { enumerable: true, get: function () { return continuity_readers_1.readNoteDecisionView; } });
|
|
25
25
|
Object.defineProperty(exports, "readObligationDetailView", { enumerable: true, get: function () { return continuity_readers_1.readObligationDetailView; } });
|
|
26
26
|
Object.defineProperty(exports, "readOrientationView", { enumerable: true, get: function () { return continuity_readers_1.readOrientationView; } });
|
|
27
27
|
Object.defineProperty(exports, "readOutlookContinuity", { enumerable: true, get: function () { return continuity_readers_1.readOutlookContinuity; } });
|