Blackboard
Shared typed scratchpad for multi-agent coordination.
A blackboard gives multiple agents a shared, typed state object. One agent writes findings, another reads them — all validated per-field with Zod so each write is checked without requiring the full board.
const board = blackboard({
id: 'research-board',
schema: z.object({
query: z.string(),
findings: z.array(z.string()),
status: z.enum(['planning', 'researching', 'done']),
}),
store: sharedStore,
})
// Write individual fields (validated per-field)
await board.set('status', 'researching')
await board.patch({ findings: ['Finding 1'], status: 'researching' })
// Read
const status = await board.get('status') // 'researching'
const all = await board.getAll() // full board state
// Subscribe to changes (in-process)
const unsubscribe = board.subscribe((fields) => {
console.log('Changed:', fields) // ['findings', 'status']
})Board writes are in-process only. For cross-process coordination (e.g., separate serverless invocations), provide a persistent store — see Memory for store options.
Prompt and tool integration
Use the board directly in a prompt when the agent should both see shared state and be able to update it:
const agentPrompt = prompt({
use: [board],
})Crux expands that into blackboard context plus four focused tools:
readBlackboard
writeBlackboard
patchBlackboard
clearBlackboardIf you only want the current board state in the system message, use
board.asContext(). If you only want to manually choose tools, use
board.asTools():
prompt({ use: [board.asContext()] }) // context only
const tools = board.asTools()When multiple blackboards are used by the same prompt, prefix their tools:
const research = blackboard({ id: 'research', schema, tools: { prefix: 'research' } })
const writing = blackboard({ id: 'writing', schema, tools: { prefix: 'writing' } })
prompt({ use: [research, writing] })
// readResearchBlackboard, writeResearchBlackboard, readWritingBlackboard, ...