clementine-agent 1.18.1 → 1.18.3

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.
@@ -13,7 +13,11 @@ import fs from 'node:fs';
13
13
  import path from 'node:path';
14
14
  import { query as rawQuery, listSubagents, getSubagentMessages, SYSTEM_PROMPT_DYNAMIC_BOUNDARY, } from '@anthropic-ai/claude-agent-sdk';
15
15
  import pino from 'pino';
16
- import { BASE_DIR, PKG_DIR, VAULT_DIR, DAILY_NOTES_DIR, SOUL_FILE, AGENTS_FILE, MEMORY_FILE, AGENTS_DIR, ASSISTANT_NAME, OWNER_NAME, MODEL, MODELS, HEARTBEAT_MAX_TURNS, SEARCH_CONTEXT_LIMIT, SEARCH_RECENCY_LIMIT, SYSTEM_PROMPT_MAX_CONTEXT_CHARS, SESSION_EXCHANGE_HISTORY_SIZE, SESSION_EXCHANGE_MAX_CHARS, INJECTED_CONTEXT_MAX_CHARS, UNLEASHED_PHASE_TURNS, UNLEASHED_DEFAULT_MAX_HOURS, UNLEASHED_MAX_PHASES, PROJECTS_META_FILE, CRON_PROGRESS_DIR, CRON_REFLECTIONS_DIR, HANDOFFS_DIR, BUDGET, TASK_BUDGET_TOKENS, IDENTITY_FILE, CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY as CONFIG_ANTHROPIC_API_KEY, } from '../config.js';
16
+ import { BASE_DIR, PKG_DIR, VAULT_DIR, DAILY_NOTES_DIR, SOUL_FILE, AGENTS_FILE, MEMORY_FILE, AGENTS_DIR, ASSISTANT_NAME, OWNER_NAME, MODEL, MODELS, HEARTBEAT_MAX_TURNS, SEARCH_CONTEXT_LIMIT, SEARCH_RECENCY_LIMIT, SYSTEM_PROMPT_MAX_CONTEXT_CHARS, SESSION_EXCHANGE_HISTORY_SIZE, SESSION_EXCHANGE_MAX_CHARS, INJECTED_CONTEXT_MAX_CHARS, UNLEASHED_PHASE_TURNS, UNLEASHED_DEFAULT_MAX_HOURS, UNLEASHED_MAX_PHASES, PROJECTS_META_FILE, CRON_PROGRESS_DIR, CRON_REFLECTIONS_DIR, HANDOFFS_DIR, BUDGET, TASK_BUDGET_TOKENS, IDENTITY_FILE, CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY as CONFIG_ANTHROPIC_API_KEY, envSnapshot, } from '../config.js';
17
+ import { summarizeIntegrationStatus } from '../config/integrations-registry.js';
18
+ import { loadToolPreferences, computeAvailability, buildPromptInstruction, buildComposioStatusBlock, } from '../integrations/tool-preferences.js';
19
+ import { loadClaudeIntegrations } from './mcp-bridge.js';
20
+ import { detectFrustrationSignals, detectRepeatedTopics } from './insight-engine.js';
17
21
  import { DEFAULT_CHANNEL_CAPABILITIES } from '../types.js';
18
22
  import { enforceToolPermissions, getSecurityPrompt, getHeartbeatSecurityPrompt, getCronSecurityPrompt, getHeartbeatDisallowedTools, logToolUse, setProfileTier, setProfileAllowedTools, setAgentDir, setSendPolicy, setInteractionSource, logAuditJsonl, } from './hooks.js';
19
23
  import { scanner } from '../security/scanner.js';
@@ -1558,8 +1562,6 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
1558
1562
  // Integration status — changes as owner adds credentials.
1559
1563
  if (!isAutonomous) {
1560
1564
  try {
1561
- const { summarizeIntegrationStatus } = require('../config/integrations-registry.js');
1562
- const { envSnapshot } = require('../config.js');
1563
1565
  const summary = summarizeIntegrationStatus(envSnapshot());
1564
1566
  if (summary)
1565
1567
  volatileParts.push(`## Integration Status\n\n${summary}\n\nCall \`integration_status\`, \`list_integrations\`, or \`setup_integration\` for details.`);
@@ -1578,11 +1580,15 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
1578
1580
  // every turn regardless.
1579
1581
  if (!isAutonomous) {
1580
1582
  try {
1581
- const { loadToolPreferences, computeAvailability, buildPromptInstruction } = require('../integrations/tool-preferences.js');
1582
- const { loadClaudeIntegrations } = require('./mcp-bridge.js');
1583
1583
  const composioSet = new Set(composioConnectedSlugs);
1584
1584
  const cdIntegrations = loadClaudeIntegrations();
1585
1585
  const cdActive = new Set(Object.values(cdIntegrations).filter(i => i.connected).map(i => i.name));
1586
+ // Status block first — gives the model ground truth that Composio
1587
+ // is configured and which toolkits are live, so it stops guessing
1588
+ // whether `mcp__<slug>__*` tools are Composio or something else.
1589
+ const statusBlock = buildComposioStatusBlock(composioConnectedSlugs);
1590
+ if (statusBlock)
1591
+ volatileParts.push(statusBlock);
1586
1592
  const prefs = loadToolPreferences();
1587
1593
  const availability = computeAvailability(composioSet, cdActive, prefs.preferences);
1588
1594
  const instruction = buildPromptInstruction(availability, prefs.preferences);
@@ -1599,7 +1605,6 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
1599
1605
  // one signal fires — keeps the prompt clean during normal sessions.
1600
1606
  if (!isAutonomous) {
1601
1607
  try {
1602
- const { detectFrustrationSignals, detectRepeatedTopics } = require('./insight-engine.js');
1603
1608
  const since24h = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
1604
1609
  const since7d = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
1605
1610
  let recent = this.getRecentActivity(since24h, 50);
@@ -68,4 +68,14 @@ export declare function computeAvailability(composioConnectedSlugs: Set<string>,
68
68
  * Compare to the previous always-on hardcoded block which was ~700 chars.
69
69
  */
70
70
  export declare function buildPromptInstruction(availability: ServiceAvailability[], preferences: Record<string, ToolSource>): string;
71
+ /**
72
+ * Ground-truth header naming the Composio toolkits currently connected.
73
+ * Without this, the model has to guess what `mcp__<slug>__*` tools are
74
+ * (often misattributing them to claude.ai integrations or "extensions"),
75
+ * because Composio's slug-prefixed naming is ambiguous in isolation.
76
+ *
77
+ * Emits an empty string when no toolkits are connected — zero overhead
78
+ * for users who haven't set up Composio.
79
+ */
80
+ export declare function buildComposioStatusBlock(connectedSlugs: string[]): string;
71
81
  //# sourceMappingURL=tool-preferences.d.ts.map
@@ -116,4 +116,20 @@ export function buildPromptInstruction(availability, preferences) {
116
116
  return '';
117
117
  return `## Tool Source Preferences\n\nThese rules OVERRIDE any tool-source preference you may recall from memory. Do not consult memory for this — the canonical source is the dashboard's Tool Source Preferences (Settings → Integrations).\n\n${lines.join('\n')}`;
118
118
  }
119
+ /**
120
+ * Ground-truth header naming the Composio toolkits currently connected.
121
+ * Without this, the model has to guess what `mcp__<slug>__*` tools are
122
+ * (often misattributing them to claude.ai integrations or "extensions"),
123
+ * because Composio's slug-prefixed naming is ambiguous in isolation.
124
+ *
125
+ * Emits an empty string when no toolkits are connected — zero overhead
126
+ * for users who haven't set up Composio.
127
+ */
128
+ export function buildComposioStatusBlock(connectedSlugs) {
129
+ if (!connectedSlugs.length)
130
+ return '';
131
+ const sorted = [...connectedSlugs].sort();
132
+ const example = sorted[0];
133
+ return `## Composio Integration\n\nComposio is configured. Connected toolkits: ${sorted.join(', ')}.\n\nTools from these toolkits are namespaced as \`mcp__<slug>__<TOOL_NAME>\` (e.g., \`mcp__${example}__*\`). These are local Composio MCP servers, NOT claude.ai integrations (which use \`mcp__claude_ai_*\`).`;
134
+ }
119
135
  //# sourceMappingURL=tool-preferences.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.1",
3
+ "version": "1.18.3",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",