@vybestack/llxprt-code-agents 0.10.0-nightly.260613.1adad3b34

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.
Files changed (176) hide show
  1. package/dist/.last_build +0 -0
  2. package/dist/index.d.ts +10 -0
  3. package/dist/index.js +11 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/src/agents/executor-prompt-builder.d.ts +19 -0
  6. package/dist/src/agents/executor-prompt-builder.js +44 -0
  7. package/dist/src/agents/executor-prompt-builder.js.map +1 -0
  8. package/dist/src/agents/executor-termination.d.ts +22 -0
  9. package/dist/src/agents/executor-termination.js +44 -0
  10. package/dist/src/agents/executor-termination.js.map +1 -0
  11. package/dist/src/agents/executor-validation.d.ts +17 -0
  12. package/dist/src/agents/executor-validation.js +35 -0
  13. package/dist/src/agents/executor-validation.js.map +1 -0
  14. package/dist/src/agents/executor.d.ts +136 -0
  15. package/dist/src/agents/executor.js +874 -0
  16. package/dist/src/agents/executor.js.map +1 -0
  17. package/dist/src/agents/invocation.d.ts +45 -0
  18. package/dist/src/agents/invocation.js +118 -0
  19. package/dist/src/agents/invocation.js.map +1 -0
  20. package/dist/src/agents/recovery.d.ts +75 -0
  21. package/dist/src/agents/recovery.js +107 -0
  22. package/dist/src/agents/recovery.js.map +1 -0
  23. package/dist/src/agents/types.d.ts +149 -0
  24. package/dist/src/agents/types.js +18 -0
  25. package/dist/src/agents/types.js.map +1 -0
  26. package/dist/src/agents/utils.d.ts +15 -0
  27. package/dist/src/agents/utils.js +28 -0
  28. package/dist/src/agents/utils.js.map +1 -0
  29. package/dist/src/compression/CompressionHandler.d.ts +178 -0
  30. package/dist/src/compression/CompressionHandler.js +630 -0
  31. package/dist/src/compression/CompressionHandler.js.map +1 -0
  32. package/dist/src/compression/HighDensityStrategy.d.ts +113 -0
  33. package/dist/src/compression/HighDensityStrategy.js +769 -0
  34. package/dist/src/compression/HighDensityStrategy.js.map +1 -0
  35. package/dist/src/compression/MiddleOutStrategy.d.ts +27 -0
  36. package/dist/src/compression/MiddleOutStrategy.js +347 -0
  37. package/dist/src/compression/MiddleOutStrategy.js.map +1 -0
  38. package/dist/src/compression/OneShotStrategy.d.ts +22 -0
  39. package/dist/src/compression/OneShotStrategy.js +235 -0
  40. package/dist/src/compression/OneShotStrategy.js.map +1 -0
  41. package/dist/src/compression/TopDownTruncationStrategy.d.ts +13 -0
  42. package/dist/src/compression/TopDownTruncationStrategy.js +74 -0
  43. package/dist/src/compression/TopDownTruncationStrategy.js.map +1 -0
  44. package/dist/src/compression/compressionBudgeting.d.ts +34 -0
  45. package/dist/src/compression/compressionBudgeting.js +139 -0
  46. package/dist/src/compression/compressionBudgeting.js.map +1 -0
  47. package/dist/src/compression/compressionStrategyFactory.d.ts +23 -0
  48. package/dist/src/compression/compressionStrategyFactory.js +40 -0
  49. package/dist/src/compression/compressionStrategyFactory.js.map +1 -0
  50. package/dist/src/compression/index.d.ts +16 -0
  51. package/dist/src/compression/index.js +17 -0
  52. package/dist/src/compression/index.js.map +1 -0
  53. package/dist/src/compression/reasoningUtils.d.ts +18 -0
  54. package/dist/src/compression/reasoningUtils.js +22 -0
  55. package/dist/src/compression/reasoningUtils.js.map +1 -0
  56. package/dist/src/compression/utils.d.ts +114 -0
  57. package/dist/src/compression/utils.js +316 -0
  58. package/dist/src/compression/utils.js.map +1 -0
  59. package/dist/src/core/AgentHookManager.d.ts +41 -0
  60. package/dist/src/core/AgentHookManager.js +65 -0
  61. package/dist/src/core/AgentHookManager.js.map +1 -0
  62. package/dist/src/core/ChatSessionFactory.d.ts +50 -0
  63. package/dist/src/core/ChatSessionFactory.js +216 -0
  64. package/dist/src/core/ChatSessionFactory.js.map +1 -0
  65. package/dist/src/core/ConversationManager.d.ts +113 -0
  66. package/dist/src/core/ConversationManager.js +311 -0
  67. package/dist/src/core/ConversationManager.js.map +1 -0
  68. package/dist/src/core/DirectMessageProcessor.d.ts +79 -0
  69. package/dist/src/core/DirectMessageProcessor.js +478 -0
  70. package/dist/src/core/DirectMessageProcessor.js.map +1 -0
  71. package/dist/src/core/IdeContextTracker.d.ts +56 -0
  72. package/dist/src/core/IdeContextTracker.js +207 -0
  73. package/dist/src/core/IdeContextTracker.js.map +1 -0
  74. package/dist/src/core/MessageConverter.d.ts +78 -0
  75. package/dist/src/core/MessageConverter.js +492 -0
  76. package/dist/src/core/MessageConverter.js.map +1 -0
  77. package/dist/src/core/MessageStreamOrchestrator.d.ts +85 -0
  78. package/dist/src/core/MessageStreamOrchestrator.js +448 -0
  79. package/dist/src/core/MessageStreamOrchestrator.js.map +1 -0
  80. package/dist/src/core/MessageStreamTerminalHandler.d.ts +16 -0
  81. package/dist/src/core/MessageStreamTerminalHandler.js +170 -0
  82. package/dist/src/core/MessageStreamTerminalHandler.js.map +1 -0
  83. package/dist/src/core/StreamProcessor.d.ts +105 -0
  84. package/dist/src/core/StreamProcessor.js +660 -0
  85. package/dist/src/core/StreamProcessor.js.map +1 -0
  86. package/dist/src/core/TodoContinuationService.d.ts +74 -0
  87. package/dist/src/core/TodoContinuationService.js +312 -0
  88. package/dist/src/core/TodoContinuationService.js.map +1 -0
  89. package/dist/src/core/TurnProcessor.d.ts +91 -0
  90. package/dist/src/core/TurnProcessor.js +540 -0
  91. package/dist/src/core/TurnProcessor.js.map +1 -0
  92. package/dist/src/core/baseLlmClient.d.ts +115 -0
  93. package/dist/src/core/baseLlmClient.js +231 -0
  94. package/dist/src/core/baseLlmClient.js.map +1 -0
  95. package/dist/src/core/bucketFailoverIntegration.d.ts +62 -0
  96. package/dist/src/core/bucketFailoverIntegration.js +186 -0
  97. package/dist/src/core/bucketFailoverIntegration.js.map +1 -0
  98. package/dist/src/core/chatSession.d.ts +121 -0
  99. package/dist/src/core/chatSession.js +720 -0
  100. package/dist/src/core/chatSession.js.map +1 -0
  101. package/dist/src/core/client.d.ts +132 -0
  102. package/dist/src/core/client.js +524 -0
  103. package/dist/src/core/client.js.map +1 -0
  104. package/dist/src/core/clientHelpers.d.ts +15 -0
  105. package/dist/src/core/clientHelpers.js +122 -0
  106. package/dist/src/core/clientHelpers.js.map +1 -0
  107. package/dist/src/core/clientLlmUtilities.d.ts +30 -0
  108. package/dist/src/core/clientLlmUtilities.js +125 -0
  109. package/dist/src/core/clientLlmUtilities.js.map +1 -0
  110. package/dist/src/core/clientToolGovernance.d.ts +37 -0
  111. package/dist/src/core/clientToolGovernance.js +104 -0
  112. package/dist/src/core/clientToolGovernance.js.map +1 -0
  113. package/dist/src/core/compression-config.d.ts +12 -0
  114. package/dist/src/core/compression-config.js +21 -0
  115. package/dist/src/core/compression-config.js.map +1 -0
  116. package/dist/src/core/coreToolScheduler.d.ts +105 -0
  117. package/dist/src/core/coreToolScheduler.js +453 -0
  118. package/dist/src/core/coreToolScheduler.js.map +1 -0
  119. package/dist/src/core/hookToolRestrictions.d.ts +18 -0
  120. package/dist/src/core/hookToolRestrictions.js +187 -0
  121. package/dist/src/core/hookToolRestrictions.js.map +1 -0
  122. package/dist/src/core/nonInteractiveToolExecutor.d.ts +17 -0
  123. package/dist/src/core/nonInteractiveToolExecutor.js +102 -0
  124. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -0
  125. package/dist/src/core/subagent.d.ts +105 -0
  126. package/dist/src/core/subagent.js +650 -0
  127. package/dist/src/core/subagent.js.map +1 -0
  128. package/dist/src/core/subagentExecution.d.ts +104 -0
  129. package/dist/src/core/subagentExecution.js +275 -0
  130. package/dist/src/core/subagentExecution.js.map +1 -0
  131. package/dist/src/core/subagentOrchestrator.d.ts +84 -0
  132. package/dist/src/core/subagentOrchestrator.js +503 -0
  133. package/dist/src/core/subagentOrchestrator.js.map +1 -0
  134. package/dist/src/core/subagentRuntimeSetup.d.ts +75 -0
  135. package/dist/src/core/subagentRuntimeSetup.js +387 -0
  136. package/dist/src/core/subagentRuntimeSetup.js.map +1 -0
  137. package/dist/src/core/subagentScheduler.d.ts +17 -0
  138. package/dist/src/core/subagentScheduler.js +7 -0
  139. package/dist/src/core/subagentScheduler.js.map +1 -0
  140. package/dist/src/core/subagentToolProcessing.d.ts +51 -0
  141. package/dist/src/core/subagentToolProcessing.js +359 -0
  142. package/dist/src/core/subagentToolProcessing.js.map +1 -0
  143. package/dist/src/core/toolGovernance.d.ts +18 -0
  144. package/dist/src/core/toolGovernance.js +50 -0
  145. package/dist/src/core/toolGovernance.js.map +1 -0
  146. package/dist/src/core/turn.d.ts +47 -0
  147. package/dist/src/core/turn.js +455 -0
  148. package/dist/src/core/turn.js.map +1 -0
  149. package/dist/src/core/turnLogging.d.ts +35 -0
  150. package/dist/src/core/turnLogging.js +80 -0
  151. package/dist/src/core/turnLogging.js.map +1 -0
  152. package/dist/src/index.d.ts +32 -0
  153. package/dist/src/index.js +44 -0
  154. package/dist/src/index.js.map +1 -0
  155. package/dist/src/scheduler/confirmation-coordinator.d.ts +139 -0
  156. package/dist/src/scheduler/confirmation-coordinator.js +443 -0
  157. package/dist/src/scheduler/confirmation-coordinator.js.map +1 -0
  158. package/dist/src/scheduler/result-aggregator.d.ts +127 -0
  159. package/dist/src/scheduler/result-aggregator.js +302 -0
  160. package/dist/src/scheduler/result-aggregator.js.map +1 -0
  161. package/dist/src/scheduler/status-transitions.d.ts +39 -0
  162. package/dist/src/scheduler/status-transitions.js +184 -0
  163. package/dist/src/scheduler/status-transitions.js.map +1 -0
  164. package/dist/src/scheduler/tool-dispatcher.d.ts +40 -0
  165. package/dist/src/scheduler/tool-dispatcher.js +120 -0
  166. package/dist/src/scheduler/tool-dispatcher.js.map +1 -0
  167. package/dist/src/scheduler/tool-executor.d.ts +44 -0
  168. package/dist/src/scheduler/tool-executor.js +117 -0
  169. package/dist/src/scheduler/tool-executor.js.map +1 -0
  170. package/dist/src/scheduler/utils.d.ts +11 -0
  171. package/dist/src/scheduler/utils.js +19 -0
  172. package/dist/src/scheduler/utils.js.map +1 -0
  173. package/dist/src/tools/task.d.ts +128 -0
  174. package/dist/src/tools/task.js +932 -0
  175. package/dist/src/tools/task.js.map +1 -0
  176. package/package.json +54 -0
@@ -0,0 +1,235 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * @plan PLAN-20260211-HIGHDENSITY.P03
8
+ * @plan PLAN-20260211-HIGHDENSITY.P05
9
+ * @requirement REQ-HD-001.3
10
+ * @pseudocode strategy-interface.md lines 90-94
11
+ *
12
+ * One-shot compression strategy: summarizes the entire history except
13
+ * the last N messages in a single LLM call. The preserved tail is
14
+ * determined by the preserveThreshold ephemeral setting.
15
+ *
16
+ * Unlike middle-out (which preserves both top and bottom), one-shot
17
+ * preserves ONLY the recent tail. The summary replaces everything
18
+ * above the preserved messages.
19
+ */
20
+ import { readFileSync } from 'node:fs';
21
+ import { CompressionExecutionError, EmptySummaryError, PromptResolutionError, isTransientCompressionError, } from '@vybestack/llxprt-code-core/core/compression/types.js';
22
+ import { adjustForToolCallBoundary, aggregateTextFromBlocks, buildTriggerInstruction, COMPRESSION_SECURITY_PREAMBLE, runVerificationPass, sanitizeHistoryForCompression, } from './utils.js';
23
+ import { getCompressionPrompt } from '@vybestack/llxprt-code-core/core/prompts.js';
24
+ import { buildContinuationDirective } from '@vybestack/llxprt-code-core/core/compression/continuationDirective.js';
25
+ function destructureProviderResult(result) {
26
+ return {
27
+ provider: result.provider,
28
+ resolvedRuntime: result.runtime,
29
+ resolvedConfig: result.config,
30
+ resolvedOptions: result.resolved,
31
+ invocation: result.invocation,
32
+ };
33
+ }
34
+ const MINIMUM_COMPRESS_MESSAGES = 4;
35
+ // ---------------------------------------------------------------------------
36
+ // OneShotStrategy
37
+ // ---------------------------------------------------------------------------
38
+ export class OneShotStrategy {
39
+ name = 'one-shot';
40
+ requiresLLM = true;
41
+ /** @plan PLAN-20260211-HIGHDENSITY.P03 @requirement REQ-HD-001.3 */
42
+ trigger = {
43
+ mode: 'threshold',
44
+ defaultThreshold: 0.85,
45
+ };
46
+ // eslint-disable-next-line max-lines-per-function -- Strategy orchestration remains linear for readability.
47
+ async compress(context) {
48
+ const { history } = context;
49
+ if (history.length === 0) {
50
+ return this.noCompressionResult(history);
51
+ }
52
+ // Compute the split: everything above the preserved tail gets compressed
53
+ const { toCompress, toKeep } = this.computeSplit(context);
54
+ if (toCompress.length < MINIMUM_COMPRESS_MESSAGES) {
55
+ return this.noCompressionResult(history);
56
+ }
57
+ // Resolve the compression prompt
58
+ const prompt = this.resolvePrompt(context);
59
+ // Resolve the provider (compression profile may be undefined)
60
+ const compressionProfile = context.runtimeContext.ephemerals.compressionProfile();
61
+ const { provider, resolvedRuntime, resolvedConfig, resolvedOptions, invocation, } = destructureProviderResult(await context.resolveProvider(compressionProfile));
62
+ // Build the LLM request
63
+ // @plan PLAN-20260211-HIGHDENSITY.P23
64
+ // @requirement REQ-HD-011.3, REQ-HD-012.2
65
+ const triggerInstruction = buildTriggerInstruction(toCompress);
66
+ const compressionRequest = [
67
+ COMPRESSION_SECURITY_PREAMBLE,
68
+ {
69
+ speaker: 'human',
70
+ blocks: [{ type: 'text', text: prompt }],
71
+ },
72
+ ...sanitizeHistoryForCompression(toCompress),
73
+ ...this.buildContextInjections(context),
74
+ {
75
+ speaker: 'human',
76
+ blocks: [{ type: 'text', text: triggerInstruction }],
77
+ },
78
+ ];
79
+ // Call the provider and aggregate the streamed response
80
+ const { text: summary, usage: capturedUsage } = await this.callProvider(provider, compressionRequest, context, resolvedRuntime, resolvedConfig, resolvedOptions, invocation);
81
+ if (!summary.trim()) {
82
+ throw new EmptySummaryError('one-shot');
83
+ }
84
+ // Optional verification pass — gated by compressionVerification flag (default off)
85
+ let finalSummary = summary;
86
+ if (context.compressionVerification === true) {
87
+ finalSummary = await runVerificationPass(provider, summary, context, resolvedRuntime, resolvedConfig, resolvedOptions, invocation);
88
+ }
89
+ // Assemble result: summary + continuation directive + preserved tail
90
+ const summaryEntry = {
91
+ speaker: 'human',
92
+ blocks: [{ type: 'text', text: finalSummary }],
93
+ ...(capturedUsage ? { metadata: { usage: capturedUsage } } : {}),
94
+ };
95
+ const newHistory = [
96
+ summaryEntry,
97
+ {
98
+ speaker: 'ai',
99
+ blocks: [
100
+ {
101
+ type: 'text',
102
+ text: buildContinuationDirective(context.activeTodos),
103
+ },
104
+ ],
105
+ },
106
+ ...toKeep,
107
+ ];
108
+ const metadata = {
109
+ originalMessageCount: history.length,
110
+ compressedMessageCount: newHistory.length,
111
+ strategyUsed: 'one-shot',
112
+ llmCallMade: true,
113
+ topPreserved: 0,
114
+ bottomPreserved: toKeep.length,
115
+ middleCompressed: toCompress.length,
116
+ ...(capturedUsage ? { usage: capturedUsage } : {}),
117
+ };
118
+ return { newHistory, metadata };
119
+ }
120
+ // -------------------------------------------------------------------------
121
+ // Private helpers
122
+ // -------------------------------------------------------------------------
123
+ computeSplit(context) {
124
+ const history = context.history;
125
+ const preserveThreshold = context.runtimeContext.ephemerals.preserveThreshold();
126
+ let splitIndex = Math.floor(history.length * (1 - preserveThreshold));
127
+ if (splitIndex < MINIMUM_COMPRESS_MESSAGES) {
128
+ return { toCompress: [], toKeep: [...history] };
129
+ }
130
+ splitIndex = adjustForToolCallBoundary(history, splitIndex);
131
+ if (splitIndex < MINIMUM_COMPRESS_MESSAGES) {
132
+ return { toCompress: [], toKeep: [...history] };
133
+ }
134
+ return {
135
+ toCompress: history.slice(0, splitIndex),
136
+ toKeep: history.slice(splitIndex),
137
+ };
138
+ }
139
+ resolvePrompt(context) {
140
+ const resolved = context.promptResolver.resolveFile(context.promptBaseDir, 'compression.md', context.promptContext);
141
+ if (resolved.found && resolved.path) {
142
+ try {
143
+ return readFileSync(resolved.path, 'utf-8');
144
+ }
145
+ catch {
146
+ // Fall through to hardcoded default
147
+ }
148
+ }
149
+ const fallback = getCompressionPrompt();
150
+ if (!fallback) {
151
+ throw new PromptResolutionError('compression.md');
152
+ }
153
+ return fallback;
154
+ }
155
+ async callProvider(provider, request, context, resolvedRuntime, resolvedConfig, resolvedOptions, invocation) {
156
+ const providerRuntime = resolvedRuntime;
157
+ try {
158
+ const stream = provider.generateChatCompletion({
159
+ contents: request,
160
+ tools: undefined,
161
+ config: resolvedConfig ?? context.config ?? providerRuntime.config,
162
+ runtime: providerRuntime,
163
+ invocation,
164
+ settings: providerRuntime.settingsService,
165
+ resolved: resolvedOptions,
166
+ metadata: {
167
+ ...(providerRuntime.metadata ?? {}),
168
+ source: 'OneShotStrategy.callProvider',
169
+ },
170
+ });
171
+ let summary = '';
172
+ let lastBlockWasNonText = false;
173
+ let capturedUsage;
174
+ for await (const chunk of stream) {
175
+ const result = aggregateTextFromBlocks(chunk.blocks, summary, lastBlockWasNonText);
176
+ summary = result.text;
177
+ lastBlockWasNonText = result.lastBlockWasNonText;
178
+ if (chunk.metadata?.usage) {
179
+ capturedUsage = chunk.metadata.usage;
180
+ }
181
+ }
182
+ return { text: summary, usage: capturedUsage };
183
+ }
184
+ catch (error) {
185
+ throw new CompressionExecutionError('one-shot', `LLM provider call failed: ${error instanceof Error ? error.message : String(error)}`, { isTransient: isTransientCompressionError(error) });
186
+ }
187
+ }
188
+ noCompressionResult(history) {
189
+ return {
190
+ newHistory: [...history],
191
+ metadata: {
192
+ originalMessageCount: history.length,
193
+ compressedMessageCount: history.length,
194
+ strategyUsed: 'one-shot',
195
+ llmCallMade: false,
196
+ topPreserved: 0,
197
+ bottomPreserved: 0,
198
+ middleCompressed: 0,
199
+ },
200
+ };
201
+ }
202
+ /**
203
+ * @plan PLAN-20260211-HIGHDENSITY.P23
204
+ * @requirement REQ-HD-011.3, REQ-HD-012.2
205
+ */
206
+ buildContextInjections(context) {
207
+ const injections = [];
208
+ if (context.activeTodos && context.activeTodos.trim().length > 0) {
209
+ injections.push({
210
+ speaker: 'human',
211
+ blocks: [
212
+ {
213
+ type: 'text',
214
+ text: `The following are the current active todo/task items. When summarizing, preserve context about why each task exists and what has been tried:
215
+
216
+ ${context.activeTodos}`,
217
+ },
218
+ ],
219
+ });
220
+ }
221
+ if (context.transcriptPath) {
222
+ injections.push({
223
+ speaker: 'human',
224
+ blocks: [
225
+ {
226
+ type: 'text',
227
+ text: `Note: The full pre-compression transcript is available at: ${context.transcriptPath}`,
228
+ },
229
+ ],
230
+ });
231
+ }
232
+ return injections;
233
+ }
234
+ }
235
+ //# sourceMappingURL=OneShotStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OneShotStrategy.js","sourceRoot":"","sources":["../../../src/compression/OneShotStrategy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { CompressionContext, CompressionResult, CompressionStrategy, StrategyTrigger } from '@vybestack/llxprt-code-core/core/compression/types.js';
7
+ export declare class TopDownTruncationStrategy implements CompressionStrategy {
8
+ readonly name: "top-down-truncation";
9
+ readonly requiresLLM = false;
10
+ /** @plan PLAN-20260211-HIGHDENSITY.P03 @requirement REQ-HD-001.3 */
11
+ readonly trigger: StrategyTrigger;
12
+ compress(context: CompressionContext): Promise<CompressionResult>;
13
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { adjustForToolCallBoundary } from './utils.js';
7
+ export class TopDownTruncationStrategy {
8
+ name = 'top-down-truncation';
9
+ requiresLLM = false;
10
+ /** @plan PLAN-20260211-HIGHDENSITY.P03 @requirement REQ-HD-001.3 */
11
+ trigger = {
12
+ mode: 'threshold',
13
+ defaultThreshold: 0.85,
14
+ };
15
+ async compress(context) {
16
+ const { history, runtimeContext, estimateTokens, currentTokenCount } = context;
17
+ const originalCount = history.length;
18
+ if (originalCount === 0) {
19
+ return {
20
+ newHistory: [],
21
+ metadata: {
22
+ originalMessageCount: 0,
23
+ compressedMessageCount: 0,
24
+ strategyUsed: 'top-down-truncation',
25
+ llmCallMade: false,
26
+ },
27
+ };
28
+ }
29
+ const compressionThreshold = runtimeContext.ephemerals.compressionThreshold();
30
+ const contextLimit = runtimeContext.ephemerals.contextLimit();
31
+ const target = compressionThreshold * contextLimit * 0.6;
32
+ if (currentTokenCount <= target) {
33
+ return {
34
+ newHistory: [...history],
35
+ metadata: {
36
+ originalMessageCount: originalCount,
37
+ compressedMessageCount: originalCount,
38
+ strategyUsed: 'top-down-truncation',
39
+ llmCallMade: false,
40
+ },
41
+ };
42
+ }
43
+ const minKeep = Math.min(2, originalCount);
44
+ // Remove messages from start (oldest first) until under target
45
+ let removeCount = 0;
46
+ for (let i = 1; i <= originalCount - minKeep; i++) {
47
+ const remaining = history.slice(i);
48
+ const tokens = await estimateTokens(remaining);
49
+ if (tokens < target) {
50
+ removeCount = i;
51
+ break;
52
+ }
53
+ removeCount = i;
54
+ }
55
+ // Ensure we keep at least minKeep messages
56
+ removeCount = Math.min(removeCount, originalCount - minKeep);
57
+ // Adjust boundary to avoid orphaning tool call/response pairs
58
+ const mutableHistory = [...history];
59
+ const adjustedIndex = adjustForToolCallBoundary(mutableHistory, removeCount);
60
+ // Clamp: never remove more than originalCount - minKeep
61
+ const finalRemoveCount = Math.min(adjustedIndex, originalCount - minKeep);
62
+ const newHistory = mutableHistory.slice(finalRemoveCount);
63
+ return {
64
+ newHistory,
65
+ metadata: {
66
+ originalMessageCount: originalCount,
67
+ compressedMessageCount: newHistory.length,
68
+ strategyUsed: 'top-down-truncation',
69
+ llmCallMade: false,
70
+ },
71
+ };
72
+ }
73
+ }
74
+ //# sourceMappingURL=TopDownTruncationStrategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TopDownTruncationStrategy.js","sourceRoot":"","sources":["../../../src/compression/TopDownTruncationStrategy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwBH,OAAO,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,OAAO,yBAAyB;IAC3B,IAAI,GAAG,qBAA8B,CAAC;IACtC,WAAW,GAAG,KAAK,CAAC;IAC7B,oEAAoE;IAC3D,OAAO,GAAoB;QAClC,IAAI,EAAE,WAAW;QACjB,gBAAgB,EAAE,IAAI;KACvB,CAAC;IAEF,KAAK,CAAC,QAAQ,CAAC,OAA2B;QACxC,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,GAClE,OAAO,CAAC;QACV,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;QAErC,IAAI,aAAa,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;gBACL,UAAU,EAAE,EAAE;gBACd,QAAQ,EAAE;oBACR,oBAAoB,EAAE,CAAC;oBACvB,sBAAsB,EAAE,CAAC;oBACzB,YAAY,EAAE,qBAAqB;oBACnC,WAAW,EAAE,KAAK;iBACnB;aACF,CAAC;QACJ,CAAC;QAED,MAAM,oBAAoB,GACxB,cAAc,CAAC,UAAU,CAAC,oBAAoB,EAAE,CAAC;QACnD,MAAM,YAAY,GAAG,cAAc,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QAC9D,MAAM,MAAM,GAAG,oBAAoB,GAAG,YAAY,GAAG,GAAG,CAAC;QAEzD,IAAI,iBAAiB,IAAI,MAAM,EAAE,CAAC;YAChC,OAAO;gBACL,UAAU,EAAE,CAAC,GAAG,OAAO,CAAC;gBACxB,QAAQ,EAAE;oBACR,oBAAoB,EAAE,aAAa;oBACnC,sBAAsB,EAAE,aAAa;oBACrC,YAAY,EAAE,qBAAqB;oBACnC,WAAW,EAAE,KAAK;iBACnB;aACF,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC;QAE3C,+DAA+D;QAC/D,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,aAAa,GAAG,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC;YAClD,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,SAAS,CAAC,CAAC;YAC/C,IAAI,MAAM,GAAG,MAAM,EAAE,CAAC;gBACpB,WAAW,GAAG,CAAC,CAAC;gBAChB,MAAM;YACR,CAAC;YACD,WAAW,GAAG,CAAC,CAAC;QAClB,CAAC;QAED,2CAA2C;QAC3C,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC;QAE7D,8DAA8D;QAC9D,MAAM,cAAc,GAAG,CAAC,GAAG,OAAO,CAAe,CAAC;QAClD,MAAM,aAAa,GAAG,yBAAyB,CAC7C,cAAc,EACd,WAAW,CACZ,CAAC;QAEF,wDAAwD;QACxD,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,aAAa,GAAG,OAAO,CAAC,CAAC;QAE1E,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAE1D,OAAO;YACL,UAAU;YACV,QAAQ,EAAE;gBACR,oBAAoB,EAAE,aAAa;gBACnC,sBAAsB,EAAE,UAAU,CAAC,MAAM;gBACzC,YAAY,EAAE,qBAAqB;gBACnC,WAAW,EAAE,KAAK;aACnB;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import type { IContent } from '@vybestack/llxprt-code-core/services/history/IContent.js';
7
+ import type { HistoryService } from '@vybestack/llxprt-code-core/services/history/HistoryService.js';
8
+ import type { GenerateContentConfig } from '@google/genai';
9
+ import type { RuntimeProvider as IProvider } from '@vybestack/llxprt-code-core/runtime/contracts/RuntimeProvider.js';
10
+ /**
11
+ * Extract a number from various value types (number, string, etc.)
12
+ * @plan PLAN-20260220-DECOMPOSE.P03
13
+ */
14
+ export declare function asNumber(value: unknown): number | undefined;
15
+ /**
16
+ * Extract completion budget from generation config parameters.
17
+ * Checks multiple possible parameter names for output token limits.
18
+ * @plan PLAN-20260220-DECOMPOSE.P03
19
+ */
20
+ export declare function extractCompletionBudgetFromParams(params: Record<string, unknown> | undefined): number | undefined;
21
+ /**
22
+ * Get completion budget from generation config, provider params, or default.
23
+ * Used to reserve output tokens when calculating context limits.
24
+ * @plan PLAN-20260220-DECOMPOSE.P03
25
+ */
26
+ export declare function getCompletionBudget(generationConfig: GenerateContentConfig, _model: string, provider?: IProvider, settingsService?: {
27
+ get: (key: string) => unknown;
28
+ }): number;
29
+ /**
30
+ * Estimate token count for pending content that hasn't been added to history yet.
31
+ * Uses historyService tokenizer when available, falls back to text-based estimation.
32
+ * @plan PLAN-20260220-DECOMPOSE.P03
33
+ */
34
+ export declare function estimatePendingTokens(contents: IContent[], historyService: HistoryService, model: string): Promise<number>;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { estimateTokens as estimateTextTokens } from '@vybestack/llxprt-code-core/utils/toolOutputLimiter.js';
7
+ import { DebugLogger } from '@vybestack/llxprt-code-core/debug/index.js';
8
+ const logger = new DebugLogger('llxprt:gemini:compression-budgeting');
9
+ /**
10
+ * Extract a number from various value types (number, string, etc.)
11
+ * @plan PLAN-20260220-DECOMPOSE.P03
12
+ */
13
+ export function asNumber(value) {
14
+ if (typeof value === 'number' && Number.isFinite(value)) {
15
+ return value;
16
+ }
17
+ if (typeof value === 'string') {
18
+ const parsed = Number(value);
19
+ if (Number.isFinite(parsed)) {
20
+ return parsed;
21
+ }
22
+ }
23
+ return undefined;
24
+ }
25
+ /**
26
+ * Extract completion budget from generation config parameters.
27
+ * Checks multiple possible parameter names for output token limits.
28
+ * @plan PLAN-20260220-DECOMPOSE.P03
29
+ */
30
+ export function extractCompletionBudgetFromParams(params) {
31
+ if (!params) {
32
+ return undefined;
33
+ }
34
+ const candidateKeys = [
35
+ 'maxOutputTokens',
36
+ 'maxTokens',
37
+ 'max_output_tokens',
38
+ 'max_tokens',
39
+ ];
40
+ for (const key of candidateKeys) {
41
+ if (key in params) {
42
+ const value = asNumber(params[key]);
43
+ if (value !== undefined) {
44
+ return value;
45
+ }
46
+ }
47
+ }
48
+ return undefined;
49
+ }
50
+ /**
51
+ * Get completion budget from generation config, provider params, or default.
52
+ * Used to reserve output tokens when calculating context limits.
53
+ * @plan PLAN-20260220-DECOMPOSE.P03
54
+ */
55
+ export function getCompletionBudget(generationConfig, _model, provider, settingsService) {
56
+ const DEFAULT_COMPLETION_BUDGET = 65_536;
57
+ // Check global ephemeral setting for maxOutputTokens (set via /set maxOutputTokens)
58
+ // This is a generic setting that providers should translate to their native param
59
+ const liveMaxOutputTokens = settingsService?.get('maxOutputTokens');
60
+ const liveBudget = asNumber(liveMaxOutputTokens);
61
+ if (liveBudget !== undefined && liveBudget > 0) {
62
+ return liveBudget;
63
+ }
64
+ const generationBudget = asNumber(generationConfig.maxOutputTokens);
65
+ const providerParams = provider?.getModelParams?.();
66
+ const providerBudget = extractCompletionBudgetFromParams(providerParams);
67
+ return generationBudget ?? providerBudget ?? DEFAULT_COMPLETION_BUDGET;
68
+ }
69
+ /**
70
+ * Estimate token count for pending content that hasn't been added to history yet.
71
+ * Uses historyService tokenizer when available, falls back to text-based estimation.
72
+ * @plan PLAN-20260220-DECOMPOSE.P03
73
+ */
74
+ export async function estimatePendingTokens(contents, historyService, model) {
75
+ if (contents.length === 0) {
76
+ return 0;
77
+ }
78
+ try {
79
+ return await historyService.estimateTokensForContents(contents, model);
80
+ }
81
+ catch (error) {
82
+ logger.debug('Falling back to local token estimate', error);
83
+ let fallback = 0;
84
+ for (const content of contents) {
85
+ fallback += estimateFallbackContentTokens(content, logger);
86
+ }
87
+ return fallback;
88
+ }
89
+ }
90
+ function estimateFallbackContentTokens(content, fallbackLogger) {
91
+ try {
92
+ const serialized = JSON.stringify(content);
93
+ return estimateTextTokens(serialized);
94
+ }
95
+ catch (stringifyError) {
96
+ fallbackLogger.debug('Failed to stringify content for fallback token estimate', stringifyError);
97
+ return estimateBlockTokens(content);
98
+ }
99
+ }
100
+ function estimateBlockTokens(content) {
101
+ try {
102
+ const blockStrings = content.blocks
103
+ .map((block) => {
104
+ switch (block.type) {
105
+ case 'text':
106
+ return block.text;
107
+ case 'tool_call':
108
+ return JSON.stringify({
109
+ name: block.name,
110
+ parameters: block.parameters,
111
+ });
112
+ case 'tool_response':
113
+ return JSON.stringify({
114
+ callId: block.callId,
115
+ toolName: block.toolName,
116
+ result: block.result,
117
+ error: block.error,
118
+ });
119
+ case 'thinking':
120
+ return block.thought;
121
+ case 'code':
122
+ return block.code;
123
+ case 'media':
124
+ return block.caption ?? '';
125
+ default:
126
+ return '';
127
+ }
128
+ })
129
+ .join('\n');
130
+ if (blockStrings) {
131
+ return estimateTextTokens(blockStrings);
132
+ }
133
+ }
134
+ catch (blockError) {
135
+ logger.debug('Failed to estimate tokens from blocks', blockError);
136
+ }
137
+ return 0;
138
+ }
139
+ //# sourceMappingURL=compressionBudgeting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compressionBudgeting.js","sourceRoot":"","sources":["../../../src/compression/compressionBudgeting.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,cAAc,IAAI,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC9G,OAAO,EAAE,WAAW,EAAE,MAAM,4CAA4C,CAAC;AAEzE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,qCAAqC,CAAC,CAAC;AAEtE;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,KAAc;IACrC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iCAAiC,CAC/C,MAA2C;IAE3C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,aAAa,GAAG;QACpB,iBAAiB;QACjB,WAAW;QACX,mBAAmB;QACnB,YAAY;KACb,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,IAAI,GAAG,IAAI,MAAM,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACpC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,gBAAuC,EACvC,MAAc,EACd,QAAoB,EACpB,eAAmD;IAEnD,MAAM,yBAAyB,GAAG,MAAM,CAAC;IAEzC,oFAAoF;IACpF,kFAAkF;IAClF,MAAM,mBAAmB,GAAG,eAAe,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACpE,MAAM,UAAU,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAAC;IACjD,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;QAC/C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,gBAAgB,GAAG,QAAQ,CAC9B,gBAAkD,CAAC,eAAe,CACpE,CAAC;IAEF,MAAM,cAAc,GAAG,QAAQ,EAAE,cAAc,EAAE,EAAE,CAAC;IACpD,MAAM,cAAc,GAAG,iCAAiC,CAAC,cAAc,CAAC,CAAC;IAEzE,OAAO,gBAAgB,IAAI,cAAc,IAAI,yBAAyB,CAAC;AACzE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAoB,EACpB,cAA8B,EAC9B,KAAa;IAEb,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,cAAc,CAAC,yBAAyB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QAE5D,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,QAAQ,IAAI,6BAA6B,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,6BAA6B,CACpC,OAAiB,EACjB,cAA2B;IAE3B,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAC3C,OAAO,kBAAkB,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,cAAc,EAAE,CAAC;QACxB,cAAc,CAAC,KAAK,CAClB,yDAAyD,EACzD,cAAc,CACf,CAAC;QACF,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAiB;IAC5C,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM;aAChC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACb,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,MAAM;oBACT,OAAO,KAAK,CAAC,IAAI,CAAC;gBACpB,KAAK,WAAW;oBACd,OAAO,IAAI,CAAC,SAAS,CAAC;wBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;wBAChB,UAAU,EAAE,KAAK,CAAC,UAAU;qBAC7B,CAAC,CAAC;gBACL,KAAK,eAAe;oBAClB,OAAO,IAAI,CAAC,SAAS,CAAC;wBACpB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;wBACxB,MAAM,EAAE,KAAK,CAAC,MAAM;wBACpB,KAAK,EAAE,KAAK,CAAC,KAAK;qBACnB,CAAC,CAAC;gBACL,KAAK,UAAU;oBACb,OAAO,KAAK,CAAC,OAAO,CAAC;gBACvB,KAAK,MAAM;oBACT,OAAO,KAAK,CAAC,IAAI,CAAC;gBACpB,KAAK,OAAO;oBACV,OAAO,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;gBAC7B;oBACE,OAAO,EAAE,CAAC;YACd,CAAC;QACH,CAAC,CAAC;aACD,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,IAAI,YAAY,EAAE,CAAC;YACjB,OAAO,kBAAkB,CAAC,YAAY,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAAC,OAAO,UAAU,EAAE,CAAC;QACpB,MAAM,CAAC,KAAK,CAAC,uCAAuC,EAAE,UAAU,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * @plan PLAN-20260211-COMPRESSION.P10
8
+ * @plan PLAN-20260211-HIGHDENSITY.P17
9
+ * @requirement REQ-CS-001.2, REQ-CS-001.3, REQ-HD-004.2
10
+ * @pseudocode settings-factory.md lines 140-157
11
+ *
12
+ * Factory functions for resolving compression strategies by name.
13
+ */
14
+ import type { CompressionStrategy, CompressionStrategyName } from '@vybestack/llxprt-code-core/core/compression/types.js';
15
+ /**
16
+ * Validates a raw string against the known strategy names.
17
+ * Returns the typed name on success; throws {@link UnknownStrategyError} otherwise.
18
+ */
19
+ export declare function parseCompressionStrategyName(name: string): CompressionStrategyName;
20
+ /**
21
+ * Returns a fresh {@link CompressionStrategy} instance for the given name.
22
+ */
23
+ export declare function getCompressionStrategy(name: CompressionStrategyName): CompressionStrategy;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { COMPRESSION_STRATEGIES, UnknownStrategyError, } from '@vybestack/llxprt-code-core/core/compression/types.js';
7
+ import { MiddleOutStrategy } from './MiddleOutStrategy.js';
8
+ import { TopDownTruncationStrategy } from './TopDownTruncationStrategy.js';
9
+ import { OneShotStrategy } from './OneShotStrategy.js';
10
+ import { HighDensityStrategy } from './HighDensityStrategy.js';
11
+ /**
12
+ * Validates a raw string against the known strategy names.
13
+ * Returns the typed name on success; throws {@link UnknownStrategyError} otherwise.
14
+ */
15
+ export function parseCompressionStrategyName(name) {
16
+ if (COMPRESSION_STRATEGIES.includes(name)) {
17
+ return name;
18
+ }
19
+ throw new UnknownStrategyError(name);
20
+ }
21
+ /**
22
+ * Returns a fresh {@link CompressionStrategy} instance for the given name.
23
+ */
24
+ export function getCompressionStrategy(name) {
25
+ switch (name) {
26
+ case 'middle-out':
27
+ return new MiddleOutStrategy();
28
+ case 'top-down-truncation':
29
+ return new TopDownTruncationStrategy();
30
+ case 'one-shot':
31
+ return new OneShotStrategy();
32
+ case 'high-density':
33
+ return new HighDensityStrategy();
34
+ default: {
35
+ const exhaustive = name;
36
+ throw new UnknownStrategyError(exhaustive);
37
+ }
38
+ }
39
+ }
40
+ //# sourceMappingURL=compressionStrategyFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compressionStrategyFactory.js","sourceRoot":"","sources":["../../../src/compression/compressionStrategyFactory.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAeH,OAAO,EACL,sBAAsB,EACtB,oBAAoB,GACrB,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D;;;GAGG;AACH,MAAM,UAAU,4BAA4B,CAC1C,IAAY;IAEZ,IAAK,sBAA4C,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjE,OAAO,IAA+B,CAAC;IACzC,CAAC;IACD,MAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAA6B;IAE7B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,YAAY;YACf,OAAO,IAAI,iBAAiB,EAAE,CAAC;QACjC,KAAK,qBAAqB;YACxB,OAAO,IAAI,yBAAyB,EAAE,CAAC;QACzC,KAAK,UAAU;YACb,OAAO,IAAI,eAAe,EAAE,CAAC;QAC/B,KAAK,cAAc;YACjB,OAAO,IAAI,mBAAmB,EAAE,CAAC;QACnC,OAAO,CAAC,CAAC,CAAC;YACR,MAAM,UAAU,GAAU,IAAI,CAAC;YAC/B,MAAM,IAAI,oBAAoB,CAAC,UAAoB,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export * from '@vybestack/llxprt-code-core/core/compression/types.js';
7
+ export * from './utils.js';
8
+ export { MiddleOutStrategy } from './MiddleOutStrategy.js';
9
+ export { TopDownTruncationStrategy } from './TopDownTruncationStrategy.js';
10
+ export { OneShotStrategy } from './OneShotStrategy.js';
11
+ /** @plan PLAN-20260211-HIGHDENSITY.P09 */
12
+ export { HighDensityStrategy } from './HighDensityStrategy.js';
13
+ export * from './compressionStrategyFactory.js';
14
+ /** @plan PLAN-20260220-DECOMPOSE.P03 */
15
+ export { CompressionHandler } from './CompressionHandler.js';
16
+ export * from './compressionBudgeting.js';
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export * from '@vybestack/llxprt-code-core/core/compression/types.js';
7
+ export * from './utils.js';
8
+ export { MiddleOutStrategy } from './MiddleOutStrategy.js';
9
+ export { TopDownTruncationStrategy } from './TopDownTruncationStrategy.js';
10
+ export { OneShotStrategy } from './OneShotStrategy.js';
11
+ /** @plan PLAN-20260211-HIGHDENSITY.P09 */
12
+ export { HighDensityStrategy } from './HighDensityStrategy.js';
13
+ export * from './compressionStrategyFactory.js';
14
+ /** @plan PLAN-20260220-DECOMPOSE.P03 */
15
+ export { CompressionHandler } from './CompressionHandler.js';
16
+ export * from './compressionBudgeting.js';
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/compression/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,uDAAuD,CAAC;AACtE,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,0CAA0C;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,cAAc,iCAAiC,CAAC;AAChD,wCAAwC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,cAAc,2BAA2B,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Vybestack LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * Core-owned reasoning helpers used by compression.
8
+ *
9
+ * Provider-specific reasoning parsing remains in the providers package. Core
10
+ * keeps only generic thinking-block accounting helpers needed by compression.
11
+ *
12
+ * @plan:PLAN-20260603-ISSUE1584.P11
13
+ * @requirement:REQ-DEP-001
14
+ * @requirement:REQ-SHIM-001
15
+ */
16
+ import type { IContent, ThinkingBlock } from '@vybestack/llxprt-code-core/services/history/IContent.js';
17
+ export declare function extractThinkingBlocks(content: IContent): ThinkingBlock[];
18
+ export declare function estimateThinkingTokens(blocks: ThinkingBlock[]): number;