clementine-agent 1.18.37 → 1.18.38

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.
@@ -417,7 +417,17 @@ const SESSIONS_FILE = path.join(BASE_DIR, '.sessions.json');
417
417
  const MAX_SESSION_EXCHANGES = 40;
418
418
  const SESSION_EXPIRY_MS = 24 * 60 * 60 * 1000;
419
419
  const AUTO_MEMORY_MIN_LENGTH = 80;
420
- const AUTO_MEMORY_MODEL = MODELS.sonnet;
420
+ // Model used by the post-exchange memory extractor + the conversation
421
+ // summarizer. Both are routine "read this exchange, extract facts, call
422
+ // memory_write with structured JSON" tasks — Haiku handles them fine and
423
+ // they fire on EVERY substantive exchange, so the multiplier matters.
424
+ // Override with CLEMENTINE_AUTO_MEMORY_MODEL=sonnet if you observe
425
+ // extraction quality drop.
426
+ const AUTO_MEMORY_MODEL = process.env.CLEMENTINE_AUTO_MEMORY_MODEL?.includes('sonnet')
427
+ ? MODELS.sonnet
428
+ : process.env.CLEMENTINE_AUTO_MEMORY_MODEL?.includes('opus')
429
+ ? MODELS.opus
430
+ : MODELS.haiku;
421
431
  const OWNER = OWNER_NAME || 'the user';
422
432
  const MCP_SERVER_SCRIPT = path.join(PKG_DIR, 'dist', 'tools', 'mcp-server.js');
423
433
  const TOOLS_SERVER = `${ASSISTANT_NAME.toLowerCase()}-tools`;
@@ -4623,6 +4633,12 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
4623
4633
  const blocks = getContentBlocks(message);
4624
4634
  summaryText += extractText(blocks);
4625
4635
  }
4636
+ else if (message.type === 'result') {
4637
+ // Make session-summarization cost visible in usage_log. Without
4638
+ // this, every session rotation spawned a Sonnet summarize call
4639
+ // that didn't appear in any metric.
4640
+ this.logQueryResult(message, 'summarize', `summarize:${sessionKey}`);
4641
+ }
4626
4642
  }
4627
4643
  if (summaryText.trim()) {
4628
4644
  if (this.memoryStore) {
@@ -4993,6 +5009,13 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
4993
5009
  });
4994
5010
  const collectedText = [];
4995
5011
  for await (const message of stream) {
5012
+ if (message.type === 'result') {
5013
+ // Auto-memory extraction fires after every substantive
5014
+ // exchange. Before this log call, its cost was invisible in
5015
+ // usage_log — a per-user-message Sonnet pass running silently.
5016
+ this.logQueryResult(message, 'auto_memory', `auto-memory:${sessionKey ?? 'unknown'}`, undefined, profile?.slug);
5017
+ continue;
5018
+ }
4996
5019
  if (message.type === 'assistant') {
4997
5020
  const blocks = getContentBlocks(message);
4998
5021
  for (const block of blocks) {
@@ -5651,6 +5674,11 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
5651
5674
  const blocks = getContentBlocks(message);
5652
5675
  responseText += extractText(blocks);
5653
5676
  }
5677
+ else if (message.type === 'result') {
5678
+ // Cron reflection (post-task quality check) fires after every
5679
+ // cron run. Cheap (Haiku, 1 turn, ~1KB) but should be visible.
5680
+ this.logQueryResult(message, 'cron_reflection', `reflection:${jobName}`, jobName);
5681
+ }
5654
5682
  }
5655
5683
  if (responseText.trim()) {
5656
5684
  const reflection = JSON.parse(responseText.trim());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.37",
3
+ "version": "1.18.38",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",