foundation-ai-agent
v1.0.1
Published
12 native protocol layers for AI-agent systems. No wrappers. No SDK dependencies.
Maintainers
Readme
foundation-ai-agent
12 native protocol layers for AI agent systems. No wrappers. No SDK dependencies.
S01 Realtime S05 Rendering S09 Persistence
S02 CRDTs S06 Payments S10 Inference
S03 Streaming S07 Identity S11 Transport
S04 Messaging S08 Containers S12 Version ControlWhy Foundation?
Most AI agent frameworks are prompt orchestrators — they wrap API calls but leave infrastructure (memory, transport, sync, payments, identity) to you. You end up gluing 10+ libraries together.
Foundation is the infrastructure itself. 12 protocol layers that compose into a full agent runtime:
| | LangChain / CrewAI | Foundation | |---|---|---| | Inference | API wrapper | Native providers (Ollama, Anthropic, OpenAI) | | Memory | Plugin required | 3-tier built-in (HOT → WARM → COLD) | | Realtime | Not included | WebRTC signaling + CRDT sync | | Transport | Not included | WebSocket rooms | | Payments | Not included | Stripe billing integration | | Containers | Not included | Docker sandbox isolation | | Dependencies | 50–200+ | 3 |
npm install foundation-ai-agentThe Architecture
src/
├── sXX-name/ Layers. Each stands alone. No cross-imports.
├── touches/ The only bridges between layers. Explicit coupling.
└── compat/ External system bridges. NOT part of the foundation.One rule governs the entire system: Layers never import from sibling layers. All cross-layer integration goes through touches/ -- named, tested, explicit connection points. If two layers need to talk, there is a file in touches/ that says exactly how.
The 12 Layers
| Layer | What it does | Key primitive |
|-------|-------------|---------------|
| S01 Realtime | WebRTC signaling, media types | SignalingMessage (11 types) |
| S02 CRDTs | Distributed state synchronization | SharedDoc (interface-first, yjs impl) |
| S03 Streaming | HLS/DASH segmentation, codecs | Segmenter, PlaylistManager |
| S04 Messaging | Chat, briefings, notifications | Channel (platform-agnostic) |
| S05 Rendering | State machines, avatar gestures | StateMachine<S, E> (generic) |
| S06 Payments | Billing, subscriptions, usage | BillingService (interface-first) |
| S07 Identity | Consent as authorization | observe / assist / act |
| S08 Containers | Process isolation, GPU scheduling | Sandbox, GpuScheduler |
| S09 Persistence | Three-tier cognitive memory | HOT → WARM → COLD |
| S10 Inference | Provider-agnostic agent loop | Provider.stream() → 4 Chunk types |
| S11 Transport | Network abstraction | send() + receive() |
| S12 Version Control | Merkle trees for decision audit | buildTree(), verifyProof() |
The Touch Points
Every connection between layers is a file. Every file is small. The average touch point is 60 lines.
audio-tap.ts S01 ↔ S10 Audio → Transcript → Tokens
stichwort.ts S01 ↔ S10 Keyword detection (pure pipeline)
transport-signal.ts S01 ↔ S11 Signaling ↔ Transport events
crdt-sync.ts S02 ↔ S11 CRDT updates ↔ Transport events
messenger-bridge.ts S04 ↔ S10 Briefing generation via Loop
avatar-state.ts S05 ↔ S10 Inference events → Avatar transitions
cost-billing.ts S06 ↔ Ledger Consent tiers → Pricing tiers
identity-gate.ts S07 ↔ S10 observe=deny, assist=ask, act=allow
container-room.ts S08 ↔ S11 Room → Container isolation
memory-persist.ts S09 ↔ S10 HOT → compact → WARM → flush → COLD
cost-track.ts S10 ↔ Ledger Usage → Cost tracking
version-persist.ts S12 ↔ S09 Merkle DAG → COLD storage
sentiment-tap.ts S01 ↔ S10 Audio → Emotion → DynamicsThe Numbers
74 source files 43 test suites 376 tests
12/12 layers 13 touch points 3 runtime deps
3 providers 0 SDK wrappers 0 AI framework imports
5 production backends (Postgres, S3, Stripe, Docker, Observability)Three runtime dependencies. Each is infrastructure, not abstraction:
| Dependency | Why |
|------------|-----|
| better-sqlite3 | WARM memory (S09) |
| ws | WebSocket transport (S11) |
| yjs | CRDT implementation (S02) |
Quick Start
npm install foundation-ai-agentUse a provider
import { createOllamaProvider, loop, createContext } from 'foundation-ai-agent'
const provider = createOllamaProvider() // localhost:11434
const ctx = createContext({ model: 'qwen2.5:3b', root: '.' })
const gen = loop({
messages: [{ id: '1', role: 'user', content: 'Hello', ts: Date.now() }],
system: 'Be helpful.',
actions: [],
provider,
ctx,
})
for await (const msg of gen) {
console.log(msg.role, typeof msg.content === 'string' ? msg.content : '[blocks]')
}Add actions
import { ok, type Action } from 'foundation-ai-agent'
const search: Action = {
name: 'search',
schema: { name: 'search', description: 'Search', parameters: { type: 'object', properties: { q: { type: 'string' } } } },
concurrent: true,
validate: (input) => ok(input),
gate: () => 'allow',
execute: async (input) => ok(`Results for ${JSON.stringify(input)}`),
}
// Pass to loop({ ... actions: [search] })
// The loop calls validate → gate → execute, batches concurrent actionsThree-tier memory
import { createHotMemory, createWarmMemory, createFsColdMemory, createMemoryStack } from 'foundation-ai-agent'
const hot = createHotMemory({ budget: 50_000 })
const warm = createWarmMemory('./data/warm.db')
const cold = createFsColdMemory('./data/cold')
const memory = createMemoryStack(hot, warm, cold)
// During session: memory.maintain(50_000) compacts when over budget
// End of session: memory.flushToCold('session-id') archives everythingConsent as a layer
import { createIdentity, consentToGate } from 'foundation-ai-agent'
const identity = createIdentity()
const session = identity.initDefaults('user-1')
// Check: can this agent suggest queue items?
const gate = consentToGate(identity, session, { feature: 'queue_suggest', required: 'assist' })
// gate === 'ask' (assist level = host must approve)
// Upgrade to autonomous
identity.setScope(session, 'queue_suggest', 'act')
const gate2 = consentToGate(identity, session, { feature: 'queue_suggest', required: 'assist' })
// gate2 === 'allow' (act level = agent can act autonomously)Multi-agent
import { createAgentRegistry, createOllamaProvider, createAnthropicProvider } from 'foundation-ai-agent'
const registry = createAgentRegistry()
registry.register({
name: 'sebastian-edge',
role: 'classifier',
provider: createOllamaProvider(),
model: 'qwen2.5:3b',
mode: 'act',
budgetCents: 100,
})
registry.register({
name: 'sebastian-cloud',
role: 'researcher',
provider: createAnthropicProvider({ apiKey: '...' }),
model: 'claude-sonnet-4-6',
mode: 'assist',
budgetCents: 5000,
})
registry.perAgent() // cost breakdown per agent
registry.perOrg() // aggregated per organizationDesign Decisions
Errors are values
type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E }No exceptions for control flow. Every function that can fail returns Result. Pattern-match on ok, not try-catch.
4 chunk types standardize all providers
type Chunk =
| { type: 'text'; text: string }
| { type: 'action_call'; id: string; name: string; input: unknown }
| { type: 'usage'; tokens: TokenUsage }
| { type: 'done'; reason: 'complete' | 'action_calls' }Ollama, Anthropic, OpenAI -- all produce the same 4 chunk types. The loop doesn't know which provider it's talking to.
Interface first, implementation second
Every layer defines its contract as a TypeScript type. The implementation is one of many possible:
Providerinterface → Ollama, Anthropic, OpenAI implementationsSharedDocinterface → yjs implementation (Automerge, diamond-types possible)Transportinterface → WebSocket, local, IPC implementationsColdMemoryinterface → Filesystem + S3/R2 implementationsBillingServiceinterface → In-memory + Stripe implementationsSandboxinterface → In-memory + Docker implementations
Open unions
Every union type is extensible:
type EntryCategory = 'decision' | 'fact' | 'action_item' | ... | (string & {})
type ArtifactType = 'transcript' | 'document' | 'media' | ... | (string & {})
type Feature = 'listening' | 'mirror_mode' | ... | (string & {})No layer is closed. No external system is locked out.
Consent is not a feature -- it is infrastructure
Three levels. Three meanings. One mapping:
observe → deny (can only watch)
assist → ask (can suggest, host approves)
act → allow (autonomous action)This maps 1:1 to pricing tiers (free/professional/enterprise), gate decisions (deny/ask/allow), and autonomy levels. It is the single most load-bearing abstraction in the system.
What Emerges
Properties that no single layer has alone:
| Combination | Emergence | |-------------|-----------| | S07 + S10 | Ethical autonomy -- consent gates action execution | | S09 HOT+WARM+COLD | Cognitive memory -- compaction = memory formation | | S06 + S07 | Monetized autonomy -- consent levels = pricing tiers | | S08 + S10 | Isolated execution -- each agent in its own sandbox | | S12 + S09 | Auditable history -- Merkle proofs for every decision | | All 12 layers | Mirror Mode -- autonomous agent with ethical boundary, cost limit, audit trail, visual transparency |
Tested
376 tests across 43 test suites. Unit tests per layer, integration tests across layer boundaries, E2E tests against real Ollama and WebSocket servers.
# Development
git clone https://github.com/relstar911/foundation.git
cd foundation
npm install
npm test # 376 tests
npm run check # tsc --noEmit
npm run build # emit dist/Project Structure
src/
├── index.ts Public API
├── types.ts Result, Message, Entry, Event
├── ledger.ts Cost tracking
│
├── s01-realtime/ WebRTC signaling + media types
├── s02-crdt/ SharedDoc interface + yjs
├── s03-streaming/ HLS segmentation + playlists
├── s04-messaging/ Chat, briefings, channels
├── s05-rendering/ StateMachine + avatar gestures
├── s06-payments/ Billing + subscriptions
├── s07-identity/ Consent (observe/assist/act)
├── s08-containers/ Sandbox + GPU scheduler
├── s09-persistence/ HOT (memory) + WARM (SQLite) + COLD (fs)
├── s10-inference/ Provider → Action → Loop
│ ├── providers/ Ollama, Anthropic, OpenAI (raw fetch)
│ └── agents/ Multi-agent registry, mirror mode
├── s11-transport/ Transport + WebSocket + Room
├── s12-versioncontrol/ Merkle trees + DAG
│
├── touches/ 13 cross-layer bridges
└── compat/ External system bridgesTypeScript
Strict mode. No any. No unguarded index access. Result<T,E> for all fallible operations. Context<Ext> is generic for type-safe domain extensions.
{
"strict": true,
"noUncheckedIndexedAccess": true,
"target": "ES2022",
"module": "NodeNext"
}License
MIT
