@vybestack/llxprt-code-core 0.1.23 → 0.2.2-nightly.250908.7b895396
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -17
- package/dist/src/adapters/IStreamAdapter.d.ts +3 -3
- package/dist/src/auth/oauth-errors.d.ts +173 -0
- package/dist/src/auth/oauth-errors.js +461 -0
- package/dist/src/auth/oauth-errors.js.map +1 -0
- package/dist/src/auth/precedence.d.ts +1 -5
- package/dist/src/auth/precedence.js +28 -48
- package/dist/src/auth/precedence.js.map +1 -1
- package/dist/src/auth/token-store.js +2 -2
- package/dist/src/auth/token-store.js.map +1 -1
- package/dist/src/auth/types.d.ts +4 -4
- package/dist/src/code_assist/codeAssist.js +19 -6
- package/dist/src/code_assist/codeAssist.js.map +1 -1
- package/dist/src/code_assist/oauth2.d.ts +7 -0
- package/dist/src/code_assist/oauth2.js +82 -32
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/server.js +15 -4
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/setup.js +9 -0
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/config/index.d.ts +7 -0
- package/dist/src/config/index.js +8 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/core/client.d.ts +15 -20
- package/dist/src/core/client.js +98 -124
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/compression-config.d.ts +10 -0
- package/dist/src/core/compression-config.js +17 -0
- package/dist/src/core/compression-config.js.map +1 -0
- package/dist/src/core/coreToolScheduler.js +50 -15
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +68 -9
- package/dist/src/core/geminiChat.js +940 -405
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.js +70 -19
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
- package/dist/src/core/prompts.js +35 -25
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/turn.d.ts +1 -0
- package/dist/src/core/turn.js +8 -6
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/ide/ide-client.d.ts +1 -1
- package/dist/src/ide/ide-client.js +12 -6
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.js +5 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/prompt-config/TemplateEngine.js +17 -0
- package/dist/src/prompt-config/TemplateEngine.js.map +1 -1
- package/dist/src/prompt-config/defaults/core-defaults.js +39 -32
- package/dist/src/prompt-config/defaults/core-defaults.js.map +1 -1
- package/dist/src/prompt-config/defaults/core.md +2 -0
- package/dist/src/prompt-config/defaults/provider-defaults.js +34 -27
- package/dist/src/prompt-config/defaults/provider-defaults.js.map +1 -1
- package/dist/src/prompt-config/defaults/providers/gemini/core.md +270 -0
- package/dist/src/prompt-config/defaults/providers/gemini/models/gemini-2.5-flash/core.md +12 -0
- package/dist/src/prompt-config/defaults/providers/gemini/models/gemini-2.5-flash/gemini-2-5-flash/core.md +12 -0
- package/dist/src/prompt-config/types.d.ts +2 -0
- package/dist/src/providers/BaseProvider.d.ts +39 -13
- package/dist/src/providers/BaseProvider.js +102 -28
- package/dist/src/providers/BaseProvider.js.map +1 -1
- package/dist/src/providers/IProvider.d.ts +17 -3
- package/dist/src/providers/LoggingProviderWrapper.d.ts +10 -3
- package/dist/src/providers/LoggingProviderWrapper.js +33 -27
- package/dist/src/providers/LoggingProviderWrapper.js.map +1 -1
- package/dist/src/providers/ProviderContentGenerator.d.ts +2 -2
- package/dist/src/providers/ProviderContentGenerator.js +9 -6
- package/dist/src/providers/ProviderContentGenerator.js.map +1 -1
- package/dist/src/providers/ProviderManager.d.ts +4 -0
- package/dist/src/providers/ProviderManager.js +6 -0
- package/dist/src/providers/ProviderManager.js.map +1 -1
- package/dist/src/providers/anthropic/AnthropicProvider.d.ts +34 -21
- package/dist/src/providers/anthropic/AnthropicProvider.js +505 -492
- package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
- package/dist/src/providers/gemini/GeminiProvider.d.ts +23 -9
- package/dist/src/providers/gemini/GeminiProvider.js +344 -515
- package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
- package/dist/src/providers/openai/ConversationCache.d.ts +3 -3
- package/dist/src/providers/openai/IChatGenerateParams.d.ts +9 -4
- package/dist/src/providers/openai/OpenAIProvider.d.ts +46 -96
- package/dist/src/providers/openai/OpenAIProvider.js +580 -1392
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
- package/dist/src/providers/openai/buildResponsesRequest.d.ts +3 -3
- package/dist/src/providers/openai/buildResponsesRequest.js +67 -37
- package/dist/src/providers/openai/buildResponsesRequest.js.map +1 -1
- package/dist/src/providers/openai/estimateRemoteTokens.d.ts +2 -2
- package/dist/src/providers/openai/estimateRemoteTokens.js +21 -8
- package/dist/src/providers/openai/estimateRemoteTokens.js.map +1 -1
- package/dist/src/providers/openai/parseResponsesStream.d.ts +6 -2
- package/dist/src/providers/openai/parseResponsesStream.js +99 -391
- package/dist/src/providers/openai/parseResponsesStream.js.map +1 -1
- package/dist/src/providers/openai/syntheticToolResponses.d.ts +5 -5
- package/dist/src/providers/openai/syntheticToolResponses.js +102 -91
- package/dist/src/providers/openai/syntheticToolResponses.js.map +1 -1
- package/dist/src/providers/openai-responses/OpenAIResponsesProvider.d.ts +89 -0
- package/dist/src/providers/openai-responses/OpenAIResponsesProvider.js +451 -0
- package/dist/src/providers/openai-responses/OpenAIResponsesProvider.js.map +1 -0
- package/dist/src/providers/openai-responses/index.d.ts +1 -0
- package/dist/src/providers/openai-responses/index.js +2 -0
- package/dist/src/providers/openai-responses/index.js.map +1 -0
- package/dist/src/providers/tokenizers/OpenAITokenizer.js +3 -3
- package/dist/src/providers/tokenizers/OpenAITokenizer.js.map +1 -1
- package/dist/src/providers/types.d.ts +1 -1
- package/dist/src/services/ClipboardService.d.ts +19 -0
- package/dist/src/services/ClipboardService.js +66 -0
- package/dist/src/services/ClipboardService.js.map +1 -0
- package/dist/src/services/history/ContentConverters.d.ts +43 -0
- package/dist/src/services/history/ContentConverters.js +325 -0
- package/dist/src/services/history/ContentConverters.js.map +1 -0
- package/dist/src/{providers/IMessage.d.ts → services/history/HistoryEvents.d.ts} +16 -22
- package/dist/src/{providers/IMessage.js → services/history/HistoryEvents.js} +1 -1
- package/dist/src/services/history/HistoryEvents.js.map +1 -0
- package/dist/src/services/history/HistoryService.d.ts +220 -0
- package/dist/src/services/history/HistoryService.js +673 -0
- package/dist/src/services/history/HistoryService.js.map +1 -0
- package/dist/src/services/history/IContent.d.ts +183 -0
- package/dist/src/services/history/IContent.js +104 -0
- package/dist/src/services/history/IContent.js.map +1 -0
- package/dist/src/services/index.d.ts +1 -0
- package/dist/src/services/index.js +1 -0
- package/dist/src/services/index.js.map +1 -1
- package/dist/src/settings/SettingsService.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +16 -4
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/tools/IToolFormatter.d.ts +2 -2
- package/dist/src/tools/ToolFormatter.d.ts +42 -4
- package/dist/src/tools/ToolFormatter.js +151 -64
- package/dist/src/tools/ToolFormatter.js.map +1 -1
- package/dist/src/tools/doubleEscapeUtils.d.ts +57 -0
- package/dist/src/tools/doubleEscapeUtils.js +241 -0
- package/dist/src/tools/doubleEscapeUtils.js.map +1 -0
- package/dist/src/tools/read-file.d.ts +6 -1
- package/dist/src/tools/read-file.js +25 -11
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/todo-schemas.d.ts +4 -4
- package/dist/src/tools/tool-registry.d.ts +8 -1
- package/dist/src/tools/tool-registry.js +79 -23
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tools.js +13 -0
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/write-file.d.ts +6 -1
- package/dist/src/tools/write-file.js +48 -26
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/types/modelParams.d.ts +12 -0
- package/dist/src/utils/bfsFileSearch.js +2 -6
- package/dist/src/utils/bfsFileSearch.js.map +1 -1
- package/dist/src/utils/schemaValidator.js +16 -1
- package/dist/src/utils/schemaValidator.js.map +1 -1
- package/package.json +8 -7
- package/dist/src/providers/IMessage.js.map +0 -1
- package/dist/src/providers/adapters/GeminiCompatibleWrapper.d.ts +0 -69
- package/dist/src/providers/adapters/GeminiCompatibleWrapper.js +0 -577
- package/dist/src/providers/adapters/GeminiCompatibleWrapper.js.map +0 -1
@@ -0,0 +1,325 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2025 Vybestack LLC
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
import { DebugLogger } from '../../debug/index.js';
|
17
|
+
/**
|
18
|
+
* Converts between Gemini Content format and IContent format
|
19
|
+
*/
|
20
|
+
export class ContentConverters {
|
21
|
+
static logger = new DebugLogger('llxprt:content:converters');
|
22
|
+
static normalizeToHistoryId(id) {
|
23
|
+
if (!id)
|
24
|
+
return undefined;
|
25
|
+
if (id.startsWith('hist_tool_'))
|
26
|
+
return id;
|
27
|
+
if (id.startsWith('call_'))
|
28
|
+
return `hist_tool_${id.substring('call_'.length)}`;
|
29
|
+
if (id.startsWith('toolu_'))
|
30
|
+
return `hist_tool_${id.substring('toolu_'.length)}`;
|
31
|
+
// Unknown provider format: preserve suffix, add history prefix
|
32
|
+
return `hist_tool_${id}`;
|
33
|
+
}
|
34
|
+
/**
|
35
|
+
* Convert IContent to Gemini Content format
|
36
|
+
*/
|
37
|
+
static toGeminiContent(iContent) {
|
38
|
+
this.logger.debug('Converting IContent to Gemini Content:', {
|
39
|
+
speaker: iContent.speaker,
|
40
|
+
blockCount: iContent.blocks?.length || 0,
|
41
|
+
blockTypes: iContent.blocks?.map((b) => b.type) || [],
|
42
|
+
toolCallIds: iContent.blocks
|
43
|
+
?.filter((b) => b.type === 'tool_call')
|
44
|
+
.map((b) => b.id) || [],
|
45
|
+
toolResponseCallIds: iContent.blocks
|
46
|
+
?.filter((b) => b.type === 'tool_response')
|
47
|
+
.map((b) => b.callId) || [],
|
48
|
+
});
|
49
|
+
// Tool responses should have 'user' role in Gemini format
|
50
|
+
let role;
|
51
|
+
if (iContent.speaker === 'tool') {
|
52
|
+
role = 'user';
|
53
|
+
}
|
54
|
+
else if (iContent.speaker === 'human') {
|
55
|
+
role = 'user';
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
role = 'model';
|
59
|
+
}
|
60
|
+
const parts = [];
|
61
|
+
for (const block of iContent.blocks) {
|
62
|
+
switch (block.type) {
|
63
|
+
case 'text': {
|
64
|
+
const textBlock = block;
|
65
|
+
parts.push({ text: textBlock.text });
|
66
|
+
break;
|
67
|
+
}
|
68
|
+
case 'tool_call': {
|
69
|
+
const toolCall = block;
|
70
|
+
this.logger.debug('Converting tool_call block to functionCall:', {
|
71
|
+
id: toolCall.id,
|
72
|
+
name: toolCall.name,
|
73
|
+
hasParameters: !!toolCall.parameters,
|
74
|
+
});
|
75
|
+
parts.push({
|
76
|
+
functionCall: {
|
77
|
+
name: toolCall.name,
|
78
|
+
args: toolCall.parameters,
|
79
|
+
id: toolCall.id,
|
80
|
+
},
|
81
|
+
});
|
82
|
+
break;
|
83
|
+
}
|
84
|
+
case 'tool_response': {
|
85
|
+
const toolResponse = block;
|
86
|
+
this.logger.debug('Converting tool_response block to functionResponse:', {
|
87
|
+
callId: toolResponse.callId,
|
88
|
+
toolName: toolResponse.toolName,
|
89
|
+
hasResult: !!toolResponse.result,
|
90
|
+
hasError: !!toolResponse.error,
|
91
|
+
});
|
92
|
+
parts.push({
|
93
|
+
functionResponse: {
|
94
|
+
name: toolResponse.toolName,
|
95
|
+
response: toolResponse.result,
|
96
|
+
id: toolResponse.callId,
|
97
|
+
},
|
98
|
+
});
|
99
|
+
break;
|
100
|
+
}
|
101
|
+
case 'thinking': {
|
102
|
+
const thinkingBlock = block;
|
103
|
+
parts.push({
|
104
|
+
thought: true,
|
105
|
+
text: thinkingBlock.thought,
|
106
|
+
});
|
107
|
+
break;
|
108
|
+
}
|
109
|
+
case 'media': {
|
110
|
+
// Media blocks can be converted to inline data parts
|
111
|
+
// For now, we'll skip these as GeminiChat doesn't handle them yet
|
112
|
+
break;
|
113
|
+
}
|
114
|
+
case 'code': {
|
115
|
+
// Code blocks are treated as text in Gemini format
|
116
|
+
const codeBlock = block;
|
117
|
+
const codeText = codeBlock.language
|
118
|
+
? `\`\`\`${codeBlock.language}\n${codeBlock.code}\n\`\`\``
|
119
|
+
: codeBlock.code;
|
120
|
+
parts.push({ text: codeText });
|
121
|
+
break;
|
122
|
+
}
|
123
|
+
default:
|
124
|
+
// Ignore unknown block types
|
125
|
+
break;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
// Keep empty parts array for empty model responses
|
129
|
+
// This is valid in Gemini Content format
|
130
|
+
const result = { role, parts };
|
131
|
+
this.logger.debug('Converted to Gemini Content:', {
|
132
|
+
role,
|
133
|
+
partCount: parts.length,
|
134
|
+
partTypes: parts.map((p) => {
|
135
|
+
if ('text' in p)
|
136
|
+
return 'text';
|
137
|
+
if ('functionCall' in p)
|
138
|
+
return 'functionCall';
|
139
|
+
if ('functionResponse' in p)
|
140
|
+
return 'functionResponse';
|
141
|
+
if ('thought' in p)
|
142
|
+
return 'thought';
|
143
|
+
return 'other';
|
144
|
+
}),
|
145
|
+
functionCallIds: parts
|
146
|
+
.filter((p) => 'functionCall' in p)
|
147
|
+
.map((p) => p.functionCall?.id),
|
148
|
+
functionResponseIds: parts
|
149
|
+
.filter((p) => 'functionResponse' in p)
|
150
|
+
.map((p) => p.functionResponse?.id),
|
151
|
+
});
|
152
|
+
return result;
|
153
|
+
}
|
154
|
+
/**
|
155
|
+
* Convert Gemini Content to IContent format
|
156
|
+
*/
|
157
|
+
static toIContent(content, generateIdCb, getNextUnmatchedToolCall) {
|
158
|
+
this.logger.debug('Converting Gemini Content to IContent:', {
|
159
|
+
role: content.role,
|
160
|
+
partCount: content.parts?.length || 0,
|
161
|
+
partTypes: content.parts?.map((p) => {
|
162
|
+
if ('text' in p)
|
163
|
+
return 'text';
|
164
|
+
if ('functionCall' in p)
|
165
|
+
return 'functionCall';
|
166
|
+
if ('functionResponse' in p)
|
167
|
+
return 'functionResponse';
|
168
|
+
if ('thought' in p)
|
169
|
+
return 'thought';
|
170
|
+
return 'other';
|
171
|
+
}) || [],
|
172
|
+
functionCallIds: content.parts
|
173
|
+
?.filter((p) => 'functionCall' in p)
|
174
|
+
.map((p) => p.functionCall?.id) || [],
|
175
|
+
functionResponseIds: content.parts
|
176
|
+
?.filter((p) => 'functionResponse' in p)
|
177
|
+
.map((p) => p.functionResponse
|
178
|
+
?.id) || [],
|
179
|
+
});
|
180
|
+
const speaker = content.role === 'user' ? 'human' : 'ai';
|
181
|
+
const blocks = [];
|
182
|
+
// Handle empty parts array explicitly
|
183
|
+
if (!content.parts || content.parts.length === 0) {
|
184
|
+
// Empty content - keep it empty
|
185
|
+
// This represents an empty model response
|
186
|
+
}
|
187
|
+
else if (content.parts) {
|
188
|
+
for (const part of content.parts) {
|
189
|
+
if ('text' in part && part.text !== undefined) {
|
190
|
+
// Check if this is a thinking block
|
191
|
+
if ('thought' in part && part.thought) {
|
192
|
+
blocks.push({
|
193
|
+
type: 'thinking',
|
194
|
+
thought: part.text,
|
195
|
+
isHidden: true,
|
196
|
+
});
|
197
|
+
}
|
198
|
+
else {
|
199
|
+
blocks.push({
|
200
|
+
type: 'text',
|
201
|
+
text: part.text,
|
202
|
+
});
|
203
|
+
}
|
204
|
+
}
|
205
|
+
else if ('functionCall' in part && part.functionCall) {
|
206
|
+
// Preserve original ID by normalizing prefix; generate only if missing.
|
207
|
+
const normalized = this.normalizeToHistoryId(part.functionCall.id);
|
208
|
+
const finalId = normalized ?? (generateIdCb ? generateIdCb() : generateId());
|
209
|
+
this.logger.debug('Converting functionCall to tool_call block:', {
|
210
|
+
originalId: part.functionCall.id,
|
211
|
+
finalId,
|
212
|
+
name: part.functionCall.name,
|
213
|
+
usedCallback: !!generateIdCb && !normalized,
|
214
|
+
});
|
215
|
+
blocks.push({
|
216
|
+
type: 'tool_call',
|
217
|
+
id: finalId,
|
218
|
+
name: part.functionCall.name || '',
|
219
|
+
parameters: part.functionCall.args || {},
|
220
|
+
});
|
221
|
+
}
|
222
|
+
else if ('functionResponse' in part && part.functionResponse) {
|
223
|
+
// Prefer provided ID (normalized). If absent, use positional matcher; else generate.
|
224
|
+
const normalized = this.normalizeToHistoryId(part.functionResponse.id);
|
225
|
+
const matched = !normalized
|
226
|
+
? getNextUnmatchedToolCall?.()
|
227
|
+
: undefined;
|
228
|
+
const callId = normalized ??
|
229
|
+
matched?.historyId ??
|
230
|
+
(generateIdCb ? generateIdCb() : generateId());
|
231
|
+
this.logger.debug('Converting functionResponse to tool_response block:', {
|
232
|
+
originalId: part.functionResponse.id,
|
233
|
+
finalId: callId,
|
234
|
+
toolName: part.functionResponse.name,
|
235
|
+
matchedByPosition: !!matched,
|
236
|
+
});
|
237
|
+
blocks.push({
|
238
|
+
type: 'tool_response',
|
239
|
+
callId,
|
240
|
+
toolName: (matched?.toolName ||
|
241
|
+
part.functionResponse.name ||
|
242
|
+
''),
|
243
|
+
result: part.functionResponse.response || {},
|
244
|
+
});
|
245
|
+
}
|
246
|
+
else if ('inlineData' in part && part.inlineData) {
|
247
|
+
// Handle inline data (media)
|
248
|
+
blocks.push({
|
249
|
+
type: 'media',
|
250
|
+
mimeType: part.inlineData.mimeType || '',
|
251
|
+
data: part.inlineData.data || '',
|
252
|
+
encoding: 'base64',
|
253
|
+
});
|
254
|
+
}
|
255
|
+
}
|
256
|
+
}
|
257
|
+
// Handle tool responses specially - they should have 'tool' speaker
|
258
|
+
// Tool responses come from user role but are tool speaker in IContent
|
259
|
+
const finalSpeaker = content.role === 'user' &&
|
260
|
+
blocks.length > 0 &&
|
261
|
+
blocks.every((b) => b.type === 'tool_response')
|
262
|
+
? 'tool'
|
263
|
+
: speaker;
|
264
|
+
const result = {
|
265
|
+
speaker: finalSpeaker,
|
266
|
+
blocks,
|
267
|
+
metadata: {},
|
268
|
+
};
|
269
|
+
this.logger.debug('Converted to IContent:', {
|
270
|
+
originalRole: content.role,
|
271
|
+
finalSpeaker,
|
272
|
+
blockCount: blocks.length,
|
273
|
+
blockTypes: blocks.map((b) => b.type),
|
274
|
+
toolCallIds: blocks
|
275
|
+
.filter((b) => b.type === 'tool_call')
|
276
|
+
.map((b) => b.id),
|
277
|
+
toolResponseCallIds: blocks
|
278
|
+
.filter((b) => b.type === 'tool_response')
|
279
|
+
.map((b) => b.callId),
|
280
|
+
});
|
281
|
+
return result;
|
282
|
+
}
|
283
|
+
/**
|
284
|
+
* Convert array of IContent to array of Gemini Content
|
285
|
+
*/
|
286
|
+
static toGeminiContents(iContents) {
|
287
|
+
this.logger.debug('Converting IContent array to Gemini Contents:', {
|
288
|
+
count: iContents.length,
|
289
|
+
speakers: iContents.map((ic) => ic.speaker),
|
290
|
+
totalToolCalls: iContents.reduce((acc, ic) => acc + ic.blocks.filter((b) => b.type === 'tool_call').length, 0),
|
291
|
+
totalToolResponses: iContents.reduce((acc, ic) => acc + ic.blocks.filter((b) => b.type === 'tool_response').length, 0),
|
292
|
+
});
|
293
|
+
const results = iContents.map((ic) => this.toGeminiContent(ic));
|
294
|
+
this.logger.debug('Conversion complete:', {
|
295
|
+
resultCount: results.length,
|
296
|
+
roles: results.map((r) => r.role),
|
297
|
+
});
|
298
|
+
return results;
|
299
|
+
}
|
300
|
+
/**
|
301
|
+
* Convert array of Gemini Content to array of IContent
|
302
|
+
*/
|
303
|
+
static toIContents(contents) {
|
304
|
+
this.logger.debug('Converting Gemini Contents array to IContent:', {
|
305
|
+
count: contents.length,
|
306
|
+
roles: contents.map((c) => c.role),
|
307
|
+
totalFunctionCalls: contents.reduce((acc, c) => acc + (c.parts?.filter((p) => 'functionCall' in p).length || 0), 0),
|
308
|
+
totalFunctionResponses: contents.reduce((acc, c) => acc + (c.parts?.filter((p) => 'functionResponse' in p).length || 0), 0),
|
309
|
+
});
|
310
|
+
const results = contents.map((c) => this.toIContent(c));
|
311
|
+
this.logger.debug('Conversion complete:', {
|
312
|
+
resultCount: results.length,
|
313
|
+
speakers: results.map((r) => r.speaker),
|
314
|
+
});
|
315
|
+
return results;
|
316
|
+
}
|
317
|
+
}
|
318
|
+
/**
|
319
|
+
* Generate a unique ID for tool calls
|
320
|
+
*/
|
321
|
+
function generateId() {
|
322
|
+
// Use normalized history ID prefix; providers convert prefixes as needed.
|
323
|
+
return `hist_tool_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
324
|
+
}
|
325
|
+
//# sourceMappingURL=ContentConverters.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ContentConverters.js","sourceRoot":"","sources":["../../../../src/services/history/ContentConverters.ts"],"names":[],"mappings":"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"}
|
@@ -13,26 +13,20 @@
|
|
13
13
|
* See the License for the specific language governing permissions and
|
14
14
|
* limitations under the License.
|
15
15
|
*/
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
}>;
|
33
|
-
usage?: {
|
34
|
-
prompt_tokens: number;
|
35
|
-
completion_tokens: number;
|
36
|
-
total_tokens: number;
|
37
|
-
};
|
16
|
+
/**
|
17
|
+
* Event data emitted when token count is updated
|
18
|
+
*/
|
19
|
+
export interface TokensUpdatedEvent {
|
20
|
+
/** The new total token count */
|
21
|
+
totalTokens: number;
|
22
|
+
/** Number of tokens added (positive) or removed (negative) */
|
23
|
+
addedTokens: number;
|
24
|
+
/** ID of the content that triggered the update, if applicable */
|
25
|
+
contentId?: string | null;
|
26
|
+
}
|
27
|
+
/**
|
28
|
+
* All possible history service events
|
29
|
+
*/
|
30
|
+
export interface HistoryServiceEvents {
|
31
|
+
tokensUpdated: (event: TokensUpdatedEvent) => void;
|
38
32
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"HistoryEvents.js","sourceRoot":"","sources":["../../../../src/services/history/HistoryEvents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
@@ -0,0 +1,220 @@
|
|
1
|
+
/**
|
2
|
+
* Copyright 2025 Vybestack LLC
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
import { IContent, ToolCallBlock } from './IContent.js';
|
17
|
+
import { EventEmitter } from 'events';
|
18
|
+
import { TokensUpdatedEvent } from './HistoryEvents.js';
|
19
|
+
/**
|
20
|
+
* Typed EventEmitter for HistoryService events
|
21
|
+
*/
|
22
|
+
interface HistoryServiceEventEmitter {
|
23
|
+
on(event: 'tokensUpdated', listener: (eventData: TokensUpdatedEvent) => void): this;
|
24
|
+
emit(event: 'tokensUpdated', eventData: TokensUpdatedEvent): boolean;
|
25
|
+
off(event: 'tokensUpdated', listener: (eventData: TokensUpdatedEvent) => void): this;
|
26
|
+
}
|
27
|
+
/**
|
28
|
+
* Configuration for compression behavior
|
29
|
+
*/
|
30
|
+
export interface CompressionConfig {
|
31
|
+
orphanTimeoutMs: number;
|
32
|
+
orphanMessageDistance: number;
|
33
|
+
pendingGracePeriodMs: number;
|
34
|
+
minMessagesForCompression: number;
|
35
|
+
}
|
36
|
+
/**
|
37
|
+
* Service for managing conversation history in a provider-agnostic way.
|
38
|
+
* All history is stored as IContent. Providers are responsible for converting
|
39
|
+
* to/from their own formats.
|
40
|
+
*/
|
41
|
+
export declare class HistoryService extends EventEmitter implements HistoryServiceEventEmitter {
|
42
|
+
private history;
|
43
|
+
private totalTokens;
|
44
|
+
private tokenizerCache;
|
45
|
+
private tokenizerLock;
|
46
|
+
private logger;
|
47
|
+
private isCompressing;
|
48
|
+
private pendingOperations;
|
49
|
+
/**
|
50
|
+
* Get or create tokenizer for a specific model
|
51
|
+
*/
|
52
|
+
private getTokenizerForModel;
|
53
|
+
/**
|
54
|
+
* Generate a new normalized history tool ID.
|
55
|
+
* Format: hist_tool_<uuid-v4>
|
56
|
+
*/
|
57
|
+
generateHistoryId(): string;
|
58
|
+
/**
|
59
|
+
* Get a callback suitable for passing into converters
|
60
|
+
* which will generate normalized history IDs on demand.
|
61
|
+
*/
|
62
|
+
getIdGeneratorCallback(): () => string;
|
63
|
+
/**
|
64
|
+
* Get the current total token count
|
65
|
+
*/
|
66
|
+
getTotalTokens(): number;
|
67
|
+
/**
|
68
|
+
* Add content to the history
|
69
|
+
* Note: We accept all content including empty responses for comprehensive history.
|
70
|
+
* Filtering happens only when getting curated history.
|
71
|
+
*/
|
72
|
+
add(content: IContent, modelName?: string): void;
|
73
|
+
private addInternal;
|
74
|
+
/**
|
75
|
+
* Atomically update token count for new content
|
76
|
+
*/
|
77
|
+
private updateTokenCount;
|
78
|
+
/**
|
79
|
+
* Estimate token count for content using tokenizer
|
80
|
+
*/
|
81
|
+
private estimateContentTokens;
|
82
|
+
/**
|
83
|
+
* Simple token estimation for text
|
84
|
+
*/
|
85
|
+
private simpleTokenEstimateForText;
|
86
|
+
/**
|
87
|
+
* Add multiple contents to the history
|
88
|
+
*/
|
89
|
+
addAll(contents: IContent[], modelName?: string): void;
|
90
|
+
/**
|
91
|
+
* Get all history
|
92
|
+
*/
|
93
|
+
getAll(): IContent[];
|
94
|
+
/**
|
95
|
+
* Clear all history
|
96
|
+
*/
|
97
|
+
clear(): void;
|
98
|
+
private clearInternal;
|
99
|
+
/**
|
100
|
+
* Get the last N messages from history
|
101
|
+
*/
|
102
|
+
getRecent(count: number): IContent[];
|
103
|
+
/**
|
104
|
+
* Get curated history (only valid, meaningful content)
|
105
|
+
* Matches the behavior of extractCuratedHistory in geminiChat.ts:
|
106
|
+
* - Always includes user/human messages
|
107
|
+
* - Always includes tool messages
|
108
|
+
* - Only includes AI messages if they are valid (have content)
|
109
|
+
*/
|
110
|
+
getCurated(): IContent[];
|
111
|
+
/**
|
112
|
+
* Get comprehensive history (all content including invalid/empty)
|
113
|
+
*/
|
114
|
+
getComprehensive(): IContent[];
|
115
|
+
/**
|
116
|
+
* Remove the last content if it matches the provided content
|
117
|
+
*/
|
118
|
+
removeLastIfMatches(content: IContent): boolean;
|
119
|
+
/**
|
120
|
+
* Pop the last content from history
|
121
|
+
*/
|
122
|
+
pop(): IContent | undefined;
|
123
|
+
/**
|
124
|
+
* Recalculate total tokens from scratch
|
125
|
+
* Use this when removing content or when token counts might be stale
|
126
|
+
*/
|
127
|
+
recalculateTokens(defaultModel?: string): Promise<void>;
|
128
|
+
/**
|
129
|
+
* Get the last user (human) content
|
130
|
+
*/
|
131
|
+
getLastUserContent(): IContent | undefined;
|
132
|
+
/**
|
133
|
+
* Get the last AI content
|
134
|
+
*/
|
135
|
+
getLastAIContent(): IContent | undefined;
|
136
|
+
/**
|
137
|
+
* Record a complete turn (user input + AI response + optional tool interactions)
|
138
|
+
*/
|
139
|
+
recordTurn(userInput: IContent, aiResponse: IContent, toolInteractions?: IContent[]): void;
|
140
|
+
/**
|
141
|
+
* Get the number of messages in history
|
142
|
+
*/
|
143
|
+
length(): number;
|
144
|
+
/**
|
145
|
+
* Check if history is empty
|
146
|
+
*/
|
147
|
+
isEmpty(): boolean;
|
148
|
+
/**
|
149
|
+
* Clone the history (deep copy)
|
150
|
+
*/
|
151
|
+
clone(): IContent[];
|
152
|
+
/**
|
153
|
+
* Find unmatched tool calls (tool calls without responses)
|
154
|
+
*/
|
155
|
+
findUnmatchedToolCalls(): ToolCallBlock[];
|
156
|
+
/**
|
157
|
+
* Validate and fix the history to ensure proper tool call/response pairing
|
158
|
+
*/
|
159
|
+
validateAndFix(): void;
|
160
|
+
/**
|
161
|
+
* Get curated history with circular references removed for providers.
|
162
|
+
* This ensures the history can be safely serialized and sent to providers.
|
163
|
+
*/
|
164
|
+
getCuratedForProvider(): IContent[];
|
165
|
+
/**
|
166
|
+
* Deep clone content array, removing circular references
|
167
|
+
*/
|
168
|
+
private deepCloneWithoutCircularRefs;
|
169
|
+
/**
|
170
|
+
* Sanitize parameters to remove circular references
|
171
|
+
*/
|
172
|
+
private sanitizeParams;
|
173
|
+
/**
|
174
|
+
* Merge two histories, handling duplicates and conflicts
|
175
|
+
*/
|
176
|
+
merge(other: HistoryService): void;
|
177
|
+
/**
|
178
|
+
* Get history within a token limit (for context window management)
|
179
|
+
*/
|
180
|
+
getWithinTokenLimit(maxTokens: number, countTokensFn: (content: IContent) => number): IContent[];
|
181
|
+
/**
|
182
|
+
* Summarize older history to fit within token limits
|
183
|
+
*/
|
184
|
+
summarizeOldHistory(keepRecentCount: number, summarizeFn: (contents: IContent[]) => Promise<IContent>): Promise<void>;
|
185
|
+
/**
|
186
|
+
* Export history to JSON
|
187
|
+
*/
|
188
|
+
toJSON(): string;
|
189
|
+
/**
|
190
|
+
* Import history from JSON
|
191
|
+
*/
|
192
|
+
static fromJSON(json: string): HistoryService;
|
193
|
+
/**
|
194
|
+
* Mark compression as starting
|
195
|
+
* This will cause add() operations to queue until compression completes
|
196
|
+
*/
|
197
|
+
startCompression(): void;
|
198
|
+
/**
|
199
|
+
* Mark compression as complete
|
200
|
+
* This will flush all queued operations
|
201
|
+
*/
|
202
|
+
endCompression(): void;
|
203
|
+
/**
|
204
|
+
* Wait for all pending operations to complete
|
205
|
+
* For synchronous operations, this is now a no-op but kept for API compatibility
|
206
|
+
*/
|
207
|
+
waitForPendingOperations(): Promise<void>;
|
208
|
+
/**
|
209
|
+
* Get conversation statistics
|
210
|
+
*/
|
211
|
+
getStatistics(): {
|
212
|
+
totalMessages: number;
|
213
|
+
userMessages: number;
|
214
|
+
aiMessages: number;
|
215
|
+
toolCalls: number;
|
216
|
+
toolResponses: number;
|
217
|
+
totalTokens?: number;
|
218
|
+
};
|
219
|
+
}
|
220
|
+
export {};
|