@link-assistant/agent 0.16.18 → 0.17.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/agent",
3
- "version": "0.16.18",
3
+ "version": "0.17.0",
4
4
  "description": "A minimal, public domain AI CLI agent compatible with OpenCode's JSON interface. Bun-only runtime.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/flag/flag.ts CHANGED
@@ -103,13 +103,19 @@ export namespace Flag {
103
103
  }
104
104
 
105
105
  // Session summarization configuration
106
- // When disabled, session summaries will not be generated
107
- // This saves tokens and prevents rate limit issues with free tier models
108
- // See: https://github.com/link-assistant/agent/issues/179
109
- export let SUMMARIZE_SESSION = truthyCompat(
110
- 'LINK_ASSISTANT_AGENT_SUMMARIZE_SESSION',
111
- 'AGENT_SUMMARIZE_SESSION'
112
- );
106
+ // Enabled by default - generates AI-powered session summaries using the same model
107
+ // Can be disabled with --no-summarize-session or AGENT_SUMMARIZE_SESSION=false
108
+ // See: https://github.com/link-assistant/agent/issues/217
109
+ export let SUMMARIZE_SESSION = (() => {
110
+ const value = (
111
+ getEnv(
112
+ 'LINK_ASSISTANT_AGENT_SUMMARIZE_SESSION',
113
+ 'AGENT_SUMMARIZE_SESSION'
114
+ ) ?? ''
115
+ ).toLowerCase();
116
+ if (value === 'false' || value === '0') return false;
117
+ return true; // Default to true
118
+ })();
113
119
 
114
120
  // Allow setting summarize-session mode programmatically (e.g., from CLI --summarize-session flag)
115
121
  export function setSummarizeSession(value: boolean) {
package/src/index.js CHANGED
@@ -733,8 +733,9 @@ async function main() {
733
733
  })
734
734
  .option('summarize-session', {
735
735
  type: 'boolean',
736
- description: 'Generate AI session summaries',
737
- default: false,
736
+ description:
737
+ 'Generate AI session summaries (default: true). Use --no-summarize-session to disable.',
738
+ default: true,
738
739
  }),
739
740
  handler: async (argv) => {
740
741
  // Check both CLI flag and environment variable for compact JSON mode
@@ -917,7 +918,10 @@ async function main() {
917
918
  if (argv['output-response-model'] === false) {
918
919
  Flag.setOutputResponseModel(false);
919
920
  }
920
- if (argv['summarize-session'] === true) {
921
+ // summarize-session is enabled by default, only set if explicitly disabled
922
+ if (argv['summarize-session'] === false) {
923
+ Flag.setSummarizeSession(false);
924
+ } else {
921
925
  Flag.setSummarizeSession(true);
922
926
  }
923
927
  // retry-on-rate-limits is enabled by default, only set if explicitly disabled
@@ -929,6 +933,15 @@ async function main() {
929
933
  level: Flag.OPENCODE_VERBOSE ? 'DEBUG' : 'INFO',
930
934
  compactJson: isCompact,
931
935
  });
936
+
937
+ // Monkey-patch globalThis.fetch for raw HTTP logging in --verbose mode.
938
+ // Catches ALL HTTP calls regardless of AI SDK fetch passthrough. (#217)
939
+ if (!globalThis.__agentVerboseFetchInstalled) {
940
+ globalThis.fetch = createVerboseFetch(globalThis.fetch, {
941
+ caller: 'global',
942
+ });
943
+ globalThis.__agentVerboseFetchInstalled = true;
944
+ }
932
945
  })
933
946
  .fail((msg, err, yargs) => {
934
947
  // Handle errors from command handlers
@@ -1201,25 +1201,23 @@ export namespace Provider {
1201
1201
  sessionID: provider.id,
1202
1202
  });
1203
1203
 
1204
- // Wrap fetch with verbose HTTP logging for debugging provider issues.
1205
- // IMPORTANT: The verbose check is done at call time (not SDK creation time)
1206
- // because the SDK is cached and Flag.OPENCODE_VERBOSE may change after creation.
1207
- // When verbose is disabled, the wrapper is a no-op passthrough with negligible overhead.
1208
- // See: https://github.com/link-assistant/agent/issues/200
1209
- // See: https://github.com/link-assistant/agent/issues/206
1204
+ // Verbose HTTP logging is handled by the global fetch monkey-patch
1205
+ // (installed in CLI middleware in index.js). The global patch catches ALL
1206
+ // HTTP calls reliably, regardless of how the AI SDK passes fetch internally.
1207
+ // This provider-level wrapper is kept as a fallback for environments where
1208
+ // the global patch may not be installed (e.g., programmatic use).
1209
+ // See: https://github.com/link-assistant/agent/issues/217
1210
1210
  // See: https://github.com/link-assistant/agent/issues/215
1211
1211
  {
1212
1212
  const innerFetch = options['fetch'];
1213
1213
  let verboseWrapperConfirmed = false;
1214
1214
  let httpCallCount = 0;
1215
1215
 
1216
- // Log at SDK creation time that the fetch wrapper is installed.
1217
- // This runs once per provider SDK creation (not per request).
1218
- // If verbose is off at creation time, the per-request check still applies.
1219
- // See: https://github.com/link-assistant/agent/issues/215
1220
- log.info('verbose HTTP fetch wrapper installed', {
1216
+ log.info('provider SDK fetch chain configured', {
1221
1217
  providerID: provider.id,
1222
1218
  pkg,
1219
+ globalVerboseFetchInstalled:
1220
+ !!globalThis.__agentVerboseFetchInstalled,
1223
1221
  verboseAtCreation: Flag.OPENCODE_VERBOSE,
1224
1222
  });
1225
1223
 
@@ -1227,8 +1225,15 @@ export namespace Provider {
1227
1225
  input: RequestInfo | URL,
1228
1226
  init?: RequestInit
1229
1227
  ): Promise<Response> => {
1230
- // Check verbose flag at call time — not at SDK creation time
1231
- if (!Flag.OPENCODE_VERBOSE) {
1228
+ // Check verbose flag at call time — not at SDK creation time.
1229
+ // When the global fetch monkey-patch is installed, it handles verbose
1230
+ // logging for all calls. The provider wrapper is a fallback for
1231
+ // environments without the global patch.
1232
+ // See: https://github.com/link-assistant/agent/issues/217
1233
+ if (
1234
+ !Flag.OPENCODE_VERBOSE ||
1235
+ globalThis.__agentVerboseFetchInstalled
1236
+ ) {
1232
1237
  return innerFetch(input, init);
1233
1238
  }
1234
1239
 
@@ -1301,8 +1306,8 @@ export namespace Provider {
1301
1306
  : undefined;
1302
1307
  if (bodyStr && typeof bodyStr === 'string') {
1303
1308
  bodyPreview =
1304
- bodyStr.length > 2000
1305
- ? bodyStr.slice(0, 2000) +
1309
+ bodyStr.length > 200000
1310
+ ? bodyStr.slice(0, 200000) +
1306
1311
  `... [truncated, total ${bodyStr.length} chars]`
1307
1312
  : bodyStr;
1308
1313
  }
@@ -1362,7 +1367,7 @@ export namespace Provider {
1362
1367
  // still receives the full stream while we asynchronously log a preview.
1363
1368
  // For non-streaming responses, buffer the body and reconstruct the Response.
1364
1369
  // See: https://github.com/link-assistant/agent/issues/204
1365
- const responseBodyMaxChars = 4000;
1370
+ const responseBodyMaxChars = 200000;
1366
1371
  const contentType = response.headers.get('content-type') ?? '';
1367
1372
  const isStreaming =
1368
1373
  contentType.includes('event-stream') ||
@@ -28,6 +28,14 @@ export namespace SessionCompaction {
28
28
  ),
29
29
  };
30
30
 
31
+ /**
32
+ * Safety margin ratio for compaction trigger.
33
+ * We trigger compaction at 85% of usable context to avoid hitting hard limits.
34
+ * This means we stop 15% before (context - output) tokens.
35
+ * @see https://github.com/link-assistant/agent/issues/217
36
+ */
37
+ export const OVERFLOW_SAFETY_MARGIN = 0.85;
38
+
31
39
  export function isOverflow(input: {
32
40
  tokens: MessageV2.Assistant['tokens'];
33
41
  model: ModelsDev.Model;
@@ -41,7 +49,56 @@ export namespace SessionCompaction {
41
49
  Math.min(input.model.limit.output, SessionPrompt.OUTPUT_TOKEN_MAX) ||
42
50
  SessionPrompt.OUTPUT_TOKEN_MAX;
43
51
  const usable = context - output;
44
- return count > usable;
52
+ const safeLimit = Math.floor(usable * OVERFLOW_SAFETY_MARGIN);
53
+ const overflow = count > safeLimit;
54
+ log.info(() => ({
55
+ message: 'overflow check',
56
+ modelID: input.model.id,
57
+ contextLimit: context,
58
+ outputLimit: output,
59
+ usableContext: usable,
60
+ safeLimit,
61
+ safetyMargin: OVERFLOW_SAFETY_MARGIN,
62
+ currentTokens: count,
63
+ tokensBreakdown: {
64
+ input: input.tokens.input,
65
+ cacheRead: input.tokens.cache.read,
66
+ output: input.tokens.output,
67
+ },
68
+ overflow,
69
+ headroom: safeLimit - count,
70
+ }));
71
+ return overflow;
72
+ }
73
+
74
+ /**
75
+ * Compute context diagnostics for a given model and token usage.
76
+ * Used in step-finish parts to show context usage in JSON output.
77
+ * @see https://github.com/link-assistant/agent/issues/217
78
+ */
79
+ export function contextDiagnostics(input: {
80
+ tokens: { input: number; output: number; cache: { read: number } };
81
+ model: ModelsDev.Model;
82
+ }): MessageV2.ContextDiagnostics | undefined {
83
+ const contextLimit = input.model.limit.context;
84
+ if (contextLimit === 0) return undefined;
85
+ const outputLimit =
86
+ Math.min(input.model.limit.output, SessionPrompt.OUTPUT_TOKEN_MAX) ||
87
+ SessionPrompt.OUTPUT_TOKEN_MAX;
88
+ const usableContext = contextLimit - outputLimit;
89
+ const safeLimit = Math.floor(usableContext * OVERFLOW_SAFETY_MARGIN);
90
+ const currentTokens =
91
+ input.tokens.input + input.tokens.cache.read + input.tokens.output;
92
+ return {
93
+ contextLimit,
94
+ outputLimit,
95
+ usableContext,
96
+ safeLimit,
97
+ safetyMargin: OVERFLOW_SAFETY_MARGIN,
98
+ currentTokens,
99
+ headroom: safeLimit - currentTokens,
100
+ overflow: currentTokens > safeLimit,
101
+ };
45
102
  }
46
103
 
47
104
  export const PRUNE_MINIMUM = 20_000;
@@ -100,10 +157,27 @@ export namespace SessionCompaction {
100
157
  };
101
158
  abort: AbortSignal;
102
159
  }) {
160
+ log.info(() => ({
161
+ message: 'compaction process starting',
162
+ providerID: input.model.providerID,
163
+ modelID: input.model.modelID,
164
+ messageCount: input.messages.length,
165
+ sessionID: input.sessionID,
166
+ }));
103
167
  const model = await Provider.getModel(
104
168
  input.model.providerID,
105
169
  input.model.modelID
106
170
  );
171
+ if (Flag.OPENCODE_VERBOSE) {
172
+ log.info(() => ({
173
+ message: 'compaction model loaded',
174
+ providerID: model.providerID,
175
+ modelID: model.modelID,
176
+ npm: model.npm,
177
+ contextLimit: model.info.limit.context,
178
+ outputLimit: model.info.limit.output,
179
+ }));
180
+ }
107
181
  const system = [...SystemPrompt.summarize(model.providerID)];
108
182
  const msg = (await Session.updateMessage({
109
183
  id: Identifier.ascending('message'),
@@ -156,6 +230,19 @@ export namespace SessionCompaction {
156
230
  );
157
231
  // Defensive check: ensure modelMessages is iterable (AI SDK 6.0.1 compatibility fix)
158
232
  const safeModelMessages = Array.isArray(modelMessages) ? modelMessages : [];
233
+
234
+ if (Flag.OPENCODE_VERBOSE) {
235
+ log.info(() => ({
236
+ message: 'compaction streamText call',
237
+ providerID: model.providerID,
238
+ modelID: model.modelID,
239
+ systemPromptCount: system.length,
240
+ modelMessageCount: safeModelMessages.length,
241
+ filteredMessageCount: input.messages.length - safeModelMessages.length,
242
+ toolCall: model.info.tool_call,
243
+ }));
244
+ }
245
+
159
246
  const result = await processor.process(() =>
160
247
  streamText({
161
248
  onError(error) {
@@ -240,6 +240,27 @@ export namespace MessageV2 {
240
240
  });
241
241
  export type ModelInfo = z.infer<typeof ModelInfo>;
242
242
 
243
+ /**
244
+ * Context diagnostic info for step-finish parts.
245
+ * Shows model context limits and current usage to help debug compaction decisions.
246
+ * @see https://github.com/link-assistant/agent/issues/217
247
+ */
248
+ export const ContextDiagnostics = z
249
+ .object({
250
+ contextLimit: z.number(),
251
+ outputLimit: z.number(),
252
+ usableContext: z.number(),
253
+ safeLimit: z.number(),
254
+ safetyMargin: z.number(),
255
+ currentTokens: z.number(),
256
+ headroom: z.number(),
257
+ overflow: z.boolean(),
258
+ })
259
+ .meta({
260
+ ref: 'ContextDiagnostics',
261
+ });
262
+ export type ContextDiagnostics = z.infer<typeof ContextDiagnostics>;
263
+
243
264
  export const StepFinishPart = PartBase.extend({
244
265
  type: z.literal('step-finish'),
245
266
  reason: z.string(),
@@ -257,6 +278,9 @@ export namespace MessageV2 {
257
278
  // Model info included when --output-response-model is enabled
258
279
  // @see https://github.com/link-assistant/agent/issues/179
259
280
  model: ModelInfo.optional(),
281
+ // Context diagnostics for debugging compaction decisions
282
+ // @see https://github.com/link-assistant/agent/issues/217
283
+ context: ContextDiagnostics.optional(),
260
284
  }).meta({
261
285
  ref: 'StepFinishPart',
262
286
  });
@@ -17,6 +17,7 @@ import { Bus } from '../bus';
17
17
  import { SessionRetry } from './retry';
18
18
  import { SessionStatus } from './status';
19
19
  import { Flag } from '../flag/flag';
20
+ import { SessionCompaction } from './compaction';
20
21
 
21
22
  export namespace SessionProcessor {
22
23
  const DOOM_LOOP_THRESHOLD = 3;
@@ -366,6 +367,22 @@ export namespace SessionProcessor {
366
367
  }
367
368
  : undefined;
368
369
 
370
+ // Compute context diagnostics for JSON output
371
+ // @see https://github.com/link-assistant/agent/issues/217
372
+ const contextDiag = SessionCompaction.contextDiagnostics({
373
+ tokens: usage.tokens,
374
+ model: input.model,
375
+ });
376
+
377
+ if (Flag.OPENCODE_VERBOSE && contextDiag) {
378
+ log.info(() => ({
379
+ message: 'step-finish context diagnostics',
380
+ providerID: input.providerID,
381
+ modelID: input.model.id,
382
+ ...contextDiag,
383
+ }));
384
+ }
385
+
369
386
  await Session.updatePart({
370
387
  id: Identifier.ascending('part'),
371
388
  reason: finishReason,
@@ -376,6 +393,7 @@ export namespace SessionProcessor {
376
393
  tokens: usage.tokens,
377
394
  cost: usage.cost,
378
395
  model: modelInfo,
396
+ context: contextDiag,
379
397
  });
380
398
  await Session.updateMessage(input.assistantMessage);
381
399
  if (snapshot) {
@@ -14,6 +14,7 @@ import { Instance } from '../project/instance';
14
14
  import { Storage } from '../storage/storage';
15
15
  import { Bus } from '../bus';
16
16
  import { Flag } from '../flag/flag';
17
+ import { Token } from '../util/token';
17
18
 
18
19
  export namespace SessionSummary {
19
20
  const log = Log.create({ service: 'session.summary' });
@@ -80,34 +81,89 @@ export namespace SessionSummary {
80
81
  };
81
82
  await Session.updateMessage(userMsg);
82
83
 
83
- // Skip AI-powered summarization if disabled (default)
84
- // See: https://github.com/link-assistant/agent/issues/179
84
+ // Skip AI-powered summarization if disabled
85
+ // See: https://github.com/link-assistant/agent/issues/217
85
86
  if (!Flag.SUMMARIZE_SESSION) {
86
87
  log.info(() => ({
87
88
  message: 'session summarization disabled',
88
- hint: 'Enable with --summarize-session flag or AGENT_SUMMARIZE_SESSION=true',
89
+ hint: 'Enable with --summarize-session flag (enabled by default) or AGENT_SUMMARIZE_SESSION=true',
89
90
  }));
90
91
  return;
91
92
  }
92
93
 
93
94
  const assistantMsg = messages.find((m) => m.info.role === 'assistant')!
94
95
  .info as MessageV2.Assistant;
95
- const small = await Provider.getSmallModel(assistantMsg.providerID);
96
- if (!small) return;
96
+
97
+ // Use the same model as the main session (--model) instead of a small model
98
+ // This ensures consistent behavior and uses the model the user explicitly requested
99
+ // See: https://github.com/link-assistant/agent/issues/217
100
+ log.info(() => ({
101
+ message: 'loading model for summarization',
102
+ providerID: assistantMsg.providerID,
103
+ modelID: assistantMsg.modelID,
104
+ hint: 'Using same model as --model (not a small model)',
105
+ }));
106
+ const model = await Provider.getModel(
107
+ assistantMsg.providerID,
108
+ assistantMsg.modelID
109
+ ).catch(() => null);
110
+ if (!model) {
111
+ log.info(() => ({
112
+ message: 'could not load session model for summarization, skipping',
113
+ providerID: assistantMsg.providerID,
114
+ modelID: assistantMsg.modelID,
115
+ }));
116
+ return;
117
+ }
118
+
119
+ if (Flag.OPENCODE_VERBOSE) {
120
+ log.info(() => ({
121
+ message: 'summarization model loaded',
122
+ providerID: model.providerID,
123
+ modelID: model.modelID,
124
+ npm: model.npm,
125
+ contextLimit: model.info.limit.context,
126
+ outputLimit: model.info.limit.output,
127
+ reasoning: model.info.reasoning,
128
+ toolCall: model.info.tool_call,
129
+ }));
130
+ }
97
131
 
98
132
  const textPart = msgWithParts.parts.find(
99
133
  (p) => p.type === 'text' && !p.synthetic
100
134
  ) as MessageV2.TextPart;
101
135
  if (textPart && !userMsg.summary?.title) {
136
+ const titleMaxTokens = model.info.reasoning ? 1500 : 20;
137
+ const systemPrompts = SystemPrompt.title(model.providerID);
138
+ const userContent = `
139
+ The following is the text to summarize:
140
+ <text>
141
+ ${textPart?.text ?? ''}
142
+ </text>
143
+ `;
144
+
145
+ if (Flag.OPENCODE_VERBOSE) {
146
+ log.info(() => ({
147
+ message: 'generating title via API',
148
+ providerID: model.providerID,
149
+ modelID: model.modelID,
150
+ maxOutputTokens: titleMaxTokens,
151
+ systemPromptCount: systemPrompts.length,
152
+ userContentLength: userContent.length,
153
+ userContentTokenEstimate: Token.estimate(userContent),
154
+ userContentPreview: userContent.substring(0, 500),
155
+ }));
156
+ }
157
+
102
158
  const result = await generateText({
103
- maxOutputTokens: small.info.reasoning ? 1500 : 20,
159
+ maxOutputTokens: titleMaxTokens,
104
160
  providerOptions: ProviderTransform.providerOptions(
105
- small.npm,
106
- small.providerID,
161
+ model.npm,
162
+ model.providerID,
107
163
  {}
108
164
  ),
109
165
  messages: [
110
- ...SystemPrompt.title(small.providerID).map(
166
+ ...systemPrompts.map(
111
167
  (x): ModelMessage => ({
112
168
  role: 'system',
113
169
  content: x,
@@ -115,17 +171,22 @@ export namespace SessionSummary {
115
171
  ),
116
172
  {
117
173
  role: 'user' as const,
118
- content: `
119
- The following is the text to summarize:
120
- <text>
121
- ${textPart?.text ?? ''}
122
- </text>
123
- `,
174
+ content: userContent,
124
175
  },
125
176
  ],
126
- headers: small.info.headers,
127
- model: small.language,
177
+ headers: model.info.headers,
178
+ model: model.language,
128
179
  });
180
+
181
+ if (Flag.OPENCODE_VERBOSE) {
182
+ log.info(() => ({
183
+ message: 'title API response received',
184
+ providerID: model.providerID,
185
+ modelID: model.modelID,
186
+ titleLength: result.text.length,
187
+ usage: result.usage,
188
+ }));
189
+ }
129
190
  log.info(() => ({ message: 'title', title: result.text }));
130
191
  userMsg.summary.title = result.text;
131
192
  await Session.updateMessage(userMsg);
@@ -146,8 +207,24 @@ export namespace SessionSummary {
146
207
  if (!summary || diffs.length > 0) {
147
208
  // Pre-convert messages to ModelMessage format (async in AI SDK 6.0+)
148
209
  const modelMessages = await MessageV2.toModelMessage(messages);
210
+ const conversationContent = JSON.stringify(modelMessages);
211
+
212
+ if (Flag.OPENCODE_VERBOSE) {
213
+ log.info(() => ({
214
+ message: 'generating body summary via API',
215
+ providerID: model.providerID,
216
+ modelID: model.modelID,
217
+ maxOutputTokens: 100,
218
+ conversationLength: conversationContent.length,
219
+ conversationTokenEstimate: Token.estimate(conversationContent),
220
+ messageCount: modelMessages.length,
221
+ diffsCount: diffs.length,
222
+ hasPriorSummary: !!summary,
223
+ }));
224
+ }
225
+
149
226
  const result = await generateText({
150
- model: small.language,
227
+ model: model.language,
151
228
  maxOutputTokens: 100,
152
229
  messages: [
153
230
  {
@@ -155,14 +232,36 @@ export namespace SessionSummary {
155
232
  content: `
156
233
  Summarize the following conversation into 2 sentences MAX explaining what the assistant did and why. Do not explain the user's input. Do not speak in the third person about the assistant.
157
234
  <conversation>
158
- ${JSON.stringify(modelMessages)}
235
+ ${conversationContent}
159
236
  </conversation>
160
237
  `,
161
238
  },
162
239
  ],
163
- headers: small.info.headers,
164
- }).catch(() => {});
165
- if (result) summary = result.text;
240
+ headers: model.info.headers,
241
+ }).catch((err) => {
242
+ if (Flag.OPENCODE_VERBOSE) {
243
+ log.warn(() => ({
244
+ message: 'body summary API call failed',
245
+ providerID: model.providerID,
246
+ modelID: model.modelID,
247
+ error: err instanceof Error ? err.message : String(err),
248
+ stack: err instanceof Error ? err.stack : undefined,
249
+ }));
250
+ }
251
+ return undefined;
252
+ });
253
+ if (result) {
254
+ if (Flag.OPENCODE_VERBOSE) {
255
+ log.info(() => ({
256
+ message: 'body summary API response received',
257
+ providerID: model.providerID,
258
+ modelID: model.modelID,
259
+ summaryLength: result.text.length,
260
+ usage: result.usage,
261
+ }));
262
+ }
263
+ summary = result.text;
264
+ }
166
265
  }
167
266
  userMsg.summary.body = summary;
168
267
  log.info(() => ({ message: 'body', body: summary }));
@@ -64,7 +64,7 @@ export function sanitizeHeaders(
64
64
  */
65
65
  export function bodyPreview(
66
66
  body: BodyInit | null | undefined,
67
- maxChars = 2000
67
+ maxChars = 200000
68
68
  ): string | undefined {
69
69
  if (!body) return undefined;
70
70
 
@@ -89,9 +89,9 @@ export function bodyPreview(
89
89
  export interface VerboseFetchOptions {
90
90
  /** Identifier for the caller (e.g. 'webfetch', 'auth-plugins', 'config') */
91
91
  caller: string;
92
- /** Maximum chars for response body preview (default: 4000) */
92
+ /** Maximum chars for response body preview (default: 200000) */
93
93
  responseBodyMaxChars?: number;
94
- /** Maximum chars for request body preview (default: 2000) */
94
+ /** Maximum chars for request body preview (default: 200000) */
95
95
  requestBodyMaxChars?: number;
96
96
  }
97
97
 
@@ -113,8 +113,8 @@ export function createVerboseFetch(
113
113
  ): typeof fetch {
114
114
  const {
115
115
  caller,
116
- responseBodyMaxChars = 4000,
117
- requestBodyMaxChars = 2000,
116
+ responseBodyMaxChars = 200000,
117
+ requestBodyMaxChars = 200000,
118
118
  } = options;
119
119
 
120
120
  return async (