oneie
Version:
Build apps, websites, and AI agents in English. Zero-interaction setup for AI agents (Claude Code, Cursor, Windsurf). Download to your computer, run in the cloud, deploy to the edge. Open source and free forever.
1,311 lines (1,033 loc) • 34.6 kB
Markdown
title: Ontology Engineering Specification
dimension: knowledge
category: ontology-engineering-specification.md
tags: 6-dimensions, agent, ai, architecture, backend, frontend, ontology
related_dimensions: connections, events, people, things
scope: global
created: 2025-11-03
updated: 2025-11-03
version: 1.0.0
ai_context: |
This document is part of the knowledge dimension in the ontology-engineering-specification.md category.
Location: one/knowledge/ontology-engineering-specification.md
Purpose: Documents one ontology engineering
Related dimensions: connections, events, people, things
For AI agents: Read this to understand ontology engineering specification.
# ONE Ontology Engineering
**Version:** 1.0.0
**Purpose:** Context Engineering, Agent Architecture, and Dynamic Website Generation
**Philosophy:** Minimal Context, Maximum Intelligence
## Table of Contents
1. [Context Engineering Strategy](#context-engineering-strategy)
2. [Specialist AI Agent Architecture](#specialist-ai-agent-architecture)
3. [Frontend/Backend Implementation](#frontendbackend-implementation)
4. [Dynamic Website Generation](#dynamic-website-generation)
5. [Code Generation Patterns](#code-generation-patterns)
6. [Performance Optimization](#performance-optimization)
## Context Engineering Strategy
### The Problem: Context Window Explosion
**Traditional Approach (❌ Bad):**
```
AI reads entire codebase → 100k+ tokens → expensive, slow, hallucinations
```
**ONE Approach (✅ Good):**
```
AI queries ontology → focused retrieval → <5k tokens → fast, accurate, cheap
```
### Principle 1: Ontology as Context Compression
The 6-dimension ontology IS our context compression:
```typescript
// Instead of loading 50 files (30k tokens):
const allUsers = readFiles(['users.ts', 'auth.ts', 'sessions.ts', ...])
// Query the ontology (500 tokens):
const context = {
things: ['creator', 'audience_member'],
connections: ['member_of'],
events: ['user_login', 'user_registered']
}
```
**Result:** 98% context reduction with full semantic fidelity.
### Principle 2: Just-In-Time Context Loading
**Strategy:** Load context ONLY when needed, not upfront.
```typescript
// ❌ BAD: Load everything
const fullOntology = await loadOntology() // 15k tokens
// ✅ GOOD: Load on demand
async function getRelevantContext(userIntent: string) {
const embedding = await embed(userIntent)
const relevantChunks = await vectorSearch(embedding, { k: 3 }) // 800 tokens
const relevantThings = await getThingsByType(extractTypes(relevantChunks)) // 300 tokens
return { chunks: relevantChunks, things: relevantThings } // Total: 1,100 tokens
}
```
### Principle 3: Query-First Architecture
**Pattern:** Every operation starts with a focused query.
```typescript
// User request: "Show me all fitness creators"
// Step 1: Parse intent
const intent = {
thingType: 'creator',
filter: { niche: 'fitness' },
connections: undefined,
events: undefined
}
// Step 2: Focused query (only what's needed)
const creators = await db
.query('things')
.withIndex('by_type', q => q.eq('type', 'creator'))
.filter(q => q.field('properties.niche').includes('fitness'))
.take(10) // ALWAYS LIMIT
// Step 3: Load related data IF NEEDED
if (needsStats) {
const stats = await getCreatorStats(creators.map(c => c._id))
}
```
**Context Used:**
- Intent parsing: ~200 tokens
- Query: ~50 tokens
- Results: ~500 tokens
- **Total: ~750 tokens** (vs 10k+ for full creator records)
### Principle 4: Contextual Caching
**Strategy:** Cache frequently accessed ontology patterns.
```typescript
// Cache structure
const ontologyCache = {
// Thing type definitions (rarely change)
thingTypes: Map<ThingType, ThingDefinition>, // ~2k tokens
// Connection patterns (rarely change)
connectionTypes: Map<ConnectionType, ConnectionDefinition>, // ~1k tokens
// Event types (rarely change)
eventTypes: Map<EventType, EventDefinition>, // ~1k tokens
// Organization-specific (cache per org, TTL: 5 min)
orgSchema: Map<OrgId, OrgContext>, // ~500 tokens per org
// User-specific (cache per session, TTL: 1 hour)
userContext: Map<UserId, UserContext>, // ~300 tokens per user
}
// Total cold start: ~5k tokens
// Total warm (per request): ~800 tokens
```
### Principle 5: Semantic Compression via Knowledge
**Strategy:** Use knowledge embeddings to compress semantic meaning.
```typescript
// Instead of passing full documentation (5k tokens):
const docs = `
The creator entity represents a human creator...
Properties include email, username, niche...
Creators can own ai_clones and create content...
[3000+ more words]
`
// Pass compressed reference (50 tokens + retrieval):
const creatorContext = {
thingType: 'creator',
knowledgeRef: 'knowledge_item_creator_docs', // Vector retrieval when needed
quickRef: 'Human creator with email, username, niche. Owns clones & content.'
}
// AI retrieves detailed docs ONLY if needed
if (needsDetail) {
const detailedDocs = await retrieveKnowledge('knowledge_item_creator_docs')
}
```
## Specialist AI Agent Architecture
### Agent Design Philosophy
**Traditional Monolithic Agent (❌ Bad):**
```
One agent tries to do everything → 50k token context → slow, expensive, confused
```
**ONE Specialist Agents (✅ Good):**
```
10 specialist agents, each expert in one domain → 3k tokens each → fast, cheap, accurate
```
### Core Agent Types
#### 1. **Ontology Agent** - The Router
**Purpose:** Parse user intent and route to specialist agents.
**Context Budget:** 2k tokens max
**Capabilities:**
- Intent classification
- Entity/connection/event identification
- Agent routing
```typescript
interface OntologyAgent {
parseIntent(userInput: string): Intent
routeToAgent(intent: Intent): SpecialistAgent
context: {
ontologyTypes: ThingType[] // Cached
connectionTypes: ConnectionType[] // Cached
eventTypes: EventType[] // Cached
}
}
// Example
const intent = await ontologyAgent.parseIntent("Create a fitness course")
// Returns: { action: 'create', thingType: 'course', metadata: { niche: 'fitness' } }
const agent = ontologyAgent.routeToAgent(intent)
// Returns: ContentCreationAgent
```
#### 2. **Schema Agent** - Database Structure Expert
**Purpose:** Generate Convex schemas, indexes, and migrations.
**Context Budget:** 3k tokens max
**Capabilities:**
- Schema generation
- Index optimization
- Migration planning
```typescript
interface SchemaAgent {
generateSchema(thingTypes: ThingType[]): ConvexSchema
optimizeIndexes(queryPatterns: QueryPattern[]): IndexDefinition[]
planMigration(from: Schema, to: Schema): MigrationPlan
context: {
ontologySpec: OntologyReference // Links to detailed docs
indexPatterns: IndexPattern[] // Common patterns
validationRules: ValidationRule[]
}
}
// Example
const schema = await schemaAgent.generateSchema(['creator', 'course', 'lesson'])
// Returns optimized Convex schema with indexes
```
#### 3. **Query Agent** - Database Query Expert
**Purpose:** Generate optimized Convex queries.
**Context Budget:** 2k tokens max
**Capabilities:**
- Query generation
- Query optimization
- Index selection
```typescript
interface QueryAgent {
generateQuery(intent: QueryIntent): ConvexQuery
optimizeQuery(query: ConvexQuery): ConvexQuery
explainQuery(query: ConvexQuery): QueryExplanation
context: {
availableIndexes: Index[] // Current DB indexes
queryPatterns: QueryPattern[] // Common patterns
}
}
// Example
const query = await queryAgent.generateQuery({
thingType: 'creator',
filter: { niche: 'fitness', totalFollowers: { $gt: 10000 } },
limit: 10
})
// Returns optimized Convex query with correct index usage
```
#### 4. **Mutation Agent** - Database Write Expert
**Purpose:** Generate Convex mutations with proper validation and events.
**Context Budget:** 3k tokens max
**Capabilities:**
- Mutation generation
- Validation logic
- Event logging
- Transaction handling
```typescript
interface MutationAgent {
generateMutation(action: MutationIntent): ConvexMutation
addValidation(mutation: ConvexMutation): ConvexMutation
logEvents(mutation: ConvexMutation): ConvexMutation
context: {
validationRules: ValidationRule[]
eventTypes: EventType[]
transactionPatterns: TransactionPattern[]
}
}
// Example
const mutation = await mutationAgent.generateMutation({
action: 'create',
thingType: 'course',
properties: { title: 'Fitness 101', niche: 'fitness' },
connections: [{ type: 'owns', fromId: creatorId }]
})
// Returns mutation with validation + event logging + connection creation
```
#### 5. **Frontend Component Agent** - UI Generator
**Purpose:** Generate Astro/React components from ontology.
**Context Budget:** 4k tokens max
**Capabilities:**
- Component generation
- Type-safe props
- Convex integration
- Styling with Tailwind
```typescript
interface FrontendAgent {
generateComponent(spec: ComponentSpec): AstroComponent
generatePage(spec: PageSpec): AstroPage
generateAPI(spec: APISpec): HonoRoute
context: {
componentPatterns: ComponentPattern[] // Reusable patterns
designSystem: DesignTokens // Colors, spacing, etc.
ontologyTypes: ThingType[] // For type generation
}
}
// Example
const component = await frontendAgent.generateComponent({
name: 'CourseCard',
thingType: 'course',
fields: ['title', 'description', 'price'],
actions: ['enroll', 'view']
})
// Returns fully typed Astro component with Convex hooks
```
#### 6. **Backend Logic Agent** - Business Logic Expert
**Purpose:** Generate Convex actions and complex business logic.
**Context Budget:** 4k tokens max
**Capabilities:**
- Action generation
- External API integration
- Workflow orchestration
- Error handling
```typescript
interface BackendAgent {
generateAction(spec: ActionSpec): ConvexAction
orchestrateWorkflow(steps: WorkflowStep[]): WorkflowAction
handleErrors(action: ConvexAction): ConvexAction
context: {
workflowPatterns: WorkflowPattern[]
integrationPatterns: IntegrationPattern[]
errorPatterns: ErrorPattern[]
}
}
// Example
const action = await backendAgent.generateAction({
name: 'createCourseWithAI',
steps: [
'generateContent',
'createCourse',
'embedContent',
'notifyCreator'
]
})
// Returns orchestrated Convex action with error handling
```
#### 7. **Knowledge Agent** - RAG & Embeddings Expert
**Purpose:** Manage knowledge embeddings and semantic search.
**Context Budget:** 3k tokens max
**Capabilities:**
- Embedding generation
- Vector search
- Chunk optimization
- Label management
```typescript
interface KnowledgeAgent {
embedContent(thing: Thing, fields: string[]): Knowledge[]
semanticSearch(query: string, filters: Filter): Knowledge[]
optimizeChunks(text: string): Chunk[]
manageLabels(thing: Thing): Label[]
context: {
embeddingModel: 'text-embedding-3-large'
chunkStrategy: ChunkStrategy
labelTaxonomy: LabelCategory[]
}
}
// Example
const chunks = await knowledgeAgent.embedContent(course, ['title', 'description', 'content'])
// Returns knowledge chunks with embeddings + links via thingKnowledge
```
#### 8. **Organization Agent** - Multi-Tenant Expert
**Purpose:** Manage organization scope, permissions, quotas.
**Context Budget:** 2k tokens max
**Capabilities:**
- Scope enforcement
- Permission checks
- Quota tracking
- Billing logic
```typescript
interface OrganizationAgent {
enforceScope(query: Query, orgId: OrgId): Query
checkPermissions(userId: UserId, action: Action): boolean
trackUsage(orgId: OrgId, resource: Resource): Usage
context: {
orgPlans: Plan[] // starter, pro, enterprise
quotaLimits: QuotaLimit[]
permissionMatrix: Permission[][]
}
}
// Example
const scopedQuery = await orgAgent.enforceScope(rawQuery, orgId)
// Returns query filtered to org's data only
```
#### 9. **Analytics Agent** - Metrics & Insights Expert
**Purpose:** Generate analytics from events and metrics.
**Context Budget:** 3k tokens max
**Capabilities:**
- Metric calculation
- Insight generation
- Prediction models
- Report generation
```typescript
interface AnalyticsAgent {
calculateMetrics(orgId: OrgId, period: Period): Metrics
generateInsights(metrics: Metrics): Insight[]
predictTrends(history: Metrics[]): Prediction[]
context: {
metricDefinitions: MetricDef[]
insightPatterns: InsightPattern[]
predictionModels: Model[]
}
}
// Example
const insights = await analyticsAgent.generateInsights(metrics)
// Returns actionable insights with confidence scores
```
#### 10. **Protocol Agent** - Cross-Protocol Expert
**Purpose:** Handle A2A, ACP, AP2, X402, AG-UI integrations.
**Context Budget:** 4k tokens max
**Capabilities:**
- Protocol detection
- Message formatting
- Transaction handling
- Cross-chain bridges
```typescript
interface ProtocolAgent {
detectProtocol(request: Request): Protocol
formatMessage(data: any, protocol: Protocol): Message
handleTransaction(tx: Transaction, protocol: Protocol): Event
context: {
protocolSpecs: ProtocolSpec[] // A2A, ACP, AP2, X402, AG-UI
networkConfigs: NetworkConfig[] // Base, Sui, Solana
}
}
// Example
const message = await protocolAgent.formatMessage(purchase, 'acp')
// Returns ACP-formatted commerce message
```
## Agent Orchestration Pattern
### Sequential Coordination
```typescript
// User: "Create a fitness course and publish it to my website"
// 1. Ontology Agent routes
const intent = await ontologyAgent.parse("Create fitness course...")
// → { actions: ['create_course', 'publish_website'] }
// 2. Mutation Agent creates course
const course = await mutationAgent.create({
thingType: 'course',
properties: { title: '...', niche: 'fitness' }
})
// 3. Knowledge Agent embeds content
await knowledgeAgent.embed(course, ['title', 'description', 'modules'])
// 4. Frontend Agent generates page
const page = await frontendAgent.generatePage({
thingType: 'course',
thingId: course._id
})
// 5. Backend Agent deploys
await backendAgent.deploy(page, { domain: creator.properties.domain })
// Total context: 2k + 3k + 3k + 4k + 4k = 16k tokens
// vs Monolithic: 80k+ tokens
```
### Parallel Execution
```typescript
// User: "Analyze my creator platform performance"
// Ontology Agent routes to multiple specialists
const [metrics, insights, predictions] = await Promise.all([
analyticsAgent.calculateMetrics(orgId, '30d'),
analyticsAgent.generateInsights(/* ... */),
analyticsAgent.predictTrends(/* ... */)
])
// Each agent runs in parallel with own context
// Total context: max(3k, 3k, 3k) = 3k tokens (not additive!)
```
## Frontend/Backend Implementation
### Architecture Overview
```
┌─────────────────────────────────────────────────────────┐
│ FRONTEND (Astro) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Pages │ │ Components │ │ API │ │
│ │ (SSR/SSG) │ │ (React) │ │ (Hono) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ └─────────────────┴─────────────────┘ │
│ ↓ │
│ ConvexHttpClient │
└────────────────────────────┬────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────┐
│ BACKEND (Convex) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐│
│ │ Queries │ │Mutations │ │ Actions │ │Scheduler││
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬────┘│
│ │ │ │ │ │
│ └─────────────┴──────────────┴──────────────┘ │
│ ↓ │
│ ┌────────────────────────┐ │
│ │ 6-Dimension Ontology │ │
│ │ things │ connections │ │ │
│ │ events │ knowledge │ │ │
│ └────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
```
### Context-Aware Query Pattern
**Traditional (❌ Bad):**
```typescript
// Load everything, filter in memory
const allThings = await db.query('things').collect() // 50k records
const filtered = allThings.filter(t => t.type === 'course')
```
**Context-Optimized (✅ Good):**
```typescript
// Query with index, limit results
const courses = await db
.query('things')
.withIndex('by_type', q => q.eq('type', 'course'))
.take(20) // ALWAYS PAGINATE
// Load related data ONLY if needed
if (needsCreators) {
const creatorIds = [...new Set(courses.map(c => c.properties.creatorId))]
const creators = await db.getMany(creatorIds) // Batch fetch
}
```
### Dynamic Component Generation
**Pattern:** Generate components from ontology at build time.
```typescript
// scripts/generate-components.ts
import { ontology } from './ontology'
import { FrontendAgent } from './agents/frontend'
// Generate component for each thing type
for (const thingType of ontology.thingTypes) {
// Generate card component
const card = await frontendAgent.generateComponent({
name: `${thingType}Card`,
thingType,
fields: ontology.getDisplayFields(thingType),
variant: 'card'
})
await writeFile(`src/components/cards/${thingType}Card.tsx`, card)
// Generate list component
const list = await frontendAgent.generateComponent({
name: `${thingType}List`,
thingType,
variant: 'list',
pagination: true
})
await writeFile(`src/components/lists/${thingType}List.tsx`, list)
// Generate detail page
const page = await frontendAgent.generatePage({
name: `${thingType}Detail`,
thingType,
sections: ['header', 'properties', 'connections', 'events']
})
await writeFile(`src/pages/${thingType}/[id].astro`, page)
}
// Result: 66 thing types × 3 components = 198 auto-generated components
```
### Backend Query Optimization
**Pattern:** Use indexes and batching to minimize context.
```typescript
// Convex query with index optimization
export const getCourseWithRelations = query({
args: { courseId: v.id('things') },
handler: async (ctx, { courseId }) => {
// 1. Get course (1 read)
const course = await ctx.db.get(courseId)
if (!course) return null
// 2. Get creator via connection (index scan, not full table)
const ownerConn = await ctx.db
.query('connections')
.withIndex('to_type', q =>
q.eq('toThingId', courseId).eq('relationshipType', 'owns')
)
.first()
// 3. Get creator (1 read)
const creator = ownerConn ? await ctx.db.get(ownerConn.fromThingId) : null
// 4. Get lessons via connection (index scan)
const lessonConns = await ctx.db
.query('connections')
.withIndex('from_type', q =>
q.eq('fromThingId', courseId).eq('relationshipType', 'part_of')
)
.collect()
// 5. Batch fetch lessons (N reads in parallel)
const lessons = await Promise.all(
lessonConns.map(c => ctx.db.get(c.toThingId))
)
// Total: 3 + N reads (vs full table scans)
return { course, creator, lessons }
}
})
```
## Dynamic Website Generation
### Concept: Organizations Create Custom Websites
**Flow:**
```
1. Organization creates account
2. Chooses template (minimal, showcase, portfolio)
3. Customizes branding (colors, logo, domain)
4. Creates content (courses, blog posts, products)
5. ONE auto-generates website at org.one.ie
```
### Implementation Strategy
#### 1. Template System
**Static Templates** (pre-built):
```typescript
// templates/minimal.ts
export const minimalTemplate: Template = {
name: 'minimal',
sections: ['hero', 'about', 'content', 'footer'],
thingTypes: ['creator', 'blog_post', 'course'],
colors: {
primary: 'blue-600',
secondary: 'gray-800',
accent: 'green-500'
}
}
```
**Dynamic Generation**:
```typescript
// Generate website for organization
export async function generateWebsite(orgId: Id<'things'>) {
// 1. Get org preferences
const org = await db.get(orgId)
const template = templates[org.properties.template || 'minimal']
// 2. Get org's things
const things = await db
.query('things')
.filter(q => q.eq(q.field('groupId'), orgId))
.collect()
// 3. Generate pages
const pages = []
// Homepage
pages.push(await frontendAgent.generatePage({
template: 'homepage',
sections: template.sections,
data: { org, creators: things.filter(t => t.type === 'creator') }
}))
// Content pages (one per thing)
for (const thing of things) {
pages.push(await frontendAgent.generatePage({
template: 'detail',
thingType: thing.type,
data: thing
}))
}
// 4. Deploy to org.one.ie
await deploy(pages, { domain: `${org.properties.slug}.one.ie` })
}
```
#### 2. Component-Based Pages
**Pattern:** Pages are composed of thing-based components.
```astro
// [orgSlug]/index.astro (auto-generated)
import { ConvexHttpClient } from 'convex/browser'
import Hero from '@/components/Hero.astro'
import CreatorCard from '@/components/cards/CreatorCard.tsx'
import CourseList from '@/components/lists/CourseList.tsx'
const convex = new ConvexHttpClient(import.meta.env.PUBLIC_CONVEX_URL)
// Get org
const org = await convex.query(api.queries.orgs.getBySlug, {
slug: Astro.params.orgSlug
})
// Get creators
const creators = await convex.query(api.queries.things.list, {
type: 'creator',
groupId: org._id
})
// Get courses
const courses = await convex.query(api.queries.things.list, {
type: 'course',
groupId: org._id,
limit: 6
})
<Layout title={org.name}>
<Hero
title={org.name}
subtitle={org.properties.description}
cta="Explore Courses"
/>
<section class="creators">
<h2>Our Creators</h2>
<div class="grid">
{creators.map(creator => (
<CreatorCard client:load creator={creator} />
))}
</div>
</section>
<section class="courses">
<h2>Featured Courses</h2>
<CourseList client:load courses={courses} />
</section>
</Layout>
```
#### 3. Real-Time Updates
**Pattern:** Components subscribe to changes.
```tsx
// components/cards/CourseCard.tsx
import { useQuery } from 'convex/react'
import { api } from '@/convex/_generated/api'
export function CourseCard({ courseId }: { courseId: Id<'things'> }) {
// Real-time subscription
const course = useQuery(api.queries.things.get, { id: courseId })
if (!course) return <Skeleton />
return (
<div class="card">
<img src={course.properties.thumbnail} alt={course.properties.title} />
<h3>{course.properties.title}</h3>
<p>{course.properties.description}</p>
<span>${course.properties.price}</span>
<button>Enroll Now</button>
</div>
)
}
```
**When creator updates course → Component auto-updates on all visitors' screens**
#### 4. Multi-Tenant Routing
**Pattern:** Route to correct org's website.
```typescript
// middleware/tenant.ts
export async function onRequest(context, next) {
const url = new URL(context.request.url)
// Extract org slug from subdomain
const hostname = url.hostname // creator.one.ie
const orgSlug = hostname.split('.')[0]
// Load org context
const org = await convex.query(api.queries.orgs.getBySlug, { slug: orgSlug })
if (!org) {
return new Response('Organization not found', { status: 404 })
}
// Inject org context into request
context.locals.org = org
context.locals.orgId = org._id
return next()
}
```
## Code Generation Patterns
### 1. Thing → CRUD Components
**Input:** Thing type definition
**Output:** Full CRUD components
```typescript
async function generateCRUD(thingType: ThingType) {
const definition = ontology.getDefinition(thingType)
// Generate list component
const list = `
import { useQuery } from 'convex/react'
import { api } from '@/convex/_generated/api'
export function ${pascalCase(thingType)}List({ orgId }) {
const items = useQuery(api.queries.${thingType}.list, { orgId })
return (
<div class="grid gap-4">
{items?.map(item => (
<${pascalCase(thingType)}Card key={item._id} item={item} />
))}
</div>
)
}
`
// Generate create form
const form = `
import { useMutation } from 'convex/react'
import { api } from '@/convex/_generated/api'
export function Create${pascalCase(thingType)}() {
const create = useMutation(api.mutations.${thingType}.create)
return (
<form onSubmit={async (e) => {
e.preventDefault()
const formData = new FormData(e.currentTarget)
await create({
${definition.fields.map(f => `${f.name}: formData.get('${f.name}')`).join(',\n ')}
})
}}>
${definition.fields.map(f => `
<label>
${f.label}
<input name="${f.name}" type="${f.inputType}" required={${f.required}} />
</label>
`).join('\n')}
<button type="submit">Create</button>
</form>
)
}
`
// Generate backend mutations
const mutations = `
import { v } from 'convex/values'
import { mutation } from './_generated/server'
export const create = mutation({
args: {
${definition.fields.map(f => `${f.name}: v.${f.vType}()`).join(',\n ')}
},
handler: async (ctx, args) => {
// Create thing
const id = await ctx.db.insert('things', {
type: '${thingType}',
name: args.${definition.nameField || 'name'},
properties: args,
status: 'active',
createdAt: Date.now(),
updatedAt: Date.now()
})
// Log event
await ctx.db.insert('events', {
type: 'entity_created',
actorId: ctx.auth.userId,
targetId: id,
timestamp: Date.now(),
metadata: { thingType: '${thingType}' }
})
return id
}
})
`
return { list, form, mutations }
}
```
### 2. Connection → Relationship Components
**Input:** Connection type definition
**Output:** Relationship management UI
```typescript
async function generateRelationshipUI(connectionType: ConnectionType) {
// Generate "Add Connection" button
const addButton = `
export function Add${pascalCase(connectionType)}({ fromId, toType }) {
const [open, setOpen] = useState(false)
const createConnection = useMutation(api.mutations.connections.create)
return (
<>
<button onClick={() => setOpen(true)}>
Add {connectionType}
</button>
<Dialog open={open} onClose={() => setOpen(false)}>
<ThingPicker
type={toType}
onSelect={async (toId) => {
await createConnection({
fromThingId: fromId,
toThingId: toId,
relationshipType: '${connectionType}'
})
setOpen(false)
}}
/>
</Dialog>
</>
)
}
`
// Generate "Show Connections" list
const list = `
export function ${pascalCase(connectionType)}List({ thingId }) {
const connections = useQuery(api.queries.connections.list, {
fromThingId: thingId,
relationshipType: '${connectionType}'
})
return (
<div>
<h3>{connectionType}s</h3>
{connections?.map(conn => (
<ConnectionCard key={conn._id} connection={conn} />
))}
</div>
)
}
`
return { addButton, list }
}
```
### 3. Event → Analytics Dashboard
**Input:** Event types for org
**Output:** Analytics dashboard
```typescript
async function generateAnalyticsDashboard(orgId: Id<'things'>) {
// Get all event types used by this org
const eventTypes = await db
.query('events')
.filter(q => q.eq(q.field('groupId'), orgId))
.collect()
.then(events => [...new Set(events.map(e => e.type))])
// Generate metrics for each event type
const dashboard = `
export function AnalyticsDashboard({ orgId }) {
${eventTypes.map(type => `
const ${camelCase(type)}Count = useQuery(api.queries.analytics.count, {
orgId,
eventType: '${type}',
period: '30d'
})
`).join('\n')}
return (
<div class="dashboard">
${eventTypes.map(type => `
<MetricCard
title="${titleCase(type)}"
value={${camelCase(type)}Count}
change={calculateChange(${camelCase(type)}Count)}
/>
`).join('\n')}
</div>
)
}
`
return dashboard
}
```
---
## Performance Optimization
### 1. Context Budget Management
**Rule:** Every agent has a max context budget.
```typescript
class Agent {
maxContextTokens = 5000
currentContext: any[] = []
async addContext(item: any) {
const tokens = estimateTokens(item)
if (this.totalTokens() + tokens > this.maxContextTokens) {
// Evict least recently used context
this.evictLRU()
}
this.currentContext.push({ item, tokens, lastUsed: Date.now() })
}
totalTokens() {
return this.currentContext.reduce((sum, c) => sum + c.tokens, 0)
}
evictLRU() {
this.currentContext.sort((a, b) => a.lastUsed - b.lastUsed)
this.currentContext.shift()
}
}
```
### 2. Query Result Caching
**Pattern:** Cache query results to avoid redundant DB reads.
```typescript
// Convex query with caching
export const getCourseWithRelations = query({
args: { courseId: v.id('things') },
handler: async (ctx, { courseId }) => {
// Check cache first
const cacheKey = `course:${courseId}`
const cached = await ctx.db.get(/* cache table */)
if (cached && Date.now() - cached.timestamp < 5 * 60 * 1000) {
return cached.data
}
// Fetch from DB
const data = await fetchCourseWithRelations(ctx, courseId)
// Cache result
await ctx.db.insert('cache', {
key: cacheKey,
data,
timestamp: Date.now(),
ttl: 5 * 60 * 1000
})
return data
}
})
```
### 3. Lazy Loading
**Pattern:** Load data only when visible.
```tsx
export function ThingGrid({ things }: { things: Thing[] }) {
return (
<div class="grid">
{things.map(thing => (
<LazyLoad key={thing._id} offset={100}>
<ThingCard thingId={thing._id} />
</LazyLoad>
))}
</div>
)
}
function ThingCard({ thingId }: { thingId: Id<'things'> }) {
// Only queries when visible
const thing = useQuery(api.queries.things.get, { id: thingId })
if (!thing) return <Skeleton />
return <Card {...thing} />
}
```
### 4. Batch Operations
**Pattern:** Batch creates/updates to reduce mutations.
```typescript
// Instead of N mutations
for (const lesson of lessons) {
await createLesson(lesson) // N calls
}
// Batch into 1 mutation
export const createLessonsBatch = mutation({
args: { lessons: v.array(v.any()) },
handler: async (ctx, { lessons }) => {
const ids = []
for (const lesson of lessons) {
const id = await ctx.db.insert('things', {
type: 'lesson',
name: lesson.title,
properties: lesson,
status: 'active',
createdAt: Date.now(),
updatedAt: Date.now()
})
ids.push(id)
}
// Single event for batch
await ctx.db.insert('events', {
type: 'entity_created',
actorId: ctx.auth.userId,
timestamp: Date.now(),
metadata: {
thingType: 'lesson',
batchSize: lessons.length,
ids
}
})
return ids
}
})
```
## Summary: Engineering Principles
### 1. **Minimal Context is Beautiful**
- Never load full ontology
- Query-first, load-on-demand
- Cache frequently used patterns
- Evict stale context aggressively
### 2. **Specialist Agents Win**
- 10 small experts beat 1 generalist
- Each agent has focused context
- Agents compose via orchestration
- Parallel execution when possible
### 3. **Ontology Drives Everything**
- Schema generation from ontology
- Component generation from thing types
- Query optimization from indexes
- Analytics from event types
### 4. **Dynamic is Better Than Static**
- Generate components at build time
- Generate pages from org content
- Real-time updates via subscriptions
- Multi-tenant routing
### 5. **Performance Through Design**
- Index-first queries
- Batch operations
- Lazy loading
- Result caching
## Next Steps
1. **Implement Core Agents**
- Start with Ontology Agent (router)
- Add Query Agent (most used)
- Add Mutation Agent (critical path)
2. **Build Code Generators**
- Thing → CRUD components
- Connection → Relationship UI
- Event → Analytics dashboards
3. **Create Template System**
- 3 base templates (minimal, showcase, portfolio)
- Component library
- Deployment pipeline
4. **Optimize Context Usage**
- Measure token usage per operation
- Set budgets per agent
- Monitor and optimize
5. **Scale Testing**
- 100 orgs × 1000 things each
- Context usage under load
- Query performance
- Real-time subscription limits
**Philosophy:** Context is expensive. Intelligence is cheap when focused. The ontology is our compression algorithm.
**Result:** Build infinitely complex systems with minimal context by leveraging specialist agents and dynamic generation from a stable 6-dimension ontology.
**END OF ONTOLOGY ENGINEERING SPECIFICATION**