From 1c33b866ba962ed7a4c147c316ad807886a0045e Mon Sep 17 00:00:00 2001 From: Kit Langton Date: Thu, 16 Apr 2026 16:11:05 -0400 Subject: [PATCH] fix: remove 10 more unnecessary `as any` casts in opencode core (#22882) --- .../src/cli/cmd/tui/routes/session/index.tsx | 35 +++++++++++-------- packages/opencode/src/config/config.ts | 2 +- packages/opencode/src/lsp/server.ts | 8 +++-- .../src/server/instance/experimental.ts | 4 +-- packages/opencode/src/session/prompt.ts | 7 ++-- .../test/session/structured-output.test.ts | 10 ------ 6 files changed, 30 insertions(+), 36 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 5b4308d593..b0514bf1b1 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -44,6 +44,8 @@ import type { GrepTool } from "@/tool/grep" import type { EditTool } from "@/tool/edit" import type { ApplyPatchTool } from "@/tool/apply_patch" import type { WebFetchTool } from "@/tool/webfetch" +import type { CodeSearchTool } from "@/tool/codesearch" +import type { WebSearchTool } from "@/tool/websearch" import type { TaskTool } from "@/tool/task" import type { QuestionTool } from "@/tool/question" import type { SkillTool } from "@/tool/skill" @@ -1934,28 +1936,26 @@ function Grep(props: ToolProps) { function WebFetch(props: ToolProps) { return ( - - WebFetch {(props.input as any).url} + + WebFetch {props.input.url} ) } -function CodeSearch(props: ToolProps) { - const input = props.input as any - const metadata = props.metadata as any +function CodeSearch(props: ToolProps) { + const metadata = props.metadata as { results?: number } return ( - - Exa Code Search "{input.query}" ({metadata.results} results) + + Exa Code Search "{props.input.query}" ({metadata.results} results) ) } -function WebSearch(props: ToolProps) { - const input = props.input as any - const metadata = props.metadata as any +function WebSearch(props: ToolProps) { + const metadata = props.metadata as { numResults?: number } return ( - - Exa Web Search "{input.query}" ({metadata.numResults} results) + + Exa Web Search "{props.input.query}" ({metadata.numResults} results) ) } @@ -1979,7 +1979,9 @@ function Task(props: ToolProps) { ) }) - const current = createMemo(() => tools().findLast((x) => (x.state as any).title)) + const current = createMemo(() => + tools().findLast((x) => (x.state.status === "running" || x.state.status === "completed") && x.state.title), + ) const isRunning = createMemo(() => props.part.state.status === "running") @@ -1996,8 +1998,11 @@ function Task(props: ToolProps) { if (isRunning() && tools().length > 0) { // content[0] += ` · ${tools().length} toolcalls` - if (current()) content.push(`↳ ${Locale.titlecase(current()!.tool)} ${(current()!.state as any).title}`) - else content.push(`↳ ${tools().length} toolcalls`) + if (current()) { + const state = current()!.state + const title = state.status === "running" || state.status === "completed" ? state.title : undefined + content.push(`↳ ${Locale.titlecase(current()!.tool)} ${title}`) + } else content.push(`↳ ${tools().length} toolcalls`) } if (props.part.state.status === "completed") { diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index a738ebf130..3cbc539600 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -517,7 +517,7 @@ export const layer = Layer.effect( if (!response.ok) { throw new Error(`failed to fetch remote config from ${url}: ${response.status}`) } - const wellknown = (yield* Effect.promise(() => response.json())) as any + const wellknown = (yield* Effect.promise(() => response.json())) as { config?: Record } const remoteConfig = wellknown.config ?? {} if (!remoteConfig.$schema) remoteConfig.$schema = "https://opencode.ai/config.json" const source = `${url}/.well-known/opencode` diff --git a/packages/opencode/src/lsp/server.ts b/packages/opencode/src/lsp/server.ts index 390c5f2428..760e8eaba0 100644 --- a/packages/opencode/src/lsp/server.ts +++ b/packages/opencode/src/lsp/server.ts @@ -611,7 +611,9 @@ export const Zls: Info = { return } - const release = (await releaseResponse.json()) as any + const release = (await releaseResponse.json()) as { + assets?: { name?: string; browser_download_url?: string }[] + } const platform = process.platform const arch = process.arch @@ -646,8 +648,8 @@ export const Zls: Info = { return } - const asset = release.assets.find((a: any) => a.name === assetName) - if (!asset) { + const asset = release.assets?.find((a) => a.name === assetName) + if (!asset?.browser_download_url) { log.error(`Could not find asset ${assetName} in latest zls release`) return } diff --git a/packages/opencode/src/server/instance/experimental.ts b/packages/opencode/src/server/instance/experimental.ts index fe80173a8b..4f8887a43c 100644 --- a/packages/opencode/src/server/instance/experimental.ts +++ b/packages/opencode/src/server/instance/experimental.ts @@ -12,7 +12,6 @@ import { Config } from "../../config" import { ConsoleState } from "../../config/console-state" import { Account, AccountID, OrgID } from "../../account" import { AppRuntime } from "../../effect/app-runtime" -import { zodToJsonSchema } from "zod-to-json-schema" import { errors } from "../error" import { lazy } from "../../util/lazy" import { Effect, Option } from "effect" @@ -226,8 +225,7 @@ export const ExperimentalRoutes = lazy(() => tools.map((t) => ({ id: t.id, description: t.description, - // Handle both Zod schemas and plain JSON schemas - parameters: (t.parameters as any)?._def ? zodToJsonSchema(t.parameters as any) : t.parameters, + parameters: z.toJSONSchema(t.parameters), })), ) }, diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 4b8b95baa8..004ee19abe 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -10,6 +10,7 @@ import { Agent } from "../agent/agent" import { Provider } from "../provider" import { ModelID, ProviderID } from "../provider/schema" import { type Tool as AITool, tool, jsonSchema, type ToolExecutionOptions, asSchema } from "ai" +import type { JSONSchema7 } from "@ai-sdk/provider" import { SessionCompaction } from "./compaction" import { Bus } from "../bus" import { ProviderTransform } from "../provider" @@ -407,9 +408,8 @@ NOTE: At any point in time through this workflow you should feel free to ask the })) { const schema = ProviderTransform.schema(input.model, z.toJSONSchema(item.parameters)) tools[item.id] = tool({ - id: item.id as any, description: item.description, - inputSchema: jsonSchema(schema as any), + inputSchema: jsonSchema(schema), execute(args, options) { return run.promise( Effect.gen(function* () { @@ -1827,9 +1827,8 @@ NOTE: At any point in time through this workflow you should feel free to ask the const { $schema: _, ...toolSchema } = input.schema return tool({ - id: "StructuredOutput" as any, description: STRUCTURED_OUTPUT_DESCRIPTION, - inputSchema: jsonSchema(toolSchema as any), + inputSchema: jsonSchema(toolSchema as JSONSchema7), async execute(args) { // AI SDK validates args against inputSchema before calling execute() input.onSuccess(args) diff --git a/packages/opencode/test/session/structured-output.test.ts b/packages/opencode/test/session/structured-output.test.ts index db3f8cfded..2debfb76d5 100644 --- a/packages/opencode/test/session/structured-output.test.ts +++ b/packages/opencode/test/session/structured-output.test.ts @@ -157,16 +157,6 @@ describe("structured-output.AssistantMessage", () => { }) describe("structured-output.createStructuredOutputTool", () => { - test("creates tool with correct id", () => { - const tool = SessionPrompt.createStructuredOutputTool({ - schema: { type: "object", properties: { name: { type: "string" } } }, - onSuccess: () => {}, - }) - - // AI SDK tool type doesn't expose id, but we set it internally - expect((tool as any).id).toBe("StructuredOutput") - }) - test("creates tool with description", () => { const tool = SessionPrompt.createStructuredOutputTool({ schema: { type: "object" },