🚀 Technical Briefing: This tutorial is part of our deep-dive series on Agentic Workflows at Gate of AI. For the full technical breakdown, interactive code sandbox, and the native Arabic translation, visit the original article here.
Tutorial · TypeScript agent architecture
Build a Memory-Backed TypeScript Coding Agent
Learn the architecture behind a coding agent that carries useful knowledge across sessions. This guide focuses on verified design principles: persistent memory outside the model, retrieval of relevant context and tools, structured fact extraction, and a controlled tool-use loop. It does not present an unverified Bun, SQLite, or OpenAI integration as a tested implementation.
What You Will Build
You will plan a TypeScript coding-agent system that can receive a repository task, gather relevant project context, request actions through tools, and preserve selected facts for later sessions. The central design goal is not to save every conversation. It is to make useful knowledge available when the next task begins.
That distinction matters because a model’s immediate conversation context is not the same thing as long-term memory. A memory-aware agent treats memory as persistent, structured infrastructure outside the model. At startup, it can load prior context; while working, it can retrieve relevant state and tools; after an interaction, it can extract or refine facts and write them back. This makes memory a designed subsystem rather than an ever-growing transcript.
The supplied evidence does not verify a particular Bun runtime, SQLite schema, FTS5 search implementation, OpenAI SDK version, or complete coding-agent code sample. Accordingly, this tutorial gives an implementation plan and architectural checkpoints, not a copy-and-paste program. Choose and verify the runtime, storage adapter, model provider, and API usage against their current official documentation before writing production code.
Prerequisites
- Comfort with TypeScript, asynchronous application flows, and agent tool concepts.
- A clear definition of the repository or project the agent is intended to assist.
- A decision about which information may be retained between sessions and which must not be stored.
- A model provider and storage technology selected from their current documentation, with credentials handled outside source code.
Step 1: Define the Agent’s Memory Contract
Begin with a written contract that states what the agent may remember, how those facts will be used, and how they can be corrected or removed. Memory engineering treats long-term memory as first-class infrastructure: it exists outside the model and is structured so that an agent can use it deliberately. This is a more useful starting point than simply retaining every message and placing the entire history into every future prompt.
For a coding assistant, candidate memory categories might include project conventions, architectural decisions, known risks, and commands or procedures confirmed during prior work. These are design examples, not a claim that any specific framework stores those categories automatically. Keep the contract narrow: retain only durable information that could help a future repository task, and distinguish confirmed observations from assumptions.
Write down the boundary between session context and long-term memory. A task-specific question or temporary debugging detail may be useful only while the current task is active. A confirmed project convention may be useful later. A secret, credential, or unrelated personal detail should not become a durable project memory. The verified sources establish the value of structured memory and fact-extraction pipelines, but they do not prescribe a universal retention policy; define one for your application.
Also decide who or what can update the memory. A write-back loop can let an agent update its own memory autonomously, but that capability is a design choice, not proof that every proposed fact is correct. Specify how updates will be checked, how conflicting facts will be handled, and how a human can inspect or correct stored knowledge.
Step 2: Design the Memory Lifecycle
Plan memory as a lifecycle with four distinct stages: loading, retrieval, consolidation, and write-back. Keeping these stages separate makes it easier to reason about what information enters a model request and why a fact was preserved.
- Load at startup. Initialize the agent with the persistent state appropriate to its task. The objective is to begin with useful prior context, not to indiscriminately replay every previous interaction.
- Retrieve for the current task. Select the facts and tools that are relevant to the task at hand. Memory-aware agent design uses retrieval to assemble context, state, and tools during execution.
- Extract and consolidate. Turn conversation evidence into structured facts, then consolidate episodic information into more reusable semantic knowledge where appropriate. The source material describes these as memory-engineering patterns; it does not provide a universal schema or extraction prompt.
- Write back deliberately. Store useful updates so a later session can retrieve them. Treat this as a separate operation with its own validation and retention rules, rather than assuming every model response belongs in long-term storage.
This lifecycle also clarifies the difference between a record and a useful memory. A transcript is a record of what was said. A durable memory is selected information intended to help with future work. Converting the former into the latter requires extraction, structure, and consolidation; simply preserving more text does not by itself create better recall.
Step 3: Decide How Retrieval Will Work
Retrieval is the bridge between persistent storage and the current task. A coding agent may have far more stored context or available tools than it can use effectively in one request. The verified course description specifically highlights semantic search as a way to scale tool access and retrieve only relevant tools at inference time, addressing the challenge of agents with hundreds of tools.
Before choosing a search method, list the information the agent must find. Project conventions, an architectural decision, or a tool description may call for different retrieval behavior. Establish what relevance means for each category, what scope applies to a result, and how the agent should behave when there is no useful match. These are application design questions; the provided context does not verify that a particular database, search index, ranking formula, or embedding model is required.
Keep retrieval focused on the task. Supplying every stored fact can recreate the same problem as passing an ever-growing transcript: the model receives more material than it needs. A useful memory system assembles relevant context rather than treating the whole store as a prompt. Inspect the retrieved items during development and test whether they help with representative tasks instead of assuming that a successful search call means the result is useful.
Tools can be treated as procedural memory: capabilities that the agent can retrieve when needed, rather than a fixed list that grows without limit in every interaction. The verified course describes this pattern as a way to scale tool access through semantic search. It does not specify an implementation for a coding agent, so treat the details—tool metadata, selection rules, and invocation policies—as decisions to document and verify in your own system.
Step 4: Build the Agent’s Tool-Use Loop
A coding agent generally needs a repeating interaction pattern. The verified description of AI coding agents gives the core cycle: the agent receives input and prepares a prompt; the model may answer the user or request a tool call; the application executes a requested tool and returns its output; the model is then queried again. The process repeats until the model provides a final assistant response instead of requesting another action.
Use that cycle to plan the boundary between the model and your application. The model can request an action, but the application is responsible for deciding what tools exist and executing them. For a coding assistant, identify which operations are needed for the task and document how each operation will be checked before it is run. Do not treat a model-generated request as proof that the action is appropriate or that it succeeded.
Keep tool results connected to the request that produced them so the agent can interpret the outcome. The model should not claim that it inspected a file, made a change, or completed a validation unless the application has returned evidence for that action. This is a practical design requirement for truthful reporting, not a guarantee that a prompt alone can enforce correctness.
Set explicit stopping and review conditions as part of the design. The verified context does not prescribe a particular iteration limit, timeout, permission scheme, or file-access sandbox. Those operational controls must be selected and tested for the application rather than presented as already supplied by an agent framework or model provider.
Step 5: Choose a TypeScript Framework or Build Your Own Harness
If you prefer a framework rather than assembling every component yourself, Mastra is described in the verified context as a modern TypeScript framework for AI-powered applications and agents. Its listed capabilities include workflows, memory, streaming, evaluations, tracing, and Studio, an interactive interface for development and testing. The reported starter command is:
npm create mastra@latest
Use the framework’s current documentation to confirm generated files, configuration, model-provider setup, memory adapters, and supported deployment choices. The verified information does not establish the exact APIs or configuration for connecting Mastra to Bun, SQLite, or a particular OpenAI model. Do not infer those integrations from a feature list; verify them against up-to-date framework and provider documentation.
Alternatively, a custom TypeScript harness gives you direct responsibility for the agent loop and memory lifecycle. That can be appropriate when you need a narrow system, but it also means you must design and test persistence, retrieval, tool execution, error handling, and evaluation yourself. The choice is not simply “framework versus no framework”: compare the capabilities you need with the implementation and maintenance work you are prepared to own.
For either option, write down the components that actually exist in your chosen implementation. A diagram might include a task entry point, context assembly, model interaction, tool execution, persistent memory, and evaluation. Do not label a component as secure, durable, or production-ready solely because it appears in a diagram or framework feature list.
Step 6: Account for Context Growth and Agent Limits
A memory-backed agent still needs a strategy for the immediate conversation. The verified reporting on OpenAI’s coding-agent architecture explains one important trade-off: when each new turn includes the complete history of earlier messages and tool calls, the prompt grows as the interaction continues, with performance implications. It also describes a design in which requests remain stateless and send the history with each API call. That report is evidence about the described Codex approach, not a universal statement about every API or agent system.
Separate this immediate conversation history from your long-term memory. Conversation history can explain the current sequence of actions; persistent memory is intended to carry selected knowledge across sessions. A design that grows the full prompt without limit can become less efficient. A design that omits relevant evidence can leave the agent without the context it needs. Determine what should remain in the active interaction and what should instead be summarized or stored as structured memory, then evaluate those decisions on real tasks.
Be realistic about coding-agent performance. The verified reporting notes that these tools can be fast on simple tasks but brittle beyond their training data, and that production work requires human oversight. A promising initial scaffold does not eliminate the debugging needed to complete details or resolve limitations. Plan for a developer to review proposed changes and confirm important outcomes.
Step 7: Evaluate Memory and Tool Behavior
Do not evaluate the system only by asking whether it returns a fluent answer. Test whether it loads relevant prior knowledge, retrieves the right facts for a new task, avoids irrelevant memory, and updates stored information in a way that remains useful later. The verified context describes evaluations and tracing among Mastra’s framework capabilities and highlights memory pipelines that extract structured facts, consolidate episodic memory, and support write-back. It does not provide a test suite for this specific coding-agent design.
Create a set of representative tasks from the kinds of work your agent is expected to support. Include cases where a relevant memory should change the answer, cases where stored context should not affect an unrelated request, and cases where the right response is to proceed without a remembered fact. Record which facts were retrieved, what tools were requested, and whether the final answer was supported by the returned results.
Review memory updates as carefully as retrieval. Check whether extracted facts are supported by the interaction, whether distinct episodes have been consolidated sensibly, and whether an update conflicts with information already stored. A write-back loop can be autonomous, but that does not establish that every write is correct. Establish a process for identifying and repairing bad memories before relying on the system for consequential work.
When tracing is available in the framework or application you select, use it to understand how the workflow proceeded. Confirm the actual observability features and data captured in your chosen setup; the verified context names tracing and evaluations as Mastra capabilities but does not specify an implementation’s precise trace format, retention, or privacy behavior.
Step 8: Introduce the Agent Carefully
Start with a narrow, well-defined use case. For example, evaluate whether memory helps an agent answer recurring questions about project conventions or retrieve the relevant tool for a task. Expand its scope only after you have evidence that retrieval, write-back, and tool interactions behave as intended.
Keep human review in the workflow for code that matters. The verified reporting emphasizes that coding agents can require tedious debugging and remain brittle beyond their training data. Review the changes or recommendations, run the checks appropriate to your project, and make the decision to accept the work yourself. Do not claim that an agent has validated a change unless the relevant validation was actually performed and its result is available.
Before using persistent memory with sensitive or proprietary repositories, decide what may be retained and who can access it. The supplied sources establish architectural ideas about persistent memory, but they do not establish the privacy, retention, security, or data-handling properties of any particular storage provider or model integration. Verify those properties independently for the tools you select.
Key Takeaways
- Treat long-term memory as structured infrastructure outside the model, not as an unbounded transcript.
- Design a lifecycle for loading prior context, retrieving relevant facts and tools, extracting information, consolidating it, and writing updates back.
- Use retrieval to make the current task’s context and tools relevant rather than exposing an ever-growing collection by default.
- Understand the tool-call cycle and account for the cost and performance implications of repeatedly sending conversation history where that design applies.
- Verify runtime, storage, provider, security, and framework APIs in their current documentation; the available evidence does not validate a specific Bun, SQLite, or OpenAI implementation.
- Evaluate the complete system and keep human oversight for coding work, particularly before production use.
Sources and Scope
This tutorial draws on the verified description of DeepLearning.AI’s Agent Memory course for persistent memory, retrieval, structured fact extraction, consolidation, and write-back; reporting on the coding-agent loop and conversation-history growth; and the verified Mastra framework listing for its TypeScript agent capabilities and starter command. These sources support the architecture and cautions described here. They do not verify the original draft’s detailed Bun/SQLite/OpenAI code, exact package compatibility, or security claims.
Top comments (0)