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

# Keep session memory

> Give a chat workflow a memory so a later request sees the earlier turns, with SESSION_MEMORY around an LLM_CALL.

<dl />

**Use this when** a user talks to a model over several requests and each answer should know what was said before.

**Prerequisites:** [Call an LLM](https://yukta.infenia.com/guides/ai/call-an-llm.md) works for you. This guide matches [example 09](https://github.com/infenia/yukta/tree/main/examples/09-llm-chat-agent), which you can run end to end. Add `-H "X-API-Key: $YUKTA_API_KEY"` if your server has keys.

## Steps

**1. Wire load, model, append**

A chat turn is a `SESSION_MEMORY` node in `load` mode, the model, and a `SESSION_MEMORY` node in `append` mode. Save as `session.json` (this one uses a local Ollama through its OpenAI-compatible endpoint):

```json session.json theme={"system"}
{
  "sessionId": "chat",
  "name": "Chat",
  "workflows": {
    "turn": {
      "workflowId": "turn",
      "description": "One chat turn with memory",
      "nodes": [
        { "nodeId": "trigger", "type": "API_TRIGGER", "config": {} },
        {
          "nodeId": "memory-load",
          "type": "SESSION_MEMORY",
          "config": {
            "mode": "load",
            "sessionId": "${payload.sessionId}",
            "message": "${payload.message}",
            "maxTurns": 20
          }
        },
        {
          "nodeId": "llm",
          "type": "LLM_CALL",
          "config": {
            "provider": "openai",
            "baseUrl": "http://localhost:11434/v1",
            "apiKey": "decrypted:llm-api-key",
            "model": "llama3.2",
            "system": "You are a concise, helpful assistant.",
            "messages": "payload['history']",
            "prompt": "${payload.message}",
            "timeout": 60
          }
        },
        { "nodeId": "memory-append", "type": "SESSION_MEMORY", "config": { "mode": "append", "maxTurns": 20 } },
        { "nodeId": "end", "type": "CONSOLE_TERMINAL", "config": {} }
      ],
      "edges": [
        { "source": "trigger", "target": "memory-load" },
        { "source": "memory-load", "target": "llm" },
        { "source": "llm", "target": "memory-append" },
        { "source": "memory-append", "target": "end" }
      ]
    }
  }
}
```

* `load` adds `history: [{role, content}]` to the payload, the newest `maxTurns` turns (default 20).
* `append` records the user turn and the model's reply (default `${payload.content}`); its `sessionId` defaults to `${metadata.sessionId}`.
* `messages` is an **expression** on purpose: a `${...}` reference would turn the list into text.
* With Ollama, set `YUKTA_SECRET_LLM_API_KEY` to any non-empty value, or drop `apiKey`.

```bash theme={"system"}
curl -X POST localhost:9858/api/sessions -H 'Content-Type: application/json' -d @session.json
```

**2. Send two turns with the same conversation id**

```bash theme={"system"}
curl -X POST localhost:9858/api/workflow/start -H 'Content-Type: application/json' \
  -d '{"sessionId":"chat","workflowId":"turn","payload":{"sessionId":"user-42","message":"My name is Ada. Remember it."}}'
curl -X POST localhost:9858/api/workflow/start -H 'Content-Type: application/json' \
  -d '{"sessionId":"chat","workflowId":"turn","payload":{"sessionId":"user-42","message":"What is my name?"}}'
```

The conversation id is `payload.sessionId` here (`user-42`). It is not the Yukta session `chat`. Each conversation id has its own history.

**3. Forget a conversation**

Use `mode: delete` with the conversation id to remove its history, for example from a separate workflow wired to a "new chat" button:

```json theme={"system"}
{ "nodeId": "forget", "type": "SESSION_MEMORY", "config": { "mode": "delete", "sessionId": "${payload.sessionId}" } }
```

## Verify it worked

Read the result of the second run:

```bash theme={"system"}
curl -s -H 'Accept: application/json' localhost:9858/api/sessions/chat/executions/$EXEC2/results
```

`payload.content` answers along the lines of "Your name is Ada". If it does not know, the first run did not finish before the second started, or you used a different `payload.sessionId`.

## Variations

* **Memory is per server process.** It lives in memory and a restart clears it. Plan for that if conversations must outlive a restart.
* **Trim long chats.** Lower `maxTurns` on both memory nodes to bound the prompt size and the token cost: [Set token budgets](https://yukta.infenia.com/guides/ai/set-token-budgets.md).
* **Several agents.** Give each agent its own conversation id (or a prefix) so they do not share history.

## Related

* [AI plugins reference](https://yukta.infenia.com/reference/plugins/ai.md) for `SESSION_MEMORY` options.
* [Example 09](https://github.com/infenia/yukta/tree/main/examples/09-llm-chat-agent).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.