@miriad-systems/nuum 0.1.12 → 0.1.13
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 +571 -185
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -34411,6 +34411,7 @@ var activity = {
|
|
|
34411
34411
|
ltmCurator: new ActivityLog("ltm-curator"),
|
|
34412
34412
|
distillation: new ActivityLog("distillation"),
|
|
34413
34413
|
reflection: new ActivityLog("reflection"),
|
|
34414
|
+
research: new ActivityLog("research"),
|
|
34414
34415
|
server: new ActivityLog("server"),
|
|
34415
34416
|
mcp: new ActivityLog("mcp")
|
|
34416
34417
|
};
|
|
@@ -35315,7 +35316,54 @@ async function buildAgentContext(storage) {
|
|
|
35315
35316
|
};
|
|
35316
35317
|
}
|
|
35317
35318
|
|
|
35318
|
-
// src/
|
|
35319
|
+
// src/sub-agent/index.ts
|
|
35320
|
+
var log8 = Log.create({ service: "sub-agent" });
|
|
35321
|
+
async function runSubAgent(storage, config) {
|
|
35322
|
+
const {
|
|
35323
|
+
name: name17,
|
|
35324
|
+
taskPrompt,
|
|
35325
|
+
tools,
|
|
35326
|
+
finishToolName,
|
|
35327
|
+
extractResult,
|
|
35328
|
+
tier = "workhorse",
|
|
35329
|
+
maxTurns = 20,
|
|
35330
|
+
maxTokens = 4096,
|
|
35331
|
+
temperature = 0,
|
|
35332
|
+
onToolResult
|
|
35333
|
+
} = config;
|
|
35334
|
+
log8.info(`starting sub-agent: ${name17}`, { maxTurns, tier });
|
|
35335
|
+
const ctx = await buildAgentContext(storage);
|
|
35336
|
+
const model = Provider.getModelForTier(tier);
|
|
35337
|
+
const initialMessages = [
|
|
35338
|
+
...ctx.historyTurns,
|
|
35339
|
+
{ role: "user", content: `[SYSTEM TASK]
|
|
35340
|
+
|
|
35341
|
+
${taskPrompt}` }
|
|
35342
|
+
];
|
|
35343
|
+
const loopResult = await runAgentLoop({
|
|
35344
|
+
model,
|
|
35345
|
+
systemPrompt: ctx.systemPrompt,
|
|
35346
|
+
initialMessages,
|
|
35347
|
+
tools,
|
|
35348
|
+
maxTokens,
|
|
35349
|
+
temperature,
|
|
35350
|
+
maxTurns,
|
|
35351
|
+
isDone: stopOnTool(finishToolName),
|
|
35352
|
+
onToolResult
|
|
35353
|
+
});
|
|
35354
|
+
log8.info(`sub-agent complete: ${name17}`, {
|
|
35355
|
+
turnsUsed: loopResult.turnsUsed,
|
|
35356
|
+
stopReason: loopResult.stopReason
|
|
35357
|
+
});
|
|
35358
|
+
return {
|
|
35359
|
+
result: extractResult(),
|
|
35360
|
+
turnsUsed: loopResult.turnsUsed,
|
|
35361
|
+
usage: loopResult.usage,
|
|
35362
|
+
stopReason: loopResult.stopReason
|
|
35363
|
+
};
|
|
35364
|
+
}
|
|
35365
|
+
|
|
35366
|
+
// src/reflection/tools.ts
|
|
35319
35367
|
function buildSearchMessagesTool(ctx) {
|
|
35320
35368
|
const { storage } = ctx;
|
|
35321
35369
|
return tool({
|
|
@@ -35373,19 +35421,6 @@ ${marker17}${m.content}`;
|
|
|
35373
35421
|
}
|
|
35374
35422
|
});
|
|
35375
35423
|
}
|
|
35376
|
-
function buildFinishReflectionTool(setAnswer) {
|
|
35377
|
-
return tool({
|
|
35378
|
-
description: "Complete the reflection and return your answer to the main agent.",
|
|
35379
|
-
parameters: exports_external.object({
|
|
35380
|
-
answer: exports_external.string().describe("Your answer or research findings. Be specific and include relevant details, quotes, or references.")
|
|
35381
|
-
}),
|
|
35382
|
-
execute: async ({ answer }) => {
|
|
35383
|
-
activity.reflection.toolResult("finish_reflection", `${answer.length} chars`);
|
|
35384
|
-
setAnswer(answer);
|
|
35385
|
-
return "Reflection complete.";
|
|
35386
|
-
}
|
|
35387
|
-
});
|
|
35388
|
-
}
|
|
35389
35424
|
function createLTMContext(storage, toolCallId) {
|
|
35390
35425
|
const baseCtx = Tool.createContext({
|
|
35391
35426
|
sessionID: "reflection",
|
|
@@ -35410,7 +35445,7 @@ function wrapLTMTool(ltmTool, toolName, storage, summarizeResult) {
|
|
|
35410
35445
|
}
|
|
35411
35446
|
});
|
|
35412
35447
|
}
|
|
35413
|
-
function
|
|
35448
|
+
function buildReflectionTools(ctx) {
|
|
35414
35449
|
let answer = null;
|
|
35415
35450
|
const tools = {
|
|
35416
35451
|
search_messages: buildSearchMessagesTool(ctx),
|
|
@@ -35419,8 +35454,16 @@ function buildReflectionSearchTools(ctx) {
|
|
|
35419
35454
|
ltm_read: wrapLTMTool(LTMReadTool, "ltm_read", ctx.storage, (output) => output.slice(0, 50)),
|
|
35420
35455
|
ltm_glob: wrapLTMTool(LTMGlobTool, "ltm_glob", ctx.storage, (output) => `${output.split(`
|
|
35421
35456
|
`).length} entries`),
|
|
35422
|
-
finish_reflection:
|
|
35423
|
-
answer
|
|
35457
|
+
finish_reflection: tool({
|
|
35458
|
+
description: "Complete the reflection and return your answer to the main agent.",
|
|
35459
|
+
parameters: exports_external.object({
|
|
35460
|
+
answer: exports_external.string().describe("Your answer or research findings. Be specific and include relevant details, quotes, or references.")
|
|
35461
|
+
}),
|
|
35462
|
+
execute: async ({ answer: ans }) => {
|
|
35463
|
+
activity.reflection.toolResult("finish_reflection", `${ans.length} chars`);
|
|
35464
|
+
answer = ans;
|
|
35465
|
+
return "Reflection complete.";
|
|
35466
|
+
}
|
|
35424
35467
|
})
|
|
35425
35468
|
};
|
|
35426
35469
|
return {
|
|
@@ -35430,8 +35473,6 @@ function buildReflectionSearchTools(ctx) {
|
|
|
35430
35473
|
}
|
|
35431
35474
|
|
|
35432
35475
|
// src/reflection/index.ts
|
|
35433
|
-
var log8 = Log.create({ service: "reflection-agent" });
|
|
35434
|
-
var MAX_REFLECTION_TURNS = 20;
|
|
35435
35476
|
function buildReflectionPrompt(question) {
|
|
35436
35477
|
return `## Reflection Mode
|
|
35437
35478
|
|
|
@@ -35459,39 +35500,24 @@ I'll search my memory now. Once I have enough information, I MUST call finish_re
|
|
|
35459
35500
|
}
|
|
35460
35501
|
async function runReflection(storage, question) {
|
|
35461
35502
|
activity.reflection.start("Memory research", { question: question.slice(0, 50) });
|
|
35462
|
-
const
|
|
35463
|
-
const
|
|
35464
|
-
|
|
35465
|
-
|
|
35466
|
-
const initialMessages = [
|
|
35467
|
-
...ctx.historyTurns,
|
|
35468
|
-
{ role: "user", content: `[SYSTEM TASK]
|
|
35469
|
-
|
|
35470
|
-
${taskPrompt}` }
|
|
35471
|
-
];
|
|
35472
|
-
const loopResult = await runAgentLoop({
|
|
35473
|
-
model,
|
|
35474
|
-
systemPrompt: ctx.systemPrompt,
|
|
35475
|
-
initialMessages,
|
|
35503
|
+
const { tools, getAnswer } = buildReflectionTools({ storage });
|
|
35504
|
+
const result = await runSubAgent(storage, {
|
|
35505
|
+
name: "reflection",
|
|
35506
|
+
taskPrompt: buildReflectionPrompt(question),
|
|
35476
35507
|
tools,
|
|
35477
|
-
|
|
35478
|
-
|
|
35479
|
-
|
|
35480
|
-
|
|
35481
|
-
|
|
35482
|
-
|
|
35483
|
-
|
|
35484
|
-
|
|
35485
|
-
|
|
35486
|
-
|
|
35487
|
-
|
|
35488
|
-
|
|
35489
|
-
answer: answer ?? loopResult.finalText ?? "Unable to find relevant information.",
|
|
35490
|
-
turnsUsed: loopResult.turnsUsed,
|
|
35491
|
-
usage: loopResult.usage
|
|
35508
|
+
finishToolName: "finish_reflection",
|
|
35509
|
+
extractResult: getAnswer,
|
|
35510
|
+
tier: "workhorse",
|
|
35511
|
+
maxTurns: 20,
|
|
35512
|
+
maxTokens: 4096
|
|
35513
|
+
});
|
|
35514
|
+
const answer = result.result ?? "Unable to find relevant information.";
|
|
35515
|
+
activity.reflection.complete(`${result.turnsUsed} turns, ${answer.length} chars`);
|
|
35516
|
+
return {
|
|
35517
|
+
answer,
|
|
35518
|
+
turnsUsed: result.turnsUsed,
|
|
35519
|
+
usage: result.usage
|
|
35492
35520
|
};
|
|
35493
|
-
activity.reflection.complete(`${result.turnsUsed} turns, ${result.answer.length} chars`);
|
|
35494
|
-
return result;
|
|
35495
35521
|
}
|
|
35496
35522
|
|
|
35497
35523
|
// src/tool/reflect.ts
|
|
@@ -35556,6 +35582,427 @@ var ReflectTool = Tool.define("reflect", {
|
|
|
35556
35582
|
}
|
|
35557
35583
|
}
|
|
35558
35584
|
});
|
|
35585
|
+
// src/research/tools.ts
|
|
35586
|
+
var AGENT_TYPE = "research";
|
|
35587
|
+
function buildResearchTools(storage) {
|
|
35588
|
+
const results = new Map;
|
|
35589
|
+
const createLTMContext2 = (toolCallId) => {
|
|
35590
|
+
const ctx = Tool.createContext({
|
|
35591
|
+
sessionID: "research",
|
|
35592
|
+
messageID: "research",
|
|
35593
|
+
callID: toolCallId
|
|
35594
|
+
});
|
|
35595
|
+
ctx.extra = {
|
|
35596
|
+
ltm: storage.ltm,
|
|
35597
|
+
agentType: AGENT_TYPE
|
|
35598
|
+
};
|
|
35599
|
+
return ctx;
|
|
35600
|
+
};
|
|
35601
|
+
const createBaseContext = (toolCallId) => {
|
|
35602
|
+
return Tool.createContext({
|
|
35603
|
+
sessionID: "research",
|
|
35604
|
+
messageID: "research",
|
|
35605
|
+
callID: toolCallId
|
|
35606
|
+
});
|
|
35607
|
+
};
|
|
35608
|
+
const tools = {};
|
|
35609
|
+
tools.ltm_glob = tool({
|
|
35610
|
+
description: LTMGlobTool.definition.description,
|
|
35611
|
+
parameters: LTMGlobTool.definition.parameters,
|
|
35612
|
+
execute: async (args, { toolCallId }) => {
|
|
35613
|
+
const toolResult = await LTMGlobTool.definition.execute(args, createLTMContext2(toolCallId));
|
|
35614
|
+
results.set(toolCallId, { output: toolResult.output, done: false });
|
|
35615
|
+
return toolResult.output;
|
|
35616
|
+
}
|
|
35617
|
+
});
|
|
35618
|
+
tools.ltm_search = tool({
|
|
35619
|
+
description: LTMSearchTool.definition.description,
|
|
35620
|
+
parameters: LTMSearchTool.definition.parameters,
|
|
35621
|
+
execute: async (args, { toolCallId }) => {
|
|
35622
|
+
const toolResult = await LTMSearchTool.definition.execute(args, createLTMContext2(toolCallId));
|
|
35623
|
+
results.set(toolCallId, { output: toolResult.output, done: false });
|
|
35624
|
+
return toolResult.output;
|
|
35625
|
+
}
|
|
35626
|
+
});
|
|
35627
|
+
tools.ltm_read = tool({
|
|
35628
|
+
description: LTMReadTool.definition.description,
|
|
35629
|
+
parameters: LTMReadTool.definition.parameters,
|
|
35630
|
+
execute: async (args, { toolCallId }) => {
|
|
35631
|
+
const toolResult = await LTMReadTool.definition.execute(args, createLTMContext2(toolCallId));
|
|
35632
|
+
results.set(toolCallId, { output: toolResult.output, done: false });
|
|
35633
|
+
return toolResult.output;
|
|
35634
|
+
}
|
|
35635
|
+
});
|
|
35636
|
+
tools.ltm_create = tool({
|
|
35637
|
+
description: LTMCreateTool.definition.description,
|
|
35638
|
+
parameters: LTMCreateTool.definition.parameters,
|
|
35639
|
+
execute: async (args, { toolCallId }) => {
|
|
35640
|
+
const toolResult = await LTMCreateTool.definition.execute(args, createLTMContext2(toolCallId));
|
|
35641
|
+
const entryCreated = toolResult.output.startsWith("Created entry:");
|
|
35642
|
+
results.set(toolCallId, {
|
|
35643
|
+
output: toolResult.output,
|
|
35644
|
+
done: false,
|
|
35645
|
+
entryCreated,
|
|
35646
|
+
slug: args.slug,
|
|
35647
|
+
title: args.title
|
|
35648
|
+
});
|
|
35649
|
+
return toolResult.output;
|
|
35650
|
+
}
|
|
35651
|
+
});
|
|
35652
|
+
tools.ltm_update = tool({
|
|
35653
|
+
description: LTMUpdateTool.definition.description,
|
|
35654
|
+
parameters: LTMUpdateTool.definition.parameters,
|
|
35655
|
+
execute: async (args, { toolCallId }) => {
|
|
35656
|
+
const toolResult = await LTMUpdateTool.definition.execute(args, createLTMContext2(toolCallId));
|
|
35657
|
+
const entryUpdated = toolResult.output.startsWith("Updated entry:");
|
|
35658
|
+
results.set(toolCallId, {
|
|
35659
|
+
output: toolResult.output,
|
|
35660
|
+
done: false,
|
|
35661
|
+
entryUpdated,
|
|
35662
|
+
slug: args.slug
|
|
35663
|
+
});
|
|
35664
|
+
return toolResult.output;
|
|
35665
|
+
}
|
|
35666
|
+
});
|
|
35667
|
+
tools.ltm_edit = tool({
|
|
35668
|
+
description: LTMEditTool.definition.description,
|
|
35669
|
+
parameters: LTMEditTool.definition.parameters,
|
|
35670
|
+
execute: async (args, { toolCallId }) => {
|
|
35671
|
+
const toolResult = await LTMEditTool.definition.execute(args, createLTMContext2(toolCallId));
|
|
35672
|
+
const entryUpdated = toolResult.output.startsWith("Edited entry:");
|
|
35673
|
+
results.set(toolCallId, {
|
|
35674
|
+
output: toolResult.output,
|
|
35675
|
+
done: false,
|
|
35676
|
+
entryUpdated,
|
|
35677
|
+
slug: args.slug
|
|
35678
|
+
});
|
|
35679
|
+
return toolResult.output;
|
|
35680
|
+
}
|
|
35681
|
+
});
|
|
35682
|
+
tools.ltm_reparent = tool({
|
|
35683
|
+
description: LTMReparentTool.definition.description,
|
|
35684
|
+
parameters: LTMReparentTool.definition.parameters,
|
|
35685
|
+
execute: async (args, { toolCallId }) => {
|
|
35686
|
+
const toolResult = await LTMReparentTool.definition.execute(args, createLTMContext2(toolCallId));
|
|
35687
|
+
const entryUpdated = toolResult.output.startsWith("Moved entry:");
|
|
35688
|
+
results.set(toolCallId, {
|
|
35689
|
+
output: toolResult.output,
|
|
35690
|
+
done: false,
|
|
35691
|
+
entryUpdated,
|
|
35692
|
+
slug: args.slug
|
|
35693
|
+
});
|
|
35694
|
+
return toolResult.output;
|
|
35695
|
+
}
|
|
35696
|
+
});
|
|
35697
|
+
tools.ltm_archive = tool({
|
|
35698
|
+
description: LTMArchiveTool.definition.description,
|
|
35699
|
+
parameters: LTMArchiveTool.definition.parameters,
|
|
35700
|
+
execute: async (args, { toolCallId }) => {
|
|
35701
|
+
const toolResult = await LTMArchiveTool.definition.execute(args, createLTMContext2(toolCallId));
|
|
35702
|
+
const entryArchived = toolResult.output.startsWith("Archived entry:");
|
|
35703
|
+
results.set(toolCallId, {
|
|
35704
|
+
output: toolResult.output,
|
|
35705
|
+
done: false,
|
|
35706
|
+
entryArchived,
|
|
35707
|
+
slug: args.slug
|
|
35708
|
+
});
|
|
35709
|
+
return toolResult.output;
|
|
35710
|
+
}
|
|
35711
|
+
});
|
|
35712
|
+
tools.search_messages = tool({
|
|
35713
|
+
description: "Search conversation history using full-text search. Returns message snippets with matches highlighted.",
|
|
35714
|
+
parameters: exports_external.object({
|
|
35715
|
+
query: exports_external.string().describe("Search query - keywords to find in messages"),
|
|
35716
|
+
limit: exports_external.number().optional().describe("Maximum results to return (default: 20)")
|
|
35717
|
+
}),
|
|
35718
|
+
execute: async ({ query, limit }, { toolCallId }) => {
|
|
35719
|
+
const searchResults = await storage.temporal.searchFTS(query, limit ?? 20);
|
|
35720
|
+
if (searchResults.length === 0) {
|
|
35721
|
+
const output2 = `No messages found matching "${query}"`;
|
|
35722
|
+
results.set(toolCallId, { output: output2, done: false });
|
|
35723
|
+
return output2;
|
|
35724
|
+
}
|
|
35725
|
+
const formatted = searchResults.map((r) => `[${r.id}] (${r.type}) ${r.snippet}`).join(`
|
|
35726
|
+
|
|
35727
|
+
`);
|
|
35728
|
+
const output = `Found ${searchResults.length} messages:
|
|
35729
|
+
|
|
35730
|
+
${formatted}`;
|
|
35731
|
+
results.set(toolCallId, { output, done: false });
|
|
35732
|
+
return output;
|
|
35733
|
+
}
|
|
35734
|
+
});
|
|
35735
|
+
tools.get_message = tool({
|
|
35736
|
+
description: "Get a specific message by ID, optionally with surrounding context messages.",
|
|
35737
|
+
parameters: exports_external.object({
|
|
35738
|
+
id: exports_external.string().describe("Message ID (e.g., msg_01ABC...)"),
|
|
35739
|
+
contextBefore: exports_external.number().optional().describe("Number of messages to include before (default: 0)"),
|
|
35740
|
+
contextAfter: exports_external.number().optional().describe("Number of messages to include after (default: 0)")
|
|
35741
|
+
}),
|
|
35742
|
+
execute: async ({ id, contextBefore, contextAfter }, { toolCallId }) => {
|
|
35743
|
+
const messages = await storage.temporal.getMessageWithContext({
|
|
35744
|
+
id,
|
|
35745
|
+
contextBefore: contextBefore ?? 0,
|
|
35746
|
+
contextAfter: contextAfter ?? 0
|
|
35747
|
+
});
|
|
35748
|
+
if (messages.length === 0) {
|
|
35749
|
+
const output = `Message not found: ${id}`;
|
|
35750
|
+
results.set(toolCallId, { output, done: false });
|
|
35751
|
+
return output;
|
|
35752
|
+
}
|
|
35753
|
+
const formatted = messages.map((m) => {
|
|
35754
|
+
const marker17 = m.id === id ? ">>> " : " ";
|
|
35755
|
+
return `${marker17}[${m.id}] (${m.type})
|
|
35756
|
+
${marker17}${m.content}`;
|
|
35757
|
+
}).join(`
|
|
35758
|
+
|
|
35759
|
+
`);
|
|
35760
|
+
results.set(toolCallId, { output: formatted, done: false });
|
|
35761
|
+
return formatted;
|
|
35762
|
+
}
|
|
35763
|
+
});
|
|
35764
|
+
tools.web_search = tool({
|
|
35765
|
+
description: WebSearchTool.definition.description,
|
|
35766
|
+
parameters: WebSearchTool.definition.parameters,
|
|
35767
|
+
execute: async (args, { toolCallId }) => {
|
|
35768
|
+
const toolResult = await WebSearchTool.definition.execute(args, createBaseContext(toolCallId));
|
|
35769
|
+
results.set(toolCallId, { output: toolResult.output, done: false });
|
|
35770
|
+
return toolResult.output;
|
|
35771
|
+
}
|
|
35772
|
+
});
|
|
35773
|
+
tools.web_fetch = tool({
|
|
35774
|
+
description: WebFetchTool.definition.description,
|
|
35775
|
+
parameters: WebFetchTool.definition.parameters,
|
|
35776
|
+
execute: async (args, { toolCallId }) => {
|
|
35777
|
+
const toolResult = await WebFetchTool.definition.execute(args, createBaseContext(toolCallId));
|
|
35778
|
+
results.set(toolCallId, { output: toolResult.output, done: false });
|
|
35779
|
+
return toolResult.output;
|
|
35780
|
+
}
|
|
35781
|
+
});
|
|
35782
|
+
tools.glob = tool({
|
|
35783
|
+
description: GlobTool.definition.description,
|
|
35784
|
+
parameters: GlobTool.definition.parameters,
|
|
35785
|
+
execute: async (args, { toolCallId }) => {
|
|
35786
|
+
const toolResult = await GlobTool.definition.execute(args, createBaseContext(toolCallId));
|
|
35787
|
+
results.set(toolCallId, { output: toolResult.output, done: false });
|
|
35788
|
+
return toolResult.output;
|
|
35789
|
+
}
|
|
35790
|
+
});
|
|
35791
|
+
tools.read = tool({
|
|
35792
|
+
description: ReadTool.definition.description,
|
|
35793
|
+
parameters: ReadTool.definition.parameters,
|
|
35794
|
+
execute: async (args, { toolCallId }) => {
|
|
35795
|
+
const toolResult = await ReadTool.definition.execute(args, createBaseContext(toolCallId));
|
|
35796
|
+
results.set(toolCallId, { output: toolResult.output, done: false });
|
|
35797
|
+
return toolResult.output;
|
|
35798
|
+
}
|
|
35799
|
+
});
|
|
35800
|
+
tools.grep = tool({
|
|
35801
|
+
description: GrepTool.definition.description,
|
|
35802
|
+
parameters: GrepTool.definition.parameters,
|
|
35803
|
+
execute: async (args, { toolCallId }) => {
|
|
35804
|
+
const toolResult = await GrepTool.definition.execute(args, createBaseContext(toolCallId));
|
|
35805
|
+
results.set(toolCallId, { output: toolResult.output, done: false });
|
|
35806
|
+
return toolResult.output;
|
|
35807
|
+
}
|
|
35808
|
+
});
|
|
35809
|
+
tools.finish_research = tool({
|
|
35810
|
+
description: "Complete the research and return your findings to the main agent.",
|
|
35811
|
+
parameters: exports_external.object({
|
|
35812
|
+
report: exports_external.string().describe("Your research report. Include: 1) Summary of what you learned, 2) LTM entries created/updated with [[slug]] references, 3) Key sources consulted.")
|
|
35813
|
+
}),
|
|
35814
|
+
execute: async ({ report }, { toolCallId }) => {
|
|
35815
|
+
results.set(toolCallId, { output: "Research complete.", done: true, report });
|
|
35816
|
+
return "Research complete.";
|
|
35817
|
+
}
|
|
35818
|
+
});
|
|
35819
|
+
return {
|
|
35820
|
+
tools,
|
|
35821
|
+
getLastResult: (toolCallId) => results.get(toolCallId)
|
|
35822
|
+
};
|
|
35823
|
+
}
|
|
35824
|
+
|
|
35825
|
+
// src/research/index.ts
|
|
35826
|
+
var MAX_RESEARCH_TURNS = 50;
|
|
35827
|
+
function buildResearchPrompt(topic) {
|
|
35828
|
+
return `## Research Mode
|
|
35829
|
+
|
|
35830
|
+
I am now in **research mode**. My task is to investigate a topic and build knowledge in my LTM.
|
|
35831
|
+
|
|
35832
|
+
**Topic to research:**
|
|
35833
|
+
${topic}
|
|
35834
|
+
|
|
35835
|
+
---
|
|
35836
|
+
|
|
35837
|
+
### My Approach
|
|
35838
|
+
|
|
35839
|
+
1. **Check existing knowledge** - What do I already know? (ltm_search, ltm_glob, ltm_read)
|
|
35840
|
+
2. **Search conversation history** - Have we discussed this before? (search_messages, get_message)
|
|
35841
|
+
3. **Research external sources** - What can I learn from the web? (web_search, web_fetch)
|
|
35842
|
+
4. **Read relevant code** - If it's about our codebase, look at the source (glob, read, grep)
|
|
35843
|
+
5. **Synthesize into LTM** - Create or update entries with what I learned (ltm_create, ltm_update)
|
|
35844
|
+
6. **Return a report** - Summarize findings and what was added (finish_research)
|
|
35845
|
+
|
|
35846
|
+
### Guidelines
|
|
35847
|
+
|
|
35848
|
+
- **Don't duplicate** - Search before creating. Update existing entries if relevant.
|
|
35849
|
+
- **Cross-link** - Use [[slug]] syntax to connect related entries.
|
|
35850
|
+
- **Cite sources** - Note where information came from (URLs, file paths, conversation IDs).
|
|
35851
|
+
- **Be thorough** - This is directed research, not a quick lookup. Take time to understand deeply.
|
|
35852
|
+
- **Focus on actionable knowledge** - What will help me work more effectively?
|
|
35853
|
+
|
|
35854
|
+
### Tools Available
|
|
35855
|
+
|
|
35856
|
+
**LTM (full access):**
|
|
35857
|
+
- \`ltm_glob(pattern)\` - Browse tree structure
|
|
35858
|
+
- \`ltm_search(query)\` - Find entries by keyword
|
|
35859
|
+
- \`ltm_read(slug)\` - Read full entry
|
|
35860
|
+
- \`ltm_create(slug, parentSlug, title, body)\` - Create new entry
|
|
35861
|
+
- \`ltm_update(slug, body, version)\` - Replace entry content
|
|
35862
|
+
- \`ltm_edit(slug, old, new, version)\` - Surgical edit
|
|
35863
|
+
- \`ltm_reparent(slug, newParentSlug, version)\` - Move entry
|
|
35864
|
+
- \`ltm_archive(slug, version)\` - Remove outdated entry
|
|
35865
|
+
|
|
35866
|
+
**History:**
|
|
35867
|
+
- \`search_messages(query)\` - Full-text search in conversation history
|
|
35868
|
+
- \`get_message(id, contextBefore, contextAfter)\` - Get specific message with context
|
|
35869
|
+
|
|
35870
|
+
**Web:**
|
|
35871
|
+
- \`web_search(query)\` - Search the web
|
|
35872
|
+
- \`web_fetch(url, question)\` - Read a webpage and extract info
|
|
35873
|
+
|
|
35874
|
+
**Files:**
|
|
35875
|
+
- \`glob(pattern)\` - Find files matching pattern
|
|
35876
|
+
- \`read(filePath)\` - Read file contents
|
|
35877
|
+
- \`grep(pattern)\` - Search file contents
|
|
35878
|
+
|
|
35879
|
+
**Control:**
|
|
35880
|
+
- \`finish_research(report)\` - Complete research and return findings
|
|
35881
|
+
|
|
35882
|
+
---
|
|
35883
|
+
|
|
35884
|
+
When done, call \`finish_research\` with a report that includes:
|
|
35885
|
+
1. Summary of what I learned
|
|
35886
|
+
2. What LTM entries I created or updated (with [[slug]] references)
|
|
35887
|
+
3. Key sources consulted
|
|
35888
|
+
|
|
35889
|
+
Be thorough! This is research, not a quick answer.
|
|
35890
|
+
`;
|
|
35891
|
+
}
|
|
35892
|
+
async function runResearch(storage, topic) {
|
|
35893
|
+
activity.research?.start?.("Research", { topic: topic.slice(0, 50) });
|
|
35894
|
+
const result = {
|
|
35895
|
+
report: "",
|
|
35896
|
+
entriesCreated: [],
|
|
35897
|
+
entriesUpdated: [],
|
|
35898
|
+
turnsUsed: 0,
|
|
35899
|
+
usage: { inputTokens: 0, outputTokens: 0 }
|
|
35900
|
+
};
|
|
35901
|
+
const { tools, getLastResult } = buildResearchTools(storage);
|
|
35902
|
+
const subAgentResult = await runSubAgent(storage, {
|
|
35903
|
+
name: "research",
|
|
35904
|
+
taskPrompt: buildResearchPrompt(topic),
|
|
35905
|
+
tools,
|
|
35906
|
+
finishToolName: "finish_research",
|
|
35907
|
+
extractResult: () => {
|
|
35908
|
+
return result.report || null;
|
|
35909
|
+
},
|
|
35910
|
+
tier: "workhorse",
|
|
35911
|
+
maxTurns: MAX_RESEARCH_TURNS,
|
|
35912
|
+
maxTokens: 8192,
|
|
35913
|
+
onToolResult: (toolCallId) => {
|
|
35914
|
+
const toolResult = getLastResult(toolCallId);
|
|
35915
|
+
if (!toolResult)
|
|
35916
|
+
return;
|
|
35917
|
+
if (toolResult.entryCreated && toolResult.slug) {
|
|
35918
|
+
result.entriesCreated.push(toolResult.slug);
|
|
35919
|
+
}
|
|
35920
|
+
if (toolResult.entryUpdated && toolResult.slug) {
|
|
35921
|
+
result.entriesUpdated.push(toolResult.slug);
|
|
35922
|
+
}
|
|
35923
|
+
if (toolResult.report) {
|
|
35924
|
+
result.report = toolResult.report;
|
|
35925
|
+
}
|
|
35926
|
+
}
|
|
35927
|
+
});
|
|
35928
|
+
result.turnsUsed = subAgentResult.turnsUsed;
|
|
35929
|
+
result.usage = subAgentResult.usage;
|
|
35930
|
+
if (!result.report) {
|
|
35931
|
+
result.report = "Research ended without explicit report.";
|
|
35932
|
+
}
|
|
35933
|
+
activity.research?.complete?.(`${result.turnsUsed} turns, ${result.entriesCreated.length} created, ${result.entriesUpdated.length} updated`);
|
|
35934
|
+
return result;
|
|
35935
|
+
}
|
|
35936
|
+
|
|
35937
|
+
// src/tool/research.ts
|
|
35938
|
+
var DESCRIPTION4 = `Investigate a topic and build knowledge in your long-term memory.
|
|
35939
|
+
|
|
35940
|
+
This spawns a research sub-agent that can:
|
|
35941
|
+
- Search and update your long-term knowledge base
|
|
35942
|
+
- Search the web and fetch documentation
|
|
35943
|
+
- Search your conversation history
|
|
35944
|
+
- Read files in the codebase
|
|
35945
|
+
|
|
35946
|
+
Use this when you need to:
|
|
35947
|
+
- Deeply understand something before implementing
|
|
35948
|
+
- Document a service, API, or system
|
|
35949
|
+
- Build a profile of a company or technology
|
|
35950
|
+
- Research best practices or prior art
|
|
35951
|
+
|
|
35952
|
+
The sub-agent will research thoroughly and return a report of what it learned and what LTM entries it created or updated.`;
|
|
35953
|
+
var parameters4 = exports_external.object({
|
|
35954
|
+
topic: exports_external.string().describe("The topic to research. Be specific about what you want to learn. Examples: 'How does Stripe's payment intent API work?', 'Document the authentication flow in our codebase', 'Research best practices for rate limiting'")
|
|
35955
|
+
});
|
|
35956
|
+
var ResearchTool = Tool.define("research", {
|
|
35957
|
+
description: DESCRIPTION4,
|
|
35958
|
+
parameters: parameters4,
|
|
35959
|
+
async execute({ topic }, ctx) {
|
|
35960
|
+
const storage = ctx.extra?.storage;
|
|
35961
|
+
if (!storage) {
|
|
35962
|
+
return {
|
|
35963
|
+
output: "Error: Storage not available for research",
|
|
35964
|
+
title: "Research failed",
|
|
35965
|
+
metadata: {
|
|
35966
|
+
topic,
|
|
35967
|
+
turnsUsed: 0,
|
|
35968
|
+
entriesCreated: [],
|
|
35969
|
+
entriesUpdated: [],
|
|
35970
|
+
inputTokens: 0,
|
|
35971
|
+
outputTokens: 0
|
|
35972
|
+
}
|
|
35973
|
+
};
|
|
35974
|
+
}
|
|
35975
|
+
try {
|
|
35976
|
+
const result = await runResearch(storage, topic);
|
|
35977
|
+
return {
|
|
35978
|
+
output: result.report,
|
|
35979
|
+
title: `Researched: ${topic.slice(0, 40)}${topic.length > 40 ? "..." : ""}`,
|
|
35980
|
+
metadata: {
|
|
35981
|
+
topic,
|
|
35982
|
+
turnsUsed: result.turnsUsed,
|
|
35983
|
+
entriesCreated: result.entriesCreated,
|
|
35984
|
+
entriesUpdated: result.entriesUpdated,
|
|
35985
|
+
inputTokens: result.usage.inputTokens,
|
|
35986
|
+
outputTokens: result.usage.outputTokens
|
|
35987
|
+
}
|
|
35988
|
+
};
|
|
35989
|
+
} catch (error) {
|
|
35990
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
35991
|
+
return {
|
|
35992
|
+
output: `Research failed: ${errorMsg}`,
|
|
35993
|
+
title: "Research error",
|
|
35994
|
+
metadata: {
|
|
35995
|
+
topic,
|
|
35996
|
+
turnsUsed: 0,
|
|
35997
|
+
entriesCreated: [],
|
|
35998
|
+
entriesUpdated: [],
|
|
35999
|
+
inputTokens: 0,
|
|
36000
|
+
outputTokens: 0
|
|
36001
|
+
}
|
|
36002
|
+
};
|
|
36003
|
+
}
|
|
36004
|
+
}
|
|
36005
|
+
});
|
|
35559
36006
|
// node_modules/zod/v4/core/core.js
|
|
35560
36007
|
var NEVER2 = Object.freeze({
|
|
35561
36008
|
status: "aborted"
|
|
@@ -43913,7 +44360,7 @@ var Mcp;
|
|
|
43913
44360
|
})(Mcp ||= {});
|
|
43914
44361
|
|
|
43915
44362
|
// src/tool/mcp-status.ts
|
|
43916
|
-
var
|
|
44363
|
+
var parameters5 = exports_external.object({});
|
|
43917
44364
|
var McpStatusTool = Tool.define("mcp_status", {
|
|
43918
44365
|
description: `Inspect MCP (Model Context Protocol) server status.
|
|
43919
44366
|
|
|
@@ -43926,7 +44373,7 @@ Use this when:
|
|
|
43926
44373
|
- A tool you expect isn't available
|
|
43927
44374
|
- You want to see what MCP capabilities are configured
|
|
43928
44375
|
- Debugging MCP connection issues`,
|
|
43929
|
-
parameters:
|
|
44376
|
+
parameters: parameters5,
|
|
43930
44377
|
async execute(_args, _ctx) {
|
|
43931
44378
|
const status = Mcp.getStatus();
|
|
43932
44379
|
const toolNames = Mcp.getToolNames();
|
|
@@ -44442,26 +44889,8 @@ var LTMTools = {
|
|
|
44442
44889
|
...LTMReadOnlyTools,
|
|
44443
44890
|
...LTMWriteTools
|
|
44444
44891
|
};
|
|
44445
|
-
// src/ltm/
|
|
44446
|
-
var
|
|
44447
|
-
var MAX_CONSOLIDATION_TURNS = 20;
|
|
44448
|
-
var AGENT_TYPE = "ltm-consolidate";
|
|
44449
|
-
function isConversationNoteworthy(messages) {
|
|
44450
|
-
if (messages.length < 5) {
|
|
44451
|
-
return false;
|
|
44452
|
-
}
|
|
44453
|
-
let hasToolUsage = false;
|
|
44454
|
-
let hasSubstantialContent = false;
|
|
44455
|
-
for (const msg of messages) {
|
|
44456
|
-
if (msg.type === "tool_call" || msg.type === "tool_result") {
|
|
44457
|
-
hasToolUsage = true;
|
|
44458
|
-
}
|
|
44459
|
-
if (msg.content.length > 200) {
|
|
44460
|
-
hasSubstantialContent = true;
|
|
44461
|
-
}
|
|
44462
|
-
}
|
|
44463
|
-
return hasToolUsage || hasSubstantialContent;
|
|
44464
|
-
}
|
|
44892
|
+
// src/ltm/tools.ts
|
|
44893
|
+
var AGENT_TYPE2 = "ltm-consolidate";
|
|
44465
44894
|
function buildConsolidationTools(storage) {
|
|
44466
44895
|
const results = new Map;
|
|
44467
44896
|
const createLTMContext2 = (toolCallId) => {
|
|
@@ -44472,10 +44901,17 @@ function buildConsolidationTools(storage) {
|
|
|
44472
44901
|
});
|
|
44473
44902
|
ctx.extra = {
|
|
44474
44903
|
ltm: storage.ltm,
|
|
44475
|
-
agentType:
|
|
44904
|
+
agentType: AGENT_TYPE2
|
|
44476
44905
|
};
|
|
44477
44906
|
return ctx;
|
|
44478
44907
|
};
|
|
44908
|
+
const createBaseContext = (toolCallId) => {
|
|
44909
|
+
return Tool.createContext({
|
|
44910
|
+
sessionID: "consolidation",
|
|
44911
|
+
messageID: "consolidation",
|
|
44912
|
+
callID: toolCallId
|
|
44913
|
+
});
|
|
44914
|
+
};
|
|
44479
44915
|
const tools = {};
|
|
44480
44916
|
tools.ltm_read = tool({
|
|
44481
44917
|
description: LTMReadTool.definition.description,
|
|
@@ -44628,12 +45064,7 @@ function buildConsolidationTools(storage) {
|
|
|
44628
45064
|
description: ReadTool.definition.description,
|
|
44629
45065
|
parameters: ReadTool.definition.parameters,
|
|
44630
45066
|
execute: async (args, { toolCallId }) => {
|
|
44631
|
-
const
|
|
44632
|
-
sessionID: "consolidation",
|
|
44633
|
-
messageID: "consolidation",
|
|
44634
|
-
callID: toolCallId
|
|
44635
|
-
});
|
|
44636
|
-
const toolResult = await ReadTool.definition.execute(args, ctx);
|
|
45067
|
+
const toolResult = await ReadTool.definition.execute(args, createBaseContext(toolCallId));
|
|
44637
45068
|
const result = { output: toolResult.output, done: false };
|
|
44638
45069
|
results.set(toolCallId, result);
|
|
44639
45070
|
return result.output;
|
|
@@ -44643,12 +45074,7 @@ function buildConsolidationTools(storage) {
|
|
|
44643
45074
|
description: GlobTool.definition.description,
|
|
44644
45075
|
parameters: GlobTool.definition.parameters,
|
|
44645
45076
|
execute: async (args, { toolCallId }) => {
|
|
44646
|
-
const
|
|
44647
|
-
sessionID: "consolidation",
|
|
44648
|
-
messageID: "consolidation",
|
|
44649
|
-
callID: toolCallId
|
|
44650
|
-
});
|
|
44651
|
-
const toolResult = await GlobTool.definition.execute(args, ctx);
|
|
45077
|
+
const toolResult = await GlobTool.definition.execute(args, createBaseContext(toolCallId));
|
|
44652
45078
|
const result = { output: toolResult.output, done: false };
|
|
44653
45079
|
results.set(toolCallId, result);
|
|
44654
45080
|
return result.output;
|
|
@@ -44658,12 +45084,7 @@ function buildConsolidationTools(storage) {
|
|
|
44658
45084
|
description: GrepTool.definition.description,
|
|
44659
45085
|
parameters: GrepTool.definition.parameters,
|
|
44660
45086
|
execute: async (args, { toolCallId }) => {
|
|
44661
|
-
const
|
|
44662
|
-
sessionID: "consolidation",
|
|
44663
|
-
messageID: "consolidation",
|
|
44664
|
-
callID: toolCallId
|
|
44665
|
-
});
|
|
44666
|
-
const toolResult = await GrepTool.definition.execute(args, ctx);
|
|
45087
|
+
const toolResult = await GrepTool.definition.execute(args, createBaseContext(toolCallId));
|
|
44667
45088
|
const result = { output: toolResult.output, done: false };
|
|
44668
45089
|
results.set(toolCallId, result);
|
|
44669
45090
|
return result.output;
|
|
@@ -44673,12 +45094,7 @@ function buildConsolidationTools(storage) {
|
|
|
44673
45094
|
description: WebSearchTool.definition.description,
|
|
44674
45095
|
parameters: WebSearchTool.definition.parameters,
|
|
44675
45096
|
execute: async (args, { toolCallId }) => {
|
|
44676
|
-
const
|
|
44677
|
-
sessionID: "consolidation",
|
|
44678
|
-
messageID: "consolidation",
|
|
44679
|
-
callID: toolCallId
|
|
44680
|
-
});
|
|
44681
|
-
const toolResult = await WebSearchTool.definition.execute(args, ctx);
|
|
45097
|
+
const toolResult = await WebSearchTool.definition.execute(args, createBaseContext(toolCallId));
|
|
44682
45098
|
const result = { output: toolResult.output, done: false };
|
|
44683
45099
|
results.set(toolCallId, result);
|
|
44684
45100
|
return result.output;
|
|
@@ -44688,12 +45104,7 @@ function buildConsolidationTools(storage) {
|
|
|
44688
45104
|
description: WebFetchTool.definition.description,
|
|
44689
45105
|
parameters: WebFetchTool.definition.parameters,
|
|
44690
45106
|
execute: async (args, { toolCallId }) => {
|
|
44691
|
-
const
|
|
44692
|
-
sessionID: "consolidation",
|
|
44693
|
-
messageID: "consolidation",
|
|
44694
|
-
callID: toolCallId
|
|
44695
|
-
});
|
|
44696
|
-
const toolResult = await WebFetchTool.definition.execute(args, ctx);
|
|
45107
|
+
const toolResult = await WebFetchTool.definition.execute(args, createBaseContext(toolCallId));
|
|
44697
45108
|
const result = { output: toolResult.output, done: false };
|
|
44698
45109
|
results.set(toolCallId, result);
|
|
44699
45110
|
return result.output;
|
|
@@ -44715,7 +45126,27 @@ function buildConsolidationTools(storage) {
|
|
|
44715
45126
|
getLastResult: (toolCallId) => results.get(toolCallId)
|
|
44716
45127
|
};
|
|
44717
45128
|
}
|
|
44718
|
-
|
|
45129
|
+
|
|
45130
|
+
// src/ltm/consolidation.ts
|
|
45131
|
+
var log9 = Log.create({ service: "consolidation-agent" });
|
|
45132
|
+
var MAX_CONSOLIDATION_TURNS = 20;
|
|
45133
|
+
function isConversationNoteworthy(messages) {
|
|
45134
|
+
if (messages.length < 5) {
|
|
45135
|
+
return false;
|
|
45136
|
+
}
|
|
45137
|
+
let hasToolUsage = false;
|
|
45138
|
+
let hasSubstantialContent = false;
|
|
45139
|
+
for (const msg of messages) {
|
|
45140
|
+
if (msg.type === "tool_call" || msg.type === "tool_result") {
|
|
45141
|
+
hasToolUsage = true;
|
|
45142
|
+
}
|
|
45143
|
+
if (msg.content.length > 200) {
|
|
45144
|
+
hasSubstantialContent = true;
|
|
45145
|
+
}
|
|
45146
|
+
}
|
|
45147
|
+
return hasToolUsage || hasSubstantialContent;
|
|
45148
|
+
}
|
|
45149
|
+
async function buildLTMReviewPrompt(storage, recentlyUpdatedEntries) {
|
|
44719
45150
|
const allEntries = await storage.ltm.glob("/**");
|
|
44720
45151
|
const treeView = renderCompactTree(allEntries, 3);
|
|
44721
45152
|
let content = `## Knowledge Base Curation Task
|
|
@@ -44772,46 +45203,6 @@ ${recentlyUpdatedEntries.map((e) => `- **${e.slug}**: ${e.title}`).join(`
|
|
|
44772
45203
|
- \u2713 "Tool pattern: parameters must be defined BEFORE Tool.define() call due to initialization order"
|
|
44773
45204
|
- \u2717 "The config module handles configuration" (too obvious, adds no value)
|
|
44774
45205
|
|
|
44775
|
-
**When to document code structure:**
|
|
44776
|
-
- Complex modules with non-obvious responsibilities
|
|
44777
|
-
- Files that interact in subtle ways
|
|
44778
|
-
- Patterns that took effort to understand
|
|
44779
|
-
- Entry points and key abstractions
|
|
44780
|
-
|
|
44781
|
-
---
|
|
44782
|
-
|
|
44783
|
-
### Curation Tasks (do these!)
|
|
44784
|
-
|
|
44785
|
-
**Organize the tree:**
|
|
44786
|
-
- Group related entries under parent paths
|
|
44787
|
-
- Create small "index" entries that just organize children (this is fine!)
|
|
44788
|
-
- A flat list of 20 entries is hard to navigate - a tree is better
|
|
44789
|
-
|
|
44790
|
-
Example structure:
|
|
44791
|
-
/miriad-code <- index entry: "My codebase - architecture and patterns"
|
|
44792
|
-
/protocol <- NDJSON protocol details
|
|
44793
|
-
/memory-system <- temporal, LTM, distillation
|
|
44794
|
-
/user <- index entry: "Working with Simen"
|
|
44795
|
-
/preferences <- simplicity over compat, incremental refactoring
|
|
44796
|
-
/integrations <- index entry: "External systems"
|
|
44797
|
-
/mcp <- MCP protocol, config resolution
|
|
44798
|
-
|
|
44799
|
-
**Cross-link for findability:**
|
|
44800
|
-
- Use [[slug]] syntax to connect related entries
|
|
44801
|
-
- Ask: "If I search for X, will I find this?"
|
|
44802
|
-
- Index entries can list their children with [[links]]
|
|
44803
|
-
|
|
44804
|
-
**Maintain quality:**
|
|
44805
|
-
- Combine entries that overlap significantly
|
|
44806
|
-
- Split entries that cover too many topics
|
|
44807
|
-
- Archive entries that are outdated or wrong
|
|
44808
|
-
- Update entries with new information
|
|
44809
|
-
|
|
44810
|
-
**Enrich with research:**
|
|
44811
|
-
- Use web_search/web_fetch to fact-check or fill gaps
|
|
44812
|
-
- Look up documentation for libraries/APIs you reference
|
|
44813
|
-
- Verify assumptions about external systems
|
|
44814
|
-
|
|
44815
45206
|
---
|
|
44816
45207
|
|
|
44817
45208
|
### Tools Available
|
|
@@ -44827,10 +45218,6 @@ Example structure:
|
|
|
44827
45218
|
- \`ltm_rename(slug, newSlug, version)\` - Change entry slug
|
|
44828
45219
|
- \`ltm_archive(slug, version)\` - Remove outdated entry
|
|
44829
45220
|
|
|
44830
|
-
To create a tree:
|
|
44831
|
-
1. Create parent first: \`ltm_create("miriad-code", null, "My Codebase", "Index of codebase knowledge...")\`
|
|
44832
|
-
2. Create children with parentSlug: \`ltm_create("protocol", "miriad-code", "Protocol", "...")\`
|
|
44833
|
-
|
|
44834
45221
|
**Codebase Research:**
|
|
44835
45222
|
- \`read(filePath)\` - Read a file to verify/enrich knowledge
|
|
44836
45223
|
- \`glob(pattern)\` - Find files matching pattern
|
|
@@ -44840,12 +45227,6 @@ To create a tree:
|
|
|
44840
45227
|
- \`web_search(query)\` - Search the web for information
|
|
44841
45228
|
- \`web_fetch(url, question)\` - Read a webpage and extract info
|
|
44842
45229
|
|
|
44843
|
-
Use codebase tools to:
|
|
44844
|
-
- Verify file paths in entries still exist
|
|
44845
|
-
- Check if documented patterns are still accurate
|
|
44846
|
-
- Explore related files to build richer documentation
|
|
44847
|
-
- Confirm technical details before recording them
|
|
44848
|
-
|
|
44849
45230
|
---
|
|
44850
45231
|
|
|
44851
45232
|
### Special Entries: /identity and /behavior
|
|
@@ -44860,16 +45241,12 @@ This frames everything you do. It's how you understand yourself in relationship
|
|
|
44860
45241
|
- Other agents or entities you interact with
|
|
44861
45242
|
- Your own nature and capabilities
|
|
44862
45243
|
|
|
44863
|
-
This is actionable because it helps you form lasting relationships and maintain continuity. Update it as your understanding deepens.
|
|
44864
|
-
|
|
44865
45244
|
**/behavior** - How you operate
|
|
44866
45245
|
- User preferences you've learned
|
|
44867
45246
|
- Working patterns that work well
|
|
44868
45247
|
- Guidelines for code quality, testing, commits
|
|
44869
45248
|
- Communication style preferences
|
|
44870
45249
|
|
|
44871
|
-
Review these entries periodically. Are they accurate? Complete? Do they reflect what you've learned?
|
|
44872
|
-
|
|
44873
45250
|
---
|
|
44874
45251
|
|
|
44875
45252
|
### Your Task
|
|
@@ -44881,12 +45258,11 @@ Review these entries periodically. Are they accurate? Complete? Do they reflect
|
|
|
44881
45258
|
|
|
44882
45259
|
### Writing Your Summary
|
|
44883
45260
|
|
|
44884
|
-
When you call \`finish_consolidation\`, write a brief note to your future self explaining what you captured and why it matters.
|
|
45261
|
+
When you call \`finish_consolidation\`, write a brief note to your future self explaining what you captured and why it matters.
|
|
44885
45262
|
|
|
44886
45263
|
**Good summaries** explain the WHAT and WHY:
|
|
44887
45264
|
- "Captured the insights on probabilistic filtering in [[bloom-filter-overview]]. Also archived the X system workarounds since it's been decommissioned."
|
|
44888
|
-
- "Updated [[user-preferences]] with the new testing philosophy - run tests before committing.
|
|
44889
|
-
- "Reorganized the codebase knowledge - moved protocol docs under [[miriad-code/protocol]] and cross-linked with [[memory-system]]."
|
|
45265
|
+
- "Updated [[user-preferences]] with the new testing philosophy - run tests before committing."
|
|
44890
45266
|
|
|
44891
45267
|
**Avoid mechanical summaries**:
|
|
44892
45268
|
- \u2717 "Created 2 entries, updated 1 entry"
|
|
@@ -44915,55 +45291,50 @@ async function runConsolidation(storage, messages) {
|
|
|
44915
45291
|
}
|
|
44916
45292
|
result.ran = true;
|
|
44917
45293
|
log9.info("starting consolidation", { messageCount: messages.length });
|
|
44918
|
-
const ctx = await buildAgentContext(storage);
|
|
44919
45294
|
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();
|
|
44920
45295
|
const allEntries = await storage.ltm.glob("/**");
|
|
44921
45296
|
const recentlyUpdated = allEntries.filter((e) => e.updatedAt > oneHourAgo && e.slug !== "identity" && e.slug !== "behavior");
|
|
44922
|
-
const
|
|
44923
|
-
const model = Provider.getModelForTier("workhorse");
|
|
45297
|
+
const taskPrompt = await buildLTMReviewPrompt(storage, recentlyUpdated);
|
|
44924
45298
|
const { tools, getLastResult } = buildConsolidationTools(storage);
|
|
44925
|
-
const
|
|
44926
|
-
|
|
44927
|
-
|
|
44928
|
-
|
|
44929
|
-
${reviewTurnContent}` }
|
|
44930
|
-
];
|
|
44931
|
-
const loopResult = await runAgentLoop({
|
|
44932
|
-
model,
|
|
44933
|
-
systemPrompt: ctx.systemPrompt,
|
|
44934
|
-
initialMessages,
|
|
45299
|
+
const subAgentResult = await runSubAgent(storage, {
|
|
45300
|
+
name: "ltm-curator",
|
|
45301
|
+
taskPrompt,
|
|
44935
45302
|
tools,
|
|
44936
|
-
|
|
44937
|
-
|
|
45303
|
+
finishToolName: "finish_consolidation",
|
|
45304
|
+
extractResult: () => {
|
|
45305
|
+
return result.summary;
|
|
45306
|
+
},
|
|
45307
|
+
tier: "workhorse",
|
|
44938
45308
|
maxTurns: MAX_CONSOLIDATION_TURNS,
|
|
44939
|
-
|
|
45309
|
+
maxTokens: 2048,
|
|
44940
45310
|
onToolResult: (toolCallId) => {
|
|
44941
45311
|
const toolResult = getLastResult(toolCallId);
|
|
44942
|
-
if (toolResult
|
|
45312
|
+
if (!toolResult)
|
|
45313
|
+
return;
|
|
45314
|
+
if (toolResult.entryCreated) {
|
|
44943
45315
|
result.entriesCreated++;
|
|
44944
45316
|
if (toolResult.slug) {
|
|
44945
45317
|
result.details.push(`Created [[${toolResult.slug}]]${toolResult.title ? ` - ${toolResult.title}` : ""}`);
|
|
44946
45318
|
}
|
|
44947
45319
|
}
|
|
44948
|
-
if (toolResult
|
|
45320
|
+
if (toolResult.entryUpdated) {
|
|
44949
45321
|
result.entriesUpdated++;
|
|
44950
45322
|
if (toolResult.slug) {
|
|
44951
45323
|
result.details.push(`Updated [[${toolResult.slug}]]`);
|
|
44952
45324
|
}
|
|
44953
45325
|
}
|
|
44954
|
-
if (toolResult
|
|
45326
|
+
if (toolResult.entryArchived) {
|
|
44955
45327
|
result.entriesArchived++;
|
|
44956
45328
|
if (toolResult.slug) {
|
|
44957
45329
|
result.details.push(`Archived [[${toolResult.slug}]]`);
|
|
44958
45330
|
}
|
|
44959
45331
|
}
|
|
44960
|
-
if (toolResult
|
|
45332
|
+
if (toolResult.summary) {
|
|
44961
45333
|
result.summary = toolResult.summary;
|
|
44962
45334
|
}
|
|
44963
45335
|
}
|
|
44964
45336
|
});
|
|
44965
|
-
result.usage
|
|
44966
|
-
result.usage.outputTokens += loopResult.usage.outputTokens;
|
|
45337
|
+
result.usage = subAgentResult.usage;
|
|
44967
45338
|
if (!result.summary) {
|
|
44968
45339
|
result.summary = "Consolidation ended without explicit finish";
|
|
44969
45340
|
}
|
|
@@ -45252,6 +45623,16 @@ function createToolContextFactory(storage, sessionId, messageId, abortSignal) {
|
|
|
45252
45623
|
storage
|
|
45253
45624
|
};
|
|
45254
45625
|
return ctx;
|
|
45626
|
+
},
|
|
45627
|
+
createResearchContext(callId) {
|
|
45628
|
+
const ctx = Tool.createContext({
|
|
45629
|
+
...baseContext,
|
|
45630
|
+
callID: callId
|
|
45631
|
+
});
|
|
45632
|
+
ctx.extra = {
|
|
45633
|
+
storage
|
|
45634
|
+
};
|
|
45635
|
+
return ctx;
|
|
45255
45636
|
}
|
|
45256
45637
|
};
|
|
45257
45638
|
}
|
|
@@ -45369,6 +45750,11 @@ function buildTools(storage, sessionId, messageId, abortSignal) {
|
|
|
45369
45750
|
parameters: ReflectTool.definition.parameters,
|
|
45370
45751
|
execute: async (args, { toolCallId }) => safeExecute("reflect", () => ReflectTool.definition.execute(args, factory.createReflectContext(toolCallId)))
|
|
45371
45752
|
});
|
|
45753
|
+
tools.research = tool({
|
|
45754
|
+
description: ResearchTool.definition.description,
|
|
45755
|
+
parameters: ResearchTool.definition.parameters,
|
|
45756
|
+
execute: async (args, { toolCallId }) => safeExecute("research", () => ResearchTool.definition.execute(args, factory.createResearchContext(toolCallId)))
|
|
45757
|
+
});
|
|
45372
45758
|
return tools;
|
|
45373
45759
|
}
|
|
45374
45760
|
async function initializeMcp() {
|
|
@@ -46805,8 +47191,8 @@ async function runRepl(options) {
|
|
|
46805
47191
|
}
|
|
46806
47192
|
|
|
46807
47193
|
// src/version.ts
|
|
46808
|
-
var VERSION = "0.1.
|
|
46809
|
-
var GIT_HASH = "
|
|
47194
|
+
var VERSION = "0.1.13";
|
|
47195
|
+
var GIT_HASH = "1d9eea4";
|
|
46810
47196
|
var VERSION_STRING = `miriad-code v${VERSION} (${GIT_HASH})`;
|
|
46811
47197
|
|
|
46812
47198
|
// src/cli/index.ts
|