@hilbras/omninode 0.7.0 → 0.8.0
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 +22 -3
- package/dist/cli/index.js +398 -19
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +143 -11
- package/dist/index.js +350 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -160,7 +160,11 @@ var projectConfigSchema = z.object({
|
|
|
160
160
|
agents: z.array(agentConfigSchema).default([]),
|
|
161
161
|
roles: z.array(roleConfigSchema).default([]),
|
|
162
162
|
pipelines: z.array(pipelineConfigSchema).default([]),
|
|
163
|
-
memory: z.object({
|
|
163
|
+
memory: z.object({
|
|
164
|
+
provider: z.string().min(1).default("local"),
|
|
165
|
+
base_url: z.string().url().optional(),
|
|
166
|
+
api_key_env_var: z.string().min(1).optional()
|
|
167
|
+
}).strict().optional()
|
|
164
168
|
}).strict();
|
|
165
169
|
var appConfigSchema = z.object({
|
|
166
170
|
project: projectConfigSchema,
|
|
@@ -230,7 +234,13 @@ function toAppConfig(yaml) {
|
|
|
230
234
|
agents: yaml.project.agents.map(toAgentConfig),
|
|
231
235
|
roles: yaml.project.roles.map(toRoleDefinition),
|
|
232
236
|
pipelines: yaml.project.pipelines.map(toPipelineDefinition),
|
|
233
|
-
...yaml.project.memory !== void 0 ? {
|
|
237
|
+
...yaml.project.memory !== void 0 ? {
|
|
238
|
+
memory: {
|
|
239
|
+
provider: yaml.project.memory.provider,
|
|
240
|
+
baseUrl: yaml.project.memory.base_url,
|
|
241
|
+
apiKeyEnvVar: yaml.project.memory.api_key_env_var
|
|
242
|
+
}
|
|
243
|
+
} : {}
|
|
234
244
|
},
|
|
235
245
|
...yaml.logging !== void 0 ? { logging: yaml.logging } : {}
|
|
236
246
|
};
|
|
@@ -1079,13 +1089,24 @@ var TaskEngine = class {
|
|
|
1079
1089
|
const role = task.role ? this.options.roles.get(task.role) : void 0;
|
|
1080
1090
|
const running = await this.transition(task, "running");
|
|
1081
1091
|
this.log.info(`Running task ${task.id} on agent "${task.agent}".`);
|
|
1092
|
+
let background = running.context?.background;
|
|
1093
|
+
if (this.options.memory) {
|
|
1094
|
+
const memoryContext = await this.options.memory.gatherContext({
|
|
1095
|
+
objective: running.objective,
|
|
1096
|
+
...running.role ? { role: running.role } : {},
|
|
1097
|
+
...running.project ? { project: running.project } : {}
|
|
1098
|
+
});
|
|
1099
|
+
if (memoryContext.length > 0) {
|
|
1100
|
+
background = [memoryContext, background].filter((part) => part && part.length > 0).join("\n\n");
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1082
1103
|
let output;
|
|
1083
1104
|
try {
|
|
1084
1105
|
output = await agent.run({
|
|
1085
1106
|
taskId: running.id,
|
|
1086
1107
|
objective: running.objective,
|
|
1087
1108
|
...role ? { role } : {},
|
|
1088
|
-
...
|
|
1109
|
+
...background !== void 0 ? { context: background } : {}
|
|
1089
1110
|
});
|
|
1090
1111
|
} catch (error) {
|
|
1091
1112
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -1103,8 +1124,12 @@ var TaskEngine = class {
|
|
|
1103
1124
|
finishedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1104
1125
|
};
|
|
1105
1126
|
const finalStatus = output.status === "completed" ? "completed" : "failed";
|
|
1127
|
+
const finished = await this.transition(running, finalStatus, { result });
|
|
1106
1128
|
this.log.info(`Task ${task.id} finished: ${finalStatus}.`);
|
|
1107
|
-
|
|
1129
|
+
if (this.options.memory) {
|
|
1130
|
+
await this.options.memory.recordTaskOutcome(finished);
|
|
1131
|
+
}
|
|
1132
|
+
return finished;
|
|
1108
1133
|
}
|
|
1109
1134
|
async cancel(id) {
|
|
1110
1135
|
const task = await this.mustGet(id);
|
|
@@ -1149,12 +1174,306 @@ function generateTaskId() {
|
|
|
1149
1174
|
return `task-${Date.now().toString(36)}-${randomBytes(3).toString("hex")}`;
|
|
1150
1175
|
}
|
|
1151
1176
|
|
|
1177
|
+
// src/memory/local.ts
|
|
1178
|
+
import { mkdir as mkdir2, readFile as readFile2, rename as rename2, writeFile as writeFile2 } from "fs/promises";
|
|
1179
|
+
import { dirname as dirname2 } from "path";
|
|
1180
|
+
var STOPWORDS = /* @__PURE__ */ new Set([
|
|
1181
|
+
"the",
|
|
1182
|
+
"and",
|
|
1183
|
+
"for",
|
|
1184
|
+
"with",
|
|
1185
|
+
"this",
|
|
1186
|
+
"that",
|
|
1187
|
+
"from",
|
|
1188
|
+
"into",
|
|
1189
|
+
"was",
|
|
1190
|
+
"were",
|
|
1191
|
+
"have",
|
|
1192
|
+
"has",
|
|
1193
|
+
"had",
|
|
1194
|
+
"are",
|
|
1195
|
+
"but",
|
|
1196
|
+
"not",
|
|
1197
|
+
"you",
|
|
1198
|
+
"his",
|
|
1199
|
+
"her",
|
|
1200
|
+
"its",
|
|
1201
|
+
"their",
|
|
1202
|
+
"them",
|
|
1203
|
+
"then",
|
|
1204
|
+
"than",
|
|
1205
|
+
"when",
|
|
1206
|
+
"what",
|
|
1207
|
+
"which",
|
|
1208
|
+
"will",
|
|
1209
|
+
"would",
|
|
1210
|
+
"been",
|
|
1211
|
+
"were",
|
|
1212
|
+
"also",
|
|
1213
|
+
"because",
|
|
1214
|
+
"about",
|
|
1215
|
+
"after",
|
|
1216
|
+
"before"
|
|
1217
|
+
]);
|
|
1218
|
+
function keywords(text) {
|
|
1219
|
+
return new Set(
|
|
1220
|
+
(text ?? "").toLowerCase().replace(/[^a-z0-9\s]/g, " ").split(/\s+/).filter((t) => t.length >= 4 && !STOPWORDS.has(t))
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
function relevanceScore(queryKeywords, entry) {
|
|
1224
|
+
if (queryKeywords.size === 0) return 0;
|
|
1225
|
+
const entryKeywords = keywords(`${entry.content} ${entry.key}`);
|
|
1226
|
+
let overlap = 0;
|
|
1227
|
+
for (const keyword of queryKeywords) {
|
|
1228
|
+
if (entryKeywords.has(keyword)) overlap += 1;
|
|
1229
|
+
}
|
|
1230
|
+
let tagMatches = 0;
|
|
1231
|
+
for (const tag of entry.tags ?? []) {
|
|
1232
|
+
if (queryKeywords.has(tag.toLowerCase())) tagMatches += 1;
|
|
1233
|
+
}
|
|
1234
|
+
return overlap * 2 + tagMatches * 1.5;
|
|
1235
|
+
}
|
|
1236
|
+
var LocalMemoryProvider = class {
|
|
1237
|
+
name = "local";
|
|
1238
|
+
filePath;
|
|
1239
|
+
queue = Promise.resolve();
|
|
1240
|
+
constructor(directory = `${process.cwd()}/.omninode`) {
|
|
1241
|
+
this.filePath = `${directory}/memory.json`;
|
|
1242
|
+
}
|
|
1243
|
+
async query(query) {
|
|
1244
|
+
return this.synchronized(async () => {
|
|
1245
|
+
const entries = await this.load();
|
|
1246
|
+
const filtered = entries.filter((entry) => query.scope ? entry.scope === query.scope : true).filter(
|
|
1247
|
+
(entry) => query.tags && query.tags.length > 0 ? query.tags.every((tag) => (entry.tags ?? []).includes(tag)) : true
|
|
1248
|
+
);
|
|
1249
|
+
if (!query.text || query.text.trim().length === 0) {
|
|
1250
|
+
return filtered.sort((a, b) => (b.updatedAt ?? b.createdAt ?? "").localeCompare(a.updatedAt ?? a.createdAt ?? "")).slice(0, query.limit ?? 10);
|
|
1251
|
+
}
|
|
1252
|
+
const queryKeywords = keywords(query.text);
|
|
1253
|
+
return filtered.map((entry) => ({ entry, score: relevanceScore(queryKeywords, entry) })).filter(({ score }) => score > 0).sort((a, b) => b.score - a.score).slice(0, query.limit ?? 10).map(({ entry }) => entry);
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
async write(entry) {
|
|
1257
|
+
return this.synchronized(async () => {
|
|
1258
|
+
const entries = await this.load();
|
|
1259
|
+
const index = entries.findIndex((e) => e.key === entry.key);
|
|
1260
|
+
const stamped = {
|
|
1261
|
+
...entry,
|
|
1262
|
+
createdAt: entry.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
1263
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1264
|
+
};
|
|
1265
|
+
if (index >= 0) entries[index] = stamped;
|
|
1266
|
+
else entries.push(stamped);
|
|
1267
|
+
await this.saveAll(entries);
|
|
1268
|
+
});
|
|
1269
|
+
}
|
|
1270
|
+
async count() {
|
|
1271
|
+
return (await this.load()).length;
|
|
1272
|
+
}
|
|
1273
|
+
synchronized(operation) {
|
|
1274
|
+
const result = this.queue.then(operation, operation);
|
|
1275
|
+
this.queue = result.then(
|
|
1276
|
+
() => void 0,
|
|
1277
|
+
() => void 0
|
|
1278
|
+
);
|
|
1279
|
+
return result;
|
|
1280
|
+
}
|
|
1281
|
+
async load() {
|
|
1282
|
+
try {
|
|
1283
|
+
const raw = await readFile2(this.filePath, "utf8");
|
|
1284
|
+
const parsed = JSON.parse(raw);
|
|
1285
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
1286
|
+
} catch {
|
|
1287
|
+
return [];
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
async saveAll(entries) {
|
|
1291
|
+
const tmp = `${this.filePath}.tmp`;
|
|
1292
|
+
await mkdir2(dirname2(this.filePath), { recursive: true });
|
|
1293
|
+
await writeFile2(tmp, `${JSON.stringify(entries, null, 2)}
|
|
1294
|
+
`, "utf8");
|
|
1295
|
+
await rename2(tmp, this.filePath);
|
|
1296
|
+
}
|
|
1297
|
+
};
|
|
1298
|
+
|
|
1299
|
+
// src/memory/remembera.ts
|
|
1300
|
+
var RememberaMemoryProvider = class {
|
|
1301
|
+
name = "remembera";
|
|
1302
|
+
baseUrl;
|
|
1303
|
+
apiKeyEnvVar;
|
|
1304
|
+
env;
|
|
1305
|
+
log;
|
|
1306
|
+
constructor(config, log = logger) {
|
|
1307
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, "");
|
|
1308
|
+
this.apiKeyEnvVar = config.apiKeyEnvVar;
|
|
1309
|
+
this.env = config.env ?? process.env;
|
|
1310
|
+
this.log = log.child({ component: "remembera" });
|
|
1311
|
+
}
|
|
1312
|
+
headers() {
|
|
1313
|
+
const key = this.apiKeyEnvVar ? resolveApiKey({ name: "remembera", apiKeyEnvVar: this.apiKeyEnvVar }, this.env) : void 0;
|
|
1314
|
+
return key ? { authorization: `Bearer ${key}` } : {};
|
|
1315
|
+
}
|
|
1316
|
+
async query(query) {
|
|
1317
|
+
const { status, body } = await this.request(`${this.baseUrl}/api/memory/query`, query);
|
|
1318
|
+
if (status !== 200) {
|
|
1319
|
+
throw new MemoryError(`Remembera query returned HTTP ${status}.`);
|
|
1320
|
+
}
|
|
1321
|
+
const entries = body.entries;
|
|
1322
|
+
if (!Array.isArray(entries)) {
|
|
1323
|
+
throw new MemoryError("Remembera query response had no entries array.");
|
|
1324
|
+
}
|
|
1325
|
+
return entries.map((entry) => this.toEntry(entry)).filter((entry) => entry !== void 0);
|
|
1326
|
+
}
|
|
1327
|
+
async write(entry) {
|
|
1328
|
+
const { status } = await this.request(`${this.baseUrl}/api/memory`, entry);
|
|
1329
|
+
if (status !== 200 && status !== 201) {
|
|
1330
|
+
throw new MemoryError(`Remembera write returned HTTP ${status}.`);
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
async request(url, body) {
|
|
1334
|
+
const headers = this.headers();
|
|
1335
|
+
try {
|
|
1336
|
+
return await requestJson(url, {
|
|
1337
|
+
method: "POST",
|
|
1338
|
+
headers,
|
|
1339
|
+
body
|
|
1340
|
+
});
|
|
1341
|
+
} catch (error) {
|
|
1342
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1343
|
+
throw new MemoryError(`Remembera request to ${url} failed: ${message}`, { cause: error });
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
toEntry(raw) {
|
|
1347
|
+
if (raw === null || typeof raw !== "object") {
|
|
1348
|
+
this.log.warn("Skipping malformed Remembera memory entry.");
|
|
1349
|
+
return void 0;
|
|
1350
|
+
}
|
|
1351
|
+
const entry = raw;
|
|
1352
|
+
if (typeof entry.key !== "string" || typeof entry.content !== "string") {
|
|
1353
|
+
this.log.warn("Skipping Remembera memory entry without key/content.");
|
|
1354
|
+
return void 0;
|
|
1355
|
+
}
|
|
1356
|
+
const scope = entry.scope;
|
|
1357
|
+
return {
|
|
1358
|
+
key: entry.key,
|
|
1359
|
+
content: entry.content,
|
|
1360
|
+
scope: scope === "project" || scope === "role" || scope === "task" || scope === "knowledge" ? scope : "knowledge",
|
|
1361
|
+
...Array.isArray(entry.tags) ? { tags: entry.tags.filter((t) => typeof t === "string") } : {},
|
|
1362
|
+
...typeof entry.createdAt === "string" ? { createdAt: entry.createdAt } : {},
|
|
1363
|
+
...typeof entry.updatedAt === "string" ? { updatedAt: entry.updatedAt } : {}
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
};
|
|
1367
|
+
|
|
1368
|
+
// src/memory/factory.ts
|
|
1369
|
+
function createMemoryProvider(config) {
|
|
1370
|
+
if (!config || config.provider === "local") {
|
|
1371
|
+
return new LocalMemoryProvider();
|
|
1372
|
+
}
|
|
1373
|
+
if (config.provider === "remembera") {
|
|
1374
|
+
if (!config.baseUrl) {
|
|
1375
|
+
throw new ConfigError(
|
|
1376
|
+
"CONFIG_INVALID",
|
|
1377
|
+
`Memory provider "remembera" needs a base_url in omninode.yaml.`
|
|
1378
|
+
);
|
|
1379
|
+
}
|
|
1380
|
+
return new RememberaMemoryProvider({
|
|
1381
|
+
baseUrl: config.baseUrl,
|
|
1382
|
+
apiKeyEnvVar: config.apiKeyEnvVar
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
throw new ConfigError(
|
|
1386
|
+
"CONFIG_INVALID",
|
|
1387
|
+
`Unknown memory provider "${config.provider}". Available: local, remembera.`
|
|
1388
|
+
);
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
// src/memory/service.ts
|
|
1392
|
+
var MAX_CONTEXT_CHARS = 4e3;
|
|
1393
|
+
var MemoryService = class {
|
|
1394
|
+
constructor(provider, log = logger) {
|
|
1395
|
+
this.provider = provider;
|
|
1396
|
+
this.log = log.child({ component: "memory", provider: provider.name });
|
|
1397
|
+
}
|
|
1398
|
+
provider;
|
|
1399
|
+
log;
|
|
1400
|
+
get providerRef() {
|
|
1401
|
+
return this.provider;
|
|
1402
|
+
}
|
|
1403
|
+
get providerName() {
|
|
1404
|
+
return this.provider.name;
|
|
1405
|
+
}
|
|
1406
|
+
/** Relevant context for a task objective; empty string when nothing matches. */
|
|
1407
|
+
async gatherContext(query) {
|
|
1408
|
+
try {
|
|
1409
|
+
const entries = await this.provider.query({
|
|
1410
|
+
text: query.objective,
|
|
1411
|
+
...query.role ? { tags: [query.role] } : {},
|
|
1412
|
+
limit: 8
|
|
1413
|
+
});
|
|
1414
|
+
if (entries.length === 0) return "";
|
|
1415
|
+
const byScope = /* @__PURE__ */ new Map();
|
|
1416
|
+
for (const entry of entries) {
|
|
1417
|
+
byScope.set(entry.scope, [...byScope.get(entry.scope) ?? [], entry]);
|
|
1418
|
+
}
|
|
1419
|
+
const parts = [];
|
|
1420
|
+
for (const scope of ["project", "task", "role", "knowledge"]) {
|
|
1421
|
+
const scopeEntries = byScope.get(scope) ?? [];
|
|
1422
|
+
if (scopeEntries.length === 0) continue;
|
|
1423
|
+
const lines = scopeEntries.map((entry) => `- ${entry.content}`).join("\n");
|
|
1424
|
+
parts.push(`### Relevant memory (${scope})
|
|
1425
|
+
${lines}`);
|
|
1426
|
+
}
|
|
1427
|
+
const context = parts.join("\n\n");
|
|
1428
|
+
return context.length > MAX_CONTEXT_CHARS ? `${context.slice(0, MAX_CONTEXT_CHARS)}\u2026` : context;
|
|
1429
|
+
} catch (error) {
|
|
1430
|
+
this.log.warn(
|
|
1431
|
+
`Memory query failed (continuing without memory): ${error instanceof Error ? error.message : String(error)}`
|
|
1432
|
+
);
|
|
1433
|
+
return "";
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
/** Records a finished task's outcome — best-effort. */
|
|
1437
|
+
async recordTaskOutcome(task) {
|
|
1438
|
+
const outcome = task.result?.summary ?? task.result?.error ?? "(no output)";
|
|
1439
|
+
try {
|
|
1440
|
+
await this.provider.write({
|
|
1441
|
+
key: `task:${task.id}`,
|
|
1442
|
+
scope: "task",
|
|
1443
|
+
content: `Objective: ${task.objective}
|
|
1444
|
+
Status: ${task.status}
|
|
1445
|
+
Outcome: ${outcome}`,
|
|
1446
|
+
tags: ["task", ...task.agent ? [task.agent] : [], ...task.role ? [task.role] : []],
|
|
1447
|
+
createdAt: task.createdAt
|
|
1448
|
+
});
|
|
1449
|
+
const significant = (task.result?.reports ?? []).flatMap(
|
|
1450
|
+
(report) => report.findings.filter((finding) => finding.severity === "high" || finding.severity === "critical").map((finding) => ({ report, finding }))
|
|
1451
|
+
);
|
|
1452
|
+
for (const { report, finding } of significant) {
|
|
1453
|
+
await this.provider.write({
|
|
1454
|
+
key: `finding:${report.id}:${finding.id}`,
|
|
1455
|
+
scope: "project",
|
|
1456
|
+
content: `[${finding.severity}] ${finding.title} \u2014 ${finding.detail}`,
|
|
1457
|
+
tags: ["known-problem", report.agent]
|
|
1458
|
+
});
|
|
1459
|
+
}
|
|
1460
|
+
} catch (error) {
|
|
1461
|
+
this.log.warn(
|
|
1462
|
+
`Memory write failed (continuing): ${error instanceof Error ? error.message : String(error)}`
|
|
1463
|
+
);
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
};
|
|
1467
|
+
|
|
1152
1468
|
// src/tasks/engine-factory.ts
|
|
1153
1469
|
function createTaskEngine(config, log = logger, directory) {
|
|
1470
|
+
const agents = buildAgentRegistry(config, log);
|
|
1471
|
+
const roles = buildRoleRegistry(config);
|
|
1154
1472
|
return new TaskEngine({
|
|
1155
|
-
agents
|
|
1156
|
-
roles
|
|
1473
|
+
agents,
|
|
1474
|
+
roles,
|
|
1157
1475
|
store: new FileTaskStore(directory),
|
|
1476
|
+
...config.project.memory !== void 0 ? { memory: new MemoryService(createMemoryProvider(config.project.memory), log) } : {},
|
|
1158
1477
|
log
|
|
1159
1478
|
});
|
|
1160
1479
|
}
|
|
@@ -1531,8 +1850,8 @@ function createDefaultChatFn(providers) {
|
|
|
1531
1850
|
}
|
|
1532
1851
|
|
|
1533
1852
|
// src/pipelines/store.ts
|
|
1534
|
-
import { mkdir as
|
|
1535
|
-
import { dirname as
|
|
1853
|
+
import { mkdir as mkdir3, readFile as readFile3, rename as rename3, writeFile as writeFile3 } from "fs/promises";
|
|
1854
|
+
import { dirname as dirname3 } from "path";
|
|
1536
1855
|
var FilePipelineRunStore = class {
|
|
1537
1856
|
filePath;
|
|
1538
1857
|
queue = Promise.resolve();
|
|
@@ -1570,7 +1889,7 @@ var FilePipelineRunStore = class {
|
|
|
1570
1889
|
}
|
|
1571
1890
|
async load() {
|
|
1572
1891
|
try {
|
|
1573
|
-
const raw = await
|
|
1892
|
+
const raw = await readFile3(this.filePath, "utf8");
|
|
1574
1893
|
const parsed = JSON.parse(raw);
|
|
1575
1894
|
return Array.isArray(parsed) ? parsed : [];
|
|
1576
1895
|
} catch {
|
|
@@ -1579,10 +1898,10 @@ var FilePipelineRunStore = class {
|
|
|
1579
1898
|
}
|
|
1580
1899
|
async write(runs) {
|
|
1581
1900
|
const tmp = `${this.filePath}.tmp`;
|
|
1582
|
-
await
|
|
1583
|
-
await
|
|
1901
|
+
await mkdir3(dirname3(this.filePath), { recursive: true });
|
|
1902
|
+
await writeFile3(tmp, `${JSON.stringify(runs, null, 2)}
|
|
1584
1903
|
`, "utf8");
|
|
1585
|
-
await
|
|
1904
|
+
await rename3(tmp, this.filePath);
|
|
1586
1905
|
}
|
|
1587
1906
|
};
|
|
1588
1907
|
|
|
@@ -1797,8 +2116,8 @@ var ReportService = class {
|
|
|
1797
2116
|
};
|
|
1798
2117
|
|
|
1799
2118
|
// src/reports/store.ts
|
|
1800
|
-
import { mkdir as
|
|
1801
|
-
import { dirname as
|
|
2119
|
+
import { mkdir as mkdir4, readFile as readFile4, rename as rename4, writeFile as writeFile4 } from "fs/promises";
|
|
2120
|
+
import { dirname as dirname4 } from "path";
|
|
1802
2121
|
var FileReportStore = class {
|
|
1803
2122
|
filePath;
|
|
1804
2123
|
queue = Promise.resolve();
|
|
@@ -1862,7 +2181,7 @@ var FileReportStore = class {
|
|
|
1862
2181
|
}
|
|
1863
2182
|
async load() {
|
|
1864
2183
|
try {
|
|
1865
|
-
const raw = await
|
|
2184
|
+
const raw = await readFile4(this.filePath, "utf8");
|
|
1866
2185
|
const parsed = JSON.parse(raw);
|
|
1867
2186
|
return Array.isArray(parsed) ? parsed : [];
|
|
1868
2187
|
} catch {
|
|
@@ -1871,10 +2190,10 @@ var FileReportStore = class {
|
|
|
1871
2190
|
}
|
|
1872
2191
|
async write(entries) {
|
|
1873
2192
|
const tmp = `${this.filePath}.tmp`;
|
|
1874
|
-
await
|
|
1875
|
-
await
|
|
2193
|
+
await mkdir4(dirname4(this.filePath), { recursive: true });
|
|
2194
|
+
await writeFile4(tmp, `${JSON.stringify(entries, null, 2)}
|
|
1876
2195
|
`, "utf8");
|
|
1877
|
-
await
|
|
2196
|
+
await rename4(tmp, this.filePath);
|
|
1878
2197
|
}
|
|
1879
2198
|
};
|
|
1880
2199
|
|
|
@@ -1886,6 +2205,7 @@ function buildPipelineEngine(config, log = logger) {
|
|
|
1886
2205
|
agents,
|
|
1887
2206
|
roles,
|
|
1888
2207
|
store: new FileTaskStore(),
|
|
2208
|
+
...config.project.memory !== void 0 ? { memory: new MemoryService(createMemoryProvider(config.project.memory), log) } : {},
|
|
1889
2209
|
log
|
|
1890
2210
|
});
|
|
1891
2211
|
return new PipelineEngine({
|
|
@@ -1901,16 +2221,19 @@ function buildPipelineEngine(config, log = logger) {
|
|
|
1901
2221
|
}
|
|
1902
2222
|
|
|
1903
2223
|
// src/version.ts
|
|
1904
|
-
var OMNINODE_VERSION = "0.
|
|
2224
|
+
var OMNINODE_VERSION = "0.8.0";
|
|
1905
2225
|
export {
|
|
1906
2226
|
AgentError,
|
|
1907
2227
|
AgentRegistry,
|
|
1908
2228
|
ConfigError,
|
|
1909
2229
|
ConsoleLogSink,
|
|
1910
2230
|
FilePipelineRunStore,
|
|
2231
|
+
FileReportStore,
|
|
1911
2232
|
FileTaskStore,
|
|
2233
|
+
LocalMemoryProvider,
|
|
1912
2234
|
Logger,
|
|
1913
2235
|
MemoryError,
|
|
2236
|
+
MemoryService,
|
|
1914
2237
|
ModelRegistry,
|
|
1915
2238
|
OMNINODE_VERSION,
|
|
1916
2239
|
OPENAI_COMPATIBLE_TYPES,
|
|
@@ -1922,10 +2245,13 @@ export {
|
|
|
1922
2245
|
ProcessAgent,
|
|
1923
2246
|
ProtocolError,
|
|
1924
2247
|
ProviderError,
|
|
2248
|
+
RememberaMemoryProvider,
|
|
2249
|
+
ReportService,
|
|
1925
2250
|
RoleRegistry,
|
|
1926
2251
|
TaskEngine,
|
|
1927
2252
|
TaskError,
|
|
1928
2253
|
agentConfigSchema,
|
|
2254
|
+
aggregateReports,
|
|
1929
2255
|
appConfigSchema,
|
|
1930
2256
|
authHeaders,
|
|
1931
2257
|
buildAgentRegistry,
|
|
@@ -1934,12 +2260,15 @@ export {
|
|
|
1934
2260
|
composeTaskText,
|
|
1935
2261
|
createAgent,
|
|
1936
2262
|
createDefaultChatFn,
|
|
2263
|
+
createMemoryProvider,
|
|
1937
2264
|
createProvider,
|
|
1938
2265
|
createTaskEngine,
|
|
1939
2266
|
defaultProjectConfigYaml,
|
|
1940
2267
|
expandEnvRefs,
|
|
2268
|
+
extractReportFromText,
|
|
1941
2269
|
findConfigFile,
|
|
1942
2270
|
isOmniNodeError,
|
|
2271
|
+
keywords,
|
|
1943
2272
|
loadConfig,
|
|
1944
2273
|
logger,
|
|
1945
2274
|
pipelineConfigSchema,
|
|
@@ -1949,6 +2278,7 @@ export {
|
|
|
1949
2278
|
registryKey,
|
|
1950
2279
|
requestJson,
|
|
1951
2280
|
resolveApiKey,
|
|
1952
|
-
roleConfigSchema
|
|
2281
|
+
roleConfigSchema,
|
|
2282
|
+
similar
|
|
1953
2283
|
};
|
|
1954
2284
|
//# sourceMappingURL=index.js.map
|