clementine-agent 1.18.53 → 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.
- package/dist/agent/assistant.d.ts +14 -0
- package/dist/agent/assistant.js +22 -0
- package/dist/gateway/router.js +70 -33
- package/package.json +1 -1
|
@@ -179,6 +179,20 @@ export declare class PersonalAssistant {
|
|
|
179
179
|
/** Fire-and-forget: extract a reusable skill from a successful execution. */
|
|
180
180
|
private extractSkillFromExecution;
|
|
181
181
|
private logMemoryExtractionSkip;
|
|
182
|
+
/**
|
|
183
|
+
* Public accessor for the SDK session ID associated with a sessionKey.
|
|
184
|
+
* Used by the canonical chat path so consecutive turns resume the
|
|
185
|
+
* same SDK conversation (the SDK persists sessions to JSONL on disk;
|
|
186
|
+
* resuming gives the agent native conversation history). Returns ''
|
|
187
|
+
* when no session exists yet.
|
|
188
|
+
*/
|
|
189
|
+
getSdkSessionId(sessionKey: string): string;
|
|
190
|
+
/**
|
|
191
|
+
* Persist the SDK session ID for a sessionKey. Called after a runAgent
|
|
192
|
+
* call returns so the next call can resume the same conversation.
|
|
193
|
+
* Writes through to disk via the existing saveSessions plumbing.
|
|
194
|
+
*/
|
|
195
|
+
setSdkSessionId(sessionKey: string, sdkSessionId: string): void;
|
|
182
196
|
/**
|
|
183
197
|
* Public entry point for triggering auto-memory extraction after an
|
|
184
198
|
* exchange. Used by the new runAgent chat path (Phase 2 migration)
|
package/dist/agent/assistant.js
CHANGED
|
@@ -2681,6 +2681,28 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
|
|
|
2681
2681
|
}
|
|
2682
2682
|
catch { /* telemetry only */ }
|
|
2683
2683
|
}
|
|
2684
|
+
/**
|
|
2685
|
+
* Public accessor for the SDK session ID associated with a sessionKey.
|
|
2686
|
+
* Used by the canonical chat path so consecutive turns resume the
|
|
2687
|
+
* same SDK conversation (the SDK persists sessions to JSONL on disk;
|
|
2688
|
+
* resuming gives the agent native conversation history). Returns ''
|
|
2689
|
+
* when no session exists yet.
|
|
2690
|
+
*/
|
|
2691
|
+
getSdkSessionId(sessionKey) {
|
|
2692
|
+
return this.sessions.get(sessionKey) ?? '';
|
|
2693
|
+
}
|
|
2694
|
+
/**
|
|
2695
|
+
* Persist the SDK session ID for a sessionKey. Called after a runAgent
|
|
2696
|
+
* call returns so the next call can resume the same conversation.
|
|
2697
|
+
* Writes through to disk via the existing saveSessions plumbing.
|
|
2698
|
+
*/
|
|
2699
|
+
setSdkSessionId(sessionKey, sdkSessionId) {
|
|
2700
|
+
if (!sdkSessionId)
|
|
2701
|
+
return;
|
|
2702
|
+
this.sessions.set(sessionKey, sdkSessionId);
|
|
2703
|
+
this.sessionTimestamps.set(sessionKey, new Date());
|
|
2704
|
+
this.saveSessions();
|
|
2705
|
+
}
|
|
2684
2706
|
/**
|
|
2685
2707
|
* Public entry point for triggering auto-memory extraction after an
|
|
2686
2708
|
* exchange. Used by the new runAgent chat path (Phase 2 migration)
|
package/dist/gateway/router.js
CHANGED
|
@@ -1780,45 +1780,72 @@ 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
|
-
//
|
|
1784
|
-
//
|
|
1785
|
-
//
|
|
1786
|
-
//
|
|
1787
|
-
//
|
|
1788
|
-
//
|
|
1789
|
-
//
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
//
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
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()
|
|
1812
|
+
? `[Context — read this for continuity, then respond to the user message below]\n${securityAnnotation}\n[/Context]\n\n`
|
|
1813
|
+
: '';
|
|
1814
|
+
const finalPrompt = turnContextPrefix + chatPrompt;
|
|
1815
|
+
// Resume the prior SDK session when one exists for this
|
|
1816
|
+
// sessionKey. The SDK persists session JSONLs to disk, so
|
|
1817
|
+
// resume works across daemon restarts AND for builder
|
|
1818
|
+
// multi-turn artifact iteration.
|
|
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;
|
|
1804
1825
|
logger.info({
|
|
1805
1826
|
sessionKey: effectiveSessionKey,
|
|
1806
1827
|
profile: resolvedProfile?.slug,
|
|
1807
|
-
path: 'runagent_chat',
|
|
1808
|
-
composioConnected: chatMcp
|
|
1809
|
-
externalConnected: chatMcp
|
|
1828
|
+
path: isBuilderSession ? 'runagent_builder' : 'runagent_chat',
|
|
1829
|
+
composioConnected: chatMcp?.composioConnected.length ?? 0,
|
|
1830
|
+
externalConnected: chatMcp?.externalConnected.length ?? 0,
|
|
1810
1831
|
systemAppendChars: chatSystemAppend.length,
|
|
1832
|
+
turnContextChars: turnContextPrefix.length,
|
|
1833
|
+
resumingSdkSessionId: priorSdkSessionId || null,
|
|
1834
|
+
isBuilderSession,
|
|
1811
1835
|
}, 'Routing chat through runAgent');
|
|
1812
|
-
const runAgentResult = await runAgent(
|
|
1836
|
+
const runAgentResult = await runAgent(finalPrompt, {
|
|
1813
1837
|
sessionKey: effectiveSessionKey,
|
|
1814
1838
|
source: 'chat',
|
|
1815
1839
|
profile: resolvedProfile,
|
|
1816
1840
|
agentManager: this.getAgentManager(),
|
|
1817
1841
|
memoryStore: this.assistant.getMemoryStore?.() ?? null,
|
|
1818
|
-
...(
|
|
1842
|
+
...(builderModel ? { model: builderModel } : {}),
|
|
1819
1843
|
...(maxTurns ? { maxTurns } : {}),
|
|
1844
|
+
...(builderBudget !== undefined ? { maxBudgetUsd: builderBudget } : {}),
|
|
1845
|
+
...(builderAllowedTools ? { allowedTools: builderAllowedTools } : {}),
|
|
1820
1846
|
...(chatSystemAppend ? { systemPromptAppend: chatSystemAppend } : {}),
|
|
1821
|
-
|
|
1847
|
+
...(priorSdkSessionId ? { resumeSessionId: priorSdkSessionId } : {}),
|
|
1848
|
+
...(chatMcp ? { extraMcpServers: chatMcp.servers } : {}),
|
|
1822
1849
|
onText: wrappedOnText,
|
|
1823
1850
|
onToolActivity: ({ tool, input }) => {
|
|
1824
1851
|
toolActivityCount++;
|
|
@@ -1829,11 +1856,18 @@ export class Gateway {
|
|
|
1829
1856
|
},
|
|
1830
1857
|
abortSignal: chatAc.signal,
|
|
1831
1858
|
});
|
|
1859
|
+
// Persist the SDK session ID so the next turn resumes the
|
|
1860
|
+
// same conversation. Survives daemon restarts via SESSIONS_FILE.
|
|
1861
|
+
if (runAgentResult.sessionId) {
|
|
1862
|
+
this.assistant.setSdkSessionId(effectiveSessionKey, runAgentResult.sessionId);
|
|
1863
|
+
}
|
|
1832
1864
|
clearTimeout(chatTimer);
|
|
1833
1865
|
clearTimeout(hardWallTimer);
|
|
1834
|
-
// 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.
|
|
1835
1869
|
const memoryStore = this.assistant.getMemoryStore?.();
|
|
1836
|
-
if (memoryStore) {
|
|
1870
|
+
if (memoryStore && !isBuilderSession) {
|
|
1837
1871
|
try {
|
|
1838
1872
|
memoryStore.saveTurn(effectiveSessionKey, 'user', originalText);
|
|
1839
1873
|
memoryStore.saveTurn(effectiveSessionKey, 'assistant', runAgentResult.text);
|
|
@@ -1842,10 +1876,13 @@ export class Gateway {
|
|
|
1842
1876
|
logger.debug({ err }, 'chat: transcript mirror failed (non-fatal)');
|
|
1843
1877
|
}
|
|
1844
1878
|
}
|
|
1845
|
-
// Fire auto-memory extraction in the background
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
.
|
|
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
|
+
}
|
|
1849
1886
|
// Auth recovered if we got a clean response.
|
|
1850
1887
|
this.clearAuthFailure();
|
|
1851
1888
|
logger.info({
|