> ## Documentation Index
> Fetch the complete documentation index at: https://koreai.mintlify.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Memory and State

Agents on the platform use two kinds of memory: session memory and persistent memory.

Learn how to declare, access, and manage session variables, persistent memory, and set up auto-recall using the ABL Editor.

## Key Concepts

| Concept                                                                                  | Description                                                                                                                                                                |
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Session Memory](#session-memory)                                                        | Declare and use variables that hold data within a single conversation — collected values, flags, and intermediate results that are discarded when the session ends.        |
| [Persistent Memory](#persistent-memory)                                                  | Store facts that survive across sessions, such as user preferences and history. Covers user-scoped, project-scoped and execution-tree scoped variables and access control. |
| [Recall](#recall)                                                                        | Automatically loads values from persistent memory into session context at lifecycle events like session start or before a search.                                          |
| [Remember Triggers]()                                                                    | Automatically stores values into persistent memory when a condition is met.                                                                                                |
| [Manipulate State: SET, CLEAR, and TRANSFORM](#manipulate-state-set-clear-and-transform) | Assign values, remove variables, and reshape data arrays during flow execution using `SET`, `CLEAR`, and `TRANSFORM` directives.                                           |
| [Best Practices](#best-practices)                                                        | Recommended patterns for naming variables, providing fallback values, and managing reset behavior.                                                                         |

## Session Memory

Session variables hold data that is relevant only during a single conversation. They are created when the session starts and discarded when the session ends (unless RESET: never is specified).

### Declare session variables

Add a `MEMORY:` block with a `session:` section to your agent definition in the ABL editor.

```yaml theme={null}
AGENT: Booking_Agent
GOAL: "Help users book hotels"

MEMORY:
  session:
    - selected_booking
      TYPE: string
      DESCRIPTION: "The booking ID the customer is currently managing"
    - action_type
      TYPE: string
      DESCRIPTION: "What the customer wants to do"
    - pending_changes
      TYPE: object
      DESCRIPTION: "Proposed changes awaiting confirmation"
    - quoted_fee
      TYPE: number
      DESCRIPTION: "Fee quoted for the pending modification"
```

**Session Variable Properties**

| Property    | Type                                                   | Required | Description                                                                         |
| ----------- | ------------------------------------------------------ | -------- | ----------------------------------------------------------------------------------- |
| name        | string                                                 | Yes      | Variable name, used as the key in session context.                                  |
| TYPE        | string \| number \| boolean \| date \| array \| object | No       | Value type for runtime validation and field resolution.                             |
| DESCRIPTION | string                                                 | No       | Human-readable description of the variable's purpose.                               |
| INITIAL     | any                                                    | No       | Initial value assigned when the session starts. Initial value is `null` by default. |
| RESET       | per\_session \| per\_step \| never                     | No       | When to reset the variable. Default is `per_session`. See Reset behavior.           |

**Reset Behavior**

| Value           | Behavior                                                                                                            |
| --------------- | ------------------------------------------------------------------------------------------------------------------- |
| per\_session    | Variable is initialized at session start and cleared when the session ends. This is the default.                    |
| per\_step       | Variable is reset to its initial value at the start of each flow step. Useful for step-scoped accumulators.         |
| never           | Variable persists for the lifetime of the runtime process. Use sparingly; prefer persistent memory instead.         |
| per\_activation | Variable is reset to `INITIAL` every time the agent is activated, including repeated activations of the same agent. |

For simple tracking without type metadata, declare a bare name:

```yaml theme={null}
MEMORY:
  session:
    - customer_id
    - order_total
```

Fields with initial values and reset control:

```yaml theme={null}
MEMORY:
  session:
    - cart_items
      TYPE: array
      DESCRIPTION: "Items currently in the shopping cart"
      INITIAL: []
      RESET: per_session
    - attempt_count
      TYPE: number
      INITIAL: 0
      RESET: per_step
```

### Access session variables in response templates

Reference session variables by name inside `{{ }}` in `RESPOND` blocks.

```yaml theme={null}
FLOW:
  confirm_booking:
    REASONING: false
    RESPOND: |
      Booking summary:
      Hotel: {{selected_hotel.name}}
      Guest: {{guest_name}}
      Total: ${{quoted_fee}}
    THEN: COMPLETE
```

### Access session variables in step conditions

Use session variables in `CHECK`, constraint expressions, and `ON_INPUT` transition logic.

```yaml theme={null}
FLOW:
  check_eligibility:
    REASONING: false
    CHECK: attempt_count < 3
    ON_FAIL: too_many_attempts
    THEN: process_request
```

### Troubleshooting

* **Variable is undefined in template.** The variable has not been set yet in the current flow. Ensure the step that sets it executes before the step that reads it.
* **Variable resets unexpectedly.** Check `RESET`. Variables with `RESET: per_step` clear at each step transition. Use `per_session` or `never` for longer-lived values.
* **Type mismatch at runtime.** `TYPE` enables runtime validation. If you declare `TYPE: number` but assign a string, the runtime logs a warning. Coerce tool results and user inputs to the declared type.

***

## Persistent Memory

Persistent variables are stored in the platform's fact store and survive across sessions. Persistent memory fields are scoped to a user, a execution chain or an entire project.

### Declare persistent variables

Add a `persistent:` section under `MEMORY:`. Use dot-notation paths to name each variable and bind them to a scope.

```yaml theme={null}
AGENT: Support_Agent
GOAL: "Help customers with personalized support"

MEMORY:
  persistent:
    - user.preferred_language
    - user.loyalty_tier
      SCOPE: user
    - user.booking_history
      SCOPE: user
      TYPE: array
      DESCRIPTION: "Recent booking history"
    - user.notification_preference
      TYPE: string
      DEFAULT: "email"
      SCOPE: user
```

**Persistent Variable Properties**

| Property    | Type                                                   | Required | Default   | Description                                                                                                                                                                                                         |
| ----------- | ------------------------------------------------------ | -------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| path        | string                                                 | Yes      | --        | Dot-notation path (e.g., user.preferred\_chains), where the first segment indicates the scope(user, project or workflow) and second indicates the name of the field.                                                |
| SCOPE       | user \| project \| execution\_tree                     | No       | user      | Ownership scope. user is per-user; project is shared across all users. execution\_tree is for an entire execution workflow across agents. If this scope differs from the scope in the path, scope takes precedence. |
| ACCESS      | read \| write \| readwrite                             | No       | readwrite | Access direction. Constrains whether the agent can read, write, or both.                                                                                                                                            |
| TYPE        | string \| number \| boolean \| date \| array \| object | No       | --        | Value type for runtime validation.                                                                                                                                                                                  |
| UNIT        | string                                                 | No       | --        | Unit of the stored value (e.g., USD, km). Informational metadata only.                                                                                                                                              |
| DEFAULT     | any                                                    | No       | null      | Default value when no fact exists in the store.                                                                                                                                                                     |
| DESCRIPTION | string                                                 | No       | --        | Human-readable description.                                                                                                                                                                                         |

### Scoping rules

| Scope                                         | Description                                                                                                                                                                        |
| --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| User scope (SCOPE: user)                      | Values are unique per authenticated user. Two users in the same project see different values for the same path.                                                                    |
| Project scope (SCOPE: project)                | Values are shared across all users within the project. Useful for reference data, feature flags, or global configuration.                                                          |
| Execution-tree scope (SCOPE: execution\_tree) | Values are shared across one workflow / handoff tree only. This is the preferred scope for cross-agent state such as auth tokens, selected account IDs, or in-flight case context. |

```yaml theme={null}
MEMORY:
  persistent:
    - user.preferred_chains
      SCOPE: user
      DESCRIPTION: "User's preferred hotel chains"

    - user.wire_history_30d
      SCOPE: user
      TYPE: array
      ACCESS: readwrite
      DEFAULT: []

    - project.exchange_rates
      SCOPE: project
      ACCESS: read
      DESCRIPTION: "Current exchange rates (shared across all users)"
```

### Access Control

Restrict whether the agent can read, write, or both for each persistent path.

```yaml theme={null}
MEMORY:
  persistent:
    - user.preferences
      ACCESS: readwrite

    - user.account_status
      ACCESS: read

    - user.interaction_log
      ACCESS: write
```

| Value       | Behavior                                        |
| ----------- | ----------------------------------------------- |
| `read`      | Agent can read but not modify the value.        |
| `write`     | Agent can write but not read the current value. |
| `readwrite` | Agent can both read and modify. (Default.)      |

### Access Persistent Variables in Expressions

Use the full dot-notation path within `{{ }}` to read persistent variables in `SET` expressions and `RESPOND` templates.

```yaml theme={null}
SET: greeting = COALESCE(user.name, "valued customer")
RESPOND: "Welcome back, {{greeting}}! Your tier is {{user.loyalty_tier}}."
```

### Troubleshooting

* **Persistent value is null on first session.** The value has not been stored yet. Use `DEFAULT` to provide a fallback, or use `COALESCE()` in expressions.
* **Value not persisting across sessions.** Ensure the value is written using a `remember` trigger or `SET` statement. Declaring a persistent path does not automatically populate it.
* **Wrong user sees another user's data.** Verify `SCOPE: user` is set. Project-scoped variables are shared. User-scoped variables require user authentication to resolve correctly.

***

## Remember Triggers

Remember triggers write values to persistent memory when a condition evaluates to `true` during conversation.

```yaml theme={null}
AGENT: Support_Agent
GOAL: "Help customers with personalized support"

MEMORY:
  persistent:
    - user.name
    - user.language
    - user.booking_history

  remember:
    - WHEN: user_name IS SET
      STORE: user_name -> user.name
      TTL: "90d"
    - WHEN: preferred_language IS SET
      STORE: preferred_language -> user.language
```

When `user_name` gets a value during the conversation (from a `GATHER` step, `SET` assignment, or tool result), the trigger fires and stores it to `user.name`. `TTL: "90d"` means the stored fact expires after 90 days.

**Remember Trigger Properties**

| Property | Type   | Required | Default | Description                                                                                                                                                                       |
| -------- | ------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| WHEN     | string | Yes      | --      | Condition expression that triggers the store operation. Evaluated after each turn.                                                                                                |
| STORE    | object | Yes      | --      | Defines the value expression and the target persistent path. Syntax: `value_expr -> target_path`.                                                                                 |
| TTL      | string | No       | --      | Time-to-live for the stored fact. After expiration, the value is deleted. Examples: "30d", "24h". TTL values use a duration string: s - Seconds, m - Minutes, h - Hours, d - Days |

### Store computed values

Store a computed object instead of a raw variable value.

```yaml theme={null}
MEMORY:
  remember:
    - WHEN: action_completed == true
      STORE: {booking_id: selected_booking, action: action_type, date: now} -> user.booking_history
```

## Recall

Recall automatically stores values into persistent memory when conditions are met, and loads stored facts back into the session at specific lifecycle events.

### Add recall instructions

```yaml theme={null}
MEMORY:
  recall:
    - ON: session:start
      ACTION: inject_context
      PATHS: [user.name, user.language, user.preferred_agent]
    - ON: session:start
      ACTION: prompt_llm
      INSTRUCTION: "Greet the user by name if known"
```

When a new session starts, the platform loads `user.name`, `user.language`, and `user.preferred_agent` from persistent memory and injects them into the session context.

**Recall Properties**

| Field         | Required | Description                                                                 |
| ------------- | -------- | --------------------------------------------------------------------------- |
| `ON`          | Yes      | Canonical event name such as `session:start` or `tool:<name>:after`.        |
| `ACTION`      | Yes      | `inject_context`, `load_memory`, or `prompt_llm`.                           |
| `PATHS`       | No       | Durable memory paths to retrieve for `inject_context` or `load_memory`.     |
| `DOMAIN`      | No       | Named memory domain used by `load_memory` when paths are domain-scoped.     |
| `INSTRUCTION` | No       | Prompt text used by `prompt_llm` to shape how retrieved context is applied. |

**Recall Events**

| Event         | When it fires                                          |
| ------------- | ------------------------------------------------------ |
| session:start | When a new session initializes, before any user input. |
| search:before | Before a search or retrieval operation.                |

**Recall Actions**

| Action           | Behavior                                                                 |
| ---------------- | ------------------------------------------------------------------------ |
| `inject_context` | Loads specified persistent paths directly into session variables.        |
| `load_memory`    | Loads all facts in the specified domain into context.                    |
| `prompt_llm`     | Passes the instruction text to the LLM as additional context. (Default.) |

### Recall before search operations

Load relevant user context before a knowledge base search executes.

```yaml theme={null}
MEMORY:
  recall:
    - ON: search:before
      ACTION: load_memory
      DOMAIN: "travel_preferences"
```

This loads all facts tagged with the `travel_preferences` domain into the session, allowing the search to incorporate user preferences.

### Inject recalled data as an LLM instruction

Instead of directly injecting variables, pass an instruction to the LLM on how to use the recalled information.

```yaml theme={null}
MEMORY:
  recall:
    - ON: session:start
      ACTION: prompt_llm
      INSTRUCTION: |
        Check if you have the user's name and preferences from previous
        conversations. If so, greet them personally and reference their
        past interactions. If not, introduce yourself and start fresh.
```

### Combined remember and recall pattern

A complete pattern that stores user preferences during a conversation and recalls them at the start of future sessions.

```yaml theme={null}
MEMORY:
  session:
    - selected_booking
      TYPE: string
    - action_type
      TYPE: string

  persistent:
    - user.booking_history
    - user.preferences

  remember:
    - WHEN: action_completed == true
      STORE: {booking_id: selected_booking, action: action_type, date: now} -> user.booking_history
    - WHEN: user_preference IS SET
      STORE: user_preference -> user.preferences

  recall:
    - ON: session:start
      ACTION: inject_context
      PATHS: [user.booking_history, user.preferences]
    - ON: tool:list_user_bookings:after
      ACTION: inject_context
      PATHS: [user.preferences]
```

### Troubleshooting

* **Remember trigger never fires.** The `WHEN` condition references a variable that is never set during conversation. Verify the variable name matches what your flow or tools produce.
* **Recalled value is stale.** The fact may have expired (TTL elapsed). Check the TTL setting and extend it if needed.
* **Recall injects null values.** The persistent path has not been written to yet. Use `DEFAULT` on the persistent variable declaration to provide a fallback.

***

## Manipulate State: SET, CLEAR, and TRANSFORM

Use `SET`, `CLEAR`, and `TRANSFORM` directives in flow steps to assign values, remove variables, and reshape data arrays during execution.

### SET a variable

Use `SET` in a flow step to assign a value to a session variable. The expression is resolved at execution time.

```yaml theme={null}
FLOW:
  calculate_total:
    REASONING: false
    SET:
      - total_price = nights * price_per_night
      - tax_amount = total_price * 0.12
      - final_total = total_price + tax_amount
    RESPOND: "Your total is ${{final_total}} (including ${{tax_amount}} tax)."
    THEN: confirm_booking
```

`SET` expressions support arithmetic, string interpolation, dot-notation access, and function calls.

**From tool results:**

```yaml theme={null}
FLOW:
  process_search:
    REASONING: false
    CALL: search_hotels(destination, checkin_date, checkout_date, num_guests)
    ON_SUCCESS:
      SET:
        - hotel_count = call_result.hotels.length
        - cheapest_price = call_result.hotels[0].price
      RESPOND: "Found {{hotel_count}} hotels. Prices start at ${{cheapest_price}}."
      THEN: select_hotel
```

**Nested objects using dot notation:**

```yaml theme={null}
SET:
  - booking.guest_name = guest_name
  - booking.check_in = checkin_date
  - booking.total = final_total
```

**In `ON_INPUT` branches:**

```yaml theme={null}
FLOW:
  select_hotel:
    REASONING: false
    ON_INPUT:
      - IF: abl.is_number(input) AND input >= 1 AND input <= hotels.length
        SET:
          - selected_hotel = hotels[input - 1]
          - need_price_quote = true
        THEN: collect_guest_info
      - ELSE:
        RESPOND: "Please enter a valid hotel number."
```

### CLEAR a variable

Use `CLEAR` to remove one or more variables from the session. After a `CLEAR`, the variable is undefined and any template reference to it renders as empty.

```yaml theme={null}
FLOW:
  restart_search:
    REASONING: false
    CLEAR: [destination, checkin_date, checkout_date, search_results]
    RESPOND: "Let's start fresh. Where would you like to go?"
    THEN: collect_trip_info
```

**In sub-intents** — allow users to clear and re-enter specific fields:

```yaml theme={null}
FLOW:
  collect_trip_info:
    REASONING: false
    GATHER:
      - destination: required
      - checkin_date: required
      - checkout_date: required

    SUB_INTENTS:
      - INTENT: "change destination"
        CLEAR: [destination]
        RESPOND: "What's the new destination?"
      - INTENT: "change dates"
        CLEAR: [checkin_date, checkout_date]
        RESPOND: "What are your new travel dates?"

    COMPLETE_WHEN: destination AND checkin_date AND checkout_date
    THEN: search_hotels
```

### TRANSFORM an array

Use `TRANSFORM` to filter, map, sort, and limit array data in a single pipeline.

In the following example `TRANSFORM` creates a new array `affordable_hotels` without modifying the source array.

**Full pipeline:**

```yaml theme={null}
FLOW:
  filter_hotels:
    REASONING: false
    TRANSFORM:
      SOURCE: search_results AS hotel
      INTO: affordable_hotels
      FILTER: hotel.price <= budget
      MAP:
        name: hotel.name
        price: hotel.price
        rating: hotel.rating
      SORT_BY: price asc
      LIMIT: 5
    RESPOND: |
      Here are {{affordable_hotels.length}} hotels within your budget:
      {{#each affordable_hotels}}
      {{add @index 1}}. {{name}} - ${{price}}/night ({{rating}} stars)
      {{/each}}
    THEN: select_hotel
```

**Filter only:**

```yaml theme={null}
TRANSFORM:
  SOURCE: all_bookings AS booking
  INTO: active_bookings
  FILTER: booking.status == "active"
```

**Map only:**

```yaml theme={null}
TRANSFORM:
  SOURCE: raw_results AS item
  INTO: formatted_results
  MAP:
    title: item.name
    summary: item.description
    link: item.url
```

### Troubleshooting

* **`SET` expression produces null.** The right-hand variable may not be defined yet. Verify the data source (tool result, gathered field, or prior `SET`) runs before this step.
* **`CLEAR` does not reset a `GATHER` field.** Clearing a variable removes it from the session, but the `GATHER` step may not re-prompt for it unless the step is re-entered. Use `CLEAR` within a `SUB_INTENT` or `DIGRESSION` that resumes the same step.
* **`TRANSFORM` produces empty array.** The `FILTER` condition may be too strict, or the source array is empty. Check the source variable and filter expression.

***

## Best Practices

* **Use meaningful variable names.** Use names like `user_preferences`, `order_history`, or `conversation_context`. Avoid generic names like `var1`, `data`, or `temp`.
* **Use `COALESCE()` for persistent variables.** Persistent paths may not be populated on a user's first session. Use `COALESCE(user.name, "valued customer")` to provide a safe fallback.
* **Set defaults on persistent variables.** Declare `DEFAULT` values so the agent behaves correctly before any data has been stored.
* **Use `CLEAR` within sub-intents to reset state.** Clearing a variable removes it from the session, but a `GATHER` step only re-prompts when the step is re-entered. Pair `CLEAR` with a `SUB_INTENT` or `DIGRESSION` that resumes the same step.
* **Prefer `per_session` reset over `never`.** Variables with `RESET: never` persist for the lifetime of the runtime process. Reserve this for counters or flags where cross-session accumulation is intentional.

***

## Further Reading

* [Memory & Constraints Reference](/agent-platform/abl-reference/memory-and-constraints) -- Full ABL syntax for MEMORY and CONSTRAINTS blocks.
* [GATHER Reference](/agent-platform/abl-reference/gather) -- Collecting user input into session variables.
* [Flow Reference](/agent-platform/abl-reference/flow) -- Flow step directives including SET, CLEAR, TRANSFORM.

***
