import { mergeDeep } from "remeda" import { App } from "../app/app" import { Config } from "../config/config" import z from "zod" export namespace Mode { export const Info = z .object({ name: z.string(), model: z .object({ modelID: z.string(), providerID: z.string(), }) .optional(), prompt: z.string().optional(), tools: z .object({ write: z.boolean().optional(), edit: z.boolean().optional(), patch: z.boolean().optional(), }) .optional(), }) .openapi({ ref: "Mode", }) export type Info = z.infer const state = App.state("mode", async () => { const cfg = await Config.get() const mode = mergeDeep( { build: {}, plan: { tools: { write: false, edit: false, patch: false, }, }, }, cfg.mode ?? {}, ) const result: Record = {} for (const [key, value] of Object.entries(mode)) { let item = result[key] if (!item) item = result[key] = { name: key, tools: {}, } const model = value.model ?? cfg.model if (model) { const [providerID, ...rest] = model.split("/") const modelID = rest.join("/") item.model = { modelID, providerID, } } if (value.prompt) item.prompt = await Bun.file(value.prompt).text() if (value.tools) item.tools = value.tools } return result }) export async function get(mode: string) { return state().then((x) => x[mode]) } export async function list() { return state().then((x) => Object.values(x)) } }