Sandcastle Integration
Give your Sandcastle agents persistent memory across runs using Synapse.
Sandcastle orchestrates AI coding agents in isolated sandboxes. By default, each run is stateless — the agent starts cold with no knowledge of what it did before. Synapse adds a persistent memory layer: agents load prior context at the start of each run and save key outputs at the end. Every run builds on the last.
Install
npm install @ai-hero/sandcastleSynapse helper module
Add this file to your project. It exposes three functions: remember (write a record), recall (semantic search), and recent (fetch the latest records). These are the only Synapse calls your agent needs.
// src/synapse.ts — Synapse memory helpers for Sandcastle agents
const BASE = 'https://synapse.by-kit.com/api/v1'
const AGENT_ID = process.env.SYNAPSE_AGENT_ID || 'sandcastle-agent'
async function request(method: string, path: string, body?: object) {
const key = process.env.SYNAPSE_API_KEY
if (!key) throw new Error('SYNAPSE_API_KEY is required')
const res = await fetch(`${BASE}${path}`, {
method,
headers: {
Authorization: `Bearer ${key}`,
'Content-Type': 'application/json',
},
body: body ? JSON.stringify(body) : undefined,
})
return res.json()
}
export async function remember(title: string, body: string, type = 'fact') {
return request('POST', '/record', { agent_id: AGENT_ID, title, body, type })
}
export async function recall(query: string, limit = 5): Promise<string> {
const records = await request('GET', `/query?q=${encodeURIComponent(query)}&limit=${limit}`, undefined)
if (!Array.isArray(records) || records.length === 0) return 'No prior memory found.'
return records.map((r: any) => `[${r.title}] ${r.body}`).join('\n---\n')
}
export async function recent(limit = 5): Promise<string> {
const records = await request('GET', `/query?limit=${limit}`, undefined)
if (!Array.isArray(records) || records.length === 0) return 'No prior memory found.'
return records.map((r: any) => `[${r.title}] ${r.body}`).join('\n---\n')
}Agent with persistent memory
The full pattern — load memory → inject into prompt → run agent → save outputs:
// src/run.ts — Sandcastle agent with Synapse memory
import { run, claudeCode } from '@ai-hero/sandcastle'
import { docker } from '@ai-hero/sandcastle/sandboxes/docker'
import { remember, recall, recent } from './synapse.js'
async function main() {
// Step 1: Load prior context from Synapse
console.log('Loading prior memory from Synapse...')
const priorMemory = await recent(5)
const taskContext = await recall('codebase architecture patterns', 3)
// Step 2: Build the prompt with injected memory
const prompt = `
You are a code analysis agent with persistent memory.
## What you remember from prior runs:
${priorMemory}
## Prior context on this codebase:
${taskContext}
## Your task for this run:
1. Analyze the codebase in the current directory
2. Identify the 3 most important architectural decisions
3. Note any patterns, anti-patterns, or tech debt
4. Write your findings to a file called ANALYSIS.md
Be specific. You have memory of prior runs — build on it, don't repeat it.
`.trim()
// Step 3: Run the agent in an isolated sandbox
console.log('Starting Sandcastle agent...')
const result = await run({
agent: claudeCode('claude-opus-4-7'),
sandbox: docker(),
prompt,
})
console.log(`Agent completed in ${result.iterations.length} iterations`)
// Step 4: Save key outputs back to Synapse
const lastIteration = result.iterations[result.iterations.length - 1]
const agentOutput = lastIteration?.output || 'No output captured'
await remember(
`Code analysis run ${new Date().toISOString().slice(0, 10)}`,
agentOutput.slice(0, 2000),
'analysis'
)
console.log('Memory saved to Synapse. Agent will remember this next run.')
}
main().catch(console.error)How it works
- Load memory — query Synapse for recent records and task-specific context before the agent runs
- Inject into prompt — include that memory in the agent's system prompt so it knows what happened before
- Run the agent — Sandcastle spins up Claude Code in an isolated Docker sandbox
- Save outputs — write key findings back to Synapse so the next run has them
Full example repo
A complete working project with all files, README, and .env.example: github.com/jfulmines/synapse-sandcastle-example