Jay V 5 месяцев назад
Родитель
Сommit
c141b88087

+ 36 - 45
cloud/app/src/routes/index.css

@@ -78,22 +78,22 @@
 
   [data-component="cta"] {
     border-top: 2px solid var(--color-border);
-    display: grid;
-    grid-template-columns: auto 1fr auto;
-    align-items: stretch;
+    display: flex;
 
     & > div + div {
       border-left: 2px solid var(--color-border);
     }
 
-    [data-slot="left"],
-    [data-slot="right"] {
+    [data-slot="left"] {
+      flex: 0 0 auto;
       text-align: center;
       line-height: 1.4;
       padding: var(--vertical-padding) 2rem;
       text-transform: uppercase;
+      font-size: 1.125rem;
 
       @media (max-width: 30rem) {
+        font-size: 1rem;
         padding-bottom: calc(var(--vertical-padding) + 4px);
       }
 
@@ -103,53 +103,18 @@
       }
     }
 
-    [data-slot="center"] {
+    [data-slot="right"] {
+      flex: 1;
       padding: var(--vertical-padding) 1rem;
     }
 
-    @media (max-width: 55rem) {
-      display: grid;
-      grid-template-columns: 1fr 1fr;
-      grid-template-rows: auto auto;
-
-      [data-slot="left"] {
-        grid-column: 1;
-        grid-row: 1;
-      }
+    @media (max-width: 50rem) {
+      flex-direction: column;
 
       [data-slot="right"] {
-        grid-column: 2;
-        grid-row: 1;
-      }
-
-      [data-slot="center"] {
-        grid-column: 1 / -1;
-        grid-row: 2;
         border-left: none;
         border-top: 2px solid var(--color-border);
       }
-
-      @media (max-width: 22rem) {
-        grid-template-columns: 1fr;
-        grid-template-rows: auto auto auto;
-
-        [data-slot="left"] {
-          grid-column: 1;
-          grid-row: 1;
-        }
-
-        [data-slot="right"] {
-          grid-column: 1;
-          grid-row: 2;
-          border-top: 2px solid var(--color-border);
-          border-left: none;
-        }
-
-        [data-slot="center"] {
-          grid-column: 1;
-          grid-row: 3;
-        }
-      }
     }
 
     [data-slot="command"] {
@@ -168,7 +133,7 @@
         @media (max-width: 24rem) {
           font-size: 0.875rem;
         }
-        @media (max-width: 64rem) {
+        @media (max-width: 56rem) {
           [data-slot="protocol"] {
             display: none;
           }
@@ -188,6 +153,32 @@
     }
   }
 
+  [data-component="zen"] {
+    border-top: 2px solid var(--color-border);
+    text-align: center;
+    font-size: 1.125rem;
+    padding: var(--vertical-padding) 2rem;
+
+    @media (max-width: 30rem) {
+      font-size: 1rem;
+      padding-left: 1rem;
+      padding-right: 1rem;
+    }
+
+    a[target="_self"] {
+      text-transform: uppercase;
+    }
+
+    [data-slot="description"] {
+      color: var(--color-text-secondary);
+    }
+
+    [data-slot="divider"] {
+      font-weight: bold;
+      color: var(--color-border);
+    }
+  }
+
   [data-component="features"] {
     border-top: 2px solid var(--color-border);
     padding: var(--padding);

+ 25 - 9
cloud/app/src/routes/index.tsx

@@ -11,6 +11,7 @@ import { createAsync, query, redirect } from "@solidjs/router"
 import { getActor } from "~/context/auth"
 import { withActor } from "~/context/auth.withActor"
 import { Account } from "@opencode/cloud-core/account.js"
+import { Show } from "solid-js"
 
 function CopyStatus() {
   return (
@@ -26,13 +27,13 @@ const isLoggedIn = query(async () => {
   const actor = await getActor()
   if (actor.type === "account") {
     const workspaces = await withActor(() => Account.workspaces())
-    throw redirect(`/workspace/${workspaces[0].id}`)
+    return workspaces[0].id
+    // throw redirect(`/workspace/${workspaces[0].id}`)
   }
-  return false
 }, "isLoggedIn")
 
 export default function Home() {
-  createAsync(() => isLoggedIn(), {
+  const workspaceId = createAsync(() => isLoggedIn(), {
     deferStream: true,
   })
   onMount(() => {
@@ -69,7 +70,7 @@ export default function Home() {
           <div data-slot="left">
             <a href="/docs">Get Started</a>
           </div>
-          <div data-slot="center">
+          <div data-slot="right">
             <button data-copy data-slot="command">
               <span>
                 <span>curl -fsSL&nbsp;</span>
@@ -80,13 +81,28 @@ export default function Home() {
               <CopyStatus />
             </button>
           </div>
-          <div data-slot="right">
-            <a href="/auth/authorize" target="_self">
-              Login
-            </a>
-          </div>
         </section>
 
+        <Show when={false}>
+          <section data-component="zen">
+            <a href="/docs/zen">opencode zen</a>
+            <span data-slot="description">
+              , a curated list of models provided by opencode
+            </span>
+            <span data-slot="divider">&nbsp;/&nbsp;</span>
+            <a
+              href={
+                workspaceId()
+                  ? `/workspace/${workspaceId()}`
+                  : "/auth/authorize"
+              }
+              target="_self"
+            >
+              Sign in
+            </a>
+          </section>
+        </Show>
+
         <section data-component="features">
           <ul data-slot="list">
             <li>

+ 3 - 3
cloud/app/src/routes/workspace/[id].tsx

@@ -63,7 +63,7 @@ const createPortalUrl = action(async (returnUrl: string) => {
   return withActor(() => Billing.generatePortalUrl({ returnUrl }))
 }, "portalUrl")
 
-export default function () {
+export default function() {
 
   /////////////////
   // Keys section
@@ -180,9 +180,9 @@ export default function () {
     <div data-slot="root">
       {/* Title */}
       <section data-slot="title-section">
-        <h1>Gateway</h1>
+        <h1>opencode zen</h1>
         <p>
-          Coding models optimized for use with opencode. <a href="/docs">Learn more</a>.
+          Curated list of models provided by opencode. <a href="/docs/zen">Learn more</a>.
         </p>
       </section>
 

+ 9 - 1
packages/web/astro.config.mjs

@@ -67,7 +67,15 @@ export default defineConfig({
 
         {
           label: "Usage",
-          items: ["docs/tui", "docs/cli", "docs/ide", "docs/share", "docs/github", "docs/gitlab"],
+          items: [
+            "docs/tui",
+            "docs/cli",
+            "docs/ide",
+            // "docs/zen",
+            "docs/share",
+            "docs/github",
+            "docs/gitlab"
+          ],
         },
 
         {

+ 4 - 0
packages/web/config.mjs

@@ -4,6 +4,10 @@ export default {
   url: stage === "production"
     ? "https://opencode.ai"
     : `https://${stage}.opencode.ai`,
+  console: stage === "production"
+    ? "https://console.opencode.ai"
+    : `https://console.${stage}.opencode.ai`,
+  email: "[email protected]",
   socialCard: "https://social-cards.sst.dev",
   github: "https://github.com/sst/opencode",
   discord: "https://opencode.ai/discord",

+ 5 - 2
packages/web/src/content/docs/docs/enterprise.mdx

@@ -3,13 +3,16 @@ title: Enterprise
 description: Using opencode in your organization.
 ---
 
+import config from "../../../../config.mjs"
+export const email = `mailto:${config.email}`
+
 opencode does not store any of your code or context data. This makes it easy for
 you to use opencode at your organization.
 
 To get started, we recommend:
 
 1. Do a trial internally with your team.
-2. [**Contact us**](mailto:[email protected]) to discuss pricing and implementation options.
+2. **<a href={email}>Contact us</a>** to discuss pricing and implementation options.
 
 ---
 
@@ -55,7 +58,7 @@ We recommend you disable this for your trial.
 ## Deployment
 
 Once you have completed your trial and you are ready to self-host opencode at
-your organization, you can [**contact us**](mailto:[email protected]) to discuss
+your organization, you can **<a href={email}>contact us</a>** to discuss
 pricing and implementation options.
 
 ---

+ 170 - 111
packages/web/src/content/docs/docs/providers.mdx

@@ -3,6 +3,9 @@ title: Providers
 description: Using any LLM provider in opencode.
 ---
 
+import config from "../../../../config.mjs"
+export const console = config.console
+
 opencode uses the [AI SDK](https://ai-sdk.dev/) and [Models.dev](https://models.dev) to support for **75+ LLM providers** and it supports running local models.
 
 To add a provider you need to:
@@ -45,123 +48,21 @@ You can customize the base URL for any provider by setting the `baseURL` option.
 
 ---
 
-## Custom provider
+## opencode zen
 
-To add any **OpenAI-compatible** provider that's not listed in `opencode auth login`:
+opencode zen is a list of models provided by the opencode team that have been
+tested and verified to work well with opencode. [Learn more](/docs/zen).
 
 :::tip
-You can use any OpenAI-compatible provider with opencode. Most modern AI providers offer OpenAI-compatible APIs.
+If you are new, we recommend starting with opencode zen.
 :::
 
-1. Run `opencode auth login` and scroll down to **Other**.
-
-   ```bash
-   $ opencode auth login
-
-   ┌  Add credential
-   │
-   ◆  Select provider
-   │  ...
-   │  ● Other
-   └
-   ```
-
-2. Enter a unique ID for the provider.
-
-   ```bash
-   $ opencode auth login
-
-   ┌  Add credential
-   │
-   ◇  Enter provider id
-   │  myprovider
-   └
-   ```
-
-   :::note
-   Choose a memorable ID, you'll use this in your config file.
-   :::
-
-3. Enter your API key for the provider.
-
-   ```bash
-   $ opencode auth login
-
-   ┌  Add credential
-   │
-   ▲  This only stores a credential for myprovider - you will need configure it in opencode.json, check the docs for examples.
-   │
-   ◇  Enter your API key
-   │  sk-...
-   └
-   ```
-
-4. Create or update your `opencode.json` file in your project directory:
-
-   ```json title="opencode.json" ""myprovider"" {5-15}
-   {
-     "$schema": "https://opencode.ai/config.json",
-     "provider": {
-       "myprovider": {
-         "npm": "@ai-sdk/openai-compatible",
-         "name": "My AI ProviderDisplay Name",
-         "options": {
-           "baseURL": "https://api.myprovider.com/v1"
-         },
-         "models": {
-           "my-model-name": {
-             "name": "My Model Display Name"
-           }
-         }
-       }
-     }
-   }
-   ```
-
-   Here are the configuration options:
-
-   - **npm**: AI SDK package to use, `@ai-sdk/openai-compatible` for OpenAI-compatible providers
-   - **name**: Display name in UI.
-   - **models**: Available models.
-   - **options.baseURL**: API endpoint URL.
-   - **options.apiKey**: Optionally set the API key, if not using auth.
-   - **options.headers**: Optionally set custom headers.
-
-   More on the advanced options in the example below.
-
-5. Run the `/models` command and your custom provider and models will appear in the selection list.
-
----
-
-##### Example
-
-Here's an example setting the `apiKey` and `headers` options.
-
-```json title="opencode.json" {9,11}
-{
-  "$schema": "https://opencode.ai/config.json",
-  "provider": {
-    "myprovider": {
-      "npm": "@ai-sdk/openai-compatible",
-      "name": "My AI ProviderDisplay Name",
-      "options": {
-        "baseURL": "https://api.myprovider.com/v1",
-        "apiKey": "{env:ANTHROPIC_API_KEY}",
-        "headers": {
-          "Authorization": "Bearer custom-token"
-        }
-      },
-      "models": {
-        "my-model-name": {
-          "name": "My Model Display Name"
-        }
-      }
-    }
-  }
-}
-```
+1. You sign in to **<a href={console}>opencode zen</a>** and get your API key.
+2. You run `opencode auth login` and select opencode zen and add your API key.
+3. Run `/models` in the TUI to see the list of models we recommend.
 
-We are setting the `apiKey` using the `env` variable syntax, [learn more](/docs/config#env-vars).
+It works like any other provider in opencode. And is completely optional to use
+it.
 
 ---
 
@@ -648,6 +549,44 @@ In this example:
 
 ---
 
+### opencode zen
+
+opencode zen is a list of tested and verified models provided by the opencode team. [Learn more](/docs/zen).
+
+1. Sign in to **<a href={console}>opencode zen</a>** and click **Create API Key**.
+
+2. Run `opencode auth login` and select **opencode zen**.
+
+   ```bash
+   $ opencode auth login
+
+   ┌  Add credential
+   │
+   ◆  Select provider
+   │  ● opencode zen
+   │  ...
+   └
+   ```
+
+3. Enter your opencode API key.
+
+   ```bash
+   $ opencode auth login
+
+   ┌  Add credential
+   │
+   ◇  Select provider
+   │  opencode zen
+   │
+   ◇  Enter your API key
+   │  _
+   └
+   ```
+
+4. Run the `/models` command to select a model like _Qwen 3 Coder 480B_.
+
+---
+
 ### OpenRouter
 
 1. Head over to the [OpenRouter dashboard](https://openrouter.ai/settings/keys), click **Create API Key**, and copy the key.
@@ -812,6 +751,126 @@ monitor and improve Grok Code.
 
 ---
 
+## Custom provider
+
+To add any **OpenAI-compatible** provider that's not listed in `opencode auth login`:
+
+:::tip
+You can use any OpenAI-compatible provider with opencode. Most modern AI providers offer OpenAI-compatible APIs.
+:::
+
+1. Run `opencode auth login` and scroll down to **Other**.
+
+   ```bash
+   $ opencode auth login
+
+   ┌  Add credential
+   │
+   ◆  Select provider
+   │  ...
+   │  ● Other
+   └
+   ```
+
+2. Enter a unique ID for the provider.
+
+   ```bash
+   $ opencode auth login
+
+   ┌  Add credential
+   │
+   ◇  Enter provider id
+   │  myprovider
+   └
+   ```
+
+   :::note
+   Choose a memorable ID, you'll use this in your config file.
+   :::
+
+3. Enter your API key for the provider.
+
+   ```bash
+   $ opencode auth login
+
+   ┌  Add credential
+   │
+   ▲  This only stores a credential for myprovider - you will need configure it in opencode.json, check the docs for examples.
+   │
+   ◇  Enter your API key
+   │  sk-...
+   └
+   ```
+
+4. Create or update your `opencode.json` file in your project directory:
+
+   ```json title="opencode.json" ""myprovider"" {5-15}
+   {
+     "$schema": "https://opencode.ai/config.json",
+     "provider": {
+       "myprovider": {
+         "npm": "@ai-sdk/openai-compatible",
+         "name": "My AI ProviderDisplay Name",
+         "options": {
+           "baseURL": "https://api.myprovider.com/v1"
+         },
+         "models": {
+           "my-model-name": {
+             "name": "My Model Display Name"
+           }
+         }
+       }
+     }
+   }
+   ```
+
+   Here are the configuration options:
+
+   - **npm**: AI SDK package to use, `@ai-sdk/openai-compatible` for OpenAI-compatible providers
+   - **name**: Display name in UI.
+   - **models**: Available models.
+   - **options.baseURL**: API endpoint URL.
+   - **options.apiKey**: Optionally set the API key, if not using auth.
+   - **options.headers**: Optionally set custom headers.
+
+   More on the advanced options in the example below.
+
+5. Run the `/models` command and your custom provider and models will appear in the selection list.
+
+---
+
+##### Example
+
+Here's an example setting the `apiKey` and `headers` options.
+
+```json title="opencode.json" {9,11}
+{
+  "$schema": "https://opencode.ai/config.json",
+  "provider": {
+    "myprovider": {
+      "npm": "@ai-sdk/openai-compatible",
+      "name": "My AI ProviderDisplay Name",
+      "options": {
+        "baseURL": "https://api.myprovider.com/v1",
+        "apiKey": "{env:ANTHROPIC_API_KEY}",
+        "headers": {
+          "Authorization": "Bearer custom-token"
+        }
+      },
+      "models": {
+        "my-model-name": {
+          "name": "My Model Display Name"
+        }
+      }
+    }
+  }
+}
+```
+
+We are setting the `apiKey` using the `env` variable syntax, [learn more](/docs/config#env-vars).
+
+---
+
 ## Troubleshooting
 
 If you are having trouble with configuring a provider, check the following:

+ 95 - 0
packages/web/src/content/docs/docs/zen.mdx

@@ -0,0 +1,95 @@
+---
+title: Zen
+description: Curated list of models provided by opencode.
+---
+
+import config from "../../../../config.mjs"
+export const console = config.console
+export const email = `mailto:${config.email}`
+
+opencode zen is a list of tested and verified models provided by the opencode team.
+
+:::note
+opencode zen is currently in beta.
+:::
+
+Zen works like any other provider in opencode. You login to opencode zen and get
+your API key. It's **completely optional** and you don't need to use it to use
+opencode.
+
+---
+
+## Background
+
+There are a large number of models out there but only a few of
+these models work well as coding agents. Additionally, most providers are
+configured very differently; so you get very different performance and quality.
+
+:::tip
+We tested a select group of models and providers that work well with opencode.
+:::
+
+So if you are using a model through something like OpenRouter, you can never be
+sure if you are getting the best version of the model you want.
+
+To fix this, we did a couple of things:
+
+1. We tested a select group of models and talked to their teams about how to
+   best run them.
+2. We then worked with a few providers to make sure these were being served
+   correctly.
+3. Finally, we benchmarked the combination of the model/provider and came up
+   with a list that we feel good recommending.
+
+opencode zen is an AI gateway that gives you access to these models.
+
+---
+
+## Motivation
+
+We created opencode zen to:
+
+1. **Benchmark** the best models/providers for coding agents.
+2. Access to **highest quality**; we don't downgrade performance or route to cheaper providers.
+3. **Sell at cost**; the only markup is to cover our processing fees and any price
+   drops will be passed along.
+4. **No lock-in**; you can use opencode zen with any other coding agent and you
+   can use any other provider with opencode.
+
+---
+
+## How it works
+
+opencode zen works like any other provider in opencode.
+
+1. You sign in to **<a href={console}>opencode zen</a>** and get your API key.
+2. You run `opencode auth login` and select opencode zen and add your API key.
+3. Run `/models` in the TUI to see the list of models we recommend.
+
+You are charged per request and you can add credits to your account.
+
+---
+
+## Pricing
+
+Below are the models that we currently support and their prices **per 1M
+tokens**.
+
+| Model | Input | Output |
+| ----- | ----- | ------ |
+| Qwen3 Coder 480B | $0.38 | $0.50 |
+| Grok Code Fast 1 | Free | Free |
+| Sonnet 4 | Soon | Soon |
+
+:::note
+We add a small markup to cover our costs.
+:::
+
+A couple of notes:
+
+- These are the raw prices based on the provider we are using internally. We
+charge a small markup on top of this to cover our processing fees.
+- Grok Code Fast 1 is currently free on opencode till Sep 10th. The xAI team is
+  using this time to collect feedback and improve Grok Code.
+
+<a href={email}>Contact us</a> if you have any questions.