jazz-ai 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/cli/commands/auth.d.ts +18 -0
- package/dist/cli/commands/auth.d.ts.map +1 -0
- package/dist/cli/commands/auth.js +128 -0
- package/dist/cli/commands/auth.js.map +1 -0
- package/dist/cli/commands/chat-agent.d.ts +18 -0
- package/dist/cli/commands/chat-agent.d.ts.map +1 -0
- package/dist/cli/commands/chat-agent.js +421 -0
- package/dist/cli/commands/chat-agent.js.map +1 -0
- package/dist/cli/commands/edit-agent.d.ts +10 -0
- package/dist/cli/commands/edit-agent.d.ts.map +1 -0
- package/dist/cli/commands/edit-agent.js +310 -0
- package/dist/cli/commands/edit-agent.js.map +1 -0
- package/dist/cli/commands/task-agent.d.ts +126 -0
- package/dist/cli/commands/task-agent.d.ts.map +1 -0
- package/dist/cli/commands/task-agent.js +345 -0
- package/dist/cli/commands/task-agent.js.map +1 -0
- package/dist/core/agent/agent-prompt.d.ts +47 -0
- package/dist/core/agent/agent-prompt.d.ts.map +1 -0
- package/dist/core/agent/agent-prompt.js +146 -0
- package/dist/core/agent/agent-prompt.js.map +1 -0
- package/dist/core/agent/agent-runner.d.ts +63 -0
- package/dist/core/agent/agent-runner.d.ts.map +1 -0
- package/dist/core/agent/agent-runner.js +346 -0
- package/dist/core/agent/agent-runner.js.map +1 -0
- package/dist/core/agent/agent-service.d.ts +164 -0
- package/dist/core/agent/agent-service.d.ts.map +1 -0
- package/dist/core/agent/agent-service.js +463 -0
- package/dist/core/agent/agent-service.js.map +1 -0
- package/dist/core/agent/gmail-agent.d.ts +17 -0
- package/dist/core/agent/gmail-agent.d.ts.map +1 -0
- package/dist/core/agent/gmail-agent.js +191 -0
- package/dist/core/agent/gmail-agent.js.map +1 -0
- package/dist/core/agent/prompts/default/v1.d.ts +2 -0
- package/dist/core/agent/prompts/default/v1.d.ts.map +1 -0
- package/dist/core/agent/prompts/default/v1.js +202 -0
- package/dist/core/agent/prompts/default/v1.js.map +1 -0
- package/dist/core/agent/prompts/default/v2.d.ts +2 -0
- package/dist/core/agent/prompts/default/v2.d.ts.map +1 -0
- package/dist/core/agent/prompts/default/v2.js +72 -0
- package/dist/core/agent/prompts/default/v2.js.map +1 -0
- package/dist/core/agent/prompts/gmail/v1.d.ts +2 -0
- package/dist/core/agent/prompts/gmail/v1.d.ts.map +1 -0
- package/dist/core/agent/prompts/gmail/v1.js +206 -0
- package/dist/core/agent/prompts/gmail/v1.js.map +1 -0
- package/dist/core/agent/prompts/gmail/v2.d.ts +2 -0
- package/dist/core/agent/prompts/gmail/v2.d.ts.map +1 -0
- package/dist/core/agent/prompts/gmail/v2.js +59 -0
- package/dist/core/agent/prompts/gmail/v2.js.map +1 -0
- package/dist/core/agent/tools/base-tool.d.ts +161 -0
- package/dist/core/agent/tools/base-tool.d.ts.map +1 -0
- package/dist/core/agent/tools/base-tool.js +153 -0
- package/dist/core/agent/tools/base-tool.js.map +1 -0
- package/dist/core/agent/tools/fs-tools.d.ts +21 -0
- package/dist/core/agent/tools/fs-tools.d.ts.map +1 -0
- package/dist/core/agent/tools/fs-tools.js +1210 -0
- package/dist/core/agent/tools/fs-tools.js.map +1 -0
- package/dist/core/agent/tools/git-tools.d.ts +63 -0
- package/dist/core/agent/tools/git-tools.d.ts.map +1 -0
- package/dist/core/agent/tools/git-tools.js +600 -0
- package/dist/core/agent/tools/git-tools.js.map +1 -0
- package/dist/core/agent/tools/gmail-tools.d.ts +22 -0
- package/dist/core/agent/tools/gmail-tools.d.ts.map +1 -0
- package/dist/core/agent/tools/gmail-tools.js +779 -0
- package/dist/core/agent/tools/gmail-tools.js.map +1 -0
- package/dist/core/agent/tools/register-tools.d.ts +13 -0
- package/dist/core/agent/tools/register-tools.d.ts.map +1 -0
- package/dist/core/agent/tools/register-tools.js +169 -0
- package/dist/core/agent/tools/register-tools.js.map +1 -0
- package/dist/core/agent/tools/shell-tools.d.ts +19 -0
- package/dist/core/agent/tools/shell-tools.d.ts.map +1 -0
- package/dist/core/agent/tools/shell-tools.js +367 -0
- package/dist/core/agent/tools/shell-tools.js.map +1 -0
- package/dist/core/agent/tools/tool-registry.d.ts +62 -0
- package/dist/core/agent/tools/tool-registry.d.ts.map +1 -0
- package/dist/core/agent/tools/tool-registry.js +187 -0
- package/dist/core/agent/tools/tool-registry.js.map +1 -0
- package/dist/core/agent/tools/web-search-tools.d.ts +39 -0
- package/dist/core/agent/tools/web-search-tools.d.ts.map +1 -0
- package/dist/core/agent/tools/web-search-tools.js +220 -0
- package/dist/core/agent/tools/web-search-tools.js.map +1 -0
- package/dist/core/types/errors.d.ts +300 -0
- package/dist/core/types/errors.d.ts.map +1 -0
- package/dist/core/types/errors.js +115 -0
- package/dist/core/types/errors.js.map +1 -0
- package/dist/core/types/index.d.ts +208 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +30 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/core/utils/error-handler.d.ts +114 -0
- package/dist/core/utils/error-handler.d.ts.map +1 -0
- package/dist/core/utils/error-handler.js +551 -0
- package/dist/core/utils/error-handler.js.map +1 -0
- package/dist/core/utils/markdown-renderer.d.ts +52 -0
- package/dist/core/utils/markdown-renderer.d.ts.map +1 -0
- package/dist/core/utils/markdown-renderer.js +134 -0
- package/dist/core/utils/markdown-renderer.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +255 -0
- package/dist/main.js.map +1 -0
- package/dist/services/config.d.ts +29 -0
- package/dist/services/config.d.ts.map +1 -0
- package/dist/services/config.js +204 -0
- package/dist/services/config.js.map +1 -0
- package/dist/services/gmail.d.ts +197 -0
- package/dist/services/gmail.d.ts.map +1 -0
- package/dist/services/gmail.js +592 -0
- package/dist/services/gmail.js.map +1 -0
- package/dist/services/llm/ai-sdk-service.d.ts +5 -0
- package/dist/services/llm/ai-sdk-service.d.ts.map +1 -0
- package/dist/services/llm/ai-sdk-service.js +326 -0
- package/dist/services/llm/ai-sdk-service.js.map +1 -0
- package/dist/services/llm/context-manager.d.ts +51 -0
- package/dist/services/llm/context-manager.d.ts.map +1 -0
- package/dist/services/llm/context-manager.js +269 -0
- package/dist/services/llm/context-manager.js.map +1 -0
- package/dist/services/llm/types.d.ts +114 -0
- package/dist/services/llm/types.d.ts.map +1 -0
- package/dist/services/llm/types.js +51 -0
- package/dist/services/llm/types.js.map +1 -0
- package/dist/services/logger.d.ts +28 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +267 -0
- package/dist/services/logger.js.map +1 -0
- package/dist/services/shell.d.ts +37 -0
- package/dist/services/shell.d.ts.map +1 -0
- package/dist/services/shell.js +197 -0
- package/dist/services/shell.js.map +1 -0
- package/dist/services/storage/file.d.ts +37 -0
- package/dist/services/storage/file.d.ts.map +1 -0
- package/dist/services/storage/file.js +221 -0
- package/dist/services/storage/file.js.map +1 -0
- package/dist/services/storage/inMemory.d.ts +25 -0
- package/dist/services/storage/inMemory.d.ts.map +1 -0
- package/dist/services/storage/inMemory.js +106 -0
- package/dist/services/storage/inMemory.js.map +1 -0
- package/dist/services/storage/service.d.ts +26 -0
- package/dist/services/storage/service.d.ts.map +1 -0
- package/dist/services/storage/service.js +48 -0
- package/dist/services/storage/service.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createAISDKServiceLayer = createAISDKServiceLayer;
|
|
4
|
+
const anthropic_1 = require("@ai-sdk/anthropic");
|
|
5
|
+
const google_1 = require("@ai-sdk/google");
|
|
6
|
+
const mistral_1 = require("@ai-sdk/mistral");
|
|
7
|
+
const openai_1 = require("@ai-sdk/openai");
|
|
8
|
+
const xai_1 = require("@ai-sdk/xai");
|
|
9
|
+
const ai_1 = require("ai");
|
|
10
|
+
const effect_1 = require("effect");
|
|
11
|
+
const config_1 = require("../config");
|
|
12
|
+
const types_1 = require("./types");
|
|
13
|
+
function safeParseJson(input) {
|
|
14
|
+
try {
|
|
15
|
+
const parsed = JSON.parse(input);
|
|
16
|
+
return parsed && typeof parsed === "object" ? parsed : {};
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function toCoreMessages(messages) {
|
|
23
|
+
return messages.map((m) => {
|
|
24
|
+
const role = m.role;
|
|
25
|
+
if (role === "system") {
|
|
26
|
+
return {
|
|
27
|
+
role: "system",
|
|
28
|
+
content: m.content,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// User messages - simple string content
|
|
32
|
+
if (role === "user") {
|
|
33
|
+
return {
|
|
34
|
+
role: "user",
|
|
35
|
+
content: m.content,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Assistant messages (may include tool calls)
|
|
39
|
+
if (role === "assistant") {
|
|
40
|
+
const contentParts = [];
|
|
41
|
+
if (m.content && m.content.length > 0) {
|
|
42
|
+
contentParts.push({ type: "text", text: m.content });
|
|
43
|
+
}
|
|
44
|
+
if (m.tool_calls && m.tool_calls.length > 0) {
|
|
45
|
+
for (const tc of m.tool_calls) {
|
|
46
|
+
contentParts.push({
|
|
47
|
+
type: "tool-call",
|
|
48
|
+
toolCallId: tc.id,
|
|
49
|
+
toolName: tc.function.name,
|
|
50
|
+
input: safeParseJson(tc.function.arguments),
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// If we have content parts, return them as an array, otherwise return as string
|
|
55
|
+
if (contentParts.length > 0) {
|
|
56
|
+
return { role: "assistant", content: contentParts };
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
return { role: "assistant", content: "" };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Tool messages (tool results)
|
|
63
|
+
if (role === "tool") {
|
|
64
|
+
const contentParts = [];
|
|
65
|
+
contentParts.push({
|
|
66
|
+
type: "tool-result",
|
|
67
|
+
toolCallId: m.tool_call_id ?? "",
|
|
68
|
+
toolName: m.name ?? "tool",
|
|
69
|
+
output: { type: "text", value: m.content },
|
|
70
|
+
});
|
|
71
|
+
return { role: "tool", content: contentParts };
|
|
72
|
+
}
|
|
73
|
+
// Fallback - should not reach here
|
|
74
|
+
throw new Error(`Unsupported message role: ${String(role)}`);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function selectModel(providerName, modelId) {
|
|
78
|
+
switch (providerName.toLowerCase()) {
|
|
79
|
+
case "openai":
|
|
80
|
+
return (0, openai_1.openai)(modelId);
|
|
81
|
+
case "anthropic":
|
|
82
|
+
return (0, anthropic_1.anthropic)(modelId);
|
|
83
|
+
case "gemini":
|
|
84
|
+
case "google":
|
|
85
|
+
return (0, google_1.google)(modelId);
|
|
86
|
+
case "mistral":
|
|
87
|
+
return (0, mistral_1.mistral)(modelId);
|
|
88
|
+
case "xai":
|
|
89
|
+
return (0, xai_1.xai)(modelId);
|
|
90
|
+
default:
|
|
91
|
+
return (0, openai_1.openai)(modelId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
class DefaultAISDKService {
|
|
95
|
+
config;
|
|
96
|
+
providerModels;
|
|
97
|
+
constructor(config) {
|
|
98
|
+
this.config = config;
|
|
99
|
+
// Export API keys to env for providers that read from env
|
|
100
|
+
Object.entries(this.config.apiKeys).forEach(([provider, apiKey]) => {
|
|
101
|
+
process.env[`${provider.toUpperCase()}_API_KEY`] = apiKey;
|
|
102
|
+
});
|
|
103
|
+
this.providerModels = {
|
|
104
|
+
openai: [
|
|
105
|
+
{ id: "gpt-5", displayName: "GPT-5", isReasoningModel: true },
|
|
106
|
+
{ id: "gpt-5-mini", displayName: "GPT-5 Mini", isReasoningModel: true },
|
|
107
|
+
{ id: "gpt-5-nano", displayName: "GPT-5 Nano", isReasoningModel: true },
|
|
108
|
+
{ id: "gpt-4.1", displayName: "GPT-4.1", isReasoningModel: true },
|
|
109
|
+
{ id: "gpt-4.1-mini", displayName: "GPT-4.1 Mini", isReasoningModel: true },
|
|
110
|
+
{ id: "gpt-4.1-nano", displayName: "GPT-4.1 Nano", isReasoningModel: true },
|
|
111
|
+
{ id: "gpt-4o", displayName: "GPT-4o", isReasoningModel: false },
|
|
112
|
+
{ id: "gpt-4o-mini", displayName: "GPT-4o Mini", isReasoningModel: false },
|
|
113
|
+
{ id: "o4-mini", displayName: "o4-mini", isReasoningModel: true },
|
|
114
|
+
],
|
|
115
|
+
anthropic: [
|
|
116
|
+
{ id: "claude-opus-4", displayName: "Claude Opus 4", isReasoningModel: true },
|
|
117
|
+
{ id: "claude-sonnet-4", displayName: "Claude Sonnet 4", isReasoningModel: true },
|
|
118
|
+
{ id: "claude-3.7", displayName: "Claude 3.7", isReasoningModel: true },
|
|
119
|
+
{ id: "claude-3-sonnet", displayName: "Claude 3 Sonnet", isReasoningModel: false },
|
|
120
|
+
{ id: "claude-3-opus", displayName: "Claude 3 Opus", isReasoningModel: false },
|
|
121
|
+
{ id: "claude-3-haiku", displayName: "Claude 3 Haiku", isReasoningModel: false },
|
|
122
|
+
],
|
|
123
|
+
gemini: [
|
|
124
|
+
{ id: "gemini-2.5-flash", displayName: "Gemini 2.5 Flash", isReasoningModel: true },
|
|
125
|
+
{ id: "gemini-2.5-pro", displayName: "Gemini 2.5 Pro", isReasoningModel: true },
|
|
126
|
+
{
|
|
127
|
+
id: "gemini-2.5-flash-lite",
|
|
128
|
+
displayName: "Gemini 2.5 Flash Lite",
|
|
129
|
+
isReasoningModel: true,
|
|
130
|
+
},
|
|
131
|
+
{ id: "gemini-2.0-flash", displayName: "Gemini 2.0 Flash", isReasoningModel: false },
|
|
132
|
+
],
|
|
133
|
+
mistral: [
|
|
134
|
+
{ id: "mistral-small-latest", displayName: "Mistral Small", isReasoningModel: false },
|
|
135
|
+
{ id: "mistral-medium-latest", displayName: "Mistral Medium", isReasoningModel: false },
|
|
136
|
+
{ id: "mistral-large-latest", displayName: "Mistral Large", isReasoningModel: false },
|
|
137
|
+
{ id: "magistral-small-2506", displayName: "Magistral Small", isReasoningModel: true },
|
|
138
|
+
{ id: "magistral-medium-2506", displayName: "Magistral Medium", isReasoningModel: true },
|
|
139
|
+
],
|
|
140
|
+
custom: [
|
|
141
|
+
{ id: "llama4", displayName: "Llama 4", isReasoningModel: false },
|
|
142
|
+
{ id: "llama3", displayName: "Llama 3", isReasoningModel: false },
|
|
143
|
+
{ id: "qwq", displayName: "QWQ", isReasoningModel: false },
|
|
144
|
+
{ id: "deepseek-r1", displayName: "DeepSeek R1", isReasoningModel: true },
|
|
145
|
+
{ id: "mistral", displayName: "Mistral", isReasoningModel: false },
|
|
146
|
+
],
|
|
147
|
+
xai: [
|
|
148
|
+
{ id: "grok-4-0709", displayName: "Grok 4", isReasoningModel: true },
|
|
149
|
+
{ id: "grok-3", displayName: "Grok 3", isReasoningModel: true },
|
|
150
|
+
{ id: "grok-3-mini", displayName: "Grok 3 Mini", isReasoningModel: true },
|
|
151
|
+
],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
getProvider(providerName) {
|
|
155
|
+
return effect_1.Effect.try({
|
|
156
|
+
try: () => {
|
|
157
|
+
if (!this.providerModels[providerName]) {
|
|
158
|
+
throw new types_1.LLMConfigurationError(providerName, `Provider not supported: ${providerName}`);
|
|
159
|
+
}
|
|
160
|
+
const provider = {
|
|
161
|
+
name: providerName,
|
|
162
|
+
supportedModels: this.providerModels[providerName],
|
|
163
|
+
defaultModel: this.providerModels[providerName][0]?.id ?? "",
|
|
164
|
+
authenticate: () => effect_1.Effect.try({
|
|
165
|
+
try: () => {
|
|
166
|
+
const apiKey = this.config.apiKeys[providerName];
|
|
167
|
+
if (!apiKey) {
|
|
168
|
+
throw new types_1.LLMAuthenticationError(providerName, "API key not configured");
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
catch: (error) => new types_1.LLMAuthenticationError(providerName, error instanceof Error ? error.message : String(error)),
|
|
172
|
+
}),
|
|
173
|
+
createChatCompletion: (options) => this.createChatCompletion(providerName, options),
|
|
174
|
+
};
|
|
175
|
+
return provider;
|
|
176
|
+
},
|
|
177
|
+
catch: (error) => new types_1.LLMConfigurationError(providerName, `Failed to get provider: ${error instanceof Error ? error.message : String(error)}`),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
listProviders() {
|
|
181
|
+
const configuredProviders = Object.keys(this.config.apiKeys);
|
|
182
|
+
const intersect = configuredProviders.filter((p) => this.providerModels[p]);
|
|
183
|
+
return effect_1.Effect.succeed(intersect);
|
|
184
|
+
}
|
|
185
|
+
createChatCompletion(providerName, options) {
|
|
186
|
+
return effect_1.Effect.tryPromise({
|
|
187
|
+
try: async () => {
|
|
188
|
+
if (options.stream === true) {
|
|
189
|
+
throw new Error("Streaming responses are not supported yet");
|
|
190
|
+
}
|
|
191
|
+
const model = selectModel(providerName, options.model);
|
|
192
|
+
// Prepare tools for AI SDK if present
|
|
193
|
+
let tools;
|
|
194
|
+
if (options.tools && options.tools.length > 0) {
|
|
195
|
+
tools = {};
|
|
196
|
+
for (const toolDef of options.tools) {
|
|
197
|
+
tools[toolDef.function.name] = (0, ai_1.tool)({
|
|
198
|
+
description: toolDef.function.description,
|
|
199
|
+
inputSchema: toolDef.function.parameters,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const result = await (0, ai_1.generateText)({
|
|
204
|
+
model,
|
|
205
|
+
messages: toCoreMessages(options.messages),
|
|
206
|
+
...(typeof options.temperature === "number" ? { temperature: options.temperature } : {}),
|
|
207
|
+
...(tools ? { tools } : {}),
|
|
208
|
+
stopWhen: (0, ai_1.stepCountIs)(8),
|
|
209
|
+
});
|
|
210
|
+
let responseModel = options.model;
|
|
211
|
+
let content = "";
|
|
212
|
+
let toolCalls = undefined;
|
|
213
|
+
let usage = undefined;
|
|
214
|
+
// Extract text content
|
|
215
|
+
content = result.text ?? "";
|
|
216
|
+
// Extract model ID from result (fallback to options.model if not available)
|
|
217
|
+
responseModel = options.model; // AI SDK doesn't expose modelId in result
|
|
218
|
+
// Extract usage information
|
|
219
|
+
if (result.usage) {
|
|
220
|
+
const usageData = result.usage;
|
|
221
|
+
usage = {
|
|
222
|
+
promptTokens: usageData.inputTokens ?? 0,
|
|
223
|
+
completionTokens: usageData.outputTokens ?? 0,
|
|
224
|
+
totalTokens: usageData.totalTokens ?? 0,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
// Extract tool calls if present
|
|
228
|
+
if (result.toolCalls && result.toolCalls.length > 0) {
|
|
229
|
+
toolCalls = result.toolCalls.map((tc) => {
|
|
230
|
+
// Handle both static and dynamic tool calls
|
|
231
|
+
if ("dynamic" in tc && tc.dynamic) {
|
|
232
|
+
// Dynamic tool call
|
|
233
|
+
return {
|
|
234
|
+
id: tc.toolCallId,
|
|
235
|
+
type: "function",
|
|
236
|
+
function: {
|
|
237
|
+
name: tc.toolName,
|
|
238
|
+
arguments: JSON.stringify(tc.input ?? {}),
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
// Static tool call
|
|
244
|
+
return {
|
|
245
|
+
id: tc.toolCallId,
|
|
246
|
+
type: "function",
|
|
247
|
+
function: {
|
|
248
|
+
name: tc.toolName,
|
|
249
|
+
arguments: JSON.stringify(tc.input ?? {}),
|
|
250
|
+
},
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
const resultObj = {
|
|
256
|
+
id: "",
|
|
257
|
+
model: responseModel,
|
|
258
|
+
content,
|
|
259
|
+
...(toolCalls ? { toolCalls } : {}),
|
|
260
|
+
...(usage ? { usage } : {}),
|
|
261
|
+
};
|
|
262
|
+
return resultObj;
|
|
263
|
+
},
|
|
264
|
+
catch: (error) => {
|
|
265
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
266
|
+
let httpStatus;
|
|
267
|
+
if (error instanceof Error) {
|
|
268
|
+
const e = error;
|
|
269
|
+
httpStatus = e.status || e.statusCode;
|
|
270
|
+
if (!httpStatus) {
|
|
271
|
+
const m = errorMessage.match(/(\d{3})\s/);
|
|
272
|
+
if (m && m[1])
|
|
273
|
+
httpStatus = parseInt(m[1], 10);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (httpStatus === 401 || httpStatus === 403) {
|
|
277
|
+
return new types_1.LLMAuthenticationError(providerName, errorMessage);
|
|
278
|
+
}
|
|
279
|
+
else if (httpStatus === 429) {
|
|
280
|
+
return new types_1.LLMRateLimitError(providerName, errorMessage);
|
|
281
|
+
}
|
|
282
|
+
else if (httpStatus && httpStatus >= 400 && httpStatus < 500) {
|
|
283
|
+
return new types_1.LLMRequestError(providerName, errorMessage);
|
|
284
|
+
}
|
|
285
|
+
else if (httpStatus && httpStatus >= 500) {
|
|
286
|
+
return new types_1.LLMRequestError(providerName, `Server error (${httpStatus}): ${errorMessage}`);
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
if (errorMessage.toLowerCase().includes("authentication") ||
|
|
290
|
+
errorMessage.toLowerCase().includes("api key")) {
|
|
291
|
+
return new types_1.LLMAuthenticationError(providerName, errorMessage);
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
return new types_1.LLMRequestError(providerName, errorMessage || "Unknown LLM request error");
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function createAISDKServiceLayer() {
|
|
302
|
+
return effect_1.Layer.effect(types_1.LLMServiceTag, effect_1.Effect.gen(function* () {
|
|
303
|
+
const configService = yield* config_1.AgentConfigService;
|
|
304
|
+
const appConfig = yield* configService.appConfig;
|
|
305
|
+
const apiKeys = {};
|
|
306
|
+
const openAIAPIKey = appConfig.llm?.openai?.api_key;
|
|
307
|
+
if (openAIAPIKey)
|
|
308
|
+
apiKeys["openai"] = openAIAPIKey;
|
|
309
|
+
const anthropicAPIKey = appConfig.llm?.anthropic?.api_key;
|
|
310
|
+
if (anthropicAPIKey)
|
|
311
|
+
apiKeys["anthropic"] = anthropicAPIKey;
|
|
312
|
+
const geminiAPIKey = appConfig.llm?.gemini?.api_key;
|
|
313
|
+
if (geminiAPIKey)
|
|
314
|
+
apiKeys["gemini"] = geminiAPIKey;
|
|
315
|
+
const mistralAPIKey = appConfig.llm?.mistral?.api_key;
|
|
316
|
+
if (mistralAPIKey)
|
|
317
|
+
apiKeys["mistral"] = mistralAPIKey;
|
|
318
|
+
const providers = Object.keys(apiKeys);
|
|
319
|
+
if (providers.length === 0) {
|
|
320
|
+
return yield* effect_1.Effect.fail(new types_1.LLMConfigurationError("unknown", "No LLM API keys configured. Set config.llm.<provider>.api_key or env (e.g., OPENAI_API_KEY)."));
|
|
321
|
+
}
|
|
322
|
+
const cfg = { apiKeys };
|
|
323
|
+
return new DefaultAISDKService(cfg);
|
|
324
|
+
}));
|
|
325
|
+
}
|
|
326
|
+
//# sourceMappingURL=ai-sdk-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-service.js","sourceRoot":"","sources":["../../../src/services/llm/ai-sdk-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { type ChatMessage } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Get the context window limit for a model
|
|
4
|
+
*/
|
|
5
|
+
export declare function getModelContextLimit(model: string): number;
|
|
6
|
+
/**
|
|
7
|
+
* Get all models for a specific provider
|
|
8
|
+
*/
|
|
9
|
+
export declare function getModelsByProvider(provider: string): Record<string, number>;
|
|
10
|
+
/**
|
|
11
|
+
* Get all available providers
|
|
12
|
+
*/
|
|
13
|
+
export declare function getAvailableProviders(): string[];
|
|
14
|
+
/**
|
|
15
|
+
* Simple token counting - rough approximation
|
|
16
|
+
* For production use, consider using tiktoken or similar
|
|
17
|
+
*/
|
|
18
|
+
export declare function estimateTokenCount(content: string): number;
|
|
19
|
+
/**
|
|
20
|
+
* Estimate tokens for a single message
|
|
21
|
+
*/
|
|
22
|
+
export declare function estimateMessageTokens(message: ChatMessage): number;
|
|
23
|
+
/**
|
|
24
|
+
* Estimate total tokens for a conversation
|
|
25
|
+
*/
|
|
26
|
+
export declare function estimateConversationTokens(messages: ChatMessage[]): number;
|
|
27
|
+
/**
|
|
28
|
+
* Check if conversation should be summarized
|
|
29
|
+
*/
|
|
30
|
+
export declare function shouldSummarize(messages: ChatMessage[], model: string, safetyMargin?: number): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Find the point where summarization should start, considering both message count and token limits
|
|
33
|
+
*/
|
|
34
|
+
export declare function findSummarizationPoint(messages: ChatMessage[], model: string, targetTokens: number, maxRecentTokens?: number, preserveRecentMessages?: number): number;
|
|
35
|
+
/**
|
|
36
|
+
* Create a simple summary message
|
|
37
|
+
*/
|
|
38
|
+
export declare function createSummaryMessage(summarizedCount: number): ChatMessage;
|
|
39
|
+
/**
|
|
40
|
+
* Check if a message contains large tool call results that should be summarized
|
|
41
|
+
*/
|
|
42
|
+
export declare function isLargeToolResult(message: ChatMessage, maxTokens?: number): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Summarize large tool call results to reduce context usage
|
|
45
|
+
*/
|
|
46
|
+
export declare function summarizeToolResult(message: ChatMessage, maxTokens?: number): ChatMessage;
|
|
47
|
+
/**
|
|
48
|
+
* Summarize conversation by replacing early messages with a summary
|
|
49
|
+
*/
|
|
50
|
+
export declare function summarizeConversation(messages: ChatMessage[], model: string, targetTokens?: number, maxRecentTokens?: number, preserveRecentMessages?: number, summarizeToolResults?: boolean): ChatMessage[];
|
|
51
|
+
//# sourceMappingURL=context-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-manager.d.ts","sourceRoot":"","sources":["../../../src/services/llm/context-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAqD3C;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAK5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAS1D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CA+BlE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,MAAM,CAQ1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,YAAY,GAAE,MAAY,GACzB,OAAO,CAMT;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,MAAM,EACxB,sBAAsB,CAAC,EAAE,MAAM,GAC9B,MAAM,CA4DR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,eAAe,EAAE,MAAM,GAAG,WAAW,CAKzE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,GAAE,MAAa,GAAG,OAAO,CAOzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,GAAE,MAAY,GAAG,WAAW,CAY9F;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,MAAM,EACrB,eAAe,CAAC,EAAE,MAAM,EACxB,sBAAsB,CAAC,EAAE,MAAM,EAC/B,oBAAoB,CAAC,EAAE,OAAO,GAC7B,WAAW,EAAE,CAqDf"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getModelContextLimit = getModelContextLimit;
|
|
4
|
+
exports.getModelsByProvider = getModelsByProvider;
|
|
5
|
+
exports.getAvailableProviders = getAvailableProviders;
|
|
6
|
+
exports.estimateTokenCount = estimateTokenCount;
|
|
7
|
+
exports.estimateMessageTokens = estimateMessageTokens;
|
|
8
|
+
exports.estimateConversationTokens = estimateConversationTokens;
|
|
9
|
+
exports.shouldSummarize = shouldSummarize;
|
|
10
|
+
exports.findSummarizationPoint = findSummarizationPoint;
|
|
11
|
+
exports.createSummaryMessage = createSummaryMessage;
|
|
12
|
+
exports.isLargeToolResult = isLargeToolResult;
|
|
13
|
+
exports.summarizeToolResult = summarizeToolResult;
|
|
14
|
+
exports.summarizeConversation = summarizeConversation;
|
|
15
|
+
/**
|
|
16
|
+
* Advanced context window management utilities
|
|
17
|
+
* Provides intelligent conversation summarization and token management
|
|
18
|
+
* for maintaining context within LLM model limits
|
|
19
|
+
*/
|
|
20
|
+
// Model context window limits organized by provider (in tokens)
|
|
21
|
+
const MODEL_CONTEXT_LIMITS_BY_PROVIDER = {
|
|
22
|
+
// OpenAI models
|
|
23
|
+
openai: {
|
|
24
|
+
"gpt-3.5-turbo": 4096,
|
|
25
|
+
"gpt-4": 8192,
|
|
26
|
+
"gpt-4o": 128000,
|
|
27
|
+
"gpt-4o-mini": 128000,
|
|
28
|
+
"gpt-4-turbo": 128000,
|
|
29
|
+
"gpt-5": 200000,
|
|
30
|
+
o3: 200000,
|
|
31
|
+
},
|
|
32
|
+
// Anthropic Claude models
|
|
33
|
+
anthropic: {
|
|
34
|
+
"claude-3-haiku": 200000,
|
|
35
|
+
"claude-3-sonnet": 200000,
|
|
36
|
+
"claude-3-opus": 200000,
|
|
37
|
+
"claude-sonnet-4": 200000,
|
|
38
|
+
"claude-opus-4": 200000,
|
|
39
|
+
},
|
|
40
|
+
// Google Gemini models
|
|
41
|
+
google: {
|
|
42
|
+
"gemini-pro": 30720,
|
|
43
|
+
"gemini-1.5-pro": 2000000,
|
|
44
|
+
"gemini-2.0-flash": 1000000,
|
|
45
|
+
},
|
|
46
|
+
// Mistral AI models
|
|
47
|
+
mistral: {
|
|
48
|
+
"mistral-small-latest": 32000,
|
|
49
|
+
"mistral-medium-latest": 32000,
|
|
50
|
+
"mistral-large-latest": 32000,
|
|
51
|
+
mistral: 32000,
|
|
52
|
+
},
|
|
53
|
+
// Meta Llama models
|
|
54
|
+
meta: {
|
|
55
|
+
llama3: 8192,
|
|
56
|
+
llama2: 4096,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
// Flatten the provider-organized limits into a single lookup table
|
|
60
|
+
const MODEL_CONTEXT_LIMITS = Object.values(MODEL_CONTEXT_LIMITS_BY_PROVIDER).reduce((acc, providerModels) => ({ ...acc, ...providerModels }), {});
|
|
61
|
+
/**
|
|
62
|
+
* Get the context window limit for a model
|
|
63
|
+
*/
|
|
64
|
+
function getModelContextLimit(model) {
|
|
65
|
+
return MODEL_CONTEXT_LIMITS[model] || 4096; // Default to 4K if unknown
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get all models for a specific provider
|
|
69
|
+
*/
|
|
70
|
+
function getModelsByProvider(provider) {
|
|
71
|
+
return (MODEL_CONTEXT_LIMITS_BY_PROVIDER[provider] ||
|
|
72
|
+
{});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get all available providers
|
|
76
|
+
*/
|
|
77
|
+
function getAvailableProviders() {
|
|
78
|
+
return Object.keys(MODEL_CONTEXT_LIMITS_BY_PROVIDER);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Simple token counting - rough approximation
|
|
82
|
+
* For production use, consider using tiktoken or similar
|
|
83
|
+
*/
|
|
84
|
+
function estimateTokenCount(content) {
|
|
85
|
+
if (!content)
|
|
86
|
+
return 0;
|
|
87
|
+
// Simple approximation: ~4 characters per token for English text
|
|
88
|
+
const charCount = content.length;
|
|
89
|
+
const estimatedTokens = Math.ceil(charCount / 4);
|
|
90
|
+
// Add overhead for special tokens and formatting
|
|
91
|
+
return Math.max(estimatedTokens, 1);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Estimate tokens for a single message
|
|
95
|
+
*/
|
|
96
|
+
function estimateMessageTokens(message) {
|
|
97
|
+
// Base tokens for message structure
|
|
98
|
+
let tokens = 3; // role, content, and formatting tokens
|
|
99
|
+
// Add role name tokens
|
|
100
|
+
tokens += message.role.length;
|
|
101
|
+
// Add content tokens
|
|
102
|
+
tokens += estimateTokenCount(message.content);
|
|
103
|
+
// Add name tokens if present
|
|
104
|
+
if (message.name) {
|
|
105
|
+
tokens += message.name.length;
|
|
106
|
+
}
|
|
107
|
+
// Add tool call tokens if present
|
|
108
|
+
if (message.tool_calls) {
|
|
109
|
+
tokens += message.tool_calls.length * 10; // Rough estimate for tool call overhead
|
|
110
|
+
for (const toolCall of message.tool_calls) {
|
|
111
|
+
tokens += toolCall.id.length;
|
|
112
|
+
tokens += toolCall.function.name.length;
|
|
113
|
+
tokens += toolCall.function.arguments.length;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Add tool call ID tokens if present
|
|
117
|
+
if (message.tool_call_id) {
|
|
118
|
+
tokens += message.tool_call_id.length;
|
|
119
|
+
}
|
|
120
|
+
return tokens;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Estimate total tokens for a conversation
|
|
124
|
+
*/
|
|
125
|
+
function estimateConversationTokens(messages) {
|
|
126
|
+
let totalTokens = 0;
|
|
127
|
+
for (const message of messages) {
|
|
128
|
+
totalTokens += estimateMessageTokens(message);
|
|
129
|
+
}
|
|
130
|
+
return totalTokens;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if conversation should be summarized
|
|
134
|
+
*/
|
|
135
|
+
function shouldSummarize(messages, model, safetyMargin = 0.8) {
|
|
136
|
+
const maxTokens = getModelContextLimit(model);
|
|
137
|
+
const currentTokens = estimateConversationTokens(messages);
|
|
138
|
+
const threshold = Math.floor(maxTokens * safetyMargin);
|
|
139
|
+
return currentTokens > threshold;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Find the point where summarization should start, considering both message count and token limits
|
|
143
|
+
*/
|
|
144
|
+
function findSummarizationPoint(messages, model, targetTokens, maxRecentTokens, preserveRecentMessages) {
|
|
145
|
+
const maxTokens = getModelContextLimit(model);
|
|
146
|
+
const availableTokens = maxTokens - targetTokens;
|
|
147
|
+
let accumulatedTokens = 0;
|
|
148
|
+
let index = 0;
|
|
149
|
+
// Always keep the first message (usually system message)
|
|
150
|
+
if (messages.length > 0) {
|
|
151
|
+
const firstMessage = messages[0];
|
|
152
|
+
if (firstMessage) {
|
|
153
|
+
accumulatedTokens += estimateMessageTokens(firstMessage);
|
|
154
|
+
index = 1;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Calculate how many recent messages to preserve
|
|
158
|
+
const recentMessagesToPreserve = preserveRecentMessages ?? 3;
|
|
159
|
+
const maxRecentTokensToPreserve = maxRecentTokens ?? 2000;
|
|
160
|
+
// Start from the end and work backwards to find recent messages to preserve
|
|
161
|
+
let recentTokens = 0;
|
|
162
|
+
let recentMessageCount = 0;
|
|
163
|
+
const recentStartIndex = Math.max(0, messages.length - recentMessagesToPreserve * 2); // *2 for user/assistant pairs
|
|
164
|
+
for (let i = messages.length - 1; i >= recentStartIndex; i--) {
|
|
165
|
+
const message = messages[i];
|
|
166
|
+
if (!message)
|
|
167
|
+
continue;
|
|
168
|
+
const messageTokens = estimateMessageTokens(message);
|
|
169
|
+
if (recentTokens + messageTokens > maxRecentTokensToPreserve) {
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
recentTokens += messageTokens;
|
|
173
|
+
recentMessageCount++;
|
|
174
|
+
}
|
|
175
|
+
const actualRecentStartIndex = Math.max(index, messages.length - recentMessageCount);
|
|
176
|
+
// Ensure we never return an index that would result in empty messages
|
|
177
|
+
if (actualRecentStartIndex >= messages.length) {
|
|
178
|
+
return Math.max(1, messages.length - 1); // Keep at least the system message + 1 recent message
|
|
179
|
+
}
|
|
180
|
+
// Find the point where we exceed available tokens, but don't go past recent messages
|
|
181
|
+
for (let i = index; i < actualRecentStartIndex; i++) {
|
|
182
|
+
const message = messages[i];
|
|
183
|
+
if (!message)
|
|
184
|
+
continue;
|
|
185
|
+
const messageTokens = estimateMessageTokens(message);
|
|
186
|
+
if (accumulatedTokens + messageTokens > availableTokens - recentTokens) {
|
|
187
|
+
return i;
|
|
188
|
+
}
|
|
189
|
+
accumulatedTokens += messageTokens;
|
|
190
|
+
}
|
|
191
|
+
// If we can fit all messages, return the recent start index
|
|
192
|
+
return actualRecentStartIndex;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Create a simple summary message
|
|
196
|
+
*/
|
|
197
|
+
function createSummaryMessage(summarizedCount) {
|
|
198
|
+
return {
|
|
199
|
+
role: "assistant",
|
|
200
|
+
content: `[CONVERSATION SUMMARY] Previous ${summarizedCount} messages have been summarized to manage context window. Key points and context preserved.`,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Check if a message contains large tool call results that should be summarized
|
|
205
|
+
*/
|
|
206
|
+
function isLargeToolResult(message, maxTokens = 1000) {
|
|
207
|
+
if (message.role !== "assistant" || !message.content) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
const tokens = estimateTokenCount(message.content);
|
|
211
|
+
return tokens > maxTokens;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Summarize large tool call results to reduce context usage
|
|
215
|
+
*/
|
|
216
|
+
function summarizeToolResult(message, maxTokens = 500) {
|
|
217
|
+
if (!isLargeToolResult(message, maxTokens * 2)) {
|
|
218
|
+
return message;
|
|
219
|
+
}
|
|
220
|
+
const originalTokens = estimateTokenCount(message.content);
|
|
221
|
+
const summary = `[TOOL RESULT SUMMARY] Large tool result (${originalTokens} tokens) has been summarized. Key information preserved.`;
|
|
222
|
+
return {
|
|
223
|
+
...message,
|
|
224
|
+
content: summary,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Summarize conversation by replacing early messages with a summary
|
|
229
|
+
*/
|
|
230
|
+
function summarizeConversation(messages, model, targetTokens, maxRecentTokens, preserveRecentMessages, summarizeToolResults) {
|
|
231
|
+
const maxTokens = getModelContextLimit(model);
|
|
232
|
+
const currentTokens = estimateConversationTokens(messages);
|
|
233
|
+
// If we don't need to summarize, return original messages
|
|
234
|
+
if (!targetTokens || currentTokens <= targetTokens) {
|
|
235
|
+
return messages;
|
|
236
|
+
}
|
|
237
|
+
const actualTargetTokens = targetTokens || Math.floor(maxTokens * 0.6);
|
|
238
|
+
const summarizationPoint = findSummarizationPoint(messages, model, actualTargetTokens, maxRecentTokens, preserveRecentMessages);
|
|
239
|
+
if (summarizationPoint <= 1) {
|
|
240
|
+
return messages; // Can't summarize much
|
|
241
|
+
}
|
|
242
|
+
// Create summary and keep recent messages
|
|
243
|
+
const summaryMessage = createSummaryMessage(summarizationPoint);
|
|
244
|
+
let recentMessages = messages.slice(summarizationPoint);
|
|
245
|
+
// Safety check: ensure we never return an empty array
|
|
246
|
+
if (recentMessages.length === 0) {
|
|
247
|
+
// If no recent messages, keep at least the last message
|
|
248
|
+
recentMessages = messages.slice(-1);
|
|
249
|
+
}
|
|
250
|
+
// Summarize large tool results in recent messages if enabled
|
|
251
|
+
if (summarizeToolResults) {
|
|
252
|
+
recentMessages = recentMessages.map((msg) => summarizeToolResult(msg));
|
|
253
|
+
}
|
|
254
|
+
// Always preserve the system message (first message) if it exists
|
|
255
|
+
const systemMessage = messages[0];
|
|
256
|
+
let result;
|
|
257
|
+
if (systemMessage && systemMessage.role === "system") {
|
|
258
|
+
result = [systemMessage, summaryMessage, ...recentMessages];
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
result = [summaryMessage, ...recentMessages];
|
|
262
|
+
}
|
|
263
|
+
// Final safety check: ensure we never return an empty array
|
|
264
|
+
if (result.length === 0) {
|
|
265
|
+
return messages; // Fallback to original messages
|
|
266
|
+
}
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=context-manager.js.map
|