Skip to content

Abstract Class: ProceduralAgentConnector<TBus, TConfig>

Makaio Framework


Makaio Framework / ai-adapters-core / ProceduralAgentConnector

Abstract Class: ProceduralAgentConnector<TBus, TConfig>

Section titled “Abstract Class: ProceduralAgentConnector<TBus, TConfig>”

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:89

Abstract base class for procedural (non-event-driven) agent connectors.

Procedural adapters (OpenAI, Copilot, Gemini) share common patterns:

  • wireSessionEvents: subscribe to turn lifecycle events and update processing state
  • processUserMessages: initialize session, enqueue, transition to active, process queue
  • complete: poll processing state until idle/paused
  • start: delegate to sendMessage and return AgentStartResult
  • acceptsImmediate: delegate to session’s current turn

Subclasses must implement:

  • getSession() / ensureSession() for session access and lazy initialization
  • getSessionQueue() for the adapter’s UserMessageQueue instance
  • getTurnSubjects() for namespace-specific turn subjects
  • sendMessage(), abort(), close(), interrupt(), getAdapterSessionId()

Subclasses may override:

  • getWireSessionConfig() for custom turn_finished behavior (e.g., Copilot multi-turn)

TBus extends ScopedBus<string> = ScopedBus<string>

Scoped bus type for adapter namespace

TConfig extends BaseAgentConnectorConfig<TBus> = BaseAgentConnectorConfig<TBus>

Configuration type extending BaseAgentConnectorConfig

protected new ProceduralAgentConnector<TBus, TConfig>(config): ProceduralAgentConnector<TBus, TConfig>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:119

BaseAgentConnectorConfig<TBus, object> & object

ProceduralAgentConnector<TBus, TConfig>

AIAgentConnector.constructor

readonly adapterId: string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:91

Adapter identifier shared across instances of the same adapter type.

AIAgentConnector.adapterId


protected readonly adapterName: string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:115

Adapter type name for event identification.

AIAgentConnector.adapterName


optional adapterSessionId?: string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:70

Session ID from the provider (set after connection/start).

AIAgentConnector.adapterSessionId


protected readonly agentId: string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:68

Unique identifier for this agent instance.

AIAgentConnector.agentId


protected readonly config: TConfig & object

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:95

adapterId: string

AIAgentConnector.config


currentReasoningEffort: "none" | "low" | "medium" | "high" | "extra-high" | undefined

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:103

Current reasoning effort level, updated by changeReasoningInPlace.

AIAgentConnector.currentReasoningEffort


cwd: string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:101

Working directory for agent execution

AIAgentConnector.cwd


protected deferredInterrupt: DeferredPromise<void> | undefined

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:82

Deferred promise for interrupt coordination.

AIAgentConnector.deferredInterrupt


protected readonly env: Record<string, string>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:109

AIAgentConnector.env


protected readonly optional errorHandler?: (error, terminate) => void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:80

Optional error handler callback.

Error

boolean

void

AIAgentConnector.errorHandler


protected lastResult: MessageResult | null = null

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:94

AIAgentConnector.lastResult


model: string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:97

Model used for this agent (subclasses may update when SDK confirms actual model)

AIAgentConnector.model


protected optional pendingMessageHandle?: MessageHandle

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:74

Currently active message handle waiting for completion.

AIAgentConnector.pendingMessageHandle


optional providerConfigId?: string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:99

ProviderConfig UUID used during agent creation, carried for runtime introspection

AIAgentConnector.providerConfigId


protected readonly optional sessionId?: string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:72

Makaio session ID for cross-session correlation and approval routing.

AIAgentConnector.sessionId


supportedReasoningLevels: { extra-high?: string | number; high?: string | number; low?: string | number; medium?: string | number; none?: string | number; } | undefined

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:108

Reasoning levels supported by the current model, forwarded from the config factory. undefined when the model does not declare reasoning support.

AIAgentConnector.supportedReasoningLevels


protected optional systemPrompt?: string | { content: string; mode: "append"; }

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:117

Runtime system prompt from start/initialize options.

AIAgentConnector.systemPrompt


protected readonly timeouts: TrackedTimeoutConfig

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:93

Resolved timeout configuration with provenance tracking.

AIAgentConnector.timeouts

get protected currentTurnNumber(): number

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:344

Current turn number (read-only). Use consumeTurnNumber to advance.

number

The current turn number

AIAgentConnector.currentTurnNumber


get protected pendingTurnNumber(): number | undefined

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:352

Staged canonical turn number, or undefined if none was staged.

number | undefined

The pending canonical turn number

AIAgentConnector.pendingTurnNumber

abstract abort(): void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:246

Abort the agent and cleanup resources (panic mode). Triggers AbortController which may cause provider errors. Use close() for graceful shutdown instead.

void

AIAgentConnector.abort


protected acceptsImmediate(): boolean

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:276

Returns true if current turn can accept immediate messages.

boolean

True if turn can accept immediate, false otherwise


protected captureSystemPrompt(prompt): void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:167

Store runtime system prompt for session creation. Subclasses may override to apply SDK-specific side effects (e.g., Gemini’s setSystemInstruction).

string | { content: string; mode: "append"; } | undefined

System prompt from start/initialize options

void

AIAgentConnector.captureSystemPrompt


changeCwdInPlace(_newCwd): Promise<boolean>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:385

Attempt to change the working directory without a connector swap. Subclasses override when the adapter supports in-place cwd changes (e.g., stateless APIs). Base implementation returns false (swap required).

Mutation contract: Implementations MUST NOT mutate this.cwd directly. The caller (AIAgent.handleCwdChange) owns the this.cwd field update after a successful in-place change. Implementations only update SDK-internal state.

string

The working directory path to switch to

Promise<boolean>

true if changed in-place, false if swap needed. Exceptions are caught by the caller and treated as false (automatic swap fallback), so implementations need not guard.

AIAgentConnector.changeCwdInPlace


changeModelInPlace(_newModel): Promise<boolean>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:369

Attempt to change the model without a connector swap. Subclasses override when the SDK supports in-place model changes. Base implementation returns false (swap required).

Mutation contract: Implementations MUST NOT mutate this.model directly. The caller (AIAgent.handleModelChange) owns the this.model field update after a successful in-place change. Implementations only configure the SDK-internal model (e.g., query.setModel(), geminiConfig.setModel()).

string

The model identifier to switch to

Promise<boolean>

true if changed in-place, false if swap needed. Exceptions are caught by the caller and treated as false (automatic swap fallback), so implementations need not guard.

AIAgentConnector.changeModelInPlace


changeReasoningInPlace(_newLevel): Promise<boolean>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:402

Attempt to change reasoning effort without swapping the connector.

Override in subclasses that support in-place reasoning changes (e.g., adapters that pass reasoning parameters per-request rather than at session-creation time). The base implementation returns false so callers fall back to a connector swap.

Mutation contract: Implementations MUST NOT mutate this.currentReasoningEffort directly. The caller owns the currentReasoningEffort field update after a successful in-place change. Implementations only configure the SDK-internal reasoning parameter.

"none" | "low" | "medium" | "high" | "extra-high"

The new reasoning effort level to apply

Promise<boolean>

true if the change was applied in-place, false if a connector swap is needed

AIAgentConnector.changeReasoningInPlace


abstract close(): Promise<void>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:253

Gracefully close the agent session. Unlike abort(), this doesn’t trigger AbortController errors. Use this for normal shutdown; use abort() for emergency termination.

Promise<void>

AIAgentConnector.close


complete(): Promise<MessageResult | null>

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:265

Complete the agent session by waiting for all messages to finish.

Promise<MessageResult | null>

Last message result or null if no messages processed

AIAgentConnector.complete


protected consumeTurnNumber(): number

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:330

Advance to the next turn number, consuming any pending canonical value. Orchestrator-staged values win; otherwise the local counter increments by one.

number

The current turn number after advancement

AIAgentConnector.consumeTurnNumber


protected createMessageHandle(message, options?): MessageHandle

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:279

Create a MessageHandle with standard initialization.

Centralizes the pattern used by all connectors:

  1. Generate messageId (use provided or generate UUID)
  2. Create MessageHandle instance
  3. Set adapterSessionId
  4. Call onMessageSent callback

NormalizedMessageInput

Normalized user message

MessageHandleOptions

Optional message options (id, delivery mode, history, and turn context)

MessageHandle

Initialized MessageHandle ready for enqueueing

AIAgentConnector.createMessageHandle


protected emit<TSubject>(subject, payload): Promise<void>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:527

Emit an event via the scoped bus with auto-injected metadata.

Wraps scopedBus.emit() to automatically include connector identity (adapterName, agentId, adapterId, adapterSessionId) in the payload.

TSubject extends ScopedSubjectDefinition<TBus["namespace"]>

TSubject

Subject definition for the event

Forbid<TSubject["$meta"]["payload"], ForbiddenKeys>

Event payload (metadata fields are forbidden and auto-injected)

Promise<void>

Promise that resolves when the event is emitted

AIAgentConnector.emit


abstract protected ensureSession(): Promise<ProceduralConnectorSession>

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:107

Initialize and return the adapter’s session. Must be idempotent (no-op if already initialized).

Promise<ProceduralConnectorSession>

The initialized session


getAdapterName(): string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:456

string

AIAgentConnector.getAdapterName


abstract getAdapterSessionId(): Promise<string>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:259

Get session ID, waiting for provider to generate it if not yet available.

Promise<string>

Session ID from provider

AIAgentConnector.getAdapterSessionId


getAgentId(): string

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:452

string

AIAgentConnector.getAgentId


getProcessingState(): ProcessingState

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:149

Get the current processing state of the agent.

ProcessingState

The current processing state

AIAgentConnector.getProcessingState


abstract protected getSession(): ProceduralConnectorSession | undefined

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:100

Get the adapter’s session instance (may be undefined if not yet initialized).

ProceduralConnectorSession | undefined

The session or undefined


abstract protected getSessionQueue(): UserMessageQueue

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:113

Get the adapter’s UserMessageQueue instance.

UserMessageQueue

The message queue


getTimeoutMs(category): number

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:465

Get timeout value for a specific category.

TimeoutCategory

Timeout category (initialization, acknowledgement, completion, toolApproval, eventWait)

number

Timeout value in milliseconds

AIAgentConnector.getTimeoutMs


abstract protected getTurnSubjects(): WireSessionSubjects<TBus["namespace"]>

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:119

Get the adapter’s namespace-specific turn subjects for wireSessionEvents.

WireSessionSubjects<TBus["namespace"]>

Turn subject definitions


protected getWireSessionConfig(): WireSessionConfig | undefined

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:127

Get optional wire session configuration for custom turn_finished behavior. Override in subclasses that need non-standard turn_finished handling (e.g., Copilot multi-turn message completion).

WireSessionConfig | undefined

Wire session configuration, or undefined for default behavior


handleError(error, terminate?): void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:418

Internal

Marks pending message as failed, calls error handler, resolves completion promise.

unknown

Error that occurred

boolean = false

Whether to abort the agent after handling error

void

AIAgentConnector.handleError


protected handlePause(_reason): void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:158

Handle pause after rejection or error. Subclasses should clear pending messages as appropriate.

"error" | "rejection"

Reason for pause (‘rejection’ | ‘error’); available for subclass overrides

void

AIAgentConnector.handlePause


protected handleToolApprovalDenied(abort, details?): void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:444

"handled" | "not_requested" | "not_supported"

string

void

AIAgentConnector.handleToolApprovalDenied


initialize(options?): Promise<void>

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:236

Initialize the connector’s SDK session without sending a message. Must set adapterSessionId before returning. Called by createAgent for idle agent setup. Implementations MUST be idempotent (no-op if already initialized).

ConnectorSendMessageOptions

Optional start options (e.g., systemPrompt)

Promise<void>

AIAgentConnector.initialize


abstract interrupt(): Promise<void>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:410

Interrupt the current message processing.

Promise<void>

Promise that resolves when interrupt is handled

AIAgentConnector.interrupt


protected logLowLevelEvent(_event): void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:572

unknown

void

AIAgentConnector.logLowLevelEvent


markToolRefreshPending(): void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:302

Signal that MCP tools have changed and should be refreshed at the next turn boundary.

Called by the AIAgent layer when receiving MCP bus events (mcp.tools.updated, mcp.tools.enabled). Connectors that support direct-inject tool refresh (e.g., BaseStreamConnector) override this to set an internal pending-refresh flag. The default implementation is a no-op so connectors that do not manage MCP tools directly are unaffected.

void

AIAgentConnector.markToolRefreshPending


on<Subject>(subject, handler, options?): () => void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:549

Subscribe to events on the filtered bus (pre-filtered by agentId).

Uses filteredBus which only delivers events matching this connector’s agentId.

Subject extends ScopedSubjectDefinition<TBus["namespace"]>

Subject

Subject definition to subscribe to

HandlerForSubjectDefinition<Subject>

Event handler receiving the event context

OnOptions

Optional subscription options (e.g., priority)

Unsubscribe function

() => void

AIAgentConnector.on


once<Subject>(subject, options?): Promise<never>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:565

Wait for a single event on the filtered bus (pre-filtered by agentId).

Uses filteredBus which only delivers events matching this connector’s agentId.

Subject extends ScopedSubjectDefinition<TBus["namespace"]>

Subject

Subject definition to wait for

OnceOptions<ScopedSubjectDefinition<TBus["namespace"]>>

Optional options (e.g., predicate filter, timeout)

Promise<never>

Promise resolving to the event context

AIAgentConnector.once


onceProcessingStateChanged(predicate?): Promise<ProcessingState>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:206

Wait for a single processing state change matching an optional predicate.

(eventData) => boolean

Optional filter, e.g., (e) => !e.isProcessing for idle

Promise<ProcessingState>

Promise resolving to { isProcessing: boolean }

AIAgentConnector.onceProcessingStateChanged


onProcessingStateChanged(handler): UnsubscribeFunction

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:195

Subscribe to processing state changes (idle ↔ processing transitions).

(payload) => void | Promise<void>

Called with { isProcessing: boolean } on each state change

UnsubscribeFunction

Unsubscribe function

AIAgentConnector.onProcessingStateChanged


protected processUserMessages(messageHandles): Promise<Set<MessageHandle>>

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:212

Process queued user messages by delegating to Session.

Shared flow:

  1. Initialize session if not yet created
  2. Enqueue the message
  3. Set adapterSessionId on handle
  4. Transition to active if currently idle/paused
  5. Process queue via session

MessageHandle[]

Array of message handles to process

Promise<Set<MessageHandle>>

Set of message handles that were processed


protected requestToolApproval<TSubject>(subject, payload): Promise<TSubject["$meta"]["payload"]["response"]>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:478

Request tool approval via the scoped bus with auto-injected metadata.

Wraps scopedBus.request() to automatically include connector identity (adapterName, agentId, adapterId, adapterSessionId) in the payload.

TSubject extends ScopedSubjectDefinition<TBus["namespace"]>

TSubject

Subject definition for the tool approval request

Forbid<TSubject["$meta"]["payload"]["request"], ForbiddenKeys>

Request payload (metadata fields are forbidden and auto-injected)

Promise<TSubject["$meta"]["payload"]["response"]>

Promise resolving to the approval response

AIAgentConnector.requestToolApproval


protected requestToolApprovalWithHandling<TSubject>(subject, payload): Promise<TSubject["$meta"]["payload"]["response"]>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:502

Execute a tool approval request with the shared diagnostics wrapper.

Handles the common RequestError/NoHandlerError path by logging a helpful message via handleError and re-throwing so callers can decide whether to surface the failure or fall back to a denial.

TSubject extends ScopedSubjectDefinition<TBus["namespace"]>

TSubject

Scoped subject definition for the tool approval request

Forbid<TSubject["$meta"]["payload"]["request"], ForbiddenKeys>

Payload that must not include adapter metadata

Promise<TSubject["$meta"]["payload"]["response"]>

Tool approval response payload

AIAgentConnector.requestToolApprovalWithHandling


abstract sendMessage(message, options?): Promise<MessageHandle>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:236

Send a message to the agent. For initial message, use start() instead.

NormalizedMessageInput

Normalized message content

ConnectorSendMessageOptions

Send options (e.g., delivery mode, message ID)

Promise<MessageHandle>

Message handle for tracking

AIAgentConnector.sendMessage


setCanonicalTurnNumber(turnNumber): void

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:312

Stage the canonical orchestrator-assigned turn number for consumption by the next consumeTurnNumber call. The counter is monotonically increasing.

number

Canonical 1-based turn number from SessionOrchestrator

void

RangeError when the value is invalid, regresses, or downgrades a staged value

AIAgentConnector.setCanonicalTurnNumber


start(message, options?): Promise<AgentStartResult>

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:248

Start session with initial message.

NormalizedMessageInput

The initial message to send

ConnectorSendMessageOptions

Optional send message options

Promise<AgentStartResult>

The agent start result with session ID and message handle

AIAgentConnector.start


protected updateProcessingState(state): Promise<void>

Defined in: ../../../adapters/core/src/connector/agent-connector.ts:177

Update the agent’s processing state. State transitions trigger events via emittery.

ProcessingState

New processing state

Promise<void>

AIAgentConnector.updateProcessingState


protected wireSessionEvents(): void

Defined in: ../../../adapters/core/src/connector/procedural-agent-connector.ts:140

Wire Session turn events to Connector state updates.

Session emits typed events, Connector subscribes and updates processing state. This maintains separation of concerns - Session does not know about Connector state.

Default turn_finished behavior: transition through processing_finished to idle, or drain the queue if messages are pending. Override via getWireSessionConfig().

void