Comma Agents
@comma-agents/coreAgents

loadAgent

Load an agent from a JSON or YAML description file with schema validation and template support.

loadAgent reads a standalone built-in or registered custom agent description file (JSON or YAML), validates it against a strict schema, and returns a live Agent ready to call. For content already in memory, loadAgentFromString accepts a raw string directly.

import { loadAgent } from "@comma-agents/core";

const agent = await loadAgent("./agents/researcher.yaml");
const result = await agent.call("What is TypeScript?");
console.log(result.text);

Agent Description File

A description file defines a single agent — its name, model, optional system prompt, optional tools, and optional generation parameters. The schema is strict: unknown fields are rejected.

Model strings support two formats: explicit "providerID/modelID" (e.g. "openai/gpt-4o") or bare model IDs (e.g. "gpt-4o") where the provider is auto-resolved from the catalog. See Model Resolution for details.

YAML

name: researcher
model: openai/gpt-4o
systemPrompt: You are a research assistant.
tools:
  - read_file
  - search_files
providerOptions:
  openai:
    reasoningEffort: high
modelOptions:
  temperature: 0.7
  maxOutputTokens: 4096
outputSchema:
  type: object
  properties:
    answer:
      type: string
  required: [answer]
context:
  rollingWindow: 40
  compaction:
    keepRecent: 8

JSON

{
  "name": "researcher",
  "model": "openai/gpt-4o",
  "systemPrompt": "You are a research assistant.",
  "tools": ["read_file", "search_files"],
  "providerOptions": {
    "openai": { "reasoningEffort": "high" }
  },
  "modelOptions": {
    "temperature": 0.7,
    "maxOutputTokens": 4096
  },
  "outputSchema": {
    "type": "object",
    "properties": { "answer": { "type": "string" } },
    "required": ["answer"]
  },
  "context": {
    "rollingWindow": 40,
    "compaction": { "keepRecent": 8 }
  }
}

providerOptions

Provider-specific options applied to each model call. The outer key is the provider ID (for example, "openai" or "anthropic") and the inner record contains that provider's options.

providerOptions:
  anthropic:
    thinking: { type: enabled, budgetTokens: 8000 }
  openai:
    reasoningEffort: high

modelOptions

Provider-independent generation parameters applied to every call. Supported fields include temperature, topP, topK, maxOutputTokens, maxRetries, frequencyPenalty, presencePenalty, and seed. See AgentDescription below for the generated field types.

outputSchema

outputSchema is a JSON Schema object. It requests a structured object response that conforms to that schema.

context

context controls conversation retention before each model call. Use rollingWindow to keep only the most recent active records visible to the model, and compaction to summarize older active records while keeping the full record history available for export.

AgentDescriptionSchema

Zod schema used to validate agent description files. Requires name and model; everything else is optional.

Prop

Type

LoadAgentOptions

Options passed to loadAgent or loadAgentFromString.

Prop

Type

loadAgentFromString

When the description content is already in memory (e.g., from a database, WebSocket, or test fixture), use loadAgentFromString directly:

import { loadAgentFromString } from "@comma-agents/core";

const yaml = `
name: writer
model: openai/gpt-4o
systemPrompt: You are a creative writer.
`;

const agent = await loadAgentFromString(yaml, "yaml");
const result = await agent.call("Write a haiku about TypeScript.");

The format parameter must be "json" or "yaml". loadAgent auto-detects format from the file extension (.json, .yaml, .yml).

Registered Custom Agents

Register the custom type before loading its description:

import {
  createAgent,
  defineAgentType,
  loadAgent,
  registerAgent,
} from "@comma-agents/core";
import { z } from "zod";

registerAgent(
  "prefixed-echo",
  defineAgentType({
    configSchema: z.object({ prefix: z.string() }).strict(),
    create: ({ name, config }) =>
      createAgent({
        name,
        execute: async (message) => `${config.prefix}${message}`,
      }),
  }),
);

const agent = await loadAgent("./agents/echo.yaml");
name: echo
type: prefixed-echo
config:
  prefix: "Echo: "

The registered schema validates config. See createAgent for the registration API.

LLMAgentDescription

The standalone description for the built-in LLM agent type.

Prop

Type

CustomAgentDescription

The standalone description for a registered custom agent type.

Prop

Type

System Prompt Templates

Instead of a static systemPrompt, you can define a systemPromptTemplate using Liquid syntax with default variables. The loader converts it to a PromptTemplate automatically. When both systemPromptTemplate and systemPrompt are present, the template takes precedence.

See the Prompts & Templates documentation for the full template syntax, custom filters, and how to use updatePromptVariables to change defaults at runtime.

Model and Tool Resolution

Model and tool names in the description file are plain strings, such as "openai/gpt-4o" and "read_file". They resolve through the model, provider, and tool registries. Register custom providers, models, and tools before loading the agent.

Error Handling

Both loadAgent and loadAgentFromString throw StrategyValidationError for:

  • Unsupported file extensions (only .json, .yaml, .yml)
  • Missing files
  • Malformed JSON or YAML
  • Schema validation failures (missing required built-in fields, unknown fields, or wrong types)
  • Unknown registered agent types or invalid custom config
import { loadAgent, StrategyValidationError } from "@comma-agents/core";

try {
  const agent = await loadAgent("./agents/broken.yaml");
} catch (error) {
  if (error instanceof StrategyValidationError) {
    console.error("Invalid agent description:", error.message);
  }
}

On this page