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.
@@ -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;AAmBlE,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;IAIpB,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,kBAAkB,EAC9B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC;CAmM3B"}
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
- for (const msg of existingMessages) {
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 = choice.message.tool_calls[0];
117
- if (toolCall && toolCall.function.name === toolSchema.function.name) {
118
- try {
119
- const parsed = JSON.parse(toolCall.function.arguments);
120
- const result = UserProfileValidator.validate(parsed);
121
- if (!result.valid) {
122
- throw new Error(result.errors.join(", "));
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;IAqEzB,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"}
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
- throw new Error(`Failed to load custom SQLite library: ${error}\n` + `Path: ${customPath}`);
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
- throw new Error(`Failed to load Homebrew SQLite: ${error}\n` + `Path: ${foundPath}`);
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;IA4Dd,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"}
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
- log("Web server worker error", { error: String(error) });
55
- reject(error);
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({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-mem",
3
- "version": "2.3.5",
3
+ "version": "2.3.6",
4
4
  "description": "OpenCode plugin that gives coding agents persistent memory using local vector database",
5
5
  "type": "module",
6
6
  "main": "dist/plugin.js",