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
3 changes: 2 additions & 1 deletion .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ jobs:
with:
node-version: 26

# Lockfiles are not committed (see .gitignore), so `npm ci` cannot run.
- name: πŸ“¦ Install dependencies
run: npm ci
run: npm install

- name: 🎭 Install Playwright browser
if: ${{ hashFiles('epicshop/test.js') != '' }}
Expand Down
6 changes: 3 additions & 3 deletions exercises/01.basic-setup/01.problem.chat-call/README.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ In `app/routes/api.chat.tsx`, two things are **already imported for you**:

You will not touch the imports. You will:

1. 🐨 Build the OpenRouter adapter by calling `openRouterText('openai/gpt-oss-120b:free')`. The adapter reads `OPENROUTER_API_KEY` from your environment by itself, so you do not pass the key in.
1. 🐨 Build the OpenRouter adapter by calling `openRouterText('nvidia/nemotron-3-super-120b-a12b:free')`. The adapter reads `OPENROUTER_API_KEY` from your environment by itself, so you do not pass the key in.
2. 🐨 Replace the body of the `action` so that it:
- Calls `await chatParamsFromRequest(request)` to parse and validate the AG-UI request body. On a malformed body it throws a `Response` with status 400 β€” React Router 7 surfaces that to the client automatically, so no `try/catch` needed.
- Destructures `messages` from the returned params.
Expand All @@ -33,7 +33,7 @@ OPENROUTER_API_KEY=your-key-here

## πŸ¦‰ About the model id

OpenRouter expects model ids that start with the provider name. We use `openai/gpt-oss-120b:free`, not just `gpt-oss-120b:free`. Other models follow the same pattern: `anthropic/claude-...`, `google/gemini-...`, and so on. The model is set when you call `openRouterText(...)`, so switching to a different model later is a one-line change.
OpenRouter expects model ids that start with the provider name. We use `nvidia/nemotron-3-super-120b-a12b:free`, not just `nemotron-3-super-120b-a12b:free`. Other models follow the same pattern: `anthropic/claude-...`, `google/gemini-...`, and so on. The model is set when you call `openRouterText(...)`, so switching to a different model later is a one-line change.

## πŸ¦‰ About `chatParamsFromRequest`

Expand All @@ -56,5 +56,5 @@ Open any product page, click the small chat bubble in the bottom-right corner, t
## 🚨 If you get stuck

- **`401` shows up in the red bubble** β†’ `OPENROUTER_API_KEY` is not loaded. Restart the dev server after you edit `.env`.
- **`400` shows up and the error mentions the model** β†’ the model id is wrong. It should be `openai/gpt-oss-120b:free`, not just `gpt-oss-120b:free`.
- **`400` shows up and the error mentions the model** β†’ the model id is wrong. It should be `nvidia/nemotron-3-super-120b-a12b:free`, not just `nemotron-3-super-120b-a12b:free`.
- **The server log shows a crash** β†’ check that you're calling `await chatParamsFromRequest(request)` (not `request.json()` directly) and `await`ing it.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { type Route } from './+types/api.chat'
* Resource route for the product chat backend.
*
* 🐨 Build an OpenRouter text adapter by calling
* `openRouterText('openai/gpt-oss-120b:free')`. The adapter reads
* `openRouterText('nvidia/nemotron-3-super-120b-a12b:free')`. The adapter reads
* `OPENROUTER_API_KEY` from your environment automatically.
* 🐨 In the action below:
* - Call `await chatParamsFromRequest(request)` to parse and validate
Expand Down
Loading
Loading