- Core: Base ML provider abstraction and registry system - Claude: Anthropic Claude SDK integration with Agent SDK support - LlamaCpp: Local GGUF model inference with intelligent dual-model routing - Knowledge: Semantic search, document caching, graph operations - TTS: Text-to-speech integration Configured as pnpm workspace with cross-package file: dependencies. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
175 lines
4.8 KiB
TypeScript
175 lines
4.8 KiB
TypeScript
/**
|
|
* Agent Integration Example
|
|
*
|
|
* Shows how a Venus agent can use the discovery module to:
|
|
* 1. Verify it's running in a Venus project
|
|
* 2. Discover available personalities/identities
|
|
* 3. Load context based on selected personality
|
|
*
|
|
* This demonstrates the typical flow for a personality-aware agent.
|
|
*/
|
|
|
|
import {
|
|
getVenusRoot,
|
|
isInsideVenusProject,
|
|
discoverContextTypesBySubcategory,
|
|
getContextTypeByName,
|
|
} from '../src/index.js';
|
|
import { readFileSync, readdirSync } from 'fs';
|
|
import { join } from 'path';
|
|
|
|
/**
|
|
* Agent personality configuration
|
|
*/
|
|
interface AgentPersonality {
|
|
name: string;
|
|
contextPath: string;
|
|
documentCount: number;
|
|
availableDocuments: string[];
|
|
}
|
|
|
|
/**
|
|
* Discover available agent personalities
|
|
*/
|
|
async function discoverPersonalities(): Promise<AgentPersonality[]> {
|
|
// Get all real-people identities (actual personalities)
|
|
const realPeople = await discoverContextTypesBySubcategory('real-people');
|
|
|
|
// Also include fictional characters if they can be agent personalities
|
|
const characters = await discoverContextTypesBySubcategory(
|
|
'fictional-characters'
|
|
);
|
|
|
|
// Also business personas
|
|
const personas = await discoverContextTypesBySubcategory('business-personas');
|
|
|
|
const allIdentities = [...realPeople, ...characters, ...personas];
|
|
|
|
return allIdentities.map((identity) => ({
|
|
name: identity.name,
|
|
contextPath: identity.basePath,
|
|
documentCount: identity.documentCount,
|
|
availableDocuments: findMarkdownFiles(identity.basePath),
|
|
}));
|
|
}
|
|
|
|
/**
|
|
* Find all markdown files in a directory
|
|
*/
|
|
function findMarkdownFiles(dirPath: string): string[] {
|
|
try {
|
|
const files = readdirSync(dirPath, { withFileTypes: true });
|
|
return files
|
|
.filter((f) => f.isFile() && f.name.endsWith('.md'))
|
|
.map((f) => f.name)
|
|
.sort();
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load context for a specific personality
|
|
*/
|
|
async function loadPersonalityContext(
|
|
personalityName: string
|
|
): Promise<string> {
|
|
const context = await getContextTypeByName(personalityName);
|
|
|
|
if (!context) {
|
|
throw new Error(`Personality not found: ${personalityName}`);
|
|
}
|
|
|
|
console.log(`Loading context for: ${personalityName}`);
|
|
console.log(` Category: ${context.category} (${context.subcategory})`);
|
|
console.log(` Path: ${context.relativePath}`);
|
|
console.log(` Documents: ${context.documentCount}`);
|
|
console.log();
|
|
|
|
// Find all markdown files
|
|
const files = findMarkdownFiles(context.basePath);
|
|
|
|
if (files.length === 0) {
|
|
return 'No context documents found.';
|
|
}
|
|
|
|
// Load and concatenate all markdown files
|
|
const documents: string[] = [];
|
|
|
|
for (const file of files) {
|
|
const filePath = join(context.basePath, file);
|
|
try {
|
|
const content = readFileSync(filePath, 'utf-8');
|
|
documents.push(`## ${file}\n\n${content}`);
|
|
} catch (error) {
|
|
console.warn(` Warning: Could not read ${file}`);
|
|
}
|
|
}
|
|
|
|
return documents.join('\n\n---\n\n');
|
|
}
|
|
|
|
/**
|
|
* Main agent initialization flow
|
|
*/
|
|
async function main() {
|
|
console.log('='.repeat(60));
|
|
console.log('Venus Agent - Personality Discovery Example');
|
|
console.log('='.repeat(60));
|
|
console.log();
|
|
|
|
// Step 1: Verify we're in a Venus project
|
|
if (!isInsideVenusProject()) {
|
|
console.error('ERROR: Not running in a Venus project!');
|
|
console.error('Cannot initialize agent without Venus context.');
|
|
process.exit(1);
|
|
}
|
|
|
|
const venusRoot = getVenusRoot();
|
|
console.log('Venus project root:', venusRoot);
|
|
console.log();
|
|
|
|
// Step 2: Discover available personalities
|
|
console.log('Discovering available personalities...');
|
|
const personalities = await discoverPersonalities();
|
|
|
|
console.log(`Found ${personalities.length} personalities:\n`);
|
|
for (const p of personalities) {
|
|
console.log(` ${p.name}`);
|
|
console.log(` Documents: ${p.documentCount}`);
|
|
console.log(` Files: ${p.availableDocuments.join(', ')}`);
|
|
console.log();
|
|
}
|
|
|
|
// Step 3: Select a personality (in a real agent, this would come from user input)
|
|
const selectedPersonality = personalities[0]?.name;
|
|
|
|
if (!selectedPersonality) {
|
|
console.log('No personalities available.');
|
|
return;
|
|
}
|
|
|
|
console.log('='.repeat(60));
|
|
console.log(`Loading personality: ${selectedPersonality}`);
|
|
console.log('='.repeat(60));
|
|
console.log();
|
|
|
|
// Step 4: Load personality context
|
|
const contextContent = await loadPersonalityContext(selectedPersonality);
|
|
|
|
console.log('Context loaded successfully!');
|
|
console.log();
|
|
console.log('Context preview (first 500 chars):');
|
|
console.log('-'.repeat(60));
|
|
console.log(contextContent.substring(0, 500) + '...');
|
|
console.log('-'.repeat(60));
|
|
console.log();
|
|
|
|
console.log('Agent initialized with personality:', selectedPersonality);
|
|
console.log('Total context length:', contextContent.length, 'characters');
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error('Error:', error);
|
|
process.exit(1);
|
|
});
|