trucontext 0.9.2 → 0.11.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/bin/cli.js +16 -2
- package/package.json +1 -1
- package/src/client.js +2 -2
- package/src/commands/ingest.js +3 -0
- package/src/commands/memory-load.js +93 -0
- package/src/commands/recall.js +4 -0
package/bin/cli.js
CHANGED
|
@@ -25,6 +25,7 @@ import { graphOverviewCommand, graphSearchCommand, graphNodeCommand, graphNeighb
|
|
|
25
25
|
import { mindPresenceCommand, mindThoughtsCommand } from '../src/commands/mind.js';
|
|
26
26
|
import { settingsShowCommand, settingsUpdateCommand } from '../src/commands/settings.js';
|
|
27
27
|
import { provisionCommand } from '../src/commands/agents.js';
|
|
28
|
+
import { memoryLoadCommand, hotTopicsCommand } from '../src/commands/memory-load.js';
|
|
28
29
|
|
|
29
30
|
program
|
|
30
31
|
.name('trucontext')
|
|
@@ -63,6 +64,7 @@ program.command('use <app>')
|
|
|
63
64
|
// Ingest
|
|
64
65
|
program.command('ingest <source>')
|
|
65
66
|
.description('Ingest a file or text string')
|
|
67
|
+
.requiredOption('-a, --agent <agent-id>', 'Agent ID (required — provision first)')
|
|
66
68
|
.option('-c, --context <entry>', 'Link to context node (entity-id:RELATIONSHIP, repeatable)', (val, prev) => [...prev, val], [])
|
|
67
69
|
.option('--confidence <n>', 'Confidence level (0.0-1.0)')
|
|
68
70
|
.option('--temporal', 'Content can decay over time (default)')
|
|
@@ -85,6 +87,7 @@ program.command('recall <query>')
|
|
|
85
87
|
.option('-c, --context <id>', 'Further scope within the root ego network')
|
|
86
88
|
.option('-l, --limit <n>', 'Max seed results', '10')
|
|
87
89
|
.option('-d, --depth <n>', 'Graph expansion depth', '2')
|
|
90
|
+
.option('-i, --intent <intent>', 'Query intent: TEMPORAL, CAUSAL, ENTITY, COMPARATIVE, EXPLORATORY (auto-detected if omitted)')
|
|
88
91
|
.action(recallCommand);
|
|
89
92
|
|
|
90
93
|
// Entities
|
|
@@ -275,8 +278,8 @@ settings.command('update')
|
|
|
275
278
|
registerRootsCommand(program);
|
|
276
279
|
registerCuriosityCommand(program);
|
|
277
280
|
|
|
278
|
-
// Agent provision
|
|
279
|
-
const agents = program.command('agents').description('Agent provisioning');
|
|
281
|
+
// Agent provision + memory
|
|
282
|
+
const agents = program.command('agents').description('Agent provisioning & memory');
|
|
280
283
|
agents.command('provision')
|
|
281
284
|
.description('Provision an agent (create or update root node, ingest content, generate memory briefing)')
|
|
282
285
|
.requiredOption('--agent-id <id>', 'Agent identifier')
|
|
@@ -291,4 +294,15 @@ agents.command('provision')
|
|
|
291
294
|
.option('--dry-run', 'Preview what would happen without doing it')
|
|
292
295
|
.action(provisionCommand);
|
|
293
296
|
|
|
297
|
+
agents.command('memory-load')
|
|
298
|
+
.description('Get the pre-computed MLC briefing document for an agent')
|
|
299
|
+
.requiredOption('-a, --agent <id>', 'Agent ID')
|
|
300
|
+
.action(memoryLoadCommand);
|
|
301
|
+
|
|
302
|
+
agents.command('hot-topics')
|
|
303
|
+
.description('List or view hot topic deep-dive documents')
|
|
304
|
+
.requiredOption('-a, --agent <id>', 'Agent ID')
|
|
305
|
+
.option('-t, --topic <slug>', 'Specific topic slug to view')
|
|
306
|
+
.action(hotTopicsCommand);
|
|
307
|
+
|
|
294
308
|
program.parse();
|
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -13,7 +13,7 @@ async function request(baseUrl, method, path, body, retry = true) {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
const ac = new AbortController();
|
|
16
|
-
const timeout = setTimeout(() => ac.abort(),
|
|
16
|
+
const timeout = setTimeout(() => ac.abort(), 60000);
|
|
17
17
|
|
|
18
18
|
try {
|
|
19
19
|
const res = await fetch(`${baseUrl}${path}`, {
|
|
@@ -80,7 +80,7 @@ export function controlPlane(method, path, body) {
|
|
|
80
80
|
|
|
81
81
|
export async function publicApi(method, path) {
|
|
82
82
|
const ac = new AbortController();
|
|
83
|
-
const timeout = setTimeout(() => ac.abort(),
|
|
83
|
+
const timeout = setTimeout(() => ac.abort(), 60000);
|
|
84
84
|
try {
|
|
85
85
|
const res = await fetch(`${CONTROL_PLANE_URL}${path}`, {
|
|
86
86
|
method,
|
package/src/commands/ingest.js
CHANGED
|
@@ -34,6 +34,9 @@ export async function ingestCommand(source, options) {
|
|
|
34
34
|
if (options.confidence !== undefined) body.confidence = parseFloat(options.confidence);
|
|
35
35
|
if (options.temporal !== undefined) body.temporal = options.temporal;
|
|
36
36
|
|
|
37
|
+
// Agent ID (required — enforced by commander's requiredOption)
|
|
38
|
+
body.agent_id = options.agent;
|
|
39
|
+
|
|
37
40
|
// Build contexts array from --context flags: "entity-id:RELATIONSHIP" (required)
|
|
38
41
|
if (!options.context || options.context.length === 0) {
|
|
39
42
|
console.error(chalk.red('At least one context is required.'));
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// commands/memory-load.js — Memory Load Cache CLI
|
|
2
|
+
//
|
|
3
|
+
// trucontext agents memory-load --agent <id>
|
|
4
|
+
// trucontext agents hot-topics --agent <id>
|
|
5
|
+
// trucontext agents hot-topics --agent <id> --topic <slug>
|
|
6
|
+
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { dataPlane } from '../client.js';
|
|
9
|
+
|
|
10
|
+
export async function memoryLoadCommand(options) {
|
|
11
|
+
try {
|
|
12
|
+
const agentId = options.agent;
|
|
13
|
+
if (!agentId) {
|
|
14
|
+
console.error(chalk.red('--agent <id> is required'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const res = await dataPlane('GET', `/v1/agents/${agentId}/memory-load`);
|
|
19
|
+
const data = res.data;
|
|
20
|
+
|
|
21
|
+
if (data.status === 'pending') {
|
|
22
|
+
console.log(chalk.yellow('MLC not yet generated. The heartbeat will produce one after the next dream cycle.'));
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Print document
|
|
27
|
+
console.log(chalk.bold(`\nMemory Load Cache — ${agentId}`));
|
|
28
|
+
console.log(chalk.dim(`Generated: ${data.generated_at} | Cycle: ${data.heartbeat_cycle} | Recipe: ${data.recipe_id}`));
|
|
29
|
+
console.log(chalk.dim('─'.repeat(60)));
|
|
30
|
+
console.log(data.document);
|
|
31
|
+
|
|
32
|
+
// Print hot topics manifest
|
|
33
|
+
if (data.hot_topics?.length > 0) {
|
|
34
|
+
console.log(chalk.dim('─'.repeat(60)));
|
|
35
|
+
console.log(chalk.bold(`\nHot Topics (${data.hot_topics.length}):`));
|
|
36
|
+
for (const t of data.hot_topics) {
|
|
37
|
+
console.log(` ${chalk.cyan(t.slug)} — ${t.label}`);
|
|
38
|
+
if (t.teaser) console.log(` ${chalk.dim(t.teaser)}`);
|
|
39
|
+
}
|
|
40
|
+
console.log(chalk.dim('\nUse: trucontext agents hot-topics --agent ' + agentId + ' --topic <slug>'));
|
|
41
|
+
}
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.error(chalk.red(`Memory load failed: ${err.message}`));
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export async function hotTopicsCommand(options) {
|
|
49
|
+
try {
|
|
50
|
+
const agentId = options.agent;
|
|
51
|
+
if (!agentId) {
|
|
52
|
+
console.error(chalk.red('--agent <id> is required'));
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// If --topic is specified, fetch individual document
|
|
57
|
+
if (options.topic) {
|
|
58
|
+
const res = await dataPlane('GET', `/v1/agents/${agentId}/hot-topics/${options.topic}`);
|
|
59
|
+
const data = res.data;
|
|
60
|
+
|
|
61
|
+
console.log(chalk.bold(`\nHot Topic: ${data.label}`));
|
|
62
|
+
console.log(chalk.dim(`Generated: ${data.generated_at} | Atoms: ${data.atoms_referenced} | Confidence: ${(data.confidence * 100).toFixed(0)}%`));
|
|
63
|
+
console.log(chalk.dim('─'.repeat(60)));
|
|
64
|
+
console.log(data.document);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// List all hot topics
|
|
69
|
+
const res = await dataPlane('GET', `/v1/agents/${agentId}/hot-topics`);
|
|
70
|
+
const topics = res.data;
|
|
71
|
+
|
|
72
|
+
if (!topics || topics.length === 0) {
|
|
73
|
+
console.log(chalk.yellow('No hot topics cached. The heartbeat will generate them after the next dream cycle.'));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(chalk.bold(`\nHot Topics for ${agentId} (${topics.length}):\n`));
|
|
78
|
+
for (const t of topics) {
|
|
79
|
+
const conf = t.confidence ? ` ${chalk.dim(`${(t.confidence * 100).toFixed(0)}%`)}` : '';
|
|
80
|
+
const atoms = t.atoms_referenced ? ` ${chalk.dim(`${t.atoms_referenced} atoms`)}` : '';
|
|
81
|
+
console.log(` ${chalk.cyan(t.slug)} — ${t.label}${conf}${atoms}`);
|
|
82
|
+
console.log(` ${chalk.dim(t.generated_at)}`);
|
|
83
|
+
}
|
|
84
|
+
console.log(chalk.dim('\nUse --topic <slug> to read a specific hot topic document.'));
|
|
85
|
+
} catch (err) {
|
|
86
|
+
if (err.status === 404) {
|
|
87
|
+
console.log(chalk.yellow('Hot topic not found. It may have expired (TTL 4 days). Use recall for a live query.'));
|
|
88
|
+
} else {
|
|
89
|
+
console.error(chalk.red(`Hot topics failed: ${err.message}`));
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
package/src/commands/recall.js
CHANGED
|
@@ -21,6 +21,7 @@ export async function recallCommand(query, options) {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
if (options.context) body.context_id = options.context;
|
|
24
|
+
if (options.intent) body.intent = options.intent.toUpperCase();
|
|
24
25
|
|
|
25
26
|
const res = await dataPlane('POST', `/v1/recall`, body);
|
|
26
27
|
const data = res.data;
|
|
@@ -46,6 +47,9 @@ export async function recallCommand(query, options) {
|
|
|
46
47
|
console.log(chalk.dim(`\nGraph: ${data.context.nodes?.length || 0} nodes, ${data.context.edges?.length || 0} edges`));
|
|
47
48
|
}
|
|
48
49
|
|
|
50
|
+
if (data.intent) {
|
|
51
|
+
console.log(chalk.dim(`Intent: ${data.intent}`));
|
|
52
|
+
}
|
|
49
53
|
console.log(chalk.dim(`${data.latency_ms}ms`));
|
|
50
54
|
} catch (err) {
|
|
51
55
|
console.error(chalk.red(`Recall failed: ${err.message}`));
|