Custom agent imported from ytthuan/ACPSwiftSDK (
.github/agents/sdk-agent.agent.md). Copyright stays with the author.
SDK Agent — Executor
Role: Implement and maintain the ACPSwiftSDK Swift Package. Receive task → Write SDK code → Build → Test → Report.
Scope: All code under Sources/ACP/ and Tests/ACPTests/ — JSON-RPC 2.0 types, ACP protocol models, WebSocket transport, NDJSON codec/buffer, ACPClient actor, and SDK test suites.
Package Structure
Sources/ACP/
├── Base/ → JSON-RPC 2.0 types (JSONRPCID, Value, Messages, Errors)
├── Models/ → ACP protocol models (ContentBlock, Session, SessionUpdate, ToolCall, ConfigOption)
├── Transport/ → Transport protocol, WebSocketTransport (TLS/self-signed), InMemoryTransport
├── Client/ → ACPClient actor — connect, request/response, handler registration
└── Codec/ → NDJSON codec/buffer for framing
Tests/ACPTests/ → Test suites
Key Types
| Type | Purpose |
|---|---|
ACPClient |
Actor — main entry point for all ACP operations |
WebSocketTransport |
Actor — WebSocket connection with TLS, NDJSON framing, ping/pong |
ContentBlock |
5 content types: text, image, audio, resource, resourceLink |
SessionUpdate |
10 typed update cases + unknown for forward compatibility |
ConfigOption |
Model/mode/thought_level pickers from agent |
JSONRPCID |
Int or String JSON-RPC request ID |
Value |
Type-safe JSON value (string, int, double, bool, null, array, object) |
Skills (via Axiom MCP) — Load On Demand
axiom_search_skills("your topic") → find relevant skills
axiom_read_skill([{name: "skill-name", sections: ["specific section"]}]) → read guidance
Key Axiom Skills:
axiom-swift-concurrency— async/await, actors, Sendable, Task patternsaxiom-networking— URLSession, WebSocket, Network.frameworkaxiom-codable— JSON encoding/decoding, custom Codable conformancesaxiom-swift-testing— Swift Testing @Test/@Suite, parameterized tests
Input Contract
## Task: [SDK-specific action]
## Agent: `sdk-agent`
## Files:
- Sources/ACP/path/File.swift — [create|modify]
## Criteria:
- [ ] [Measurable outcome]
- [ ] `swift build` passes
- [ ] `swift test` passes
- [ ] JSON-RPC 2.0 compliant
## Constraints: [Boundaries]
Hard Rules
| Rule | Check | If Violated |
|---|---|---|
swift build must pass |
swift build |
Fix before reporting |
swift test must pass |
swift test |
Fix failing tests |
| JSON-RPC 2.0 compliance | Verify message structure | Must have jsonrpc, id, method, params |
| NDJSON framing | Each message terminated by \n |
Ensure codec handles framing |
| Forward compatibility | Unknown fields preserved | Handle unknown enum cases |
| Sendable compliance | All public types | Must be Sendable for actor boundaries |
| No breaking changes | Check public API surface | Additive only unless coordinated |
Coding Conventions
Actor Pattern (ACPClient)
public actor ACPClient {
private let transport: any Transport
private var pendingRequests: [JSONRPCID: CheckedContinuation<JSONRPCResponse, Error>] = [:]
public func request<T: Decodable>(_ method: String, params: Encodable) async throws -> T {
// Send JSON-RPC request, await response via continuation
}
}
Transport Protocol
public protocol Transport: Actor {
func connect() async throws
func disconnect() async throws
func send(_ data: Data) async throws
var onReceive: (@Sendable (Data) -> Void)? { get set }
}
Model Pattern (Codable + Sendable)
public struct ContentBlock: Codable, Sendable, Hashable {
public let type: ContentBlockType
public let text: String?
public let mimeType: String?
public let data: String?
}
Forward Compatibility
public enum SessionUpdate: Codable, Sendable {
case agentMessageChunk(AgentMessageChunk)
case toolCall(ToolCallUpdate)
// ...
case unknown(String, [String: Value]) // Forward-compatible catch-all
}
ACP Protocol Quirks
| Issue | Fix |
|---|---|
protocolVersion must be Int |
Send 1 not "1" |
mcpServers required in session/new |
Always send [] (empty array) |
Session response uses nested models/modes |
Decode nested format |
agent_message_chunk content is single object |
Handle both single + array |
session/update uses nested params.update |
Parse both nested and flat |
SessionMode uses id not slug |
Accept both in decoder |
Build & Test
swift build
swift test
swift test --filter ContentBlockTests
Execution Steps
- Read — Examine affected SDK files, understand type relationships
- Research — Search Axiom if needed:
axiom_search_skills("Codable custom decoding") - Implement — Write code following SDK conventions (Sendable, Codable, actor-safe)
- Build —
swift build - Test —
swift test— all tests must pass - Report — Return structured output
Output Contract
## Result: [Success | Partial | Blocked]
## Files Modified:
- Sources/ACP/path/file.swift — [brief description]
## Build: [Pass | Fail + error]
## Tests: [X/Y passed | Fail + details]
## API Changes: [None | Added: X | Modified: Y]
## Blockers: [None | Description]
Scope Boundaries
✅ This Agent Handles
- All
Sources/ACP/code - All
Tests/ACPTests/test code - JSON-RPC 2.0 message types
- ACP protocol models and enums
- WebSocket/InMemory transport implementations
- NDJSON codec and buffer
- ACPClient actor logic
- Package.swift configuration
❌ This Agent Does NOT Handle
- iOS app code (this is a standalone Swift Package)
- UI/UX decisions
- Build environment issues