Skip to content
/ sdk Public

RelayPlane SDK provides a unified interface for routing AI model calls across providers with automatic fallback, optimization, and cost control.

Notifications You must be signed in to change notification settings

RelayPlane/sdk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@relayplane/sdk

The local-first AI workflow engine. Switch providers without rewriting your app.

npm version License: MIT

Install

npm install @relayplane/sdk

Quick Start

import { relay } from "@relayplane/sdk";

const result = await relay
  .workflow("content-pipeline")
  .step("draft")
  .with("openai:gpt-4.1")
  .prompt("Write a blog post about {{input.topic}}")
  .step("review")
  .with("anthropic:claude-sonnet-4-5-20250929")
  .prompt("Improve this draft for clarity and engagement")
  .depends("draft")
  .run({ topic: "AI workflows" });

console.log(result.steps.review);

That's it. Runs locally with your API keys. No gateway. No surprises.

Switch Providers in One Line

// OpenAI
.with("openai:gpt-4.1")

// Anthropic
.with("anthropic:claude-sonnet-4-5-20250929")

// Google
.with("google:gemini-2.5-flash")

// xAI
.with("xai:grok-4")

// Local (Ollama)
.with("local:llama3.3")

Same code. Same response format. Change one string.

Why RelayPlane?

Without RelayPlane With RelayPlane
Different SDK for each provider One SDK, every provider
Rewrite code to switch models Change one string
Silent model changes break production Explicit provider:model — what you write runs
DIY retry, fallback, caching Built-in reliability
Observability is an afterthought Telemetry from day one
Tool calls need separate plumbing MCP steps native in workflows

Complete Example

import { relay } from "@relayplane/sdk";
import { z } from "zod";

const InvoiceSchema = z.object({
  invoiceNumber: z.string(),
  vendor: z.string(),
  totalAmount: z.number(),
  items: z.array(z.object({
    description: z.string(),
    quantity: z.number(),
    unitPrice: z.number(),
  })),
});

const result = await relay
  .workflow("invoice-processor")

  // Step 1: Extract structured data
  .step("extract", {
    schema: InvoiceSchema,
    systemPrompt: "Extract all invoice fields as structured JSON.",
  })
  .with("openai:gpt-4.1")

  // Step 2: Validate with a different model
  .step("validate", {
    systemPrompt: "Verify totals and flag discrepancies.",
  })
  .with("anthropic:claude-sonnet-4-5-20250929")
  .depends("extract")

  // Step 3: Generate summary
  .step("summarize")
  .with("openai:gpt-5-mini")
  .prompt("Create executive summary for finance approval.")
  .depends("validate")

  .run({ fileUrl: "https://example.com/invoice.pdf" });

console.log(result.steps.extract);   // Typed as InvoiceSchema
console.log(result.steps.summarize);

MCP Tool Integration

Mix AI steps with external tools using the Model Context Protocol:

relay.configure({
  mcp: {
    servers: {
      crm: { url: "http://localhost:3100" },
      github: { url: "http://localhost:3101" },
    },
  },
});

const result = await relay
  .workflow("lead-enrichment")

  // AI step: Extract company name
  .step("extract")
  .with("openai:gpt-4.1")
  .prompt("Extract the company name from: {{input.email}}")

  // MCP step: Look up in CRM
  .step("lookup")
  .mcp("crm:searchCompany")
  .params({ name: "{{steps.extract.companyName}}" })
  .depends("extract")

  // AI step: Generate personalized outreach
  .step("outreach")
  .with("anthropic:claude-sonnet-4-5-20250929")
  .prompt("Write a personalized email using this CRM data: {{steps.lookup}}")
  .depends("lookup")

  .run({ email: "jane@acme.com" });

Configuration

Environment Variables (Recommended)

OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GOOGLE_API_KEY=...
XAI_API_KEY=...

Programmatic

relay.configure({
  providers: {
    openai: { apiKey: process.env.OPENAI_API_KEY },
    anthropic: { apiKey: process.env.ANTHROPIC_API_KEY },
  },
});

Per-Run Override

await relay
  .workflow("example")
  .step("test").with("openai:gpt-4.1")
  .run(input, {
    providers: {
      openai: { apiKey: "sk-override-key" },
    },
  });

Supported Providers

Provider Example Models Format
OpenAI GPT-5.2, GPT-4.1, o3 openai:gpt-5.2
Anthropic Claude Opus 4.5, Sonnet 4.5, Haiku 4.5 anthropic:claude-sonnet-4-5-20250929
Google Gemini 3 Pro, Gemini 2.5 Flash google:gemini-2.5-flash
xAI Grok 4, Grok 3 Mini xai:grok-4
Perplexity Sonar Pro, Sonar Reasoning perplexity:sonar-pro
Local Any Ollama model local:llama3.3

Note: Use exact model IDs from each provider. See relayplane.com/docs/providers for the complete list of supported models.

API Reference

Workflow Builder

relay
  .workflow("name")           // Create workflow
  .step("stepName", config?)  // Add step
  .with("provider:model")     // Set AI model
  .prompt("text")             // Set prompt
  .mcp("server:tool")         // Or use MCP tool
  .params({ ... })            // MCP parameters
  .depends("step1", "step2")  // Declare dependencies
  .webhook("https://...")     // Add webhook (cloud)
  .schedule("0 9 * * *")      // Add schedule (cloud)
  .run(input, options?)       // Execute

Builder Chain Order

The SDK uses phantom types for compile-time safety. This means methods must be called in a specific order:

AI Steps:

.step() → .with() → [.prompt() | .depends() | .step() | .run()]

MCP Steps:

.step() → .mcp() → .params() → [.depends() | .step() | .run()]

Key constraints:

  • After .prompt(), you cannot call .depends() — call .depends() before .prompt() if needed
  • After .mcp(), you must call .params() before .step() or .run()
  • TypeScript will enforce these constraints at compile time

Example: Correct ordering

// AI step with dependencies - call .depends() before .prompt()
.step("review")
.with("anthropic:claude-sonnet-4-5-20250929")
.depends("extract")                    // Dependencies first
.prompt("Review the extracted data")   // Prompt last

// MCP step - .params() is required after .mcp()
.step("lookup")
.mcp("crm:searchCompany")
.params({ name: "{{steps.extract.company}}" })
.depends("extract")

Step Config

.step("name", {
  schema: ZodSchema,           // Structured output validation
  systemPrompt: "...",         // System prompt
  userPrompt: "...",           // User prompt
  retry: { maxAttempts: 3 },   // Retry config
  metadata: { ... },           // Custom metadata
})

Result

const result = await workflow.run(input);

result.success        // boolean
result.steps          // { stepName: output, ... }
result.finalOutput    // Last step's output
result.error          // { message, stepName, cause }
result.metadata       // { workflowName, startTime, endTime, duration }

Error Handling

const result = await relay
  .workflow("example")
  .step("process").with("openai:gpt-4.1")
  .run(input);

if (!result.success) {
  console.error(`Failed at step: ${result.error.stepName}`);
  console.error(result.error.message);
}

TypeScript: Typed Results with Schemas

import { z } from "zod";

const UserSchema = z.object({
  name: z.string(),
  email: z.string().email(),
});

const result = await relay
  .workflow("extract-user")
  .step("extract", { schema: UserSchema })
  .with("openai:gpt-4.1")
  .run({ text: "Contact: John at john@example.com" });

// result.steps.extract is typed as { name: string; email: string }
console.log(result.steps.extract.name);

Cloud Features (Optional)

Webhooks & Schedules

await relay
  .workflow("daily-report")
  .schedule("0 9 * * *")
  .webhook("https://slack.com/webhook/...")
  .step("generate").with("openai:gpt-4.1")
  .run(input);

Key-Value Store

// Store data across runs
await relay.kv.set("user:settings", { theme: "dark" });
const settings = await relay.kv.get("user:settings");

// With TTL
await relay.kv.set("cache:data", data, { ttl: 3600 });

Backup & Restore

const backupId = await relay.backup.create({
  name: "daily-backup",
  includes: { workflows: true, configs: true },
});

await relay.backup.restore({ backupId, mode: "merge" });

Pricing: Free tier available. Pro ($99/mo) unlocks webhooks & schedules.

BYOK (Bring Your Own Keys)

RelayPlane never proxies your API calls. Your keys talk directly to providers.

  • No markup on API costs
  • No usage fees beyond providers
  • Your data stays between you and the provider

CLI

npx relay login      # Authenticate (optional)
npx relay status     # Check connection
npx relay dashboard  # Open web dashboard
npx relay logout     # Sign out

Links

License

MIT

About

RelayPlane SDK provides a unified interface for routing AI model calls across providers with automatic fallback, optimization, and cost control.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •