Daydreams Logo
Extra reading

types.ts

This file acts as the central dictionary for all the data structures used within the Daydreams framework. It defines the specific "shape" (using TypeScript types and interfaces) that different pieces of data should have, such as what information defines an Action, what goes into a Context, or what the Agent object looks like.

How to Use

You generally don't need to change this file. However, you'll interact with the types defined here frequently when writing your agent code:

  • Type Hints: When defining the handler for your action, input, or output, you'll often use types imported from @daydreamsai/core (which ultimately come from this file) to get auto-completion and type safety for the arguments passed to your function (like the args, ctx, and agent parameters).

    import {
      action,
      type ActionCallContext,
      type AnyAgent,
    } from "@daydreamsai/core";
    import { z } from "zod";
     
    // Define the memory structure for a specific context
    interface MyChatMemory {
      history: { role: "user" | "agent"; text: string }[];
    }
     
    // Use ActionCallContext with your memory type for the 'ctx' parameter
    export const myAction = action({
      name: "reply",
      schema: z.object({ message: z.string() }),
      handler: async (
        args,
        ctx: ActionCallContext<any, any, MyChatMemory>,
        agent: AnyAgent
      ) => {
        // Now, ctx.memory is correctly typed as MyChatMemory
        ctx.memory.history.push({ role: "agent", text: args.message });
        // agent parameter is typed as AnyAgent
      },
    });
  • Defining Memory: When you define a context, you'll often create an interface for its specific memory structure (like MyChatMemory above). This interface defines the shape of the data stored in ctx.memory for that context.

  • Understanding Logs: If you work with the detailed execution logs (agent.run results), the types like InputRef, OutputRef, ActionCall, ActionResult, Thought define the structure of each log entry.

Benefit

Using the types defined here makes your code safer and easier to write. Your code editor can provide helpful auto-completion and immediately warn you if you're using a component incorrectly (e.g., trying to access a property that doesn't exist on the ctx object or passing the wrong type of argument to an action). It acts as a form of documentation, clarifying what data is available where.

Anticipated Questions

  • "Do I need to import types directly from types.ts?" No, you should import types directly from the main package entry point: import type { Action, Context, Agent } from '@daydreamsai/core';.

  • "There are so many types! Which ones are most important?" The most common ones you'll likely encounter when building your agent are Agent, Context, Action, Input, Output, ActionCallContext, ContextState, WorkingMemory, MemoryStore, VectorStore, and the various Ref types (InputRef, OutputRef, etc.) if you inspect execution logs. Many others are for internal framework use.

  • "I see types like AnyAction. Is it easier to use those instead of specific ones like Action<MySchema, ...>?" While using AnyAction might seem simpler because you don't need to specify detailed types, it's generally not recommended, especially when starting out. Using specific types gives you significant advantages:

    1. Type Safety: TypeScript can check your code for errors before you run it (e.g., did you misspell a property name in ctx.memory? Are you using the action's args correctly?). AnyAction turns these checks off, leading to potential runtime bugs that are harder to find.
    2. Auto-completion: Your code editor can provide helpful suggestions for properties and methods when you use specific types, making coding faster and reducing typos. This doesn't work well with AnyAction.
    3. Clarity: Specific types make your code easier to understand for yourself and others. It clearly shows what data an action expects and uses.

    It's better practice to define Zod schemas for action arguments and interfaces for context memory, then use those in your definitions (e.g., Action<typeof mySchema, MyResult, MyMemoryInterface>).

On this page