clementine-agent 1.18.44 → 1.18.45
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.
|
@@ -277,6 +277,13 @@ export declare class PersonalAssistant {
|
|
|
277
277
|
private memoryExtractionKey;
|
|
278
278
|
private assessMemoryExtraction;
|
|
279
279
|
private logMemoryExtractionSkip;
|
|
280
|
+
/**
|
|
281
|
+
* Public entry point for triggering auto-memory extraction after an
|
|
282
|
+
* exchange. Used by the new runAgent chat path (Phase 2 migration)
|
|
283
|
+
* so it can keep the existing memory-extraction behavior without
|
|
284
|
+
* having to recreate the surrounding plumbing.
|
|
285
|
+
*/
|
|
286
|
+
triggerMemoryExtractionPostExchange(userMessage: string, assistantResponse: string, sessionKey?: string, profile?: AgentProfile): Promise<void>;
|
|
280
287
|
private spawnMemoryExtraction;
|
|
281
288
|
private static readonly MEMORY_TOOL_NAMES;
|
|
282
289
|
private extractMemory;
|
package/dist/agent/assistant.js
CHANGED
|
@@ -4883,6 +4883,15 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
|
|
|
4883
4883
|
}
|
|
4884
4884
|
catch { /* telemetry only */ }
|
|
4885
4885
|
}
|
|
4886
|
+
/**
|
|
4887
|
+
* Public entry point for triggering auto-memory extraction after an
|
|
4888
|
+
* exchange. Used by the new runAgent chat path (Phase 2 migration)
|
|
4889
|
+
* so it can keep the existing memory-extraction behavior without
|
|
4890
|
+
* having to recreate the surrounding plumbing.
|
|
4891
|
+
*/
|
|
4892
|
+
async triggerMemoryExtractionPostExchange(userMessage, assistantResponse, sessionKey, profile) {
|
|
4893
|
+
return this.spawnMemoryExtraction(userMessage, assistantResponse, sessionKey, profile);
|
|
4894
|
+
}
|
|
4886
4895
|
async spawnMemoryExtraction(userMessage, assistantResponse, sessionKey, profile) {
|
|
4887
4896
|
// Guard: skip memory extraction if the user message looks like injection
|
|
4888
4897
|
const memScan = scanner.scan(userMessage);
|
|
@@ -66,6 +66,17 @@ export interface RunAgentOptions {
|
|
|
66
66
|
allowedTools?: string[];
|
|
67
67
|
/** Optional CLAUDE.md / project setting source. Defaults to ['project']. */
|
|
68
68
|
settingSources?: ('project' | 'user' | 'local')[];
|
|
69
|
+
/** Additional MCP servers to merge with the always-on clementine-tools
|
|
70
|
+
* server. Use to wire Composio + claude.ai integrations on chat-path
|
|
71
|
+
* invocations that need Outlook/Salesforce/etc. */
|
|
72
|
+
extraMcpServers?: Record<string, {
|
|
73
|
+
type: 'stdio' | 'http' | 'sse';
|
|
74
|
+
command?: string;
|
|
75
|
+
args?: string[];
|
|
76
|
+
env?: Record<string, string>;
|
|
77
|
+
url?: string;
|
|
78
|
+
headers?: Record<string, string>;
|
|
79
|
+
}>;
|
|
69
80
|
}
|
|
70
81
|
export interface RunAgentResult {
|
|
71
82
|
/** Final text response from the agent. */
|
package/dist/agent/run-agent.js
CHANGED
|
@@ -124,6 +124,9 @@ export async function runAgent(prompt, opts) {
|
|
|
124
124
|
// list references mcp__clementine-tools__* that don't exist in the
|
|
125
125
|
// session, and the agent falls back to reading raw JSON files.
|
|
126
126
|
const subprocessEnv = buildRunAgentEnv();
|
|
127
|
+
// SDK accepts a Record<string, McpServerConfig> here. We cast on
|
|
128
|
+
// assignment because we mix the always-on Clementine stdio server
|
|
129
|
+
// with caller-supplied servers of various types.
|
|
127
130
|
const mcpServers = {
|
|
128
131
|
[TOOLS_SERVER]: {
|
|
129
132
|
type: 'stdio',
|
|
@@ -136,6 +139,7 @@ export async function runAgent(prompt, opts) {
|
|
|
136
139
|
CLEMENTINE_INTERACTION_SOURCE: source === 'cron' || source === 'heartbeat' ? 'autonomous' : 'interactive',
|
|
137
140
|
},
|
|
138
141
|
},
|
|
142
|
+
...(opts.extraMcpServers ?? {}),
|
|
139
143
|
};
|
|
140
144
|
// Apply 1M-context env normalization (existing infra)
|
|
141
145
|
const sdkOptionsRaw = {
|
|
@@ -144,7 +148,9 @@ export async function runAgent(prompt, opts) {
|
|
|
144
148
|
: { type: 'preset', preset: 'claude_code' },
|
|
145
149
|
settingSources: opts.settingSources ?? ['project'],
|
|
146
150
|
agents,
|
|
147
|
-
|
|
151
|
+
// SDK's McpServerConfig is a union; cast at the boundary since
|
|
152
|
+
// callers can mix stdio + http + sse server shapes.
|
|
153
|
+
mcpServers: mcpServers,
|
|
148
154
|
allowedTools,
|
|
149
155
|
permissionMode: 'bypassPermissions',
|
|
150
156
|
cwd: BASE_DIR,
|
package/dist/gateway/router.js
CHANGED
|
@@ -2088,6 +2088,79 @@ export class Gateway {
|
|
|
2088
2088
|
delete sessState.pendingInterrupt;
|
|
2089
2089
|
}
|
|
2090
2090
|
try {
|
|
2091
|
+
// ── Phase 2: opt-in canonical SDK chat path ──────────────────
|
|
2092
|
+
// When CLEMENTINE_USE_RUNAGENT_CHAT=1 is set, route through
|
|
2093
|
+
// the new runAgent() wrapper instead of the legacy
|
|
2094
|
+
// assistant.chat path. This is the SDK-canonical pattern
|
|
2095
|
+
// (one query() call, agents map for subagents, no
|
|
2096
|
+
// wrapper layers). Today's Phase 2 connects only the
|
|
2097
|
+
// Clementine MCP server — Composio/external integrations
|
|
2098
|
+
// come in Phase 3. Useful for testing the new path on
|
|
2099
|
+
// tool-light sessions like cron-fix or memory queries.
|
|
2100
|
+
//
|
|
2101
|
+
// The legacy path (default) keeps full Composio/external
|
|
2102
|
+
// routing + all post-response handlers, so this flag is
|
|
2103
|
+
// safe to leave off until we're ready.
|
|
2104
|
+
if (process.env.CLEMENTINE_USE_RUNAGENT_CHAT === '1'
|
|
2105
|
+
&& this.isTrustedPersonalSession(sessionKey)
|
|
2106
|
+
&& !sessState.pendingInterrupt) {
|
|
2107
|
+
const { runAgent } = await import('../agent/run-agent.js');
|
|
2108
|
+
logger.info({
|
|
2109
|
+
sessionKey: effectiveSessionKey,
|
|
2110
|
+
profile: resolvedProfile?.slug,
|
|
2111
|
+
path: 'runagent_chat',
|
|
2112
|
+
}, 'Phase 2: routing chat through runAgent');
|
|
2113
|
+
try {
|
|
2114
|
+
const runAgentResult = await runAgent(originalText, {
|
|
2115
|
+
sessionKey: effectiveSessionKey,
|
|
2116
|
+
source: 'chat',
|
|
2117
|
+
profile: resolvedProfile,
|
|
2118
|
+
agentManager: this.getAgentManager(),
|
|
2119
|
+
memoryStore: this.assistant.getMemoryStore?.() ?? null,
|
|
2120
|
+
onText: wrappedOnText,
|
|
2121
|
+
onToolActivity: ({ tool, input }) => {
|
|
2122
|
+
toolActivityCount++;
|
|
2123
|
+
if (wrappedOnToolActivity) {
|
|
2124
|
+
return wrappedOnToolActivity(tool, input);
|
|
2125
|
+
}
|
|
2126
|
+
return undefined;
|
|
2127
|
+
},
|
|
2128
|
+
abortSignal: chatAc.signal,
|
|
2129
|
+
});
|
|
2130
|
+
clearTimeout(chatTimer);
|
|
2131
|
+
clearTimeout(hardWallTimer);
|
|
2132
|
+
// Mirror transcript so memory + recall continue working.
|
|
2133
|
+
const memoryStore = this.assistant.getMemoryStore?.();
|
|
2134
|
+
if (memoryStore) {
|
|
2135
|
+
try {
|
|
2136
|
+
memoryStore.saveTurn(effectiveSessionKey, 'user', originalText);
|
|
2137
|
+
memoryStore.saveTurn(effectiveSessionKey, 'assistant', runAgentResult.text);
|
|
2138
|
+
}
|
|
2139
|
+
catch (err) {
|
|
2140
|
+
logger.debug({ err }, 'runAgent chat: transcript mirror failed (non-fatal)');
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
// Fire auto-memory extraction in the background so
|
|
2144
|
+
// MEMORY.md continues to update like the legacy path.
|
|
2145
|
+
this.assistant
|
|
2146
|
+
.triggerMemoryExtractionPostExchange(originalText, runAgentResult.text, effectiveSessionKey, resolvedProfile)
|
|
2147
|
+
.catch(err => logger.debug({ err, sessionKey: effectiveSessionKey }, 'runAgent chat: auto-memory failed (non-fatal)'));
|
|
2148
|
+
logger.info({
|
|
2149
|
+
sessionKey: effectiveSessionKey,
|
|
2150
|
+
totalMs: Date.now() - tInnerStart,
|
|
2151
|
+
routedVia: 'runagent_chat',
|
|
2152
|
+
numTurns: runAgentResult.numTurns,
|
|
2153
|
+
cost: Number(runAgentResult.totalCostUsd.toFixed(4)),
|
|
2154
|
+
responseLen: runAgentResult.text.length,
|
|
2155
|
+
}, 'chat:latency');
|
|
2156
|
+
return runAgentResult.text;
|
|
2157
|
+
}
|
|
2158
|
+
catch (err) {
|
|
2159
|
+
logger.warn({ err, sessionKey: effectiveSessionKey }, 'runAgent chat path failed — falling back to legacy chat');
|
|
2160
|
+
// Fall through to the legacy chat path so the user
|
|
2161
|
+
// still gets a response.
|
|
2162
|
+
}
|
|
2163
|
+
}
|
|
2091
2164
|
// ── Pre-LLM plan routing (Gap #3 from orchestration audit) ──
|
|
2092
2165
|
// When the user's text clearly maps to multi-step parallel
|
|
2093
2166
|
// work, route through the orchestrator BEFORE the main agent
|