clementine-agent 1.18.25 → 1.18.27

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.
@@ -33,6 +33,7 @@ export declare function contextThrashRecoveryNotice(): string;
33
33
  export declare function buildContextThrashRecoveryPrompt(userRequest: string, priorFailureText?: string): string;
34
34
  /** Format a millisecond duration as a human-friendly "X ago" string. */
35
35
  export declare function formatTimeAgo(ms: number): string;
36
+ export declare function scrubInternalContextBlocks(text: string): string;
36
37
  export declare function looksLikeOneMillionContextError(value: unknown): boolean;
37
38
  export declare function oneMillionContextRecoveryMessage(): string;
38
39
  export declare function looksLikeProviderApiErrorResponse(value: unknown): boolean;
@@ -123,7 +124,7 @@ export declare class PersonalAssistant {
123
124
  }>;
124
125
  updatedAt: string;
125
126
  };
126
- /** Inject a background work result into the session so the next chat naturally references it. */
127
+ /** Inject a background work result into the session as silent follow-up context. */
127
128
  injectPendingContext(sessionKey: string, userPrompt: string, result: string): void;
128
129
  private initMemoryStore;
129
130
  /**
@@ -321,7 +322,9 @@ export declare class PersonalAssistant {
321
322
  * a query. Used to give the DM session visibility of cron/heartbeat outputs
322
323
  * so follow-up conversation has context.
323
324
  */
324
- injectContext(sessionKey: string, userText: string, assistantText: string): void;
325
+ injectContext(sessionKey: string, userText: string, assistantText: string, opts?: {
326
+ pending?: boolean;
327
+ }): void;
325
328
  getRecentActivity(sinceIso: string, maxEntries?: number): Array<{
326
329
  sessionKey: string;
327
330
  role: string;
@@ -373,6 +373,13 @@ function getContextWindow(model) {
373
373
  function capContextBlock(text, maxChars) {
374
374
  return capOutput(String(text ?? ''), maxChars);
375
375
  }
376
+ export function scrubInternalContextBlocks(text) {
377
+ return text
378
+ .replace(/\[Context governance:[^\]]*\][\s\S]*?\[\/Context governance:[^\]]*\]\s*/gi, '')
379
+ .replace(/\[Active working set\][\s\S]*?\[\/Active working set\]\s*/gi, '')
380
+ .replace(/\[Recent proactive notification context\][\s\S]*?\[\/Recent proactive notification context\]\s*/gi, '')
381
+ .trim();
382
+ }
376
383
  function capContextItem(text) {
377
384
  return capContextBlock(text, CRON_PROGRESS_ITEM_MAX_CHARS).replace(/\s+/g, ' ').trim();
378
385
  }
@@ -1182,7 +1189,7 @@ export class PersonalAssistant {
1182
1189
  getMcpStatus() {
1183
1190
  return { servers: this._lastMcpStatus, updatedAt: this._lastMcpStatusTime };
1184
1191
  }
1185
- /** Inject a background work result into the session so the next chat naturally references it. */
1192
+ /** Inject a background work result into the session as silent follow-up context. */
1186
1193
  injectPendingContext(sessionKey, userPrompt, result) {
1187
1194
  const pending = this.pendingContext.get(sessionKey) ?? [];
1188
1195
  pending.push({ user: userPrompt.slice(0, 500), assistant: result.slice(0, 2000) });
@@ -3043,7 +3050,10 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
3043
3050
  contextLines.push(`[${user}]\n${assistant}`);
3044
3051
  }
3045
3052
  effectivePrompt =
3046
- `[Since we last talked, you did some background work. Naturally mention what happened lead with anything that needs attention, briefly note routine completions. Don't dump raw tool calls or list job names. Be conversational.\nBackground:\n${contextLines.join('\n\n')}]\n\n${effectivePrompt}`;
3053
+ `[Background work contextREFERENCE ONLY, not new user input.\n` +
3054
+ `Use this silently to understand follow-ups. Mention it only if the user asks about status, results, fixes, or what changed, or if it is a new urgent blocker. ` +
3055
+ `Do not lead greetings or casual small talk with stale heartbeat, cron, or background-task details.\n` +
3056
+ `Background:\n${contextLines.join('\n\n')}]\n\n${effectivePrompt}`;
3047
3057
  }
3048
3058
  }
3049
3059
  // Inject stall nudge if the previous query for this session showed stall signals
@@ -3070,6 +3080,7 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
3070
3080
  const CHAT_TIMEOUT_MS = 30 * 60 * 1000;
3071
3081
  const guard = new StallGuard();
3072
3082
  let [responseText, sessionId] = await this.runQuery(effectivePrompt, key, onText, model, profile, securityAnnotation, effectiveMaxTurns, projectOverride, onToolActivity, verboseLevel, abortController, guard, CHAT_TIMEOUT_MS, intent, turnPolicy, toolset);
3083
+ responseText = scrubInternalContextBlocks(responseText);
3073
3084
  // If we got a context-length / prompt-too-long error, retry with a fresh session
3074
3085
  const errLower = responseText.toLowerCase();
3075
3086
  const isContextOverflow = errLower.includes('prompt is too long') ||
@@ -6184,7 +6195,7 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
6184
6195
  * a query. Used to give the DM session visibility of cron/heartbeat outputs
6185
6196
  * so follow-up conversation has context.
6186
6197
  */
6187
- injectContext(sessionKey, userText, assistantText) {
6198
+ injectContext(sessionKey, userText, assistantText, opts = {}) {
6188
6199
  const trimmedUser = capContextBlock(userText, INJECTED_CONTEXT_MAX_CHARS);
6189
6200
  const trimmedAssistant = capContextBlock(assistantText, INJECTED_CONTEXT_MAX_CHARS);
6190
6201
  // Add to in-memory exchange history
@@ -6199,12 +6210,14 @@ You have a cost budget per message — not a hard turn limit. Work until the tas
6199
6210
  // Queue as pending context so the next chat() prepends it even
6200
6211
  // when an active SDK session exists (session recovery alone won't
6201
6212
  // help because the SDK session has no knowledge of this exchange).
6202
- const pending = this.pendingContext.get(sessionKey) ?? [];
6203
- pending.push({ user: trimmedUser, assistant: trimmedAssistant });
6204
- // Keep at most 3 pending to avoid bloating the next prompt
6205
- if (pending.length > 3)
6206
- pending.shift();
6207
- this.pendingContext.set(sessionKey, pending);
6213
+ if (opts.pending !== false) {
6214
+ const pending = this.pendingContext.get(sessionKey) ?? [];
6215
+ pending.push({ user: trimmedUser, assistant: trimmedAssistant });
6216
+ // Keep at most 3 pending to avoid bloating the next prompt
6217
+ if (pending.length > 3)
6218
+ pending.shift();
6219
+ this.pendingContext.set(sessionKey, pending);
6220
+ }
6208
6221
  this.sessionTimestamps.set(sessionKey, new Date());
6209
6222
  this.saveSessions();
6210
6223
  // Persist to transcript store
@@ -67,7 +67,7 @@ export const TOOL_BUNDLES = [
67
67
  },
68
68
  {
69
69
  id: 'github',
70
- patterns: [/\b(github|pull request|pull requests|prs?|issues?)\b/i],
70
+ patterns: [/\b(github|pull request|pull requests|prs?)\b/i, /\b(repo|github)\s+issues?\b/i],
71
71
  externalMcpServers: ['github'],
72
72
  composioToolkits: ['github'],
73
73
  },