Daydreams Logo
Advanced

Extensions

Building your own modular Daydreams extensions.

Extensions are the primary mechanism for packaging and distributing reusable Daydreams functionality. They bundle together contexts, actions, inputs, outputs, and the service providers they depend on.

Purpose

  • Encapsulate Features: Group all related components for a specific capability (e.g., Discord integration, ChromaDB support, a custom game interface).
  • Simplify Agent Configuration: Add complex features to an agent by simply including the extension in the createDreams configuration.
  • Promote Code Reuse: Share common functionalities across different agents.

Defining an Extension

Use the extension helper function exported from @daydreamsai/core:

import {
  extension,
  context,
  action,
  input,
  output,
  service,
  type AnyAgent, // Import necessary types
} from "@daydreamsai/core";
import { z } from "zod";
 
// Assume necessary components like myApiService, myFeatureContext, etc. are defined elsewhere
declare const myApiService: any;
declare const myFeatureContext: any;
declare const myFeatureAction: any;
 
export const myExtension = extension({
  // Required: A unique name for the extension
  name: "my-feature",
 
  // Optional: Service providers required by this extension's components.
  // These services will be registered and booted automatically.
  services: [myApiService],
 
  // Optional: Context definitions provided by this extension.
  // These become available for use with agent.run() / agent.send().
  contexts: {
    myFeature: myFeatureContext,
  },
 
  // Optional: Action definitions provided by this extension.
  // These become available for the LLM to call.
  actions: [myFeatureAction],
 
  // Optional: Input definitions provided by this extension.
  // Their 'subscribe' methods will be called on agent.start().
  inputs: {
    "my-feature:event": input({
      /* ... input definition ... */
      subscribe: (send, agent) => {
        /* ... listen and call send() ... */
      },
    }),
  },
 
  // Optional: Output definitions provided by this extension.
  // These become available for the LLM to use in <output> tags.
  outputs: {
    "my-feature:notify": output({
      /* ... output definition ... */
      handler: (data, ctx, agent) => {
        /* ... send notification ... */
      },
    }),
  },
 
  // Optional: Events defined by this extension (primarily for typing ctx.emit).
  events: {
    myEvent: z.object({ id: z.string() }),
  },
 
  // Optional: Logic to run once when the extension is added during agent.start().
  // Useful for one-time setup that doesn't fit the service 'boot' lifecycle.
  async install(agent: AnyAgent) {
    console.log("Installing My Feature Extension!");
    // Example: agent.container.resolve('logger').info(...)
  },
});

Usage and Lifecycle

  1. Configuration: Pass your extension instances to createDreams in the extensions array:

    import { createDreams } from "@daydreamsai/core";
    import { myExtension } from "./my-extension";
    import { discord } from "@daydreamsai/discord"; // Example built-in
     
    const agent = createDreams({
      model: /* ... */,
      extensions: [
        myExtension,
        discord, // Add other extensions
      ],
      // ... other agent config
    });
  2. Merging: When createDreams initializes, it iterates through the extensions array. For each extension, it merges the defined contexts, actions, inputs, outputs, and events into the agent's central registries, making them available for use.

  3. Service Registration: It automatically registers all services listed within each extension with the agent's ServiceManager.

  4. Installation & Booting: When agent.start() is called:

    • The install method of each extension is executed (if defined).
    • The ServiceManager boots all registered services (calling their boot methods, ensuring dependencies are ready).
    • Input subscribe methods are called to start listening for external events.

Extensions provide a powerful and organized way to structure agent capabilities, making it easy to combine built-in features with your own custom logic and integrations.

On this page