cd /news/ai-agents/giving-an-opencode-coding-agent-pers… · home topics ai-agents article
[ARTICLE · art-133125] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Giving an OpenCode Coding Agent Persistent, Editable Memory

A developer maintains @ghilteras/opencode-agent-memory, an experimental OpenCode plugin that gives AI coding agents persistent, editable memory stored as scoped Markdown files on disk rather than an opaque remote service. The plugin exposes memory_list, memory_set, and memory_replace tools for global and per-project blocks, plus an opt-in append-only journal with local embedding-based search using paraphrase-multilingual-MiniLM-L12-v2 via Transformers.js. The developer notes that memory systems fail quietly, with stale memory being worse than none.

by read4 min views1 publishedSep 17, 2026

AI coding agents are good at using the context currently in front of them. They are much less reliable at carrying useful context from one session to the next.

Project conventions, decisions made during a debugging session, and preferences that were obvious yesterday often need to be re-explained after a restart or after context compaction.

I maintain @ghilteras/opencode-agent-memory, an experimental plugin for OpenCode that explores an alternative: treating agent memory as editable, scoped Markdown state on disk rather than as an opaque remote service.

AGENTS.md and custom instruction files are a good start. I rely on them heavily. But they are a single flat document with no notion of scope, no size enforcement, and no dedicated operations for the agent to maintain it.

What I actually wanted was structured state:

The plugin gives the agent three tools: memory_list, memory_set, and memory_replace. Blocks are plain Markdown files with YAML frontmatter.

Global blocks live in ~/.config/opencode/memory/*.md and are shared across projects. Project blocks live in .opencode/memory/*.md and are shared across sessions in that codebase, and are gitignored automatically.

Each block has:

Field Type Default Purpose
label string filename unique identifier
description string generic fallback tells the agent how to use the block
limit integer 5000 maximum characters
read_only boolean false prevents agent edits

The description field carries more weight than it looks like it should. Without it, the agent gets a generic fallback and does not know when the block is relevant. This mirrors the emphasis Letta puts on describing memory blocks well.

Three blocks are seeded on first run: persona and human globally, project for the current codebase.

Memory blocks are curated state. Some things are not: observations, dead ends, discoveries, decisions, and the reasoning behind them.

For that the plugin adds an optional append-only journal with journal_write, journal_search, and journal_read. Entries are Markdown files with YAML frontmatter stored under ~/.config/opencode/journal/, and each entry records which project, model, provider, agent, and session it came from.

The journal is deliberately opt-in. Enabling it is a line in ~/.config/opencode/agent-memory.json:

{
  "journal": {
    "enabled": true
  }
}

Append-only plus retrieval is what makes it useful. I do not want the agent rewriting history; I want it to be able to find what happened last month.

journal_search uses local embeddings rather than a hosted API. Entries are embedded with paraphrase-multilingual-MiniLM-L12-v2 (384 dimensions, multilingual) through Transformers.js, and the model is cached locally. Journal content does not leave the machine for search.

Two implementation details were worth the effort:

Embedding files are versioned. Each .embedding sidecar stores { v, model, dimension, vector }. If the stored dimension does not match the current model, the entry degrades to text matching instead of failing the search. Legacy bare-array embeddings from earlier versions remain readable.

The in-memory index is fingerprinted. journal_search keeps an index per store instance and re-reads an entry only when the entry .md or its .embedding sidecar changed (mtime plus size). Regenerating or deleting a sidecar is picked up on the next search without a restart, and the embedding model is warmed up in the background at plugin init so the first search after a restart does not pay the cold model-load cost.

There is also a deliberate retrieval floor: since v0.4.2, a query whose text matches an entry title (in either direction, case-insensitive) is guaranteed a high score, so title-based pointers stay retrievable even for entries with long bodies.

I want to be clear about the failure modes, because memory systems fail quietly.

Stale memory is worse than no memory. A block that says something true six weeks ago will be confidently applied today. The description field and size limits help the agent judge relevance, but they do not make the content true. Having the state as editable Markdown on disk means you can inspect and fix it directly; that is a feature, not a workaround.

Automatic persistence is not the same as truth. The journal records what the agent observed, including wrong conclusions. Treat it as a log, not a knowledge base.

The journal is opt-in because silent collection is worse than explicit collection.

Requires OpenCode v1.0.115 or later.

{
  "plugin": ["@ghilteras/opencode-agent-memory@0.4.3"]
}

OpenCode fetches unpinned plugins from npm on each startup; pinned versions are cached and need a manual bump. Restart OpenCode after changing plugin configuration; editing the config file alone is not enough to load a new plugin version.

A cacheDir key at the top level of agent-memory.json relocates the Transformers.js model cache if you prefer not to use the default Hugging Face cache location.

This is experimental software, MIT licensed. It is maintained at https://github.com/Ghilteras/opencode-agent-memory and published as @ghilteras/opencode-agent-memory. It is not built by or affiliated with the OpenCode team.

If you try it, issues and concrete workflow reports are welcome.

── more in #ai-agents 4 stories · sorted by recency
── more on @opencode 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/giving-an-opencode-c…] indexed:0 read:4min 2026-09-17 ·