clementine-agent 1.18.54 → 1.18.55

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.
@@ -1780,53 +1780,58 @@ export class Gateway {
1780
1780
  const { runAgent } = await import('../agent/run-agent.js');
1781
1781
  const { buildExtraMcpForRunAgent } = await import('../agent/run-agent-mcp.js');
1782
1782
  const { buildChatSystemAppend } = await import('../agent/run-agent-context.js');
1783
- // Wire Composio + external MCP servers (Outlook, Gmail,
1784
- // Salesforce, etc) so chat can reach the same tools the
1785
- // legacy chat path did. Profile allowlists override the
1786
- // bundle router when set.
1787
- //
1788
- // Use originalText (not chatPrompt) for scope routing
1789
- // chatPrompt may have the partial-interrupt banner folded in,
1790
- // which would skew bundle matching.
1791
- const chatMcp = await buildExtraMcpForRunAgent({
1792
- scopeText: originalText,
1793
- profile: resolvedProfile,
1794
- });
1795
- // Inject vault context (SOUL.md / MEMORY.md / AGENTS.md +
1796
- // optional profile body) into the system-prompt append so
1797
- // the agent has personality + long-term memory + team
1798
- // awareness. Profile-specific MEMORY.md takes precedence
1799
- // over the global one when a hired agent is active.
1800
- const chatSystemAppend = buildChatSystemAppend({
1801
- profile: resolvedProfile,
1802
- profileAppend: resolvedProfile?.systemPromptBody,
1803
- });
1804
- // Per-turn context — recall of recent transcripts, persistent
1805
- // learnings, silent context blocks, security advisories, and
1806
- // toolset directives accumulated above. This is what gives
1807
- // continuity across daemon restarts (SDK in-memory session is
1808
- // gone, but transcripts in SQLite persist; recall surfaces
1809
- // them). Prefixed to the user message in a clearly-delimited
1810
- // [Context] block so the model knows it's framing, not user
1811
- // input.
1812
- const turnContextPrefix = securityAnnotation.trim()
1783
+ // Builder sessions (dashboard trick/skill/cron/agent builder)
1784
+ // are conversational JSON-drafting flows, not real chat. They
1785
+ // don't need vault context, MCP tools, recall, or auto-memory
1786
+ // extraction the builder prefix IS the system prompt and
1787
+ // the agent only emits json-artifact blocks. Strip everything
1788
+ // expensive; keep just SDK session resume so multi-turn
1789
+ // artifact iteration sees its own prior turns.
1790
+ const isBuilderSession = sessionKey.startsWith('dashboard:builder:');
1791
+ // Wire Composio + external MCP only for real chat. Builder
1792
+ // skips entirely — builder turns never call tools.
1793
+ const chatMcp = isBuilderSession
1794
+ ? null
1795
+ : await buildExtraMcpForRunAgent({
1796
+ scopeText: originalText,
1797
+ profile: resolvedProfile,
1798
+ });
1799
+ // Vault context (SOUL.md / MEMORY.md / AGENTS.md + optional
1800
+ // profile body) — real chat only. Builder gets just its own
1801
+ // prefix as the system prompt.
1802
+ const chatSystemAppend = isBuilderSession
1803
+ ? ''
1804
+ : buildChatSystemAppend({
1805
+ profile: resolvedProfile,
1806
+ profileAppend: resolvedProfile?.systemPromptBody,
1807
+ });
1808
+ // Per-turn context (recall + persistent learnings + silent
1809
+ // blocks + security/toolset directives) real chat only.
1810
+ // Builder doesn't need recall of unrelated transcripts.
1811
+ const turnContextPrefix = !isBuilderSession && securityAnnotation.trim()
1813
1812
  ? `[Context — read this for continuity, then respond to the user message below]\n${securityAnnotation}\n[/Context]\n\n`
1814
1813
  : '';
1815
1814
  const finalPrompt = turnContextPrefix + chatPrompt;
1816
1815
  // Resume the prior SDK session when one exists for this
1817
1816
  // sessionKey. The SDK persists session JSONLs to disk, so
1818
- // resume works across daemon restarts. Without this, every
1819
- // turn is a fresh SDK session with zero conversation history.
1817
+ // resume works across daemon restarts AND for builder
1818
+ // multi-turn artifact iteration.
1820
1819
  const priorSdkSessionId = this.assistant.getSdkSessionId(effectiveSessionKey);
1820
+ // Builder cost knobs: Haiku is plenty for JSON drafting,
1821
+ // tight budget, no tools surfaced in the system prompt.
1822
+ const builderModel = isBuilderSession ? MODELS.haiku : effectiveModel;
1823
+ const builderBudget = isBuilderSession ? 0.10 : undefined;
1824
+ const builderAllowedTools = isBuilderSession ? [] : undefined;
1821
1825
  logger.info({
1822
1826
  sessionKey: effectiveSessionKey,
1823
1827
  profile: resolvedProfile?.slug,
1824
- path: 'runagent_chat',
1825
- composioConnected: chatMcp.composioConnected.length,
1826
- externalConnected: chatMcp.externalConnected.length,
1828
+ path: isBuilderSession ? 'runagent_builder' : 'runagent_chat',
1829
+ composioConnected: chatMcp?.composioConnected.length ?? 0,
1830
+ externalConnected: chatMcp?.externalConnected.length ?? 0,
1827
1831
  systemAppendChars: chatSystemAppend.length,
1828
1832
  turnContextChars: turnContextPrefix.length,
1829
1833
  resumingSdkSessionId: priorSdkSessionId || null,
1834
+ isBuilderSession,
1830
1835
  }, 'Routing chat through runAgent');
1831
1836
  const runAgentResult = await runAgent(finalPrompt, {
1832
1837
  sessionKey: effectiveSessionKey,
@@ -1834,11 +1839,13 @@ export class Gateway {
1834
1839
  profile: resolvedProfile,
1835
1840
  agentManager: this.getAgentManager(),
1836
1841
  memoryStore: this.assistant.getMemoryStore?.() ?? null,
1837
- ...(effectiveModel ? { model: effectiveModel } : {}),
1842
+ ...(builderModel ? { model: builderModel } : {}),
1838
1843
  ...(maxTurns ? { maxTurns } : {}),
1844
+ ...(builderBudget !== undefined ? { maxBudgetUsd: builderBudget } : {}),
1845
+ ...(builderAllowedTools ? { allowedTools: builderAllowedTools } : {}),
1839
1846
  ...(chatSystemAppend ? { systemPromptAppend: chatSystemAppend } : {}),
1840
1847
  ...(priorSdkSessionId ? { resumeSessionId: priorSdkSessionId } : {}),
1841
- extraMcpServers: chatMcp.servers,
1848
+ ...(chatMcp ? { extraMcpServers: chatMcp.servers } : {}),
1842
1849
  onText: wrappedOnText,
1843
1850
  onToolActivity: ({ tool, input }) => {
1844
1851
  toolActivityCount++;
@@ -1856,9 +1863,11 @@ export class Gateway {
1856
1863
  }
1857
1864
  clearTimeout(chatTimer);
1858
1865
  clearTimeout(hardWallTimer);
1859
- // Mirror transcript so memory + recall continue working.
1866
+ // Mirror transcript so memory + recall continue working — but
1867
+ // skip for builder sessions since their turns are spec-drafting,
1868
+ // not real conversation worth recalling later.
1860
1869
  const memoryStore = this.assistant.getMemoryStore?.();
1861
- if (memoryStore) {
1870
+ if (memoryStore && !isBuilderSession) {
1862
1871
  try {
1863
1872
  memoryStore.saveTurn(effectiveSessionKey, 'user', originalText);
1864
1873
  memoryStore.saveTurn(effectiveSessionKey, 'assistant', runAgentResult.text);
@@ -1867,10 +1876,13 @@ export class Gateway {
1867
1876
  logger.debug({ err }, 'chat: transcript mirror failed (non-fatal)');
1868
1877
  }
1869
1878
  }
1870
- // Fire auto-memory extraction in the background.
1871
- this.assistant
1872
- .triggerMemoryExtractionPostExchange(originalText, runAgentResult.text, effectiveSessionKey, resolvedProfile)
1873
- .catch(err => logger.debug({ err, sessionKey: effectiveSessionKey }, 'chat: auto-memory failed (non-fatal)'));
1879
+ // Fire auto-memory extraction in the background — builder
1880
+ // turns are JSON-drafting noise, not memorable exchanges.
1881
+ if (!isBuilderSession) {
1882
+ this.assistant
1883
+ .triggerMemoryExtractionPostExchange(originalText, runAgentResult.text, effectiveSessionKey, resolvedProfile)
1884
+ .catch(err => logger.debug({ err, sessionKey: effectiveSessionKey }, 'chat: auto-memory failed (non-fatal)'));
1885
+ }
1874
1886
  // Auth recovered if we got a clean response.
1875
1887
  this.clearAuthFailure();
1876
1888
  logger.info({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.54",
3
+ "version": "1.18.55",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",