mirror of
https://github.com/aljazceru/opencode.git
synced 2025-12-23 10:44:21 +01:00
zen: data share
This commit is contained in:
1
bun.lock
1
bun.lock
@@ -56,6 +56,7 @@
|
|||||||
"@solidjs/start": "^1.1.0",
|
"@solidjs/start": "^1.1.0",
|
||||||
"solid-js": "catalog:",
|
"solid-js": "catalog:",
|
||||||
"vinxi": "^0.5.7",
|
"vinxi": "^0.5.7",
|
||||||
|
"zod": "catalog:",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages/console/core": {
|
"packages/console/core": {
|
||||||
|
|||||||
@@ -99,11 +99,7 @@ export const stripeWebhook = new WebhookEndpoint("StripeWebhookEndpoint", {
|
|||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
const ANTHROPIC_API_KEY = new sst.Secret("ANTHROPIC_API_KEY")
|
const ZEN_MODELS = new sst.Secret("ZEN_MODELS")
|
||||||
const OPENAI_API_KEY = new sst.Secret("OPENAI_API_KEY")
|
|
||||||
const XAI_API_KEY = new sst.Secret("XAI_API_KEY")
|
|
||||||
const BASETEN_API_KEY = new sst.Secret("BASETEN_API_KEY")
|
|
||||||
const FIREWORKS_API_KEY = new sst.Secret("FIREWORKS_API_KEY")
|
|
||||||
const STRIPE_SECRET_KEY = new sst.Secret("STRIPE_SECRET_KEY")
|
const STRIPE_SECRET_KEY = new sst.Secret("STRIPE_SECRET_KEY")
|
||||||
const AUTH_API_URL = new sst.Linkable("AUTH_API_URL", {
|
const AUTH_API_URL = new sst.Linkable("AUTH_API_URL", {
|
||||||
properties: { value: auth.url.apply((url) => url!) },
|
properties: { value: auth.url.apply((url) => url!) },
|
||||||
@@ -128,17 +124,7 @@ if ($app.stage === "production" || $app.stage === "frank") {
|
|||||||
new sst.cloudflare.x.SolidStart("Console", {
|
new sst.cloudflare.x.SolidStart("Console", {
|
||||||
domain,
|
domain,
|
||||||
path: "packages/console/app",
|
path: "packages/console/app",
|
||||||
link: [
|
link: [database, AUTH_API_URL, STRIPE_WEBHOOK_SECRET, STRIPE_SECRET_KEY, ZEN_MODELS],
|
||||||
database,
|
|
||||||
AUTH_API_URL,
|
|
||||||
STRIPE_WEBHOOK_SECRET,
|
|
||||||
STRIPE_SECRET_KEY,
|
|
||||||
ANTHROPIC_API_KEY,
|
|
||||||
OPENAI_API_KEY,
|
|
||||||
XAI_API_KEY,
|
|
||||||
BASETEN_API_KEY,
|
|
||||||
FIREWORKS_API_KEY,
|
|
||||||
],
|
|
||||||
environment: {
|
environment: {
|
||||||
//VITE_DOCS_URL: web.url.apply((url) => url!),
|
//VITE_DOCS_URL: web.url.apply((url) => url!),
|
||||||
//VITE_API_URL: gateway.url.apply((url) => url!),
|
//VITE_API_URL: gateway.url.apply((url) => url!),
|
||||||
|
|||||||
@@ -12,12 +12,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ibm/plex": "6.4.1",
|
"@ibm/plex": "6.4.1",
|
||||||
"@openauthjs/openauth": "0.0.0-20250322224806",
|
"@openauthjs/openauth": "0.0.0-20250322224806",
|
||||||
|
"@opencode/console-core": "workspace:*",
|
||||||
"@solidjs/meta": "^0.29.4",
|
"@solidjs/meta": "^0.29.4",
|
||||||
"@solidjs/router": "^0.15.0",
|
"@solidjs/router": "^0.15.0",
|
||||||
"@solidjs/start": "^1.1.0",
|
"@solidjs/start": "^1.1.0",
|
||||||
"solid-js": "catalog:",
|
"solid-js": "catalog:",
|
||||||
"vinxi": "^0.5.7",
|
"vinxi": "^0.5.7",
|
||||||
"@opencode/console-core": "workspace:*"
|
"zod": "catalog:"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=22"
|
"node": ">=22"
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
.root {
|
||||||
|
[data-slot="section-content"] {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="reload-error"] {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: var(--space-4);
|
||||||
|
padding: var(--space-4);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--border-radius-sm);
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--color-danger);
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="create-form"] {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--space-2);
|
||||||
|
margin: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[data-slot="payment"] {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--space-3);
|
||||||
|
padding: var(--space-4);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
border-radius: var(--border-radius-sm);
|
||||||
|
min-width: 14.5rem;
|
||||||
|
width: fit-content;
|
||||||
|
|
||||||
|
@media (max-width: 30rem) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="credit-card"] {
|
||||||
|
padding: var(--space-3-5) var(--space-4);
|
||||||
|
background-color: var(--color-bg-surface);
|
||||||
|
border-radius: var(--border-radius-sm);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
[data-slot="card-icon"] {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="card-details"] {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
gap: var(--space-1);
|
||||||
|
|
||||||
|
[data-slot="secret"] {
|
||||||
|
position: relative;
|
||||||
|
bottom: 2px;
|
||||||
|
font-size: var(--font-size-lg);
|
||||||
|
color: var(--color-text-muted);
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="number"] {
|
||||||
|
font-size: var(--font-size-3xl);
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="button-row"] {
|
||||||
|
display: flex;
|
||||||
|
gap: var(--space-2);
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
@media (max-width: 30rem) {
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
> button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="create-form"] {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make Enable Billing button full width when it's the only button */
|
||||||
|
> button {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[data-slot="usage"] {
|
||||||
|
p {
|
||||||
|
font-size: var(--font-size-sm);
|
||||||
|
line-height: 1.5;
|
||||||
|
color: var(--color-text-secondary);
|
||||||
|
b {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import { json, query, action, useParams, createAsync, useSubmission } from "@solidjs/router"
|
||||||
|
import { withActor } from "~/context/auth.withActor"
|
||||||
|
import styles from "./billing-section.module.css"
|
||||||
|
import { Database, eq } from "@opencode/console-core/drizzle/index.js"
|
||||||
|
import { WorkspaceTable } from "@opencode/console-core/schema/workspace.sql.js"
|
||||||
|
import { Show } from "solid-js"
|
||||||
|
|
||||||
|
const updateShare = action(async (form: FormData) => {
|
||||||
|
"use server"
|
||||||
|
const workspaceID = form.get("workspaceID")?.toString()
|
||||||
|
if (!workspaceID) return { error: "Workspace ID is required" }
|
||||||
|
const dataShare = form.get("dataShare")?.toString() === "true" ? true : null
|
||||||
|
return json(
|
||||||
|
await withActor(() => {
|
||||||
|
return Database.use((tx) =>
|
||||||
|
tx
|
||||||
|
.update(WorkspaceTable)
|
||||||
|
.set({
|
||||||
|
dataShare,
|
||||||
|
})
|
||||||
|
.where(eq(WorkspaceTable.id, workspaceID)),
|
||||||
|
)
|
||||||
|
}, workspaceID),
|
||||||
|
{ revalidate: getWorkspaceInfo.key },
|
||||||
|
)
|
||||||
|
}, "workspace.disableShare")
|
||||||
|
|
||||||
|
const getWorkspaceInfo = query(async (workspaceID: string) => {
|
||||||
|
"use server"
|
||||||
|
return withActor(() => {
|
||||||
|
return Database.use((tx) =>
|
||||||
|
tx
|
||||||
|
.select({
|
||||||
|
dataShare: WorkspaceTable.dataShare,
|
||||||
|
})
|
||||||
|
.from(WorkspaceTable)
|
||||||
|
.where(eq(WorkspaceTable.id, workspaceID))
|
||||||
|
.then((r) => r[0]),
|
||||||
|
)
|
||||||
|
}, workspaceID)
|
||||||
|
}, "workspace.get")
|
||||||
|
|
||||||
|
export function PrivacySection() {
|
||||||
|
const params = useParams()
|
||||||
|
const workspaceInfo = createAsync(() => getWorkspaceInfo(params.id))
|
||||||
|
const updateShareSubmission = useSubmission(updateShare)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section class={styles.root}>
|
||||||
|
<div data-slot="section-title">
|
||||||
|
<h2>Privacy controls</h2>
|
||||||
|
<p>
|
||||||
|
Some providers offer data-sharing programs. If you opt in, you voluntarily <b>share your usage data</b> with
|
||||||
|
them, which they may use to improve their services, including <b>model training</b>.
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
By opting in, you gain access to <b>discounted pricing</b> from the provider. You can opt in or out at any
|
||||||
|
time.
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<p>
|
||||||
|
<a target="_blank" href="/docs/zen">
|
||||||
|
Learn more
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<Show when={workspaceInfo()?.dataShare}>
|
||||||
|
<div data-slot="payment">
|
||||||
|
<div data-slot="credit-card">
|
||||||
|
<div data-slot="card-details">
|
||||||
|
<span data-slot="number">You are currently opted in to the data-sharing program.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
<div data-slot="section-content">
|
||||||
|
<div data-slot="payment">
|
||||||
|
<div data-slot="button-row">
|
||||||
|
<form action={updateShare} method="post" data-slot="create-form">
|
||||||
|
<input type="hidden" name="workspaceID" value={params.id} />
|
||||||
|
<input type="hidden" name="dataShare" value={workspaceInfo()?.dataShare ? "false" : "true"} />
|
||||||
|
<button data-color="ghost" type="submit" disabled={updateShareSubmission.pending}>
|
||||||
|
{workspaceInfo()?.dataShare
|
||||||
|
? updateShareSubmission.pending
|
||||||
|
? "Opting out..."
|
||||||
|
: "Opt out"
|
||||||
|
: updateShareSubmission.pending
|
||||||
|
? "Opting in..."
|
||||||
|
: "Opt in"}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@ import "./[id].css"
|
|||||||
import { MonthlyLimitSection } from "~/component/workspace/monthly-limit-section"
|
import { MonthlyLimitSection } from "~/component/workspace/monthly-limit-section"
|
||||||
import { NewUserSection } from "~/component/workspace/new-user-section"
|
import { NewUserSection } from "~/component/workspace/new-user-section"
|
||||||
import { BillingSection } from "~/component/workspace/billing-section"
|
import { BillingSection } from "~/component/workspace/billing-section"
|
||||||
|
import { PrivacySection } from "~/component/workspace/privacy-section"
|
||||||
import { PaymentSection } from "~/component/workspace/payment-section"
|
import { PaymentSection } from "~/component/workspace/payment-section"
|
||||||
import { UsageSection } from "~/component/workspace/usage-section"
|
import { UsageSection } from "~/component/workspace/usage-section"
|
||||||
import { KeySection } from "~/component/workspace/key-section"
|
import { KeySection } from "~/component/workspace/key-section"
|
||||||
|
import { Show } from "solid-js"
|
||||||
|
import { useParams } from "@solidjs/router"
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
|
const params = useParams()
|
||||||
return (
|
return (
|
||||||
<div data-page="workspace-[id]">
|
<div data-page="workspace-[id]">
|
||||||
<section data-component="title-section">
|
<section data-component="title-section">
|
||||||
@@ -25,9 +29,20 @@ export default function () {
|
|||||||
<KeySection />
|
<KeySection />
|
||||||
<BillingSection />
|
<BillingSection />
|
||||||
<MonthlyLimitSection />
|
<MonthlyLimitSection />
|
||||||
|
<Show when={isBeta(params.id)}>
|
||||||
|
<PrivacySection />
|
||||||
|
</Show>
|
||||||
<UsageSection />
|
<UsageSection />
|
||||||
<PaymentSection />
|
<PaymentSection />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isBeta(workspaceID: string) {
|
||||||
|
return [
|
||||||
|
"wrk_01K46JDFR0E75SG2Q8K172KF3Y", // production
|
||||||
|
"wrk_01K4NFRR5P7FSYWH88307B4DDS", // dev
|
||||||
|
"wrk_01K4PJRKJ2WPQZN3FFYRV4673F", // frank
|
||||||
|
].includes(workspaceID)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,37 +1,15 @@
|
|||||||
|
import { z } from "zod"
|
||||||
import type { APIEvent } from "@solidjs/start/server"
|
import type { APIEvent } from "@solidjs/start/server"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import { and, Database, eq, isNull, lt, or, sql } from "@opencode/console-core/drizzle/index.js"
|
import { and, Database, eq, isNull, lt, or, sql } from "@opencode/console-core/drizzle/index.js"
|
||||||
import { KeyTable } from "@opencode/console-core/schema/key.sql.js"
|
import { KeyTable } from "@opencode/console-core/schema/key.sql.js"
|
||||||
import { BillingTable, PaymentTable, UsageTable } from "@opencode/console-core/schema/billing.sql.js"
|
import { BillingTable, UsageTable } from "@opencode/console-core/schema/billing.sql.js"
|
||||||
import { centsToMicroCents } from "@opencode/console-core/util/price.js"
|
import { centsToMicroCents } from "@opencode/console-core/util/price.js"
|
||||||
import { Identifier } from "@opencode/console-core/identifier.js"
|
import { Identifier } from "@opencode/console-core/identifier.js"
|
||||||
import { Resource } from "@opencode/console-resource"
|
import { Resource } from "@opencode/console-resource"
|
||||||
import { Billing } from "../../../../core/src/billing"
|
import { Billing } from "../../../../core/src/billing"
|
||||||
import { Actor } from "@opencode/console-core/actor.js"
|
import { Actor } from "@opencode/console-core/actor.js"
|
||||||
|
import { WorkspaceTable } from "@opencode/console-core/schema/workspace.sql.js"
|
||||||
type ModelCost = {
|
|
||||||
input: number
|
|
||||||
output: number
|
|
||||||
cacheRead?: number
|
|
||||||
cacheWrite5m?: number
|
|
||||||
cacheWrite1h?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
type Model = {
|
|
||||||
id: string
|
|
||||||
auth: boolean
|
|
||||||
cost: ModelCost | ((usage: any) => ModelCost)
|
|
||||||
headerMappings: Record<string, string>
|
|
||||||
providers: Record<
|
|
||||||
string,
|
|
||||||
{
|
|
||||||
api: string
|
|
||||||
apiKey: string
|
|
||||||
model: string
|
|
||||||
weight?: number
|
|
||||||
}
|
|
||||||
>
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function handler(
|
export async function handler(
|
||||||
input: APIEvent,
|
input: APIEvent,
|
||||||
@@ -56,184 +34,32 @@ export async function handler(
|
|||||||
class MonthlyLimitError extends Error {}
|
class MonthlyLimitError extends Error {}
|
||||||
class ModelError extends Error {}
|
class ModelError extends Error {}
|
||||||
|
|
||||||
const MODELS: Record<string, Model> = {
|
const ModelCostSchema = z.object({
|
||||||
"claude-opus-4-1": {
|
input: z.number(),
|
||||||
id: "claude-opus-4-1" as const,
|
output: z.number(),
|
||||||
auth: true,
|
cacheRead: z.number().optional(),
|
||||||
cost: {
|
cacheWrite5m: z.number().optional(),
|
||||||
input: 0.000015,
|
cacheWrite1h: z.number().optional(),
|
||||||
output: 0.000075,
|
})
|
||||||
cacheRead: 0.0000015,
|
|
||||||
cacheWrite5m: 0.00001875,
|
const ModelSchema = z.object({
|
||||||
cacheWrite1h: 0.00003,
|
cost: ModelCostSchema,
|
||||||
},
|
cost200K: ModelCostSchema.optional(),
|
||||||
headerMappings: {},
|
providers: z.array(
|
||||||
providers: {
|
z.object({
|
||||||
anthropic: {
|
id: z.string(),
|
||||||
api: "https://api.anthropic.com",
|
api: z.string(),
|
||||||
apiKey: Resource.ANTHROPIC_API_KEY.value,
|
apiKey: z.string(),
|
||||||
model: "claude-opus-4-1-20250805",
|
model: z.string(),
|
||||||
},
|
weight: z.number().optional(),
|
||||||
},
|
allowAnonymous: z.boolean().optional(),
|
||||||
},
|
headerMappings: z.record(z.string(), z.string()).optional(),
|
||||||
"claude-sonnet-4": {
|
disabled: z.boolean().optional(),
|
||||||
id: "claude-sonnet-4" as const,
|
}),
|
||||||
auth: true,
|
),
|
||||||
cost: (usage: any) => {
|
})
|
||||||
const totalInputTokens =
|
|
||||||
usage.inputTokens + usage.cacheReadTokens + usage.cacheWrite5mTokens + usage.cacheWrite1hTokens
|
type Model = z.infer<typeof ModelSchema>
|
||||||
return totalInputTokens <= 200_000
|
|
||||||
? {
|
|
||||||
input: 0.000003,
|
|
||||||
output: 0.000015,
|
|
||||||
cacheRead: 0.0000003,
|
|
||||||
cacheWrite5m: 0.00000375,
|
|
||||||
cacheWrite1h: 0.000006,
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
input: 0.000006,
|
|
||||||
output: 0.0000225,
|
|
||||||
cacheRead: 0.0000006,
|
|
||||||
cacheWrite5m: 0.0000075,
|
|
||||||
cacheWrite1h: 0.000012,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
headerMappings: {},
|
|
||||||
providers: {
|
|
||||||
anthropic: {
|
|
||||||
api: "https://api.anthropic.com",
|
|
||||||
apiKey: Resource.ANTHROPIC_API_KEY.value,
|
|
||||||
model: "claude-sonnet-4-20250514",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"claude-3-5-haiku": {
|
|
||||||
id: "claude-3-5-haiku" as const,
|
|
||||||
auth: true,
|
|
||||||
cost: {
|
|
||||||
input: 0.0000008,
|
|
||||||
output: 0.000004,
|
|
||||||
cacheRead: 0.00000008,
|
|
||||||
cacheWrite5m: 0.000001,
|
|
||||||
cacheWrite1h: 0.0000016,
|
|
||||||
},
|
|
||||||
headerMappings: {},
|
|
||||||
providers: {
|
|
||||||
anthropic: {
|
|
||||||
api: "https://api.anthropic.com",
|
|
||||||
apiKey: Resource.ANTHROPIC_API_KEY.value,
|
|
||||||
model: "claude-3-5-haiku-20241022",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"gpt-5": {
|
|
||||||
id: "gpt-5" as const,
|
|
||||||
auth: true,
|
|
||||||
cost: {
|
|
||||||
input: 0.00000125,
|
|
||||||
output: 0.00001,
|
|
||||||
cacheRead: 0.000000125,
|
|
||||||
},
|
|
||||||
headerMappings: {},
|
|
||||||
providers: {
|
|
||||||
openai: {
|
|
||||||
api: "https://api.openai.com",
|
|
||||||
apiKey: Resource.OPENAI_API_KEY.value,
|
|
||||||
model: "gpt-5",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"qwen3-coder": {
|
|
||||||
id: "qwen3-coder" as const,
|
|
||||||
auth: true,
|
|
||||||
cost: {
|
|
||||||
input: 0.00000045,
|
|
||||||
output: 0.0000018,
|
|
||||||
},
|
|
||||||
headerMappings: {},
|
|
||||||
providers: {
|
|
||||||
baseten: {
|
|
||||||
api: "https://inference.baseten.co",
|
|
||||||
apiKey: Resource.BASETEN_API_KEY.value,
|
|
||||||
model: "Qwen/Qwen3-Coder-480B-A35B-Instruct",
|
|
||||||
weight: 4,
|
|
||||||
},
|
|
||||||
fireworks: {
|
|
||||||
api: "https://api.fireworks.ai/inference",
|
|
||||||
apiKey: Resource.FIREWORKS_API_KEY.value,
|
|
||||||
model: "accounts/fireworks/models/qwen3-coder-480b-a35b-instruct",
|
|
||||||
weight: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"kimi-k2": {
|
|
||||||
id: "kimi-k2" as const,
|
|
||||||
auth: true,
|
|
||||||
cost: {
|
|
||||||
input: 0.0000006,
|
|
||||||
output: 0.0000025,
|
|
||||||
},
|
|
||||||
headerMappings: {},
|
|
||||||
providers: {
|
|
||||||
baseten: {
|
|
||||||
api: "https://inference.baseten.co",
|
|
||||||
apiKey: Resource.BASETEN_API_KEY.value,
|
|
||||||
model: "moonshotai/Kimi-K2-Instruct-0905",
|
|
||||||
//weight: 4,
|
|
||||||
},
|
|
||||||
//fireworks: {
|
|
||||||
// api: "https://api.fireworks.ai/inference",
|
|
||||||
// apiKey: Resource.FIREWORKS_API_KEY.value,
|
|
||||||
// model: "accounts/fireworks/models/kimi-k2-instruct-0905",
|
|
||||||
// weight: 1,
|
|
||||||
//},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"grok-code": {
|
|
||||||
id: "grok-code" as const,
|
|
||||||
auth: false,
|
|
||||||
cost: {
|
|
||||||
input: 0,
|
|
||||||
output: 0,
|
|
||||||
cacheRead: 0,
|
|
||||||
},
|
|
||||||
headerMappings: {
|
|
||||||
"x-grok-conv-id": "x-opencode-session",
|
|
||||||
"x-grok-req-id": "x-opencode-request",
|
|
||||||
},
|
|
||||||
providers: {
|
|
||||||
xai: {
|
|
||||||
api: "https://api.x.ai",
|
|
||||||
apiKey: Resource.XAI_API_KEY.value,
|
|
||||||
model: "grok-code",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// deprecated
|
|
||||||
"qwen/qwen3-coder": {
|
|
||||||
id: "qwen/qwen3-coder" as const,
|
|
||||||
auth: true,
|
|
||||||
cost: {
|
|
||||||
input: 0.00000038,
|
|
||||||
output: 0.00000153,
|
|
||||||
},
|
|
||||||
headerMappings: {},
|
|
||||||
providers: {
|
|
||||||
baseten: {
|
|
||||||
api: "https://inference.baseten.co",
|
|
||||||
apiKey: Resource.BASETEN_API_KEY.value,
|
|
||||||
model: "Qwen/Qwen3-Coder-480B-A35B-Instruct",
|
|
||||||
weight: 5,
|
|
||||||
},
|
|
||||||
fireworks: {
|
|
||||||
api: "https://api.fireworks.ai/inference",
|
|
||||||
apiKey: Resource.FIREWORKS_API_KEY.value,
|
|
||||||
model: "accounts/fireworks/models/qwen3-coder-480b-a35b-instruct",
|
|
||||||
weight: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const FREE_WORKSPACES = [
|
const FREE_WORKSPACES = [
|
||||||
"wrk_01K46JDFR0E75SG2Q8K172KF3Y", // frank
|
"wrk_01K46JDFR0E75SG2Q8K172KF3Y", // frank
|
||||||
@@ -259,31 +85,28 @@ export async function handler(
|
|||||||
session: input.request.headers.get("x-opencode-session"),
|
session: input.request.headers.get("x-opencode-session"),
|
||||||
request: input.request.headers.get("x-opencode-request"),
|
request: input.request.headers.get("x-opencode-request"),
|
||||||
})
|
})
|
||||||
const MODEL = validateModel()
|
const authInfo = await authenticate()
|
||||||
const apiKey = await authenticate()
|
const modelInfo = validateModel(body.model, authInfo)
|
||||||
const isFree = FREE_WORKSPACES.includes(apiKey?.workspaceID ?? "")
|
const providerInfo = selectProvider(modelInfo, authInfo)
|
||||||
await checkCreditsAndLimit()
|
logger.metric({ provider: providerInfo.id })
|
||||||
const providerName = selectProvider()
|
|
||||||
const providerData = MODEL.providers[providerName]
|
|
||||||
logger.metric({ provider: providerName })
|
|
||||||
|
|
||||||
// Request to model provider
|
// Request to model provider
|
||||||
const startTimestamp = Date.now()
|
const startTimestamp = Date.now()
|
||||||
const res = await fetch(path.posix.join(providerData.api, url.pathname.replace(/^\/zen/, "") + url.search), {
|
const res = await fetch(path.posix.join(providerInfo.api, url.pathname.replace(/^\/zen/, "") + url.search), {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: (() => {
|
headers: (() => {
|
||||||
const headers = input.request.headers
|
const headers = input.request.headers
|
||||||
headers.delete("host")
|
headers.delete("host")
|
||||||
headers.delete("content-length")
|
headers.delete("content-length")
|
||||||
opts.setAuthHeader(headers, providerData.apiKey)
|
opts.setAuthHeader(headers, providerInfo.apiKey)
|
||||||
Object.entries(MODEL.headerMappings ?? {}).forEach(([k, v]) => {
|
Object.entries(providerInfo.headerMappings ?? {}).forEach(([k, v]) => {
|
||||||
headers.set(k, headers.get(v)!)
|
headers.set(k, headers.get(v)!)
|
||||||
})
|
})
|
||||||
return headers
|
return headers
|
||||||
})(),
|
})(),
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
...(opts.modifyBody?.(body) ?? body),
|
...(opts.modifyBody?.(body) ?? body),
|
||||||
model: providerData.model,
|
model: providerInfo.model,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -302,8 +125,8 @@ export async function handler(
|
|||||||
const body = JSON.stringify(json)
|
const body = JSON.stringify(json)
|
||||||
logger.metric({ response_length: body.length })
|
logger.metric({ response_length: body.length })
|
||||||
logger.debug(body)
|
logger.debug(body)
|
||||||
await trackUsage(json.usage)
|
await trackUsage(authInfo, modelInfo, providerInfo.id, json.usage)
|
||||||
await reload()
|
await reload(authInfo)
|
||||||
return new Response(body, {
|
return new Response(body, {
|
||||||
status: res.status,
|
status: res.status,
|
||||||
statusText: res.statusText,
|
statusText: res.statusText,
|
||||||
@@ -326,8 +149,8 @@ export async function handler(
|
|||||||
logger.metric({ response_length: responseLength })
|
logger.metric({ response_length: responseLength })
|
||||||
const usage = opts.getStreamUsage()
|
const usage = opts.getStreamUsage()
|
||||||
if (usage) {
|
if (usage) {
|
||||||
await trackUsage(usage)
|
await trackUsage(authInfo, modelInfo, providerInfo.id, usage)
|
||||||
await reload()
|
await reload(authInfo)
|
||||||
}
|
}
|
||||||
c.close()
|
c.close()
|
||||||
return
|
return
|
||||||
@@ -337,6 +160,7 @@ export async function handler(
|
|||||||
logger.metric({ time_to_first_byte: Date.now() - startTimestamp })
|
logger.metric({ time_to_first_byte: Date.now() - startTimestamp })
|
||||||
}
|
}
|
||||||
responseLength += value.length
|
responseLength += value.length
|
||||||
|
console.log(decoder.decode(value, { stream: true }))
|
||||||
buffer += decoder.decode(value, { stream: true })
|
buffer += decoder.decode(value, { stream: true })
|
||||||
|
|
||||||
const parts = buffer.split("\n\n")
|
const parts = buffer.split("\n\n")
|
||||||
@@ -363,92 +187,146 @@ export async function handler(
|
|||||||
statusText: res.statusText,
|
statusText: res.statusText,
|
||||||
headers: resHeaders,
|
headers: resHeaders,
|
||||||
})
|
})
|
||||||
|
} catch (error: any) {
|
||||||
|
logger.metric({
|
||||||
|
"error.type": error.constructor.name,
|
||||||
|
"error.message": error.message,
|
||||||
|
})
|
||||||
|
|
||||||
function validateModel() {
|
// Note: both top level "type" and "error.type" fields are used by the @ai-sdk/anthropic client to render the error message.
|
||||||
if (!(body.model in MODELS)) {
|
if (
|
||||||
throw new ModelError(`Model ${body.model} not supported`)
|
error instanceof AuthError ||
|
||||||
}
|
error instanceof CreditsError ||
|
||||||
const model = MODELS[body.model as keyof typeof MODELS]
|
error instanceof MonthlyLimitError ||
|
||||||
logger.metric({ model: model.id })
|
error instanceof ModelError
|
||||||
return model
|
)
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
type: "error",
|
||||||
|
error: { type: error.constructor.name, message: error.message },
|
||||||
|
}),
|
||||||
|
{ status: 401 },
|
||||||
|
)
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
type: "error",
|
||||||
|
error: {
|
||||||
|
type: "error",
|
||||||
|
message: error.message,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{ status: 500 },
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function authenticate() {
|
async function authenticate() {
|
||||||
try {
|
|
||||||
const apiKey = opts.parseApiKey(input.request.headers)
|
const apiKey = opts.parseApiKey(input.request.headers)
|
||||||
if (!apiKey) throw new AuthError("Missing API key.")
|
if (!apiKey) return
|
||||||
|
|
||||||
const key = await Database.use((tx) =>
|
const data = await Database.use((tx) =>
|
||||||
tx
|
tx
|
||||||
.select({
|
.select({
|
||||||
id: KeyTable.id,
|
apiKey: KeyTable.id,
|
||||||
workspaceID: KeyTable.workspaceID,
|
workspaceID: KeyTable.workspaceID,
|
||||||
})
|
dataShare: WorkspaceTable.dataShare,
|
||||||
.from(KeyTable)
|
|
||||||
.where(and(eq(KeyTable.key, apiKey), isNull(KeyTable.timeDeleted)))
|
|
||||||
.then((rows) => rows[0]),
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!key) throw new AuthError("Invalid API key.")
|
|
||||||
logger.metric({
|
|
||||||
api_key: key.id,
|
|
||||||
workspace: key.workspaceID,
|
|
||||||
})
|
|
||||||
return key
|
|
||||||
} catch (e) {
|
|
||||||
// ignore error if model does not require authentication
|
|
||||||
if (!MODEL.auth) return
|
|
||||||
throw e
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function checkCreditsAndLimit() {
|
|
||||||
if (!apiKey || !MODEL.auth || isFree) return
|
|
||||||
|
|
||||||
const billing = await Database.use((tx) =>
|
|
||||||
tx
|
|
||||||
.select({
|
|
||||||
balance: BillingTable.balance,
|
balance: BillingTable.balance,
|
||||||
paymentMethodID: BillingTable.paymentMethodID,
|
paymentMethodID: BillingTable.paymentMethodID,
|
||||||
monthlyLimit: BillingTable.monthlyLimit,
|
monthlyLimit: BillingTable.monthlyLimit,
|
||||||
monthlyUsage: BillingTable.monthlyUsage,
|
monthlyUsage: BillingTable.monthlyUsage,
|
||||||
timeMonthlyUsageUpdated: BillingTable.timeMonthlyUsageUpdated,
|
timeMonthlyUsageUpdated: BillingTable.timeMonthlyUsageUpdated,
|
||||||
})
|
})
|
||||||
.from(BillingTable)
|
.from(KeyTable)
|
||||||
.where(eq(BillingTable.workspaceID, apiKey.workspaceID))
|
.innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID))
|
||||||
|
.innerJoin(BillingTable, eq(BillingTable.workspaceID, KeyTable.workspaceID))
|
||||||
|
.where(and(eq(KeyTable.key, apiKey), isNull(KeyTable.timeDeleted)))
|
||||||
.then((rows) => rows[0]),
|
.then((rows) => rows[0]),
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!billing.paymentMethodID) throw new CreditsError("No payment method")
|
if (!data) throw new AuthError("Invalid API key.")
|
||||||
if (billing.balance <= 0) throw new CreditsError("Insufficient balance")
|
logger.metric({
|
||||||
|
api_key: data.apiKey,
|
||||||
|
workspace: data.workspaceID,
|
||||||
|
})
|
||||||
|
|
||||||
|
const isFree = FREE_WORKSPACES.includes(data.workspaceID)
|
||||||
|
if (!isFree) {
|
||||||
|
if (!data.paymentMethodID) throw new CreditsError("No payment method")
|
||||||
|
if (data.balance <= 0) throw new CreditsError("Insufficient balance")
|
||||||
if (
|
if (
|
||||||
billing.monthlyLimit &&
|
data.monthlyLimit &&
|
||||||
billing.monthlyUsage &&
|
data.monthlyUsage &&
|
||||||
billing.timeMonthlyUsageUpdated &&
|
data.timeMonthlyUsageUpdated &&
|
||||||
billing.monthlyUsage >= centsToMicroCents(billing.monthlyLimit * 100)
|
data.monthlyUsage >= centsToMicroCents(data.monthlyLimit * 100)
|
||||||
) {
|
) {
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
const currentYear = now.getUTCFullYear()
|
const currentYear = now.getUTCFullYear()
|
||||||
const currentMonth = now.getUTCMonth()
|
const currentMonth = now.getUTCMonth()
|
||||||
const dateYear = billing.timeMonthlyUsageUpdated.getUTCFullYear()
|
const dateYear = data.timeMonthlyUsageUpdated.getUTCFullYear()
|
||||||
const dateMonth = billing.timeMonthlyUsageUpdated.getUTCMonth()
|
const dateMonth = data.timeMonthlyUsageUpdated.getUTCMonth()
|
||||||
if (currentYear === dateYear && currentMonth === dateMonth)
|
if (currentYear === dateYear && currentMonth === dateMonth)
|
||||||
throw new MonthlyLimitError(`You have reached your monthly spending limit of $${billing.monthlyLimit}.`)
|
throw new MonthlyLimitError(`You have reached your monthly spending limit of $${data.monthlyLimit}.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectProvider() {
|
return {
|
||||||
const picks = Object.entries(MODEL.providers).flatMap(([name, provider]) =>
|
apiKeyId: data.apiKey,
|
||||||
Array<string>(provider.weight ?? 1).fill(name),
|
workspaceID: data.workspaceID,
|
||||||
|
dataShare: data.dataShare,
|
||||||
|
isFree,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateModel(reqModel: string, authInfo: Awaited<ReturnType<typeof authenticate>>) {
|
||||||
|
const json = JSON.parse(Resource.ZEN_MODELS.value)
|
||||||
|
|
||||||
|
const allModels = z
|
||||||
|
.record(
|
||||||
|
z.string(),
|
||||||
|
z.object({
|
||||||
|
standard: ModelSchema,
|
||||||
|
dataShare: ModelSchema.optional(),
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
.parse(json)
|
||||||
|
|
||||||
|
if (!(reqModel in allModels)) {
|
||||||
|
throw new ModelError(`Model ${reqModel} not supported`)
|
||||||
|
}
|
||||||
|
const modelId = reqModel as keyof typeof allModels
|
||||||
|
const modelData = authInfo?.dataShare
|
||||||
|
? (allModels[modelId].dataShare ?? allModels[modelId].standard)
|
||||||
|
: allModels[modelId].standard
|
||||||
|
logger.metric({ model: modelId })
|
||||||
|
return { id: modelId, ...modelData }
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectProvider(model: Model, authInfo: Awaited<ReturnType<typeof authenticate>>) {
|
||||||
|
let providers = model.providers.filter((provider) => !provider.disabled)
|
||||||
|
|
||||||
|
if (!authInfo) {
|
||||||
|
providers = providers.filter((provider) => provider.allowAnonymous)
|
||||||
|
if (providers.length === 0) throw new AuthError("Missing API key.")
|
||||||
|
}
|
||||||
|
|
||||||
|
const picks = providers.flatMap((provider) => Array<typeof provider>(provider.weight ?? 1).fill(provider))
|
||||||
return picks[Math.floor(Math.random() * picks.length)]
|
return picks[Math.floor(Math.random() * picks.length)]
|
||||||
}
|
}
|
||||||
|
|
||||||
async function trackUsage(usage: any) {
|
async function trackUsage(
|
||||||
|
authInfo: Awaited<ReturnType<typeof authenticate>>,
|
||||||
|
modelInfo: ReturnType<typeof validateModel>,
|
||||||
|
providerId: string,
|
||||||
|
usage: any,
|
||||||
|
) {
|
||||||
const { inputTokens, outputTokens, reasoningTokens, cacheReadTokens, cacheWrite5mTokens, cacheWrite1hTokens } =
|
const { inputTokens, outputTokens, reasoningTokens, cacheReadTokens, cacheWrite5mTokens, cacheWrite1hTokens } =
|
||||||
opts.normalizeUsage(usage)
|
opts.normalizeUsage(usage)
|
||||||
|
|
||||||
const modelCost = typeof MODEL.cost === "function" ? MODEL.cost(usage) : MODEL.cost
|
const modelCost =
|
||||||
|
modelInfo.cost200K &&
|
||||||
|
usage.inputTokens + usage.cacheReadTokens + usage.cacheWrite5mTokens + usage.cacheWrite1hTokens > 200_000
|
||||||
|
? modelInfo.cost200K
|
||||||
|
: modelInfo.cost
|
||||||
|
|
||||||
const inputCost = modelCost.input * inputTokens * 100
|
const inputCost = modelCost.input * inputTokens * 100
|
||||||
const outputCost = modelCost.output * outputTokens * 100
|
const outputCost = modelCost.output * outputTokens * 100
|
||||||
@@ -495,15 +373,15 @@ export async function handler(
|
|||||||
"cost.total": Math.round(totalCostInCent),
|
"cost.total": Math.round(totalCostInCent),
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!apiKey) return
|
if (!authInfo) return
|
||||||
|
|
||||||
const cost = isFree ? 0 : centsToMicroCents(totalCostInCent)
|
const cost = authInfo.isFree ? 0 : centsToMicroCents(totalCostInCent)
|
||||||
await Database.transaction(async (tx) => {
|
await Database.transaction(async (tx) => {
|
||||||
await tx.insert(UsageTable).values({
|
await tx.insert(UsageTable).values({
|
||||||
workspaceID: apiKey.workspaceID,
|
workspaceID: authInfo.workspaceID,
|
||||||
id: Identifier.create("usage"),
|
id: Identifier.create("usage"),
|
||||||
model: MODEL.id,
|
model: modelInfo.id,
|
||||||
provider: providerName,
|
provider: providerId,
|
||||||
inputTokens,
|
inputTokens,
|
||||||
outputTokens,
|
outputTokens,
|
||||||
reasoningTokens,
|
reasoningTokens,
|
||||||
@@ -524,19 +402,19 @@ export async function handler(
|
|||||||
`,
|
`,
|
||||||
timeMonthlyUsageUpdated: sql`now()`,
|
timeMonthlyUsageUpdated: sql`now()`,
|
||||||
})
|
})
|
||||||
.where(eq(BillingTable.workspaceID, apiKey.workspaceID))
|
.where(eq(BillingTable.workspaceID, authInfo.workspaceID))
|
||||||
})
|
})
|
||||||
|
|
||||||
await Database.use((tx) =>
|
await Database.use((tx) =>
|
||||||
tx
|
tx
|
||||||
.update(KeyTable)
|
.update(KeyTable)
|
||||||
.set({ timeUsed: sql`now()` })
|
.set({ timeUsed: sql`now()` })
|
||||||
.where(eq(KeyTable.id, apiKey.id)),
|
.where(eq(KeyTable.id, authInfo.apiKeyId)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function reload() {
|
async function reload(authInfo: Awaited<ReturnType<typeof authenticate>>) {
|
||||||
if (!apiKey) return
|
if (!authInfo) return
|
||||||
|
|
||||||
const lock = await Database.use((tx) =>
|
const lock = await Database.use((tx) =>
|
||||||
tx
|
tx
|
||||||
@@ -546,7 +424,7 @@ export async function handler(
|
|||||||
})
|
})
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
eq(BillingTable.workspaceID, apiKey.workspaceID),
|
eq(BillingTable.workspaceID, authInfo.workspaceID),
|
||||||
eq(BillingTable.reload, true),
|
eq(BillingTable.reload, true),
|
||||||
lt(BillingTable.balance, centsToMicroCents(Billing.CHARGE_THRESHOLD)),
|
lt(BillingTable.balance, centsToMicroCents(Billing.CHARGE_THRESHOLD)),
|
||||||
or(isNull(BillingTable.timeReloadLockedTill), lt(BillingTable.timeReloadLockedTill, sql`now()`)),
|
or(isNull(BillingTable.timeReloadLockedTill), lt(BillingTable.timeReloadLockedTill, sql`now()`)),
|
||||||
@@ -555,40 +433,8 @@ export async function handler(
|
|||||||
)
|
)
|
||||||
if (lock.rowsAffected === 0) return
|
if (lock.rowsAffected === 0) return
|
||||||
|
|
||||||
await Actor.provide("system", { workspaceID: apiKey.workspaceID }, async () => {
|
await Actor.provide("system", { workspaceID: authInfo.workspaceID }, async () => {
|
||||||
await Billing.reload()
|
await Billing.reload()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} catch (error: any) {
|
|
||||||
logger.metric({
|
|
||||||
"error.type": error.constructor.name,
|
|
||||||
"error.message": error.message,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Note: both top level "type" and "error.type" fields are used by the @ai-sdk/anthropic client to render the error message.
|
|
||||||
if (
|
|
||||||
error instanceof AuthError ||
|
|
||||||
error instanceof CreditsError ||
|
|
||||||
error instanceof MonthlyLimitError ||
|
|
||||||
error instanceof ModelError
|
|
||||||
)
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
type: "error",
|
|
||||||
error: { type: error.constructor.name, message: error.message },
|
|
||||||
}),
|
|
||||||
{ status: 401 },
|
|
||||||
)
|
|
||||||
|
|
||||||
return new Response(
|
|
||||||
JSON.stringify({
|
|
||||||
type: "error",
|
|
||||||
error: {
|
|
||||||
type: "error",
|
|
||||||
message: error.message,
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
{ status: 500 },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ type Usage = {
|
|||||||
prompt_tokens?: number
|
prompt_tokens?: number
|
||||||
completion_tokens?: number
|
completion_tokens?: number
|
||||||
total_tokens?: number
|
total_tokens?: number
|
||||||
|
// used by moonshot
|
||||||
|
cached_tokens?: number
|
||||||
|
// used by xai
|
||||||
prompt_tokens_details?: {
|
prompt_tokens_details?: {
|
||||||
text_tokens?: number
|
text_tokens?: number
|
||||||
audio_tokens?: number
|
audio_tokens?: number
|
||||||
@@ -48,7 +51,7 @@ export function POST(input: APIEvent) {
|
|||||||
inputTokens: usage.prompt_tokens ?? 0,
|
inputTokens: usage.prompt_tokens ?? 0,
|
||||||
outputTokens: usage.completion_tokens ?? 0,
|
outputTokens: usage.completion_tokens ?? 0,
|
||||||
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? undefined,
|
reasoningTokens: usage.completion_tokens_details?.reasoning_tokens ?? undefined,
|
||||||
cacheReadTokens: usage.prompt_tokens_details?.cached_tokens ?? undefined,
|
cacheReadTokens: usage.cached_tokens ?? usage.prompt_tokens_details?.cached_tokens ?? undefined,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `workspace` ADD `data_share` boolean;
|
||||||
681
packages/console/core/migrations/meta/0014_snapshot.json
Normal file
681
packages/console/core/migrations/meta/0014_snapshot.json
Normal file
@@ -0,0 +1,681 @@
|
|||||||
|
{
|
||||||
|
"version": "5",
|
||||||
|
"dialect": "mysql",
|
||||||
|
"id": "12189a4e-5083-4b17-b8e3-8279c9a3e61a",
|
||||||
|
"prevId": "28336c91-553c-4d1d-9875-1ee761e47582",
|
||||||
|
"tables": {
|
||||||
|
"account": {
|
||||||
|
"name": "account",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_created": {
|
||||||
|
"name": "time_created",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "(now())"
|
||||||
|
},
|
||||||
|
"time_updated": {
|
||||||
|
"name": "time_updated",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||||
|
},
|
||||||
|
"time_deleted": {
|
||||||
|
"name": "time_deleted",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"columns": [
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraint": {}
|
||||||
|
},
|
||||||
|
"billing": {
|
||||||
|
"name": "billing",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"workspace_id": {
|
||||||
|
"name": "workspace_id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_created": {
|
||||||
|
"name": "time_created",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "(now())"
|
||||||
|
},
|
||||||
|
"time_updated": {
|
||||||
|
"name": "time_updated",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||||
|
},
|
||||||
|
"time_deleted": {
|
||||||
|
"name": "time_deleted",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"customer_id": {
|
||||||
|
"name": "customer_id",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"payment_method_id": {
|
||||||
|
"name": "payment_method_id",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"payment_method_last4": {
|
||||||
|
"name": "payment_method_last4",
|
||||||
|
"type": "varchar(4)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"balance": {
|
||||||
|
"name": "balance",
|
||||||
|
"type": "bigint",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"monthly_limit": {
|
||||||
|
"name": "monthly_limit",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"monthly_usage": {
|
||||||
|
"name": "monthly_usage",
|
||||||
|
"type": "bigint",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_monthly_usage_updated": {
|
||||||
|
"name": "time_monthly_usage_updated",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"reload": {
|
||||||
|
"name": "reload",
|
||||||
|
"type": "boolean",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"reload_error": {
|
||||||
|
"name": "reload_error",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_reload_error": {
|
||||||
|
"name": "time_reload_error",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_reload_locked_till": {
|
||||||
|
"name": "time_reload_locked_till",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"global_customer_id": {
|
||||||
|
"name": "global_customer_id",
|
||||||
|
"columns": [
|
||||||
|
"customer_id"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"billing_workspace_id_id_pk": {
|
||||||
|
"name": "billing_workspace_id_id_pk",
|
||||||
|
"columns": [
|
||||||
|
"workspace_id",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraint": {}
|
||||||
|
},
|
||||||
|
"payment": {
|
||||||
|
"name": "payment",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"workspace_id": {
|
||||||
|
"name": "workspace_id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_created": {
|
||||||
|
"name": "time_created",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "(now())"
|
||||||
|
},
|
||||||
|
"time_updated": {
|
||||||
|
"name": "time_updated",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||||
|
},
|
||||||
|
"time_deleted": {
|
||||||
|
"name": "time_deleted",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"customer_id": {
|
||||||
|
"name": "customer_id",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"payment_id": {
|
||||||
|
"name": "payment_id",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"amount": {
|
||||||
|
"name": "amount",
|
||||||
|
"type": "bigint",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"payment_workspace_id_id_pk": {
|
||||||
|
"name": "payment_workspace_id_id_pk",
|
||||||
|
"columns": [
|
||||||
|
"workspace_id",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraint": {}
|
||||||
|
},
|
||||||
|
"usage": {
|
||||||
|
"name": "usage",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"workspace_id": {
|
||||||
|
"name": "workspace_id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_created": {
|
||||||
|
"name": "time_created",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "(now())"
|
||||||
|
},
|
||||||
|
"time_updated": {
|
||||||
|
"name": "time_updated",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||||
|
},
|
||||||
|
"time_deleted": {
|
||||||
|
"name": "time_deleted",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"model": {
|
||||||
|
"name": "model",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"provider": {
|
||||||
|
"name": "provider",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"input_tokens": {
|
||||||
|
"name": "input_tokens",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"output_tokens": {
|
||||||
|
"name": "output_tokens",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"reasoning_tokens": {
|
||||||
|
"name": "reasoning_tokens",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"cache_read_tokens": {
|
||||||
|
"name": "cache_read_tokens",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"cache_write_5m_tokens": {
|
||||||
|
"name": "cache_write_5m_tokens",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"cache_write_1h_tokens": {
|
||||||
|
"name": "cache_write_1h_tokens",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"cost": {
|
||||||
|
"name": "cost",
|
||||||
|
"type": "bigint",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"usage_workspace_id_id_pk": {
|
||||||
|
"name": "usage_workspace_id_id_pk",
|
||||||
|
"columns": [
|
||||||
|
"workspace_id",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraint": {}
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"workspace_id": {
|
||||||
|
"name": "workspace_id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_created": {
|
||||||
|
"name": "time_created",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "(now())"
|
||||||
|
},
|
||||||
|
"time_updated": {
|
||||||
|
"name": "time_updated",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||||
|
},
|
||||||
|
"time_deleted": {
|
||||||
|
"name": "time_deleted",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"actor": {
|
||||||
|
"name": "actor",
|
||||||
|
"type": "json",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"old_name": {
|
||||||
|
"name": "old_name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"name": "key",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_used": {
|
||||||
|
"name": "time_used",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"global_key": {
|
||||||
|
"name": "global_key",
|
||||||
|
"columns": [
|
||||||
|
"key"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"columns": [
|
||||||
|
"workspace_id",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"key_workspace_id_id_pk": {
|
||||||
|
"name": "key_workspace_id_id_pk",
|
||||||
|
"columns": [
|
||||||
|
"workspace_id",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraint": {}
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"name": "user",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"workspace_id": {
|
||||||
|
"name": "workspace_id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_created": {
|
||||||
|
"name": "time_created",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "(now())"
|
||||||
|
},
|
||||||
|
"time_updated": {
|
||||||
|
"name": "time_updated",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||||
|
},
|
||||||
|
"time_deleted": {
|
||||||
|
"name": "time_deleted",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"email": {
|
||||||
|
"name": "email",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_seen": {
|
||||||
|
"name": "time_seen",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"name": "color",
|
||||||
|
"type": "int",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"user_email": {
|
||||||
|
"name": "user_email",
|
||||||
|
"columns": [
|
||||||
|
"workspace_id",
|
||||||
|
"email"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"user_workspace_id_id_pk": {
|
||||||
|
"name": "user_workspace_id_id_pk",
|
||||||
|
"columns": [
|
||||||
|
"workspace_id",
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraint": {}
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"name": "workspace",
|
||||||
|
"columns": {
|
||||||
|
"id": {
|
||||||
|
"name": "id",
|
||||||
|
"type": "varchar(30)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"slug": {
|
||||||
|
"name": "slug",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"name": "name",
|
||||||
|
"type": "varchar(255)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"data_share": {
|
||||||
|
"name": "data_share",
|
||||||
|
"type": "boolean",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
},
|
||||||
|
"time_created": {
|
||||||
|
"name": "time_created",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "(now())"
|
||||||
|
},
|
||||||
|
"time_updated": {
|
||||||
|
"name": "time_updated",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": true,
|
||||||
|
"autoincrement": false,
|
||||||
|
"default": "CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)"
|
||||||
|
},
|
||||||
|
"time_deleted": {
|
||||||
|
"name": "time_deleted",
|
||||||
|
"type": "timestamp(3)",
|
||||||
|
"primaryKey": false,
|
||||||
|
"notNull": false,
|
||||||
|
"autoincrement": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"indexes": {
|
||||||
|
"slug": {
|
||||||
|
"name": "slug",
|
||||||
|
"columns": [
|
||||||
|
"slug"
|
||||||
|
],
|
||||||
|
"isUnique": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"foreignKeys": {},
|
||||||
|
"compositePrimaryKeys": {
|
||||||
|
"workspace_id": {
|
||||||
|
"name": "workspace_id",
|
||||||
|
"columns": [
|
||||||
|
"id"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniqueConstraints": {},
|
||||||
|
"checkConstraint": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"views": {},
|
||||||
|
"_meta": {
|
||||||
|
"schemas": {},
|
||||||
|
"tables": {},
|
||||||
|
"columns": {}
|
||||||
|
},
|
||||||
|
"internal": {
|
||||||
|
"tables": {},
|
||||||
|
"indexes": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -99,6 +99,13 @@
|
|||||||
"when": 1757956978089,
|
"when": 1757956978089,
|
||||||
"tag": "0013_absurd_hobgoblin",
|
"tag": "0013_absurd_hobgoblin",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idx": 14,
|
||||||
|
"version": "5",
|
||||||
|
"when": 1758289919722,
|
||||||
|
"tag": "0014_demonic_princess_powerful",
|
||||||
|
"breakpoints": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { primaryKey, mysqlTable, uniqueIndex, varchar } from "drizzle-orm/mysql-core"
|
import { primaryKey, mysqlTable, uniqueIndex, varchar, boolean } from "drizzle-orm/mysql-core"
|
||||||
import { timestamps, ulid } from "../drizzle/types"
|
import { timestamps, ulid } from "../drizzle/types"
|
||||||
|
|
||||||
export const WorkspaceTable = mysqlTable(
|
export const WorkspaceTable = mysqlTable(
|
||||||
@@ -7,6 +7,7 @@ export const WorkspaceTable = mysqlTable(
|
|||||||
id: ulid("id").notNull().primaryKey(),
|
id: ulid("id").notNull().primaryKey(),
|
||||||
slug: varchar("slug", { length: 255 }),
|
slug: varchar("slug", { length: 255 }),
|
||||||
name: varchar("name", { length: 255 }),
|
name: varchar("name", { length: 255 }),
|
||||||
|
dataShare: boolean("data_share"),
|
||||||
...timestamps,
|
...timestamps,
|
||||||
},
|
},
|
||||||
(table) => [uniqueIndex("slug").on(table.slug)],
|
(table) => [uniqueIndex("slug").on(table.slug)],
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
import { fn } from "./util/fn"
|
import { fn } from "./util/fn"
|
||||||
import { centsToMicroCents } from "./util/price"
|
|
||||||
import { Actor } from "./actor"
|
import { Actor } from "./actor"
|
||||||
import { Database, eq } from "./drizzle"
|
import { Database, eq } from "./drizzle"
|
||||||
import { Identifier } from "./identifier"
|
import { Identifier } from "./identifier"
|
||||||
|
|||||||
114
packages/console/function/sst-env.d.ts
vendored
114
packages/console/function/sst-env.d.ts
vendored
@@ -6,89 +6,73 @@
|
|||||||
import "sst"
|
import "sst"
|
||||||
declare module "sst" {
|
declare module "sst" {
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
ANTHROPIC_API_KEY: {
|
"AUTH_API_URL": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Linkable"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
AUTH_API_URL: {
|
"Console": {
|
||||||
type: "sst.sst.Linkable"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
value: string
|
"url": string
|
||||||
}
|
}
|
||||||
BASETEN_API_KEY: {
|
"Database": {
|
||||||
type: "sst.sst.Secret"
|
"database": string
|
||||||
value: string
|
"host": string
|
||||||
|
"password": string
|
||||||
|
"port": number
|
||||||
|
"type": "sst.sst.Linkable"
|
||||||
|
"username": string
|
||||||
}
|
}
|
||||||
Console: {
|
"GITHUB_APP_ID": {
|
||||||
type: "sst.cloudflare.SolidStart"
|
"type": "sst.sst.Secret"
|
||||||
url: string
|
"value": string
|
||||||
}
|
}
|
||||||
Database: {
|
"GITHUB_APP_PRIVATE_KEY": {
|
||||||
database: string
|
"type": "sst.sst.Secret"
|
||||||
host: string
|
"value": string
|
||||||
password: string
|
|
||||||
port: number
|
|
||||||
type: "sst.sst.Linkable"
|
|
||||||
username: string
|
|
||||||
}
|
}
|
||||||
FIREWORKS_API_KEY: {
|
"GITHUB_CLIENT_ID_CONSOLE": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_APP_ID: {
|
"GITHUB_CLIENT_SECRET_CONSOLE": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_APP_PRIVATE_KEY: {
|
"GOOGLE_CLIENT_ID": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_CLIENT_ID_CONSOLE: {
|
"HONEYCOMB_API_KEY": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_CLIENT_SECRET_CONSOLE: {
|
"STRIPE_SECRET_KEY": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GOOGLE_CLIENT_ID: {
|
"STRIPE_WEBHOOK_SECRET": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Linkable"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
HONEYCOMB_API_KEY: {
|
"Web": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.cloudflare.Astro"
|
||||||
value: string
|
"url": string
|
||||||
}
|
}
|
||||||
OPENAI_API_KEY: {
|
"ZEN_MODELS": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
|
||||||
STRIPE_SECRET_KEY: {
|
|
||||||
type: "sst.sst.Secret"
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
STRIPE_WEBHOOK_SECRET: {
|
|
||||||
type: "sst.sst.Linkable"
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
Web: {
|
|
||||||
type: "sst.cloudflare.Astro"
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
XAI_API_KEY: {
|
|
||||||
type: "sst.sst.Secret"
|
|
||||||
value: string
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// cloudflare
|
// cloudflare
|
||||||
import * as cloudflare from "@cloudflare/workers-types"
|
import * as cloudflare from "@cloudflare/workers-types";
|
||||||
declare module "sst" {
|
declare module "sst" {
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
Api: cloudflare.Service
|
"Api": cloudflare.Service
|
||||||
AuthApi: cloudflare.Service
|
"AuthApi": cloudflare.Service
|
||||||
AuthStorage: cloudflare.KVNamespace
|
"AuthStorage": cloudflare.KVNamespace
|
||||||
Bucket: cloudflare.R2Bucket
|
"Bucket": cloudflare.R2Bucket
|
||||||
LogProcessor: cloudflare.Service
|
"LogProcessor": cloudflare.Service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
114
packages/console/resource/sst-env.d.ts
vendored
114
packages/console/resource/sst-env.d.ts
vendored
@@ -6,89 +6,73 @@
|
|||||||
import "sst"
|
import "sst"
|
||||||
declare module "sst" {
|
declare module "sst" {
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
ANTHROPIC_API_KEY: {
|
"AUTH_API_URL": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Linkable"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
AUTH_API_URL: {
|
"Console": {
|
||||||
type: "sst.sst.Linkable"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
value: string
|
"url": string
|
||||||
}
|
}
|
||||||
BASETEN_API_KEY: {
|
"Database": {
|
||||||
type: "sst.sst.Secret"
|
"database": string
|
||||||
value: string
|
"host": string
|
||||||
|
"password": string
|
||||||
|
"port": number
|
||||||
|
"type": "sst.sst.Linkable"
|
||||||
|
"username": string
|
||||||
}
|
}
|
||||||
Console: {
|
"GITHUB_APP_ID": {
|
||||||
type: "sst.cloudflare.SolidStart"
|
"type": "sst.sst.Secret"
|
||||||
url: string
|
"value": string
|
||||||
}
|
}
|
||||||
Database: {
|
"GITHUB_APP_PRIVATE_KEY": {
|
||||||
database: string
|
"type": "sst.sst.Secret"
|
||||||
host: string
|
"value": string
|
||||||
password: string
|
|
||||||
port: number
|
|
||||||
type: "sst.sst.Linkable"
|
|
||||||
username: string
|
|
||||||
}
|
}
|
||||||
FIREWORKS_API_KEY: {
|
"GITHUB_CLIENT_ID_CONSOLE": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_APP_ID: {
|
"GITHUB_CLIENT_SECRET_CONSOLE": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_APP_PRIVATE_KEY: {
|
"GOOGLE_CLIENT_ID": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_CLIENT_ID_CONSOLE: {
|
"HONEYCOMB_API_KEY": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_CLIENT_SECRET_CONSOLE: {
|
"STRIPE_SECRET_KEY": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GOOGLE_CLIENT_ID: {
|
"STRIPE_WEBHOOK_SECRET": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Linkable"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
HONEYCOMB_API_KEY: {
|
"Web": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.cloudflare.Astro"
|
||||||
value: string
|
"url": string
|
||||||
}
|
}
|
||||||
OPENAI_API_KEY: {
|
"ZEN_MODELS": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
|
||||||
STRIPE_SECRET_KEY: {
|
|
||||||
type: "sst.sst.Secret"
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
STRIPE_WEBHOOK_SECRET: {
|
|
||||||
type: "sst.sst.Linkable"
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
Web: {
|
|
||||||
type: "sst.cloudflare.Astro"
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
XAI_API_KEY: {
|
|
||||||
type: "sst.sst.Secret"
|
|
||||||
value: string
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// cloudflare
|
// cloudflare
|
||||||
import * as cloudflare from "@cloudflare/workers-types"
|
import * as cloudflare from "@cloudflare/workers-types";
|
||||||
declare module "sst" {
|
declare module "sst" {
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
Api: cloudflare.Service
|
"Api": cloudflare.Service
|
||||||
AuthApi: cloudflare.Service
|
"AuthApi": cloudflare.Service
|
||||||
AuthStorage: cloudflare.KVNamespace
|
"AuthStorage": cloudflare.KVNamespace
|
||||||
Bucket: cloudflare.R2Bucket
|
"Bucket": cloudflare.R2Bucket
|
||||||
LogProcessor: cloudflare.Service
|
"LogProcessor": cloudflare.Service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
114
packages/function/sst-env.d.ts
vendored
114
packages/function/sst-env.d.ts
vendored
@@ -6,89 +6,73 @@
|
|||||||
import "sst"
|
import "sst"
|
||||||
declare module "sst" {
|
declare module "sst" {
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
ANTHROPIC_API_KEY: {
|
"AUTH_API_URL": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Linkable"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
AUTH_API_URL: {
|
"Console": {
|
||||||
type: "sst.sst.Linkable"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
value: string
|
"url": string
|
||||||
}
|
}
|
||||||
BASETEN_API_KEY: {
|
"Database": {
|
||||||
type: "sst.sst.Secret"
|
"database": string
|
||||||
value: string
|
"host": string
|
||||||
|
"password": string
|
||||||
|
"port": number
|
||||||
|
"type": "sst.sst.Linkable"
|
||||||
|
"username": string
|
||||||
}
|
}
|
||||||
Console: {
|
"GITHUB_APP_ID": {
|
||||||
type: "sst.cloudflare.SolidStart"
|
"type": "sst.sst.Secret"
|
||||||
url: string
|
"value": string
|
||||||
}
|
}
|
||||||
Database: {
|
"GITHUB_APP_PRIVATE_KEY": {
|
||||||
database: string
|
"type": "sst.sst.Secret"
|
||||||
host: string
|
"value": string
|
||||||
password: string
|
|
||||||
port: number
|
|
||||||
type: "sst.sst.Linkable"
|
|
||||||
username: string
|
|
||||||
}
|
}
|
||||||
FIREWORKS_API_KEY: {
|
"GITHUB_CLIENT_ID_CONSOLE": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_APP_ID: {
|
"GITHUB_CLIENT_SECRET_CONSOLE": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_APP_PRIVATE_KEY: {
|
"GOOGLE_CLIENT_ID": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_CLIENT_ID_CONSOLE: {
|
"HONEYCOMB_API_KEY": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_CLIENT_SECRET_CONSOLE: {
|
"STRIPE_SECRET_KEY": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GOOGLE_CLIENT_ID: {
|
"STRIPE_WEBHOOK_SECRET": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Linkable"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
HONEYCOMB_API_KEY: {
|
"Web": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.cloudflare.Astro"
|
||||||
value: string
|
"url": string
|
||||||
}
|
}
|
||||||
OPENAI_API_KEY: {
|
"ZEN_MODELS": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
|
||||||
STRIPE_SECRET_KEY: {
|
|
||||||
type: "sst.sst.Secret"
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
STRIPE_WEBHOOK_SECRET: {
|
|
||||||
type: "sst.sst.Linkable"
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
Web: {
|
|
||||||
type: "sst.cloudflare.Astro"
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
XAI_API_KEY: {
|
|
||||||
type: "sst.sst.Secret"
|
|
||||||
value: string
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// cloudflare
|
// cloudflare
|
||||||
import * as cloudflare from "@cloudflare/workers-types"
|
import * as cloudflare from "@cloudflare/workers-types";
|
||||||
declare module "sst" {
|
declare module "sst" {
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
Api: cloudflare.Service
|
"Api": cloudflare.Service
|
||||||
AuthApi: cloudflare.Service
|
"AuthApi": cloudflare.Service
|
||||||
AuthStorage: cloudflare.KVNamespace
|
"AuthStorage": cloudflare.KVNamespace
|
||||||
Bucket: cloudflare.R2Bucket
|
"Bucket": cloudflare.R2Bucket
|
||||||
LogProcessor: cloudflare.Service
|
"LogProcessor": cloudflare.Service
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
128
sst-env.d.ts
vendored
128
sst-env.d.ts
vendored
@@ -5,95 +5,79 @@
|
|||||||
|
|
||||||
declare module "sst" {
|
declare module "sst" {
|
||||||
export interface Resource {
|
export interface Resource {
|
||||||
ANTHROPIC_API_KEY: {
|
"AUTH_API_URL": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Linkable"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
AUTH_API_URL: {
|
"Api": {
|
||||||
type: "sst.sst.Linkable"
|
"type": "sst.cloudflare.Worker"
|
||||||
value: string
|
"url": string
|
||||||
}
|
}
|
||||||
Api: {
|
"AuthApi": {
|
||||||
type: "sst.cloudflare.Worker"
|
"type": "sst.cloudflare.Worker"
|
||||||
url: string
|
"url": string
|
||||||
}
|
}
|
||||||
AuthApi: {
|
"AuthStorage": {
|
||||||
type: "sst.cloudflare.Worker"
|
"type": "sst.cloudflare.Kv"
|
||||||
url: string
|
|
||||||
}
|
}
|
||||||
AuthStorage: {
|
"Bucket": {
|
||||||
type: "sst.cloudflare.Kv"
|
"name": string
|
||||||
|
"type": "sst.cloudflare.Bucket"
|
||||||
}
|
}
|
||||||
BASETEN_API_KEY: {
|
"Console": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.cloudflare.SolidStart"
|
||||||
value: string
|
"url": string
|
||||||
}
|
}
|
||||||
Bucket: {
|
"Database": {
|
||||||
name: string
|
"database": string
|
||||||
type: "sst.cloudflare.Bucket"
|
"host": string
|
||||||
|
"password": string
|
||||||
|
"port": number
|
||||||
|
"type": "sst.sst.Linkable"
|
||||||
|
"username": string
|
||||||
}
|
}
|
||||||
Console: {
|
"GITHUB_APP_ID": {
|
||||||
type: "sst.cloudflare.SolidStart"
|
"type": "sst.sst.Secret"
|
||||||
url: string
|
"value": string
|
||||||
}
|
}
|
||||||
Database: {
|
"GITHUB_APP_PRIVATE_KEY": {
|
||||||
database: string
|
"type": "sst.sst.Secret"
|
||||||
host: string
|
"value": string
|
||||||
password: string
|
|
||||||
port: number
|
|
||||||
type: "sst.sst.Linkable"
|
|
||||||
username: string
|
|
||||||
}
|
}
|
||||||
FIREWORKS_API_KEY: {
|
"GITHUB_CLIENT_ID_CONSOLE": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_APP_ID: {
|
"GITHUB_CLIENT_SECRET_CONSOLE": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_APP_PRIVATE_KEY: {
|
"GOOGLE_CLIENT_ID": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_CLIENT_ID_CONSOLE: {
|
"HONEYCOMB_API_KEY": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
GITHUB_CLIENT_SECRET_CONSOLE: {
|
"LogProcessor": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.cloudflare.Worker"
|
||||||
value: string
|
|
||||||
}
|
}
|
||||||
GOOGLE_CLIENT_ID: {
|
"STRIPE_SECRET_KEY": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
HONEYCOMB_API_KEY: {
|
"STRIPE_WEBHOOK_SECRET": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Linkable"
|
||||||
value: string
|
"value": string
|
||||||
}
|
}
|
||||||
LogProcessor: {
|
"Web": {
|
||||||
type: "sst.cloudflare.Worker"
|
"type": "sst.cloudflare.Astro"
|
||||||
|
"url": string
|
||||||
}
|
}
|
||||||
OPENAI_API_KEY: {
|
"ZEN_MODELS": {
|
||||||
type: "sst.sst.Secret"
|
"type": "sst.sst.Secret"
|
||||||
value: string
|
"value": string
|
||||||
}
|
|
||||||
STRIPE_SECRET_KEY: {
|
|
||||||
type: "sst.sst.Secret"
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
STRIPE_WEBHOOK_SECRET: {
|
|
||||||
type: "sst.sst.Linkable"
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
Web: {
|
|
||||||
type: "sst.cloudflare.Astro"
|
|
||||||
url: string
|
|
||||||
}
|
|
||||||
XAI_API_KEY: {
|
|
||||||
type: "sst.sst.Secret"
|
|
||||||
value: string
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user