model.ts 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import { z } from "zod"
  2. import { eq, and } from "drizzle-orm"
  3. import { Database } from "./drizzle"
  4. import { ModelTable } from "./schema/model.sql"
  5. import { Identifier } from "./identifier"
  6. import { fn } from "./util/fn"
  7. import { Actor } from "./actor"
  8. import { Resource } from "@opencode-ai/console-resource"
  9. export namespace ZenModel {
  10. const ModelCostSchema = z.object({
  11. input: z.number(),
  12. output: z.number(),
  13. cacheRead: z.number().optional(),
  14. cacheWrite5m: z.number().optional(),
  15. cacheWrite1h: z.number().optional(),
  16. })
  17. export const ModelSchema = z.object({
  18. name: z.string(),
  19. cost: ModelCostSchema,
  20. cost200K: ModelCostSchema.optional(),
  21. allowAnonymous: z.boolean().optional(),
  22. providers: z.array(
  23. z.object({
  24. id: z.string(),
  25. api: z.string(),
  26. apiKey: z.string(),
  27. model: z.string(),
  28. weight: z.number().optional(),
  29. headerMappings: z.record(z.string(), z.string()).optional(),
  30. disabled: z.boolean().optional(),
  31. }),
  32. ),
  33. })
  34. export const ModelsSchema = z.record(z.string(), ModelSchema)
  35. export const list = fn(z.void(), () => ModelsSchema.parse(JSON.parse(Resource.ZEN_MODELS.value)))
  36. }
  37. export namespace Model {
  38. export const enable = fn(z.object({ model: z.string() }), ({ model }) => {
  39. Actor.assertAdmin()
  40. return Database.use((db) =>
  41. db.delete(ModelTable).where(and(eq(ModelTable.workspaceID, Actor.workspace()), eq(ModelTable.model, model))),
  42. )
  43. })
  44. export const disable = fn(z.object({ model: z.string() }), ({ model }) => {
  45. Actor.assertAdmin()
  46. return Database.use((db) =>
  47. db
  48. .insert(ModelTable)
  49. .values({
  50. id: Identifier.create("model"),
  51. workspaceID: Actor.workspace(),
  52. model: model,
  53. })
  54. .onDuplicateKeyUpdate({
  55. set: {
  56. timeDeleted: null,
  57. },
  58. }),
  59. )
  60. })
  61. export const listDisabled = fn(z.void(), () => {
  62. return Database.use((db) =>
  63. db
  64. .select({ model: ModelTable.model })
  65. .from(ModelTable)
  66. .where(eq(ModelTable.workspaceID, Actor.workspace()))
  67. .then((rows) => rows.map((row) => row.model)),
  68. )
  69. })
  70. export const isDisabled = fn(
  71. z.object({
  72. model: z.string(),
  73. }),
  74. ({ model }) => {
  75. return Database.use(async (db) => {
  76. const result = await db
  77. .select()
  78. .from(ModelTable)
  79. .where(and(eq(ModelTable.workspaceID, Actor.workspace()), eq(ModelTable.model, model)))
  80. .limit(1)
  81. return result.length > 0
  82. })
  83. },
  84. )
  85. }