API Reference

June 25, 2026 · View on GitHub

Complete reference for the Swift AgentSDK.

Agent

The core configuration unit for an AI agent.

public final class Agent: @unchecked Sendable {
    public let name: String
    public let instructions: String
    public let tools: [ToolName]
    public let maxTurns: Int
    public private(set) var model: ModelID?
    public private(set) var provider: (any Provider)?
    public let loopType: LoopType
    public let cwd: String?
    public let memories: String?
    public let customInstructions: [String]?
    public let modelSettings: [String: AnyCodable]?
}

Constructor

public init(
    name: String,
    instructions: String,
    tools: [ToolName] = [],
    maxTurns: Int = 10,
    model: ModelID? = nil,
    provider: (any Provider)? = nil,
    loopType: LoopType = .react,
    cwd: String? = nil,
    memories: String? = nil,
    customInstructions: [String]? = nil,
    modelSettings: [String: AnyCodable]? = nil
)

Methods

setModel(_:)

public func setModel(_ model: ModelID)

Sets the model identifier for the agent.

setProvider(_:)

public func setProvider(_ provider: any Provider)

Sets the LLM provider for the agent.


Runner

Executes agents and manages the execution loop.

public final class Runner: @unchecked Sendable

Static Methods

run(agent:prompt:options:)

public static func run(
    agent: Agent,
    prompt: String,
    options: LoopOptions? = nil
) async throws -> RunResult

Runs an agent with the given prompt. Returns the full RunResult including session and turn count.

Throws AgentSDKError.agentConfig if configuration is invalid.

runSync(agent:prompt:options:)

public static func runSync(
    agent: Agent,
    prompt: String,
    options: LoopOptions? = nil
) async throws -> String

Runs an agent and returns the final output string. Throws if max turns are reached.

runStream(agent:prompt:options:)

public static func runStream(
    agent: Agent,
    prompt: String,
    options: LoopOptions? = nil
) -> AsyncThrowingStream<StreamEvent, Error>

Runs an agent and yields StreamEvent values as they occur.

setHookManager(_:)

public static func setHookManager(_ manager: HookManager)

Sets the global hook manager.

getHookManager()

public static func getHookManager() -> HookManager

Returns the current hook manager.

setPermissionManager(_:)

public static func setPermissionManager(_ manager: PermissionManager?)

Sets the global permission manager.


Provider

Protocol for LLM providers.

public protocol Provider: Sendable {
    func modelName(_ model: String) -> String

    func chat(
        messages: [Message],
        model: String,
        tools: [ToolSchema]?,
        options: ProviderOptions?
    ) async throws -> ChatResponse

    func chatStream(
        messages: [Message],
        model: String,
        tools: [ToolSchema]?,
        options: ProviderOptions?
    ) -> AsyncThrowingStream<ChatChunk, Error>
}

OpenAIProvider

public final class OpenAIProvider: Provider {
    public init(apiKey: String, baseURL: URL = URL(string: "https://api.openai.com/v1")!)
}

OpenAI-compatible provider. Works with OpenAI, OpenRouter, and any OpenAI-compatible API.

ProviderFactory

public enum ProviderFactory {
    public static func create(
        providerName: String,
        apiKey: String,
        baseURL: URL? = nil
    ) throws -> Provider
}

Creates a provider by name. Supported: "openai", "openrouter".

ProviderOptions

public struct ProviderOptions: Sendable {
    public let timeout: TimeInterval      // Default: 30
    public let maxRetries: Int            // Default: 3
    public let maxTokens: Int?
    public let temperature: Double?
}

Tools

ToolDefinition Protocol

public protocol ToolDefinition: Sendable {
    var name: String { get }
    var description: String { get }
    var annotations: ToolAnnotations { get }
    var parameters: [String: AnyCodable] { get }

    func execute(params: [String: AnyCodable]) async throws -> ToolResult
}

ToolAnnotations

public struct ToolAnnotations: Sendable {
    public let readOnlyHint: Bool
    public let destructiveHint: Bool
    public let idempotentHint: Bool
    public let openWorldHint: Bool
}

ToolRegistry

public class ToolRegistry: @unchecked Sendable {
    public func register(_ tool: ToolDefinition)
    public func execute(toolCall: ToolCall) async throws -> ToolResult
    public func getTool(name: String) -> ToolDefinition?
    public func getAllTools() -> [ToolDefinition]
    public func getSchemas() -> [ToolSchema]
}

DefaultToolRegistry

public final class DefaultToolRegistry: ToolRegistry

Pre-registers all built-in tools: ReadFileTool, WriteFileTool, EditFileTool, BashTool, WebSearchTool, and 10 Git tools.

Built-in Tools

ToolNameDescription
ReadFileToolread_fileRead file contents
WriteFileToolwrite_fileWrite content to a file
EditFileTooledit_fileExact string replacements in a file
BashToolbashExecute shell commands
WebSearchToolweb_searchSearch the web via DuckDuckGo
GitStatusToolgit_statusShow working tree status
GitDiffToolgit_diffShow changes
GitLogToolgit_logShow commit logs
GitAddToolgit_addAdd files to index
GitCommitToolgit_commitRecord changes
GitPushToolgit_pushUpdate remote refs
GitPullToolgit_pullFetch and integrate
GitBranchToolgit_branchList branches
GitCheckoutToolgit_checkoutSwitch branches

Loop Strategies

LoopType

public enum LoopType: String, Sendable, CaseIterable {
    case react
    case planAndExecute = "plan_and_execute"
    case parallel
    case reflexion
}

LoopStrategy Protocol

public protocol LoopStrategy: Sendable {
    var loopType: LoopType { get }
    func execute(context: LoopContext) async throws -> RunResult
    func buildInitialMessages(context: LoopContext) async -> [Message]
}

Built-in Strategies

StrategyLoopTypeBest For
ReActStrategy.reactGeneral-purpose reasoning + acting
PlanAndExecuteStrategy.planAndExecuteComplex multi-step tasks
ParallelStrategy.parallelIndependent operations
ReflexionStrategy.reflexionQuality-critical tasks

LoopStrategyRegistry

public final class LoopStrategyRegistry {
    public func register(_ type: LoopType, strategy: any LoopStrategy)
    public func getStrategy(_ type: LoopType) -> (any LoopStrategy)?
    public func allTypes() -> [LoopType]
}

LoopOptions

public struct LoopOptions: Sendable {
    public let maxPlanningSteps: Int?
    public let maxParallelCalls: Int?
    public let reflectionSteps: Int?
    public let qualityThreshold: Double?
    public let callbacks: ExecutionCallbacks?
}

ExecutionCallbacks

public struct ExecutionCallbacks: Sendable {
    public let onTurnStart: (@Sendable (Int, Int) async -> Void)?
    public let onRequestStart: (@Sendable (Int, Int) async -> Void)?
    public let onResponse: (@Sendable (Bool, Int) async -> Void)?
    public let onToolCall: (@Sendable (ToolCallEvent) async -> Void)?
    public let onToolResult: (@Sendable (ToolResultEvent) async -> Void)?
    public let onTurnEnd: (@Sendable (Int, Int) async -> Void)?
    public let onComplete: (@Sendable (Int, String) async -> Void)?
    public let onError: (@Sendable (Error, Int?) async -> Void)?
}

Hooks

HookManager

public final class HookManager: @unchecked Sendable {
    public init(enabled: Bool = true)

    public var isEnabled: Bool
    public func setEnabled(_ enabled: Bool)

    public func addHook(_ hook: HookDefinition)
    public func removeHook(event: HookEvent, index: Int) -> Bool
    public func getHooks(for event: HookEvent) -> [HookDefinition]
    public func getAllHooks() -> [HookDefinition]
    public func execute(event: HookEvent, context: HookContext) async throws
}

HookEvent

public enum HookEvent: String, Sendable, CaseIterable {
    case sessionStart, sessionEnd
    case preClear, prePrompt
    case preTool, postTool
    case fileModified
    case stop, postResponse
    case subagentStop
    case permissionRequest
    case notification
    case sessionError
    case automodeStart, automodeIteration, automodeCheckpoint
    case automodePause, automodeResume, automodeCancel
    case automodeComplete, automodeError
    case preLearn, postLearn
    case teamCreated, teammateSpawned, teammateIdle
    case taskAssigned, taskCompleted, teamShutdown
    case reviewStart, reviewEnd, reviewPaused
    case reviewFailed, reviewCompleted
    case modeChange
    case contextCompact, contextOverflow
    case contextWarning, contextCritical
    case beforeExecution, afterExecution
    case onError
}

HookDefinition

public struct HookDefinition: Sendable {
    public let event: HookEvent
    public let command: String
    public let description: String?
    public let enabled: Bool
    public let timeout: Int          // milliseconds, default: 5000
    public let async: Bool
    public let matcher: String?      // regex pattern
    public let filter: HookFilter?
}

HookContext

public struct HookContext: Sendable {
    public let sessionID: String
    public let cwd: String
    public let hookEventName: HookEvent
    public let toolName: String?
    public let toolInput: [String: AnyCodable]?
    public let instruction: String?
    public let tokensUsed: Int?
    public let error: String?
    public let errorCode: String?
    // ... additional context fields
}

Permissions

PermissionManager

public final class PermissionManager: @unchecked Sendable {
    public init(hookManager: HookManager, mode: PermissionMode = .ask)

    public var permissionMode: PermissionMode
    public func setPermissionMode(_ mode: PermissionMode)

    public func requestPermission(_ request: PermissionRequest) async -> PermissionResult
}

PermissionMode

public enum PermissionMode: String, Sendable, Codable {
    case yolo    // Allow everything
    case ask     // Ask for each tool (default)
    case deny    // Deny everything
}

PermissionDecision

public enum PermissionDecision: String, Sendable {
    case allow
    case deny
    case ask
    case block
}

PermissionRequest

public struct PermissionRequest: Sendable {
    public let tool: ToolName
    public let args: [String: AnyCodable]
    public let path: String?
    public let command: String?
}

PermissionResult

public struct PermissionResult: Sendable {
    public let decision: PermissionDecision
    public let reason: String?
    public let `continue`: Bool
}

Core Types

ToolName

public enum ToolName: String, Sendable, CaseIterable, Codable {
    case readFile, writeFile, editFile, applyPatch
    case find, glob, searchInFiles
    case bash
    case gitStatus, gitDiff, gitLog, gitCommit, gitAdd
    case gitReset, gitPush, gitPull, gitFetch, gitCheckout
    case gitBranch, gitMerge, gitRebase, gitStash
    case webSearch
    case notebookRead, notebookEdit
    case readPackageManifest, addDependency, removeDependency
    case formatFile, formatDirectory, listFormatters, checkFormatting
    case lintFile, lintDirectory, listLinters
}

Message

public enum Message: Sendable, Codable {
    case user(UserMessage)
    case assistant(AssistantMessage)
    case system(SystemMessage)
    case tool(ToolMessage)
}

ToolCall

public struct ToolCall: Sendable, Codable {
    public let id: String
    public let name: ToolName
    public let arguments: String  // JSON string
}

ToolResult

public enum ToolResult: Sendable {
    case success(data: String, metadata: [String: AnyCodable]? = nil)
    case failure(error: String, metadata: [String: AnyCodable]? = nil)
}

Session

public struct Session: Sendable, Codable {
    public let id: SessionID
    public var messages: [Message]
    public let workingDirectory: String
    public let createdAt: Date
}

RunResult

public enum RunResult: Sendable {
    case success(finalOutput: String, session: Session, turns: Int)
    case maxTurnsReached(session: Session, turns: Int)
}

StreamEvent

public struct StreamEvent: Sendable {
    public let type: StreamEventType  // .content, .toolCall, .toolResult, .toolError, .done
    public let data: String?
    public let tool: ToolName?
    public let toolID: String?
}

ChatResponse

public struct ChatResponse: Sendable, Codable {
    public let id: String
    public let content: String
    public let toolCalls: [ToolCall]?
    public let finishReason: String?
    public let usage: [String: Int]?
}

Errors

AgentSDKError

public enum AgentSDKError: Error, LocalizedError, Sendable {
    case timeout(message: String, timeoutMs: Int, context: [String: AnyCodable]?)
    case retryExhausted(message: String, attempts: Int, lastError: Error)
    case validation(message: String, field: String?, value: AnyCodable?)
    case provider(message: String, providerName: String, context: [String: AnyCodable]?)
    case toolExecution(message: String, toolName: String, context: [String: AnyCodable]?)
    case agentConfig(message: String)
    case notFound(message: String, resourceType: String, resourceID: String)
    case executionFailed(message: String, context: [String: AnyCodable]?)
}

Properties:

  • code: String — Error code (TIMEOUT, VALIDATION, PROVIDER_ERROR, etc.)
  • isRetryable: Bool — Whether the error is safe to retry
  • errorDescription: String? — Human-readable description

Branded Types

public struct ToolCallID: Hashable, Sendable, Codable, ExpressibleByStringLiteral
public struct SessionID: Hashable, Sendable, Codable, ExpressibleByStringLiteral
public struct ModelID: Hashable, Sendable, Codable, ExpressibleByStringLiteral

Prevent accidental mixing of string identifiers.


AnyCodable

public struct AnyCodable: Codable, @unchecked Sendable {
    public let value: Any
    public init(_ value: Any)
}

Type-erased Codable wrapper for dynamic JSON values in tool parameters and hook contexts.