# Working Memory with Template

Use template to define the structure of information stored in working memory. Template helps agents extract and persist consistent, structured data across conversations.

It works with both streamed responses using `.stream()` and generated responses using `.generate()`, and requires a storage provider such as PostgreSQL, LibSQL, or Redis to persist data between sessions.

This example shows how to manage a todo list using a working memory template.

## Prerequisites

This example uses the `openai` model. Make sure to add `OPENAI_API_KEY` to your `.env` file.

```bash
OPENAI_API_KEY=<your-api-key>
```

And install the following package:

```bash
npm install @mastra/libsql@beta
```

## Adding memory to an agent

To add LibSQL memory to an agent, use the `Memory` class and pass a `storage` instance using `LibSQLStore`. The `url` can point to a remote location or local file.

### Working memory with `template`

Enable working memory by setting `workingMemory.enabled` to `true`. This allows the agent to remember structured information between interactions.

Providing a `template` helps define the structure of what should be remembered. In this example, the template organizes tasks into active and completed items using Markdown formatting.

Threads group related messages into conversations. When `generateTitle` is enabled, each thread is automatically given a descriptive name based on its content.

```typescript
import { Memory } from '@mastra/memory';
import { Agent } from '@mastra/core/agent';
import { LibSQLStore } from '@mastra/libsql';

export const workingMemoryTemplateAgent = new Agent({
  name: 'working-memory-template-agent',
  instructions: `
    You are a todo list AI agent.
    Always show the current list when starting a conversation.
    For each task, include: title with index number, due date, description, status, and estimated time.
    Use emojis for each field.
    Support subtasks with bullet points.
    Ask for time estimates to help with timeboxing.
  `,
  model: 'openai/gpt-5.1',
  memory: new Memory({
    storage: new LibSQLStore({
      url: 'file:working-memory-template.db',
    }),
    options: {
      workingMemory: {
        enabled: true,
        template: `
          # Todo List
          ## Active Items
          - Task 1: Example task
            - Due: Feb 7 2028
            - Description: This is an example task
            - Status: Not Started
            - Estimated Time: 2 hours

          ## Completed Items
          - None yet`,
      },
      threads: {
        generateTitle: true,
      },
    },
  }),
});
```

## Usage examples

This example shows how to interact with an agent that uses a working memory template to manage structured information. The agent updates and persists the todo list across multiple interactions within the same thread.

### Streaming a response using `.stream()`

This example sends a message to the agent with a new task. The response is streamed and includes the updated todo list.

```typescript
import 'dotenv/config';

import { mastra } from './mastra';

const threadId = '123';
const resourceId = 'user-456';

const agent = mastra.getAgent('workingMemoryTemplateAgent');

const stream = await agent.stream(
  'Add a task: Build a new feature for our app. It should take about 2 hours and needs to be done by next Friday.',
  {
    memory: {
      thread: threadId,
      resource: resourceId,
    },
  },
);

for await (const chunk of stream.textStream) {
  process.stdout.write(chunk);
}
```

### Generating a response using `.generate()`

This example sends a message to the agent with a new task. The response is returned as a single message and includes the updated todo list.

```typescript
import 'dotenv/config';

import { mastra } from './mastra';

const threadId = '123';
const resourceId = 'user-456';

const agent = mastra.getAgent('workingMemoryTemplateAgent');

const response = await agent.generate(
  'Add a task: Build a new feature for our app. It should take about 2 hours and needs to be done by next Friday.',
  {
    memory: {
      thread: threadId,
      resource: resourceId,
    },
  },
);

console.log(response.text);
```

## Example output

The output demonstrates how the agent formats and returns the updated todo list using the structure defined in the working memory template.

```text
# Todo List
## Active Items
1. 🛠️ **Task:** Build a new feature for our app
   - 📅 **Due:** Next Friday
   - 📝 **Description:** Develop and integrate a new feature into the existing application.
   - ⏳ **Status:** Not Started
   - ⏲️ **Estimated Time:** 2 hours

## Completed Items
- None yet
```

## Example storage object

Working memory stores data in `.json` format, which would look similar to the below:

```json
{
  // ...
  "toolInvocations": [
    {
      // ...
      "args": {
        "memory": "# Todo List\n## Active Items\n- Task 1: Build a new feature for our app\n  - Due: Next Friday\n  - Description: Build a new feature for our app\n  - Status: Not Started\n  - Estimated Time: 2 hours\n\n## Completed Items\n- None yet"
      }
    }
  ]
}
```

## Related

- [Calling Agents](https://mastra.ai/docs/v1/agents/overview#referencing-an-agent)
- [Agent Memory](https://mastra.ai/docs/v1/agents/agent-memory)
- [Serverless Deployment](https://mastra.ai/reference/v1/storage/libsql)
