File size: 2,214 Bytes
3e05655 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | export * as TodoWriteTool from "./todowrite"
import { ToolFailure } from "@opencode-ai/llm"
import { Effect, Layer, Schema } from "effect"
import { makeLocationNode } from "../effect/app-node"
import { PermissionV2 } from "../permission"
import { SessionTodo } from "../session/todo"
import { ToolRegistry } from "./registry"
import { Tool } from "./tool"
import { Tools } from "./tools"
export const name = "todowrite"
export const Input = Schema.Struct({
todos: Schema.Array(SessionTodo.Info).annotate({ description: "The updated todo list" }),
})
export const Output = Schema.Struct({
todos: Schema.Array(SessionTodo.Info),
})
export type Output = typeof Output.Type
export const toModelOutput = (output: Output) => JSON.stringify(output.todos, null, 2)
const layer = Layer.effectDiscard(
Effect.gen(function* () {
const tools = yield* Tools.Service
const todos = yield* SessionTodo.Service
const permission = yield* PermissionV2.Service
yield* tools
.register({
[name]: Tool.make({
description:
"Create and maintain a structured task list for the current coding session. Use it to track progress during multi-step work and keep todo statuses current.",
input: Input,
output: Output,
toModelOutput: ({ output }) => [{ type: "text", text: toModelOutput(output) }],
execute: (input, context) =>
Effect.gen(function* () {
yield* permission.assert({
action: name,
resources: ["*"],
save: ["*"],
sessionID: context.sessionID,
agent: context.agent,
source: { type: "tool", messageID: context.assistantMessageID, callID: context.toolCallID },
})
yield* todos.update({ sessionID: context.sessionID, todos: input.todos })
return { todos: input.todos }
}).pipe(Effect.mapError(() => new ToolFailure({ message: "Unable to update todos" }))),
}),
})
.pipe(Effect.orDie)
}),
)
export const node = makeLocationNode({
name: "tool/todowrite",
layer,
deps: [ToolRegistry.node, PermissionV2.node, SessionTodo.node],
})
|