feat(core): bound v2 tool output (#30999)
This commit is contained in:
@@ -3,9 +3,7 @@ export * as ReadTool from "./read"
|
||||
import { Tool, ToolFailure } from "@opencode-ai/llm"
|
||||
import { Cause, Effect, Layer, Schema } from "effect"
|
||||
import { FileSystem } from "../filesystem"
|
||||
import { NonNegativeInt, PositiveInt } from "../schema"
|
||||
import { PermissionV2 } from "../permission"
|
||||
import { ToolOutputStore } from "../tool-output-store"
|
||||
import { ToolRegistry } from "./registry"
|
||||
|
||||
export const name = "read"
|
||||
@@ -18,17 +16,12 @@ const LocationInput = Schema.Struct({
|
||||
description: "The maximum number of directory entries or text lines to read",
|
||||
}),
|
||||
})
|
||||
const ResourceInput = Schema.Struct({
|
||||
resource: Schema.String,
|
||||
offset: NonNegativeInt.pipe(Schema.optional),
|
||||
limit: PositiveInt.check(Schema.isLessThanOrEqualTo(ToolOutputStore.MAX_READ_BYTES)).pipe(Schema.optional),
|
||||
})
|
||||
const Input = Schema.Union([LocationInput, ResourceInput])
|
||||
const Success = Schema.Union([FileSystem.Content, FileSystem.TextPage, FileSystem.ListPage, ToolOutputStore.Page])
|
||||
const Input = LocationInput
|
||||
const Success = Schema.Union([FileSystem.Content, FileSystem.TextPage, FileSystem.ListPage])
|
||||
|
||||
const definition = Tool.make({
|
||||
description:
|
||||
"Read a text or binary file, page through a large UTF-8 text file by line offset, list a directory page relative to the current location, or page through a managed tool-output resource by opaque URI.",
|
||||
"Read a text or binary file, page through a large UTF-8 text file by line offset, or list a directory page relative to the current location. Absolute paths are accepted only for managed tool-output files.",
|
||||
parameters: Input,
|
||||
success: Success,
|
||||
})
|
||||
@@ -37,7 +30,6 @@ export const layer = Layer.effectDiscard(
|
||||
Effect.gen(function* () {
|
||||
const registry = yield* ToolRegistry.Service
|
||||
const filesystem = yield* FileSystem.Service
|
||||
const resources = yield* ToolOutputStore.Service
|
||||
|
||||
yield* registry.contribute((editor) =>
|
||||
editor.set(name, {
|
||||
@@ -45,8 +37,6 @@ export const layer = Layer.effectDiscard(
|
||||
execute: ({ parameters, sessionID, assertPermission }) => {
|
||||
const input = parameters
|
||||
return Effect.gen(function* () {
|
||||
if ("resource" in input)
|
||||
return yield* resources.read({ sessionID, uri: input.resource, offset: input.offset, limit: input.limit })
|
||||
const resolved = yield* filesystem.resolveReadPath(input)
|
||||
if (resolved.type === "directory") {
|
||||
const { offset, limit } = input
|
||||
@@ -81,7 +71,7 @@ export const layer = Layer.effectDiscard(
|
||||
Effect.catchCause((cause) =>
|
||||
Effect.fail(
|
||||
new ToolFailure({
|
||||
message: `Unable to read ${"resource" in input ? input.resource : input.path}`,
|
||||
message: `Unable to read ${input.path}`,
|
||||
error: Cause.squash(cause),
|
||||
}),
|
||||
),
|
||||
@@ -96,5 +86,4 @@ export const locationLayer = layer.pipe(
|
||||
Layer.provideMerge(ToolRegistry.defaultLayer),
|
||||
Layer.provideMerge(FileSystem.locationLayer),
|
||||
Layer.provideMerge(PermissionV2.locationLayer),
|
||||
Layer.provideMerge(ToolOutputStore.defaultLayer),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user