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
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Create an RLLM instance with sensible defaults.
```typescript
const rlm = createRLLM({
model: 'gpt-4o-mini', // Model name
provider: 'openai', // 'openai' | 'anthropic' | 'gemini' | 'openrouter' | 'custom'
provider: 'openai', // 'openai' | 'anthropic' | 'gemini' | 'openrouter' | 'cerebras' | 'custom'
apiKey: process.env.KEY, // Optional, uses env vars by default
baseUrl: undefined, // Optional, required for 'custom' provider
verbose: true, // Enable logging
Expand All @@ -131,6 +131,23 @@ const rlm = createRLLM({

**Note:** When using `provider: 'custom'`, the `baseUrl` parameter is **required**. An error will be thrown if it's not provided.

### Cerebras Provider

Use Cerebras with the built-in `cerebras` provider:

```typescript
const rlm = createRLLM({
provider: 'cerebras',
model: 'gpt-oss-120b',
// optional if CEREBRAS_API_KEY is set
apiKey: process.env.CEREBRAS_API_KEY,
});
```

Defaults:
- API key env var: `CEREBRAS_API_KEY`
- Base URL: `https://api.cerebras.ai/v1`

### `RLLM` Methods

| Method | Description |
Expand Down
3 changes: 3 additions & 0 deletions examples/node-modules-viz/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,9 @@ Create a `.env` file:
```bash
OPENAI_API_KEY=your_key_here
MODEL=gpt-4o-mini # or gpt-4o, gpt-4-turbo, etc.
# Optional: switch provider (openai | anthropic | gemini | openrouter | cerebras)
# PROVIDER=cerebras
# CEREBRAS_API_KEY=your_key_here
```

## Tips
Expand Down
1 change: 1 addition & 0 deletions examples/node-modules-viz/server.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const apiKeyName = {
openai: 'OPENAI_API_KEY',
anthropic: 'ANTHROPIC_API_KEY',
openrouter: 'OPENROUTER_API_KEY',
cerebras: 'CEREBRAS_API_KEY',
}[provider] || 'API key';

const hasApiKey = provider === 'gemini'
Expand Down
21 changes: 19 additions & 2 deletions src/llm-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,31 @@ import { LLMClient } from "./llm-client.js";
// Test the provider configuration logic directly
// (extracted from LLMClient to make it testable)

function getDefaultApiKey(provider: "openai" | "anthropic" | "openrouter" | "custom"): string | undefined {
function getDefaultApiKey(provider: "openai" | "anthropic" | "openrouter" | "cerebras" | "custom"): string | undefined {
switch (provider) {
case "openai":
return process.env["OPENAI_API_KEY"];
case "anthropic":
return process.env["ANTHROPIC_API_KEY"];
case "openrouter":
return process.env["OPENROUTER_API_KEY"];
case "cerebras":
return process.env["CEREBRAS_API_KEY"];
case "custom":
return undefined;
}
}

function getDefaultBaseUrl(provider: "openai" | "anthropic" | "openrouter" | "custom"): string | undefined {
function getDefaultBaseUrl(provider: "openai" | "anthropic" | "openrouter" | "cerebras" | "custom"): string | undefined {
switch (provider) {
case "openai":
return undefined; // Uses default
case "anthropic":
return "https://api.anthropic.com/v1";
case "openrouter":
return "https://openrouter.ai/api/v1";
case "cerebras":
return "https://api.cerebras.ai/v1";
case "custom":
return undefined;
}
Expand All @@ -50,6 +54,10 @@ describe("LLMClient provider configuration", () => {
it("returns OpenRouter base URL", () => {
expect(getDefaultBaseUrl("openrouter")).toBe("https://openrouter.ai/api/v1");
});

it("returns Cerebras base URL", () => {
expect(getDefaultBaseUrl("cerebras")).toBe("https://api.cerebras.ai/v1");
});
});

describe("getDefaultApiKey", () => {
Expand Down Expand Up @@ -80,6 +88,15 @@ describe("LLMClient provider configuration", () => {
process.env["OPENROUTER_API_KEY"] = original;
});

it("reads CEREBRAS_API_KEY for cerebras provider", () => {
const original = process.env["CEREBRAS_API_KEY"];
process.env["CEREBRAS_API_KEY"] = "test-cerebras-key";

expect(getDefaultApiKey("cerebras")).toBe("test-cerebras-key");

process.env["CEREBRAS_API_KEY"] = original;
});

it("returns undefined for custom provider (must be provided explicitly)", () => {
expect(getDefaultApiKey("custom")).toBeUndefined();
});
Expand Down
4 changes: 4 additions & 0 deletions src/llm-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ export class LLMClient {
return process.env["GEMINI_API_KEY"] ?? process.env["GOOGLE_API_KEY"];
case "openrouter":
return process.env["OPENROUTER_API_KEY"];
case "cerebras":
return process.env["CEREBRAS_API_KEY"];
case "custom":
return undefined; // Must be provided explicitly
}
Expand All @@ -78,6 +80,8 @@ export class LLMClient {
return "https://generativelanguage.googleapis.com/v1beta/openai/";
case "openrouter":
return "https://openrouter.ai/api/v1";
case "cerebras":
return "https://api.cerebras.ai/v1";
case "custom":
return undefined; // Must be provided explicitly (validated in constructor)
}
Expand Down
2 changes: 1 addition & 1 deletion src/rlm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ export class RLLM {
*/
export function createRLLM(options: {
model?: string;
provider?: "openai" | "anthropic" | "gemini" | "openrouter" | "custom";
provider?: "openai" | "anthropic" | "gemini" | "openrouter" | "cerebras" | "custom";
apiKey?: string;
baseUrl?: string;
verbose?: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export type InferContextType<S> = S extends ZodType<infer T> ? T : string;
// LLM Client Types
// ============================================================================

export type LLMProvider = "openai" | "anthropic" | "gemini" | "openrouter" | "custom";
export type LLMProvider = "openai" | "anthropic" | "gemini" | "openrouter" | "cerebras" | "custom";

export interface ChatMessage {
role: "system" | "user" | "assistant" | "tool";
Expand Down