TypeScript conductor for ACP proxy chains - orchestrates message routing between clients, proxies, and agents
TypeScript conductor for ACP proxy chains.
The conductor orchestrates message routing between clients, proxies, and agents in the Agent Client Protocol (ACP). It sits between every component, managing process lifecycle and message flow.
```
Client <-> Conductor <-> [Proxy 0] <-> [Proxy 1] <-> ... <-> Agent
`bash`
pnpm add @thinkwell/conductor
`typescript
import { Conductor, fromCommands, ChannelConnector } from '@thinkwell/conductor';
// Create a conductor that spawns an agent subprocess
const conductor = new Conductor({
instantiator: fromCommands(['my-agent']),
});
// Connect a client
const clientConnector = new ChannelConnector(/ your channel /);
await conductor.connect(clientConnector);
`
`typescript`
const conductor = new Conductor({
// Last command is the agent, earlier commands are proxies
instantiator: fromCommands(['my-proxy', 'my-agent']),
});
`typescript`
const conductor = new Conductor({
instantiator: fromCommands(['my-agent']),
logging: {
level: 'debug', // 'error' | 'warn' | 'info' | 'debug' | 'trace'
name: 'my-app',
json: true, // Output as JSON for machine parsing
},
});
Write all messages to a JSONL file for debugging:
`typescript`
const conductor = new Conductor({
instantiator: fromCommands(['my-agent']),
trace: {
path: '/tmp/conductor-trace.jsonl',
},
});
Each line in the trace file is a JSON object with:
- timestamp: ISO 8601 timestampdirection
- : 'left-to-right' | 'right-to-left' | 'internal'source
- : Source component identifiertarget
- : Target component identifiermessage
- : The full ConductorMessage object
`typescript
import { Conductor, dynamic, StdioConnector } from '@thinkwell/conductor';
const conductor = new Conductor({
instantiator: dynamic(async (initRequest) => {
// Inspect the initialize request to decide what to spawn
const needsProxy = initRequest.params?.mcpServers?.length > 0;
return {
proxies: needsProxy ? [new StdioConnector('my-proxy')] : [],
agent: new StdioConnector('my-agent'),
};
}),
});
`
Main class that orchestrates the proxy chain.
#### Constructor Options
| Option | Type | Description |
|--------|------|-------------|
| name | string | Optional name for debugging |instantiator
| | ComponentInstantiator | Creates components on initialization |mcpBridgeMode
| | 'http' \| 'disabled' | MCP bridge mode (default: 'http') |logging
| | LoggerOptions | Logging configuration |trace
| | TraceOptions | JSONL trace output configuration |
#### Methods
- connect(clientConnector): Connect to a client and run the message loopshutdown()
- : Shut down the conductor and all components
Factory functions for creating component configurations:
- fromCommands(commands): Create from a list of command strings (last is agent)fromConnectors({ proxies, agent })
- : Create from explicit connectorsstaticInstantiator(config)
- : Create with detailed optionsdynamic(factory)
- : Create dynamically based on initialize request
- StdioConnector: Spawns a subprocess and communicates via stdin/stdoutChannelConnector
- : In-memory channel for testing
- createLogger(options): Create a logger instancecreateNoopLogger()
- : Create a logger that discards all outputgetLogger()
- : Get the default loggersetLogger(logger)`: Set the default logger
-
See repository root for license information.