Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/happy-oyster/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ REACTOR_API_KEY=rk_your_api_key_here
# ── Local development only ───────────────────────────────────────────────────

# Point the app at a different Reactor API. Defaults to https://api.reactor.inc.
# NEXT_PUBLIC_COORDINATOR_URL=
# NEXT_PUBLIC_REACTOR_API_URL=

# Talk straight to a happy-oyster model served by the Reactor runtime (adventure
# on :8080, directing on :8081), skipping the Coordinator: no REACTOR_API_KEY and
Expand Down
12 changes: 6 additions & 6 deletions examples/happy-oyster/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pnpm dev

Open [http://localhost:3000](http://localhost:3000), pick a featured world or compose your own, and the app connects a Reactor session, builds (or attaches) the world, and drops you into the live travel.

The API key never reaches the browser: the server route [`app/api/reactor/token/route.ts`](app/api/reactor/token/route.ts) exchanges it for a short-lived JWT (see [docs.reactor.inc/authentication](https://docs.reactor.inc/authentication)), and the SDK re-fetches it (through the browser's HTTP cache) on every Coordinator call via the `getJwt` resolver.
The API key never reaches the browser: the server route [`app/api/reactor/token/route.ts`](app/api/reactor/token/route.ts) exchanges it for a short-lived JWT (see [docs.reactor.inc/authentication](https://docs.reactor.inc/authentication)), and the SDK re-fetches it (through the browser's HTTP cache) on every Reactor Platform call via the `getJwt` resolver.

## What you can do with it

Expand Down Expand Up @@ -66,11 +66,11 @@ Everything model-specific runs through the typed **`@reactor-models/happy-oyster

## Configuration

| Env var | Required | What it does |
| ------------------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REACTOR_API_KEY` | yes (live) | Server-side key exchanged for session JWTs by `app/api/reactor/token/route.ts`. |
| `NEXT_PUBLIC_COORDINATOR_URL` | no | Reactor API base URL. Defaults to `https://api.reactor.inc`. |
| `NEXT_PUBLIC_HO_LOCAL_RUNTIME` | no | Set to `1` to talk straight to a runtime-served model (adventure on `:8080`, directing on `:8081`), skipping the Coordinator: no `REACTOR_API_KEY`, no JWT. |
| Env var | Required | What it does |
| ------------------------------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `REACTOR_API_KEY` | yes (live) | Server-side key exchanged for session JWTs by `app/api/reactor/token/route.ts`. |
| `NEXT_PUBLIC_REACTOR_API_URL` | no | Reactor API base URL. Defaults to `https://api.reactor.inc`. |
| `NEXT_PUBLIC_HO_LOCAL_RUNTIME` | no | Set to `1` to talk straight to a runtime-served model (adventure on `:8080`, directing on `:8081`), skipping the Reactor Platform: no `REACTOR_API_KEY`, no JWT. |

If `REACTOR_API_KEY` is missing, the app renders a friendly setup landing instead of erroring (see [`app/SetupRequired.tsx`](app/SetupRequired.tsx)).

Expand Down
2 changes: 1 addition & 1 deletion examples/happy-oyster/app/api/reactor/token/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export async function GET() {
}

const baseUrl =
process.env.NEXT_PUBLIC_COORDINATOR_URL || "https://api.reactor.inc";
process.env.NEXT_PUBLIC_REACTOR_API_URL || "https://api.reactor.inc";

const res = await fetch(`${baseUrl}/tokens`, {
method: "POST",
Expand Down
15 changes: 8 additions & 7 deletions examples/happy-oyster/components/happy-oyster/ho-client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,19 @@ export function useVideoSlot(): ReactNode {
// ── live ─────────────────────────────────────────────────────────────────────

// Local mode talks to a model served by the Reactor runtime on your own host
// (adventure on :8080, directing on :8081), skipping the Coordinator: connect()
// takes no JWT and there is no /tokens exchange. `local` lets the SDK pick the
// right per-mode port; an explicit NEXT_PUBLIC_COORDINATOR_URL always wins.
// (adventure on :8080, directing on :8081), skipping the Reactor Platform:
// connect() takes no JWT and there is no /tokens exchange. `local` lets the
// SDK pick the right per-mode port; an explicit NEXT_PUBLIC_REACTOR_API_URL
// always wins.
const LOCAL_RUNTIME = process.env.NEXT_PUBLIC_HO_LOCAL_RUNTIME === "1";
const COORDINATOR_URL = process.env.NEXT_PUBLIC_COORDINATOR_URL;
const REACTOR_API_URL = process.env.NEXT_PUBLIC_REACTOR_API_URL;

// The Reactor connection options, minus the mode the provider is mounted with.
const providerOptions = LOCAL_RUNTIME
? { local: true, ...(COORDINATOR_URL ? { apiUrl: COORDINATOR_URL } : {}) }
: { apiUrl: COORDINATOR_URL ?? "https://api.reactor.inc" };
? { local: true, ...(REACTOR_API_URL ? { apiUrl: REACTOR_API_URL } : {}) }
: { apiUrl: REACTOR_API_URL ?? "https://api.reactor.inc" };

// JWT resolver: the SDK calls it on every Coordinator HTTP hop, so a short-lived
// JWT resolver: the SDK calls it on every Reactor Platform HTTP hop, so a short-lived
// token can't age out mid-session. The route caches the token, so most calls
// come back from the browser's HTTP cache without hitting the server.
async function fetchToken(): Promise<string> {
Expand Down
2 changes: 1 addition & 1 deletion examples/lingbot-world-2/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
REACTOR_API_KEY=rk_your_api_key_here

# Optional — Reactor API base URL. Defaults to https://api.reactor.inc
# NEXT_PUBLIC_COORDINATOR_URL=
# NEXT_PUBLIC_REACTOR_API_URL=
2 changes: 1 addition & 1 deletion examples/lingbot-world-2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ The model only ever sees a single prose string (`set_prompt`), but the app autho
| Env var | Required | What it does |
| ----------------------------- | -------- | ------------------------------------------------------------------------------- |
| `REACTOR_API_KEY` | yes | Server-side key exchanged for session JWTs by `app/api/reactor/token/route.ts`. |
| `NEXT_PUBLIC_COORDINATOR_URL` | no | Reactor API base URL. Defaults to `https://api.reactor.inc`. |
| `NEXT_PUBLIC_REACTOR_API_URL` | no | Reactor API base URL. Defaults to `https://api.reactor.inc`. |

If `REACTOR_API_KEY` is missing, the app renders a friendly setup landing instead of erroring — see [`app/SetupRequired.tsx`](app/SetupRequired.tsx).

Expand Down
6 changes: 3 additions & 3 deletions examples/lingbot-world-2/app/LingbotWorld2App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ import { Header } from "@/components/Header";
import { SnapClip } from "@/components/SnapClip";
import { LingbotWorldController } from "@/components/lingbot-world-2/LingbotWorldController";

// Reactor coordinator the SDK connects to. Override with
// NEXT_PUBLIC_COORDINATOR_URL in .env.local if you need a different one.
// Reactor Platform the SDK connects to. Override with
// NEXT_PUBLIC_REACTOR_API_URL in .env.local if you need a different one.
const API_URL =
process.env.NEXT_PUBLIC_COORDINATOR_URL ?? "https://api.reactor.inc";
process.env.NEXT_PUBLIC_REACTOR_API_URL ?? "https://api.reactor.inc";

// JWT resolver passed to <LingbotWorld2Provider getJwt>.
//
Expand Down
2 changes: 1 addition & 1 deletion examples/lingbot-world-2/app/api/reactor/token/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export async function GET() {
}

const baseUrl =
process.env.NEXT_PUBLIC_COORDINATOR_URL || "https://api.reactor.inc";
process.env.NEXT_PUBLIC_REACTOR_API_URL || "https://api.reactor.inc";

const res = await fetch(`${baseUrl}/tokens`, {
method: "POST",
Expand Down