opencode-mem 2.3.5 → 2.3.6
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/dist/services/ai/providers/openai-chat-completion.d.ts +2 -0
- package/dist/services/ai/providers/openai-chat-completion.d.ts.map +1 -1
- package/dist/services/ai/providers/openai-chat-completion.js +92 -32
- package/dist/services/sqlite/connection-manager.d.ts.map +1 -1
- package/dist/services/sqlite/connection-manager.js +14 -2
- package/dist/services/web-server.d.ts.map +1 -1
- package/dist/services/web-server.js +15 -2
- package/package.json +1 -1
|
@@ -6,6 +6,8 @@ export declare class OpenAIChatCompletionProvider extends BaseAIProvider {
|
|
|
6
6
|
constructor(config: any, aiSessionManager: AISessionManager);
|
|
7
7
|
getProviderName(): string;
|
|
8
8
|
supportsSession(): boolean;
|
|
9
|
+
private addToolResponse;
|
|
10
|
+
private filterIncompleteToolCallSequences;
|
|
9
11
|
executeToolCall(systemPrompt: string, userPrompt: string, toolSchema: ChatCompletionTool, sessionId: string): Promise<ToolCallResult>;
|
|
10
12
|
}
|
|
11
13
|
//# sourceMappingURL=openai-chat-completion.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-chat-completion.d.ts","sourceRoot":"","sources":["../../../../src/services/ai/providers/openai-chat-completion.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;
|
|
1
|
+
{"version":3,"file":"openai-chat-completion.d.ts","sourceRoot":"","sources":["../../../../src/services/ai/providers/openai-chat-completion.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;AAqBlE,qBAAa,4BAA6B,SAAQ,cAAc;IAC9D,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;IAqBvB,OAAO,CAAC,iCAAiC;IAwCnC,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,kBAAkB,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC;CAkO3B"}
|
|
@@ -14,6 +14,57 @@ export class OpenAIChatCompletionProvider extends BaseAIProvider {
|
|
|
14
14
|
supportsSession() {
|
|
15
15
|
return true;
|
|
16
16
|
}
|
|
17
|
+
addToolResponse(sessionId, messages, toolCallId, content) {
|
|
18
|
+
const sequence = this.aiSessionManager.getLastSequence(sessionId) + 1;
|
|
19
|
+
this.aiSessionManager.addMessage({
|
|
20
|
+
aiSessionId: sessionId,
|
|
21
|
+
sequence,
|
|
22
|
+
role: "tool",
|
|
23
|
+
content,
|
|
24
|
+
toolCallId,
|
|
25
|
+
});
|
|
26
|
+
messages.push({
|
|
27
|
+
role: "tool",
|
|
28
|
+
tool_call_id: toolCallId,
|
|
29
|
+
content,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
filterIncompleteToolCallSequences(messages) {
|
|
33
|
+
const result = [];
|
|
34
|
+
let i = 0;
|
|
35
|
+
while (i < messages.length) {
|
|
36
|
+
const msg = messages[i];
|
|
37
|
+
if (msg.role === "assistant" && msg.toolCalls && msg.toolCalls.length > 0) {
|
|
38
|
+
const toolCallIds = new Set(msg.toolCalls.map((tc) => tc.id));
|
|
39
|
+
const toolResponses = [];
|
|
40
|
+
let j = i + 1;
|
|
41
|
+
while (j < messages.length && messages[j].role === "tool") {
|
|
42
|
+
if (toolCallIds.has(messages[j].toolCallId)) {
|
|
43
|
+
toolResponses.push(messages[j]);
|
|
44
|
+
toolCallIds.delete(messages[j].toolCallId);
|
|
45
|
+
}
|
|
46
|
+
j++;
|
|
47
|
+
}
|
|
48
|
+
if (toolCallIds.size === 0) {
|
|
49
|
+
result.push(msg);
|
|
50
|
+
toolResponses.forEach((tr) => result.push(tr));
|
|
51
|
+
i = j;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
log("Skipping incomplete tool call sequence", {
|
|
55
|
+
assistantMsgIndex: i,
|
|
56
|
+
missingToolCallIds: Array.from(toolCallIds),
|
|
57
|
+
});
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
result.push(msg);
|
|
63
|
+
i++;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
17
68
|
async executeToolCall(systemPrompt, userPrompt, toolSchema, sessionId) {
|
|
18
69
|
let session = this.aiSessionManager.getSession(sessionId, "openai-chat");
|
|
19
70
|
if (!session) {
|
|
@@ -24,7 +75,8 @@ export class OpenAIChatCompletionProvider extends BaseAIProvider {
|
|
|
24
75
|
}
|
|
25
76
|
const existingMessages = this.aiSessionManager.getMessages(session.id);
|
|
26
77
|
const messages = [];
|
|
27
|
-
|
|
78
|
+
const validatedMessages = this.filterIncompleteToolCallSequences(existingMessages);
|
|
79
|
+
for (const msg of validatedMessages) {
|
|
28
80
|
const apiMsg = {
|
|
29
81
|
role: msg.role,
|
|
30
82
|
content: msg.content,
|
|
@@ -65,7 +117,7 @@ export class OpenAIChatCompletionProvider extends BaseAIProvider {
|
|
|
65
117
|
model: this.config.model,
|
|
66
118
|
messages,
|
|
67
119
|
tools: [toolSchema],
|
|
68
|
-
tool_choice: { type: "function", name: toolSchema.function.name },
|
|
120
|
+
tool_choice: { type: "function", function: { name: toolSchema.function.name } },
|
|
69
121
|
temperature: 0.3,
|
|
70
122
|
};
|
|
71
123
|
const response = await fetch(`${this.config.apiUrl}/chat/completions`, {
|
|
@@ -113,38 +165,46 @@ export class OpenAIChatCompletionProvider extends BaseAIProvider {
|
|
|
113
165
|
this.aiSessionManager.addMessage(assistantMsg);
|
|
114
166
|
messages.push(choice.message);
|
|
115
167
|
if (choice.message.tool_calls && choice.message.tool_calls.length > 0) {
|
|
116
|
-
const toolCall
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
168
|
+
for (const toolCall of choice.message.tool_calls) {
|
|
169
|
+
const toolCallId = toolCall.id;
|
|
170
|
+
if (toolCall.function.name === toolSchema.function.name) {
|
|
171
|
+
try {
|
|
172
|
+
const parsed = JSON.parse(toolCall.function.arguments);
|
|
173
|
+
const result = UserProfileValidator.validate(parsed);
|
|
174
|
+
if (!result.valid) {
|
|
175
|
+
throw new Error(result.errors.join(", "));
|
|
176
|
+
}
|
|
177
|
+
this.addToolResponse(session.id, messages, toolCallId, JSON.stringify({ success: true }));
|
|
178
|
+
return {
|
|
179
|
+
success: true,
|
|
180
|
+
data: result.data,
|
|
181
|
+
iterations,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
catch (validationError) {
|
|
185
|
+
const errorStack = validationError instanceof Error ? validationError.stack : undefined;
|
|
186
|
+
log("OpenAI tool response validation failed", {
|
|
187
|
+
error: String(validationError),
|
|
188
|
+
stack: errorStack,
|
|
189
|
+
errorType: validationError instanceof Error
|
|
190
|
+
? validationError.constructor.name
|
|
191
|
+
: typeof validationError,
|
|
192
|
+
toolName: toolSchema.function.name,
|
|
193
|
+
iteration: iterations,
|
|
194
|
+
rawArguments: toolCall.function.arguments.slice(0, 500),
|
|
195
|
+
});
|
|
196
|
+
const errorMessage = `Validation failed: ${String(validationError)}`;
|
|
197
|
+
this.addToolResponse(session.id, messages, toolCallId, JSON.stringify({ success: false, error: errorMessage }));
|
|
198
|
+
return {
|
|
199
|
+
success: false,
|
|
200
|
+
error: errorMessage,
|
|
201
|
+
iterations,
|
|
202
|
+
};
|
|
123
203
|
}
|
|
124
|
-
return {
|
|
125
|
-
success: true,
|
|
126
|
-
data: result.data,
|
|
127
|
-
iterations,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
catch (validationError) {
|
|
131
|
-
const errorStack = validationError instanceof Error ? validationError.stack : undefined;
|
|
132
|
-
log("OpenAI tool response validation failed", {
|
|
133
|
-
error: String(validationError),
|
|
134
|
-
stack: errorStack,
|
|
135
|
-
errorType: validationError instanceof Error
|
|
136
|
-
? validationError.constructor.name
|
|
137
|
-
: typeof validationError,
|
|
138
|
-
toolName: toolSchema.function.name,
|
|
139
|
-
iteration: iterations,
|
|
140
|
-
rawArguments: toolCall.function.arguments.slice(0, 500),
|
|
141
|
-
});
|
|
142
|
-
return {
|
|
143
|
-
success: false,
|
|
144
|
-
error: `Validation failed: ${String(validationError)}`,
|
|
145
|
-
iterations,
|
|
146
|
-
};
|
|
147
204
|
}
|
|
205
|
+
const wrongToolMessage = `Wrong tool called. Please use ${toolSchema.function.name} instead.`;
|
|
206
|
+
this.addToolResponse(session.id, messages, toolCallId, JSON.stringify({ success: false, error: wrongToolMessage }));
|
|
207
|
+
break;
|
|
148
208
|
}
|
|
149
209
|
}
|
|
150
210
|
const retrySequence = this.aiSessionManager.getLastSequence(session.id) + 1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAOtC,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,gBAAgB,CAAS;IAEjC,OAAO,CAAC,eAAe;
|
|
1
|
+
{"version":3,"file":"connection-manager.d.ts","sourceRoot":"","sources":["../../../src/services/sqlite/connection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAOtC,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,gBAAgB,CAAS;IAEjC,OAAO,CAAC,eAAe;IA+EzB,OAAO,CAAC,YAAY;IAqBlB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;IAmBvC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IASrC,QAAQ,IAAI,IAAI;CAWjB;AAED,eAAO,MAAM,iBAAiB,mBAA0B,CAAC"}
|
|
@@ -24,7 +24,13 @@ export class ConnectionManager {
|
|
|
24
24
|
log("Using custom SQLite library", { path: customPath });
|
|
25
25
|
}
|
|
26
26
|
catch (error) {
|
|
27
|
-
|
|
27
|
+
const errorStr = String(error);
|
|
28
|
+
if (errorStr.includes("SQLite already loaded")) {
|
|
29
|
+
log("SQLite already loaded, skipping custom path configuration");
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
throw new Error(`Failed to load custom SQLite library: ${error}\n` + `Path: ${customPath}`);
|
|
33
|
+
}
|
|
28
34
|
}
|
|
29
35
|
}
|
|
30
36
|
else {
|
|
@@ -45,7 +51,13 @@ export class ConnectionManager {
|
|
|
45
51
|
log("Auto-detected and using Homebrew SQLite", { path: foundPath });
|
|
46
52
|
}
|
|
47
53
|
catch (error) {
|
|
48
|
-
|
|
54
|
+
const errorStr = String(error);
|
|
55
|
+
if (errorStr.includes("SQLite already loaded")) {
|
|
56
|
+
log("SQLite already loaded, skipping auto-detected path configuration");
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
throw new Error(`Failed to load Homebrew SQLite: ${error}\n` + `Path: ${foundPath}`);
|
|
60
|
+
}
|
|
49
61
|
}
|
|
50
62
|
}
|
|
51
63
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../../src/services/web-server.ts"],"names":[],"mappings":"AAOA,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAeD,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,YAAY,CAA8B;gBAEtC,MAAM,EAAE,eAAe;IAI7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,MAAM;
|
|
1
|
+
{"version":3,"file":"web-server.d.ts","sourceRoot":"","sources":["../../src/services/web-server.ts"],"names":[],"mappings":"AAOA,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAeD,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAAkB;IACjC,OAAO,CAAC,YAAY,CAA8B;gBAEtC,MAAM,EAAE,eAAe;IAI7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASd,MAAM;IA0Ed,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiC3B,SAAS,IAAI,OAAO;IAIpB,aAAa,IAAI,OAAO;IAIxB,MAAM,IAAI,MAAM;IAIV,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC;CAW/C;AAED,wBAAsB,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CAIhF"}
|
|
@@ -51,8 +51,21 @@ export class WebServer {
|
|
|
51
51
|
};
|
|
52
52
|
this.worker.onerror = (error) => {
|
|
53
53
|
clearTimeout(timeout);
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
const errorDetails = {
|
|
55
|
+
message: error.message || "Unknown error",
|
|
56
|
+
filename: error.filename || "unknown",
|
|
57
|
+
lineno: error.lineno || 0,
|
|
58
|
+
colno: error.colno || 0,
|
|
59
|
+
error: error.error ? String(error.error) : "no error object",
|
|
60
|
+
type: error.type || "error",
|
|
61
|
+
};
|
|
62
|
+
log("Web server worker error (detailed)", errorDetails);
|
|
63
|
+
const errorMsg = error.message
|
|
64
|
+
? `${error.message} (at ${error.filename}:${error.lineno}:${error.colno})`
|
|
65
|
+
: error.error
|
|
66
|
+
? String(error.error)
|
|
67
|
+
: `Worker failed: ${JSON.stringify(errorDetails)}`;
|
|
68
|
+
reject(new Error(errorMsg));
|
|
56
69
|
};
|
|
57
70
|
});
|
|
58
71
|
this.worker.postMessage({
|