@miriad-systems/nuum 0.1.9 → 0.1.10
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/dist/index.js
CHANGED
|
@@ -17400,7 +17400,8 @@ __export(exports_schema, {
|
|
|
17400
17400
|
temporalMessages: () => temporalMessages,
|
|
17401
17401
|
sessionConfig: () => sessionConfig,
|
|
17402
17402
|
presentState: () => presentState,
|
|
17403
|
-
ltmEntries: () => ltmEntries
|
|
17403
|
+
ltmEntries: () => ltmEntries,
|
|
17404
|
+
backgroundReports: () => backgroundReports
|
|
17404
17405
|
});
|
|
17405
17406
|
|
|
17406
17407
|
// node_modules/drizzle-orm/entity.js
|
|
@@ -18694,6 +18695,15 @@ var workers = sqliteTable("workers", {
|
|
|
18694
18695
|
completedAt: text("completed_at"),
|
|
18695
18696
|
error: text("error")
|
|
18696
18697
|
});
|
|
18698
|
+
var backgroundReports = sqliteTable("background_reports", {
|
|
18699
|
+
id: text("id").primaryKey(),
|
|
18700
|
+
createdAt: text("created_at").notNull(),
|
|
18701
|
+
subsystem: text("subsystem").notNull(),
|
|
18702
|
+
report: text("report").notNull(),
|
|
18703
|
+
surfacedAt: text("surfaced_at")
|
|
18704
|
+
}, (table) => [
|
|
18705
|
+
index("idx_background_reports_unsurfaced").on(table.surfacedAt)
|
|
18706
|
+
]);
|
|
18697
18707
|
|
|
18698
18708
|
// src/storage/db.ts
|
|
18699
18709
|
var isBun = typeof globalThis.Bun !== "undefined";
|
|
@@ -23457,7 +23467,9 @@ var Identifier;
|
|
|
23457
23467
|
task: "tsk",
|
|
23458
23468
|
entry: "ent",
|
|
23459
23469
|
worker: "wrk",
|
|
23460
|
-
|
|
23470
|
+
report: "rpt",
|
|
23471
|
+
session: "ses",
|
|
23472
|
+
toolcall: "tcl"
|
|
23461
23473
|
};
|
|
23462
23474
|
function schema(prefix) {
|
|
23463
23475
|
return exports_external.string().startsWith(prefixes[prefix]);
|
|
@@ -23561,6 +23573,45 @@ function createSessionStorage(db) {
|
|
|
23561
23573
|
};
|
|
23562
23574
|
}
|
|
23563
23575
|
|
|
23576
|
+
// src/storage/background.ts
|
|
23577
|
+
function createBackgroundStorage(db) {
|
|
23578
|
+
return {
|
|
23579
|
+
async fileReport(input) {
|
|
23580
|
+
const id = Identifier.ascending("report");
|
|
23581
|
+
const now = new Date().toISOString();
|
|
23582
|
+
await db.insert(backgroundReports).values({
|
|
23583
|
+
id,
|
|
23584
|
+
createdAt: now,
|
|
23585
|
+
subsystem: input.subsystem,
|
|
23586
|
+
report: JSON.stringify(input.report)
|
|
23587
|
+
});
|
|
23588
|
+
return id;
|
|
23589
|
+
},
|
|
23590
|
+
async getUnsurfaced() {
|
|
23591
|
+
const rows = await db.select().from(backgroundReports).where(isNull(backgroundReports.surfacedAt)).orderBy(backgroundReports.createdAt);
|
|
23592
|
+
return rows.map((row) => ({
|
|
23593
|
+
id: row.id,
|
|
23594
|
+
createdAt: row.createdAt,
|
|
23595
|
+
subsystem: row.subsystem,
|
|
23596
|
+
report: JSON.parse(row.report),
|
|
23597
|
+
surfacedAt: row.surfacedAt
|
|
23598
|
+
}));
|
|
23599
|
+
},
|
|
23600
|
+
async markSurfaced(id) {
|
|
23601
|
+
const now = new Date().toISOString();
|
|
23602
|
+
await db.update(backgroundReports).set({ surfacedAt: now }).where(eq(backgroundReports.id, id));
|
|
23603
|
+
},
|
|
23604
|
+
async markManySurfaced(ids) {
|
|
23605
|
+
if (ids.length === 0)
|
|
23606
|
+
return;
|
|
23607
|
+
const now = new Date().toISOString();
|
|
23608
|
+
for (const id of ids) {
|
|
23609
|
+
await db.update(backgroundReports).set({ surfacedAt: now }).where(eq(backgroundReports.id, id));
|
|
23610
|
+
}
|
|
23611
|
+
}
|
|
23612
|
+
};
|
|
23613
|
+
}
|
|
23614
|
+
|
|
23564
23615
|
// src/storage/index.ts
|
|
23565
23616
|
function createStorage(dbPath, options) {
|
|
23566
23617
|
const { mkdirSync } = __require("fs");
|
|
@@ -23579,6 +23630,7 @@ function createStorageFromDb(db) {
|
|
|
23579
23630
|
ltm: createLTMStorage(db),
|
|
23580
23631
|
workers: createWorkerStorage(db),
|
|
23581
23632
|
session: createSessionStorage(db),
|
|
23633
|
+
background: createBackgroundStorage(db),
|
|
23582
23634
|
_db: db
|
|
23583
23635
|
};
|
|
23584
23636
|
}
|
|
@@ -34945,16 +34997,17 @@ function buildCreateDistillationTool(ctx, results) {
|
|
|
34945
34997
|
}
|
|
34946
34998
|
function buildFinishDistillationTool(results) {
|
|
34947
34999
|
return tool({
|
|
34948
|
-
description: "Signal that working memory optimization is complete.
|
|
35000
|
+
description: "Signal that working memory optimization is complete. Write a contextual summary for your future self explaining what you compressed and what you retained.",
|
|
34949
35001
|
parameters: exports_external.object({
|
|
34950
|
-
|
|
35002
|
+
summary: exports_external.string().describe("A note to your future self: what did you compress and what key information did you retain? Example: 'Combined the three debugging sessions into one distillation - retained the key insight about the race condition and the fix in src/agent/loop.ts.'")
|
|
34951
35003
|
}),
|
|
34952
|
-
execute: async ({
|
|
34953
|
-
log6.info("distillation finished", {
|
|
35004
|
+
execute: async ({ summary }, { toolCallId }) => {
|
|
35005
|
+
log6.info("distillation finished", { summary });
|
|
34954
35006
|
const result = {
|
|
34955
|
-
output: `Distillation complete
|
|
35007
|
+
output: `Distillation complete`,
|
|
34956
35008
|
done: true,
|
|
34957
|
-
distillationCreated: false
|
|
35009
|
+
distillationCreated: false,
|
|
35010
|
+
summary
|
|
34958
35011
|
};
|
|
34959
35012
|
results.set(toolCallId, result);
|
|
34960
35013
|
return result.output;
|
|
@@ -35044,6 +35097,19 @@ For each distillation, call **create_distillation** with:
|
|
|
35044
35097
|
|
|
35045
35098
|
Call **finish_distillation** when you've optimized enough or no more distillation is beneficial.
|
|
35046
35099
|
|
|
35100
|
+
### Writing Your Summary
|
|
35101
|
+
|
|
35102
|
+
When you call \`finish_distillation\`, write a brief note to your future self explaining what you compressed and what you retained. This is a dialog between your subconscious (the compactor) and your conscious self (the main agent).
|
|
35103
|
+
|
|
35104
|
+
**Good summaries** explain the WHAT and WHY:
|
|
35105
|
+
- "Combined the three debugging sessions into one distillation - retained the key insight about the race condition and the fix in src/agent/loop.ts."
|
|
35106
|
+
- "Distilled the API refactoring work, keeping all the endpoint paths and the decision to use REST over GraphQL."
|
|
35107
|
+
- "Compressed the deployment troubleshooting - kept the final working config and the gotcha about environment variables."
|
|
35108
|
+
|
|
35109
|
+
**Avoid mechanical summaries**:
|
|
35110
|
+
- \u2717 "Reached target"
|
|
35111
|
+
- \u2717 "Created 3 distillations"
|
|
35112
|
+
|
|
35047
35113
|
**Remember:** You're optimizing your own working memory. Keep what helps you act with precision.
|
|
35048
35114
|
`;
|
|
35049
35115
|
}
|
|
@@ -35128,6 +35194,9 @@ async function runCompaction(storage, config) {
|
|
|
35128
35194
|
if (toolResult?.distillationCreated) {
|
|
35129
35195
|
result.distillationsCreated++;
|
|
35130
35196
|
}
|
|
35197
|
+
if (toolResult?.summary) {
|
|
35198
|
+
result.summary = toolResult.summary;
|
|
35199
|
+
}
|
|
35131
35200
|
}
|
|
35132
35201
|
});
|
|
35133
35202
|
} catch (error) {
|
|
@@ -44340,7 +44409,7 @@ var LTMTools = {
|
|
|
44340
44409
|
};
|
|
44341
44410
|
// src/ltm/consolidation.ts
|
|
44342
44411
|
var log9 = Log.create({ service: "consolidation-agent" });
|
|
44343
|
-
var MAX_CONSOLIDATION_TURNS =
|
|
44412
|
+
var MAX_CONSOLIDATION_TURNS = 20;
|
|
44344
44413
|
var AGENT_TYPE = "ltm-consolidate";
|
|
44345
44414
|
function isConversationNoteworthy(messages) {
|
|
44346
44415
|
if (messages.length < 5) {
|
|
@@ -44414,7 +44483,13 @@ function buildConsolidationTools(storage) {
|
|
|
44414
44483
|
if (entryCreated) {
|
|
44415
44484
|
activity.ltmCurator.ltmOperation("create", args.slug, args.title);
|
|
44416
44485
|
}
|
|
44417
|
-
const result = {
|
|
44486
|
+
const result = {
|
|
44487
|
+
output: toolResult.output,
|
|
44488
|
+
done: false,
|
|
44489
|
+
entryCreated,
|
|
44490
|
+
slug: args.slug,
|
|
44491
|
+
title: args.title
|
|
44492
|
+
};
|
|
44418
44493
|
results.set(toolCallId, result);
|
|
44419
44494
|
return result.output;
|
|
44420
44495
|
}
|
|
@@ -44428,7 +44503,12 @@ function buildConsolidationTools(storage) {
|
|
|
44428
44503
|
if (entryUpdated) {
|
|
44429
44504
|
activity.ltmCurator.ltmOperation("update", args.slug);
|
|
44430
44505
|
}
|
|
44431
|
-
const result = {
|
|
44506
|
+
const result = {
|
|
44507
|
+
output: toolResult.output,
|
|
44508
|
+
done: false,
|
|
44509
|
+
entryUpdated,
|
|
44510
|
+
slug: args.slug
|
|
44511
|
+
};
|
|
44432
44512
|
results.set(toolCallId, result);
|
|
44433
44513
|
return result.output;
|
|
44434
44514
|
}
|
|
@@ -44442,7 +44522,12 @@ function buildConsolidationTools(storage) {
|
|
|
44442
44522
|
if (entryUpdated) {
|
|
44443
44523
|
activity.ltmCurator.ltmOperation("update", args.slug, "surgical edit");
|
|
44444
44524
|
}
|
|
44445
|
-
const result = {
|
|
44525
|
+
const result = {
|
|
44526
|
+
output: toolResult.output,
|
|
44527
|
+
done: false,
|
|
44528
|
+
entryUpdated,
|
|
44529
|
+
slug: args.slug
|
|
44530
|
+
};
|
|
44446
44531
|
results.set(toolCallId, result);
|
|
44447
44532
|
return result.output;
|
|
44448
44533
|
}
|
|
@@ -44456,7 +44541,12 @@ function buildConsolidationTools(storage) {
|
|
|
44456
44541
|
if (entryUpdated) {
|
|
44457
44542
|
activity.ltmCurator.ltmOperation("reparent", args.slug, `\u2192 ${args.newParentSlug ?? "root"}`);
|
|
44458
44543
|
}
|
|
44459
|
-
const result = {
|
|
44544
|
+
const result = {
|
|
44545
|
+
output: toolResult.output,
|
|
44546
|
+
done: false,
|
|
44547
|
+
entryUpdated,
|
|
44548
|
+
slug: args.slug
|
|
44549
|
+
};
|
|
44460
44550
|
results.set(toolCallId, result);
|
|
44461
44551
|
return result.output;
|
|
44462
44552
|
}
|
|
@@ -44470,7 +44560,12 @@ function buildConsolidationTools(storage) {
|
|
|
44470
44560
|
if (entryUpdated) {
|
|
44471
44561
|
activity.ltmCurator.ltmOperation("rename", args.slug, `\u2192 ${args.newSlug}`);
|
|
44472
44562
|
}
|
|
44473
|
-
const result = {
|
|
44563
|
+
const result = {
|
|
44564
|
+
output: toolResult.output,
|
|
44565
|
+
done: false,
|
|
44566
|
+
entryUpdated,
|
|
44567
|
+
slug: args.slug
|
|
44568
|
+
};
|
|
44474
44569
|
results.set(toolCallId, result);
|
|
44475
44570
|
return result.output;
|
|
44476
44571
|
}
|
|
@@ -44484,7 +44579,12 @@ function buildConsolidationTools(storage) {
|
|
|
44484
44579
|
if (entryArchived) {
|
|
44485
44580
|
activity.ltmCurator.ltmOperation("archive", args.slug);
|
|
44486
44581
|
}
|
|
44487
|
-
const result = {
|
|
44582
|
+
const result = {
|
|
44583
|
+
output: toolResult.output,
|
|
44584
|
+
done: false,
|
|
44585
|
+
entryArchived,
|
|
44586
|
+
slug: args.slug
|
|
44587
|
+
};
|
|
44488
44588
|
results.set(toolCallId, result);
|
|
44489
44589
|
return result.output;
|
|
44490
44590
|
}
|
|
@@ -44565,9 +44665,9 @@ function buildConsolidationTools(storage) {
|
|
|
44565
44665
|
}
|
|
44566
44666
|
});
|
|
44567
44667
|
tools.finish_consolidation = tool({
|
|
44568
|
-
description: "Call this when you have finished curating the knowledge base.
|
|
44668
|
+
description: "Call this when you have finished curating the knowledge base. Write a contextual summary for your future self.",
|
|
44569
44669
|
parameters: exports_external.object({
|
|
44570
|
-
summary: exports_external.string().describe("
|
|
44670
|
+
summary: exports_external.string().describe("A note to your future self: what did you capture and why does it matter? Reference entries with [[slug]] syntax. Example: 'Captured the bloom filter insights in [[bloom-filter-overview]]. Archived X system workarounds since it's decommissioned.'")
|
|
44571
44671
|
}),
|
|
44572
44672
|
execute: async ({ summary }, { toolCallId }) => {
|
|
44573
44673
|
const result = { output: "Curation complete", done: true, summary };
|
|
@@ -44742,7 +44842,20 @@ Review these entries periodically. Are they accurate? Complete? Do they reflect
|
|
|
44742
44842
|
1. **First**: Capture any insights from the recent conversation (this is the priority)
|
|
44743
44843
|
2. **Then**: Look at your knowledge base - is it serving you well? Improve it.
|
|
44744
44844
|
3. **Check**: Are /identity and /behavior current? Update them if you've learned something new.
|
|
44745
|
-
4. **Finally**: Call \`finish_consolidation\` with a summary
|
|
44845
|
+
4. **Finally**: Call \`finish_consolidation\` with a contextual summary
|
|
44846
|
+
|
|
44847
|
+
### Writing Your Summary
|
|
44848
|
+
|
|
44849
|
+
When you call \`finish_consolidation\`, write a brief note to your future self explaining what you captured and why it matters. This is a dialog between your subconscious (the curator) and your conscious self (the main agent).
|
|
44850
|
+
|
|
44851
|
+
**Good summaries** explain the WHAT and WHY:
|
|
44852
|
+
- "Captured the insights on probabilistic filtering in [[bloom-filter-overview]]. Also archived the X system workarounds since it's been decommissioned."
|
|
44853
|
+
- "Updated [[user-preferences]] with the new testing philosophy - run tests before committing. Created [[cast-integration]] to document the engine abstraction pattern."
|
|
44854
|
+
- "Reorganized the codebase knowledge - moved protocol docs under [[miriad-code/protocol]] and cross-linked with [[memory-system]]."
|
|
44855
|
+
|
|
44856
|
+
**Avoid mechanical summaries**:
|
|
44857
|
+
- \u2717 "Created 2 entries, updated 1 entry"
|
|
44858
|
+
- \u2717 "Finished curation"
|
|
44746
44859
|
|
|
44747
44860
|
Be proactive! This is YOUR knowledge base. Make it useful.
|
|
44748
44861
|
`;
|
|
@@ -44755,6 +44868,7 @@ async function runConsolidation(storage, messages) {
|
|
|
44755
44868
|
entriesUpdated: 0,
|
|
44756
44869
|
entriesArchived: 0,
|
|
44757
44870
|
summary: "",
|
|
44871
|
+
details: [],
|
|
44758
44872
|
usage: { inputTokens: 0, outputTokens: 0 }
|
|
44759
44873
|
};
|
|
44760
44874
|
if (!isConversationNoteworthy(messages)) {
|
|
@@ -44792,12 +44906,21 @@ ${reviewTurnContent}` }
|
|
|
44792
44906
|
const toolResult = getLastResult(toolCallId);
|
|
44793
44907
|
if (toolResult?.entryCreated) {
|
|
44794
44908
|
result.entriesCreated++;
|
|
44909
|
+
if (toolResult.slug) {
|
|
44910
|
+
result.details.push(`Created [[${toolResult.slug}]]${toolResult.title ? ` - ${toolResult.title}` : ""}`);
|
|
44911
|
+
}
|
|
44795
44912
|
}
|
|
44796
44913
|
if (toolResult?.entryUpdated) {
|
|
44797
44914
|
result.entriesUpdated++;
|
|
44915
|
+
if (toolResult.slug) {
|
|
44916
|
+
result.details.push(`Updated [[${toolResult.slug}]]`);
|
|
44917
|
+
}
|
|
44798
44918
|
}
|
|
44799
44919
|
if (toolResult?.entryArchived) {
|
|
44800
44920
|
result.entriesArchived++;
|
|
44921
|
+
if (toolResult.slug) {
|
|
44922
|
+
result.details.push(`Archived [[${toolResult.slug}]]`);
|
|
44923
|
+
}
|
|
44801
44924
|
}
|
|
44802
44925
|
if (toolResult?.summary) {
|
|
44803
44926
|
result.summary = toolResult.summary;
|
|
@@ -44874,6 +44997,16 @@ async function runLTMConsolidation(storage) {
|
|
|
44874
44997
|
const changes = result.entriesCreated + result.entriesUpdated + result.entriesArchived;
|
|
44875
44998
|
if (changes > 0) {
|
|
44876
44999
|
activity.ltmCurator.complete(`${result.entriesCreated} created, ${result.entriesUpdated} updated, ${result.entriesArchived} archived`);
|
|
45000
|
+
await storage.background.fileReport({
|
|
45001
|
+
subsystem: "ltm_curator",
|
|
45002
|
+
report: {
|
|
45003
|
+
entriesCreated: result.entriesCreated,
|
|
45004
|
+
entriesUpdated: result.entriesUpdated,
|
|
45005
|
+
entriesArchived: result.entriesArchived,
|
|
45006
|
+
details: result.details || [],
|
|
45007
|
+
summary: result.summary
|
|
45008
|
+
}
|
|
45009
|
+
});
|
|
44877
45010
|
} else {
|
|
44878
45011
|
activity.ltmCurator.complete("No changes needed");
|
|
44879
45012
|
}
|
|
@@ -44899,6 +45032,17 @@ async function runDistillation(storage, threshold, target, force) {
|
|
|
44899
45032
|
force
|
|
44900
45033
|
});
|
|
44901
45034
|
activity.distillation.tokens(result.tokensBefore, result.tokensAfter, `${result.distillationsCreated} distillations`);
|
|
45035
|
+
if (result.distillationsCreated > 0) {
|
|
45036
|
+
await storage.background.fileReport({
|
|
45037
|
+
subsystem: "distillation",
|
|
45038
|
+
report: {
|
|
45039
|
+
tokensBefore: result.tokensBefore,
|
|
45040
|
+
tokensAfter: result.tokensAfter,
|
|
45041
|
+
distillationsCreated: result.distillationsCreated,
|
|
45042
|
+
summary: result.summary
|
|
45043
|
+
}
|
|
45044
|
+
});
|
|
45045
|
+
}
|
|
44902
45046
|
return result;
|
|
44903
45047
|
} catch (error2) {
|
|
44904
45048
|
activity.distillation.error(error2 instanceof Error ? error2.message : String(error2));
|
|
@@ -44908,7 +45052,81 @@ async function runDistillation(storage, threshold, target, force) {
|
|
|
44908
45052
|
|
|
44909
45053
|
// src/agent/index.ts
|
|
44910
45054
|
var log10 = Log.create({ service: "agent" });
|
|
44911
|
-
var MAX_TURNS =
|
|
45055
|
+
var MAX_TURNS = 200;
|
|
45056
|
+
async function surfaceBackgroundReports(storage) {
|
|
45057
|
+
const reports = await storage.background.getUnsurfaced();
|
|
45058
|
+
if (reports.length === 0)
|
|
45059
|
+
return;
|
|
45060
|
+
log10.info("surfacing background reports", { count: reports.length });
|
|
45061
|
+
for (const report of reports) {
|
|
45062
|
+
const toolCallId = Identifier.ascending("toolcall");
|
|
45063
|
+
await storage.temporal.appendMessage({
|
|
45064
|
+
id: Identifier.ascending("message"),
|
|
45065
|
+
type: "tool_call",
|
|
45066
|
+
content: JSON.stringify({
|
|
45067
|
+
name: "background_activity",
|
|
45068
|
+
args: { subsystem: report.subsystem },
|
|
45069
|
+
toolCallId
|
|
45070
|
+
}),
|
|
45071
|
+
tokenEstimate: 20,
|
|
45072
|
+
createdAt: report.createdAt
|
|
45073
|
+
});
|
|
45074
|
+
const reportContent = formatBackgroundReport(report.subsystem, report.report);
|
|
45075
|
+
await storage.temporal.appendMessage({
|
|
45076
|
+
id: Identifier.ascending("message"),
|
|
45077
|
+
type: "tool_result",
|
|
45078
|
+
content: JSON.stringify({
|
|
45079
|
+
toolCallId,
|
|
45080
|
+
result: reportContent
|
|
45081
|
+
}),
|
|
45082
|
+
tokenEstimate: estimateTokens2(reportContent),
|
|
45083
|
+
createdAt: report.createdAt
|
|
45084
|
+
});
|
|
45085
|
+
await storage.background.markSurfaced(report.id);
|
|
45086
|
+
}
|
|
45087
|
+
}
|
|
45088
|
+
function formatBackgroundReport(subsystem, report) {
|
|
45089
|
+
switch (subsystem) {
|
|
45090
|
+
case "ltm_curator": {
|
|
45091
|
+
const r = report;
|
|
45092
|
+
if (r.summary) {
|
|
45093
|
+
return `[Knowledge Curator] ${r.summary}`;
|
|
45094
|
+
}
|
|
45095
|
+
const lines = ["[Knowledge Curator] I organized my knowledge:"];
|
|
45096
|
+
if (r.entriesCreated)
|
|
45097
|
+
lines.push(`- Created ${r.entriesCreated} new entries`);
|
|
45098
|
+
if (r.entriesUpdated)
|
|
45099
|
+
lines.push(`- Updated ${r.entriesUpdated} existing entries`);
|
|
45100
|
+
if (r.entriesArchived)
|
|
45101
|
+
lines.push(`- Archived ${r.entriesArchived} outdated entries`);
|
|
45102
|
+
if (r.details && r.details.length > 0) {
|
|
45103
|
+
lines.push("");
|
|
45104
|
+
lines.push(...r.details.map((d) => `- ${d}`));
|
|
45105
|
+
}
|
|
45106
|
+
return lines.join(`
|
|
45107
|
+
`);
|
|
45108
|
+
}
|
|
45109
|
+
case "distillation": {
|
|
45110
|
+
const r = report;
|
|
45111
|
+
if (r.summary) {
|
|
45112
|
+
const tokenInfo = r.tokensBefore && r.tokensAfter ? ` (${r.tokensBefore.toLocaleString()} \u2192 ${r.tokensAfter.toLocaleString()} tokens)` : "";
|
|
45113
|
+
return `[Memory Compaction]${tokenInfo} ${r.summary}`;
|
|
45114
|
+
}
|
|
45115
|
+
const lines = ["[Memory Compaction] I compressed my working memory:"];
|
|
45116
|
+
if (r.tokensBefore && r.tokensAfter) {
|
|
45117
|
+
const saved = r.tokensBefore - r.tokensAfter;
|
|
45118
|
+
lines.push(`- Reduced from ${r.tokensBefore.toLocaleString()} to ${r.tokensAfter.toLocaleString()} tokens (saved ${saved.toLocaleString()})`);
|
|
45119
|
+
}
|
|
45120
|
+
if (r.distillationsCreated) {
|
|
45121
|
+
lines.push(`- Created ${r.distillationsCreated} distillation${r.distillationsCreated > 1 ? "s" : ""}`);
|
|
45122
|
+
}
|
|
45123
|
+
return lines.join(`
|
|
45124
|
+
`);
|
|
45125
|
+
}
|
|
45126
|
+
default:
|
|
45127
|
+
return `[${subsystem}] ${JSON.stringify(report, null, 2)}`;
|
|
45128
|
+
}
|
|
45129
|
+
}
|
|
44912
45130
|
function summarizeToolResult(toolName, result) {
|
|
44913
45131
|
const lines = result.split(`
|
|
44914
45132
|
`).length;
|
|
@@ -45139,6 +45357,7 @@ async function runAgent(prompt, options) {
|
|
|
45139
45357
|
const { storage, onEvent, abortSignal, onBeforeTurn } = options;
|
|
45140
45358
|
const sessionId = Identifier.ascending("session");
|
|
45141
45359
|
await initializeMcp();
|
|
45360
|
+
await surfaceBackgroundReports(storage);
|
|
45142
45361
|
const config2 = Config.get();
|
|
45143
45362
|
const softLimit = config2.tokenBudgets.compactionThreshold;
|
|
45144
45363
|
const hardLimit = config2.tokenBudgets.compactionHardLimit;
|
package/package.json
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
-- Background reports table
|
|
2
|
+
-- Allows background workers (LTM curator, distillation, etc.) to file reports
|
|
3
|
+
-- that get surfaced to the main agent at the start of the next turn.
|
|
4
|
+
|
|
5
|
+
CREATE TABLE IF NOT EXISTS background_reports (
|
|
6
|
+
id TEXT PRIMARY KEY,
|
|
7
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
8
|
+
subsystem TEXT NOT NULL, -- e.g., 'ltm_curator', 'distillation'
|
|
9
|
+
report TEXT NOT NULL, -- JSON report content
|
|
10
|
+
surfaced_at TEXT -- NULL until shown to main agent
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
-- Index for efficient lookup of unsurfaced reports
|
|
14
|
+
CREATE INDEX IF NOT EXISTS idx_background_reports_unsurfaced
|
|
15
|
+
ON background_reports(surfaced_at) WHERE surfaced_at IS NULL;
|