Comma Agents
@comma-agents/coreStrategy

Loading

Parse, validate, and instantiate strategy files into runnable flows.

The strategy loader reads a JSON or YAML strategy, validates it against the schema, instantiates agents and flows, and returns a LoadedStrategy with a runnable entry flow.

loadStrategy

Load a strategy from a file path. The format is auto-detected from the file extension (.json, .yaml, .yml).

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

const strategy = await loadStrategy("./strategy.json");
console.log(strategy.name);    // "Code Review Pipeline"
console.log(strategy.version); // "1.0"

// Run the flow
const result = await strategy.flow.call("Review this function...");
console.log(result.text);

loadStrategyFromString

Load a strategy from a raw string when the content is already in memory — for example, received over a network or from a test fixture.

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

const json = `{
  "name": "Simple Q&A",
  "version": "1.0",
  "agents": {
    "assistant": {
      "model": "openai/gpt-4o",
      "systemPrompt": "Answer concisely."
    }
  },
  "flow": {
    "name": "Q&A",
    "type": "sequential",
    "steps": [{ "agent": "assistant" }]
  }
}`;

const strategy = await loadStrategyFromString(json, "json");
const result = await strategy.flow.call("What is TypeScript?");

YAML works the same way:

const yaml = `
name: Brainstorm
version: "1.0"
agents:
  optimist:
    model: openai/gpt-4o
    systemPrompt: Find 2 positive aspects of the idea.
  critic:
    model: openai/gpt-4o
    systemPrompt: Find 2 potential problems with the idea.
flow:
  name: Brainstorm
  type: broadcast
  steps:
    - agent: optimist
    - agent: critic
`;

const strategy = await loadStrategyFromString(yaml.trim(), "yaml");

Options

Both loadStrategy and loadStrategyFromString accept an options object.

LoadStrategyOptions

Prop

Type

Model Override

Override the model for every LLM agent in the strategy, regardless of what the file specifies:

const strategy = await loadStrategy("./strategy.json", {
  modelOverride: "anthropic/claude-sonnet-4-20250514",
});

Flow Hooks

Inject hooks into all flows after construction:

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

const strategy = await loadStrategy("./strategy.json", {
  flowHooks: {
    onStepComplete: [
      async (result) => console.log("Step done:", result.agent.name),
    ],
  },
});

User Agent Input

If the strategy contains user agents with requireInput: true, provide an input collector:

const strategy = await loadStrategy("./strategy.json", {
  inputCollector: async () => {
    return prompt("Enter your question: ") ?? "";
  },
});

LoadedStrategy

The result of loading a strategy.

Prop

Type

The flow field is a standard runnable flow — call it with .call() or .stream(), or attach additional hooks via hookIntoFlow.

The agents map provides access to the instantiated agents for inspection or attaching hooks via hookIntoAgent.

The raw field contains the validated strategy data, used by exportStrategy for round-trip serialization.

Model and Tool Resolution

Models, tools, flows, and custom agent types are resolved via global registries. Before loading a strategy, ensure the required implementations are registered:

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

// Register a provider so "openai/gpt-4o" resolves
registerProvider("openai", (modelId) => openai(modelId));

// Register a custom tool so "weather" resolves in strategy files
registerTool("weather", weatherTool);

// Register a custom agent so "prefixed-echo" resolves in strategy files
registerAgent(
  "prefixed-echo",
  defineAgentType({
    configSchema: z.object({ prefix: z.string() }).strict(),
    create: ({ name, config }) =>
      createAgent({
        name,
        execute: async (message) => `${config.prefix}${message}`,
      }),
  }),
);

const strategy = await loadStrategy("./strategy.json");

Built-in agent types (llm and user) and built-in tools are available automatically and do not need registration.

On this page