Documentation
Nity Agent
Extension

Extension Entry Point

The extensions/nity/index.ts file is the main entry point for the Nity extension. It registers tools with pi-coding-agent, subscribes to lifecycle events, and initializes the coordinator with all component references.


Registration

On load, Nity registers 5 tools with the pi-coding-agent tool system:

ToolPurposeSection
nity_analyzeDecompose a task into subtasks and complexity scoresTools →
nity_executeRun a task through the autonomous execution loopTools →
nity_quality_gateValidate outputs against quality dimensionsTools →
nity_reflectTrigger post-task self-reflection and learningTools →
nity_skillsFind, create, and manage learned skillsTools →

These 5 tools are the user-facing surface. Internally, Nity uses 12 tool primitives — see the full Tool Reference.


Event Subscriptions

Nity subscribes to three pi-coding-agent lifecycle events:

Event               When Fired                  Nity Action
─────────────────── ─────────────────────────── ────────────────────────────────────
session_start       New session created          Load brain context, recall episodes
before_agent_start  Before agent processes turn  Inject relevant context into prompt
turn_end            After agent completes turn   Record episode, check for new skills

Event Flow Diagram

pi-coding-agent

    ├──► session_start
    │       │
    │       └──► NityExtension.onSessionStart()
    │               ├── Load brain context (brain-context.ts)
    │               ├── Recall recent episodes (episodic-memory.ts)
    │               └── Inject context into session

    ├──► before_agent_start
    │       │
    │       └──► NityExtension.onBeforeAgentStart()
    │               ├── Retrieve relevant skills (skill-registry.ts)
    │               ├── Derive adapter recommendations
    │               └── Enrich agent context

    └──► turn_end

            └──► NityExtension.onTurnEnd()
                    ├── Record episode (episodic-memory.ts)
                    ├── Update skill registry if applicable
                    ├── Run self-reflection (self-reflection.ts)
                    └── Update adapter recommendations

Coordinator Initialization

The extension initializes the Coordinator with references to all major subsystems:

// index.ts — Coordinator wiring
const coordinator = new Coordinator({
  brain: new BrainContextManager(config.brain),
  skillRegistry: new SkillRegistry(config.skills),
  qualityGates: new QualityGates(config.quality),
  selfReflection: new SelfReflection(config.reflection),
  episodicMemory: new EpisodicMemory(config.memory),
  taskAnalyzer: new TaskAnalyzer(),
  strategyPlanner: new StrategyPlanner(),
  executionRouter: new ExecutionRouter(config.adapters),
  progressTracker: new ProgressTracker(),
  metaLearner: new MetaLearner(config.meta),
  logger: new Logger('nity'),
});

Session Start Behavior

When session_start fires, the extension performs two critical operations:

1. Brain Context Injection

// Simplified from index.ts
private async onSessionStart(session: Session): Promise<void> {
  // Load persisted brain context for this project/user
  const context = await this.coordinator.brain.load(session.projectId);
 
  // Inject into the session so the agent has it in every prompt
  session.injectContext({
    type: 'nity_brain',
    content: context.summary,
    memories: context.recentMemories,
    priority: 'high',
  });
 
  this.logger.info('Brain context injected', {
    sessionId: session.id,
    memoryCount: context.recentMemories.length,
  });
}

2. Episode Recall

// Load recent episodes to prime the agent with task history
const episodes = await this.coordinator.episodicMemory.recall({
  projectId: session.projectId,
  limit: 10,
  sortBy: 'recency',
});
 
if (episodes.length > 0) {
  session.injectContext({
    type: 'nity_episodes',
    content: this.formatEpisodes(episodes),
    priority: 'medium',
  });
}

Type Definitions

Core types from types.ts:

interface NityConfig {
  brain: {
    storagePath: string;
    maxContextSize: number;
  };
  skills: {
    storagePath: string;
    maxSkills: number;
    autoCreate: boolean;
  };
  quality: {
    dimensions: string[];
    thresholds: Record<string, number>;
  };
  reflection: {
    enabled: boolean;
    interval: number; // turns between reflections
  };
  memory: {
    maxEpisodes: number;
    similarityThreshold: number;
  };
  adapters: {
    available: string[];
    default: string;
  };
  meta: {
    optimizeInterval: number; // turns between meta-learning
  };
}

QualityGateReport

interface QualityGateReport {
  dimensions: QualityDimension[];
  overallScore: number;        // 0–100
  passed: boolean;
  timestamp: string;
}
 
interface QualityDimension {
  name: string;
  score: number;               // 0–100
  passed: boolean;
  findings: Finding[];
}
 
interface Finding {
  severity: 'critical' | 'high' | 'medium' | 'low' | 'info';
  message: string;
  evidence?: string;
  suggestion?: string;
}

ReflectionRecord

interface ReflectionRecord {
  id: string;
  taskId: string;
  timestamp: string;
  insights: Insight[];
  confidence: number;          // 0–100
  appliedToSkills: string[];   // skill IDs updated by this reflection
}
 
interface Insight {
  category: 'approach' | 'quality' | 'efficiency' | 'gap';
  description: string;
  actionable: boolean;
  evidence: string[];
}

SkillEntry

interface SkillEntry {
  id: string;
  name: string;
  trigger: string;             // pattern that activates this skill
  prompt: string;              // the skill's instruction set
  createdAt: string;
  updatedAt: string;
  usageCount: number;
  successRate: number;         // 0–100
  tags: string[];
}

Episode

interface Episode {
  id: string;
  taskId: string;
  task: string;
  outcome: 'success' | 'failure' | 'partial';
  strategy: ExecutionStrategy;
  iterations: number;
  durationMs: number;
  notes: string;
  qualityReport?: QualityGateReport;
  reflectionId?: string;
  timestamp: string;
}

BrainContext

interface BrainContext {
  projectId: string;
  summary: string;
  recentMemories: Memory[];
  activeSkills: SkillEntry[];
  lastUpdated: string;
}
 
interface Memory {
  id: string;
  content: string;
  importance: number;          // 0–100
  timestamp: string;
  tags: string[];
}

Next Steps