From ca874cf13454a68c57cb5d20999334ba10164c08 Mon Sep 17 00:00:00 2001 From: roboomp Date: Fri, 17 Jul 2026 07:43:40 +0000 Subject: [PATCH 1/2] fix(lsp): raised timeout ceiling to 300 seconds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allowed explicit LSP request budgets above 60 seconds and exposed the 5–300 second range in the tool schema. Fixes #5804 --- packages/coding-agent/CHANGELOG.md | 4 ++ packages/coding-agent/src/lsp/types.ts | 6 ++- .../coding-agent/src/tools/tool-timeouts.ts | 2 +- .../test/tools/lsp-regressions.test.ts | 40 ++++++++++++------- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 493bd5332..0d775f191 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed LSP requests silently clamping explicit timeouts above 60 seconds by supporting documented budgets up to 300 seconds ([#5804](https://github.com/can1357/oh-my-pi/issues/5804)). + ## [17.0.2] - 2026-07-17 ### Added diff --git a/packages/coding-agent/src/lsp/types.ts b/packages/coding-agent/src/lsp/types.ts index 13f2c6b80..c612658c1 100644 --- a/packages/coding-agent/src/lsp/types.ts +++ b/packages/coding-agent/src/lsp/types.ts @@ -1,5 +1,6 @@ import type { ptree } from "@oh-my-pi/pi-utils"; import { type } from "arktype"; +import { TOOL_TIMEOUTS } from "../tools/tool-timeouts"; // ============================================================================= // Tool Schema @@ -14,7 +15,10 @@ export const lspSchema = type({ query: "string?", new_name: "string?", apply: "boolean?", - timeout: "number?", + "timeout?": type.number + .atLeast(TOOL_TIMEOUTS.lsp.min) + .atMost(TOOL_TIMEOUTS.lsp.max) + .describe("Timeout in seconds (default 20; range 5–300)."), payload: "string?", }); diff --git a/packages/coding-agent/src/tools/tool-timeouts.ts b/packages/coding-agent/src/tools/tool-timeouts.ts index 8d5342b93..102c640ec 100644 --- a/packages/coding-agent/src/tools/tool-timeouts.ts +++ b/packages/coding-agent/src/tools/tool-timeouts.ts @@ -13,7 +13,7 @@ export const TOOL_TIMEOUTS = { browser: { default: 30, min: 1, max: 300 }, ssh: { default: 60, min: 1, max: 3600 }, fetch: { default: 20, min: 1, max: 45 }, - lsp: { default: 20, min: 5, max: 60 }, + lsp: { default: 20, min: 5, max: 300 }, debug: { default: 30, min: 5, max: 300 }, } as const satisfies Record; diff --git a/packages/coding-agent/test/tools/lsp-regressions.test.ts b/packages/coding-agent/test/tools/lsp-regressions.test.ts index 467fee72f..8ef6fcad3 100644 --- a/packages/coding-agent/test/tools/lsp-regressions.test.ts +++ b/packages/coding-agent/test/tools/lsp-regressions.test.ts @@ -3,6 +3,7 @@ import * as fs from "node:fs"; import * as os from "node:os"; import * as path from "node:path"; import type { AgentToolResult, RenderResultOptions } from "@oh-my-pi/pi-agent-core"; +import { arkToWireSchema } from "@oh-my-pi/pi-ai/utils/schema"; import { preloadPluginRoots } from "@oh-my-pi/pi-coding-agent/discovery/helpers"; import { LspTool } from "@oh-my-pi/pi-coding-agent/lsp"; import * as lspClient from "@oh-my-pi/pi-coding-agent/lsp/client"; @@ -14,18 +15,19 @@ import { sortAndValidateTextEdits, } from "@oh-my-pi/pi-coding-agent/lsp/edits"; import { renderCall, renderResult } from "@oh-my-pi/pi-coding-agent/lsp/render"; -import type { - CodeAction, - CreateFile, - DeleteFile, - Diagnostic, - LspClient, - LspToolDetails, - RenameFile, - ServerConfig, - SymbolInformation, - TextDocumentEdit, - WorkspaceEdit, +import { + type CodeAction, + type CreateFile, + type DeleteFile, + type Diagnostic, + type LspClient, + type LspToolDetails, + lspSchema, + type RenameFile, + type ServerConfig, + type SymbolInformation, + type TextDocumentEdit, + type WorkspaceEdit, } from "@oh-my-pi/pi-coding-agent/lsp/types"; import { applyCodeAction, @@ -253,10 +255,20 @@ describe("lsp regressions", () => { expect(hasGlobPattern("src/main.ts")).toBe(false); }); - it("clamps LSP timeout to configured bounds", () => { + it("supports long LSP timeouts up to the advertised ceiling", () => { expect(clampTimeout("lsp")).toBe(20); expect(clampTimeout("lsp", 1)).toBe(5); - expect(clampTimeout("lsp", 1000)).toBe(60); + expect(clampTimeout("lsp", 120)).toBe(120); + expect(clampTimeout("lsp", 1000)).toBe(300); + expect(arkToWireSchema(lspSchema)).toMatchObject({ + properties: { + timeout: { + description: "Timeout in seconds (default 20; range 5–300).", + maximum: 300, + minimum: 5, + }, + }, + }); }); it("sends the LSP exit notification after shutdown completes", async () => { From bdd7647bd92881d5a5e43505c3ceb6fe9bde42ed Mon Sep 17 00:00:00 2001 From: roboomp Date: Fri, 17 Jul 2026 07:46:59 +0000 Subject: [PATCH 2/2] docs(lsp): documented 300 second timeout ceiling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aligned the LSP tool input table and limits section with the raised 5–300 second clamp. Fixes #5804 --- docs/tools/lsp.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/tools/lsp.md b/docs/tools/lsp.md index ca4be1f86..f86f9e058 100644 --- a/docs/tools/lsp.md +++ b/docs/tools/lsp.md @@ -31,7 +31,7 @@ | `query` | string | No | Workspace symbol query, code-action selector/filter, or LSP method name for `action=request`. | | `new_name` | string | No | Required for `rename` and `rename_file`. | | `apply` | boolean | No | For `rename`/`rename_file`, apply unless explicitly `false`. For `code_actions`, list unless explicitly `true`. | -| `timeout` | number | No | Seconds, clamped by `clampTimeout("lsp", ...)` to `5..60`, default `20`. | +| `timeout` | number | No | Seconds, clamped by `clampTimeout("lsp", ...)` to `5..300`, default `20`. | | `payload` | string | No | JSON string for `action=request`; overrides auto-built params. | ## Outputs @@ -268,7 +268,7 @@ Same as `definition`, but sends `textDocument/implementation` and reports `imple - Background message readers persist for each live client until process exit/shutdown. ## Limits & Caps -- Tool timeout clamp: default `20`, min `5`, max `60` seconds — `TOOL_TIMEOUTS.lsp` in `packages/coding-agent/src/tools/tool-timeouts.ts`. +- Tool timeout clamp: default `20`, min `5`, max `300` seconds — `TOOL_TIMEOUTS.lsp` in `packages/coding-agent/src/tools/tool-timeouts.ts`. - LSP request default timeout inside `sendRequest()`: `30_000ms` — `DEFAULT_REQUEST_TIMEOUT_MS` in `packages/coding-agent/src/lsp/client.ts`. - Warmup initialize timeout default: `5_000ms` — `WARMUP_TIMEOUT_MS` in `packages/coding-agent/src/lsp/client.ts`. - Project-load wait fallback: `15_000ms` — `PROJECT_LOAD_TIMEOUT_MS` in `packages/coding-agent/src/lsp/client.ts`.