summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-05-26 22:08:50 -0400
committerDax Raad <[email protected]>2025-05-26 22:08:50 -0400
commit2e938d9da1589e1e00b9739c5e6c8dc72dda872a (patch)
tree40b58ba37c7566311a67cf1fb6daa103eef9545a
parentb840a4075956f00d0c46c82b19da24d984dddd07 (diff)
downloadopencode-2e938d9da1589e1e00b9739c5e6c8dc72dda872a.tar.gz
opencode-2e938d9da1589e1e00b9739c5e6c8dc72dda872a.zip
Standardize API parameters to camelCase and improve LSP client reliability
- Convert tool parameters from snake_case to camelCase for consistency - Add file existence check in LSP client before opening files - Fix version increment timing in LSP textDocument operations - Optimize session token tracking using onStepFinish callback - Add debugging logs for diagnostics troubleshooting 🤖 Generated with opencode Co-Authored-By: opencode <[email protected]>
-rw-r--r--js/src/lsp/client.ts15
-rw-r--r--js/src/session/session.ts12
-rw-r--r--js/src/tool/diagnostics.ts4
-rw-r--r--js/src/tool/edit.ts28
-rw-r--r--js/src/tool/grep.ts6
-rw-r--r--js/src/tool/patch.ts14
-rw-r--r--js/src/tool/view.ts4
7 files changed, 42 insertions, 41 deletions
diff --git a/js/src/lsp/client.ts b/js/src/lsp/client.ts
index 73a216b06..0ad7be6e7 100644
--- a/js/src/lsp/client.ts
+++ b/js/src/lsp/client.ts
@@ -51,6 +51,7 @@ export namespace LSPClient {
log.info("textDocument/publishDiagnostics", {
path,
});
+ console.log(path, params);
diagnostics.set(path, params.diagnostics);
Bus.publish(Event.Diagnostics, { path, serverID: input.serverID });
});
@@ -129,7 +130,9 @@ export namespace LSPClient {
},
notify: {
async open(input: { path: string }) {
- const text = await Bun.file(input.path).text();
+ const file = Bun.file(input.path);
+ if (!file.exists()) return;
+ const text = await file.text();
const opened = files.has(input.path);
if (!opened) {
log.info("textDocument/didOpen", input);
@@ -140,8 +143,8 @@ export namespace LSPClient {
textDocument: {
uri: `file://` + input.path,
languageId,
- version: 1,
- text: text,
+ version: ++version,
+ text,
},
});
files.add(input.path);
@@ -150,11 +153,10 @@ export namespace LSPClient {
log.info("textDocument/didChange", input);
diagnostics.delete(input.path);
- version++;
await connection.sendNotification("textDocument/didChange", {
textDocument: {
uri: `file://` + input.path,
- version,
+ version: ++version,
},
contentChanges: [
{
@@ -168,7 +170,7 @@ export namespace LSPClient {
return diagnostics;
},
async waitForDiagnostics(input: { path: string }) {
- log.info("refreshing diagnostics", input);
+ log.info("waiting for diagnostics", input);
let unsub: () => void;
let timeout: NodeJS.Timeout;
return await Promise.race([
@@ -184,7 +186,6 @@ export namespace LSPClient {
resolve();
}
});
- await result.notify.open(input);
}),
new Promise<void>((resolve) => {
timeout = setTimeout(() => {
diff --git a/js/src/session/session.ts b/js/src/session/session.ts
index 1ab09d40d..8b3f990de 100644
--- a/js/src/session/session.ts
+++ b/js/src/session/session.ts
@@ -162,6 +162,13 @@ export namespace Session {
msgs.push(system);
state().messages.set(sessionID, msgs);
generateText({
+ onStepFinish: (step) => {
+ update(sessionID, (draft) => {
+ draft.tokens.input += step.usage.inputTokens || 0;
+ draft.tokens.output += step.usage.outputTokens || 0;
+ draft.tokens.reasoning += step.usage.reasoningTokens || 0;
+ });
+ },
messages: convertToModelMessages([
{
role: "system",
@@ -293,11 +300,6 @@ export namespace Session {
session.tokens.input += usage.inputTokens || 0;
session.tokens.output += usage.outputTokens || 0;
session.tokens.reasoning += usage.reasoningTokens || 0;
- await update(sessionID, (draft) => {
- draft.tokens.input += usage.inputTokens || 0;
- draft.tokens.output += usage.outputTokens || 0;
- draft.tokens.reasoning += usage.reasoningTokens || 0;
- });
return next;
}
}
diff --git a/js/src/tool/diagnostics.ts b/js/src/tool/diagnostics.ts
index 3d5565621..efd4b880f 100644
--- a/js/src/tool/diagnostics.ts
+++ b/js/src/tool/diagnostics.ts
@@ -40,6 +40,7 @@ TIPS:
: path.join(app.root, args.path);
await LSP.file(normalized);
const diagnostics = await LSP.diagnostics();
+ console.log(diagnostics, "diagnostics");
const file = diagnostics[normalized];
return {
metadata: {
@@ -51,6 +52,3 @@ TIPS:
};
},
});
-
-const x: number = "asd";
-
diff --git a/js/src/tool/edit.ts b/js/src/tool/edit.ts
index 270c80e45..f041a4748 100644
--- a/js/src/tool/edit.ts
+++ b/js/src/tool/edit.ts
@@ -59,23 +59,23 @@ export const edit = Tool.define({
name: "edit",
description: DESCRIPTION,
parameters: z.object({
- file_path: z.string().describe("The absolute path to the file to modify"),
- old_string: z.string().describe("The text to replace"),
- new_string: z.string().describe("The text to replace it with"),
+ filePath: z.string().describe("The absolute path to the file to modify"),
+ oldString: z.string().describe("The text to replace"),
+ newString: z.string().describe("The text to replace it with"),
}),
async execute(params) {
- if (!params.file_path) {
- throw new Error("file_path is required");
+ if (!params.filePath) {
+ throw new Error("filePath is required");
}
- let filePath = params.file_path;
+ let filePath = params.filePath;
if (!path.isAbsolute(filePath)) {
filePath = path.join(process.cwd(), filePath);
}
await (async () => {
- if (params.old_string === "") {
- await Bun.write(filePath, params.new_string);
+ if (params.oldString === "") {
+ await Bun.write(filePath, params.newString);
return;
}
@@ -95,21 +95,21 @@ export const edit = Tool.define({
);
const content = await file.text();
- const index = content.indexOf(params.old_string);
+ const index = content.indexOf(params.oldString);
if (index === -1)
throw new Error(
- `old_string not found in file. Make sure it matches exactly, including whitespace and line breaks`,
+ `oldString not found in file. Make sure it matches exactly, including whitespace and line breaks`,
);
- const lastIndex = content.lastIndexOf(params.old_string);
+ const lastIndex = content.lastIndexOf(params.oldString);
if (index !== lastIndex)
throw new Error(
- `old_string appears multiple times in the file. Please provide more context to ensure a unique match`,
+ `oldString appears multiple times in the file. Please provide more context to ensure a unique match`,
);
const newContent =
content.substring(0, index) +
- params.new_string +
- content.substring(index + params.old_string.length);
+ params.newString +
+ content.substring(index + params.oldString.length);
await file.write(newContent);
})();
diff --git a/js/src/tool/grep.ts b/js/src/tool/grep.ts
index 9c3754ce9..b67a4790e 100644
--- a/js/src/tool/grep.ts
+++ b/js/src/tool/grep.ts
@@ -274,7 +274,7 @@ export const grep = Tool.define({
'File pattern to include in the search (e.g. "*.js", "*.{ts,tsx}")',
)
.optional(),
- literal_text: z
+ literalText: z
.boolean()
.describe(
"If true, the pattern will be treated as literal text with special regex characters escaped. Default is false.",
@@ -289,8 +289,8 @@ export const grep = Tool.define({
const app = await App.use();
const searchPath = params.path || app.root;
- // If literal_text is true, escape the pattern
- const searchPattern = params.literal_text
+ // If literalText is true, escape the pattern
+ const searchPattern = params.literalText
? escapeRegexPattern(params.pattern)
: params.pattern;
diff --git a/js/src/tool/patch.ts b/js/src/tool/patch.ts
index d1969e8a1..209a2d927 100644
--- a/js/src/tool/patch.ts
+++ b/js/src/tool/patch.ts
@@ -34,7 +34,7 @@ CRITICAL REQUIREMENTS FOR USING THIS TOOL:
The tool will apply all changes in a single atomic operation.`;
const PatchParams = z.object({
- patch_text: z
+ patchText: z
.string()
.describe("The full patch text that describes all changes to be made"),
});
@@ -269,13 +269,13 @@ export const patch = Tool.define({
name: "patch",
description: DESCRIPTION,
parameters: PatchParams,
- execute: async ({ patch_text }) => {
- if (!patch_text) {
- throw new Error("patch_text is required");
+ execute: async (params) => {
+ if (!params.patchText) {
+ throw new Error("patchText is required");
}
// Identify all files needed for the patch and verify they've been read
- const filesToRead = identifyFilesNeeded(patch_text);
+ const filesToRead = identifyFilesNeeded(params.patchText);
for (const filePath of filesToRead) {
let absPath = filePath;
if (!path.isAbsolute(absPath)) {
@@ -309,7 +309,7 @@ export const patch = Tool.define({
}
// Check for new files to ensure they don't already exist
- const filesToAdd = identifyFilesAdded(patch_text);
+ const filesToAdd = identifyFilesAdded(params.patchText);
for (const filePath of filesToAdd) {
let absPath = filePath;
if (!path.isAbsolute(absPath)) {
@@ -343,7 +343,7 @@ export const patch = Tool.define({
}
// Process the patch
- const [patch, fuzz] = textToPatch(patch_text, currentFiles);
+ const [patch, fuzz] = textToPatch(params.patchText, currentFiles);
if (fuzz > 3) {
throw new Error(
`patch contains fuzzy matches (fuzz level: ${fuzz}). Please make your context lines more precise`,
diff --git a/js/src/tool/view.ts b/js/src/tool/view.ts
index 987e4e276..c3d9fa72b 100644
--- a/js/src/tool/view.ts
+++ b/js/src/tool/view.ts
@@ -44,7 +44,7 @@ export const view = Tool.define({
name: "view",
description: DESCRIPTION,
parameters: z.object({
- file_path: z.string().describe("The path to the file to read"),
+ filePath: z.string().describe("The path to the file to read"),
offset: z
.number()
.describe("The line number to start reading from (0-based)")
@@ -55,7 +55,7 @@ export const view = Tool.define({
.optional(),
}),
async execute(params) {
- let filePath = params.file_path;
+ let filePath = params.filePath;
if (!path.isAbsolute(filePath)) {
filePath = path.join(process.cwd(), filePath);
}