JSPM

@fancyrobot/fred

2.0.0-alpha.0
    • ESM via JSPM
    • ES Module Entrypoint
    • Export Map
    • Keywords
    • License
    • Repository URL
    • TypeScript Types
    • README
    • Created
    • Published
    • Downloads 349
    • Score
      100M100P100Q59942F
    • License MIT

    Fred AI agent framework - core package

    Package Exports

    • @fancyrobot/fred
    • @fancyrobot/fred/context/postgres
    • @fancyrobot/fred/context/sqlite
    • @fancyrobot/fred/effect
    • @fancyrobot/fred/eval
    • @fancyrobot/fred/mcp/registry
    • @fancyrobot/fred/mcp/types
    • @fancyrobot/fred/messages
    • @fancyrobot/fred/stream
    • @fancyrobot/fred/tool/tool
    • @fancyrobot/fred/tools

    Readme

    @fancyrobot/fred

    npm version TypeScript AI agent framework with intent-based routing and pipeline orchestration.

    Installation

    bun add @fancyrobot/fred effect

    Add at least one provider package:

    Quick Start

    Recommended workflow: markdown agent files (.md) + config.yaml.

    1) Create an agent file

    Create src/agents/assistant.md:

    ---
    id: assistant
    platform: openrouter
    model: openrouter/auto
    utterances:
      - hello
      - help
    ---
    
    You are a concise, practical assistant.

    2) Create config.yaml

    providers:
      - id: openrouter
        type: openrouter
    
    agentDirs:
      - ./src/agents
    
    routing:
      defaultAgent: assistant
      rules: []

    3) Initialize and send a message

    import { Fred } from '@fancyrobot/fred';
    import '@fancyrobot/fred-openrouter';
    
    const fred = await Fred.create();
    await fred.initializeFromConfig('config.yaml');
    
    const response = await fred.processMessage('Hello Fred!', {
      conversationId: 'quickstart',
    });
    
    console.log(response.content);
    await fred.shutdown();

    Programmatic alternative (secondary)

    const fred = new Fred();
    fred.registerDefaultProviders();
    await fred.createAgent({
      id: 'assistant',
      systemMessage: 'You are concise and helpful.',
      platform: 'openrouter',
      model: 'openrouter/auto',
    });
    fred.setDefaultAgent('assistant');
    await fred.processMessage('What can you do?');

    Agents

    Agent files use YAML frontmatter for runtime configuration and markdown body for the prompt.

    ---
    id: support-agent
    platform: openai
    model: gpt-4o
    tools:
      - calculator
    utterances:
      - billing
      - invoice
      - /refund/i
    ---
    
    You are a billing specialist.
    Explain charges clearly and ask for missing details.
    • Configure discovery directories with agentDirs and keep agents in src/agents

    Programmatic Agents

    await fred.createAgent({
      id: 'triage',
      systemMessage: 'Route requests to the right specialist.',
      platform: 'anthropic',
      model: 'claude-sonnet-4-20250514',
      tools: ['calculator'],
      utterances: ['urgent', 'outage', /priority/i],
    });

    ETA Templates

    Prompts support ETA templating for expressions, conditionals, loops, and partials. See the Examples section for end-to-end patterns.

    Tools

    import { Schema } from 'effect';
    
    fred.registerTool({
      id: 'weather',
      name: 'weather',
      description: 'Get weather for a city',
      schema: {
        input: Schema.Struct({ city: Schema.String }),
        success: Schema.String,
        metadata: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'] },
      },
      execute: async ({ city }) => `Sunny in ${city}`,
    });

    Legacy JSON Schema

    fred.registerTool({
      id: 'lookup-order',
      name: 'lookup-order',
      description: 'Get order status by ID',
      parameters: {
        type: 'object',
        properties: {
          orderId: { type: 'string' },
        },
        required: ['orderId'],
      },
      execute: async ({ orderId }) => `Order ${orderId}: in transit`,
    });

    Fred also includes a built-in calculator tool via @fancyrobot/fred/tools.

    Intent Routing

    intents:
      - id: billing
        utterances: [billing, invoice, /refund/i]
        action:
          type: agent
          target: billing-agent
    
    routing:
      defaultAgent: billing-agent
      rules: []

    Priority: utterances -> intents -> routing.defaultAgent.

    Pipelines

    Sequential Pipelines

    import { PipelineBuilder } from '@fancyrobot/fred';
    
    const pipeline = new PipelineBuilder('classify-plan-summarize')
      .addAgentStep('classifier')
      .addAgentStep('planner')
      .addAgentStep('summarizer')
      .build();
    
    await fred.createPipeline({ ...pipeline, checkpoint: { enabled: true } });
    const result = await fred.executePipeline('classify-plan-summarize', 'Draft launch checklist');
    console.log(result.finalOutput);

    Graph Workflows

    import { GraphWorkflowBuilder } from '@fancyrobot/fred';
    
    const workflow = new GraphWorkflowBuilder('research-flow')
      .addNode('classifier', { type: 'agent', agentId: 'classifier' })
      .addNode('factual', { type: 'agent', agentId: 'researcher' })
      .addNode('creative', { type: 'agent', agentId: 'ideator' })
      .addNode('merge', { type: 'agent', agentId: 'synthesizer' })
      .addEdge('classifier', 'factual')
      .setDefaultEdge('classifier', 'creative')
      .addEdge('factual', 'merge')
      .addEdge('creative', 'merge')
      .setEntry('classifier')
      .build();
    
    fred.registerGraphWorkflow(workflow);

    Checkpoints and Pause/Resume

    const resumed = await fred.resume(runId, {
      humanInput: 'approve',
      resumeBehavior: 'continue',
    });

    Hooks

    Fred exposes 21 hook points across the message lifecycle.

    fred.registerHook('beforeMessageReceived', async (event) => {
      if (typeof event.data !== 'string') return;
      return { data: event.data.replace(/secret/gi, '[REDACTED]') };
    });
    
    fred.registerHook('afterResponseGenerated', async (event) => {
      console.log('Generated response:', event.data);
    });

    Configuration

    YAML Config

    providers:
      - id: openai
        type: openai
    
    agentDirs:
      - ./src/agents
    
    agents:
      - id: fallback-agent
        systemMessage: ./prompts/fallback.md
        platform: openai
        model: gpt-4o
    
    intents:
      - id: refunds
        utterances: [refund, chargeback]
        action:
          type: agent
          target: support-agent
    
    routing:
      defaultAgent: fallback-agent
      rules: []

    Config API

    await fred.initializeFromConfig('config.yaml');

    Context and Persistence

    SQLite (local development)

    import { SqliteContextStorage } from '@fancyrobot/fred/context/sqlite';
    
    const fred = new Fred({
      storage: new SqliteContextStorage({ path: './fred.db' }),
    });

    Postgres (production)

    import { PostgresContextStorage } from '@fancyrobot/fred/context/postgres';
    
    const fred = new Fred({
      storage: new PostgresContextStorage({
        connectionString: process.env.FRED_POSTGRES_URL,
      }),
    });

    Providers

    Provider Package Env Variable
    OpenAI @fancyrobot/fred-openai OPENAI_API_KEY
    Anthropic @fancyrobot/fred-anthropic ANTHROPIC_API_KEY
    Google @fancyrobot/fred-google GOOGLE_GENERATIVE_AI_API_KEY
    Groq @fancyrobot/fred-groq GROQ_API_KEY
    OpenRouter @fancyrobot/fred-openrouter OPENROUTER_API_KEY
    MiniMax @fancyrobot/fred-minimax MINIMAX_API_KEY

    Advanced: Effect Services

    Fred is built on Effect and exposes service tags for custom Layer composition.

    import { Effect, Runtime } from 'effect';
    import {
      FredLayers,
      AgentService,
      PipelineService,
      ProviderRegistryService,
    } from '@fancyrobot/fred';
    
    const program = Effect.gen(function* () {
      const providers = yield* ProviderRegistryService;
      const agents = yield* AgentService;
      const pipelines = yield* PipelineService;
    
      return {
        providers: yield* providers.listProviders(),
        agents: yield* agents.listAgents(),
        pipelines: yield* pipelines.listPipelines(),
      };
    }).pipe(Effect.provide(FredLayers));
    
    const result = await Runtime.runPromise(Runtime.defaultRuntime)(program);
    console.log(result);

    Use this path when you need low-level service control or custom runtime wiring.

    Examples

    See examples/README.md for the 12-example learning path covering quickstart, tools, routing, pipelines, hooks, observability, evaluation, MCP integration, and CLI/TUI workflows.

    License

    MIT