ignore: zen

This commit is contained in:
Jay V
2025-09-02 17:28:32 -04:00
parent 023c4532c1
commit c141b88087
8 changed files with 347 additions and 171 deletions

View File

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

View File

@@ -11,6 +11,7 @@ import { createAsync, query, redirect } from "@solidjs/router"
import { getActor } from "~/context/auth" import { getActor } from "~/context/auth"
import { withActor } from "~/context/auth.withActor" import { withActor } from "~/context/auth.withActor"
import { Account } from "@opencode/cloud-core/account.js" import { Account } from "@opencode/cloud-core/account.js"
import { Show } from "solid-js"
function CopyStatus() { function CopyStatus() {
return ( return (
@@ -26,13 +27,13 @@ const isLoggedIn = query(async () => {
const actor = await getActor() const actor = await getActor()
if (actor.type === "account") { if (actor.type === "account") {
const workspaces = await withActor(() => Account.workspaces()) 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") }, "isLoggedIn")
export default function Home() { export default function Home() {
createAsync(() => isLoggedIn(), { const workspaceId = createAsync(() => isLoggedIn(), {
deferStream: true, deferStream: true,
}) })
onMount(() => { onMount(() => {
@@ -69,7 +70,7 @@ export default function Home() {
<div data-slot="left"> <div data-slot="left">
<a href="/docs">Get Started</a> <a href="/docs">Get Started</a>
</div> </div>
<div data-slot="center"> <div data-slot="right">
<button data-copy data-slot="command"> <button data-copy data-slot="command">
<span> <span>
<span>curl -fsSL&nbsp;</span> <span>curl -fsSL&nbsp;</span>
@@ -80,13 +81,28 @@ export default function Home() {
<CopyStatus /> <CopyStatus />
</button> </button>
</div> </div>
<div data-slot="right">
<a href="/auth/authorize" target="_self">
Login
</a>
</div>
</section> </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"> <section data-component="features">
<ul data-slot="list"> <ul data-slot="list">
<li> <li>

View File

@@ -63,7 +63,7 @@ const createPortalUrl = action(async (returnUrl: string) => {
return withActor(() => Billing.generatePortalUrl({ returnUrl })) return withActor(() => Billing.generatePortalUrl({ returnUrl }))
}, "portalUrl") }, "portalUrl")
export default function () { export default function() {
///////////////// /////////////////
// Keys section // Keys section
@@ -180,9 +180,9 @@ export default function () {
<div data-slot="root"> <div data-slot="root">
{/* Title */} {/* Title */}
<section data-slot="title-section"> <section data-slot="title-section">
<h1>Gateway</h1> <h1>opencode zen</h1>
<p> <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> </p>
</section> </section>

View File

@@ -67,7 +67,15 @@ export default defineConfig({
{ {
label: "Usage", 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"
],
}, },
{ {

View File

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

View File

@@ -3,13 +3,16 @@ title: Enterprise
description: Using opencode in your organization. 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 opencode does not store any of your code or context data. This makes it easy for
you to use opencode at your organization. you to use opencode at your organization.
To get started, we recommend: To get started, we recommend:
1. Do a trial internally with your team. 1. Do a trial internally with your team.
2. [**Contact us**](mailto:contact@anoma.ly) 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 ## Deployment
Once you have completed your trial and you are ready to self-host opencode at Once you have completed your trial and you are ready to self-host opencode at
your organization, you can [**contact us**](mailto:contact@anoma.ly) to discuss your organization, you can **<a href={email}>contact us</a>** to discuss
pricing and implementation options. pricing and implementation options.
--- ---

View File

@@ -3,6 +3,9 @@ title: Providers
description: Using any LLM provider in opencode. 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. 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: 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 :::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**. 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.
```bash It works like any other provider in opencode. And is completely optional to use
$ opencode auth login it.
┌ 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).
--- ---
@@ -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 ### OpenRouter
1. Head over to the [OpenRouter dashboard](https://openrouter.ai/settings/keys), click **Create API Key**, and copy the key. 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 ## Troubleshooting
If you are having trouble with configuring a provider, check the following: If you are having trouble with configuring a provider, check the following:

View File

@@ -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.