Skip to content

Conversation

@prosdev
Copy link
Collaborator

@prosdev prosdev commented Nov 25, 2025

Summary

This PR implements the integration of the MCP server with the subagents architecture, establishing foundational infrastructure for a coordinated AI assistant system.

Changes

Phase 1: Wire up Coordinator (commits 1-2)

  • Add coordinator support to adapter framework types
  • Wire up SubagentCoordinator in MCP server entry point
  • Pass coordinator to adapters during initialization

Phase 2: Route Adapters Through Subagents (commits 3-5)

  • Add dispatchToAgent() capability to Adapter base class
  • Route ExploreAdapter through ExplorerAgent
  • Route PlanAdapter through PlannerAgent
  • Fallback to direct execution when coordinator unavailable

Phase 3: Enable Coordination Features (commits 6-8)

  • StorageAdapter Interface: Pluggable persistence strategy
  • MemoryStorageAdapter: Fast, ephemeral (default)
  • CompositeStorageAdapter: Routes by prefix (session: vs persistent:)
  • Update ContextManager to use StorageAdapter
  • Add persistent storage methods to Adapter base class

Phase 4: Event Bus + Observability (commits 9-11)

  • AsyncEventBus: Node.js-native event bus with async handlers
  • Standard System Events: index., health., agent., request., system.*
  • Integrate EventBus with Coordinator
  • ObservableLogger: Structured logging with request correlation
  • RequestTracker: Track request lifecycle, emit events, calculate metrics

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                        MCP Server                               │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │              SubagentCoordinator                         │   │
│  │                                                         │   │
│  │   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐    │   │
│  │   │ EventBus    │  │ContextMgr   │  │ TaskQueue   │    │   │
│  │   │ pub/sub     │  │ session     │  │ priority    │    │   │
│  │   │             │  │ persistent  │  │             │    │   │
│  │   └─────────────┘  └─────────────┘  └─────────────┘    │   │
│  │                                                         │   │
│  │   Agents: ExplorerAgent, PlannerAgent, PrAgent          │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  Adapters (with dispatch, context, events):                    │
│  - ExploreAdapter → ExplorerAgent                              │
│  - PlanAdapter → PlannerAgent                                  │
│  - SearchAdapter, StatusAdapter, GitHubAdapter                 │
└─────────────────────────────────────────────────────────────────┘

Testing

  • All 892 tests passing
  • New tests for:
    • StorageAdapter (28 tests)
    • EventBus (17 tests)
    • Observability (28 tests)

Breaking Changes

None - all changes are additive and backwards compatible.

Related

Closes #44

## Changes

### Type Updates
- Add optional `coordinator` field to `AdapterContext`
- Add optional `coordinator` field to `MCPServerConfig`

### MCPServer Updates
- Store coordinator reference in MCPServer class
- Start coordinator before initializing adapters
- Pass coordinator to adapters via AdapterContext
- Stop coordinator during server shutdown
- Log coordinator status (agents registered)

### Integration Points
- Adapters can now access `context.coordinator` if provided
- Backwards compatible - coordinator is optional
- Foundation for routing adapters through subagents

All 812 tests passing.
## Changes

### Coordinator Setup
- Create SubagentCoordinator with configured options
- Set up ContextManager with repository indexer
- Register all subagents (Explorer, Planner, PR)
- Pass coordinator to MCPServer

### Subagents Registered
- ExplorerAgent: pattern search, similar code, relationships
- PlannerAgent: task breakdown, estimation
- PrAgent: GitHub PR management (placeholder)

### Integration
- Coordinator starts/stops with MCP server lifecycle
- Adapters now have access to coordinator via context
- Foundation for routing adapter calls through subagents

All 812 tests passing.
## Changes

### Adapter Base Class Enhancements
- Add protected `coordinator` field for subagent access
- Add protected `logger` field for consistent logging
- Add `initializeBase()` method for common initialization
- Add `hasCoordinator()` check for conditional routing
- Add `dispatchToAgent()` method for sending requests to subagents

### Usage Pattern
Adapters can now optionally route through subagents:

```typescript
// In adapter execute():
if (this.hasCoordinator()) {
  const response = await this.dispatchToAgent('explorer', {
    action: 'pattern',
    query: searchQuery,
  });
  // Use agent response
} else {
  // Fallback to direct service call
}
```

### Benefits
- Backwards compatible (coordinator is optional)
- Enables incremental adoption
- Consistent message format for agent communication
- Foundation for full subagent integration

All 812 tests passing.
## Changes

### ExploreAdapter Integration
- Call `initializeBase()` to store coordinator reference
- Add `executeViaAgent()` method for agent-routed execution
- Add `formatAgentResult()` to format agent responses
- Try agent routing first, fall back to direct execution

### Execution Flow
```
Request → ExploreAdapter
         ├── hasCoordinator? → dispatchToAgent('explorer', payload)
         │                     └── ExplorerAgent handles request
         │                     └── Format response
         └── No coordinator → Direct indexer call (existing behavior)
```

### Benefits
- Leverages ExplorerAgent's context awareness
- Enables future coordination features
- Backwards compatible (falls back to direct calls)
- Consistent formatting regardless of execution path

### Technical Notes
- Agent payload matches ExplorerAgent's request types
- Response is cast from Message payload to ExplorationResult
- All existing tests pass (no behavior change for direct execution)

All 812 tests passing.
## Changes

### PlanAdapter Integration
- Call `initializeBase()` to store coordinator reference
- Add `executeViaAgent()` method for agent-routed execution
- Add `convertAgentPlan()` to convert agent response to adapter format
- Try agent routing first, fall back to direct execution

### Subagents Exports
- Export planner types (Plan, PlanTask, PlanningResult, etc.)
- Enables MCP adapters to use typed agent responses

### Test Updates
- Update initialize test to expect `hasCoordinator` property

All 812 tests passing.
## Changes

### StorageAdapter Interface
- Define `StorageAdapter` interface for pluggable persistence
- Async-first design (even in-memory returns Promises)
- Lifecycle hooks: `initialize()`, `shutdown()`
- Key operations: get, set, delete, has, keys, clear, size
- Prefix filtering for namespaced storage

### Implementations
- `MemoryStorageAdapter`: Fast, ephemeral (default)
- `CompositeStorageAdapter`: Routes by prefix (session: vs persistent:)

### Design Principles
- Future-proof: Easy to add FileStorageAdapter, RedisStorageAdapter, etc.
- Testable: Mock storage in tests
- Separation of concerns: Adapters don't know how storage works

### Fixes
- Rename `GitHubAdapter.getContext()` → `getIssueContext()` to avoid collision
- Add `has()` method to `ContextManager` interface

### Tests
- 28 new tests for StorageAdapter implementations
- All 840 tests passing
## Changes

### ContextManager Refactored
- Uses `StorageAdapter` for both session and persistent storage
- Session storage: Fast, ephemeral (default: MemoryStorageAdapter)
- Persistent storage: Durable, survives restarts (configurable)

### New APIs
- `getAsync()`, `setAsync()`, `hasAsync()`: Async session state
- `getPersistent()`, `setPersistent()`, `deletePersistent()`: Durable storage
- `keysPersistent(prefix?)`: List persistent keys with optional filtering
- `getSessionStorage()`, `getPersistentStorage()`: Direct adapter access
- `initialize()`, `shutdown()`: Lifecycle management

### Backwards Compatibility
- Sync methods (get, set, has, delete) still work for MemoryStorageAdapter
- Existing code continues to work without changes

### Statistics
- `getStats()` now returns sessionSize + persistentSize (async)

### Tests
- Updated context-manager tests for async operations
- Added tests for persistent storage
- Added tests for custom storage adapters
- All 847 tests passing
## Changes

### Adapter Base Class
- Add persistent storage methods for durable state
- `setPersistent(key, value)`: Store value that survives restarts
- `getPersistent<T>(key)`: Retrieve persistent value
- `hasPersistent(key)`: Check if key exists
- `deletePersistent(key)`: Remove persistent value

### Use Cases
- User preferences (format, verbosity)
- Learning data (search patterns, common queries)
- Cached expensive computations

### Implementation
- Uses duck typing to detect ContextManagerImpl
- Graceful fallback when coordinator not available
- All methods return sensible defaults (undefined, false)

### Documentation
- Clear separation between session (ephemeral) and persistent storage
- Recommended key namespacing: "adapter:key"

All 847 tests passing.
## Changes

### EventBus Interface
- `on()`: Subscribe to events with optional priority
- `once()`: Subscribe once (auto-unsubscribe)
- `off()`: Unsubscribe from events
- `emit()`: Emit events (fire-and-forget or wait for handlers)
- `waitFor()`: Promise-based event waiting with timeout

### AsyncEventBus Implementation
- Built on Node.js EventEmitter for performance
- Async handler support (all handlers can be async)
- Priority-based handler ordering
- Error isolation (one handler error doesn't crash others)
- Configurable max listeners and timeouts

### Type-Safe Events
- `createTypedEventBus<EventMap>()`: Compile-time type checking
- `SystemEventMap`: Standard system events

### Standard System Events
- Index: `index.updated`, `index.error`
- Health: `health.changed`
- Agent: `agent.registered`, `agent.unregistered`
- Request: `request.started`, `request.completed`, `request.failed`
- System: `system.started`, `system.shuttingDown`

### Tests
- 17 new tests for EventBus
- All 864 tests passing
## Changes

### Coordinator Integration
- Add `eventBus` field to SubagentCoordinator
- Add `getEventBus()` method to expose event bus
- Emit `agent.registered` event when agent is registered
- Emit `agent.unregistered` event when agent is unregistered

### Event Flow
```
registerAgent() → agent.initialize() → emit('agent.registered')
unregisterAgent() → agent.shutdown() → emit('agent.unregistered')
```

### Usage
```typescript
const eventBus = coordinator.getEventBus();
eventBus.on('agent.registered', (event) => {
  console.log(`Agent ${event.name} registered`);
});
```

All 864 tests passing.
## Changes

### ObservableLogger
- Structured logging with levels (debug, info, warn, error)
- Pretty and JSON output formats
- Request ID correlation via `withRequest()`
- Child loggers via `child()`
- Timing utilities: `startTimer()`, `time()`
- ANSI colors for pretty terminal output

### RequestTracker
- Track request lifecycle (start, complete, fail)
- Emit events via EventBus for real-time observability
- Request metrics: total, success, failed, durations
- Percentile calculations (p50, p95, p99)
- Per-tool breakdown
- History management with configurable max size

### Types
- `RequestContext`: Request tracking context
- `LogEntry`: Structured log entry
- `RequestMetrics`: Metrics summary
- `Timer`: Timing interface

### Usage
```typescript
const logger = createLogger({ component: 'adapter', level: 'debug' });
const scoped = logger.withRequest(requestId);
scoped.info('Processing request', { tool: 'dev_search' });

const tracker = createRequestTracker({ eventBus });
const ctx = tracker.startRequest('dev_search', args);
tracker.completeRequest(ctx.requestId, tokenEstimate);
```

### Tests
- 28 new tests for observability
- All 892 tests passing
## Changes

### packages/core/src/events/README.md
- Overview of EventBus architecture
- Quick start examples
- Feature documentation (async handlers, priority, once, waitFor)
- Standard system events table
- API reference
- Integration with Coordinator
- Best practices

### packages/core/src/observability/README.md
- Overview of observability components
- ObservableLogger documentation (levels, correlation, timing)
- RequestTracker documentation (lifecycle, metrics, events)
- API reference with types
- Best practices

### README.md (root)
- Added Infrastructure section to Key Features
- Updated project structure with events/, observability/, mcp-server/
- Updated test count to 892
- Added Infrastructure (New) section to Current Status
@prosdev prosdev merged commit 2ace7d4 into main Nov 25, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Epic: Integrate MCP Server with Subagents Architecture

1 participant