-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Integrate MCP Server with Subagents Architecture #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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)
Phase 2: Route Adapters Through Subagents (commits 3-5)
dispatchToAgent()capability to Adapter base classPhase 3: Enable Coordination Features (commits 6-8)
Phase 4: Event Bus + Observability (commits 9-11)
Architecture
Testing
Breaking Changes
None - all changes are additive and backwards compatible.
Related
Closes #44