| name | acp-adapter-layer |
| version | 1.0.0 |
| description | ACP (Agent Control Protocol) Adapter Layer for AI Native Full-Stack Software Factory - provides seamless integration between ASF multi-agent workflows and OpenClaw's ACP protocol. Enables IDE integration, session management, and tool protocol conversion for AI-native development environments. |
| triggers | ["ACP integration","Agent Control Protocol","IDE integration","ACP session","protocol adapter","vscode integration","jetbrains integration","acp tools"] |
| role | specialist |
| scope | system |
| output-format | structured |
ACP Adapter Layer - ASF ↔ OpenClaw Bridge
Purpose in AI Native Full-Stack Software Factory
Position: System Infrastructure (Cross-Layer Integration)
Purpose: Bridge ASF multi-agent workflows with OpenClaw's Agent Control Protocol (ACP), enabling IDE integration, standardized session management, and tool interoperability.
OpenClaw Version: 2026.3.24+
ACP Specification: https://agentclientprotocol.com/
Architecture Overview
┌─────────────────────────────────────────────────────────┐
│ IDE / Editor │
│ (VS Code, JetBrains, etc. with ACP support) │
└────────────────────┬────────────────────────────────────┘
│ ACP Protocol (stdio)
│ - initialize
│ - newSession
│ - prompt
│ - cancel
│ - tool calls
▼
┌─────────────────────────────────────────────────────────┐
│ ACP ADAPTER LAYER │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ ACP Protocol │ │ Session │ │
│ │ Parser │ │ Manager │ │
│ │ - JSON-RPC │ │ - ACP ↔ ASF │ │
│ │ - Validation │ │ - State sync │ │
│ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ Tool Protocol Converter │ │
│ │ - ACP tools ↔ ASF tools │ │
│ │ - Capability mapping │ │
│ │ - Result transformation │ │
│ └────────────────────┬────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ ASF Multi-Agent Router │ │
│ │ - agentic-factory │ │
│ │ - role-namespace-engine │ │
│ │ - OpenClaw Gateway │ │
│ └────────────────────┬────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────┐ │
│ │ OpenClaw Gateway (WebSocket) │ │
│ │ - ws://127.0.0.1:18789 │ │
│ │ - sessions, routing, tools │ │
│ └─────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
ACP Protocol Support Matrix
| ACP Feature | Status | Notes |
|---|
initialize | ✅ Implemented | Handshake with capability negotiation |
newSession | ✅ Implemented | Create ASF session, return ACP session ID |
prompt | ✅ Implemented | Convert ACP prompt to ASF task |
cancel | ✅ Implemented | Abort ASF task, notify ACP client |
session/set_mode | ✅ Implemented | Map to ASF thinking/tool levels |
session/info | ✅ Implemented | Return ASF session state |
loadSession | ✅ Implemented | Replay ASF session history |
listSessions | ✅ Implemented | List active ASF sessions |
| Tool calls | ✅ Implemented | ACP tools ↔ ASF tools mapping |
| Tool streaming | ✅ Implemented | Real-time tool status updates |
| Resource handling | ✅ Implemented | Images, files, embedded resources |
| Progress updates | ✅ Implemented | Task progress streaming |
| Usage updates | ✅ Implemented | Token usage from ASF |
Core Capabilities
1. ACP Protocol Parser & Validator
interface ACPMessage {
jsonrpc: '2.0';
id?: string | number;
method: string;
params?: Record<string, unknown>;
}
interface ACPResponse {
jsonrpc: '2.0';
id?: string | number;
result?: unknown;
error?: {
code: number;
message: string;
data?: unknown;
};
}
class ACPProtocolParser {
private schema: Map<string, ACPSchema>;
constructor() {
this.schema = this.loadACPSchema();
}
parse(message: string): ParsedACPMessage {
try {
const raw = JSON.parse(message);
this.validate(raw);
return .(raw);
} (error) {
();
}
}
(: ): {
(message. !== ) {
();
}
(!..(message.)) {
();
}
schema = ..(message.);
.(message., schema.);
}
(: ): {
(raw.) {
:
{
: ,
: raw.?. ,
: raw.?.
};
:
{
: ,
: raw.?.
};
:
{
: ,
: raw.?. ,
: raw.?. ,
: raw.?.
};
:
{
: ,
: raw.?. ,
: raw.?.
};
:
();
}
}
}
2. Session Manager (ACP ↔ ASF)
interface ACPSession {
acpSessionId: string;
asfSessionKey: string;
state: 'initializing' | 'active' | 'paused' | 'completed' | 'failed';
createdAt: Date;
lastActivityAt: Date;
mode: ACPSessionMode;
metadata: {
clientInfo: ClientInfo;
capabilities: ACPCapabilities;
workspace?: string;
};
}
interface ACPSessionMode {
thinking: 'off' | 'low' | 'medium' | 'high';
toolVerbosity: 'quiet' | 'normal' | 'verbose';
reasoning: boolean;
usageDetail: boolean;
elevatedActions: boolean;
}
class ACPSessionManager {
private sessions: Map<string, ACPSession>;
private gatewayClient: OpenClawGatewayClient;
() {
. = (gatewayUrl);
. = ();
}
(: , : ): <> {
acpSessionId = ;
asfSessionKey = ..({
: config. || ,
: ,
: ,
: .(config.),
: config. ||
});
: = {
acpSessionId,
asfSessionKey,
: ,
: (),
: (),
: {
: config. || ,
: config. || ,
: config. ?? ,
: config. ?? ,
: config. ??
},
: {
clientInfo,
: config.,
: config.
}
};
..(acpSessionId, session);
session;
}
(?: , ?: ): <> {
(!sessionId) {
.({ label }, {} );
}
session = ..(sessionId);
(!session) {
();
}
session;
}
(: ): <> {
session = ..(sessionId);
(!session) {
();
}
asfHistory = ..(session.);
.(asfHistory);
}
(: , : <>): <> {
session = ..(sessionId);
(!session) {
();
}
session. = { ...session., ...mode };
..(session., {
: mode.,
: mode.
});
}
(: ): {
: <, > = {
: ,
: ,
: ,
:
};
mapping[level] || ;
}
}
3. Tool Protocol Converter
interface ACPTool {
name: string;
description: string;
inputSchema: JSONSchema;
annotations?: {
title?: string;
readOnlyHint?: boolean;
destructiveHint?: boolean;
idempotentHint?: boolean;
openWorldHint?: boolean;
};
}
interface ASFTool {
name: string;
description: string;
parameters: Record<string, unknown>;
handler: (args: unknown) => Promise<unknown>;
}
class ToolProtocolConverter {
private acpTools: Map<string, ACPTool>;
private asfTools: Map<string, ASFTool>;
async convertACPCallToASF(acpCall: ACPCall): <> {
asfTool = ..(acpCall.);
(!asfTool) {
();
}
{
: asfTool.,
: .(acpCall., asfTool.),
: acpCall.
};
}
(: ): <> {
{
: asfResult.,
: .(asfResult.),
: .(asfResult),
: asfResult.,
: {
: asfResult.,
: asfResult.
}
};
}
(: []): [] {
: [] = [];
( asfTool asfTools) {
: = {
: asfTool.,
: asfTool.,
: .(asfTool.),
: {
: asfTool.,
: .(asfTool),
: .(asfTool),
: .(asfTool),
:
}
};
acpTools.(acpTool);
..(acpTool., acpTool);
}
acpTools;
}
(: ): {
readOnlyTools = [, , , , ];
readOnlyTools.( tool..().(keyword));
}
(: ): {
destructiveTools = [, , , ];
destructiveTools.( tool..().(keyword));
}
(: ): {
idempotentTools = [, , , ];
idempotentTools.( tool..().(keyword));
}
}
4. ASF Multi-Agent Router Integration
interface ACPTaskRouter {
routePrompt(prompt: ACPPrompt, session: ACPSession): Promise<RoutingDecision>;
coordinateMultiAgent(task: ASFTask): Promise<MultiAgentResult>;
streamProgress(sessionId: string, progress: ProgressUpdate): Promise<void>;
}
class ACPTaskRouter {
private sessionManager: ACPSessionManager;
private gatewayClient: OpenClawGatewayClient;
private factoryOrchestrator: AgenticFactoryOrchestrator;
async routePrompt(prompt: ACPPrompt, session: ACPSession): Promise<RoutingDecision> {
const analysis = await this.analyzePrompt(prompt);
(analysis. === ) {
{
: ,
: ,
: session.
};
} (analysis. === ) {
{
: ,
: .(analysis.),
: session.
};
} {
{
: ,
: [, , ],
: ..()
};
}
}
(: ): <> {
factoryResult = ..(task);
{
: factoryResult.,
: factoryResult..( ({
: a.,
: a.,
: a.
})),
: factoryResult.,
: factoryResult.
};
}
(: , : ): <> {
session = ...(sessionId);
(!session) {
;
}
: = {
: ,
: sessionId,
: progress.,
: progress.,
: progress.,
: progress.,
: progress.
};
.(acpProgress);
}
}
5. OpenClaw Gateway Integration
class OpenClawGatewayClient {
private ws: WebSocket;
private token: string;
private messageQueue: Map<string, ResolveReject>;
constructor(gatewayUrl: string, token: string) {
this.ws = new WebSocket(gatewayUrl);
this.token = token;
this.messageQueue = new Map();
this.setupConnection();
}
async createSession(config: SessionConfig): Promise<string> {
const response = await this.send({
type: 'session/create',
payload: config
});
return response.sessionKey;
}
async sendPrompt(sessionKey: string, prompt: string): <> {
response = .({
: ,
: {
sessionKey,
: prompt
}
});
response;
}
(: ): <> {
response = .({
: ,
: { sessionKey }
});
response.;
}
(: , : <>): <> {
.({
: ,
: { sessionKey, config }
});
}
(: ): <> {
( {
id = crypto.();
..(id, { resolve, reject });
..(.({ id, ...message }));
( {
..(id);
( ());
}, );
});
}
(): {
.. = {
message = .(event.);
pending = ..(message.);
(pending) {
pending.(message.);
..(message.);
}
};
.. = {
.(, error);
};
}
}
Integration with ASF Components
With agentic-factory (L6)
interface AgenticFactoryIntegration {
createFactoryForACP(acpSession: ACPSession): Promise<FactorySession>;
routeToFactory(prompt: ACPPrompt): Promise<FactoryResult>;
streamFactoryProgress(factorySession: FactorySession): AsyncIterable<ProgressUpdate>;
}
With role-namespace-engine (L6)
interface RoleNamespaceIntegration {
mapClientToNamespace(clientInfo: ClientInfo): Promise<string>;
enforceIsolation(acpSession: ACPSession): Promise<void>;
checkAccess(session: ACPSession, target: string): Promise<AccessDecision>;
}
Configuration
{
"acpAdapter": {
"enabled": true,
"gateway": {
"url": "ws://127.0.0.1:18789",
"token": "~/.openclaw/gateway.token",
"reconnectAttempts": 3,
"reconnectDelay": 1000
},
"session": {
"defaultMode": {
"thinking": "medium",
"toolVerbosity": "normal",
"reasoning": false,
"usageDetail": false,
"elevatedActions": false
}
Usage Examples
Example 1: Initialize ACP Connection
const adapter = new ACPAdapterLayer({
gatewayUrl: 'ws://127.0.0.1:18789',
token: 'your-gateway-token'
});
const initializeRequest = {
jsonrpc: '2.0',
id: 1,
method: 'initialize',
params: {
protocolVersion: '2024-11-05',
capabilities: {
roots: { listChanged: true },
sampling: {},
tools: { listChanged: true }
},
clientInfo: {
name: 'vscode',
version: '1.85.0'
}
}
};
const response = await adapter.handle(initializeRequest);
{
jsonrpc: '2.0',
id: 1,
result: {
protocolVersion: '2024-11-05',
capabilities: {
tools: {
listChanged: true,
tools: []
}
},
serverInfo: {
name: 'asf-acp-adapter',
version:
}
}
}
Example 2: Create ACP Session
const newSessionRequest = {
jsonrpc: '2.0',
id: 2,
method: 'newSession',
params: {
config: {
label: 'Code Review Session',
thinking: 'high',
toolVerbosity: 'verbose'
}
}
};
const response = await adapter.handle(newSessionRequest);
{
jsonrpc: '2.0',
id: 2,
result: {
sessionId: 'acp:uuid-here',
state: 'active',
mode: {
thinking: 'high',
toolVerbosity: 'verbose'
}
}
}
Example 3: Process ACP Prompt
const promptRequest = {
jsonrpc: '2.0',
id: 3,
method: 'prompt',
params: {
sessionId: 'acp:uuid-here',
prompt: {
role: 'user',
content: [{ type: 'text', text: 'Review this code for performance issues' }]
}
}
};
const response = await adapter.handle(promptRequest);
{
jsonrpc: '2.0',
id: 3,
result: {
content: [{ type: 'text', text: 'Code review complete...' }],
toolCalls: [...],
usage: {
inputTokens: 1500,
outputTokens: 800
}
}
}
Remember: ACP is the bridge between IDEs and AI. Make it seamless.