@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,216 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { getEnvironmentContext } from '@vybestack/llxprt-code-core/utils/environmentContext.js';
7
+ import { getCoreSystemPromptAsync } from '@vybestack/llxprt-code-core/core/prompts.js';
8
+ import { getToolGovernanceEphemerals, buildToolDeclarationsFromView, getEnabledToolNamesForPrompt, shouldIncludeSubagentDelegationForConfig, } from './clientToolGovernance.js';
9
+ import { reportError } from '@vybestack/llxprt-code-core/utils/errorReporting.js';
10
+ import { ChatSession } from './chatSession.js';
11
+ import { DebugLogger } from '@vybestack/llxprt-code-core/debug/index.js';
12
+ import { HistoryService } from '@vybestack/llxprt-code-core/services/history/HistoryService.js';
13
+ import { ContentConverters } from '@vybestack/llxprt-code-core/services/history/ContentConverters.js';
14
+ import { createSettingsProviderRuntimeContext } from '@vybestack/llxprt-code-core/runtime/settingsRuntimeAdapter.js';
15
+ import { loadAgentRuntime } from '@vybestack/llxprt-code-core/runtime/AgentRuntimeLoader.js';
16
+ import { getErrorMessage } from '@vybestack/llxprt-code-core/utils/errors.js';
17
+ import { isThinkingSupported } from './clientHelpers.js';
18
+ import { estimateTokens as estimateTextTokens } from '@vybestack/llxprt-code-core/utils/toolOutputLimiter.js';
19
+ /**
20
+ * Assembles ephemeral settings into an immutable snapshot for the runtime.
21
+ * Pure function — reads config, no side effects.
22
+ */
23
+ export function buildSettingsSnapshot(config) {
24
+ const rawCompressionThreshold = config.getEphemeralSetting('compression-threshold');
25
+ const compressionThreshold = typeof rawCompressionThreshold === 'number' &&
26
+ Number.isFinite(rawCompressionThreshold)
27
+ ? rawCompressionThreshold
28
+ : undefined;
29
+ const rawContextLimit = config.getEphemeralSetting('context-limit');
30
+ const contextLimit = typeof rawContextLimit === 'number' &&
31
+ Number.isFinite(rawContextLimit) &&
32
+ rawContextLimit > 0
33
+ ? rawContextLimit
34
+ : undefined;
35
+ const rawPreserveThreshold = config.getEphemeralSetting('compression-preserve-threshold');
36
+ const preserveThreshold = typeof rawPreserveThreshold === 'number' &&
37
+ Number.isFinite(rawPreserveThreshold)
38
+ ? rawPreserveThreshold
39
+ : undefined;
40
+ return {
41
+ compressionThreshold: compressionThreshold ?? 0.85,
42
+ contextLimit,
43
+ preserveThreshold: preserveThreshold ?? 0.2,
44
+ telemetry: { enabled: true, target: null },
45
+ tools: getToolGovernanceEphemerals(config),
46
+ 'reasoning.enabled': config.getEphemeralSetting('reasoning.enabled'),
47
+ 'reasoning.includeInContext': config.getEphemeralSetting('reasoning.includeInContext'),
48
+ 'reasoning.includeInResponse': config.getEphemeralSetting('reasoning.includeInResponse'),
49
+ 'reasoning.format': config.getEphemeralSetting('reasoning.format'),
50
+ 'reasoning.stripFromContext': config.getEphemeralSetting('reasoning.stripFromContext'),
51
+ 'reasoning.effort': config.getEphemeralSetting('reasoning.effort'),
52
+ 'reasoning.maxTokens': config.getEphemeralSetting('reasoning.maxTokens'),
53
+ };
54
+ }
55
+ /**
56
+ * Builds the full system instruction: env context, core memory, JIT memory,
57
+ * user memory, MCP instructions, subagent delegation.
58
+ *
59
+ * This is the FULL path used by startChat — differs from the lightweight path
60
+ * in clientLlmUtilities which skips env context, core memory, and JIT memory.
61
+ */
62
+ export async function buildSystemInstruction(config, enabledToolNames, envParts, model) {
63
+ let userMemory = config.isJitContextEnabled()
64
+ ? config.getGlobalMemory()
65
+ : config.getUserMemory();
66
+ const coreMemory = config.getCoreMemory();
67
+ const jitMemory = await config.getJitMemoryForPath(config.getWorkingDir());
68
+ if (jitMemory) {
69
+ userMemory = userMemory ? `${userMemory}\n\n${jitMemory}` : jitMemory;
70
+ }
71
+ const mcpInstructions = config.getMcpClientManager()?.getMcpInstructions();
72
+ const includeSubagentDelegation = await shouldIncludeSubagentDelegationForConfig(config, enabledToolNames);
73
+ const interactionMode = config.isInteractive()
74
+ ? 'interactive'
75
+ : 'non-interactive';
76
+ let systemInstruction = await getCoreSystemPromptAsync({
77
+ userMemory,
78
+ coreMemory,
79
+ mcpInstructions,
80
+ model,
81
+ tools: enabledToolNames,
82
+ includeSubagentDelegation,
83
+ interactionMode,
84
+ });
85
+ const envContextText = envParts
86
+ .map((part) => ('text' in part && part.text ? part.text : ''))
87
+ .join('\n');
88
+ if (envContextText) {
89
+ systemInstruction = envContextText + '\n\n' + systemInstruction;
90
+ }
91
+ return systemInstruction;
92
+ }
93
+ /**
94
+ * Resolves (or creates) the HistoryService and optionally loads extra history.
95
+ */
96
+ function setupHistoryService(storedHistoryService, extraHistory, runtimeState) {
97
+ const logger = new DebugLogger('llxprt:client:start');
98
+ if (storedHistoryService) {
99
+ logger.debug('Reusing stored HistoryService to preserve UI conversation');
100
+ return { historyService: storedHistoryService, reused: true };
101
+ }
102
+ const historyService = new HistoryService();
103
+ if (extraHistory && extraHistory.length > 0) {
104
+ const currentModel = runtimeState.model;
105
+ for (const content of extraHistory) {
106
+ const turnKey = historyService.generateTurnKey();
107
+ historyService.add(ContentConverters.toIContent(content, undefined, undefined, turnKey), currentModel);
108
+ }
109
+ }
110
+ return { historyService, reused: false };
111
+ }
112
+ /**
113
+ * Estimates and sets the system prompt token offset on the history service.
114
+ */
115
+ async function applySystemPromptTokenOffset(historyService, systemInstruction, model, logger) {
116
+ try {
117
+ const tokens = await historyService.estimateTokensForText(systemInstruction, model);
118
+ historyService.setBaseTokenOffset(tokens);
119
+ }
120
+ catch {
121
+ // Token estimation failed - use fallback estimation
122
+ logger.debug(() => `Failed to count system instruction tokens for model ${model}, using fallback`);
123
+ historyService.setBaseTokenOffset(estimateTextTokens(systemInstruction));
124
+ }
125
+ }
126
+ /**
127
+ * Builds the GenerateContentConfig with thinking support if applicable.
128
+ */
129
+ function buildGenerateContentConfig(baseConfig, model) {
130
+ return isThinkingSupported(model)
131
+ ? {
132
+ ...baseConfig,
133
+ thinkingConfig: { thinkingBudget: -1, includeThoughts: true },
134
+ }
135
+ : baseConfig;
136
+ }
137
+ /**
138
+ * Builds the runtime bundle, tool declarations, and ChatSession instance.
139
+ */
140
+ async function buildChatFromRuntime(config, runtimeState, contentGenerator, historyService, generateContentConfig, todoContinuationService, toolRegistry, systemInstruction) {
141
+ const model = runtimeState.model;
142
+ const generationConfigWithThinking = buildGenerateContentConfig(generateContentConfig, model);
143
+ const settings = buildSettingsSnapshot(config);
144
+ const providerRuntime = createSettingsProviderRuntimeContext({
145
+ settingsService: config.getSettingsService(),
146
+ config,
147
+ runtimeId: runtimeState.runtimeId,
148
+ metadata: { source: 'AgentClient.startChat' },
149
+ });
150
+ const runtimeBundle = await loadAgentRuntime({
151
+ profile: {
152
+ config,
153
+ state: runtimeState,
154
+ settings,
155
+ providerRuntime,
156
+ contentGeneratorConfig: config.getContentGeneratorConfig(),
157
+ toolRegistry,
158
+ providerManager: config.getProviderManager(),
159
+ },
160
+ overrides: { historyService, contentGenerator },
161
+ });
162
+ const filteredDeclarations = buildToolDeclarationsFromView(toolRegistry, runtimeBundle.toolsView);
163
+ todoContinuationService.updateTodoToolAvailabilityFromDeclarations(filteredDeclarations);
164
+ const tools = [{ functionDeclarations: filteredDeclarations }];
165
+ const chat = new ChatSession(runtimeBundle.runtimeContext, runtimeBundle.contentGenerator, { systemInstruction, ...generationConfigWithThinking, tools }, []);
166
+ chat.setActiveTodosProvider(async () => {
167
+ const todos = await todoContinuationService.readTodoSnapshot();
168
+ const active = todoContinuationService.getActiveTodos(todos);
169
+ if (active.length === 0)
170
+ return undefined;
171
+ return active.map((t) => `- [${t.status}] ${t.content}`).join('\n');
172
+ });
173
+ return chat;
174
+ }
175
+ /**
176
+ * Stateful factory: creates a ChatSession session.
177
+ * Reuses stored HistoryService when available, creates a new one otherwise.
178
+ * Configures thinking, loads the agent runtime, builds tool declarations.
179
+ */
180
+ export async function createChatSession(deps) {
181
+ const { config, runtimeState, contentGenerator, storedHistoryService, clearStoredHistoryService, extraHistory, generateContentConfig, todoContinuationService, toolRegistry, } = deps;
182
+ const logger = new DebugLogger('llxprt:client:start');
183
+ const { historyService, reused } = setupHistoryService(storedHistoryService, extraHistory, runtimeState);
184
+ const getTokenizerFactory = config['getTokenizerFactory'];
185
+ if (typeof getTokenizerFactory === 'function') {
186
+ const tokenizerFactory = getTokenizerFactory.call(config);
187
+ if (tokenizerFactory) {
188
+ historyService.setTokenizerFactory(tokenizerFactory);
189
+ }
190
+ }
191
+ const enabledToolNames = getEnabledToolNamesForPrompt(config);
192
+ const envParts = await getEnvironmentContext(config);
193
+ const model = runtimeState.model;
194
+ logger.debug(() => `DEBUG [client.startChat]: Model from config: ${model}`);
195
+ const systemInstruction = await buildSystemInstruction(config, enabledToolNames, envParts, model);
196
+ await applySystemPromptTokenOffset(historyService, systemInstruction, model, logger);
197
+ logger.debug(() => `DEBUG [client.startChat]: System instruction includes Flash instructions: ${systemInstruction.includes('IMPORTANT: You MUST use the provided tools')}`);
198
+ const chat = await buildChatFromRuntime(config, runtimeState, contentGenerator, historyService, generateContentConfig, todoContinuationService, toolRegistry, systemInstruction);
199
+ if (reused) {
200
+ clearStoredHistoryService();
201
+ }
202
+ return chat;
203
+ }
204
+ /**
205
+ * Wraps createChatSession with error reporting for the startChat call site.
206
+ */
207
+ export async function createChatSessionSafe(deps) {
208
+ try {
209
+ return await createChatSession(deps);
210
+ }
211
+ catch (error) {
212
+ await reportError(error, 'Error initializing chat session.', deps.extraHistory ?? [], 'startChat');
213
+ throw new Error(`Failed to initialize chat: ${getErrorMessage(error)}`);
214
+ }
215
+ }
216
+ //# sourceMappingURL=ChatSessionFactory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatSessionFactory.js","sourceRoot":"","sources":["../../../src/core/ChatSessionFactory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ /**
7
+ * ConversationManager - Gemini-specific conversation/history recording layer.
8
+ *
9
+ * This class wraps HistoryService with chatSession-specific recording logic,
10
+ * handling Content→IContent conversion, thinking block attachment, usage
11
+ * metadata injection, and model output consolidation.
12
+ */
13
+ import type { Content } from '@google/genai';
14
+ import type { AgentRuntimeContext } from '@vybestack/llxprt-code-core/runtime/AgentRuntimeContext.js';
15
+ import type { HistoryService } from '@vybestack/llxprt-code-core/services/history/HistoryService.js';
16
+ import type { IContent, UsageStats } from '@vybestack/llxprt-code-core/services/history/IContent.js';
17
+ import type { CompletedToolCall } from './coreToolScheduler.js';
18
+ /**
19
+ * ConversationManager handles conversation history management for ChatSession.
20
+ * It provides methods for recording turns, converting Content to IContent,
21
+ * and managing conversation state.
22
+ */
23
+ export declare class ConversationManager {
24
+ private readonly historyService;
25
+ private readonly runtimeContext;
26
+ private readonly model;
27
+ constructor(historyService: HistoryService, runtimeContext: AgentRuntimeContext, model: string);
28
+ /**
29
+ * Get the underlying HistoryService instance
30
+ */
31
+ getHistoryService(): HistoryService;
32
+ /**
33
+ * Creates a position-based matcher for Gemini tool responses.
34
+ * Returns a function that matches tool responses to their calls, or undefined
35
+ * if there are no unmatched tool calls.
36
+ */
37
+ makePositionMatcher(): (() => {
38
+ historyId: string;
39
+ toolName?: string;
40
+ }) | undefined;
41
+ /**
42
+ * Converts user input (Content or Content[]) to IContent[] for history.
43
+ * This consolidates the Content→IContent conversion pattern used in:
44
+ * - Constructor initial history import
45
+ * - sendMessage pre-send
46
+ * - sendMessageStream pre-send
47
+ *
48
+ * These all share the same semantics: model + matcher/idGen.
49
+ */
50
+ convertUserInputToIContents(userContent: Content | Content[]): IContent[];
51
+ /**
52
+ * Imports initial history during ChatSession construction.
53
+ * Validates the history and converts each Content to IContent before adding.
54
+ * Called from ChatSession constructor after ConversationManager is created.
55
+ */
56
+ importInitialHistory(initialHistory: Content[], model: string): void;
57
+ /**
58
+ * Records a completed conversation turn to history.
59
+ * This is the main orchestrator that handles both user and model turns.
60
+ *
61
+ * @param userInput - User's input (Content or Content[] for paired tool call/response)
62
+ * @param modelOutput - Model's output Content array
63
+ * @param automaticFunctionCallingHistory - Optional AFC history from Gemini SDK
64
+ * @param usageMetadata - Optional usage statistics
65
+ */
66
+ recordHistory(userInput: Content | Content[], modelOutput: Content[], automaticFunctionCallingHistory?: Content[], usageMetadata?: UsageStats | null): void;
67
+ /**
68
+ * Handles user Content → IContent conversion, including AFC and paired
69
+ * tool call/response scenarios.
70
+ *
71
+ * Mutates newHistoryEntries by appending user turn entries.
72
+ */
73
+ private _recordUserTurn;
74
+ /**
75
+ * Handles model output filtering, thinking block attachment, consolidation,
76
+ * and usage metadata injection.
77
+ *
78
+ * Mutates newHistoryEntries by appending model turn entries.
79
+ */
80
+ private _recordModelTurn;
81
+ /**
82
+ * Consolidates the parts of a model's turn response.
83
+ * Merges adjacent text content to avoid fragmentation.
84
+ */
85
+ private _consolidateModelOutput;
86
+ /**
87
+ * Adds consolidated model output to history with thinking blocks and usage metadata.
88
+ * Attaches thinking blocks to the first model entry and ensures proper metadata.
89
+ */
90
+ private _addModelOutputToHistory;
91
+ /**
92
+ * Gets the conversation history in Gemini Content format.
93
+ * @param curated - If true, returns curated history; otherwise returns all history
94
+ */
95
+ getHistory(curated?: boolean): Content[];
96
+ /**
97
+ * Clears the chat history.
98
+ */
99
+ clearHistory(): void;
100
+ /**
101
+ * Adds a new entry to the chat history.
102
+ */
103
+ addHistory(content: Content): void;
104
+ /**
105
+ * Sets the full chat history, replacing any existing history.
106
+ */
107
+ setHistory(history: Content[]): void;
108
+ /**
109
+ * Compatibility stub for tool call recording.
110
+ * This is a no-op maintained for backward compatibility.
111
+ */
112
+ recordCompletedToolCalls(_model: string, _toolCalls: CompletedToolCall[]): void;
113
+ }
@@ -0,0 +1,311 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { ContentConverters } from '@vybestack/llxprt-code-core/services/history/ContentConverters.js';
7
+ import { isFunctionResponse } from '@vybestack/llxprt-code-core/utils/messageInspectors.js';
8
+ import { isThoughtPart } from '@vybestack/llxprt-code-core/core/chatSessionTypes.js';
9
+ import { extractCuratedHistory, hasTextContent, validateHistory, } from './MessageConverter.js';
10
+ function appendTextContentParts(lastContent, content) {
11
+ const lastParts = lastContent.parts ?? [];
12
+ const contentParts = content.parts ?? [];
13
+ lastParts[0].text += contentParts[0].text ?? '';
14
+ if (contentParts.length > 1) {
15
+ lastParts.push(...contentParts.slice(1));
16
+ }
17
+ }
18
+ /**
19
+ * ConversationManager handles conversation history management for ChatSession.
20
+ * It provides methods for recording turns, converting Content to IContent,
21
+ * and managing conversation state.
22
+ */
23
+ export class ConversationManager {
24
+ historyService;
25
+ runtimeContext;
26
+ model;
27
+ constructor(historyService, runtimeContext, model) {
28
+ this.historyService = historyService;
29
+ this.runtimeContext = runtimeContext;
30
+ this.model = model;
31
+ }
32
+ /**
33
+ * Get the underlying HistoryService instance
34
+ */
35
+ getHistoryService() {
36
+ return this.historyService;
37
+ }
38
+ /**
39
+ * Creates a position-based matcher for Gemini tool responses.
40
+ * Returns a function that matches tool responses to their calls, or undefined
41
+ * if there are no unmatched tool calls.
42
+ */
43
+ makePositionMatcher() {
44
+ const queue = this.historyService
45
+ .findUnmatchedToolCalls()
46
+ .map((b) => ({ historyId: b.id, toolName: b.name }));
47
+ // Return undefined if there are no unmatched tool calls
48
+ if (queue.length === 0) {
49
+ return undefined;
50
+ }
51
+ // Return a function that always returns a valid value (never undefined)
52
+ return () => {
53
+ const result = queue.shift();
54
+ // If queue is empty, return a fallback value
55
+ return result ?? { historyId: '', toolName: undefined };
56
+ };
57
+ }
58
+ /**
59
+ * Converts user input (Content or Content[]) to IContent[] for history.
60
+ * This consolidates the Content→IContent conversion pattern used in:
61
+ * - Constructor initial history import
62
+ * - sendMessage pre-send
63
+ * - sendMessageStream pre-send
64
+ *
65
+ * These all share the same semantics: model + matcher/idGen.
66
+ */
67
+ convertUserInputToIContents(userContent) {
68
+ const contents = Array.isArray(userContent) ? userContent : [userContent];
69
+ const matcher = this.makePositionMatcher();
70
+ return contents.map((content) => {
71
+ const turnKey = this.historyService.generateTurnKey();
72
+ const idGen = this.historyService.getIdGeneratorCallback(turnKey);
73
+ return ContentConverters.toIContent(content, idGen, matcher, turnKey);
74
+ });
75
+ }
76
+ /**
77
+ * Imports initial history during ChatSession construction.
78
+ * Validates the history and converts each Content to IContent before adding.
79
+ * Called from ChatSession constructor after ConversationManager is created.
80
+ */
81
+ importInitialHistory(initialHistory, model) {
82
+ if (initialHistory.length === 0) {
83
+ return;
84
+ }
85
+ // Validate before importing
86
+ validateHistory(initialHistory);
87
+ // Convert and add each entry
88
+ const matcher = this.makePositionMatcher();
89
+ for (const content of initialHistory) {
90
+ const turnKey = this.historyService.generateTurnKey();
91
+ const idGen = this.historyService.getIdGeneratorCallback(turnKey);
92
+ this.historyService.add(ContentConverters.toIContent(content, idGen, matcher, turnKey), model);
93
+ }
94
+ }
95
+ /**
96
+ * Records a completed conversation turn to history.
97
+ * This is the main orchestrator that handles both user and model turns.
98
+ *
99
+ * @param userInput - User's input (Content or Content[] for paired tool call/response)
100
+ * @param modelOutput - Model's output Content array
101
+ * @param automaticFunctionCallingHistory - Optional AFC history from Gemini SDK
102
+ * @param usageMetadata - Optional usage statistics
103
+ */
104
+ recordHistory(userInput, modelOutput, automaticFunctionCallingHistory, usageMetadata) {
105
+ const newHistoryEntries = [];
106
+ // Capture user input characteristics for model turn logic
107
+ const userInputWasArray = Array.isArray(userInput);
108
+ const userInputWasFunctionResponse = !userInputWasArray && isFunctionResponse(userInput);
109
+ const hasAfc = !!(automaticFunctionCallingHistory &&
110
+ automaticFunctionCallingHistory.length > 0);
111
+ // Record user turn
112
+ this._recordUserTurn(userInput, automaticFunctionCallingHistory, newHistoryEntries);
113
+ // Record model turn
114
+ this._recordModelTurn(modelOutput, usageMetadata, newHistoryEntries, userInputWasArray, userInputWasFunctionResponse, hasAfc);
115
+ // Add all entries to history service
116
+ for (const entry of newHistoryEntries) {
117
+ this.historyService.add(entry, this.model);
118
+ }
119
+ }
120
+ /**
121
+ * Handles user Content → IContent conversion, including AFC and paired
122
+ * tool call/response scenarios.
123
+ *
124
+ * Mutates newHistoryEntries by appending user turn entries.
125
+ */
126
+ _recordUserTurn(userInput, automaticFunctionCallingHistory, newHistoryEntries) {
127
+ if (automaticFunctionCallingHistory &&
128
+ automaticFunctionCallingHistory.length > 0) {
129
+ // AFC branch: extract curated history
130
+ const curatedAfc = extractCuratedHistory(automaticFunctionCallingHistory);
131
+ for (const content of curatedAfc) {
132
+ const turnKey = this.historyService.generateTurnKey();
133
+ newHistoryEntries.push(ContentConverters.toIContent(content, undefined, undefined, turnKey));
134
+ }
135
+ }
136
+ else {
137
+ const matcher = this.makePositionMatcher();
138
+ // Handle both single Content and Content[] (for paired tool call/response)
139
+ if (Array.isArray(userInput)) {
140
+ // This is a paired tool call/response from the executor
141
+ // Add each part to history
142
+ for (const content of userInput) {
143
+ const turnKey = this.historyService.generateTurnKey();
144
+ const idGen = this.historyService.getIdGeneratorCallback(turnKey);
145
+ const userIContent = ContentConverters.toIContent(content, idGen, matcher, turnKey);
146
+ newHistoryEntries.push(userIContent);
147
+ }
148
+ }
149
+ else {
150
+ // Normal user message
151
+ const turnKey = this.historyService.generateTurnKey();
152
+ const idGen = this.historyService.getIdGeneratorCallback(turnKey);
153
+ const userIContent = ContentConverters.toIContent(userInput, idGen, matcher, turnKey);
154
+ newHistoryEntries.push(userIContent);
155
+ }
156
+ }
157
+ }
158
+ /**
159
+ * Handles model output filtering, thinking block attachment, consolidation,
160
+ * and usage metadata injection.
161
+ *
162
+ * Mutates newHistoryEntries by appending model turn entries.
163
+ */
164
+ _recordModelTurn(modelOutput, usageMetadata, newHistoryEntries, userInputWasArray, userInputWasFunctionResponse, hasAfc) {
165
+ // Filter out thoughts based on reasoning configuration
166
+ const includeThoughtsInHistory = this.runtimeContext.ephemerals.reasoning.includeInContext();
167
+ const nonThoughtModelOutput = modelOutput
168
+ .map((content) => ({
169
+ ...content,
170
+ parts: (content.parts ?? []).filter((part) => !isThoughtPart(part)),
171
+ }))
172
+ .filter((content) => content.parts.length > 0);
173
+ // Extract thinking blocks if needed
174
+ const thoughtBlocks = includeThoughtsInHistory
175
+ ? modelOutput
176
+ .flatMap((content) => content.parts ?? [])
177
+ .filter(isThoughtPart)
178
+ .map((part) => ({
179
+ type: 'thinking',
180
+ thought: (part.text ?? '').trim(),
181
+ sourceField: part.llxprtSourceField ?? 'thought',
182
+ signature: part.thoughtSignature,
183
+ }))
184
+ .filter((block) => block.thought.length > 0)
185
+ : [];
186
+ // Determine output contents
187
+ let outputContents = [];
188
+ if (nonThoughtModelOutput.length > 0) {
189
+ outputContents = nonThoughtModelOutput;
190
+ }
191
+ else if (modelOutput.length === 0 &&
192
+ !userInputWasArray &&
193
+ !userInputWasFunctionResponse &&
194
+ !hasAfc) {
195
+ // Add an empty model response if the model truly returned nothing
196
+ outputContents.push({ role: 'model', parts: [] });
197
+ }
198
+ if (outputContents.length === 0 && thoughtBlocks.length > 0) {
199
+ outputContents = [{ role: 'model', parts: [] }];
200
+ }
201
+ // Consolidate model response parts
202
+ const consolidatedOutputContents = this._consolidateModelOutput(outputContents);
203
+ // Add consolidated output to new history with thinking blocks
204
+ this._addModelOutputToHistory(consolidatedOutputContents, thoughtBlocks, usageMetadata, newHistoryEntries);
205
+ }
206
+ /**
207
+ * Consolidates the parts of a model's turn response.
208
+ * Merges adjacent text content to avoid fragmentation.
209
+ */
210
+ _consolidateModelOutput(outputContents) {
211
+ const consolidatedOutputContents = [];
212
+ if (outputContents.length > 0) {
213
+ for (const content of outputContents) {
214
+ const lastContent = consolidatedOutputContents[consolidatedOutputContents.length - 1];
215
+ if (hasTextContent(lastContent) && hasTextContent(content)) {
216
+ appendTextContentParts(lastContent, content);
217
+ }
218
+ else {
219
+ consolidatedOutputContents.push(content);
220
+ }
221
+ }
222
+ }
223
+ return consolidatedOutputContents;
224
+ }
225
+ /**
226
+ * Adds consolidated model output to history with thinking blocks and usage metadata.
227
+ * Attaches thinking blocks to the first model entry and ensures proper metadata.
228
+ */
229
+ _addModelOutputToHistory(consolidatedOutputContents, thoughtBlocks, usageMetadata, newHistoryEntries) {
230
+ let didAttachThoughtBlocks = false;
231
+ for (const content of consolidatedOutputContents) {
232
+ const turnKey = this.historyService.generateTurnKey();
233
+ const iContent = ContentConverters.toIContent(content, undefined, undefined, turnKey);
234
+ // Attach thinking blocks to first model entry
235
+ if (thoughtBlocks.length > 0 && !didAttachThoughtBlocks) {
236
+ iContent.blocks = [...thoughtBlocks, ...iContent.blocks];
237
+ didAttachThoughtBlocks = true;
238
+ }
239
+ // Add usage metadata if available
240
+ if (usageMetadata !== undefined && usageMetadata !== null) {
241
+ iContent.metadata = {
242
+ ...iContent.metadata,
243
+ usage: usageMetadata,
244
+ };
245
+ }
246
+ newHistoryEntries.push(iContent);
247
+ }
248
+ // If we have thinking blocks but nowhere to attach them, create standalone entry
249
+ if (thoughtBlocks.length > 0 && !didAttachThoughtBlocks) {
250
+ const turnKey = this.historyService.generateTurnKey();
251
+ const iContent = {
252
+ speaker: 'ai',
253
+ blocks: thoughtBlocks,
254
+ metadata: { turnId: turnKey },
255
+ };
256
+ if (usageMetadata !== undefined && usageMetadata !== null) {
257
+ iContent.metadata = {
258
+ ...iContent.metadata,
259
+ usage: usageMetadata,
260
+ };
261
+ }
262
+ newHistoryEntries.push(iContent);
263
+ }
264
+ }
265
+ /**
266
+ * Gets the conversation history in Gemini Content format.
267
+ * @param curated - If true, returns curated history; otherwise returns all history
268
+ */
269
+ getHistory(curated = false) {
270
+ // Get history from HistoryService in IContent format
271
+ const iContents = curated
272
+ ? this.historyService.getCurated()
273
+ : this.historyService.getAll();
274
+ // Convert to Gemini Content format
275
+ const contents = ContentConverters.toGeminiContents(iContents);
276
+ // Deep copy the history to avoid mutating the history outside of the
277
+ // chat session.
278
+ return structuredClone(contents);
279
+ }
280
+ /**
281
+ * Clears the chat history.
282
+ */
283
+ clearHistory() {
284
+ this.historyService.clear();
285
+ }
286
+ /**
287
+ * Adds a new entry to the chat history.
288
+ */
289
+ addHistory(content) {
290
+ const turnKey = this.historyService.generateTurnKey();
291
+ this.historyService.add(ContentConverters.toIContent(content, undefined, undefined, turnKey), this.model);
292
+ }
293
+ /**
294
+ * Sets the full chat history, replacing any existing history.
295
+ */
296
+ setHistory(history) {
297
+ this.historyService.clear();
298
+ for (const content of history) {
299
+ const turnKey = this.historyService.generateTurnKey();
300
+ this.historyService.add(ContentConverters.toIContent(content, undefined, undefined, turnKey), this.model);
301
+ }
302
+ }
303
+ /**
304
+ * Compatibility stub for tool call recording.
305
+ * This is a no-op maintained for backward compatibility.
306
+ */
307
+ recordCompletedToolCalls(_model, _toolCalls) {
308
+ // No-op stub for compatibility
309
+ }
310
+ }
311
+ //# sourceMappingURL=ConversationManager.js.map