Yoke.sh
Agents

Inference

defineInferenceStack, LLM providers, model routing, failover, and ctx.llm.infer.

Yoke's inference layer provides a canonical LLM interface for processor actors. All providers accept and return InferenceMessage[] using the same body.parts schema as the conversation store.

InferenceMessage

type InferenceRole = "user" | "agent";

type InferenceMessage = {
  type: string;
  role: InferenceRole;
  body: MessageBody;  // { parts[], meta? }
};

Roles are derived at inference time (not stored on messages):

SourceRole
External shadow actors (ingested forum authors)user
tool_result partsuser
tool_call / reasoning / refusalagent
OtherwiseCompare author participant → agent actor id

defineInferenceStack

Register models, providers, and routing on the runtime builder:

import {
  defineInferenceStack,
  createOpenAiProvider,
  createAnthropicProvider,
  createFixtureProvider,
  defineRuntime,
} from "@yoke/sdk";

const inferenceStack = defineInferenceStack({
  models: {
    "gpt-4o": { id: "gpt-4o", contextWindow: 128_000 },
    "claude-sonnet-4": { id: "claude-sonnet-4", contextWindow: 200_000 },
    "fixture-echo": { id: "fixture-echo" },
  },
  providers: {
    fixture: createFixtureProvider(),
    openai: createOpenAiProvider({
      apiKey: Deno.env.get("OPENAI_API_KEY") ?? "",
    }),
    anthropic: createAnthropicProvider({
      apiKey: Deno.env.get("ANTHROPIC_API_KEY") ?? "",
    }),
  },
  routing: {
    "gpt-4o": ["openai", "fixture"],
    "claude-sonnet-4": ["anthropic"],
    "fixture-echo": ["fixture"],
  },
});

export default defineRuntime()
  .inferenceStack(inferenceStack)
  .actors(/* ... */);

Without .inferenceStack(), ctx.llm.infer() throws at runtime.

ctx.llm.infer

Inside processor process():

const outputs = await ctx.llm.infer(inputMessages, {
  model: ctx.config.model ?? "fixture-echo",
  temperature: 0.7,
  maxTokens: 1024,
  tools: resolvedTools,
});
OptionPurpose
modelLogical model name from stack
temperatureSampling temperature
maxTokensOutput token limit
toolsResolved tools/toolchains for this round

Returns InferenceMessage[] to post into the monologue.

Router behavior

The inference router handles:

  • Provider selection — first available in routing array for model
  • Round-robin — load balance across provider instances
  • Retries — transient failures
  • Failover — next provider in routing list (e.g. ["openai", "fixture"])

Providers

FactoryEnvUse
createOpenAiProviderOPENAI_API_KEYGPT models
createAnthropicProviderANTHROPIC_API_KEYClaude models
createFixtureProvidernoneTests, CI
createLocalToolLoopProvidernoneLocal tool demo loop
createSaysV1TestProvidernoneDeterministic test replies
createGuardianSteerTestProvidernoneGuardian angel E2E

Routing example

routing: {
  "local-tool-loop": ["local"],
  "fixture-echo": ["fixture"],
  "gpt-4o": ["openai", "fixture"],
  "claude-sonnet-4": ["anthropic"],
  "guardian-steer": ["guardian-steer"],
},

Join conversation with model: "local-tool-loop" for offline demos.

Processor integration

The processor reads monologue transcript → converts to InferenceMessage[] → optionally compacts → calls ctx.llm.infer → posts output parts to monologue.

One infer step per conversation.message.posted event — not a blocking while-loop. See Processor.

On this page