@xiaoxiamimengfb/my-opencode-mem 2.12.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/README.md +155 -0
- package/dist/config.d.ts +58 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +411 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +427 -0
- package/dist/plugin.d.ts +5 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +4 -0
- package/dist/services/ai/ai-provider-factory.d.ts +8 -0
- package/dist/services/ai/ai-provider-factory.d.ts.map +1 -0
- package/dist/services/ai/ai-provider-factory.js +28 -0
- package/dist/services/ai/opencode-provider.d.ts +30 -0
- package/dist/services/ai/opencode-provider.d.ts.map +1 -0
- package/dist/services/ai/opencode-provider.js +332 -0
- package/dist/services/ai/provider-config.d.ts +17 -0
- package/dist/services/ai/provider-config.d.ts.map +1 -0
- package/dist/services/ai/provider-config.js +14 -0
- package/dist/services/ai/providers/anthropic-messages.d.ts +12 -0
- package/dist/services/ai/providers/anthropic-messages.d.ts.map +1 -0
- package/dist/services/ai/providers/anthropic-messages.js +184 -0
- package/dist/services/ai/providers/base-provider.d.ts +25 -0
- package/dist/services/ai/providers/base-provider.d.ts.map +1 -0
- package/dist/services/ai/providers/base-provider.js +23 -0
- package/dist/services/ai/providers/google-gemini.d.ts +16 -0
- package/dist/services/ai/providers/google-gemini.d.ts.map +1 -0
- package/dist/services/ai/providers/google-gemini.js +228 -0
- package/dist/services/ai/providers/openai-chat-completion.d.ts +13 -0
- package/dist/services/ai/providers/openai-chat-completion.d.ts.map +1 -0
- package/dist/services/ai/providers/openai-chat-completion.js +277 -0
- package/dist/services/ai/providers/openai-responses.d.ts +14 -0
- package/dist/services/ai/providers/openai-responses.d.ts.map +1 -0
- package/dist/services/ai/providers/openai-responses.js +182 -0
- package/dist/services/ai/session/ai-session-manager.d.ts +21 -0
- package/dist/services/ai/session/ai-session-manager.d.ts.map +1 -0
- package/dist/services/ai/session/ai-session-manager.js +166 -0
- package/dist/services/ai/session/session-types.d.ts +43 -0
- package/dist/services/ai/session/session-types.d.ts.map +1 -0
- package/dist/services/ai/session/session-types.js +1 -0
- package/dist/services/ai/tools/tool-schema.d.ts +41 -0
- package/dist/services/ai/tools/tool-schema.d.ts.map +1 -0
- package/dist/services/ai/tools/tool-schema.js +24 -0
- package/dist/services/ai/validators/user-profile-validator.d.ts +13 -0
- package/dist/services/ai/validators/user-profile-validator.d.ts.map +1 -0
- package/dist/services/ai/validators/user-profile-validator.js +111 -0
- package/dist/services/api-handlers.d.ts +164 -0
- package/dist/services/api-handlers.d.ts.map +1 -0
- package/dist/services/api-handlers.js +901 -0
- package/dist/services/auto-capture.d.ts +3 -0
- package/dist/services/auto-capture.d.ts.map +1 -0
- package/dist/services/auto-capture.js +306 -0
- package/dist/services/cleanup-service.d.ts +23 -0
- package/dist/services/cleanup-service.d.ts.map +1 -0
- package/dist/services/cleanup-service.js +102 -0
- package/dist/services/client.d.ts +118 -0
- package/dist/services/client.d.ts.map +1 -0
- package/dist/services/client.js +251 -0
- package/dist/services/context.d.ts +11 -0
- package/dist/services/context.d.ts.map +1 -0
- package/dist/services/context.js +24 -0
- package/dist/services/deduplication-service.d.ts +30 -0
- package/dist/services/deduplication-service.d.ts.map +1 -0
- package/dist/services/deduplication-service.js +124 -0
- package/dist/services/embedding.d.ts +15 -0
- package/dist/services/embedding.d.ts.map +1 -0
- package/dist/services/embedding.js +106 -0
- package/dist/services/jsonc.d.ts +7 -0
- package/dist/services/jsonc.d.ts.map +1 -0
- package/dist/services/jsonc.js +76 -0
- package/dist/services/language-detector.d.ts +3 -0
- package/dist/services/language-detector.d.ts.map +1 -0
- package/dist/services/language-detector.js +16 -0
- package/dist/services/logger.d.ts +2 -0
- package/dist/services/logger.d.ts.map +1 -0
- package/dist/services/logger.js +51 -0
- package/dist/services/migration-service.d.ts +42 -0
- package/dist/services/migration-service.d.ts.map +1 -0
- package/dist/services/migration-service.js +250 -0
- package/dist/services/privacy.d.ts +3 -0
- package/dist/services/privacy.d.ts.map +1 -0
- package/dist/services/privacy.js +7 -0
- package/dist/services/secret-resolver.d.ts +2 -0
- package/dist/services/secret-resolver.d.ts.map +1 -0
- package/dist/services/secret-resolver.js +55 -0
- package/dist/services/sqlite/connection-manager.d.ts +13 -0
- package/dist/services/sqlite/connection-manager.d.ts.map +1 -0
- package/dist/services/sqlite/connection-manager.js +74 -0
- package/dist/services/sqlite/shard-manager.d.ts +23 -0
- package/dist/services/sqlite/shard-manager.d.ts.map +1 -0
- package/dist/services/sqlite/shard-manager.js +288 -0
- package/dist/services/sqlite/sqlite-bootstrap.d.ts +2 -0
- package/dist/services/sqlite/sqlite-bootstrap.d.ts.map +1 -0
- package/dist/services/sqlite/sqlite-bootstrap.js +8 -0
- package/dist/services/sqlite/types.d.ts +42 -0
- package/dist/services/sqlite/types.d.ts.map +1 -0
- package/dist/services/sqlite/types.js +1 -0
- package/dist/services/sqlite/vector-search.d.ts +29 -0
- package/dist/services/sqlite/vector-search.d.ts.map +1 -0
- package/dist/services/sqlite/vector-search.js +268 -0
- package/dist/services/tags.d.ts +24 -0
- package/dist/services/tags.d.ts.map +1 -0
- package/dist/services/tags.js +146 -0
- package/dist/services/user-memory-learning.d.ts +3 -0
- package/dist/services/user-memory-learning.d.ts.map +1 -0
- package/dist/services/user-memory-learning.js +231 -0
- package/dist/services/user-profile/profile-context.d.ts +2 -0
- package/dist/services/user-profile/profile-context.d.ts.map +1 -0
- package/dist/services/user-profile/profile-context.js +40 -0
- package/dist/services/user-profile/profile-utils.d.ts +3 -0
- package/dist/services/user-profile/profile-utils.d.ts.map +1 -0
- package/dist/services/user-profile/profile-utils.js +45 -0
- package/dist/services/user-profile/types.d.ts +46 -0
- package/dist/services/user-profile/types.d.ts.map +1 -0
- package/dist/services/user-profile/types.js +1 -0
- package/dist/services/user-profile/user-profile-manager.d.ts +23 -0
- package/dist/services/user-profile/user-profile-manager.d.ts.map +1 -0
- package/dist/services/user-profile/user-profile-manager.js +292 -0
- package/dist/services/user-prompt/user-prompt-manager.d.ts +41 -0
- package/dist/services/user-prompt/user-prompt-manager.d.ts.map +1 -0
- package/dist/services/user-prompt/user-prompt-manager.js +192 -0
- package/dist/services/vector-backends/backend-factory.d.ts +3 -0
- package/dist/services/vector-backends/backend-factory.d.ts.map +1 -0
- package/dist/services/vector-backends/backend-factory.js +104 -0
- package/dist/services/vector-backends/exact-scan-backend.d.ts +39 -0
- package/dist/services/vector-backends/exact-scan-backend.d.ts.map +1 -0
- package/dist/services/vector-backends/exact-scan-backend.js +63 -0
- package/dist/services/vector-backends/types.d.ts +51 -0
- package/dist/services/vector-backends/types.d.ts.map +1 -0
- package/dist/services/vector-backends/types.js +1 -0
- package/dist/services/vector-backends/usearch-backend.d.ts +47 -0
- package/dist/services/vector-backends/usearch-backend.d.ts.map +1 -0
- package/dist/services/vector-backends/usearch-backend.js +174 -0
- package/dist/services/web-server-worker.d.ts +2 -0
- package/dist/services/web-server-worker.d.ts.map +1 -0
- package/dist/services/web-server-worker.js +283 -0
- package/dist/services/web-server.d.ts +31 -0
- package/dist/services/web-server.d.ts.map +1 -0
- package/dist/services/web-server.js +356 -0
- package/dist/types/index.d.ts +19 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +1 -0
- package/dist/web/app.d.ts +2 -0
- package/dist/web/app.d.ts.map +1 -0
- package/dist/web/app.js +1194 -0
- package/dist/web/favicon.ico +0 -0
- package/dist/web/i18n.d.ts +2 -0
- package/dist/web/i18n.d.ts.map +1 -0
- package/dist/web/i18n.js +265 -0
- package/dist/web/index.html +284 -0
- package/dist/web/styles.css +1631 -0
- package/package.json +71 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import { generateText, Output } from "ai";
|
|
5
|
+
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
6
|
+
import { createOpenAI } from "@ai-sdk/openai";
|
|
7
|
+
import { createMinimax, createMinimaxOpenAI } from "vercel-minimax-ai-provider";
|
|
8
|
+
// --- State (set from plugin init in index.ts, Task 4) ---
|
|
9
|
+
let _statePath = null;
|
|
10
|
+
let _connectedProviders = [];
|
|
11
|
+
export function setStatePath(path) {
|
|
12
|
+
_statePath = path;
|
|
13
|
+
}
|
|
14
|
+
export function getStatePath() {
|
|
15
|
+
if (!_statePath) {
|
|
16
|
+
throw new Error("opencode state path not initialized. Plugin may not be fully started.");
|
|
17
|
+
}
|
|
18
|
+
return _statePath;
|
|
19
|
+
}
|
|
20
|
+
// Provider name aliases mapping
|
|
21
|
+
const PROVIDER_ALIASES = {
|
|
22
|
+
"MiniMax Coding Plan (minimaxi.com)": "minimax-cn-coding-plan",
|
|
23
|
+
"MiniMax (minimaxi.com)": "minimax",
|
|
24
|
+
"MiniMax Coding Plan (minimax.io)": "minimax-coding-plan",
|
|
25
|
+
};
|
|
26
|
+
// Reverse mapping: internal name -> opencode display name
|
|
27
|
+
const ALIASES_REVERSE = {
|
|
28
|
+
"minimax-cn-coding-plan": "MiniMax Coding Plan (minimaxi.com)",
|
|
29
|
+
"minimax": "MiniMax (minimaxi.com)",
|
|
30
|
+
"minimax-coding-plan": "MiniMax Coding Plan (minimax.io)",
|
|
31
|
+
};
|
|
32
|
+
export function setConnectedProviders(providers) {
|
|
33
|
+
let validProviders = [];
|
|
34
|
+
if (Array.isArray(providers)) {
|
|
35
|
+
validProviders = providers.filter(p => typeof p === "string");
|
|
36
|
+
}
|
|
37
|
+
else if (typeof providers === "string") {
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(providers);
|
|
40
|
+
validProviders = Array.isArray(parsed) ? parsed.filter(p => typeof p === "string") : [];
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
validProviders = [];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
_connectedProviders = validProviders;
|
|
47
|
+
}
|
|
48
|
+
export function isProviderConnected(providerName) {
|
|
49
|
+
if (providerName.includes("minimax") || providerName.includes("MiniMax")) {
|
|
50
|
+
const homeDir = os.homedir();
|
|
51
|
+
const authPath = join(homeDir, ".local", "share", "opencode", "auth.json");
|
|
52
|
+
try {
|
|
53
|
+
if (existsSync(authPath)) {
|
|
54
|
+
const authContent = readFileSync(authPath, "utf-8");
|
|
55
|
+
const auth = JSON.parse(authContent);
|
|
56
|
+
const keys = Object.keys(auth);
|
|
57
|
+
const hasMinimax = keys.some(k => k.toLowerCase().includes("minimax"));
|
|
58
|
+
return hasMinimax;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch { }
|
|
62
|
+
}
|
|
63
|
+
if (_connectedProviders.includes(providerName)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
for (const connected of _connectedProviders) {
|
|
67
|
+
if (PROVIDER_ALIASES[connected] === providerName) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const reverseMatch = ALIASES_REVERSE[providerName];
|
|
72
|
+
if (reverseMatch && _connectedProviders.includes(reverseMatch)) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
// --- Auth ---
|
|
78
|
+
function findAuthJsonPath(statePath) {
|
|
79
|
+
const homeDir = os.homedir();
|
|
80
|
+
const candidates = [
|
|
81
|
+
join(statePath, "auth.json"),
|
|
82
|
+
join(dirname(dirname(statePath)), "share", "opencode", "auth.json"),
|
|
83
|
+
join(statePath.replace("/state/", "/share/"), "auth.json"),
|
|
84
|
+
join(statePath.replace("\\state\\", "\\share\\"), "auth.json"),
|
|
85
|
+
// 全局 auth.json 路径 (Linux/macOS: ~/.local/share/opencode/auth.json, Windows: %USERPROFILE%/.local/share/opencode/auth.json)
|
|
86
|
+
join(homeDir, ".local", "share", "opencode", "auth.json"),
|
|
87
|
+
// Windows 可能的全局路径
|
|
88
|
+
join(homeDir, ".config", "opencode", "auth.json"),
|
|
89
|
+
];
|
|
90
|
+
return candidates.find(existsSync);
|
|
91
|
+
}
|
|
92
|
+
export function readOpencodeAuth(statePath, providerName) {
|
|
93
|
+
const authPath = findAuthJsonPath(statePath);
|
|
94
|
+
let raw;
|
|
95
|
+
if (authPath) {
|
|
96
|
+
try {
|
|
97
|
+
raw = readFileSync(authPath, "utf-8");
|
|
98
|
+
}
|
|
99
|
+
catch { }
|
|
100
|
+
}
|
|
101
|
+
if (!raw || !authPath) {
|
|
102
|
+
throw new Error(`opencode auth.json not found at ${authPath ?? statePath}. Is opencode authenticated?`);
|
|
103
|
+
}
|
|
104
|
+
let parsed;
|
|
105
|
+
try {
|
|
106
|
+
parsed = JSON.parse(raw);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
throw new Error(`Failed to read opencode auth.json: invalid JSON`);
|
|
110
|
+
}
|
|
111
|
+
let auth = parsed[providerName];
|
|
112
|
+
if (!auth) {
|
|
113
|
+
const reverseKey = ALIASES_REVERSE[providerName];
|
|
114
|
+
if (reverseKey) {
|
|
115
|
+
auth = parsed[reverseKey];
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!auth) {
|
|
119
|
+
for (const [authKey, internalName] of Object.entries(PROVIDER_ALIASES)) {
|
|
120
|
+
if (internalName === providerName && parsed[authKey]) {
|
|
121
|
+
auth = parsed[authKey];
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!auth) {
|
|
127
|
+
const connected = Object.keys(parsed).join(", ") || "none";
|
|
128
|
+
throw new Error(`Provider '${providerName}' not found in opencode auth.json. Connected providers: ${connected}`);
|
|
129
|
+
}
|
|
130
|
+
return auth;
|
|
131
|
+
}
|
|
132
|
+
// --- OAuth Fetch ---
|
|
133
|
+
const OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
134
|
+
const OAUTH_TOKEN_URL = "https://console.anthropic.com/v1/oauth/token";
|
|
135
|
+
const OAUTH_REQUIRED_BETAS = ["oauth-2025-04-20", "interleaved-thinking-2025-05-14"];
|
|
136
|
+
const MCP_TOOL_PREFIX = "mcp_";
|
|
137
|
+
export function createOAuthFetch(statePath, providerName) {
|
|
138
|
+
return async (input, init) => {
|
|
139
|
+
let auth = readOpencodeAuth(statePath, providerName);
|
|
140
|
+
// Refresh token if expired
|
|
141
|
+
if (!auth.access || auth.expires < Date.now()) {
|
|
142
|
+
const refreshResponse = await fetch(OAUTH_TOKEN_URL, {
|
|
143
|
+
method: "POST",
|
|
144
|
+
headers: { "Content-Type": "application/json" },
|
|
145
|
+
body: JSON.stringify({
|
|
146
|
+
grant_type: "refresh_token",
|
|
147
|
+
refresh_token: auth.refresh,
|
|
148
|
+
client_id: OAUTH_CLIENT_ID,
|
|
149
|
+
}),
|
|
150
|
+
});
|
|
151
|
+
if (!refreshResponse.ok) {
|
|
152
|
+
throw new Error(`OAuth token refresh failed: ${refreshResponse.status}`);
|
|
153
|
+
}
|
|
154
|
+
const json = (await refreshResponse.json());
|
|
155
|
+
auth = {
|
|
156
|
+
type: "oauth",
|
|
157
|
+
refresh: json.refresh_token,
|
|
158
|
+
access: json.access_token,
|
|
159
|
+
expires: Date.now() + json.expires_in * 1000,
|
|
160
|
+
};
|
|
161
|
+
const authPath = findAuthJsonPath(statePath);
|
|
162
|
+
if (authPath) {
|
|
163
|
+
try {
|
|
164
|
+
const allAuth = JSON.parse(readFileSync(authPath, "utf-8"));
|
|
165
|
+
allAuth[providerName] = auth;
|
|
166
|
+
writeFileSync(authPath, JSON.stringify(allAuth));
|
|
167
|
+
}
|
|
168
|
+
catch { }
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
// Build headers
|
|
172
|
+
const requestInit = init ?? {};
|
|
173
|
+
const requestHeaders = new Headers();
|
|
174
|
+
if (input instanceof Request) {
|
|
175
|
+
input.headers.forEach((value, key) => requestHeaders.set(key, value));
|
|
176
|
+
}
|
|
177
|
+
if (requestInit.headers) {
|
|
178
|
+
if (requestInit.headers instanceof Headers) {
|
|
179
|
+
requestInit.headers.forEach((value, key) => requestHeaders.set(key, value));
|
|
180
|
+
}
|
|
181
|
+
else if (Array.isArray(requestInit.headers)) {
|
|
182
|
+
for (const pair of requestInit.headers) {
|
|
183
|
+
const [key, value] = pair;
|
|
184
|
+
if (typeof value !== "undefined")
|
|
185
|
+
requestHeaders.set(key, value);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
for (const [key, value] of Object.entries(requestInit.headers)) {
|
|
190
|
+
if (typeof value !== "undefined")
|
|
191
|
+
requestHeaders.set(key, String(value));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Merge beta headers
|
|
196
|
+
const incomingBeta = requestHeaders.get("anthropic-beta") ?? "";
|
|
197
|
+
const incomingBetas = incomingBeta
|
|
198
|
+
.split(",")
|
|
199
|
+
.map((b) => b.trim())
|
|
200
|
+
.filter(Boolean);
|
|
201
|
+
const mergedBetas = [...new Set([...OAUTH_REQUIRED_BETAS, ...incomingBetas])].join(",");
|
|
202
|
+
requestHeaders.set("authorization", `Bearer ${auth.access}`);
|
|
203
|
+
requestHeaders.set("anthropic-beta", mergedBetas);
|
|
204
|
+
requestHeaders.set("user-agent", "claude-cli/2.1.2 (external, cli)");
|
|
205
|
+
requestHeaders.delete("x-api-key");
|
|
206
|
+
// Prefix tool names in request body
|
|
207
|
+
let body = requestInit.body;
|
|
208
|
+
if (body && typeof body === "string") {
|
|
209
|
+
try {
|
|
210
|
+
const parsed = JSON.parse(body);
|
|
211
|
+
if (parsed.tools && Array.isArray(parsed.tools)) {
|
|
212
|
+
parsed.tools = parsed.tools.map((tool) => ({
|
|
213
|
+
...tool,
|
|
214
|
+
name: tool.name ? `${MCP_TOOL_PREFIX}${tool.name}` : tool.name,
|
|
215
|
+
}));
|
|
216
|
+
}
|
|
217
|
+
if (parsed.messages && Array.isArray(parsed.messages)) {
|
|
218
|
+
parsed.messages = parsed.messages.map((msg) => {
|
|
219
|
+
if (msg.content && Array.isArray(msg.content)) {
|
|
220
|
+
msg.content = msg.content.map((block) => {
|
|
221
|
+
if (block.type === "tool_use" && block.name) {
|
|
222
|
+
return { ...block, name: `${MCP_TOOL_PREFIX}${block.name}` };
|
|
223
|
+
}
|
|
224
|
+
return block;
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return msg;
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
body = JSON.stringify(parsed);
|
|
231
|
+
}
|
|
232
|
+
catch { }
|
|
233
|
+
}
|
|
234
|
+
// Modify URL: add ?beta=true to /v1/messages
|
|
235
|
+
let requestInput = input;
|
|
236
|
+
try {
|
|
237
|
+
let requestUrl = null;
|
|
238
|
+
if (typeof input === "string" || input instanceof URL) {
|
|
239
|
+
requestUrl = new URL(input.toString());
|
|
240
|
+
}
|
|
241
|
+
else if (input instanceof Request) {
|
|
242
|
+
requestUrl = new URL(input.url);
|
|
243
|
+
}
|
|
244
|
+
if (requestUrl?.pathname === "/v1/messages" && !requestUrl.searchParams.has("beta")) {
|
|
245
|
+
requestUrl.searchParams.set("beta", "true");
|
|
246
|
+
requestInput =
|
|
247
|
+
input instanceof Request ? new Request(requestUrl.toString(), input) : requestUrl;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
catch { }
|
|
251
|
+
const response = await fetch(requestInput, { ...requestInit, body, headers: requestHeaders });
|
|
252
|
+
// Strip mcp_ prefix from tool names in streaming response
|
|
253
|
+
if (response.body) {
|
|
254
|
+
const reader = response.body.getReader();
|
|
255
|
+
const decoder = new TextDecoder();
|
|
256
|
+
const encoder = new TextEncoder();
|
|
257
|
+
const stream = new ReadableStream({
|
|
258
|
+
async pull(controller) {
|
|
259
|
+
const { done, value } = await reader.read();
|
|
260
|
+
if (done) {
|
|
261
|
+
controller.close();
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
let text = decoder.decode(value, { stream: true });
|
|
265
|
+
text = text.replace(/"name"\s*:\s*"mcp_([^"]+)"/g, '"name": "$1"');
|
|
266
|
+
controller.enqueue(encoder.encode(text));
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
return new Response(stream, {
|
|
270
|
+
status: response.status,
|
|
271
|
+
statusText: response.statusText,
|
|
272
|
+
headers: response.headers,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
return response;
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
// --- Provider ---
|
|
279
|
+
export function createOpencodeAIProvider(providerName, auth, statePath) {
|
|
280
|
+
if (providerName === "anthropic") {
|
|
281
|
+
if (auth.type === "oauth") {
|
|
282
|
+
if (!statePath)
|
|
283
|
+
throw new Error("statePath is required for OAuth authentication");
|
|
284
|
+
return createAnthropic({
|
|
285
|
+
apiKey: "",
|
|
286
|
+
fetch: createOAuthFetch(statePath, providerName),
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return createAnthropic({ apiKey: auth.key });
|
|
290
|
+
}
|
|
291
|
+
if (providerName === "openai") {
|
|
292
|
+
if (auth.type === "oauth") {
|
|
293
|
+
throw new Error("OpenAI does not support OAuth authentication. Use an API key instead.");
|
|
294
|
+
}
|
|
295
|
+
return createOpenAI({ apiKey: auth.key });
|
|
296
|
+
}
|
|
297
|
+
if (providerName === "minimax") {
|
|
298
|
+
if (auth.type === "oauth") {
|
|
299
|
+
throw new Error("Minimax does not support OAuth authentication. Use an API key instead.");
|
|
300
|
+
}
|
|
301
|
+
return createMinimaxOpenAI({ apiKey: auth.key });
|
|
302
|
+
}
|
|
303
|
+
if (providerName === "minimax-cn-coding-plan") {
|
|
304
|
+
if (auth.type === "oauth") {
|
|
305
|
+
throw new Error("Minimax does not support OAuth authentication. Use an API key instead.");
|
|
306
|
+
}
|
|
307
|
+
return createMinimax({
|
|
308
|
+
apiKey: auth.key,
|
|
309
|
+
baseURL: "https://api.minimaxi.com/anthropic/v1"
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
if (providerName === "minimax-cn") {
|
|
313
|
+
if (auth.type === "oauth") {
|
|
314
|
+
throw new Error("Minimax does not support OAuth authentication. Use an API key instead.");
|
|
315
|
+
}
|
|
316
|
+
return createMinimaxOpenAI({ apiKey: auth.key });
|
|
317
|
+
}
|
|
318
|
+
throw new Error(`Unsupported opencode provider: '${providerName}'. Supported providers: anthropic, openai, minimax, minimax-cn-coding-plan, minimax-cn`);
|
|
319
|
+
}
|
|
320
|
+
// --- Structured Output ---
|
|
321
|
+
export async function generateStructuredOutput(options) {
|
|
322
|
+
const auth = readOpencodeAuth(options.statePath, options.providerName);
|
|
323
|
+
const provider = createOpencodeAIProvider(options.providerName, auth, options.statePath);
|
|
324
|
+
const result = await generateText({
|
|
325
|
+
model: provider(options.modelId),
|
|
326
|
+
system: options.systemPrompt,
|
|
327
|
+
prompt: options.userPrompt,
|
|
328
|
+
output: Output.object({ schema: options.schema }),
|
|
329
|
+
temperature: options.temperature ?? 0.3,
|
|
330
|
+
});
|
|
331
|
+
return result.output;
|
|
332
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ProviderConfig } from "./providers/base-provider.js";
|
|
2
|
+
interface MemoryProviderRuntimeConfig {
|
|
3
|
+
memoryModel?: string;
|
|
4
|
+
memoryApiUrl?: string;
|
|
5
|
+
memoryApiKey?: string;
|
|
6
|
+
memoryTemperature?: number | false;
|
|
7
|
+
memoryExtraParams?: Record<string, unknown>;
|
|
8
|
+
autoCaptureMaxIterations?: number;
|
|
9
|
+
autoCaptureIterationTimeout?: number;
|
|
10
|
+
}
|
|
11
|
+
interface ProviderConfigOverrides {
|
|
12
|
+
maxIterations?: number;
|
|
13
|
+
iterationTimeout?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function buildMemoryProviderConfig(config: MemoryProviderRuntimeConfig, overrides?: ProviderConfigOverrides): ProviderConfig;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=provider-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-config.d.ts","sourceRoot":"","sources":["../../../src/services/ai/provider-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,UAAU,2BAA2B;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACnC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5C,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,2BAA2B,CAAC,EAAE,MAAM,CAAC;CACtC;AAED,UAAU,uBAAuB;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,2BAA2B,EACnC,SAAS,GAAE,uBAA4B,GACtC,cAAc,CAchB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function buildMemoryProviderConfig(config, overrides = {}) {
|
|
2
|
+
if (!config.memoryModel || !config.memoryApiUrl) {
|
|
3
|
+
throw new Error("External API not configured for memory provider");
|
|
4
|
+
}
|
|
5
|
+
return {
|
|
6
|
+
model: config.memoryModel,
|
|
7
|
+
apiUrl: config.memoryApiUrl,
|
|
8
|
+
apiKey: config.memoryApiKey,
|
|
9
|
+
memoryTemperature: config.memoryTemperature,
|
|
10
|
+
extraParams: config.memoryExtraParams,
|
|
11
|
+
maxIterations: overrides.maxIterations ?? config.autoCaptureMaxIterations,
|
|
12
|
+
iterationTimeout: overrides.iterationTimeout ?? config.autoCaptureIterationTimeout,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseAIProvider, type ToolCallResult } from "./base-provider.js";
|
|
2
|
+
import { AISessionManager } from "../session/ai-session-manager.js";
|
|
3
|
+
import { type ChatCompletionTool } from "../tools/tool-schema.js";
|
|
4
|
+
export declare class AnthropicMessagesProvider extends BaseAIProvider {
|
|
5
|
+
private aiSessionManager;
|
|
6
|
+
constructor(config: any, aiSessionManager: AISessionManager);
|
|
7
|
+
getProviderName(): string;
|
|
8
|
+
supportsSession(): boolean;
|
|
9
|
+
executeToolCall(systemPrompt: string, userPrompt: string, toolSchema: ChatCompletionTool, sessionId: string): Promise<ToolCallResult>;
|
|
10
|
+
private extractToolUse;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=anthropic-messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-messages.d.ts","sourceRoot":"","sources":["../../../../src/services/ai/providers/anthropic-messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAuB,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AA4BvF,qBAAa,yBAA0B,SAAQ,cAAc;IAC3D,OAAO,CAAC,gBAAgB,CAAmB;gBAE/B,MAAM,EAAE,GAAG,EAAE,gBAAgB,EAAE,gBAAgB;IAK3D,eAAe,IAAI,MAAM;IAIzB,eAAe,IAAI,OAAO;IAIpB,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,kBAAkB,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC;IAoL1B,OAAO,CAAC,cAAc;CAavB"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { BaseAIProvider } from "./base-provider.js";
|
|
2
|
+
import { AISessionManager } from "../session/ai-session-manager.js";
|
|
3
|
+
import { ToolSchemaConverter } from "../tools/tool-schema.js";
|
|
4
|
+
import { log } from "../../logger.js";
|
|
5
|
+
import { UserProfileValidator } from "../validators/user-profile-validator.js";
|
|
6
|
+
export class AnthropicMessagesProvider extends BaseAIProvider {
|
|
7
|
+
aiSessionManager;
|
|
8
|
+
constructor(config, aiSessionManager) {
|
|
9
|
+
super(config);
|
|
10
|
+
this.aiSessionManager = aiSessionManager;
|
|
11
|
+
}
|
|
12
|
+
getProviderName() {
|
|
13
|
+
return "anthropic";
|
|
14
|
+
}
|
|
15
|
+
supportsSession() {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
async executeToolCall(systemPrompt, userPrompt, toolSchema, sessionId) {
|
|
19
|
+
let session = this.aiSessionManager.getSession(sessionId, "anthropic");
|
|
20
|
+
if (!session) {
|
|
21
|
+
session = this.aiSessionManager.createSession({
|
|
22
|
+
provider: "anthropic",
|
|
23
|
+
sessionId,
|
|
24
|
+
metadata: { systemPrompt },
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const storedMessages = this.aiSessionManager.getMessages(session.id);
|
|
28
|
+
const messages = [];
|
|
29
|
+
for (const msg of storedMessages) {
|
|
30
|
+
if (msg.role === "system")
|
|
31
|
+
continue;
|
|
32
|
+
const anthropicMsg = {
|
|
33
|
+
role: msg.role,
|
|
34
|
+
content: msg.contentBlocks || msg.content,
|
|
35
|
+
};
|
|
36
|
+
messages.push(anthropicMsg);
|
|
37
|
+
}
|
|
38
|
+
const userSequence = this.aiSessionManager.getLastSequence(session.id) + 1;
|
|
39
|
+
this.aiSessionManager.addMessage({
|
|
40
|
+
aiSessionId: session.id,
|
|
41
|
+
sequence: userSequence,
|
|
42
|
+
role: "user",
|
|
43
|
+
content: userPrompt,
|
|
44
|
+
});
|
|
45
|
+
messages.push({ role: "user", content: userPrompt });
|
|
46
|
+
let iterations = 0;
|
|
47
|
+
const maxIterations = this.config.maxIterations ?? 5;
|
|
48
|
+
const iterationTimeout = this.config.iterationTimeout ?? 30000;
|
|
49
|
+
while (iterations < maxIterations) {
|
|
50
|
+
iterations++;
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
const timeout = setTimeout(() => controller.abort(), iterationTimeout);
|
|
53
|
+
try {
|
|
54
|
+
const tool = ToolSchemaConverter.toAnthropic(toolSchema);
|
|
55
|
+
const requestBody = {
|
|
56
|
+
model: this.config.model,
|
|
57
|
+
max_tokens: this.config.maxTokens ?? 4096,
|
|
58
|
+
system: systemPrompt,
|
|
59
|
+
messages,
|
|
60
|
+
tools: [tool],
|
|
61
|
+
};
|
|
62
|
+
const headers = {
|
|
63
|
+
"Content-Type": "application/json",
|
|
64
|
+
"anthropic-version": "2023-06-01",
|
|
65
|
+
};
|
|
66
|
+
if (this.config.apiKey) {
|
|
67
|
+
headers["x-api-key"] = this.config.apiKey;
|
|
68
|
+
}
|
|
69
|
+
const response = await fetch(`${this.config.apiUrl}/messages`, {
|
|
70
|
+
method: "POST",
|
|
71
|
+
headers,
|
|
72
|
+
body: JSON.stringify(requestBody),
|
|
73
|
+
signal: controller.signal,
|
|
74
|
+
});
|
|
75
|
+
clearTimeout(timeout);
|
|
76
|
+
if (!response.ok) {
|
|
77
|
+
const errorText = await response.text().catch(() => response.statusText);
|
|
78
|
+
log("Anthropic Messages API error", {
|
|
79
|
+
provider: this.getProviderName(),
|
|
80
|
+
model: this.config.model,
|
|
81
|
+
status: response.status,
|
|
82
|
+
error: errorText,
|
|
83
|
+
iteration: iterations,
|
|
84
|
+
});
|
|
85
|
+
return {
|
|
86
|
+
success: false,
|
|
87
|
+
error: `API error: ${response.status} - ${errorText}`,
|
|
88
|
+
iterations,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const data = (await response.json());
|
|
92
|
+
const assistantSequence = this.aiSessionManager.getLastSequence(session.id) + 1;
|
|
93
|
+
this.aiSessionManager.addMessage({
|
|
94
|
+
aiSessionId: session.id,
|
|
95
|
+
sequence: assistantSequence,
|
|
96
|
+
role: "assistant",
|
|
97
|
+
content: JSON.stringify(data.content),
|
|
98
|
+
contentBlocks: data.content,
|
|
99
|
+
});
|
|
100
|
+
messages.push({
|
|
101
|
+
role: "assistant",
|
|
102
|
+
content: data.content,
|
|
103
|
+
});
|
|
104
|
+
const toolUse = this.extractToolUse(data, toolSchema.function.name);
|
|
105
|
+
if (toolUse) {
|
|
106
|
+
try {
|
|
107
|
+
const result = UserProfileValidator.validate(toolUse);
|
|
108
|
+
if (!result.valid) {
|
|
109
|
+
throw new Error(result.errors.join(", "));
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
success: true,
|
|
113
|
+
data: result.data,
|
|
114
|
+
iterations,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
catch (validationError) {
|
|
118
|
+
const errorStack = validationError instanceof Error ? validationError.stack : undefined;
|
|
119
|
+
log("Anthropic tool response validation failed", {
|
|
120
|
+
error: String(validationError),
|
|
121
|
+
stack: errorStack,
|
|
122
|
+
errorType: validationError instanceof Error
|
|
123
|
+
? validationError.constructor.name
|
|
124
|
+
: typeof validationError,
|
|
125
|
+
toolName: toolSchema.function.name,
|
|
126
|
+
iteration: iterations,
|
|
127
|
+
rawData: JSON.stringify(toolUse).slice(0, 500),
|
|
128
|
+
});
|
|
129
|
+
return {
|
|
130
|
+
success: false,
|
|
131
|
+
error: `Validation failed: ${String(validationError)}`,
|
|
132
|
+
iterations,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (data.stop_reason === "end_turn") {
|
|
137
|
+
const retrySequence = this.aiSessionManager.getLastSequence(session.id) + 1;
|
|
138
|
+
const retryPrompt = "Please use the save_memories tool to extract and save the memories from the conversation as instructed.";
|
|
139
|
+
this.aiSessionManager.addMessage({
|
|
140
|
+
aiSessionId: session.id,
|
|
141
|
+
sequence: retrySequence,
|
|
142
|
+
role: "user",
|
|
143
|
+
content: retryPrompt,
|
|
144
|
+
});
|
|
145
|
+
messages.push({ role: "user", content: retryPrompt });
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
clearTimeout(timeout);
|
|
153
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
154
|
+
return {
|
|
155
|
+
success: false,
|
|
156
|
+
error: `API request timeout (${this.config.iterationTimeout}ms)`,
|
|
157
|
+
iterations,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
success: false,
|
|
162
|
+
error: String(error),
|
|
163
|
+
iterations,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
success: false,
|
|
169
|
+
error: `Max iterations (${maxIterations}) reached without tool use`,
|
|
170
|
+
iterations,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
extractToolUse(data, expectedToolName) {
|
|
174
|
+
if (!data.content || !Array.isArray(data.content)) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
for (const block of data.content) {
|
|
178
|
+
if (block.type === "tool_use" && block.name === expectedToolName && block.input) {
|
|
179
|
+
return block.input;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ToolCallResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
data?: any;
|
|
4
|
+
error?: string;
|
|
5
|
+
iterations?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ProviderConfig {
|
|
8
|
+
model: string;
|
|
9
|
+
apiUrl: string;
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
maxIterations?: number;
|
|
12
|
+
iterationTimeout?: number;
|
|
13
|
+
maxTokens?: number;
|
|
14
|
+
memoryTemperature?: number | false;
|
|
15
|
+
extraParams?: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
export declare function applySafeExtraParams(requestBody: Record<string, any>, extraParams: Record<string, unknown>): void;
|
|
18
|
+
export declare abstract class BaseAIProvider {
|
|
19
|
+
protected config: ProviderConfig;
|
|
20
|
+
constructor(config: ProviderConfig);
|
|
21
|
+
abstract executeToolCall(systemPrompt: string, userPrompt: string, toolSchema: any, sessionId: string): Promise<ToolCallResult>;
|
|
22
|
+
abstract getProviderName(): string;
|
|
23
|
+
abstract supportsSession(): boolean;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=base-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-provider.d.ts","sourceRoot":"","sources":["../../../../src/services/ai/providers/base-provider.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAaD,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,IAAI,CAMN;AAED,8BAAsB,cAAc;IAClC,SAAS,CAAC,MAAM,EAAE,cAAc,CAAC;gBAErB,MAAM,EAAE,cAAc;IAIlC,QAAQ,CAAC,eAAe,CACtB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,GAAG,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC;IAE1B,QAAQ,CAAC,eAAe,IAAI,MAAM;IAElC,QAAQ,CAAC,eAAe,IAAI,OAAO;CACpC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const PROTECTED_KEYS = new Set([
|
|
2
|
+
"model",
|
|
3
|
+
"messages",
|
|
4
|
+
"tools",
|
|
5
|
+
"tool_choice",
|
|
6
|
+
"temperature",
|
|
7
|
+
"input",
|
|
8
|
+
"instructions",
|
|
9
|
+
"conversation",
|
|
10
|
+
]);
|
|
11
|
+
export function applySafeExtraParams(requestBody, extraParams) {
|
|
12
|
+
for (const [key, value] of Object.entries(extraParams)) {
|
|
13
|
+
if (!PROTECTED_KEYS.has(key)) {
|
|
14
|
+
requestBody[key] = value;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class BaseAIProvider {
|
|
19
|
+
config;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = config;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { BaseAIProvider, type ToolCallResult } from "./base-provider.js";
|
|
2
|
+
import { AISessionManager } from "../session/ai-session-manager.js";
|
|
3
|
+
import type { ChatCompletionTool } from "../tools/tool-schema.js";
|
|
4
|
+
/**
|
|
5
|
+
* Google Gemini Provider
|
|
6
|
+
* Supports Google's Gemini models (e.g. gemini-1.5-flash) via Google AI Studio API.
|
|
7
|
+
*/
|
|
8
|
+
export declare class GoogleGeminiProvider extends BaseAIProvider {
|
|
9
|
+
private aiSessionManager;
|
|
10
|
+
constructor(config: any, aiSessionManager: AISessionManager);
|
|
11
|
+
getProviderName(): string;
|
|
12
|
+
supportsSession(): boolean;
|
|
13
|
+
private addToolResponse;
|
|
14
|
+
executeToolCall(systemPrompt: string, userPrompt: string, toolSchema: ChatCompletionTool, sessionId: string): Promise<ToolCallResult>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=google-gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-gemini.d.ts","sourceRoot":"","sources":["../../../../src/services/ai/providers/google-gemini.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAIlE;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,cAAc;IACtD,OAAO,CAAC,gBAAgB,CAAmB;gBAE/B,MAAM,EAAE,GAAG,EAAE,gBAAgB,EAAE,gBAAgB;IAK3D,eAAe,IAAI,MAAM;IAIzB,eAAe,IAAI,OAAO;IAI1B,OAAO,CAAC,eAAe;IA4BjB,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,kBAAkB,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC;CA2N3B"}
|