mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-22 11:25:15 +00:00
tui: remove @effect/language-service and refactor tool output structure
Removed the @effect/language-service dependency from packages/opencode and packages/core to simplify the build and reduce unnecessary complexity. Refactored tool output handling to use a structured content array instead of flat fields. This enables richer tool responses with mixed content types (text, files) and better structured data support for future extensibility.
This commit is contained in:
parent
8bf098cf47
commit
b46b09450a
9 changed files with 67 additions and 52 deletions
3
bun.lock
3
bun.lock
|
|
@ -456,7 +456,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.28.4",
|
||||
"@effect/language-service": "0.84.2",
|
||||
"@octokit/webhooks-types": "7.6.1",
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
"@opencode-ai/script": "workspace:*",
|
||||
|
|
@ -1069,8 +1068,6 @@
|
|||
|
||||
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.11.0", "", {}, "sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg=="],
|
||||
|
||||
"@effect/language-service": ["@effect/language-service@0.84.2", "", { "bin": { "effect-language-service": "cli.js" } }, "sha512-l04qNxpiA8rY5yXWckRPJ7Mk5MNerXuNymSFf+IdflfI5i8jgL1bpBNLuP6ijg7wgjdHc/KmTnCj2kT0SCntuA=="],
|
||||
|
||||
"@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-beta.48", "", { "peerDependencies": { "@opentelemetry/api": "^1.9", "@opentelemetry/resources": "^2.0.0", "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", "@opentelemetry/sdk-metrics": "^2.0.0", "@opentelemetry/sdk-trace-base": "^2.0.0", "@opentelemetry/sdk-trace-node": "^2.0.0", "@opentelemetry/sdk-trace-web": "^2.0.0", "@opentelemetry/semantic-conventions": "^1.33.0", "effect": "^4.0.0-beta.48" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/resources", "@opentelemetry/sdk-logs", "@opentelemetry/sdk-metrics", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-node", "@opentelemetry/sdk-trace-web"] }, "sha512-vHk/X1vgDrviGcOTHQqzm2D81TtyPE/C7Qdksg5eAdbGpnqL4Dm4lk6PzTReQ0pO1/avIvWqpxy315IURV0Ldw=="],
|
||||
|
||||
"@effect/platform-node": ["@effect/platform-node@4.0.0-beta.48", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-beta.48", "mime": "^4.1.0", "undici": "^8.0.2" }, "peerDependencies": { "effect": "^4.0.0-beta.48", "ioredis": "^5.7.0" } }, "sha512-8J6H0k9rtbp9O1QvKOyOPRcCTJ8WrR7IzZLJtYFTZ4bXVEEMCTo84h0CRpi7ccpA9t7DLqotip0NeFgiBosNKQ=="],
|
||||
|
|
|
|||
|
|
@ -2,13 +2,6 @@
|
|||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"extends": "@tsconfig/bun/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noUncheckedIndexedAccess": false,
|
||||
"plugins": [
|
||||
{
|
||||
"name": "@effect/language-service",
|
||||
"transform": "@effect/language-service/transform",
|
||||
"namespaceImportPackages": ["effect", "@effect/*"]
|
||||
}
|
||||
]
|
||||
"noUncheckedIndexedAccess": false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"prepare": "effect-language-service patch || true",
|
||||
"typecheck": "tsgo --noEmit",
|
||||
"test": "bun test --timeout 30000",
|
||||
"test:ci": "mkdir -p .artifacts/unit && bun test --timeout 30000 --reporter=junit --reporter-outfile=.artifacts/unit/junit.xml",
|
||||
|
|
@ -42,7 +41,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.28.4",
|
||||
"@effect/language-service": "0.84.2",
|
||||
"@octokit/webhooks-types": "7.6.1",
|
||||
"@opencode-ai/script": "workspace:*",
|
||||
"@opencode-ai/core": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -380,22 +380,19 @@ export const layer: Layer.Layer<
|
|||
SyncEvent.run(SessionEvent.Tool.Success.Sync, {
|
||||
sessionID: ctx.sessionID,
|
||||
callID: value.toolCallId,
|
||||
output: value.output.output,
|
||||
attachments: value.output.attachments?.map((item: MessageV2.FilePart) => ({
|
||||
uri: item.url,
|
||||
mime: item.mime,
|
||||
...(item.filename ? { name: item.filename } : {}),
|
||||
...(item.source
|
||||
? {
|
||||
source: {
|
||||
start: item.source.text.start,
|
||||
end: item.source.text.end,
|
||||
text: item.source.text.value,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
})),
|
||||
details: value.output.metadata,
|
||||
structured: value.output.metadata,
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: value.output.output,
|
||||
},
|
||||
...value.output.attachments?.map((item: MessageV2.FilePart) => ({
|
||||
type: "file",
|
||||
uri: item.url,
|
||||
mime: item.mime,
|
||||
name: item.filename,
|
||||
})),
|
||||
],
|
||||
provider: {
|
||||
executed: toolCall?.part.metadata?.providerExecuted === true,
|
||||
},
|
||||
|
|
@ -410,7 +407,10 @@ export const layer: Layer.Layer<
|
|||
SyncEvent.run(SessionEvent.Tool.Error.Sync, {
|
||||
sessionID: ctx.sessionID,
|
||||
callID: value.toolCallId,
|
||||
error: errorMessage(value.error),
|
||||
error: {
|
||||
type: "unknown",
|
||||
message: errorMessage(value.error),
|
||||
},
|
||||
provider: {
|
||||
executed: toolCall?.part.metadata?.providerExecuted === true,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { Event } from "./event"
|
|||
import { FileAttachment, Prompt } from "./session-prompt"
|
||||
import { Schema } from "effect"
|
||||
export { FileAttachment }
|
||||
import { ToolOutput } from "./tool-output"
|
||||
|
||||
export const ID = Event.ID
|
||||
export type ID = Schema.Schema.Type<typeof ID>
|
||||
|
|
@ -201,7 +202,8 @@ export namespace Tool {
|
|||
schema: {
|
||||
...Base,
|
||||
callID: Schema.String,
|
||||
details: Schema.Record(Schema.String, Schema.Unknown),
|
||||
structured: ToolOutput.Structured,
|
||||
content: Schema.Array(ToolOutput.Content),
|
||||
},
|
||||
})
|
||||
export type Progress = Schema.Schema.Type<typeof Progress>
|
||||
|
|
@ -212,9 +214,8 @@ export namespace Tool {
|
|||
schema: {
|
||||
...Base,
|
||||
callID: Schema.String,
|
||||
output: Schema.String.pipe(Schema.optional),
|
||||
attachments: Schema.Array(FileAttachment).pipe(Schema.optional),
|
||||
details: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
structured: ToolOutput.Structured,
|
||||
content: Schema.Array(ToolOutput.Content),
|
||||
provider: Schema.Struct({
|
||||
executed: Schema.Boolean,
|
||||
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
|
|
@ -229,7 +230,10 @@ export namespace Tool {
|
|||
schema: {
|
||||
...Base,
|
||||
callID: Schema.String,
|
||||
error: Schema.String,
|
||||
error: Schema.Struct({
|
||||
type: Schema.String,
|
||||
message: Schema.String,
|
||||
}),
|
||||
provider: Schema.Struct({
|
||||
executed: Schema.Boolean,
|
||||
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
|
|
|
|||
|
|
@ -163,6 +163,8 @@ export function update<Result>(adapter: Adapter<Result>, event: SessionEvent.Eve
|
|||
match.state = {
|
||||
status: "running",
|
||||
input: event.data.input,
|
||||
structured: {},
|
||||
content: [],
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
|
@ -174,7 +176,10 @@ export function update<Result>(adapter: Adapter<Result>, event: SessionEvent.Eve
|
|||
adapter.updateAssistant(
|
||||
produce(currentAssistant, (draft) => {
|
||||
const match = latestTool(draft, event.data.callID)
|
||||
if (match && match.state.status === "running") match.state.details = event.data.details
|
||||
if (match && match.state.status === "running") {
|
||||
match.state.structured = event.data.structured
|
||||
match.state.content = [...event.data.content]
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
|
@ -188,9 +193,8 @@ export function update<Result>(adapter: Adapter<Result>, event: SessionEvent.Eve
|
|||
match.state = {
|
||||
status: "completed",
|
||||
input: match.state.input,
|
||||
output: event.data.output ?? "",
|
||||
details: event.data.details,
|
||||
attachments: [...(event.data.attachments ?? [])],
|
||||
structured: event.data.structured,
|
||||
content: [...event.data.content],
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
|
@ -207,6 +211,8 @@ export function update<Result>(adapter: Adapter<Result>, event: SessionEvent.Eve
|
|||
status: "error",
|
||||
error: event.data.error,
|
||||
input: match.state.input,
|
||||
structured: match.state.structured,
|
||||
content: match.state.content,
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { Schema } from "effect"
|
|||
import { Prompt } from "./session-prompt"
|
||||
import { SessionEvent } from "./session-event"
|
||||
import { Event } from "./event"
|
||||
import { ToolOutput } from "./tool-output"
|
||||
|
||||
export const ID = Event.ID
|
||||
export type ID = Schema.Schema.Type<typeof ID>
|
||||
|
|
@ -62,22 +63,27 @@ export class ToolStatePending extends Schema.Class<ToolStatePending>("Session.Me
|
|||
export class ToolStateRunning extends Schema.Class<ToolStateRunning>("Session.Message.ToolState.Running")({
|
||||
status: Schema.Literal("running"),
|
||||
input: Schema.Record(Schema.String, Schema.Unknown),
|
||||
details: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
structured: ToolOutput.Structured,
|
||||
content: ToolOutput.Content.pipe(Schema.Array),
|
||||
}) {}
|
||||
|
||||
export class ToolStateCompleted extends Schema.Class<ToolStateCompleted>("Session.Message.ToolState.Completed")({
|
||||
status: Schema.Literal("completed"),
|
||||
input: Schema.Record(Schema.String, Schema.Unknown),
|
||||
output: Schema.String,
|
||||
details: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
attachments: SessionEvent.FileAttachment.pipe(Schema.Array, Schema.optional),
|
||||
content: ToolOutput.Content.pipe(Schema.Array),
|
||||
structured: ToolOutput.Structured,
|
||||
}) {}
|
||||
|
||||
export class ToolStateError extends Schema.Class<ToolStateError>("Session.Message.ToolState.Error")({
|
||||
status: Schema.Literal("error"),
|
||||
input: Schema.Record(Schema.String, Schema.Unknown),
|
||||
error: Schema.String,
|
||||
details: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
|
||||
content: ToolOutput.Content.pipe(Schema.Array),
|
||||
structured: ToolOutput.Structured,
|
||||
error: Schema.Struct({
|
||||
type: Schema.String,
|
||||
message: Schema.String,
|
||||
}),
|
||||
}) {}
|
||||
|
||||
export const ToolState = Schema.Union([ToolStatePending, ToolStateRunning, ToolStateCompleted, ToolStateError]).pipe(
|
||||
|
|
|
|||
18
packages/opencode/src/v2/tool-output.ts
Normal file
18
packages/opencode/src/v2/tool-output.ts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
export * as ToolOutput from "./tool-output"
|
||||
import { Schema } from "effect"
|
||||
|
||||
export class TextContent extends Schema.Class<TextContent>("Tool.TextContent")({
|
||||
type: Schema.Literal("text"),
|
||||
text: Schema.String,
|
||||
}) {}
|
||||
|
||||
export class FileContent extends Schema.Class<FileContent>("Tool.FileContent")({
|
||||
type: Schema.Literal("file"),
|
||||
uri: Schema.String,
|
||||
mime: Schema.String,
|
||||
name: Schema.String.pipe(Schema.optional),
|
||||
}) {}
|
||||
|
||||
export const Content = Schema.Union([TextContent, FileContent]).pipe(Schema.toTaggedUnion("type"))
|
||||
|
||||
export const Structured = Schema.Record(Schema.String, Schema.Any)
|
||||
|
|
@ -12,13 +12,6 @@
|
|||
"@/*": ["./src/*"],
|
||||
"@tui/*": ["./src/cli/cmd/tui/*"],
|
||||
"@test/*": ["./test/*"]
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "@effect/language-service",
|
||||
"transform": "@effect/language-service/transform",
|
||||
"namespaceImportPackages": ["effect", "@effect/*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue