docs: Added documentation for the new memory system
+1
@@ -38,6 +38,7 @@ Coming from [AIChat](https://github.com/sigoden/aichat)? Follow the [migration g
|
||||
* [Macros](Macros): Automate repetitive tasks and workflows with Coyote "scripts" (macros).
|
||||
* [RAG](RAG): Retrieval-Augmented Generation for enhanced information retrieval and generation.
|
||||
* [Sessions](Sessions): Manage and persist conversational contexts and settings across multiple interactions.
|
||||
* [Memory](Memory): Persistent file-based memory that survives across sessions. Bootstrap with `coyote --init-memory [global|workspace]`.
|
||||
* [Roles](Roles): Customize model behavior for specific tasks or domains.
|
||||
* [Skills](Skills): Modular knowledge or capability packs the LLM can load and unload mid-conversation. Multiple skills compose; instructions stack, tools and MCPs union.
|
||||
* [Agents](Agents): Leverage AI agents to perform complex tasks and workflows, including sub-agent spawning, teammate messaging, and user interaction tools.
|
||||
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
# Memory
|
||||
|
||||
Coyote can maintain a **persistent memory file system** that survives across sessions. Memory captures cross-session
|
||||
facts about you, your project, and your preferences, complementing [Sessions](Sessions) (which handle
|
||||
within-conversation state) and [Skills](Skills) (which are static knowledge packs).
|
||||
|
||||
## Quick Start
|
||||
|
||||
The fastest path is the bootstrap command:
|
||||
|
||||
```bash
|
||||
# Workspace memory (per-project)
|
||||
cd /path/to/your/project
|
||||
coyote --init-memory workspace
|
||||
# → creates ./COYOTE.md with a skeleton
|
||||
|
||||
# Global memory (per-user, applies everywhere)
|
||||
coyote --init-memory global
|
||||
# → creates <config_dir>/memory/MEMORY.md
|
||||
```
|
||||
|
||||
Then edit the file with anything you want the LLM to remember:
|
||||
|
||||
```markdown
|
||||
# Project Memory
|
||||
|
||||
This project is a Rust CLI tool. I prefer terse responses and concrete code examples.
|
||||
```
|
||||
|
||||
Run coyote in that directory and the memory content is injected into every system prompt automatically. The LLM will see and use the `memory__*` tools to update it over time (when function calling is on).
|
||||
|
||||
That's it for "lite mode." For structured memory, see below.
|
||||
|
||||
> Memory is **opt-in by file presence** for the read path. If no marker exists on disk, no workspace memory is injected and global memory is loaded only if the global marker exists. `--init-memory` is the explicit consent signal.
|
||||
|
||||
> **Write-side exception (git repos only):** if the LLM calls `memory__write(scope=workspace)` and no marker exists, coyote auto-bootstraps a structured layout at the git root and adds `.coyote/memory/` to `.gitignore`. See [Git-Repo Auto-Bootstrap](#git-repo-auto-bootstrap) below. Outside a git repo this fails with a hint to run `coyote --init-memory workspace`.
|
||||
|
||||
> **Re-running is safe.** `--init-memory` refuses to overwrite an existing marker — it prints `Memory marker already exists at '...'` and exits without touching the file. Useful in setup scripts.
|
||||
|
||||
## How It Works
|
||||
|
||||
Memory has two scopes:
|
||||
|
||||
- **Global** (user-level): `~/.config/coyote/memory/` - facts about you that apply everywhere
|
||||
- **Workspace** (project-level): `<workspace>/COYOTE.md` (lite) or `<workspace>/.coyote/memory/` (structured)
|
||||
|
||||
Memory is **opt-in by workspace**: coyote walks up from your current directory looking for a memory marker. If none is
|
||||
found, no workspace memory is loaded. Global memory is loaded if it exists.
|
||||
|
||||
When both a `.coyote/memory/MEMORY.md` and a `COYOTE.md` exist at the same level, the structured layout wins.
|
||||
|
||||
### Git-Repo Auto-Bootstrap
|
||||
|
||||
If the LLM tries to write workspace memory and no marker exists in any ancestor, coyote checks for a git repository before erroring:
|
||||
|
||||
- **Git root found** (ancestor contains a `.git` directory or file, worktrees and submodules included): coyote creates
|
||||
`<git_root>/.coyote/memory/MEMORY.md` with an empty index, appends `.coyote/memory/` to `<git_root>/.gitignore`
|
||||
(idempotent; no duplicate if you already have it, including the trailing-slash-less form), and emits a `WARN`-level
|
||||
log line so you know it happened. The write then proceeds.
|
||||
- **No git root**: the write fails with an error pointing you at `coyote --init-memory workspace`.
|
||||
|
||||
The rationale: if you're in a git repo, the natural anchor for workspace-wide memory is the repo root, and the
|
||||
gitignore entry keeps the LLM's drill files out of version control by default. If you're not in a git repo, the
|
||||
bootstrap location is genuinely ambiguous, so coyote requires explicit consent via `--init-memory`.
|
||||
|
||||
This only affects the write path. The read path remains opt-in: until a marker exists, no workspace memory is injected.
|
||||
|
||||
## Two Halves: Read and Write
|
||||
|
||||
Memory has two independent halves:
|
||||
|
||||
| Half | Requires | Behavior |
|
||||
|-----------|--------------------------|-----------------------------------------------------------------|
|
||||
| **Read** | Nothing | Memory content is injected into the system prompt every session |
|
||||
| **Write** | Function calling support | The LLM uses `memory__*` tools to curate memory autonomously |
|
||||
|
||||
If your model lacks function calling, memory degrades to read-only: you maintain the files manually, the LLM sees them.
|
||||
In read-only mode coyote injects all known drill files (up to the without-tools cap) so the model has full context
|
||||
without needing tools.
|
||||
|
||||
## Structured Mode
|
||||
|
||||
For non-trivial memory, use the structured layout:
|
||||
|
||||
```
|
||||
<workspace>/.coyote/memory/
|
||||
├── MEMORY.md # index (always injected)
|
||||
├── project_compliance.md
|
||||
├── feedback_terse.md
|
||||
└── reference_dashboards.md
|
||||
```
|
||||
|
||||
Each drill file has YAML frontmatter:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: project_compliance
|
||||
description: Compliance constraints driving the auth rewrite
|
||||
type: project
|
||||
---
|
||||
|
||||
We must store session tokens server-side per the 2026 audit. ...
|
||||
```
|
||||
|
||||
`MEMORY.md` is what gets injected on every prompt. It serves two purposes:
|
||||
1. **An index** of available drill files (one line per file: name + description)
|
||||
2. **A home for universal facts** the LLM should always see (user identity, hard rules, binding feedback)
|
||||
|
||||
Drill files are fetched on demand by the LLM via `memory__read`. Keep them focused; for facts that should always be
|
||||
visible, write them directly in `MEMORY.md` instead.
|
||||
|
||||
## Memory Types
|
||||
|
||||
| Type | Purpose | Example |
|
||||
|-------------|---------------------------------------------------|------------------------------------------------|
|
||||
| `user` | Persistent facts about you | "Senior Rust dev, terse responses preferred" |
|
||||
| `feedback` | Past corrections that should bind future behavior | "Never use `as any`; got burned in incident X" |
|
||||
| `project` | Workspace-specific facts | "API freeze begins 2026-03-05" |
|
||||
| `reference` | Pointers to external systems | "Bugs tracked in Linear project INGEST" |
|
||||
|
||||
The `type:` field is informational, meaning coyote does not change behavior based on it. It exists so the LLM can
|
||||
categorize its own writes and so you can grep by category.
|
||||
|
||||
## Tools
|
||||
|
||||
When function calling is enabled, coyote exposes:
|
||||
|
||||
- `memory__read(name)`: read a specific drill file by its slug
|
||||
- `memory__write(name, description, content, scope, type)`: create or replace a drill file (`scope`: `global` |
|
||||
`workspace`)
|
||||
- `memory__list()`: see all known drill files with metadata
|
||||
- `memory__lint()`: health-check (orphans, broken `[[wikilinks]]`, oversized files >2K chars)
|
||||
|
||||
The LLM is instructed to update `MEMORY.md` whenever it writes a new file. Two silent promotions can happen on a
|
||||
`memory__write(scope=workspace)`:
|
||||
|
||||
- **Lite -> structured**: if the workspace is in lite mode (`COYOTE.md` only), the new file goes into
|
||||
`<workspace>/.coyote/memory/` and `COYOTE.md` is left untouched.
|
||||
- **None -> structured (git only)**: if no marker exists anywhere, coyote auto-bootstraps at the git root. See
|
||||
[Git-Repo Auto-Bootstrap](#git-repo-auto-bootstrap).
|
||||
|
||||
## Toggles
|
||||
|
||||
Memory can be disabled at multiple levels (most specific wins):
|
||||
|
||||
1. **CLI flag**: `coyote --no-memory ...` (per-invocation; sets `false` at the app layer)
|
||||
2. **Graph agents**: memory is always off
|
||||
3. **Agent config**: `memory: false` in the agent's `config.yaml`
|
||||
4. **Session**: `memory: false` in the saved session frontmatter (also settable via the session's `set_memory` API)
|
||||
5. **Role config**: `memory: false` in role frontmatter
|
||||
6. **AppConfig**: `memory: false` in global config
|
||||
7. **Workspace presence** (read side): absence of `COYOTE.md` and `.coyote/memory/`. On the write side,
|
||||
`memory__write(scope=workspace)` inside a git repo can auto-create `.coyote/memory/` (see
|
||||
[Git-Repo Auto-Bootstrap](#git-repo-auto-bootstrap) for more information).
|
||||
|
||||
Resolution cascade for the boolean flag: **agent > session > role > app**, with the first explicit value winning.
|
||||
No value means "no opinion, defer to next layer." If the flag resolves to true but no memory exists on disk anywhere,
|
||||
memory stays off (no empty injection).
|
||||
|
||||
## Caps
|
||||
|
||||
Two cap constants control how much memory content is injected:
|
||||
|
||||
| Field (in AppConfig) | Default | When |
|
||||
|----------------------------|--------------|----------------------------------------------------------------------------|
|
||||
| `memory_cap_with_tools` | 6,000 chars | Function calling on. Only indexes injected, drill bodies fetched on demand |
|
||||
| `memory_cap_without_tools` | 12,000 chars | Function calling off. Indexes plus drill bodies up to the cap |
|
||||
|
||||
In without-tools mode, drill files are appended alphabetically until the cap is exhausted; any omitted files are
|
||||
reported via a truncation marker in the injection block.
|
||||
|
||||
If the `MEMORY.md` indexes alone exceed the cap, coyote injects them fully and logs a warning. A partial index would
|
||||
confuse the LLM more than going over budget by a few hundred chars.
|
||||
|
||||
## When NOT to Use Memory
|
||||
|
||||
- **One-shot prompts**: no recurring context, memory is overhead
|
||||
- **Privacy-sensitive sessions**: memory persists on disk in plaintext
|
||||
- **Throwaway scripts using coyote as a library**: the script is the context
|
||||
|
||||
For session-specific suppression without changing config, use `--no-memory` or set `memory: false` on a Session before
|
||||
saving it.
|
||||
|
||||
## Comparison
|
||||
|
||||
| | Memory | [Sessions](Sessions) | [Skills](Skills) | [RAG](RAG) | [Vault](Vault) |
|
||||
|-------------|---------------------|----------------------|------------------|--------------------|----------------|
|
||||
| Scope | Cross-session facts | One conversation | Knowledge packs | Document retrieval | Secrets |
|
||||
| Lifecycle | Evolves over time | Per-conversation | Static, curated | Indexed, retrieved | Long-lived |
|
||||
| Encrypted | No (plaintext) | No | No | No | Yes |
|
||||
| LLM writes? | Yes (with tools) | No | No | No | No |
|
||||
|
||||
## Privacy & Security
|
||||
|
||||
Memory files are **plaintext markdown on disk**. Anything you (or the LLM) writes there is readable to anyone with
|
||||
access to your home directory.
|
||||
|
||||
**Never store secrets in memory.** Use [Vault](Vault) for credentials and API keys. The default memory instructions
|
||||
explicitly tell the LLM not to write secrets, but treat that as a defense-in-depth measure, not a guarantee.
|
||||
|
||||
## See Also
|
||||
|
||||
- [Sessions](Sessions): per-conversation state
|
||||
- [Skills](Skills): modular knowledge packs
|
||||
- [Roles](Roles): model behavior customization (supports `memory: false`)
|
||||
- [RAG](RAG): document retrieval (complementary, not redundant)
|
||||
- [Vault](Vault): encrypted secret storage
|
||||
+3
@@ -6,6 +6,9 @@ Think of them kind of like a baby: That baby can grow up to do anything! Be a re
|
||||
The only difference is that with roles, we're explicitly telling the LLM what we want it to be. Also: the LLM is already
|
||||
grown up so we don't have to wait!
|
||||
|
||||
> Roles can disable the memory system for their scope by setting `memory: false` in their frontmatter.
|
||||
> See [Memory](Memory) for the full toggle cascade.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
+3
@@ -7,6 +7,9 @@ answers and ask follow-up questions and the model will know what you're referrin
|
||||
|
||||
Sessions can be temporary, or can be saved so you can continue conversations at a later time.
|
||||
|
||||
> Sessions persist *one conversation*. For facts that should survive across all sessions (e.g., user preferences,
|
||||
> project constraints, accumulated feedback), see [Memory](Memory).
|
||||
|
||||
Saved sessions are stored in the `sessions` subdirectory of the Coyote configuration directory. The location of the
|
||||
`sessions` directory varies by system, so you can use the following command to find the `sessions` directory if you need
|
||||
it:
|
||||
|
||||
+3
@@ -5,6 +5,9 @@ the user), a skill is a capability the model layers onto whatever role/agent/ses
|
||||
Multiple skills can be loaded at once. They compose, meaning their instructions stack, their tool whitelists union, and
|
||||
their declared MCP servers get acquired automatically.
|
||||
|
||||
> Skills are *static* curated knowledge packs. For *evolving* facts the LLM curates over time across sessions,
|
||||
> see [Memory](Memory).
|
||||
|
||||
Common uses:
|
||||
|
||||
- **Methodology overlays** ("how to do git surgery", "how to review code").
|
||||
|
||||
+5
@@ -45,6 +45,11 @@
|
||||
- [Limitations](Graph-Agents#limitations--gotchas)
|
||||
|
||||
## Knowledge & Automation
|
||||
- [Memory](Memory)
|
||||
- [Quick Start](Memory#quick-start)
|
||||
- [Structured Mode](Memory#structured-mode)
|
||||
- [Tools](Memory#tools)
|
||||
- [Toggles](Memory#toggles)
|
||||
- [RAG](RAG)
|
||||
- [Macros](Macros)
|
||||
- [Roles](Roles)
|
||||
|
||||
Reference in New Issue
Block a user