refactor(core): consolidate tool architecture
This commit is contained in:
parent
0fd73a2976
commit
8db7487c89
466 changed files with 9405 additions and 11071 deletions
|
|
@ -71,7 +71,7 @@ export async function streamTurn(input: {
|
|||
const next = await stream.next()
|
||||
if (next.done) throw new Error("event stream disconnected during prompt execution")
|
||||
const event = next.value
|
||||
if (event.type === "permission.v2.asked" && event.data.sessionID === input.sessionID) {
|
||||
if (event.type === "permission.asked" && event.data.sessionID === input.sessionID) {
|
||||
const tool = event.data.source?.callID ? tools.get(event.data.source.callID) : undefined
|
||||
await replyPermission({
|
||||
client: input.client,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { Result } from "effect"
|
|||
import { isAbsolute, resolve } from "node:path"
|
||||
import { pendingToolCall, stringValue, toLocations, toToolKind, type ToolInput } from "./tool"
|
||||
|
||||
type PermissionEvent = Extract<EventSubscribeOutput, { type: "permission.v2.asked" }>
|
||||
type PermissionEvent = Extract<EventSubscribeOutput, { type: "permission.asked" }>
|
||||
type Connection = Pick<AgentSideConnection, "requestPermission"> & Partial<Pick<AgentSideConnection, "writeTextFile">>
|
||||
type Tool = { readonly name: string; readonly input: ToolInput }
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import {
|
|||
Provider,
|
||||
Reference,
|
||||
Skill,
|
||||
} from "@opencode-ai/plugin/v2/effect"
|
||||
import { Tool } from "@opencode-ai/plugin/v2/effect/tool"
|
||||
} from "@opencode-ai/plugin/effect"
|
||||
import { Tool } from "@opencode-ai/schema/tool"
|
||||
|
||||
const key = Symbol.for("opencode.plugin.v2.effect")
|
||||
;(globalThis as typeof globalThis & { [key]?: unknown })[key] = {
|
||||
|
|
@ -24,5 +24,5 @@ const key = Symbol.for("opencode.plugin.v2.effect")
|
|||
Provider,
|
||||
Reference,
|
||||
Skill,
|
||||
Tool,
|
||||
Tool: { Error: Tool.Error },
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ import {
|
|||
Provider,
|
||||
Reference,
|
||||
Skill,
|
||||
} from "@opencode-ai/plugin/v2"
|
||||
import { Tool } from "@opencode-ai/plugin/v2/tool"
|
||||
} from "@opencode-ai/plugin"
|
||||
|
||||
const key = Symbol.for("opencode.plugin.v2.promise")
|
||||
;(globalThis as typeof globalThis & { [key]?: unknown })[key] = {
|
||||
|
|
@ -24,5 +23,4 @@ const key = Symbol.for("opencode.plugin.v2.promise")
|
|||
Provider,
|
||||
Reference,
|
||||
Skill,
|
||||
Tool,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ export async function runNonInteractivePrompt(input: Input) {
|
|||
}
|
||||
const event = next.value
|
||||
|
||||
if (event.type === "permission.v2.asked" && submitted && event.data.sessionID === input.sessionID) {
|
||||
if (event.type === "permission.asked" && submitted && event.data.sessionID === input.sessionID) {
|
||||
await replyPermission(event.data)
|
||||
continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,11 +13,13 @@ type Options = {
|
|||
readonly command?: ReadonlyArray<string>
|
||||
}
|
||||
|
||||
const startupDirectory = process.cwd()
|
||||
|
||||
function command(password: string, options: Options) {
|
||||
const [executable, ...args] = options.command ?? [...selfCommand(), "serve"]
|
||||
if (!executable) throw new Error("Failed to resolve standalone server command")
|
||||
return ChildProcess.make(executable, [...args, "--stdio", "--port", "0"], {
|
||||
cwd: process.cwd(),
|
||||
cwd: startupDirectory,
|
||||
// Explicit entry wins over anything inherited, so a user-exported
|
||||
// OPENCODE_PASSWORD cannot shadow the child's lease credential.
|
||||
env: { OPENCODE_PASSWORD: password },
|
||||
|
|
|
|||
|
|
@ -1,11 +1,13 @@
|
|||
import path from "node:path"
|
||||
|
||||
const entrypoint = process.argv[1] ? path.resolve(process.argv[1]) : undefined
|
||||
|
||||
export function selfCommand() {
|
||||
const runtime = path.basename(process.execPath, path.extname(process.execPath)).toLowerCase()
|
||||
if (runtime !== "bun" && runtime !== "node" && runtime !== "nodejs") return [process.execPath]
|
||||
if (!process.argv[1]) throw new Error("Failed to resolve CLI entrypoint")
|
||||
if (runtime === "node" || runtime === "nodejs") return [process.execPath, ...nodeFlags(), process.argv[1]]
|
||||
return [process.execPath, process.argv[1]]
|
||||
if (!entrypoint) throw new Error("Failed to resolve CLI entrypoint")
|
||||
if (runtime === "node" || runtime === "nodejs") return [process.execPath, ...nodeFlags(), entrypoint]
|
||||
return [process.execPath, entrypoint]
|
||||
}
|
||||
|
||||
function nodeFlags() {
|
||||
|
|
|
|||
|
|
@ -502,7 +502,7 @@ function permissionAsked(
|
|||
readonly source?: { readonly type: "tool"; readonly messageID: string; readonly callID: string }
|
||||
} = {},
|
||||
) {
|
||||
return ephemeralEvent("permission.v2.asked", {
|
||||
return ephemeralEvent("permission.asked", {
|
||||
id,
|
||||
sessionID,
|
||||
action: input.action ?? "shell",
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ import { Service } from "@opencode-ai/client/effect/service"
|
|||
import path from "node:path"
|
||||
import { Standalone } from "../../src/services/standalone"
|
||||
|
||||
process.argv[1] = path.join(import.meta.dir, "../../src/index.ts")
|
||||
process.chdir(path.join(import.meta.dir, "../../../.."))
|
||||
|
||||
await Effect.runPromise(
|
||||
Effect.scoped(
|
||||
Effect.gen(function* () {
|
||||
const endpoint = yield* Standalone.start()
|
||||
const endpoint = yield* Standalone.start({
|
||||
command: [process.execPath, path.join(import.meta.dir, "../../src/index.ts"), "serve"],
|
||||
})
|
||||
const response = yield* Effect.promise(() =>
|
||||
fetch(new URL("/api/health", endpoint.url), { headers: Service.headers(endpoint) }),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -75,20 +75,11 @@ export const define = sdk.Plugin.define`
|
|||
const effectPluginModule = promisePluginModule
|
||||
.replace("opencode.plugin.v2.promise", "opencode.plugin.v2.effect")
|
||||
.replace("Promise plugin", "Effect plugin")
|
||||
const promiseToolModule = `const sdk = globalThis[Symbol.for("opencode.plugin.v2.promise")]
|
||||
if (!sdk) throw new Error("OpenCode Promise plugin SDK is unavailable")
|
||||
export const Tool = sdk.Tool
|
||||
export const make = sdk.Tool.make`
|
||||
const promiseToolModule = `export {}`
|
||||
const effectToolModule = `const sdk = globalThis[Symbol.for("opencode.plugin.v2.effect")]
|
||||
if (!sdk) throw new Error("OpenCode Effect plugin SDK is unavailable")
|
||||
export const Tool = sdk.Tool
|
||||
export const Failure = sdk.Tool.Failure
|
||||
export const RegistrationError = sdk.Tool.RegistrationError
|
||||
export const make = sdk.Tool.make
|
||||
export const validateName = sdk.Tool.validateName
|
||||
export const registrationEntries = sdk.Tool.registrationEntries
|
||||
export const validateNamespace = sdk.Tool.validateNamespace
|
||||
export const toLLMDefinition = sdk.Tool.toLLMDefinition`
|
||||
export const Error = sdk.Tool.Error
|
||||
`
|
||||
return `#!/usr/bin/env -S node ${nodeExecArgv.join(" ")}
|
||||
import __cjs_mod__ from "node:module"
|
||||
import { chmodSync as __ocChmod, existsSync as __ocExists, lstatSync as __ocLstat, mkdirSync as __ocMkdir, renameSync as __ocRename, rmSync as __ocRm, writeFileSync as __ocWrite } from "node:fs"
|
||||
|
|
@ -100,17 +91,17 @@ const __filename = import.meta.filename
|
|||
const __dirname = import.meta.dirname
|
||||
const require = __cjs_mod__.createRequire(import.meta.url)
|
||||
const __ocPluginModules = ${JSON.stringify({
|
||||
"@opencode-ai/plugin/v2": "opencode:plugin-v2",
|
||||
"@opencode-ai/plugin/v2/plugin": "opencode:plugin-v2-plugin",
|
||||
"@opencode-ai/plugin/v2/tool": "opencode:plugin-v2-tool",
|
||||
"@opencode-ai/plugin/v2/effect": "opencode:plugin-v2-effect",
|
||||
"@opencode-ai/plugin/v2/effect/plugin": "opencode:plugin-v2-effect-plugin",
|
||||
"@opencode-ai/plugin/v2/effect/tool": "opencode:plugin-v2-effect-tool",
|
||||
"@opencode-ai/plugin": "opencode:plugin-v2",
|
||||
"@opencode-ai/plugin/promise/plugin": "opencode:plugin-promise-plugin",
|
||||
"@opencode-ai/plugin/promise/tool": "opencode:plugin-promise-tool",
|
||||
"@opencode-ai/plugin/effect": "opencode:plugin-v2-effect",
|
||||
"@opencode-ai/plugin/effect/plugin": "opencode:plugin-v2-effect-plugin",
|
||||
"@opencode-ai/plugin/effect/tool": "opencode:plugin-v2-effect-tool",
|
||||
})}
|
||||
const __ocPluginSources = ${JSON.stringify({
|
||||
"opencode:plugin-v2": promiseModule,
|
||||
"opencode:plugin-v2-plugin": promisePluginModule,
|
||||
"opencode:plugin-v2-tool": promiseToolModule,
|
||||
"opencode:plugin-promise-plugin": promisePluginModule,
|
||||
"opencode:plugin-promise-tool": promiseToolModule,
|
||||
"opencode:plugin-v2-effect": effectModule,
|
||||
"opencode:plugin-v2-effect-plugin": effectPluginModule,
|
||||
"opencode:plugin-v2-effect-tool": effectToolModule,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue