clementine-agent 1.18.208 → 1.18.209

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.
@@ -212,6 +212,11 @@ function extractProviderLogId(raw) {
212
212
  ?? (obj.data && typeof obj.data === 'object' ? extractProviderLogId(obj.data) : undefined);
213
213
  }
214
214
  function statusPhrase(call) {
215
+ if (call.result && !call.result.successful) {
216
+ const error = call.result.error ? `: ${call.result.error}` : '';
217
+ const status = call.result.statusCode ? ` (${call.result.statusCode})` : '';
218
+ return `failed${status}${error}`.slice(0, 260);
219
+ }
215
220
  const status = call.result?.statusCode;
216
221
  if (status && toolKindLabel(call.toolName) === 'email sends')
217
222
  return `accepted (${status})`;
@@ -289,10 +294,20 @@ export function formatOverflowRecoveryMessage(summary) {
289
294
  || summary.failedDelegations.length > 0
290
295
  || summary.pendingDelegations.length > 0) {
291
296
  lines.push('Needs attention:');
292
- if (summary.failedSideEffects.length > 0)
293
- lines.push(...formatGroupedLines('failed', summary.failedSideEffects));
294
- if (summary.pendingSideEffects.length > 0)
295
- lines.push(...formatGroupedLines('started, no confirmation', summary.pendingSideEffects));
297
+ if (summary.failedSideEffects.length > 0) {
298
+ for (const call of summary.failedSideEffects.slice(0, 5))
299
+ lines.push(formatDetailedCall(call));
300
+ if (summary.failedSideEffects.length > 5) {
301
+ lines.push(`- ...and ${summary.failedSideEffects.length - 5} more failed side effects`);
302
+ }
303
+ }
304
+ if (summary.pendingSideEffects.length > 0) {
305
+ for (const call of summary.pendingSideEffects.slice(0, 5))
306
+ lines.push(formatDetailedCall(call));
307
+ if (summary.pendingSideEffects.length > 5) {
308
+ lines.push(`- ...and ${summary.pendingSideEffects.length - 5} more side effects started with no confirmation`);
309
+ }
310
+ }
296
311
  for (const call of summary.failedDelegations.slice(0, 5))
297
312
  lines.push(formatDelegationCall(call, 'failed'));
298
313
  for (const call of summary.pendingDelegations.slice(0, 5))
@@ -312,10 +327,14 @@ function formatDetailedCall(call) {
312
327
  const recipients = extractRecipients(call.input);
313
328
  const subject = extractSubject(call.input);
314
329
  const filePath = extractFilePath(call.input, call.result?.raw);
330
+ const command = call.toolName === 'Bash'
331
+ ? firstString(call.input.command)?.replace(/\s+/g, ' ').slice(0, 180)
332
+ : undefined;
315
333
  const logId = call.result ? extractProviderLogId(call.result.raw) : undefined;
316
334
  const parts = [
317
335
  toolKindLabel(call.toolName),
318
336
  filePath ? `file ${filePath}` : undefined,
337
+ command ? `command "${command}"` : undefined,
319
338
  recipients.length ? `to ${recipients.join(', ')}` : undefined,
320
339
  subject ? `subject "${subject}"` : undefined,
321
340
  call.result ? statusPhrase(call) : 'started, no confirmation',
@@ -85,6 +85,8 @@ const BASH_SIDE_EFFECT_PATTERNS = [
85
85
  /\btee\b/i,
86
86
  /\bgit\s+(commit|push|merge|rebase|tag)\b/i,
87
87
  /\bnpm\s+(install|publish|update)\b/i,
88
+ /\bnetlify\s+deploy\b/i,
89
+ /\bvercel\s+(deploy|--prod)\b/i,
88
90
  /\b(?:sf|sfdx)\s+data\s+(update|delete|create|upsert)\b/i,
89
91
  /\b(?:sf|sfdx)\s+org\s+(create|delete)\b/i,
90
92
  /\bcurl\b.*(?:-X|--request)\s*(POST|PUT|DELETE|PATCH)\b/i,
@@ -200,10 +202,26 @@ function findError(value) {
200
202
  }
201
203
  return undefined;
202
204
  }
205
+ function findStringError(value) {
206
+ if (typeof value !== 'string')
207
+ return undefined;
208
+ const text = value.trim();
209
+ if (!text)
210
+ return undefined;
211
+ const firstLine = text.split(/\r?\n/).map((line) => line.trim()).find(Boolean) ?? text;
212
+ const prefixed = firstLine.match(/^(?:›\s*)?(?:error|failed|fatal):\s+(.+)$/i);
213
+ if (prefixed)
214
+ return prefixed[1]?.slice(0, 500);
215
+ const known = text.match(/\b(Project not found\. Please rerun "netlify link"|command not found|No such file or directory|deploy failed|build failed)\b/i);
216
+ return known?.[1]?.slice(0, 500);
217
+ }
203
218
  export function isToolResultSuccessful(rawResult, sdkIsError = false) {
204
219
  if (sdkIsError)
205
220
  return { successful: false, reason: 'sdk-is-error' };
206
221
  const result = normalizeResultPayload(rawResult);
222
+ const stringError = findStringError(result);
223
+ if (stringError)
224
+ return { successful: false, reason: 'tool-result-error-string', error: stringError };
207
225
  if (result && typeof result === 'object') {
208
226
  const obj = result;
209
227
  if (obj.is_error === true || obj.isError === true) {
package/dist/config.js CHANGED
@@ -553,9 +553,10 @@ export const TOOL_OUTPUT_GUARD = {
553
553
  hardLimitBytes: getEnvOrJsonNumber('TOOL_OUTPUT_GUARD_HARD_BYTES', json.toolOutputGuard?.hardLimitBytes, 200_000),
554
554
  adaptive: boolEnv('TOOL_OUTPUT_GUARD_ADAPTIVE', json.toolOutputGuard?.adaptive, true),
555
555
  // Agent results are especially dangerous: even a "medium" subagent report
556
- // refills the parent orchestrator after compaction. Keep the handoff tight;
556
+ // refills the parent orchestrator after compaction. Full-file `Read` calls
557
+ // are the same failure class for generated HTML/reports. Keep both tight;
557
558
  // the full result is archived by tool-output-guard.
558
- perTool: { Agent: 4_000, ...(json.toolOutputGuard?.perTool ?? {}) },
559
+ perTool: { Agent: 4_000, Read: 10_000, ...(json.toolOutputGuard?.perTool ?? {}) },
559
560
  };
560
561
  export const DEFAULT_MODEL_TIER = (getEnvOrJson('DEFAULT_MODEL_TIER', json.models?.default, 'sonnet'));
561
562
  export const MODEL = MODELS[DEFAULT_MODEL_TIER] ?? MODELS.sonnet;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clementine-agent",
3
- "version": "1.18.208",
3
+ "version": "1.18.209",
4
4
  "description": "Clementine — Personal AI Assistant (TypeScript)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",