Skip to content

@makaio/ai-adapters-openai-node

OpenAI adapter implementation using the official OpenAI Node SDK for agentic chat completions.

import { OpenAIAdapter, createOpenAINodeAdapter } from '@makaio/ai-adapters-openai-node';
import { MakaioBus } from '@makaio/bus-core';
import { AdapterSubjects } from '@makaio/contracts';
// Using the convenience factory
const adapter = await createOpenAINodeAdapter();
const result = await MakaioBus.request(AdapterSubjects.startAgent, {
adapterId: adapter.adapterId,
role: 'lead',
initialMessage: 'Inspect this repository',
model: 'gpt-4.1',
});
// Or using the class directly
const directAdapter = new OpenAIAdapter();
await directAdapter.init();
const directResult = await MakaioBus.request(AdapterSubjects.startAgent, {
adapterId: directAdapter.adapterId,
role: 'lead',
initialMessage: 'Inspect this repository',
model: 'gpt-4.1',
});

This adapter implements a three-layer architecture for clean separation of concerns:

OpenAIAdapter (extends AIAdapter)
↓ creates via agentFactory()
OpenAIAgent (extends BaseStreamAgent)
↓ creates via connectorFactory()
OpenAINodeConnector (extends BaseStreamConnector)
↓ wraps
OpenAI SDK Client
LayerClassResponsibility
AdapterOpenAIAdapterHandle adapter.startAgent RPC, manage agent lifecycle, emit adapter events
AgentOpenAIAgentWire connector events to global agent.* subjects, enrich payloads with agent context
ConnectorOpenAINodeConnectorSDK client setup, credentials, tool loading, stream-session lifecycle
SessionOpenAIConnectorSessionOpenAI message history, streaming API calls, and the agentic tool-call loop

The session implements the standard agentic loop:

  1. Send user message to OpenAI
  2. Process streaming response
  3. If tool_calls present, execute tools via Bus RPC and recurse
  4. When no tool_calls, mark turn complete

OpenAIAgent, OpenAINodeConnector, OpenAIConnectorSession, OpenAIConnectorTurn, and namespace exports are public for framework implementers and tests. Most applications should use the ./server runtime contribution or createOpenAINodeAdapter() rather than constructing the lower layers directly.

Raw SDK events are normalized into typed semantic subjects:

SubjectDescription
chunkStreaming text delta
usageToken usage metrics
tool_callsTool call requests from model
tool_startedTool execution started
tool_completedTool execution finished
message_completeFull message assembled
reasoning_deltaReasoning content delta (o1-style)
reasoning_completeFull reasoning assembled
agent_startedAgent turn started
agent_completeAgent turn finished
errorError occurred

sdk.event carries an envelope with an event property. The exported SdkEvent type is the envelope; use SdkEventMessage internally when you need the nested discriminated union.

  • OpenAIConnectorSession - Manages turn lifecycle and message history
  • OpenAIConnectorTurn - Handles a single turn’s streaming and tool execution
  • UserMessageQueue - Internal queue from adapter core

Tool execution routes through the approval system:

  1. Connector emits tool_approval RPC on scoped bus
  2. Agent wires to global AgentSubjects.toolApprove
  3. Approval handler responds with approve/deny
  4. Connector proceeds or skips based on response
ExportDescription
OpenAIAdapterDomain-level adapter, handles adapter.* subjects
OpenAIAgentAgent wrapper, handles agent.* subjects
OpenAINodeConnectorSDK connector, extends BaseStreamConnector
OpenAIConnectorSessionSession state management
OpenAIConnectorTurnSingle turn execution
UserMessageQueueInternal queue from adapter core
ExportDescription
OpenAINodeConnectorNamespaceBus namespace with typed schemas
OpenAINodeConnectorSubjectsPre-extracted subject constants
OPENAI_NODE_NAMESPACENamespace string constant
SdkEventsdk.event envelope with nested event discriminated union
ExportDescription
OpenAISessionConfigSession configuration type
createTestConfigConformance test suite configuration

Runtime registration is contributed by @makaio/ai-adapters-openai-node/server. That entrypoint default-exports the openaiNodePackage MakaioExtension descriptor, whose adapters[] entry wraps the internal definition from src/definition.ts.

src/
├── index.ts # Public API exports
├── adapter.ts # OpenAIAdapter class
├── agent.ts # OpenAIAgent class
├── connector.ts # OpenAINodeConnector class
├── session.ts # Session management
├── turn.ts # Turn execution
├── config.ts # Configuration factory
├── constants.ts # Namespace constants
├── definition.ts # Internal adapter definition
├── package.ts # MakaioExtension package descriptor
├── server.ts # Server entrypoint exporting the package descriptor
├── provider.ts # Provider registration
├── provider.fetcher.ts # Model fetcher
├── model-normalization.ts # Model metadata normalization
├── mcp-integration.ts # MCP tool integration
├── tool-handling.ts # Tool approval and execution
├── stream-bridge.ts # SDK stream normalization
├── schemas.ts # Provider config and credential schemas
├── namespaces/
│ ├── index.ts # Namespace registration
│ └── schemas/ # Event type schemas
│ ├── chunk.ts
│ ├── message.ts
│ ├── reasoning.ts
│ ├── tool-calls.ts
│ └── usage.ts
├── types/
│ └── index.ts # TypeScript type definitions
└── utils/
├── blockToContentPart.ts
├── buildChatCompletionRequest.ts
├── classifyOpenAIError.ts
└── convertMessageHistory.ts

Part of the Makaio AI framework