mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-22 10:14:22 +01:00
wip: zen
This commit is contained in:
@@ -24,7 +24,6 @@ const updateModel = action(async (form: FormData) => {
|
|||||||
const workspaceID = form.get("workspaceID")?.toString()
|
const workspaceID = form.get("workspaceID")?.toString()
|
||||||
if (!workspaceID) return { error: "Workspace ID is required" }
|
if (!workspaceID) return { error: "Workspace ID is required" }
|
||||||
const enabled = form.get("enabled")?.toString() === "true"
|
const enabled = form.get("enabled")?.toString() === "true"
|
||||||
console.log({ model, workspaceID, enabled })
|
|
||||||
return json(
|
return json(
|
||||||
withActor(async () => {
|
withActor(async () => {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { Actor } from "@opencode-ai/console-core/actor.js"
|
|||||||
import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
|
import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js"
|
||||||
import { ZenModel } from "@opencode-ai/console-core/model.js"
|
import { ZenModel } from "@opencode-ai/console-core/model.js"
|
||||||
import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
|
import { UserTable } from "@opencode-ai/console-core/schema/user.sql.js"
|
||||||
|
import { ModelTable } from "@opencode-ai/console-core/schema/model.sql.js"
|
||||||
|
|
||||||
export async function handler(
|
export async function handler(
|
||||||
input: APIEvent,
|
input: APIEvent,
|
||||||
@@ -67,6 +68,7 @@ export async function handler(
|
|||||||
const providerInfo = selectProvider(modelInfo)
|
const providerInfo = selectProvider(modelInfo)
|
||||||
const authInfo = await authenticate(modelInfo)
|
const authInfo = await authenticate(modelInfo)
|
||||||
validateBilling(modelInfo, authInfo)
|
validateBilling(modelInfo, authInfo)
|
||||||
|
validateModelSettings(authInfo)
|
||||||
logger.metric({ provider: providerInfo.id })
|
logger.metric({ provider: providerInfo.id })
|
||||||
|
|
||||||
// Request to model provider
|
// Request to model provider
|
||||||
@@ -222,14 +224,14 @@ export async function handler(
|
|||||||
return { id: modelId, ...modelData }
|
return { id: modelId, ...modelData }
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectProvider(model: Model) {
|
function selectProvider(model: Awaited<ReturnType<typeof validateModel>>) {
|
||||||
const providers = model.providers
|
const providers = model.providers
|
||||||
.filter((provider) => !provider.disabled)
|
.filter((provider) => !provider.disabled)
|
||||||
.flatMap((provider) => Array<typeof provider>(provider.weight ?? 1).fill(provider))
|
.flatMap((provider) => Array<typeof provider>(provider.weight ?? 1).fill(provider))
|
||||||
return providers[Math.floor(Math.random() * providers.length)]
|
return providers[Math.floor(Math.random() * providers.length)]
|
||||||
}
|
}
|
||||||
|
|
||||||
async function authenticate(model: Model) {
|
async function authenticate(model: Awaited<ReturnType<typeof validateModel>>) {
|
||||||
const apiKey = opts.parseApiKey(input.request.headers)
|
const apiKey = opts.parseApiKey(input.request.headers)
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
if (model.allowAnonymous) return
|
if (model.allowAnonymous) return
|
||||||
@@ -241,20 +243,26 @@ export async function handler(
|
|||||||
.select({
|
.select({
|
||||||
apiKey: KeyTable.id,
|
apiKey: KeyTable.id,
|
||||||
workspaceID: KeyTable.workspaceID,
|
workspaceID: KeyTable.workspaceID,
|
||||||
balance: BillingTable.balance,
|
billing: {
|
||||||
paymentMethodID: BillingTable.paymentMethodID,
|
balance: BillingTable.balance,
|
||||||
monthlyLimit: BillingTable.monthlyLimit,
|
paymentMethodID: BillingTable.paymentMethodID,
|
||||||
monthlyUsage: BillingTable.monthlyUsage,
|
monthlyLimit: BillingTable.monthlyLimit,
|
||||||
timeMonthlyUsageUpdated: BillingTable.timeMonthlyUsageUpdated,
|
monthlyUsage: BillingTable.monthlyUsage,
|
||||||
userID: UserTable.id,
|
timeMonthlyUsageUpdated: BillingTable.timeMonthlyUsageUpdated,
|
||||||
userMonthlyLimit: UserTable.monthlyLimit,
|
},
|
||||||
userMonthlyUsage: UserTable.monthlyUsage,
|
user: {
|
||||||
timeUserMonthlyUsageUpdated: UserTable.timeMonthlyUsageUpdated,
|
id: UserTable.id,
|
||||||
|
monthlyLimit: UserTable.monthlyLimit,
|
||||||
|
monthlyUsage: UserTable.monthlyUsage,
|
||||||
|
timeMonthlyUsageUpdated: UserTable.timeMonthlyUsageUpdated,
|
||||||
|
},
|
||||||
|
timeDisabled: ModelTable.timeCreated,
|
||||||
})
|
})
|
||||||
.from(KeyTable)
|
.from(KeyTable)
|
||||||
.innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID))
|
.innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID))
|
||||||
.innerJoin(BillingTable, eq(BillingTable.workspaceID, KeyTable.workspaceID))
|
.innerJoin(BillingTable, eq(BillingTable.workspaceID, KeyTable.workspaceID))
|
||||||
.innerJoin(UserTable, and(eq(UserTable.workspaceID, KeyTable.workspaceID), eq(UserTable.id, KeyTable.userID)))
|
.innerJoin(UserTable, and(eq(UserTable.workspaceID, KeyTable.workspaceID), eq(UserTable.id, KeyTable.userID)))
|
||||||
|
.leftJoin(ModelTable, and(eq(ModelTable.workspaceID, KeyTable.workspaceID), eq(ModelTable.model, model.id)))
|
||||||
.where(and(eq(KeyTable.key, apiKey), isNull(KeyTable.timeDeleted)))
|
.where(and(eq(KeyTable.key, apiKey), isNull(KeyTable.timeDeleted)))
|
||||||
.then((rows) => rows[0]),
|
.then((rows) => rows[0]),
|
||||||
)
|
)
|
||||||
@@ -265,25 +273,13 @@ export async function handler(
|
|||||||
workspace: data.workspaceID,
|
workspace: data.workspaceID,
|
||||||
})
|
})
|
||||||
|
|
||||||
const isFree = FREE_WORKSPACES.includes(data.workspaceID)
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
apiKeyId: data.apiKey,
|
apiKeyId: data.apiKey,
|
||||||
workspaceID: data.workspaceID,
|
workspaceID: data.workspaceID,
|
||||||
billing: {
|
billing: data.billing,
|
||||||
paymentMethodID: data.paymentMethodID,
|
user: data.user,
|
||||||
balance: data.balance,
|
isFree: FREE_WORKSPACES.includes(data.workspaceID),
|
||||||
monthlyLimit: data.monthlyLimit,
|
isDisabled: !!data.timeDisabled,
|
||||||
monthlyUsage: data.monthlyUsage,
|
|
||||||
timeMonthlyUsageUpdated: data.timeMonthlyUsageUpdated,
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
id: data.userID,
|
|
||||||
monthlyLimit: data.userMonthlyLimit,
|
|
||||||
monthlyUsage: data.userMonthlyUsage,
|
|
||||||
timeMonthlyUsageUpdated: data.timeUserMonthlyUsageUpdated,
|
|
||||||
},
|
|
||||||
isFree,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,6 +321,11 @@ export async function handler(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validateModelSettings(authInfo: Awaited<ReturnType<typeof authenticate>>) {
|
||||||
|
if (!authInfo) return
|
||||||
|
if (authInfo.isDisabled) throw new ModelError("Model is disabled")
|
||||||
|
}
|
||||||
|
|
||||||
async function trackUsage(
|
async function trackUsage(
|
||||||
authInfo: Awaited<ReturnType<typeof authenticate>>,
|
authInfo: Awaited<ReturnType<typeof authenticate>>,
|
||||||
modelInfo: ReturnType<typeof validateModel>,
|
modelInfo: ReturnType<typeof validateModel>,
|
||||||
|
|||||||
Reference in New Issue
Block a user