@ouro.bot/cli 0.0.1-alpha.0 → 0.1.0-alpha.2

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.
Files changed (119) hide show
  1. package/AdoptionSpecialist.ouro/agent.json +20 -0
  2. package/AdoptionSpecialist.ouro/psyche/SOUL.md +22 -0
  3. package/AdoptionSpecialist.ouro/psyche/identities/basilisk.md +31 -0
  4. package/AdoptionSpecialist.ouro/psyche/identities/jafar.md +31 -0
  5. package/AdoptionSpecialist.ouro/psyche/identities/jormungandr.md +31 -0
  6. package/AdoptionSpecialist.ouro/psyche/identities/kaa.md +31 -0
  7. package/AdoptionSpecialist.ouro/psyche/identities/medusa.md +31 -0
  8. package/AdoptionSpecialist.ouro/psyche/identities/monty.md +31 -0
  9. package/AdoptionSpecialist.ouro/psyche/identities/nagini.md +31 -0
  10. package/AdoptionSpecialist.ouro/psyche/identities/ouroboros.md +31 -0
  11. package/AdoptionSpecialist.ouro/psyche/identities/python.md +31 -0
  12. package/AdoptionSpecialist.ouro/psyche/identities/quetzalcoatl.md +31 -0
  13. package/AdoptionSpecialist.ouro/psyche/identities/sir-hiss.md +31 -0
  14. package/AdoptionSpecialist.ouro/psyche/identities/the-serpent.md +31 -0
  15. package/AdoptionSpecialist.ouro/psyche/identities/the-snake.md +31 -0
  16. package/README.md +224 -6
  17. package/dist/heart/agent-entry.js +17 -0
  18. package/dist/heart/api-error.js +34 -0
  19. package/dist/heart/config.js +296 -0
  20. package/dist/heart/core.js +515 -0
  21. package/dist/heart/daemon/daemon-cli.js +675 -0
  22. package/dist/heart/daemon/daemon-entry.js +74 -0
  23. package/dist/heart/daemon/daemon.js +313 -0
  24. package/dist/heart/daemon/hatch-flow.js +285 -0
  25. package/dist/heart/daemon/hatch-specialist.js +107 -0
  26. package/dist/heart/daemon/health-monitor.js +79 -0
  27. package/dist/heart/daemon/log-tailer.js +146 -0
  28. package/dist/heart/daemon/message-router.js +98 -0
  29. package/dist/heart/daemon/os-cron.js +260 -0
  30. package/dist/heart/daemon/ouro-bot-entry.js +23 -0
  31. package/dist/heart/daemon/ouro-bot-wrapper.js +90 -0
  32. package/dist/heart/daemon/ouro-entry.js +23 -0
  33. package/dist/heart/daemon/ouro-uti.js +212 -0
  34. package/dist/heart/daemon/process-manager.js +237 -0
  35. package/dist/heart/daemon/runtime-logging.js +98 -0
  36. package/dist/heart/daemon/subagent-installer.js +125 -0
  37. package/dist/heart/daemon/task-scheduler.js +240 -0
  38. package/dist/heart/harness.js +26 -0
  39. package/dist/heart/identity.js +281 -0
  40. package/dist/heart/kicks.js +144 -0
  41. package/dist/heart/primitives.js +4 -0
  42. package/dist/heart/providers/anthropic.js +329 -0
  43. package/dist/heart/providers/azure.js +66 -0
  44. package/dist/heart/providers/minimax.js +53 -0
  45. package/dist/heart/providers/openai-codex.js +162 -0
  46. package/dist/heart/streaming.js +412 -0
  47. package/dist/heart/turn-coordinator.js +62 -0
  48. package/dist/inner-worker-entry.js +4 -0
  49. package/dist/mind/associative-recall.js +197 -0
  50. package/dist/mind/bundle-manifest.js +118 -0
  51. package/dist/mind/context.js +302 -0
  52. package/dist/mind/first-impressions.js +43 -0
  53. package/dist/mind/format.js +56 -0
  54. package/dist/mind/friends/channel.js +41 -0
  55. package/dist/mind/friends/resolver.js +84 -0
  56. package/dist/mind/friends/store-file.js +171 -0
  57. package/dist/mind/friends/store.js +4 -0
  58. package/dist/mind/friends/tokens.js +26 -0
  59. package/dist/mind/friends/types.js +21 -0
  60. package/dist/mind/memory.js +388 -0
  61. package/dist/mind/pending.js +93 -0
  62. package/dist/mind/phrases.js +43 -0
  63. package/dist/mind/prompt-refresh.js +20 -0
  64. package/dist/mind/prompt.js +352 -0
  65. package/dist/mind/token-estimate.js +119 -0
  66. package/dist/nerves/cli-logging.js +31 -0
  67. package/dist/nerves/coverage/audit-rules.js +81 -0
  68. package/dist/nerves/coverage/audit.js +200 -0
  69. package/dist/nerves/coverage/cli-main.js +5 -0
  70. package/dist/nerves/coverage/cli.js +51 -0
  71. package/dist/nerves/coverage/contract.js +23 -0
  72. package/dist/nerves/coverage/file-completeness.js +56 -0
  73. package/dist/nerves/coverage/run-artifacts.js +77 -0
  74. package/dist/nerves/coverage/source-scanner.js +34 -0
  75. package/dist/nerves/index.js +152 -0
  76. package/dist/nerves/runtime.js +38 -0
  77. package/dist/repertoire/ado-client.js +211 -0
  78. package/dist/repertoire/ado-context.js +73 -0
  79. package/dist/repertoire/ado-semantic.js +841 -0
  80. package/dist/repertoire/ado-templates.js +146 -0
  81. package/dist/repertoire/coding/index.js +36 -0
  82. package/dist/repertoire/coding/manager.js +489 -0
  83. package/dist/repertoire/coding/monitor.js +60 -0
  84. package/dist/repertoire/coding/reporter.js +45 -0
  85. package/dist/repertoire/coding/spawner.js +102 -0
  86. package/dist/repertoire/coding/tools.js +167 -0
  87. package/dist/repertoire/coding/types.js +2 -0
  88. package/dist/repertoire/data/ado-endpoints.json +122 -0
  89. package/dist/repertoire/data/graph-endpoints.json +212 -0
  90. package/dist/repertoire/github-client.js +64 -0
  91. package/dist/repertoire/graph-client.js +118 -0
  92. package/dist/repertoire/skills.js +156 -0
  93. package/dist/repertoire/tasks/board.js +122 -0
  94. package/dist/repertoire/tasks/index.js +210 -0
  95. package/dist/repertoire/tasks/lifecycle.js +80 -0
  96. package/dist/repertoire/tasks/middleware.js +65 -0
  97. package/dist/repertoire/tasks/parser.js +173 -0
  98. package/dist/repertoire/tasks/scanner.js +132 -0
  99. package/dist/repertoire/tasks/transitions.js +145 -0
  100. package/dist/repertoire/tasks/types.js +2 -0
  101. package/dist/repertoire/tools-base.js +714 -0
  102. package/dist/repertoire/tools-github.js +53 -0
  103. package/dist/repertoire/tools-teams.js +308 -0
  104. package/dist/repertoire/tools.js +199 -0
  105. package/dist/senses/cli-entry.js +15 -0
  106. package/dist/senses/cli.js +604 -0
  107. package/dist/senses/commands.js +98 -0
  108. package/dist/senses/inner-dialog-worker.js +61 -0
  109. package/dist/senses/inner-dialog.js +231 -0
  110. package/dist/senses/session-lock.js +119 -0
  111. package/dist/senses/teams-entry.js +15 -0
  112. package/dist/senses/teams.js +696 -0
  113. package/dist/senses/trust-gate.js +150 -0
  114. package/package.json +34 -11
  115. package/subagents/README.md +73 -0
  116. package/subagents/work-doer.md +233 -0
  117. package/subagents/work-merger.md +624 -0
  118. package/subagents/work-planner.md +373 -0
  119. package/bin/ouro.js +0 -6
@@ -0,0 +1,388 @@
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.__memoryTestUtils = void 0;
37
+ exports.ensureMemoryStorePaths = ensureMemoryStorePaths;
38
+ exports.appendFactsWithDedup = appendFactsWithDedup;
39
+ exports.readMemoryFacts = readMemoryFacts;
40
+ exports.saveMemoryFact = saveMemoryFact;
41
+ exports.backfillEmbeddings = backfillEmbeddings;
42
+ exports.searchMemoryFacts = searchMemoryFacts;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const crypto_1 = require("crypto");
46
+ const config_1 = require("../heart/config");
47
+ const identity_1 = require("../heart/identity");
48
+ const runtime_1 = require("../nerves/runtime");
49
+ const DEDUP_THRESHOLD = 0.6;
50
+ const ENTITY_TOKEN = /[a-z0-9]+/g;
51
+ const DEFAULT_EMBEDDING_MODEL = "text-embedding-3-small";
52
+ class OpenAIEmbeddingProvider {
53
+ apiKey;
54
+ model;
55
+ constructor(apiKey, model = DEFAULT_EMBEDDING_MODEL) {
56
+ this.apiKey = apiKey;
57
+ this.model = model;
58
+ }
59
+ async embed(texts) {
60
+ const response = await fetch("https://api.openai.com/v1/embeddings", {
61
+ method: "POST",
62
+ headers: {
63
+ Authorization: `Bearer ${this.apiKey}`,
64
+ "Content-Type": "application/json",
65
+ },
66
+ body: JSON.stringify({
67
+ model: this.model,
68
+ input: texts,
69
+ }),
70
+ });
71
+ if (!response.ok) {
72
+ throw new Error(`embedding request failed: ${response.status} ${response.statusText}`);
73
+ }
74
+ const payload = (await response.json());
75
+ if (!payload.data || payload.data.length !== texts.length) {
76
+ throw new Error("embedding response missing expected vectors");
77
+ }
78
+ return payload.data.map((entry) => entry.embedding);
79
+ }
80
+ }
81
+ function ensureMemoryStorePaths(rootDir) {
82
+ const factsPath = path.join(rootDir, "facts.jsonl");
83
+ const entitiesPath = path.join(rootDir, "entities.json");
84
+ const dailyDir = path.join(rootDir, "daily");
85
+ fs.mkdirSync(rootDir, { recursive: true });
86
+ fs.mkdirSync(dailyDir, { recursive: true });
87
+ if (!fs.existsSync(factsPath))
88
+ fs.writeFileSync(factsPath, "", "utf8");
89
+ if (!fs.existsSync(entitiesPath))
90
+ fs.writeFileSync(entitiesPath, "{}\n", "utf8");
91
+ (0, runtime_1.emitNervesEvent)({
92
+ component: "mind",
93
+ event: "mind.memory_paths_ready",
94
+ message: "memory store paths ready",
95
+ meta: { rootDir },
96
+ });
97
+ return { rootDir, factsPath, entitiesPath, dailyDir };
98
+ }
99
+ function overlapScore(left, right) {
100
+ const leftWords = new Set(left
101
+ .toLowerCase()
102
+ .split(/[^a-z0-9]+/g)
103
+ .filter(Boolean));
104
+ const rightWords = new Set(right
105
+ .toLowerCase()
106
+ .split(/[^a-z0-9]+/g)
107
+ .filter(Boolean));
108
+ if (leftWords.size === 0 || rightWords.size === 0)
109
+ return 0;
110
+ let common = 0;
111
+ for (const word of leftWords) {
112
+ if (rightWords.has(word))
113
+ common++;
114
+ }
115
+ return common / Math.min(leftWords.size, rightWords.size);
116
+ }
117
+ function readExistingFacts(factsPath) {
118
+ if (!fs.existsSync(factsPath))
119
+ return [];
120
+ const raw = fs.readFileSync(factsPath, "utf8").trim();
121
+ if (!raw)
122
+ return [];
123
+ return raw
124
+ .split("\n")
125
+ .map((line) => JSON.parse(line));
126
+ }
127
+ function readEntityIndex(entitiesPath) {
128
+ if (!fs.existsSync(entitiesPath))
129
+ return {};
130
+ try {
131
+ const raw = fs.readFileSync(entitiesPath, "utf8").trim();
132
+ if (!raw)
133
+ return {};
134
+ return JSON.parse(raw);
135
+ }
136
+ catch {
137
+ return {};
138
+ }
139
+ }
140
+ function writeEntityIndex(entitiesPath, index) {
141
+ fs.writeFileSync(entitiesPath, JSON.stringify(index, null, 2) + "\n", "utf8");
142
+ }
143
+ function extractEntityTokens(text) {
144
+ const matches = text.toLowerCase().match(ENTITY_TOKEN) ?? [];
145
+ return [...new Set(matches.filter((token) => token.length >= 3))];
146
+ }
147
+ function updateEntityIndex(entitiesPath, fact) {
148
+ const index = readEntityIndex(entitiesPath);
149
+ const tokens = extractEntityTokens(fact.text);
150
+ for (const token of tokens) {
151
+ const existing = index[token];
152
+ if (existing) {
153
+ existing.count += 1;
154
+ if (!existing.factIds.includes(fact.id))
155
+ existing.factIds.push(fact.id);
156
+ existing.lastSeenAt = fact.createdAt;
157
+ continue;
158
+ }
159
+ index[token] = {
160
+ count: 1,
161
+ factIds: [fact.id],
162
+ lastSeenAt: fact.createdAt,
163
+ };
164
+ }
165
+ writeEntityIndex(entitiesPath, index);
166
+ }
167
+ function appendDailyFact(dailyDir, fact) {
168
+ fs.mkdirSync(dailyDir, { recursive: true });
169
+ const day = fact.createdAt.slice(0, 10) || "unknown";
170
+ const dayPath = path.join(dailyDir, `${day}.jsonl`);
171
+ fs.appendFileSync(dayPath, `${JSON.stringify(fact)}\n`, "utf8");
172
+ }
173
+ function appendFactsWithDedup(stores, incoming) {
174
+ const existing = readExistingFacts(stores.factsPath);
175
+ const all = [...existing];
176
+ let added = 0;
177
+ let skipped = 0;
178
+ for (const fact of incoming) {
179
+ const duplicate = all.some((prior) => overlapScore(prior.text, fact.text) > DEDUP_THRESHOLD);
180
+ if (duplicate) {
181
+ skipped++;
182
+ continue;
183
+ }
184
+ all.push(fact);
185
+ added++;
186
+ fs.appendFileSync(stores.factsPath, `${JSON.stringify(fact)}\n`, "utf8");
187
+ updateEntityIndex(stores.entitiesPath, fact);
188
+ appendDailyFact(stores.dailyDir, fact);
189
+ }
190
+ (0, runtime_1.emitNervesEvent)({
191
+ component: "mind",
192
+ event: "mind.memory_write",
193
+ message: "memory write completed",
194
+ meta: { added, skipped },
195
+ });
196
+ return { added, skipped };
197
+ }
198
+ function cosineSimilarity(left, right) {
199
+ if (left.length === 0 || right.length === 0 || left.length !== right.length)
200
+ return 0;
201
+ let dot = 0;
202
+ let leftNorm = 0;
203
+ let rightNorm = 0;
204
+ for (let i = 0; i < left.length; i += 1) {
205
+ dot += left[i] * right[i];
206
+ leftNorm += left[i] * left[i];
207
+ rightNorm += right[i] * right[i];
208
+ }
209
+ if (leftNorm === 0 || rightNorm === 0)
210
+ return 0;
211
+ return dot / (Math.sqrt(leftNorm) * Math.sqrt(rightNorm));
212
+ }
213
+ exports.__memoryTestUtils = {
214
+ cosineSimilarity,
215
+ };
216
+ function createDefaultEmbeddingProvider() {
217
+ const apiKey = (0, config_1.getOpenAIEmbeddingsApiKey)().trim();
218
+ if (!apiKey)
219
+ return null;
220
+ return new OpenAIEmbeddingProvider(apiKey);
221
+ }
222
+ async function buildEmbedding(text, embeddingProvider) {
223
+ const provider = embeddingProvider ?? createDefaultEmbeddingProvider();
224
+ if (!provider) {
225
+ (0, runtime_1.emitNervesEvent)({
226
+ level: "warn",
227
+ component: "mind",
228
+ event: "mind.memory_embedding_unavailable",
229
+ message: "embedding provider unavailable for memory write",
230
+ meta: { reason: "missing_openai_embeddings_key" },
231
+ });
232
+ return [];
233
+ }
234
+ try {
235
+ const vectors = await provider.embed([text]);
236
+ return vectors[0] ?? [];
237
+ }
238
+ catch (error) {
239
+ (0, runtime_1.emitNervesEvent)({
240
+ level: "warn",
241
+ component: "mind",
242
+ event: "mind.memory_embedding_unavailable",
243
+ message: "embedding provider unavailable for memory write",
244
+ meta: {
245
+ reason: error instanceof Error ? error.message : String(error),
246
+ },
247
+ });
248
+ return [];
249
+ }
250
+ }
251
+ function readMemoryFacts(memoryRoot = path.join((0, identity_1.getAgentRoot)(), "psyche", "memory")) {
252
+ return readExistingFacts(path.join(memoryRoot, "facts.jsonl"));
253
+ }
254
+ async function saveMemoryFact(options) {
255
+ const text = options.text.trim();
256
+ const memoryRoot = options.memoryRoot ?? path.join((0, identity_1.getAgentRoot)(), "psyche", "memory");
257
+ const stores = ensureMemoryStorePaths(memoryRoot);
258
+ const embedding = await buildEmbedding(text, options.embeddingProvider);
259
+ const fact = {
260
+ id: options.idFactory ? options.idFactory() : (0, crypto_1.randomUUID)(),
261
+ text,
262
+ source: options.source,
263
+ about: options.about?.trim() || undefined,
264
+ createdAt: (options.now ?? (() => new Date()))().toISOString(),
265
+ embedding,
266
+ };
267
+ return appendFactsWithDedup(stores, [fact]);
268
+ }
269
+ async function backfillEmbeddings(options) {
270
+ const memoryRoot = options?.memoryRoot ?? path.join((0, identity_1.getAgentRoot)(), "psyche", "memory");
271
+ const factsPath = path.join(memoryRoot, "facts.jsonl");
272
+ if (!fs.existsSync(factsPath))
273
+ return { total: 0, backfilled: 0, failed: 0 };
274
+ const facts = readExistingFacts(factsPath);
275
+ const needsEmbedding = facts.filter((f) => !Array.isArray(f.embedding) || f.embedding.length === 0);
276
+ if (needsEmbedding.length === 0)
277
+ return { total: facts.length, backfilled: 0, failed: 0 };
278
+ const provider = options?.embeddingProvider ?? createDefaultEmbeddingProvider();
279
+ if (!provider) {
280
+ (0, runtime_1.emitNervesEvent)({
281
+ level: "warn",
282
+ component: "mind",
283
+ event: "mind.memory_backfill_skipped",
284
+ message: "embedding provider unavailable for backfill",
285
+ meta: { needsEmbedding: needsEmbedding.length },
286
+ });
287
+ return { total: facts.length, backfilled: 0, failed: needsEmbedding.length };
288
+ }
289
+ const batchSize = options?.batchSize ?? 50;
290
+ let backfilled = 0;
291
+ let failed = 0;
292
+ for (let i = 0; i < needsEmbedding.length; i += batchSize) {
293
+ const batch = needsEmbedding.slice(i, i + batchSize);
294
+ try {
295
+ const vectors = await provider.embed(batch.map((f) => f.text));
296
+ for (let j = 0; j < batch.length; j++) {
297
+ batch[j].embedding = vectors[j] ?? [];
298
+ if (batch[j].embedding.length > 0)
299
+ backfilled++;
300
+ else
301
+ failed++;
302
+ }
303
+ }
304
+ catch (error) {
305
+ failed += batch.length;
306
+ (0, runtime_1.emitNervesEvent)({
307
+ level: "warn",
308
+ component: "mind",
309
+ event: "mind.memory_backfill_batch_error",
310
+ message: "embedding backfill batch failed",
311
+ meta: {
312
+ batchStart: i,
313
+ batchSize: batch.length,
314
+ reason: error instanceof Error ? error.message : String(error),
315
+ },
316
+ });
317
+ }
318
+ }
319
+ // Rewrite facts file with updated embeddings
320
+ const lines = facts.map((f) => JSON.stringify(f)).join("\n") + "\n";
321
+ fs.writeFileSync(factsPath, lines, "utf8");
322
+ (0, runtime_1.emitNervesEvent)({
323
+ component: "mind",
324
+ event: "mind.memory_backfill_complete",
325
+ message: "embedding backfill completed",
326
+ meta: { total: facts.length, backfilled, failed },
327
+ });
328
+ return { total: facts.length, backfilled, failed };
329
+ }
330
+ function substringMatches(queryLower, facts) {
331
+ return facts.filter((fact) => fact.text.toLowerCase().includes(queryLower));
332
+ }
333
+ function uniqueFacts(facts) {
334
+ const seen = new Set();
335
+ const unique = [];
336
+ for (const fact of facts) {
337
+ if (seen.has(fact.id))
338
+ continue;
339
+ seen.add(fact.id);
340
+ unique.push(fact);
341
+ }
342
+ return unique;
343
+ }
344
+ async function searchMemoryFacts(query, facts, embeddingProvider) {
345
+ const trimmed = query.trim();
346
+ if (!trimmed)
347
+ return [];
348
+ const queryLower = trimmed.toLowerCase();
349
+ const substringFallback = () => substringMatches(queryLower, facts).slice(0, 5);
350
+ const embeddedFacts = facts.filter((fact) => Array.isArray(fact.embedding) && fact.embedding.length > 0);
351
+ if (embeddedFacts.length === 0) {
352
+ return substringFallback();
353
+ }
354
+ const provider = embeddingProvider ?? createDefaultEmbeddingProvider();
355
+ if (!provider) {
356
+ return substringFallback();
357
+ }
358
+ try {
359
+ const vectors = await provider.embed([trimmed]);
360
+ const queryEmbedding = vectors[0];
361
+ if (!Array.isArray(queryEmbedding) || queryEmbedding.length === 0) {
362
+ return substringFallback();
363
+ }
364
+ const scored = embeddedFacts
365
+ .filter((fact) => fact.embedding.length === queryEmbedding.length)
366
+ .map((fact) => ({
367
+ fact,
368
+ score: cosineSimilarity(queryEmbedding, fact.embedding),
369
+ }))
370
+ .filter((entry) => entry.score > 0)
371
+ .sort((left, right) => right.score - left.score)
372
+ .map((entry) => entry.fact);
373
+ const fallback = substringFallback();
374
+ return uniqueFacts([...scored, ...fallback]).slice(0, 5);
375
+ }
376
+ catch (error) {
377
+ (0, runtime_1.emitNervesEvent)({
378
+ level: "warn",
379
+ component: "mind",
380
+ event: "mind.memory_embedding_unavailable",
381
+ message: "embedding provider unavailable for memory search",
382
+ meta: {
383
+ reason: error instanceof Error ? error.message : String(error),
384
+ },
385
+ });
386
+ return substringFallback();
387
+ }
388
+ }
@@ -0,0 +1,93 @@
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.getPendingDir = getPendingDir;
37
+ exports.drainPending = drainPending;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const os = __importStar(require("os"));
41
+ const runtime_1 = require("../nerves/runtime");
42
+ function getPendingDir(agentName, friendId, channel, key) {
43
+ return path.join(os.homedir(), ".agentstate", agentName, "pending", friendId, channel, key);
44
+ }
45
+ function drainPending(pendingDir) {
46
+ if (!fs.existsSync(pendingDir))
47
+ return [];
48
+ let entries;
49
+ try {
50
+ entries = fs.readdirSync(pendingDir);
51
+ }
52
+ catch {
53
+ return [];
54
+ }
55
+ // Collect both .json (new) and .processing (crash recovery)
56
+ const jsonFiles = entries.filter(f => f.endsWith(".json") && !f.endsWith(".processing"));
57
+ const processingFiles = entries.filter(f => f.endsWith(".json.processing"));
58
+ // Sort by filename (timestamp prefix gives chronological order)
59
+ const allFiles = [
60
+ ...processingFiles.map(f => ({ file: f, needsRename: false })),
61
+ ...jsonFiles.map(f => ({ file: f, needsRename: true })),
62
+ ].sort((a, b) => a.file.localeCompare(b.file));
63
+ const messages = [];
64
+ for (const { file, needsRename } of allFiles) {
65
+ const srcPath = path.join(pendingDir, file);
66
+ const processingPath = needsRename
67
+ ? path.join(pendingDir, file + ".processing")
68
+ : srcPath;
69
+ try {
70
+ if (needsRename) {
71
+ fs.renameSync(srcPath, processingPath);
72
+ }
73
+ const raw = fs.readFileSync(processingPath, "utf-8");
74
+ const parsed = JSON.parse(raw);
75
+ messages.push(parsed);
76
+ fs.unlinkSync(processingPath);
77
+ }
78
+ catch {
79
+ // Skip unparseable files — still try to clean up
80
+ try {
81
+ fs.unlinkSync(processingPath);
82
+ }
83
+ catch { /* ignore */ }
84
+ }
85
+ }
86
+ (0, runtime_1.emitNervesEvent)({
87
+ event: "mind.pending_drained",
88
+ component: "mind",
89
+ message: "pending queue drained",
90
+ meta: { pendingDir, count: messages.length, recovered: processingFiles.length },
91
+ });
92
+ return messages;
93
+ }
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ // Shared phrase pools for fun loading messages.
3
+ // Phrases have NO trailing "..." -- adapters add that.
4
+ // Pools are loaded from agent.json via loadAgentConfig().
5
+ // If agent.json has no phrases, loadAgentConfig() auto-fills placeholders.
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.getPhrases = getPhrases;
8
+ exports.pickPhrase = pickPhrase;
9
+ const identity_1 = require("../heart/identity");
10
+ const runtime_1 = require("../nerves/runtime");
11
+ // Returns phrase pools from agent.json (always present — loadAgentConfig auto-fills).
12
+ function getPhrases() {
13
+ (0, runtime_1.emitNervesEvent)({
14
+ event: "repertoire.load_start",
15
+ component: "repertoire",
16
+ message: "loading phrase pools",
17
+ meta: {},
18
+ });
19
+ const phrases = (0, identity_1.loadAgentConfig)().phrases;
20
+ (0, runtime_1.emitNervesEvent)({
21
+ event: "repertoire.load_end",
22
+ component: "repertoire",
23
+ message: "loaded phrase pools",
24
+ meta: {
25
+ thinking_count: phrases.thinking.length,
26
+ tool_count: phrases.tool.length,
27
+ followup_count: phrases.followup.length,
28
+ },
29
+ });
30
+ return phrases;
31
+ }
32
+ // Pick a random phrase from a pool, avoiding immediate repeats.
33
+ function pickPhrase(pool, lastUsed) {
34
+ if (pool.length === 0)
35
+ return "";
36
+ if (pool.length === 1)
37
+ return pool[0];
38
+ let pick;
39
+ do {
40
+ pick = pool[Math.floor(Math.random() * pool.length)];
41
+ } while (pick === lastUsed);
42
+ return pick;
43
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.refreshSystemPrompt = refreshSystemPrompt;
4
+ const prompt_1 = require("./prompt");
5
+ const runtime_1 = require("../nerves/runtime");
6
+ async function refreshSystemPrompt(messages, channel, options, context) {
7
+ const newSystem = await (0, prompt_1.buildSystem)(channel, options, context);
8
+ if (messages.length > 0 && messages[0].role === "system") {
9
+ messages[0] = { role: "system", content: newSystem };
10
+ }
11
+ else {
12
+ messages.unshift({ role: "system", content: newSystem });
13
+ }
14
+ (0, runtime_1.emitNervesEvent)({
15
+ event: "mind.system_prompt_refreshed",
16
+ component: "mind",
17
+ message: "system prompt refreshed",
18
+ meta: { channel },
19
+ });
20
+ }