refactor(schema): decode effect schemas directly (#24169)

This commit is contained in:
Kit Langton
2026-04-24 17:11:52 -04:00
committed by GitHub
parent 435becbea0
commit cf45a8d807
4 changed files with 24 additions and 19 deletions

View File

@@ -46,7 +46,7 @@ import { MessageV2 } from "@/session/message-v2"
import { Config } from "@/config"
import { ConfigMCP } from "@/config/mcp"
import { Todo } from "@/session/todo"
import { z } from "zod"
import { Result, Schema } from "effect"
import { LoadAPIKeyError } from "ai"
import type { AssistantMessage, Event, OpencodeClient, SessionMessageResponse, ToolPart } from "@opencode-ai/sdk/v2"
import { applyPatch } from "diff"
@@ -54,6 +54,7 @@ import { InstallationVersion } from "@/installation/version"
type ModeOption = { id: string; name: string; description?: string }
type ModelOption = { modelId: string; name: string }
const decodeTodos = Schema.decodeUnknownResult(Schema.fromJsonString(Schema.Array(Todo.Info)))
const DEFAULT_VARIANT_VALUE = "default"
@@ -372,14 +373,14 @@ export class Agent implements ACPAgent {
}
if (part.tool === "todowrite") {
const parsedTodos = z.array(Todo.Info.zod).safeParse(JSON.parse(part.state.output))
if (parsedTodos.success) {
const parsedTodos = decodeTodos(part.state.output)
if (Result.isSuccess(parsedTodos)) {
await this.connection
.sessionUpdate({
sessionId,
update: {
sessionUpdate: "plan",
entries: parsedTodos.data.map((todo) => {
entries: parsedTodos.success.map((todo) => {
const status: PlanEntry["status"] =
todo.status === "cancelled" ? "completed" : (todo.status as PlanEntry["status"])
return {
@@ -394,7 +395,7 @@ export class Agent implements ACPAgent {
log.error("failed to send session update for todo", { error })
})
} else {
log.error("failed to parse todo output", { error: parsedTodos.error })
log.error("failed to parse todo output", { error: parsedTodos.failure })
}
}
@@ -901,14 +902,14 @@ export class Agent implements ACPAgent {
}
if (part.tool === "todowrite") {
const parsedTodos = z.array(Todo.Info.zod).safeParse(JSON.parse(part.state.output))
if (parsedTodos.success) {
const parsedTodos = decodeTodos(part.state.output)
if (Result.isSuccess(parsedTodos)) {
await this.connection
.sessionUpdate({
sessionId,
update: {
sessionUpdate: "plan",
entries: parsedTodos.data.map((todo) => {
entries: parsedTodos.success.map((todo) => {
const status: PlanEntry["status"] =
todo.status === "cancelled" ? "completed" : (todo.status as PlanEntry["status"])
return {
@@ -923,7 +924,7 @@ export class Agent implements ACPAgent {
log.error("failed to send session update for todo", { error: err })
})
} else {
log.error("failed to parse todo output", { error: parsedTodos.error })
log.error("failed to parse todo output", { error: parsedTodos.failure })
}
}