Goal: Enable personas to learn from code through embeddings and self-directed study.
Key Principle: Break down into small, composable commands that can be used independently or combined for emergent behaviors.
# 1. Generate embeddings for any text
./jtag ai/embedding/generate --text="code snippet" --model="qwen3-embedding"
# Returns: { embedding: number[], model: string, dimensions: number }
# 2. Store code index entry
./jtag ai/rag/index/create --filePath="..." --content="..." --embedding=[...]
# Returns: { entryId: UUID, indexed: boolean }
# 3. Query code index with embeddings
./jtag ai/rag/index/query --query="PersonaUser" --limit=5
# Returns: { entries: CodeIndexEntry[], relevanceScores: number[] }# Index a single file (uses: generate + create)
./jtag ai/rag/index/file --filePath="system/user/PersonaUser.ts"
# Internally: Parse → Generate embeddings → Store entries
# Index a directory (uses: index/file repeatedly)
./jtag ai/rag/index/directory --path="system/user" --recursive
# Internally: Find files → Index each file
# Search codebase (uses: generate + query)
./jtag ai/rag/search --query="how does coordination work?" --limit=10
# Internally: Generate query embedding → Search index → Return ranked results# Index entire codebase
./jtag ai/rag/index-codebase --paths="system,commands" --fileTypes="typescript,markdown"
# Uses: index/directory for each path
# Ask question about codebase
./jtag ai/rag/ask --question="How does PersonaUser handle learning?"
# Uses: search + AI generation with context- ✅
CodeIndexEntity- Data structure - ✅ Candle embedding generation via Rust IPC
- ✅
ai/embedding/generate- Command wrapper for embedding generation - ✅
ai/rag/index/create- Store single code entry - ⬜
ai/rag/query-open- Open similarity search, return handle + first page - ⬜
ai/rag/query-fetch- Fetch results at any offset (bidirectional) - ⬜
ai/rag/query-close- Close query handle and cleanup
- ⬜
ai/rag/index/file- Parse and index single file (TypeScript/Markdown) - ⬜
ai/rag/index/directory- Index multiple files - ⬜
ai/rag/search- Semantic code search
- ⬜
ai/rag/index-codebase- Full codebase indexing - ⬜
ai/rag/ask- Natural language queries
- ⬜ PersonaUser captures conversation embeddings
- ⬜ PersonaUser schedules self-training tasks
- ⬜ Learning session orchestration
Each command follows this structure:
commands/ai/[category]/[action]/
├── shared/
│ ├── [Action]Types.ts # Params & Result interfaces
│ └── [Action]Command.ts # Abstract base class
├── server/
│ └── [Action]ServerCommand.ts # Implementation
└── browser/
└── [Action]BrowserCommand.ts # (if needed)
Composability:
- Low-level commands = Lego blocks
- Mid-level commands = Pre-built structures
- High-level commands = Complete solutions
- PersonaUser can use ANY level for its needs
Emergent Behaviors:
// Simple: Human indexes code manually
./jtag ai/rag/index-codebase --paths="system/user"
// Complex: Persona self-directs learning
PersonaUser.serviceInbox()
→ Detects knowledge gap in "coordination"
→ Creates task: { type: 'study', topic: 'coordination' }
→ Executes: ai/rag/search --query="coordination patterns"
→ Generates quiz from results
→ Answers quiz
→ Captures training data
→ Fine-tunes adapter
→ Returns to normal operationReusability:
- Teacher AI uses
ai/rag/searchto generate quizzes - Helper AI uses
ai/rag/searchto improve answers - CodeReview AI uses
ai/rag/searchto find patterns - Human uses
ai/rag/searchto explore codebase
- Implement
ai/embedding/generatecommand (wrapper for Candle Rust IPC) - Implement
ai/rag/index/createcommand (store single entry) - Implement
ai/rag/index/querycommand (search with embeddings) - Test composition by building
ai/rag/index/filefrom primitives - Continue building upward
Start simple, compose elegantly, unlock emergence.
The RAG query commands implement a universal iterator pattern that works for all time-ordered and ranked data.
Every iterator follows this structure:
{domain}/query-open- Opens query, returns handle + first page{domain}/query-fetch- Fetches at any position (bidirectional + random access){domain}/query-close- Closes handle and cleanup
Bidirectional Navigation:
# Move forward through results
./jtag ai/rag/query-fetch --queryHandle="abc" --direction="forward"
# Move backward
./jtag ai/rag/query-fetch --queryHandle="abc" --direction="backward"Random Access:
# Jump to specific offset
./jtag ai/rag/query-fetch --queryHandle="abc" --offset=30 --limit=10Position Tracking:
- Handle maintains current offset
- Results include
hasMoreandhasPreviousflags - Frontend can implement infinite scroll in both directions
This pattern applies to:
- RAG similarity search (relevance-ranked)
- Chat message history (time-ordered)
- Game replays (frame-by-frame navigation)
- Training logs (epoch progression)
- Database queries (already implemented:
data/query-*) - Time series data (any chronological sequence)
- Event streams (real-time or historical)
Eventually this will become a generic abstraction:
interface Iterator<T> {
handle: UUID;
offset: number;
limit: number;
totalCount: number;
hasMore: boolean;
hasPrevious: boolean;
}One mental model, infinite applications.