diff --git a/packages/opencode/src/acp/tool.ts b/packages/opencode/src/acp/tool.ts index 309c126d6e99..cfcc2b0652be 100644 --- a/packages/opencode/src/acp/tool.ts +++ b/packages/opencode/src/acp/tool.ts @@ -296,17 +296,6 @@ function isShell(toolName: string) { return tool === "bash" || tool === "shell" } -export const mapToolKind = toToolKind -export const extractLocations = toLocations -export const buildCompletedToolContent = completedToolContent -export const buildCompletedRawOutput = completedToolRawOutput -export const extractShellOutputSnapshot = shellOutputSnapshot -export const buildPendingToolCall = pendingToolCall -export const buildRunningToolUpdate = runningToolUpdate -export const buildDuplicateRunningToolUpdate = duplicateRunningToolUpdate -export const buildCompletedToolUpdate = completedToolUpdate -export const buildErrorToolUpdate = errorToolUpdate - function locationFrom(...values: unknown[]): ToolCallLocation[] { return Array.from( new Set( diff --git a/packages/opencode/src/acp/usage.ts b/packages/opencode/src/acp/usage.ts index bc17447e6141..12a0724ffdcf 100644 --- a/packages/opencode/src/acp/usage.ts +++ b/packages/opencode/src/acp/usage.ts @@ -25,15 +25,6 @@ export type MessagesInput = { readonly directory: string } -export type SDK = { - readonly session: { - readonly messages: ( - parameters: { readonly sessionID: string; readonly directory: string }, - options: { readonly throwOnError: true }, - ) => Promise<{ readonly data?: readonly SessionMessage[] | null }> - } -} - export interface MessageLoaderInterface { readonly messages: (input: MessagesInput) => Effect.Effect } @@ -70,19 +61,6 @@ export class ContextLimitLoader extends Context.Service()("@opencode/ACPUsage") {} -export function messageLoaderFromSDK(sdk: SDK): MessageLoaderInterface { - return MessageLoader.of({ - messages: (input) => - Effect.promise(() => - sdk.session - .messages({ sessionID: input.sessionID, directory: input.directory }, { throwOnError: true }) - .then((response) => response.data ?? []), - ), - }) -} - -export const messageLoaderLayer = (sdk: SDK) => Layer.succeed(MessageLoader, messageLoaderFromSDK(sdk)) - export function contextTokens(message: AssistantTokenCost): number { return message.tokens.input + message.tokens.cache.read + message.tokens.cache.write } diff --git a/packages/opencode/src/patch/index.ts b/packages/opencode/src/patch/index.ts index 66797d4f89ba..0ac854974433 100644 --- a/packages/opencode/src/patch/index.ts +++ b/packages/opencode/src/patch/index.ts @@ -1,5 +1,4 @@ import { Effect, Schema } from "effect" -import * as path from "path" import { FSUtil } from "@opencode-ai/core/fs-util" import * as Bom from "../util/bom" @@ -28,30 +27,12 @@ export interface UpdateFileChunk { is_end_of_file?: boolean } -export interface ApplyPatchAction { - changes: Map - patch: string - cwd: string -} - -export type ApplyPatchFileChange = - | { type: "add"; content: string } - | { type: "delete"; content: string } - | { type: "update"; unified_diff: string; move_path?: string; new_content: string } - export interface AffectedPaths { added: string[] modified: string[] deleted: string[] } -export enum ApplyPatchError { - ParseError = "ParseError", - IoError = "IoError", - ComputeReplacements = "ComputeReplacements", - ImplicitInvocation = "ImplicitInvocation", -} - export enum MaybeApplyPatch { Body = "Body", ShellParseError = "ShellParseError", @@ -59,13 +40,6 @@ export enum MaybeApplyPatch { NotApplyPatch = "NotApplyPatch", } -export enum MaybeApplyPatchVerified { - Body = "Body", - ShellParseError = "ShellParseError", - CorrectnessError = "CorrectnessError", - NotApplyPatch = "NotApplyPatch", -} - // Parser implementation function parsePatchHeader( lines: string[], @@ -566,121 +540,4 @@ export const applyPatch = Effect.fn("Patch.applyPatch")(function* (patchText: st return yield* applyHunksToFiles(hunks) }) -type MaybeApplyPatchVerifiedResult = - | { type: MaybeApplyPatchVerified.Body; action: ApplyPatchAction } - | { type: MaybeApplyPatchVerified.CorrectnessError; error: Error } - | { type: MaybeApplyPatchVerified.NotApplyPatch } - -// Effectful verified-parse: needs FSUtil.Service to read existing files -export const maybeParseApplyPatchVerified = Effect.fn("Patch.maybeParseApplyPatchVerified")(function* ( - argv: string[], - cwd: string, -) { - // Detect implicit patch invocation (raw patch without apply_patch command) - if (argv.length === 1) { - try { - parsePatch(argv[0]) - return { - type: MaybeApplyPatchVerified.CorrectnessError, - error: new Error(ApplyPatchError.ImplicitInvocation), - } satisfies MaybeApplyPatchVerifiedResult - } catch { - // Not a patch, continue - } - } - - const result = maybeParseApplyPatch(argv) - - switch (result.type) { - case MaybeApplyPatch.Body: { - const fs = yield* FSUtil.Service - const args = result.args - const effectiveCwd = args.workdir ? path.resolve(cwd, args.workdir) : cwd - const changes = new Map() - - for (const hunk of args.hunks) { - const resolvedPath = path.resolve( - effectiveCwd, - hunk.type === "update" && hunk.move_path ? hunk.move_path : hunk.path, - ) - - switch (hunk.type) { - case "add": - changes.set(resolvedPath, { - type: "add", - content: hunk.contents, - }) - break - - case "delete": { - const deletePath = path.resolve(effectiveCwd, hunk.path) - const content = yield* fs.readFileString(deletePath).pipe(Effect.catch(() => Effect.succeed(undefined))) - if (content === undefined) { - return { - type: MaybeApplyPatchVerified.CorrectnessError, - error: new Error(`Failed to read file for deletion: ${deletePath}`), - } satisfies MaybeApplyPatchVerifiedResult - } - changes.set(resolvedPath, { - type: "delete", - content, - }) - break - } - - case "update": { - const updatePath = path.resolve(effectiveCwd, hunk.path) - const originalText = yield* fs - .readFileString(updatePath) - .pipe( - Effect.catch((cause) => - Effect.succeed(new Error(`Failed to read file ${updatePath}: ${cause}`, { cause })), - ), - ) - if (originalText instanceof Error) { - return { - type: MaybeApplyPatchVerified.CorrectnessError, - error: originalText, - } satisfies MaybeApplyPatchVerifiedResult - } - try { - const fileUpdate = deriveNewContentsFromChunks(updatePath, hunk.chunks, originalText) - changes.set(resolvedPath, { - type: "update", - unified_diff: fileUpdate.unified_diff, - move_path: hunk.move_path ? path.resolve(effectiveCwd, hunk.move_path) : undefined, - new_content: fileUpdate.content, - }) - } catch (error) { - return { - type: MaybeApplyPatchVerified.CorrectnessError, - error: error as Error, - } satisfies MaybeApplyPatchVerifiedResult - } - break - } - } - } - - return { - type: MaybeApplyPatchVerified.Body, - action: { - changes, - patch: args.patch, - cwd: effectiveCwd, - }, - } satisfies MaybeApplyPatchVerifiedResult - } - - case MaybeApplyPatch.PatchParseError: - return { - type: MaybeApplyPatchVerified.CorrectnessError, - error: result.error, - } satisfies MaybeApplyPatchVerifiedResult - - case MaybeApplyPatch.NotApplyPatch: - return { type: MaybeApplyPatchVerified.NotApplyPatch } satisfies MaybeApplyPatchVerifiedResult - } -}) - export * as Patch from "." diff --git a/packages/opencode/src/tool/tool.ts b/packages/opencode/src/tool/tool.ts index e5e7802858ca..d1eeae64ad08 100644 --- a/packages/opencode/src/tool/tool.ts +++ b/packages/opencode/src/tool/tool.ts @@ -12,9 +12,6 @@ interface Metadata { [key: string]: any } -// TODO: remove this hack -export type DynamicDescription = (agent: Agent.Info) => Effect.Effect - /** * Raised when the LLM calls a tool with arguments that fail the parameter * schema. This is the canonical "rewrite the input" tool error: the typed