@ottocode/server 0.1.234 → 0.1.236

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.
@@ -1,12 +1,11 @@
1
- import { hasToolCall, stepCountIs, streamText } from 'ai';
2
- import { messages, messageParts, sessions } from '@ottocode/database/schema';
1
+ import { hasToolCall, streamText } from 'ai';
2
+ import { messageParts } from '@ottocode/database/schema';
3
3
  import { eq } from 'drizzle-orm';
4
4
  import { publish, subscribe } from '../../events/bus.ts';
5
- import { debugLog, time } from '../debug/index.ts';
5
+ import { time } from '../debug/index.ts';
6
6
  import { toErrorPayload } from '../errors/handling.ts';
7
7
  import {
8
8
  type RunOpts,
9
- enqueueAssistantRun,
10
9
  setRunning,
11
10
  dequeueJob,
12
11
  cleanupSession,
@@ -41,7 +40,6 @@ import {
41
40
  createOauthCodexTextGuardState,
42
41
  consumeOauthCodexTextDelta,
43
42
  } from '../stream/text-guard.ts';
44
- import { decideOauthCodexContinuation } from './oauth-codex-continuation.ts';
45
43
  import { createTurnDumpCollector } from '../debug/turn-dump.ts';
46
44
 
47
45
  export {
@@ -56,17 +54,9 @@ export {
56
54
  const DEFAULT_TRACED_TOOL_INPUTS = new Set(['write', 'apply_patch']);
57
55
 
58
56
  function shouldTraceToolInput(name: string): boolean {
59
- const raw = process.env.OTTO_DEBUG_TOOL_INPUT?.trim();
60
- if (!raw) return false;
61
- const normalized = raw.toLowerCase();
62
- if (['1', 'true', 'yes', 'on', 'all'].includes(normalized)) {
63
- return DEFAULT_TRACED_TOOL_INPUTS.has(name);
64
- }
65
- const tokens = raw
66
- .split(/[\s,]+/)
67
- .map((token) => token.trim().toLowerCase())
68
- .filter(Boolean);
69
- return tokens.includes('all') || tokens.includes(name.toLowerCase());
57
+ void DEFAULT_TRACED_TOOL_INPUTS;
58
+ void name;
59
+ return false;
70
60
  }
71
61
 
72
62
  function summarizeTraceValue(value: unknown, max = 160): string {
@@ -89,11 +79,7 @@ export async function runSessionLoop(sessionId: string) {
89
79
 
90
80
  try {
91
81
  await runAssistant(job);
92
- } catch (_err) {
93
- debugLog(
94
- `[RUNNER] runAssistant threw (swallowed to keep loop alive): ${_err instanceof Error ? _err.message : String(_err)}`,
95
- );
96
- }
82
+ } catch {}
97
83
  }
98
84
 
99
85
  setRunning(sessionId, false);
@@ -101,12 +87,6 @@ export async function runSessionLoop(sessionId: string) {
101
87
  }
102
88
 
103
89
  async function runAssistant(opts: RunOpts) {
104
- const separator = '='.repeat(72);
105
- debugLog(separator);
106
- debugLog(
107
- `[RUNNER] Starting turn for session ${opts.sessionId}, message ${opts.assistantMessageId}`,
108
- );
109
-
110
90
  const setup = await setupRunner(opts);
111
91
  const {
112
92
  cfg,
@@ -203,10 +183,6 @@ async function runAssistant(opts: RunOpts) {
203
183
  }
204
184
  }
205
185
 
206
- debugLog(
207
- `[RUNNER] messagesWithSystemInstructions length: ${messagesWithSystemInstructions.length}`,
208
- );
209
-
210
186
  const dump = createTurnDumpCollector({
211
187
  sessionId: opts.sessionId,
212
188
  messageId: opts.assistantMessageId,
@@ -282,11 +258,7 @@ async function runAssistant(opts: RunOpts) {
282
258
  try {
283
259
  const name = (evt.payload as { name?: string } | undefined)?.name;
284
260
  if (name === 'finish') _finishObserved = true;
285
- } catch (err) {
286
- debugLog(
287
- `[RUNNER] finish observer error: ${err instanceof Error ? err.message : String(err)}`,
288
- );
289
- }
261
+ } catch {}
290
262
  }
291
263
  });
292
264
 
@@ -364,10 +336,9 @@ async function runAssistant(opts: RunOpts) {
364
336
  const onFinish = createFinishHandler(opts, db, completeAssistantMessage);
365
337
  const isCopilotResponsesApi =
366
338
  opts.provider === 'copilot' && !opts.model.startsWith('gpt-5-mini');
367
- const stopWhenCondition =
368
- isOpenAIOAuth || isCopilotResponsesApi
369
- ? stepCountIs(20)
370
- : hasToolCall('finish');
339
+ const stopWhenCondition = isCopilotResponsesApi
340
+ ? undefined
341
+ : hasToolCall('finish');
371
342
 
372
343
  try {
373
344
  const result = streamText({
@@ -401,29 +372,19 @@ async function runAssistant(opts: RunOpts) {
401
372
  if (part.type === 'tool-input-start') {
402
373
  if (shouldTraceToolInput(part.toolName)) {
403
374
  tracedToolInputNamesById.set(part.id, part.toolName);
404
- debugLog(
405
- `[TOOL_INPUT_TRACE][runner] fullStream tool-input-start tool=${part.toolName} callId=${part.id}`,
406
- );
407
375
  }
408
376
  continue;
409
377
  }
410
378
 
411
379
  if (part.type === 'tool-input-delta') {
412
380
  const toolName = tracedToolInputNamesById.get(part.id);
413
- if (toolName) {
414
- debugLog(
415
- `[TOOL_INPUT_TRACE][runner] fullStream tool-input-delta tool=${toolName} callId=${part.id} delta=${summarizeTraceValue(part.delta)}`,
416
- );
417
- }
381
+ if (toolName) void summarizeTraceValue(part.delta);
418
382
  continue;
419
383
  }
420
384
 
421
385
  if (part.type === 'tool-input-end') {
422
386
  const toolName = tracedToolInputNamesById.get(part.id);
423
387
  if (toolName) {
424
- debugLog(
425
- `[TOOL_INPUT_TRACE][runner] fullStream tool-input-end tool=${toolName} callId=${part.id}`,
426
- );
427
388
  tracedToolInputNamesById.delete(part.id);
428
389
  }
429
390
  continue;
@@ -432,18 +393,14 @@ async function runAssistant(opts: RunOpts) {
432
393
  if (part.type === 'tool-call') {
433
394
  if (shouldTraceToolInput(part.toolName)) {
434
395
  tracedToolInputNamesById.delete(part.toolCallId);
435
- debugLog(
436
- `[TOOL_INPUT_TRACE][runner] fullStream tool-call tool=${part.toolName} callId=${part.toolCallId} input=${summarizeTraceValue(part.input)}`,
437
- );
396
+ void summarizeTraceValue(part.input);
438
397
  }
439
398
  continue;
440
399
  }
441
400
 
442
401
  if (part.type === 'tool-result') {
443
402
  if (shouldTraceToolInput(part.toolName)) {
444
- debugLog(
445
- `[TOOL_INPUT_TRACE][runner] fullStream tool-result tool=${part.toolName} callId=${part.toolCallId} output=${summarizeTraceValue(part.output)}`,
446
- );
403
+ void summarizeTraceValue(part.output);
447
404
  }
448
405
  continue;
449
406
  }
@@ -550,11 +507,6 @@ async function runAssistant(opts: RunOpts) {
550
507
  }
551
508
 
552
509
  const fs = firstToolSeen();
553
- if (oauthTextGuard?.dropped) {
554
- debugLog(
555
- '[RUNNER] Dropped pseudo tool-call text leaked by OpenAI OAuth stream',
556
- );
557
- }
558
510
  if (!fs && !_finishObserved) {
559
511
  publish({
560
512
  type: 'finish-step',
@@ -581,10 +533,6 @@ async function runAssistant(opts: RunOpts) {
581
533
  streamRawFinishReason = undefined;
582
534
  }
583
535
 
584
- debugLog(
585
- `[RUNNER] Stream finished. finishSeen=${_finishObserved}, firstToolSeen=${fs}, trailingAssistantTextAfterTool=${_trailingAssistantTextAfterTool}, finishReason=${streamFinishReason}, rawFinishReason=${streamRawFinishReason}`,
586
- );
587
-
588
536
  if (dump) {
589
537
  const finalTextSnapshot = latestAssistantText || accumulated;
590
538
  if (finalTextSnapshot.length > 0) {
@@ -601,98 +549,6 @@ async function runAssistant(opts: RunOpts) {
601
549
  aborted: _abortedByUser,
602
550
  });
603
551
  }
604
-
605
- const MAX_CONTINUATIONS = 6;
606
- const continuationCount = opts.continuationCount ?? 0;
607
- const continuationDecision = decideOauthCodexContinuation({
608
- provider: opts.provider,
609
- isOpenAIOAuth,
610
- finishObserved: _finishObserved,
611
- abortedByUser: _abortedByUser,
612
- continuationCount,
613
- maxContinuations: MAX_CONTINUATIONS,
614
- finishReason: streamFinishReason,
615
- rawFinishReason: streamRawFinishReason,
616
- firstToolSeen: fs,
617
- hasTrailingAssistantText: _trailingAssistantTextAfterTool,
618
- endedWithToolActivity: _endedWithToolActivity,
619
- lastToolName: _lastToolName,
620
- droppedPseudoToolText: oauthTextGuard?.dropped ?? false,
621
- lastAssistantText: latestAssistantText,
622
- });
623
-
624
- if (continuationDecision.shouldContinue) {
625
- const sessRows = await db
626
- .select()
627
- .from(sessions)
628
- .where(eq(sessions.id, opts.sessionId))
629
- .limit(1);
630
- const sessionInputTokens = Number(sessRows[0]?.totalInputTokens ?? 0);
631
- const MAX_SESSION_INPUT_TOKENS = 800_000;
632
- if (sessionInputTokens > MAX_SESSION_INPUT_TOKENS) {
633
- debugLog(
634
- `[RUNNER] Token budget exceeded (${sessionInputTokens} > ${MAX_SESSION_INPUT_TOKENS}), stopping continuation.`,
635
- );
636
- } else {
637
- debugLog(
638
- `[RUNNER] WARNING: Stream ended without finish. reason=${continuationDecision.reason ?? 'unknown'}, finishReason=${streamFinishReason}, rawFinishReason=${streamRawFinishReason}, firstToolSeen=${fs}. Auto-continuing.`,
639
- );
640
-
641
- debugLog(
642
- `[RUNNER] Auto-continuing (${continuationCount + 1}/${MAX_CONTINUATIONS})...`,
643
- );
644
-
645
- try {
646
- await completeAssistantMessage({}, opts, db);
647
- } catch (err) {
648
- debugLog(
649
- `[RUNNER] completeAssistantMessage failed before continuation: ${err instanceof Error ? err.message : String(err)}`,
650
- );
651
- }
652
-
653
- const continuationMessageId = crypto.randomUUID();
654
- await db.insert(messages).values({
655
- id: continuationMessageId,
656
- sessionId: opts.sessionId,
657
- role: 'assistant',
658
- status: 'pending',
659
- agent: opts.agent,
660
- provider: opts.provider,
661
- model: opts.model,
662
- createdAt: Date.now(),
663
- });
664
-
665
- publish({
666
- type: 'message.created',
667
- sessionId: opts.sessionId,
668
- payload: {
669
- id: continuationMessageId,
670
- role: 'assistant',
671
- agent: opts.agent,
672
- provider: opts.provider,
673
- model: opts.model,
674
- },
675
- });
676
-
677
- enqueueAssistantRun(
678
- {
679
- ...opts,
680
- assistantMessageId: continuationMessageId,
681
- continuationCount: continuationCount + 1,
682
- },
683
- runSessionLoop,
684
- );
685
- return;
686
- }
687
- }
688
- if (
689
- continuationDecision.reason === 'max-continuations-reached' &&
690
- !_finishObserved
691
- ) {
692
- debugLog(
693
- `[RUNNER] Max continuations (${MAX_CONTINUATIONS}) reached, stopping.`,
694
- );
695
- }
696
552
  } catch (err) {
697
553
  unsubscribeFinish();
698
554
  dump?.recordError(err);
@@ -715,17 +571,10 @@ async function runAssistant(opts: RunOpts) {
715
571
  errorCode === 'context_length_exceeded' ||
716
572
  apiErrorType === 'invalid_request_error';
717
573
 
718
- debugLog(
719
- `[RUNNER] isPromptTooLong: ${isPromptTooLong}, isCompactCommand: ${opts.isCompactCommand}`,
720
- );
721
-
722
574
  if (isPromptTooLong && !opts.isCompactCommand) {
723
- debugLog('[RUNNER] Prompt too long - auto-compacting');
724
575
  try {
725
576
  const pruneResult = await pruneSession(db, opts.sessionId);
726
- debugLog(
727
- `[RUNNER] Auto-pruned ${pruneResult.pruned} parts, saved ~${pruneResult.saved} tokens`,
728
- );
577
+ void pruneResult;
729
578
 
730
579
  publish({
731
580
  type: 'error',
@@ -739,20 +588,10 @@ async function runAssistant(opts: RunOpts) {
739
588
 
740
589
  try {
741
590
  await completeAssistantMessage({}, opts, db);
742
- } catch (err2) {
743
- debugLog(
744
- `[RUNNER] completeAssistantMessage failed after prune: ${err2 instanceof Error ? err2.message : String(err2)}`,
745
- );
746
- }
591
+ } catch {}
747
592
  return;
748
- } catch (pruneErr) {
749
- debugLog(
750
- `[RUNNER] Auto-prune failed: ${pruneErr instanceof Error ? pruneErr.message : String(pruneErr)}`,
751
- );
752
- }
593
+ } catch {}
753
594
  }
754
-
755
- debugLog(`[RUNNER] Error during stream: ${payload.message}`);
756
595
  publish({
757
596
  type: 'error',
758
597
  sessionId: opts.sessionId,
@@ -773,26 +612,13 @@ async function runAssistant(opts: RunOpts) {
773
612
  db,
774
613
  );
775
614
  await completeAssistantMessage({}, opts, db);
776
- } catch (err2) {
777
- debugLog(
778
- `[RUNNER] Failed to complete message after error: ${err2 instanceof Error ? err2.message : String(err2)}`,
779
- );
780
- }
615
+ } catch {}
781
616
  throw err;
782
617
  } finally {
783
618
  if (dump) {
784
619
  try {
785
- const dumpPath = await dump.flush(cfg.projectRoot);
786
- debugLog(`[RUNNER] Debug dump written to ${dumpPath}`);
787
- } catch (dumpErr) {
788
- debugLog(
789
- `[RUNNER] Failed to write debug dump: ${dumpErr instanceof Error ? dumpErr.message : String(dumpErr)}`,
790
- );
791
- }
620
+ await dump.flush(cfg.projectRoot);
621
+ } catch {}
792
622
  }
793
- debugLog(
794
- `[RUNNER] Turn complete for session ${opts.sessionId}, message ${opts.assistantMessageId}`,
795
- );
796
- debugLog(separator);
797
623
  }
798
624
  }
@@ -5,70 +5,7 @@
5
5
  * centralized debug-state and logger modules.
6
6
  */
7
7
 
8
- import { isDebugEnabled as isDebugEnabledNew } from './state.ts';
9
- import { time as timeNew, debug as debugNew } from '@ottocode/sdk';
10
-
11
- const TRUTHY = new Set(['1', 'true', 'yes', 'on']);
12
-
13
- const SYNONYMS: Record<string, string> = {
14
- debug: 'log',
15
- logs: 'log',
16
- logging: 'log',
17
- trace: 'log',
18
- verbose: 'log',
19
- log: 'log',
20
- time: 'timing',
21
- timing: 'timing',
22
- timings: 'timing',
23
- perf: 'timing',
24
- };
25
-
26
- type DebugConfig = { flags: Set<string> };
27
-
28
- let cachedConfig: DebugConfig | null = null;
29
-
30
- function isTruthy(raw: string | undefined): boolean {
31
- if (!raw) return false;
32
- const trimmed = raw.trim().toLowerCase();
33
- if (!trimmed) return false;
34
- return TRUTHY.has(trimmed) || trimmed === 'all';
35
- }
36
-
37
- function normalizeToken(token: string): string {
38
- const trimmed = token.trim().toLowerCase();
39
- if (!trimmed) return '';
40
- if (TRUTHY.has(trimmed) || trimmed === 'all') return 'all';
41
- return SYNONYMS[trimmed] ?? trimmed;
42
- }
43
-
44
- function parseDebugConfig(): DebugConfig {
45
- const flags = new Set<string>();
46
- const sources = [process.env.OTTO_DEBUG, process.env.DEBUG_OTTO];
47
- let sawValue = false;
48
- for (const raw of sources) {
49
- if (typeof raw !== 'string') continue;
50
- const trimmed = raw.trim();
51
- if (!trimmed) continue;
52
- sawValue = true;
53
- const tokens = trimmed.split(/[\s,]+/);
54
- let matched = false;
55
- for (const token of tokens) {
56
- const normalized = normalizeToken(token);
57
- if (!normalized) continue;
58
- matched = true;
59
- flags.add(normalized);
60
- }
61
- if (!matched && isTruthy(trimmed)) flags.add('all');
62
- }
63
- if (isTruthy(process.env.OTTO_DEBUG_TIMING)) flags.add('timing');
64
- if (!flags.size && sawValue) flags.add('all');
65
- return { flags };
66
- }
67
-
68
- function getDebugConfig(): DebugConfig {
69
- if (!cachedConfig) cachedConfig = parseDebugConfig();
70
- return cachedConfig;
71
- }
8
+ import { time as timeNew } from '@ottocode/sdk';
72
9
 
73
10
  /**
74
11
  * Check if debug mode is enabled for a specific flag
@@ -77,33 +14,8 @@ function getDebugConfig(): DebugConfig {
77
14
  * @deprecated Use isDebugEnabled from debug-state.ts instead
78
15
  */
79
16
  export function isDebugEnabled(flag?: string): boolean {
80
- // Use new centralized debug state for general debug
81
- if (!flag || flag === 'log') {
82
- return isDebugEnabledNew();
83
- }
84
-
85
- // For specific flags like 'timing', check both new state and legacy env vars
86
- if (flag === 'timing') {
87
- // If new debug state is enabled OR timing flag is set
88
- if (isDebugEnabledNew()) return true;
89
- }
90
-
91
- // Legacy flag checking
92
- const config = getDebugConfig();
93
- if (config.flags.has('all')) return true;
94
- if (flag) return config.flags.has(flag);
95
- return config.flags.has('log');
96
- }
97
-
98
- /**
99
- * Log debug message
100
- * Now uses the centralized logger
101
- *
102
- * @deprecated Use logger.debug from logger.ts instead
103
- */
104
- export function debugLog(...args: unknown[]) {
105
- if (!isDebugEnabled('log')) return;
106
- debugNew(args.map((arg) => String(arg)).join(' '));
17
+ void flag;
18
+ return false;
107
19
  }
108
20
 
109
21
  /**
@@ -2,12 +2,9 @@
2
2
  * Runtime debug state management
3
3
  *
4
4
  * Centralizes debug flag state that can be set either via:
5
- * - Environment variables (OTTO_DEBUG, DEBUG_OTTO)
6
5
  * - Runtime configuration (CLI --debug flag)
7
6
  */
8
7
 
9
- const TRUTHY = new Set(['1', 'true', 'yes', 'on']);
10
-
11
8
  type DebugState = {
12
9
  enabled: boolean;
13
10
  traceEnabled: boolean;
@@ -23,66 +20,16 @@ const state: DebugState = {
23
20
  runtimeTraceOverride: null,
24
21
  };
25
22
 
26
- type GlobalDebugFlags = {
27
- __OTTO_DEBUG_ENABLED__?: boolean;
28
- __OTTO_TRACE_ENABLED__?: boolean;
29
- };
30
-
31
- const globalFlags = globalThis as GlobalDebugFlags;
32
-
33
- function syncGlobalFlags() {
34
- globalFlags.__OTTO_DEBUG_ENABLED__ = state.enabled;
35
- globalFlags.__OTTO_TRACE_ENABLED__ = state.traceEnabled;
36
- }
37
-
38
- /**
39
- * Check if environment variables indicate debug mode
40
- */
41
- function checkEnvDebug(): boolean {
42
- const sources = [process.env.OTTO_DEBUG, process.env.DEBUG_OTTO];
43
- for (const value of sources) {
44
- if (!value) continue;
45
- const trimmed = value.trim().toLowerCase();
46
- if (TRUTHY.has(trimmed) || trimmed === 'all') {
47
- return true;
48
- }
49
- }
50
- return false;
51
- }
52
-
53
- /**
54
- * Check if environment variables indicate trace mode
55
- */
56
- function checkEnvTrace(): boolean {
57
- const sources = [process.env.OTTO_TRACE, process.env.TRACE_OTTO];
58
- for (const value of sources) {
59
- if (!value) continue;
60
- const trimmed = value.trim().toLowerCase();
61
- if (TRUTHY.has(trimmed)) {
62
- return true;
63
- }
64
- }
65
- return false;
66
- }
67
-
68
- function checkEnvDevtools(): boolean {
69
- const raw = process.env.OTTO_DEVTOOLS;
70
- if (!raw) return false;
71
- const trimmed = raw.trim().toLowerCase();
72
- return TRUTHY.has(trimmed);
73
- }
74
-
75
23
  /**
76
24
  * Initialize debug state from environment
77
25
  */
78
26
  function initialize() {
79
27
  if (state.runtimeOverride === null) {
80
- state.enabled = checkEnvDebug();
28
+ state.enabled = false;
81
29
  }
82
30
  if (state.runtimeTraceOverride === null) {
83
- state.traceEnabled = checkEnvTrace();
31
+ state.traceEnabled = false;
84
32
  }
85
- syncGlobalFlags();
86
33
  }
87
34
 
88
35
  /**
@@ -104,7 +51,7 @@ export function isTraceEnabled(): boolean {
104
51
  }
105
52
 
106
53
  export function isDevtoolsEnabled(): boolean {
107
- return checkEnvDevtools();
54
+ return false;
108
55
  }
109
56
 
110
57
  /**
@@ -116,7 +63,6 @@ export function isDevtoolsEnabled(): boolean {
116
63
  export function setDebugEnabled(enabled: boolean): void {
117
64
  state.enabled = enabled;
118
65
  state.runtimeOverride = enabled;
119
- syncGlobalFlags();
120
66
  }
121
67
 
122
68
  /**
@@ -128,7 +74,6 @@ export function setDebugEnabled(enabled: boolean): void {
128
74
  export function setTraceEnabled(enabled: boolean): void {
129
75
  state.traceEnabled = enabled;
130
76
  state.runtimeTraceOverride = enabled;
131
- syncGlobalFlags();
132
77
  }
133
78
 
134
79
  /**
@@ -137,9 +82,8 @@ export function setTraceEnabled(enabled: boolean): void {
137
82
  export function resetDebugState(): void {
138
83
  state.runtimeOverride = null;
139
84
  state.runtimeTraceOverride = null;
140
- state.enabled = checkEnvDebug();
141
- state.traceEnabled = checkEnvTrace();
142
- syncGlobalFlags();
85
+ state.enabled = false;
86
+ state.traceEnabled = false;
143
87
  }
144
88
 
145
89
  /**
@@ -3,11 +3,7 @@ import { join } from 'node:path';
3
3
  import { mkdir } from 'node:fs/promises';
4
4
  import { isDebugEnabled } from './state.ts';
5
5
 
6
- const TRUTHY = new Set(['1', 'true', 'yes', 'on']);
7
-
8
6
  function isDumpEnabled(): boolean {
9
- const explicit = process.env.OTTO_DEBUG_DUMP;
10
- if (explicit) return TRUTHY.has(explicit.trim().toLowerCase());
11
7
  return isDebugEnabled();
12
8
  }
13
9
 
@@ -5,7 +5,6 @@ import { streamText } from 'ai';
5
5
  import { resolveModel } from '../provider/index.ts';
6
6
  import { getAuth } from '@ottocode/sdk';
7
7
  import { loadConfig } from '@ottocode/sdk';
8
- import { debugLog } from '../debug/index.ts';
9
8
  import { getModelLimits } from './compaction-limits.ts';
10
9
  import { buildCompactionContext } from './compaction-context.ts';
11
10
  import { getCompactionSystemPrompt } from './compaction-detect.ts';
@@ -29,16 +28,11 @@ export async function performAutoCompaction(
29
28
  error?: string;
30
29
  compactMessageId?: string;
31
30
  }> {
32
- debugLog(`[compaction] Starting auto-compaction for session ${sessionId}`);
33
-
34
31
  try {
35
32
  const limits = getModelLimits(provider, modelId);
36
33
  const contextTokenLimit = limits
37
34
  ? Math.max(Math.floor(limits.context * 0.5), 15000)
38
35
  : 15000;
39
- debugLog(
40
- `[compaction] Model ${modelId} context limit: ${limits?.context ?? 'unknown'}, using ${contextTokenLimit} tokens for compaction`,
41
- );
42
36
 
43
37
  const context = await buildCompactionContext(
44
38
  db,
@@ -46,14 +40,10 @@ export async function performAutoCompaction(
46
40
  contextTokenLimit,
47
41
  );
48
42
  if (!context || context.length < 100) {
49
- debugLog('[compaction] Not enough context to compact');
50
43
  return { success: false, error: 'Not enough context to compact' };
51
44
  }
52
45
 
53
46
  const cfg = await loadConfig();
54
- debugLog(
55
- `[compaction] Using session model ${provider}/${modelId} for auto-compaction`,
56
- );
57
47
 
58
48
  const auth = await getAuth(
59
49
  provider as Parameters<typeof getAuth>[0],
@@ -61,10 +51,6 @@ export async function performAutoCompaction(
61
51
  );
62
52
  const oauth = detectOAuth(provider, auth);
63
53
 
64
- debugLog(
65
- `[compaction] OAuth: needsSpoof=${oauth.needsSpoof}, isOpenAIOAuth=${oauth.isOpenAIOAuth}`,
66
- );
67
-
68
54
  const model = await resolveModel(
69
55
  provider as Parameters<typeof resolveModel>[0],
70
56
  modelId,
@@ -130,25 +116,19 @@ export async function performAutoCompaction(
130
116
  .where(eq(messageParts.id, compactPartId));
131
117
 
132
118
  if (!summary || summary.length < 50) {
133
- debugLog('[compaction] Failed to generate summary');
134
119
  return { success: false, error: 'Failed to generate summary' };
135
120
  }
136
121
 
137
- debugLog(`[compaction] Generated summary: ${summary.slice(0, 100)}...`);
138
-
139
122
  const compactResult = await markSessionCompacted(
140
123
  db,
141
124
  sessionId,
142
125
  assistantMessageId,
143
126
  );
144
- debugLog(
145
- `[compaction] Marked ${compactResult.compacted} parts as compacted, saved ~${compactResult.saved} tokens`,
146
- );
127
+ void compactResult;
147
128
 
148
129
  return { success: true, summary, compactMessageId: assistantMessageId };
149
130
  } catch (err) {
150
131
  const errorMsg = err instanceof Error ? err.message : String(err);
151
- debugLog(`[compaction] Auto-compaction failed: ${errorMsg}`);
152
132
  return { success: false, error: errorMsg };
153
133
  }
154
134
  }