import { Effect, Schema } from "effect" /** * JSON Schema subset for model-visible signatures. CodeMode does not validate values against * these schemas. */ export type JsonSchema = { readonly type?: string | ReadonlyArray readonly enum?: ReadonlyArray readonly const?: unknown readonly anyOf?: ReadonlyArray readonly oneOf?: ReadonlyArray readonly allOf?: ReadonlyArray readonly properties?: Readonly> readonly required?: ReadonlyArray readonly items?: JsonSchema readonly additionalProperties?: boolean | JsonSchema readonly description?: string readonly default?: unknown readonly format?: string readonly deprecated?: boolean readonly minItems?: number readonly maxItems?: number readonly $ref?: string readonly $defs?: Readonly> readonly definitions?: Readonly> } /** Either a validating Effect Schema or a render-only JSON Schema document. */ export type SchemaType = Schema.Decoder | JsonSchema /** Schema-backed tool definition exposed through CodeMode's `tools` object. */ export type Definition = { readonly _tag: "CodeModeTool" readonly description: string readonly input: SchemaType readonly output: SchemaType | undefined readonly run: (input: unknown) => Effect.Effect } type InputType = S extends Schema.Decoder ? S["Type"] : unknown type ResultType = S extends Schema.Decoder ? S["Encoded"] : unknown /** Options for defining one CodeMode tool. */ export type Options = { readonly description: string readonly input: I readonly output?: O readonly run: (input: InputType) => Effect.Effect, unknown, R> } // Object.hasOwn: an inherited _tag must not classify a namespace as a Definition. export const isDefinition = (value: unknown): value is Definition => typeof value === "object" && value !== null && "_tag" in value && Object.hasOwn(value, "_tag") && value._tag === "CodeModeTool" /** * Defines one schema-described tool available to a CodeMode program through `tools.*`. * * Effect Schemas validate values; JSON Schemas only shape the model-visible signature. * Without `output`, results are exposed as `unknown`. Hosts remain responsible for authorization * and durable side effects. */ export const make = ( options: Options, ): Definition => ({ _tag: "CodeModeTool", description: options.description, input: options.input, output: options.output, run: (input) => options.run(input as InputType), })