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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "trucontext",
3
- "version": "0.9.2",
3
+ "version": "0.11.0",
4
4
  "description": "TruContext CLI — contextual memory for AI applications",
5
5
  "type": "module",
6
6
  "bin": {
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(), 15000);
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(), 15000);
83
+ const timeout = setTimeout(() => ac.abort(), 60000);
84
84
  try {
85
85
  const res = await fetch(`${CONTROL_PLANE_URL}${path}`, {
86
86
  method,
@@ -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
+ }
@@ -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}`));