Documentation - v1.2.0-alpha.3
    Preparing search index...

    Class AgentStatePropertyAccessor<T>

    Provides typed access to an Agent state property with automatic state loading and persistence management.

    AgentStatePropertyAccessor simplifies working with persisted state by abstracting the complexity of loading state from storage and manipulating specific properties. It provides a type-safe interface for state management with automatic handling of:

    • Lazy Loading: State is loaded from storage only when first accessed
    • Type Safety: Full TypeScript support with generic type parameters
    • Default Values: Automatic deep cloning of default values to prevent reference issues
    • Memory Management: Efficient in-memory caching with explicit persistence control
    • Custom Keys: Support for custom storage keys for advanced scenarios

    Key features of AgentStatePropertyAccessor include:

    The accessor provides compile-time type checking when using TypeScript:

    interface UserProfile {
    name: string;
    preferences: { theme: string; language: string };
    }
    const userProfile = userState.createProperty<UserProfile>("userProfile");

    When a property doesn't exist, default values are automatically cloned and stored:

    // If userProfile doesn't exist, the default will be cloned and saved
    const profile = await userProfile.get(context, {
    name: "Anonymous",
    preferences: { theme: "light", language: "en" }
    });

    Changes are kept in memory until explicitly persisted:

    // Modify the state
    const counter = await counterProperty.get(context, 0);
    await counterProperty.set(context, counter + 1);

    // Changes are only in memory at this point
    // Persist to storage
    await userState.saveChanges(context);
    // Create a property accessor
    const userProfile = userState.createProperty<UserProfile>("userProfile");

    // Get with default value
    const profile = await userProfile.get(context, {
    name: "",
    preferences: { theme: "light", language: "en" }
    });

    // Modify the profile
    profile.preferences.theme = "dark";

    // Save the changes
    await userProfile.set(context, profile);
    await userState.saveChanges(context); // Persist to storage
    const counterProperty = userState.createProperty<number>("counter");

    // Increment counter
    const currentCount = await counterProperty.get(context, 0);
    await counterProperty.set(context, currentCount + 1);
    await userState.saveChanges(context);
    const settingsProperty = userState.createProperty<Settings>("settings");

    // Check if property exists
    const settings = await settingsProperty.get(context);
    if (settings === undefined) {
    // Property doesn't exist, initialize with defaults
    await settingsProperty.set(context, getDefaultSettings());
    }
    // Store state with a custom key for multi-tenant scenarios
    const customKey = { key: `tenant_${tenantId}` };
    const tenantData = await dataProperty.get(context, defaultData, customKey);
    await dataProperty.set(context, updatedData, customKey);
    • Thread Safety: This class is not thread-safe. Ensure proper synchronization in concurrent scenarios.
    • Memory Usage: State objects are kept in memory until the context is disposed.
    • Persistence: Always call state.saveChanges(context) to persist changes to storage.
    • Deep Cloning: Default values are deep cloned using JSON serialization, which may not work with complex objects containing functions or circular references.

    Type Parameters

    • T = any

      The type of the property being accessed. Can be any serializable type.

    Implements

    Index

    Constructors

    Properties

    Methods

    Constructors

    • Creates a new instance of AgentStatePropertyAccessor.

      Type Parameters

      • T = any

        The type of the property being accessed. Can be any serializable type.

      Parameters

      • state: AgentState

        The agent state object that manages the backing storage for this property

      • name: string

        The unique name of the property within the state object. This name is used as the key in the state storage.

      Returns AgentStatePropertyAccessor<T>

      This constructor is typically not called directly. Instead, use AgentState.createProperty to create property accessors, which ensures proper integration with the state management system.

      // Recommended way - use AgentState.createProperty
      const userProfile = userState.createProperty<UserProfile>("userProfile");

      // Direct construction (not recommended)
      const accessor = new AgentStatePropertyAccessor<UserProfile>(userState, "userProfile");

    Properties

    name: string

    The unique name of the property within the state object. This name is used as the key in the state storage.

    state: AgentState

    The agent state object that manages the backing storage for this property

    Methods

    • Deletes the property from the state storage.

      Parameters

      • context: TurnContext

        The turn context for the current conversation turn

      • OptionalcustomKey: CustomKey

        Optional custom key for accessing state in a specific storage location. Useful for multi-tenant scenarios or when state needs to be partitioned.

      Returns Promise<void>

      A promise that resolves when the delete operation is complete

      This operation removes the property from the in-memory state object but does not automatically persist the change to the underlying storage. You must call state.saveChanges(context) afterwards to persist the deletion.

      • If the property doesn't exist, this operation is a no-op
      • The deletion only affects the in-memory state until saveChanges() is called
      • After deletion, subsequent get() calls will return undefined (or the default value if provided)
      const userSettings = userState.createProperty<UserSettings>("settings");

      // Delete the user settings
      await userSettings.delete(context);

      // Persist the deletion to storage
      await userState.saveChanges(context);

      // Verify deletion
      const settings = await userSettings.get(context); // Returns undefined
      const tenantKey = { key: `tenant_${tenantId}` };
      await userSettings.delete(context, tenantKey);
      await userState.saveChanges(context);
    • Retrieves the value of the property from state storage.

      Parameters

      • context: TurnContext

        The turn context for the current conversation turn

      • OptionaldefaultValue: T

        Optional default value to use if the property doesn't exist. When provided, this value is deep cloned and stored in state.

      • OptionalcustomKey: CustomKey

        Optional custom key for accessing state in a specific storage location. Useful for multi-tenant scenarios or when state needs to be partitioned.

      Returns Promise<T>

      A promise that resolves to the property value, the cloned default value, or undefined

      This method provides intelligent default value handling:

      • If the property exists, its value is returned
      • If the property doesn't exist and a default value is provided, the default is deep cloned, stored in state, and returned
      • If the property doesn't exist and no default is provided, undefined is returned

      Deep Cloning: Default values are deep cloned using JSON serialization to prevent reference sharing issues. This means:

      • Functions, symbols, and circular references will be lost
      • Dates become strings (use Date constructor to restore)
      • Complex objects with prototypes lose their prototype chain

      Performance: The first access loads state from storage; subsequent accesses use the in-memory cached version until the context is disposed.

      const counterProperty = userState.createProperty<number>("counter");

      // Get with default value
      const count = await counterProperty.get(context, 0);
      console.log(count); // 0 if property doesn't exist, otherwise the stored value
      interface UserProfile {
      name: string;
      preferences: { theme: string; notifications: boolean };
      }

      const userProfile = userState.createProperty<UserProfile>("profile");
      const profile = await userProfile.get(context, {
      name: "Anonymous",
      preferences: { theme: "light", notifications: true }
      });
      const profile = await userProfile.get(context);
      if (profile === undefined) {
      console.log("Profile has not been set yet");
      } else {
      console.log(`Welcome back, ${profile.name}!`);
      }
      const tenantKey = { key: `tenant_${tenantId}` };
      const tenantData = await dataProperty.get(context, defaultData, tenantKey);
    • Sets the value of the property in state storage.

      Parameters

      • context: TurnContext

        The turn context for the current conversation turn

      • value: T

        The value to assign to the property. Can be any serializable value.

      • OptionalcustomKey: CustomKey

        Optional custom key for accessing state in a specific storage location. Useful for multi-tenant scenarios or when state needs to be partitioned.

      Returns Promise<void>

      A promise that resolves when the set operation is complete

      This operation updates the property in the in-memory state object but does not automatically persist the change to the underlying storage. You must call state.saveChanges(context) afterwards to persist the changes.

      Memory vs Storage: Changes are immediately reflected in memory and will be available to subsequent get() calls within the same context, but are not persisted to storage until saveChanges() is called.

      Value References: The exact value reference is stored (no cloning occurs). Ensure you don't modify objects after setting them unless you intend for those changes to be reflected in state.

      Type Safety: When using TypeScript, the value must match the property's declared type parameter.

      const counterProperty = userState.createProperty<number>("counter");

      // Set a new value
      await counterProperty.set(context, 42);

      // Persist to storage
      await userState.saveChanges(context);
      const userProfile = userState.createProperty<UserProfile>("profile");

      const newProfile: UserProfile = {
      name: "John Doe",
      preferences: { theme: "dark", notifications: false }
      };

      await userProfile.set(context, newProfile);
      await userState.saveChanges(context);
      // Get current value, modify, then set
      const settings = await settingsProperty.get(context, getDefaultSettings());
      settings.theme = "dark";
      settings.lastUpdated = new Date();

      await settingsProperty.set(context, settings);
      await userState.saveChanges(context);
      const tenantKey = { key: `tenant_${tenantId}` };
      await dataProperty.set(context, updatedData, tenantKey);
      await userState.saveChanges(context);