refactor(schema): tighten public contracts (#33771)

This commit is contained in:
Kit Langton 2026-06-25 19:10:23 +02:00 committed by GitHub
commit 9e9d405d7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
49 changed files with 759 additions and 897 deletions

View file

@ -14,7 +14,7 @@ export type Info = SessionTodo.Info
export const Event = SessionTodo.Event
export interface Interface {
readonly update: (input: { sessionID: SessionID; todos: Info[] }) => Effect.Effect<void>
readonly update: (input: { sessionID: SessionID; todos: ReadonlyArray<Info> }) => Effect.Effect<void>
readonly get: (sessionID: SessionID) => Effect.Effect<Info[]>
}
@ -26,7 +26,7 @@ export const layer = Layer.effect(
const events = yield* EventV2Bridge.Service
const { db } = yield* Database.Service
const update = Effect.fn("Todo.update")(function* (input: { sessionID: SessionID; todos: Info[] }) {
const update = Effect.fn("Todo.update")(function* (input: { sessionID: SessionID; todos: ReadonlyArray<Info> }) {
yield* db
.transaction((tx) =>
Effect.gen(function* () {

View file

@ -3,19 +3,8 @@ import * as Tool from "./tool"
import DESCRIPTION_WRITE from "./todowrite.txt"
import { Todo } from "../session/todo"
// Todo.Info is still a zod schema (session/todo.ts). Inline the field shape
// here rather than referencing its `.shape` — the LLM-visible JSON Schema is
// identical, and it removes the last zod dependency from this tool.
const TodoItem = Schema.Struct({
content: Schema.String.annotate({ description: "Brief description of the task" }),
status: Schema.String.annotate({
description: "Current status of the task: pending, in_progress, completed, cancelled",
}),
priority: Schema.String.annotate({ description: "Priority level of the task: high, medium, low" }),
})
export const Parameters = Schema.Struct({
todos: Schema.mutable(Schema.Array(TodoItem)).annotate({ description: "The updated todo list" }),
todos: Schema.mutable(Schema.Array(Todo.Info)).annotate({ description: "The updated todo list" }),
})
type Metadata = {

View file

@ -1195,7 +1195,7 @@ const scenarios: Scenario[] = [
.seeded((ctx) =>
Effect.gen(function* () {
const session = yield* ctx.session({ title: "Todo session" })
const todos = [{ content: "cover session todo", status: "pending", priority: "high" }]
const todos = [{ content: "cover session todo", status: "pending" as const, priority: "high" as const }]
yield* ctx.todos(session.id, todos)
return { session, todos }
}),

View file

@ -119,5 +119,9 @@ export type Result =
| { status: "skip"; scenario: TodoScenario }
export type SessionInfo = { id: SessionID; title: string; parentID?: SessionID }
export type TodoInfo = { content: string; status: string; priority: string }
export type TodoInfo = {
content: string
status: "pending" | "in_progress" | "completed" | "cancelled"
priority: "high" | "medium" | "low"
}
export type MessageSeed = { info: SessionV1.User; part: SessionV1.TextPart }

View file

@ -44,26 +44,18 @@ describe("reference HttpApi", () => {
{
name: "docs",
path: path.join(tmp.path, "docs"),
description: null,
hidden: null,
source: {
type: "local",
path: path.join(tmp.path, "docs"),
description: null,
hidden: null,
},
},
{
name: "effect",
path: path.join(Global.Path.repos, "github.com", "Effect-TS", "effect"),
description: null,
hidden: null,
source: {
type: "git",
repository: "Effect-TS/effect",
branch: "main",
description: null,
hidden: null,
},
},
])

View file

@ -256,7 +256,7 @@ describe("Todo.Info", () => {
const decode = decodeUnknown(Todo.Info)
test("three-field round-trip", () => {
const input = { content: "do a thing", status: "pending", priority: "high" }
const input = Todo.Info.make({ content: "do a thing", status: "pending", priority: "high" })
expect(decode(input)).toEqual(input)
})
})