@agentxjs/core 2.0.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/{Processor-DT0N1qI6.d.ts → Processor-CeMyXtsX.d.ts} +1 -1
  2. package/dist/agent/engine/internal/index.d.ts +4 -5
  3. package/dist/agent/engine/internal/index.js +1 -1
  4. package/dist/agent/engine/mealy/index.d.ts +4 -4
  5. package/dist/agent/engine/mealy/index.js +1 -1
  6. package/dist/agent/index.d.ts +91 -91
  7. package/dist/agent/index.js +6 -6
  8. package/dist/agent/types/index.d.ts +4 -4
  9. package/dist/agent/types/index.js +1 -1
  10. package/dist/bash/index.d.ts +4 -4
  11. package/dist/{chunk-LTVNPHST.js → chunk-22NTRYNO.js} +60 -60
  12. package/dist/chunk-22NTRYNO.js.map +1 -0
  13. package/dist/{chunk-7ZDX3O6I.js → chunk-AAFPAF67.js} +2 -2
  14. package/dist/{chunk-7ZDX3O6I.js.map → chunk-AAFPAF67.js.map} +1 -1
  15. package/dist/{chunk-EKHT54KN.js → chunk-APCBNCOW.js} +1 -1
  16. package/dist/{chunk-EKHT54KN.js.map → chunk-APCBNCOW.js.map} +1 -1
  17. package/dist/{chunk-JTKCV7IS.js → chunk-RWIYC65R.js} +111 -111
  18. package/dist/{chunk-JTKCV7IS.js.map → chunk-RWIYC65R.js.map} +1 -1
  19. package/dist/{chunk-DEAR6N3O.js → chunk-TUFZ2YH6.js} +1 -1
  20. package/dist/chunk-TUFZ2YH6.js.map +1 -0
  21. package/dist/{chunk-23UUBQXR.js → chunk-YSZG6XIM.js} +1 -1
  22. package/dist/chunk-YSZG6XIM.js.map +1 -0
  23. package/dist/{combinators-nEa5dD0T.d.ts → combinators-Dy-7lxKV.d.ts} +50 -50
  24. package/dist/common/logger/index.js +14 -14
  25. package/dist/common/logger/index.js.map +1 -1
  26. package/dist/container/index.d.ts +3 -3
  27. package/dist/driver/index.d.ts +2 -2
  28. package/dist/event/index.d.ts +1 -1
  29. package/dist/event/index.js +2 -2
  30. package/dist/event/types/index.d.ts +199 -199
  31. package/dist/event/types/index.js +1 -1
  32. package/dist/{event-DNWOBSBO.d.ts → event-DNsF9EkO.d.ts} +4 -6
  33. package/dist/image/index.d.ts +3 -3
  34. package/dist/image/index.js.map +1 -1
  35. package/dist/{index-CuS1i5V-.d.ts → index--gxNpY5W.d.ts} +2 -2
  36. package/dist/index.d.ts +4 -4
  37. package/dist/index.js +6 -6
  38. package/dist/{message-03TJzvIX.d.ts → message-Dn-I2vr0.d.ts} +1 -1
  39. package/dist/mq/index.d.ts +25 -25
  40. package/dist/mq/index.js +1 -1
  41. package/dist/mq/index.js.map +1 -1
  42. package/dist/network/index.d.ts +2 -220
  43. package/dist/network/index.js +27 -27
  44. package/dist/network/index.js.map +1 -1
  45. package/dist/persistence/index.d.ts +2 -2
  46. package/dist/platform/index.d.ts +14 -6
  47. package/dist/runtime/index.d.ts +5 -5
  48. package/dist/runtime/index.js +6 -6
  49. package/dist/runtime/index.js.map +1 -1
  50. package/dist/session/index.d.ts +3 -3
  51. package/dist/{RpcClient-BcJ_zAGu.d.ts → types-CTV8Z9PI.d.ts} +225 -7
  52. package/dist/{types-aE74Eo6G.d.ts → types-Cb8tKM6Y.d.ts} +1 -1
  53. package/package.json +1 -1
  54. package/src/agent/AgentStateMachine.ts +2 -2
  55. package/src/agent/__tests__/AgentStateMachine.test.ts +2 -2
  56. package/src/agent/__tests__/createAgent.test.ts +4 -4
  57. package/src/agent/__tests__/engine/internal/messageAssemblerProcessor.test.ts +10 -10
  58. package/src/agent/__tests__/engine/internal/stateEventProcessor.test.ts +6 -6
  59. package/src/agent/__tests__/engine/internal/turnTrackerProcessor.test.ts +4 -4
  60. package/src/agent/__tests__/engine/mealy/Mealy.test.ts +3 -3
  61. package/src/agent/__tests__/engine/mealy/Store.test.ts +1 -1
  62. package/src/agent/__tests__/engine/mealy/combinators.test.ts +4 -4
  63. package/src/agent/createAgent.ts +15 -15
  64. package/src/agent/engine/AgentProcessor.ts +7 -7
  65. package/src/agent/engine/MealyMachine.ts +3 -3
  66. package/src/agent/engine/internal/index.ts +11 -11
  67. package/src/agent/engine/internal/messageAssemblerProcessor.ts +14 -14
  68. package/src/agent/engine/internal/stateEventProcessor.ts +13 -15
  69. package/src/agent/engine/internal/turnTrackerProcessor.ts +4 -4
  70. package/src/agent/engine/mealy/Mealy.ts +2 -2
  71. package/src/agent/engine/mealy/combinators.ts +10 -10
  72. package/src/agent/engine/mealy/index.ts +9 -11
  73. package/src/agent/index.ts +30 -32
  74. package/src/agent/types/engine.ts +3 -3
  75. package/src/agent/types/event.ts +4 -8
  76. package/src/agent/types/index.ts +85 -85
  77. package/src/bash/index.ts +1 -1
  78. package/src/common/logger/ConsoleLogger.ts +1 -1
  79. package/src/common/logger/LoggerFactoryImpl.ts +14 -14
  80. package/src/common/logger/index.ts +3 -3
  81. package/src/container/index.ts +4 -5
  82. package/src/container/types.ts +1 -1
  83. package/src/driver/index.ts +15 -17
  84. package/src/driver/types.ts +89 -79
  85. package/src/event/EventBus.ts +10 -10
  86. package/src/event/__tests__/EventBus.test.ts +1 -1
  87. package/src/event/index.ts +2 -3
  88. package/src/event/types/agent.ts +186 -180
  89. package/src/event/types/bus.ts +1 -1
  90. package/src/event/types/command.ts +292 -265
  91. package/src/event/types/container.ts +207 -222
  92. package/src/event/types/driver.ts +153 -155
  93. package/src/event/types/index.ts +6 -12
  94. package/src/event/types/session.ts +117 -130
  95. package/src/image/Image.ts +1 -1
  96. package/src/image/index.ts +4 -5
  97. package/src/mq/OffsetGenerator.ts +1 -1
  98. package/src/mq/__tests__/OffsetGenerator.test.ts +1 -1
  99. package/src/mq/index.ts +4 -5
  100. package/src/network/RpcClient.ts +10 -10
  101. package/src/network/index.ts +41 -44
  102. package/src/network/jsonrpc.ts +5 -5
  103. package/src/persistence/index.ts +5 -5
  104. package/src/platform/types.ts +15 -5
  105. package/src/runtime/AgentXRuntime.ts +15 -15
  106. package/src/runtime/__tests__/AgentXRuntime.test.ts +5 -5
  107. package/src/runtime/index.ts +5 -6
  108. package/src/runtime/types.ts +1 -1
  109. package/src/session/index.ts +2 -3
  110. package/dist/chunk-23UUBQXR.js.map +0 -1
  111. package/dist/chunk-DEAR6N3O.js.map +0 -1
  112. package/dist/chunk-LTVNPHST.js.map +0 -1
@@ -1,8 +1,8 @@
1
- import { d as ContainerRepository, I as ImageRepository, c as SessionRepository } from '../index-CuS1i5V-.js';
1
+ import { B as BashProvider } from '../types-Cb8tKM6Y.js';
2
+ import { d as ContainerRepository, I as ImageRepository, c as SessionRepository } from '../index--gxNpY5W.js';
2
3
  import { E as EventBus } from '../bus-C9FLWIu8.js';
3
- import { B as BashProvider } from '../types-aE74Eo6G.js';
4
- import { W as WebSocketFactory } from '../RpcClient-BcJ_zAGu.js';
5
- import '../message-03TJzvIX.js';
4
+ import { F as ChannelServer, w as ChannelClientFactory } from '../types-CTV8Z9PI.js';
5
+ import '../message-Dn-I2vr0.js';
6
6
  import '../base-m40r3Qgu.js';
7
7
  import 'jsonrpc-lite';
8
8
 
@@ -65,12 +65,20 @@ interface AgentXPlatform {
65
65
  */
66
66
  readonly bashProvider?: BashProvider;
67
67
  /**
68
- * WebSocket factory for creating client connections
68
+ * Channel server for accepting client connections (server-side)
69
+ *
70
+ * Optional — only needed for server scenarios.
71
+ * Node.js platform provides ws-based implementation.
72
+ * Cloudflare platform provides DO Hibernation API implementation.
73
+ */
74
+ readonly channelServer?: ChannelServer;
75
+ /**
76
+ * Channel client factory for creating connections (client-side)
69
77
  *
70
78
  * Optional — browser uses native WebSocket by default.
71
79
  * Node.js platform provides ws-based implementation.
72
80
  */
73
- readonly webSocketFactory?: WebSocketFactory;
81
+ readonly channelClient?: ChannelClientFactory;
74
82
  }
75
83
 
76
84
  export type { AgentXPlatform };
@@ -1,10 +1,10 @@
1
- import { AgentXPlatform } from '../platform/index.js';
2
- import { b as UserContentPart } from '../message-03TJzvIX.js';
1
+ import { b as UserContentPart } from '../message-Dn-I2vr0.js';
2
+ import { h as CreateDriver } from '../index--gxNpY5W.js';
3
3
  import { B as BusEvent } from '../base-m40r3Qgu.js';
4
- import { h as CreateDriver } from '../index-CuS1i5V-.js';
4
+ import { AgentXPlatform } from '../platform/index.js';
5
+ import '../types-Cb8tKM6Y.js';
5
6
  import '../bus-C9FLWIu8.js';
6
- import '../types-aE74Eo6G.js';
7
- import '../RpcClient-BcJ_zAGu.js';
7
+ import '../types-CTV8Z9PI.js';
8
8
  import 'jsonrpc-lite';
9
9
 
10
10
  /**
@@ -3,15 +3,15 @@ import {
3
3
  } from "../chunk-BHOD5PKR.js";
4
4
  import {
5
5
  createAgent
6
- } from "../chunk-JTKCV7IS.js";
7
- import "../chunk-DEAR6N3O.js";
8
- import "../chunk-EKHT54KN.js";
9
- import "../chunk-23UUBQXR.js";
6
+ } from "../chunk-RWIYC65R.js";
7
+ import "../chunk-TUFZ2YH6.js";
8
+ import "../chunk-APCBNCOW.js";
9
+ import "../chunk-YSZG6XIM.js";
10
10
  import {
11
11
  createBashTool
12
12
  } from "../chunk-FI7WQFGV.js";
13
- import "../chunk-7ZDX3O6I.js";
14
- import "../chunk-LTVNPHST.js";
13
+ import "../chunk-AAFPAF67.js";
14
+ import "../chunk-22NTRYNO.js";
15
15
 
16
16
  // src/runtime/AgentXRuntime.ts
17
17
  import { createLogger } from "commonxjs/logger";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/AgentXRuntime.ts"],"sourcesContent":["/**\n * AgentXRuntimeImpl - Runtime integration implementation\n *\n * Integrates all components to provide agent lifecycle management.\n * Uses Platform dependencies to coordinate Session, Image, Container, etc.\n *\n * Architecture:\n * - Driver.receive() returns AsyncIterable<DriverStreamEvent>\n * - Runtime emits raw stream events to EventBus\n * - Runtime pushes events through AgentEngine (MealyMachine → Presenter)\n * - Presenter emits message/state/turn events and persists messages\n */\n\nimport { createLogger } from \"commonxjs/logger\";\nimport type {\n AgentXPlatform,\n AgentXRuntime,\n RuntimeAgent,\n CreateAgentOptions,\n AgentEventHandler,\n Subscription,\n AgentLifecycle,\n} from \"./types\";\nimport type {\n UserContentPart,\n UserMessage,\n AgentEngine,\n StreamEvent,\n AgentOutput,\n AgentPresenter,\n AgentSource,\n Message,\n} from \"../agent/types\";\nimport type { BusEvent } from \"../event/types\";\nimport type {\n CreateDriver,\n Driver,\n DriverConfig,\n DriverStreamEvent,\n ToolDefinition,\n} from \"../driver/types\";\nimport { createSession } from \"../session/Session\";\nimport { createBashTool } from \"../bash/tool\";\nimport { createAgent as createAgentEngine } from \"../agent/createAgent\";\n\nconst logger = createLogger(\"runtime/AgentXRuntime\");\n\n/**\n * Internal agent state\n */\ninterface AgentState {\n agent: RuntimeAgent;\n lifecycle: AgentLifecycle;\n subscriptions: Set<() => void>;\n driver: Driver;\n engine: AgentEngine;\n /** Flag to track if a receive operation is in progress */\n isReceiving: boolean;\n}\n\n/**\n * AgentXRuntimeImpl - Runtime implementation\n */\nexport class AgentXRuntimeImpl implements AgentXRuntime {\n readonly platform: AgentXPlatform;\n private readonly createDriver: CreateDriver;\n\n private agents = new Map<string, AgentState>();\n private globalSubscriptions = new Set<() => void>();\n private isShutdown = false;\n\n constructor(platform: AgentXPlatform, createDriver: CreateDriver) {\n this.platform = platform;\n this.createDriver = createDriver;\n logger.info(\"AgentXRuntime initialized\");\n }\n\n // ==================== Agent Lifecycle ====================\n\n async createAgent(options: CreateAgentOptions): Promise<RuntimeAgent> {\n if (this.isShutdown) {\n throw new Error(\"Runtime is shutdown\");\n }\n\n const { imageId } = options;\n\n // Load image\n const imageRecord = await this.platform.imageRepository.findImageById(imageId);\n if (!imageRecord) {\n throw new Error(`Image not found: ${imageId}`);\n }\n\n // Generate agent ID\n const agentId = options.agentId ?? this.generateAgentId();\n\n // Ensure container exists\n const containerExists = await this.platform.containerRepository.containerExists(\n imageRecord.containerId\n );\n if (!containerExists) {\n throw new Error(`Container not found: ${imageRecord.containerId}`);\n }\n\n // Create Session for driver (MonoDriver needs this to read history)\n const session = createSession({\n sessionId: imageRecord.sessionId,\n imageId,\n containerId: imageRecord.containerId,\n repository: this.platform.sessionRepository,\n });\n\n // Assemble platform-provided default tools\n const defaultTools: ToolDefinition[] = [];\n if (this.platform.bashProvider) {\n defaultTools.push(createBashTool(this.platform.bashProvider));\n }\n\n // Create driver config (apiKey/baseUrl are provided by the createDriver closure)\n const driverConfig: DriverConfig = {\n apiKey: \"\",\n agentId,\n systemPrompt: imageRecord.systemPrompt,\n mcpServers: imageRecord.mcpServers,\n tools: defaultTools.length > 0 ? defaultTools : undefined,\n session, // Inject Session for stateless drivers\n resumeSessionId: imageRecord.metadata?.driverSessionId as string | undefined,\n onSessionIdCaptured: async (driverSessionId: string) => {\n // Persist driver session ID for resume\n await this.platform.imageRepository.updateMetadata(imageId, { driverSessionId });\n },\n };\n\n // Create driver using the injected CreateDriver function\n const driver = this.createDriver(driverConfig);\n\n // Initialize driver\n await driver.initialize();\n\n // Create AgentEngine with custom Source and Presenter\n // Source: no-op (Runtime pushes events directly via handleStreamEvent)\n // Presenter: emits message/state/turn events to EventBus + persists messages\n const noopSource: AgentSource = {\n name: \"RuntimeSource\",\n connect: () => {},\n disconnect: () => {},\n };\n\n const sessionId = imageRecord.sessionId;\n const sessionRepository = this.platform.sessionRepository;\n const eventBus = this.platform.eventBus;\n\n const runtimePresenter: AgentPresenter = {\n name: \"RuntimePresenter\",\n present: (_agentId: string, output: AgentOutput) => {\n const category = categorizeAgentOutput(output.type);\n\n // Skip stream events — already emitted by handleDriverEvent\n if (category === \"stream\") return;\n\n // Emit state/message/turn events to EventBus\n eventBus.emit({\n type: output.type,\n timestamp: output.timestamp,\n source: \"agent\",\n category,\n intent: \"notification\",\n data: output.data,\n context: {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n sessionId,\n },\n } as BusEvent);\n\n // Persist message events to SessionRepository\n if (category === \"message\" && output.type !== \"user_message\") {\n const message = output.data as Message;\n sessionRepository.addMessage(sessionId, message).catch((err) => {\n logger.error(\"Failed to persist message\", { type: output.type, error: err });\n });\n }\n },\n };\n\n const engine = createAgentEngine({\n agentId,\n bus: this.platform.eventBus,\n source: noopSource,\n presenter: runtimePresenter,\n });\n\n // Create runtime agent\n const agent: RuntimeAgent = {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n sessionId: imageRecord.sessionId,\n name: imageRecord.name,\n lifecycle: \"running\",\n createdAt: Date.now(),\n };\n\n // Store agent state with driver and engine\n const state: AgentState = {\n agent,\n lifecycle: \"running\",\n subscriptions: new Set(),\n driver,\n engine,\n isReceiving: false,\n };\n this.agents.set(agentId, state);\n\n // Emit agent_created event\n this.platform.eventBus.emit({\n type: \"agent_created\",\n timestamp: Date.now(),\n source: \"runtime\",\n category: \"lifecycle\",\n intent: \"notification\",\n data: {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n },\n context: {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n sessionId: imageRecord.sessionId,\n },\n } as BusEvent);\n\n logger.info(\"Agent created\", {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n });\n\n return agent;\n }\n\n getAgent(agentId: string): RuntimeAgent | undefined {\n const state = this.agents.get(agentId);\n return state?.agent;\n }\n\n getAgents(): RuntimeAgent[] {\n return Array.from(this.agents.values()).map((s) => s.agent);\n }\n\n getAgentsByContainer(containerId: string): RuntimeAgent[] {\n return Array.from(this.agents.values())\n .filter((s) => s.agent.containerId === containerId)\n .map((s) => s.agent);\n }\n\n async stopAgent(agentId: string): Promise<void> {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n if (state.lifecycle === \"destroyed\") {\n throw new Error(`Agent already destroyed: ${agentId}`);\n }\n\n state.lifecycle = \"stopped\";\n\n // Emit agent_stopped event\n this.platform.eventBus.emit({\n type: \"agent_stopped\",\n timestamp: Date.now(),\n source: \"runtime\",\n category: \"lifecycle\",\n intent: \"notification\",\n data: { agentId },\n context: {\n agentId,\n imageId: state.agent.imageId,\n containerId: state.agent.containerId,\n sessionId: state.agent.sessionId,\n },\n } as BusEvent);\n\n logger.info(\"Agent stopped\", { agentId });\n }\n\n async resumeAgent(agentId: string): Promise<void> {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n if (state.lifecycle === \"destroyed\") {\n throw new Error(`Cannot resume destroyed agent: ${agentId}`);\n }\n\n state.lifecycle = \"running\";\n\n // Emit agent_resumed event\n this.platform.eventBus.emit({\n type: \"agent_resumed\",\n timestamp: Date.now(),\n source: \"runtime\",\n category: \"lifecycle\",\n intent: \"notification\",\n data: { agentId },\n context: {\n agentId,\n imageId: state.agent.imageId,\n containerId: state.agent.containerId,\n sessionId: state.agent.sessionId,\n },\n } as BusEvent);\n\n logger.info(\"Agent resumed\", { agentId });\n }\n\n async destroyAgent(agentId: string): Promise<void> {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n // Dispose driver and engine\n await state.driver.dispose();\n await state.engine.destroy();\n\n // Cleanup subscriptions\n for (const unsub of state.subscriptions) {\n unsub();\n }\n state.subscriptions.clear();\n\n state.lifecycle = \"destroyed\";\n\n // Emit agent_destroyed event\n this.platform.eventBus.emit({\n type: \"agent_destroyed\",\n timestamp: Date.now(),\n source: \"runtime\",\n category: \"lifecycle\",\n intent: \"notification\",\n data: { agentId },\n context: {\n agentId,\n imageId: state.agent.imageId,\n containerId: state.agent.containerId,\n sessionId: state.agent.sessionId,\n },\n } as BusEvent);\n\n // Remove from map\n this.agents.delete(agentId);\n\n logger.info(\"Agent destroyed\", { agentId });\n }\n\n // ==================== Message Handling ====================\n\n async receive(\n agentId: string,\n content: string | UserContentPart[],\n requestId?: string\n ): Promise<void> {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n if (state.lifecycle !== \"running\") {\n throw new Error(`Cannot send message to ${state.lifecycle} agent: ${agentId}`);\n }\n\n if (state.isReceiving) {\n throw new Error(`Agent ${agentId} is already processing a message`);\n }\n\n const actualRequestId = requestId ?? this.generateRequestId();\n\n // Build user message\n const userMessage: UserMessage = {\n id: this.generateMessageId(),\n role: \"user\",\n subtype: \"user\",\n content,\n timestamp: Date.now(),\n };\n\n // Persist to session\n await this.platform.sessionRepository.addMessage(state.agent.sessionId, userMessage);\n\n // Emit user_message event (for external subscribers)\n this.emitEvent(state, \"user_message\", userMessage, actualRequestId);\n\n logger.debug(\"User message sent\", {\n agentId,\n requestId: actualRequestId,\n contentPreview:\n typeof content === \"string\"\n ? content.substring(0, 50)\n : Array.isArray(content)\n ? `[${content.length} parts]`\n : `[${typeof content}]`,\n });\n\n // Mark as receiving\n state.isReceiving = true;\n\n try {\n // Call driver.receive() and process the AsyncIterable\n for await (const event of state.driver.receive(userMessage)) {\n // Convert DriverStreamEvent to BusEvent and emit\n this.handleDriverEvent(state, event, actualRequestId);\n }\n } catch (error) {\n // Emit error event\n this.emitEvent(\n state,\n \"error_received\",\n {\n message: error instanceof Error ? error.message : String(error),\n errorCode: \"runtime_error\",\n },\n actualRequestId\n );\n throw error;\n } finally {\n state.isReceiving = false;\n }\n }\n\n interrupt(agentId: string, requestId?: string): void {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n // Call driver.interrupt() directly\n state.driver.interrupt();\n\n // Emit interrupt event (for external subscribers)\n this.emitEvent(state, \"interrupt\", { agentId }, requestId ?? this.generateRequestId());\n\n logger.debug(\"Interrupt sent\", { agentId, requestId });\n }\n\n // ==================== Event Subscription ====================\n\n subscribe(agentId: string, handler: AgentEventHandler): Subscription {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n const unsub = this.platform.eventBus.onAny((event) => {\n const context = (event as BusEvent & { context?: { agentId?: string } }).context;\n if (context?.agentId === agentId) {\n handler(event);\n }\n });\n\n state.subscriptions.add(unsub);\n\n return {\n unsubscribe: () => {\n unsub();\n state.subscriptions.delete(unsub);\n },\n };\n }\n\n subscribeAll(handler: AgentEventHandler): Subscription {\n const unsub = this.platform.eventBus.onAny(handler);\n this.globalSubscriptions.add(unsub);\n\n return {\n unsubscribe: () => {\n unsub();\n this.globalSubscriptions.delete(unsub);\n },\n };\n }\n\n // ==================== Cleanup ====================\n\n async shutdown(): Promise<void> {\n if (this.isShutdown) return;\n\n logger.info(\"Shutting down AgentXRuntime...\");\n\n // Destroy all agents\n const agentIds = Array.from(this.agents.keys());\n for (const agentId of agentIds) {\n await this.destroyAgent(agentId);\n }\n\n // Cleanup global subscriptions\n for (const unsub of this.globalSubscriptions) {\n unsub();\n }\n this.globalSubscriptions.clear();\n\n this.isShutdown = true;\n logger.info(\"AgentXRuntime shutdown complete\");\n }\n\n // ==================== Private Helpers ====================\n\n /**\n * Handle a single DriverStreamEvent\n */\n private handleDriverEvent(state: AgentState, event: DriverStreamEvent, requestId: string): void {\n // 1. Emit raw stream event to EventBus (for Presentation and other subscribers)\n this.emitEvent(state, event.type, event.data, requestId);\n\n // 2. Push to AgentEngine for MealyMachine processing\n // Engine produces message/state/turn events via Presenter\n const streamEvent = toStreamEvent(event);\n state.engine.handleStreamEvent(streamEvent);\n }\n\n /**\n * Emit an event to the EventBus\n */\n private emitEvent(state: AgentState, type: string, data: unknown, requestId: string): void {\n this.platform.eventBus.emit({\n type,\n timestamp: Date.now(),\n source: \"runtime\",\n category: this.categorizeEvent(type),\n intent: \"notification\",\n requestId,\n data,\n context: {\n agentId: state.agent.agentId,\n imageId: state.agent.imageId,\n containerId: state.agent.containerId,\n sessionId: state.agent.sessionId,\n },\n } as BusEvent);\n }\n\n /**\n * Categorize event type\n */\n private categorizeEvent(type: string): string {\n if (type.includes(\"message\")) return \"message\";\n if (type.includes(\"tool\")) return \"tool\";\n if (type.includes(\"error\") || type.includes(\"interrupted\")) return \"error\";\n if (type.includes(\"delta\")) return \"stream\";\n return \"stream\";\n }\n\n private generateAgentId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `agent_${timestamp}_${random}`;\n }\n\n private generateRequestId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `req_${timestamp}_${random}`;\n }\n\n private generateMessageId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `msg_${timestamp}_${random}`;\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Convert DriverStreamEvent to agent-layer StreamEvent.\n * Data structures are identical; only \"error\" type needs renaming.\n */\nfunction toStreamEvent(event: DriverStreamEvent): StreamEvent {\n const type = event.type === \"error\" ? \"error_received\" : event.type;\n return { type, data: event.data, timestamp: Date.now() } as StreamEvent;\n}\n\n/**\n * Categorize AgentOutput type for EventBus emission.\n */\nfunction categorizeAgentOutput(type: string): string {\n // Stream layer — already emitted by handleDriverEvent\n const streamTypes = [\n \"message_start\",\n \"message_delta\",\n \"message_stop\",\n \"text_delta\",\n \"tool_use_start\",\n \"input_json_delta\",\n \"tool_use_stop\",\n \"tool_result\",\n \"error_received\",\n ];\n if (streamTypes.includes(type)) return \"stream\";\n\n // Message layer\n if (type.endsWith(\"_message\")) return \"message\";\n\n // Turn layer\n if (type.startsWith(\"turn_\")) return \"turn\";\n\n // State layer (default)\n return \"state\";\n}\n\n/**\n * Create an AgentXRuntime instance\n *\n * @param platform - AgentXPlatform with repositories and event bus\n * @param createDriver - Factory function for creating Driver instances per Agent\n */\nexport function createAgentXRuntime(\n platform: AgentXPlatform,\n createDriver: CreateDriver\n): AgentXRuntime {\n return new AgentXRuntimeImpl(platform, createDriver);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/runtime/AgentXRuntime.ts"],"sourcesContent":["/**\n * AgentXRuntimeImpl - Runtime integration implementation\n *\n * Integrates all components to provide agent lifecycle management.\n * Uses Platform dependencies to coordinate Session, Image, Container, etc.\n *\n * Architecture:\n * - Driver.receive() returns AsyncIterable<DriverStreamEvent>\n * - Runtime emits raw stream events to EventBus\n * - Runtime pushes events through AgentEngine (MealyMachine → Presenter)\n * - Presenter emits message/state/turn events and persists messages\n */\n\nimport { createLogger } from \"commonxjs/logger\";\nimport { createAgent as createAgentEngine } from \"../agent/createAgent\";\nimport type {\n AgentEngine,\n AgentOutput,\n AgentPresenter,\n AgentSource,\n Message,\n StreamEvent,\n UserContentPart,\n UserMessage,\n} from \"../agent/types\";\nimport { createBashTool } from \"../bash/tool\";\nimport type {\n CreateDriver,\n Driver,\n DriverConfig,\n DriverStreamEvent,\n ToolDefinition,\n} from \"../driver/types\";\nimport type { BusEvent } from \"../event/types\";\nimport { createSession } from \"../session/Session\";\nimport type {\n AgentEventHandler,\n AgentLifecycle,\n AgentXPlatform,\n AgentXRuntime,\n CreateAgentOptions,\n RuntimeAgent,\n Subscription,\n} from \"./types\";\n\nconst logger = createLogger(\"runtime/AgentXRuntime\");\n\n/**\n * Internal agent state\n */\ninterface AgentState {\n agent: RuntimeAgent;\n lifecycle: AgentLifecycle;\n subscriptions: Set<() => void>;\n driver: Driver;\n engine: AgentEngine;\n /** Flag to track if a receive operation is in progress */\n isReceiving: boolean;\n}\n\n/**\n * AgentXRuntimeImpl - Runtime implementation\n */\nexport class AgentXRuntimeImpl implements AgentXRuntime {\n readonly platform: AgentXPlatform;\n private readonly createDriver: CreateDriver;\n\n private agents = new Map<string, AgentState>();\n private globalSubscriptions = new Set<() => void>();\n private isShutdown = false;\n\n constructor(platform: AgentXPlatform, createDriver: CreateDriver) {\n this.platform = platform;\n this.createDriver = createDriver;\n logger.info(\"AgentXRuntime initialized\");\n }\n\n // ==================== Agent Lifecycle ====================\n\n async createAgent(options: CreateAgentOptions): Promise<RuntimeAgent> {\n if (this.isShutdown) {\n throw new Error(\"Runtime is shutdown\");\n }\n\n const { imageId } = options;\n\n // Load image\n const imageRecord = await this.platform.imageRepository.findImageById(imageId);\n if (!imageRecord) {\n throw new Error(`Image not found: ${imageId}`);\n }\n\n // Generate agent ID\n const agentId = options.agentId ?? this.generateAgentId();\n\n // Ensure container exists\n const containerExists = await this.platform.containerRepository.containerExists(\n imageRecord.containerId\n );\n if (!containerExists) {\n throw new Error(`Container not found: ${imageRecord.containerId}`);\n }\n\n // Create Session for driver (MonoDriver needs this to read history)\n const session = createSession({\n sessionId: imageRecord.sessionId,\n imageId,\n containerId: imageRecord.containerId,\n repository: this.platform.sessionRepository,\n });\n\n // Assemble platform-provided default tools\n const defaultTools: ToolDefinition[] = [];\n if (this.platform.bashProvider) {\n defaultTools.push(createBashTool(this.platform.bashProvider));\n }\n\n // Create driver config (apiKey/baseUrl are provided by the createDriver closure)\n const driverConfig: DriverConfig = {\n apiKey: \"\",\n agentId,\n systemPrompt: imageRecord.systemPrompt,\n mcpServers: imageRecord.mcpServers,\n tools: defaultTools.length > 0 ? defaultTools : undefined,\n session, // Inject Session for stateless drivers\n resumeSessionId: imageRecord.metadata?.driverSessionId as string | undefined,\n onSessionIdCaptured: async (driverSessionId: string) => {\n // Persist driver session ID for resume\n await this.platform.imageRepository.updateMetadata(imageId, { driverSessionId });\n },\n };\n\n // Create driver using the injected CreateDriver function\n const driver = this.createDriver(driverConfig);\n\n // Initialize driver\n await driver.initialize();\n\n // Create AgentEngine with custom Source and Presenter\n // Source: no-op (Runtime pushes events directly via handleStreamEvent)\n // Presenter: emits message/state/turn events to EventBus + persists messages\n const noopSource: AgentSource = {\n name: \"RuntimeSource\",\n connect: () => {},\n disconnect: () => {},\n };\n\n const sessionId = imageRecord.sessionId;\n const sessionRepository = this.platform.sessionRepository;\n const eventBus = this.platform.eventBus;\n\n const runtimePresenter: AgentPresenter = {\n name: \"RuntimePresenter\",\n present: (_agentId: string, output: AgentOutput) => {\n const category = categorizeAgentOutput(output.type);\n\n // Skip stream events — already emitted by handleDriverEvent\n if (category === \"stream\") return;\n\n // Emit state/message/turn events to EventBus\n eventBus.emit({\n type: output.type,\n timestamp: output.timestamp,\n source: \"agent\",\n category,\n intent: \"notification\",\n data: output.data,\n context: {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n sessionId,\n },\n } as BusEvent);\n\n // Persist message events to SessionRepository\n if (category === \"message\" && output.type !== \"user_message\") {\n const message = output.data as Message;\n sessionRepository.addMessage(sessionId, message).catch((err) => {\n logger.error(\"Failed to persist message\", { type: output.type, error: err });\n });\n }\n },\n };\n\n const engine = createAgentEngine({\n agentId,\n bus: this.platform.eventBus,\n source: noopSource,\n presenter: runtimePresenter,\n });\n\n // Create runtime agent\n const agent: RuntimeAgent = {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n sessionId: imageRecord.sessionId,\n name: imageRecord.name,\n lifecycle: \"running\",\n createdAt: Date.now(),\n };\n\n // Store agent state with driver and engine\n const state: AgentState = {\n agent,\n lifecycle: \"running\",\n subscriptions: new Set(),\n driver,\n engine,\n isReceiving: false,\n };\n this.agents.set(agentId, state);\n\n // Emit agent_created event\n this.platform.eventBus.emit({\n type: \"agent_created\",\n timestamp: Date.now(),\n source: \"runtime\",\n category: \"lifecycle\",\n intent: \"notification\",\n data: {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n },\n context: {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n sessionId: imageRecord.sessionId,\n },\n } as BusEvent);\n\n logger.info(\"Agent created\", {\n agentId,\n imageId,\n containerId: imageRecord.containerId,\n });\n\n return agent;\n }\n\n getAgent(agentId: string): RuntimeAgent | undefined {\n const state = this.agents.get(agentId);\n return state?.agent;\n }\n\n getAgents(): RuntimeAgent[] {\n return Array.from(this.agents.values()).map((s) => s.agent);\n }\n\n getAgentsByContainer(containerId: string): RuntimeAgent[] {\n return Array.from(this.agents.values())\n .filter((s) => s.agent.containerId === containerId)\n .map((s) => s.agent);\n }\n\n async stopAgent(agentId: string): Promise<void> {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n if (state.lifecycle === \"destroyed\") {\n throw new Error(`Agent already destroyed: ${agentId}`);\n }\n\n state.lifecycle = \"stopped\";\n\n // Emit agent_stopped event\n this.platform.eventBus.emit({\n type: \"agent_stopped\",\n timestamp: Date.now(),\n source: \"runtime\",\n category: \"lifecycle\",\n intent: \"notification\",\n data: { agentId },\n context: {\n agentId,\n imageId: state.agent.imageId,\n containerId: state.agent.containerId,\n sessionId: state.agent.sessionId,\n },\n } as BusEvent);\n\n logger.info(\"Agent stopped\", { agentId });\n }\n\n async resumeAgent(agentId: string): Promise<void> {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n if (state.lifecycle === \"destroyed\") {\n throw new Error(`Cannot resume destroyed agent: ${agentId}`);\n }\n\n state.lifecycle = \"running\";\n\n // Emit agent_resumed event\n this.platform.eventBus.emit({\n type: \"agent_resumed\",\n timestamp: Date.now(),\n source: \"runtime\",\n category: \"lifecycle\",\n intent: \"notification\",\n data: { agentId },\n context: {\n agentId,\n imageId: state.agent.imageId,\n containerId: state.agent.containerId,\n sessionId: state.agent.sessionId,\n },\n } as BusEvent);\n\n logger.info(\"Agent resumed\", { agentId });\n }\n\n async destroyAgent(agentId: string): Promise<void> {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n // Dispose driver and engine\n await state.driver.dispose();\n await state.engine.destroy();\n\n // Cleanup subscriptions\n for (const unsub of state.subscriptions) {\n unsub();\n }\n state.subscriptions.clear();\n\n state.lifecycle = \"destroyed\";\n\n // Emit agent_destroyed event\n this.platform.eventBus.emit({\n type: \"agent_destroyed\",\n timestamp: Date.now(),\n source: \"runtime\",\n category: \"lifecycle\",\n intent: \"notification\",\n data: { agentId },\n context: {\n agentId,\n imageId: state.agent.imageId,\n containerId: state.agent.containerId,\n sessionId: state.agent.sessionId,\n },\n } as BusEvent);\n\n // Remove from map\n this.agents.delete(agentId);\n\n logger.info(\"Agent destroyed\", { agentId });\n }\n\n // ==================== Message Handling ====================\n\n async receive(\n agentId: string,\n content: string | UserContentPart[],\n requestId?: string\n ): Promise<void> {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n if (state.lifecycle !== \"running\") {\n throw new Error(`Cannot send message to ${state.lifecycle} agent: ${agentId}`);\n }\n\n if (state.isReceiving) {\n throw new Error(`Agent ${agentId} is already processing a message`);\n }\n\n const actualRequestId = requestId ?? this.generateRequestId();\n\n // Build user message\n const userMessage: UserMessage = {\n id: this.generateMessageId(),\n role: \"user\",\n subtype: \"user\",\n content,\n timestamp: Date.now(),\n };\n\n // Persist to session\n await this.platform.sessionRepository.addMessage(state.agent.sessionId, userMessage);\n\n // Emit user_message event (for external subscribers)\n this.emitEvent(state, \"user_message\", userMessage, actualRequestId);\n\n logger.debug(\"User message sent\", {\n agentId,\n requestId: actualRequestId,\n contentPreview:\n typeof content === \"string\"\n ? content.substring(0, 50)\n : Array.isArray(content)\n ? `[${content.length} parts]`\n : `[${typeof content}]`,\n });\n\n // Mark as receiving\n state.isReceiving = true;\n\n try {\n // Call driver.receive() and process the AsyncIterable\n for await (const event of state.driver.receive(userMessage)) {\n // Convert DriverStreamEvent to BusEvent and emit\n this.handleDriverEvent(state, event, actualRequestId);\n }\n } catch (error) {\n // Emit error event\n this.emitEvent(\n state,\n \"error_received\",\n {\n message: error instanceof Error ? error.message : String(error),\n errorCode: \"runtime_error\",\n },\n actualRequestId\n );\n throw error;\n } finally {\n state.isReceiving = false;\n }\n }\n\n interrupt(agentId: string, requestId?: string): void {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n // Call driver.interrupt() directly\n state.driver.interrupt();\n\n // Emit interrupt event (for external subscribers)\n this.emitEvent(state, \"interrupt\", { agentId }, requestId ?? this.generateRequestId());\n\n logger.debug(\"Interrupt sent\", { agentId, requestId });\n }\n\n // ==================== Event Subscription ====================\n\n subscribe(agentId: string, handler: AgentEventHandler): Subscription {\n const state = this.agents.get(agentId);\n if (!state) {\n throw new Error(`Agent not found: ${agentId}`);\n }\n\n const unsub = this.platform.eventBus.onAny((event) => {\n const context = (event as BusEvent & { context?: { agentId?: string } }).context;\n if (context?.agentId === agentId) {\n handler(event);\n }\n });\n\n state.subscriptions.add(unsub);\n\n return {\n unsubscribe: () => {\n unsub();\n state.subscriptions.delete(unsub);\n },\n };\n }\n\n subscribeAll(handler: AgentEventHandler): Subscription {\n const unsub = this.platform.eventBus.onAny(handler);\n this.globalSubscriptions.add(unsub);\n\n return {\n unsubscribe: () => {\n unsub();\n this.globalSubscriptions.delete(unsub);\n },\n };\n }\n\n // ==================== Cleanup ====================\n\n async shutdown(): Promise<void> {\n if (this.isShutdown) return;\n\n logger.info(\"Shutting down AgentXRuntime...\");\n\n // Destroy all agents\n const agentIds = Array.from(this.agents.keys());\n for (const agentId of agentIds) {\n await this.destroyAgent(agentId);\n }\n\n // Cleanup global subscriptions\n for (const unsub of this.globalSubscriptions) {\n unsub();\n }\n this.globalSubscriptions.clear();\n\n this.isShutdown = true;\n logger.info(\"AgentXRuntime shutdown complete\");\n }\n\n // ==================== Private Helpers ====================\n\n /**\n * Handle a single DriverStreamEvent\n */\n private handleDriverEvent(state: AgentState, event: DriverStreamEvent, requestId: string): void {\n // 1. Emit raw stream event to EventBus (for Presentation and other subscribers)\n this.emitEvent(state, event.type, event.data, requestId);\n\n // 2. Push to AgentEngine for MealyMachine processing\n // Engine produces message/state/turn events via Presenter\n const streamEvent = toStreamEvent(event);\n state.engine.handleStreamEvent(streamEvent);\n }\n\n /**\n * Emit an event to the EventBus\n */\n private emitEvent(state: AgentState, type: string, data: unknown, requestId: string): void {\n this.platform.eventBus.emit({\n type,\n timestamp: Date.now(),\n source: \"runtime\",\n category: this.categorizeEvent(type),\n intent: \"notification\",\n requestId,\n data,\n context: {\n agentId: state.agent.agentId,\n imageId: state.agent.imageId,\n containerId: state.agent.containerId,\n sessionId: state.agent.sessionId,\n },\n } as BusEvent);\n }\n\n /**\n * Categorize event type\n */\n private categorizeEvent(type: string): string {\n if (type.includes(\"message\")) return \"message\";\n if (type.includes(\"tool\")) return \"tool\";\n if (type.includes(\"error\") || type.includes(\"interrupted\")) return \"error\";\n if (type.includes(\"delta\")) return \"stream\";\n return \"stream\";\n }\n\n private generateAgentId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `agent_${timestamp}_${random}`;\n }\n\n private generateRequestId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `req_${timestamp}_${random}`;\n }\n\n private generateMessageId(): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `msg_${timestamp}_${random}`;\n }\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Convert DriverStreamEvent to agent-layer StreamEvent.\n * Data structures are identical; only \"error\" type needs renaming.\n */\nfunction toStreamEvent(event: DriverStreamEvent): StreamEvent {\n const type = event.type === \"error\" ? \"error_received\" : event.type;\n return { type, data: event.data, timestamp: Date.now() } as StreamEvent;\n}\n\n/**\n * Categorize AgentOutput type for EventBus emission.\n */\nfunction categorizeAgentOutput(type: string): string {\n // Stream layer — already emitted by handleDriverEvent\n const streamTypes = [\n \"message_start\",\n \"message_delta\",\n \"message_stop\",\n \"text_delta\",\n \"tool_use_start\",\n \"input_json_delta\",\n \"tool_use_stop\",\n \"tool_result\",\n \"error_received\",\n ];\n if (streamTypes.includes(type)) return \"stream\";\n\n // Message layer\n if (type.endsWith(\"_message\")) return \"message\";\n\n // Turn layer\n if (type.startsWith(\"turn_\")) return \"turn\";\n\n // State layer (default)\n return \"state\";\n}\n\n/**\n * Create an AgentXRuntime instance\n *\n * @param platform - AgentXPlatform with repositories and event bus\n * @param createDriver - Factory function for creating Driver instances per Agent\n */\nexport function createAgentXRuntime(\n platform: AgentXPlatform,\n createDriver: CreateDriver\n): AgentXRuntime {\n return new AgentXRuntimeImpl(platform, createDriver);\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,6 @@
1
- import { S as Session, a as SessionConfig } from '../index-CuS1i5V-.js';
2
- export { b as SessionRecord, c as SessionRepository } from '../index-CuS1i5V-.js';
3
- import { M as Message } from '../message-03TJzvIX.js';
1
+ import { M as Message } from '../message-Dn-I2vr0.js';
2
+ import { S as SessionConfig, a as Session } from '../index--gxNpY5W.js';
3
+ export { b as SessionRecord, c as SessionRepository } from '../index--gxNpY5W.js';
4
4
 
5
5
  /**
6
6
  * Session - Manages conversation messages
@@ -1,5 +1,5 @@
1
- import { JsonRpc, IParsedObject } from 'jsonrpc-lite';
2
1
  import { S as SystemEvent } from './base-m40r3Qgu.js';
2
+ import { JsonRpc, IParsedObject } from 'jsonrpc-lite';
3
3
 
4
4
  /**
5
5
  * JSON-RPC 2.0 Protocol for AgentX Network Communication
@@ -185,12 +185,12 @@ declare const rpcMethodToResponseType: Record<RpcMethod, string>;
185
185
  */
186
186
 
187
187
  /**
188
- * Factory function for creating WebSocket instances.
189
- * Platform layer provides the implementation:
190
- * - Browser: native WebSocket (default)
188
+ * Factory for creating client-side WebSocket connections.
189
+ * Injected via Platform:
190
+ * - Browser: native WebSocket (default fallback)
191
191
  * - Node.js: ws library (via @agentxjs/node-platform)
192
192
  */
193
- type WebSocketFactory = (url: string) => WebSocket;
193
+ type ChannelClientFactory = (url: string) => WebSocket;
194
194
  /**
195
195
  * RpcClient configuration
196
196
  */
@@ -203,7 +203,7 @@ interface RpcClientConfig {
203
203
  * Factory for creating WebSocket instances.
204
204
  * If not provided, falls back to the global WebSocket constructor.
205
205
  */
206
- createWebSocket?: WebSocketFactory;
206
+ createWebSocket?: ChannelClientFactory;
207
207
  /**
208
208
  * Request timeout in milliseconds (default: 30000)
209
209
  */
@@ -301,4 +301,222 @@ declare class RpcClient {
301
301
  private handleParsedMessage;
302
302
  }
303
303
 
304
- export { type ControlAckParams as C, type NotificationMethod as N, type RpcMethod as R, type StreamEventParams as S, type WebSocketFactory as W, type RpcRequest as a, type RpcSuccessResponse as b, type RpcErrorResponse as c, type RpcNotification as d, RpcErrorCodes as e, createRequest as f, createNotification as g, createStreamEvent as h, createAckNotification as i, createSuccessResponse as j, createErrorResponse as k, parseMessageObject as l, isRequest as m, isNotification as n, isSuccessResponse as o, parseMessage as p, isErrorResponse as q, isInvalid as r, isStreamEvent as s, isControlAck as t, eventTypeToRpcMethod as u, rpcMethodToResponseType as v, type RpcClientConfig as w, type RpcClientState as x, RpcClient as y };
304
+ /**
305
+ * Network Types - Channel interfaces for client-server communication
306
+ *
307
+ * Provides transport-agnostic interfaces that can be implemented with:
308
+ * - WebSocket (Node.js, Browser)
309
+ * - Durable Objects WebSocket (Cloudflare Workers)
310
+ * - HTTP/2, gRPC, etc.
311
+ */
312
+ /**
313
+ * Unsubscribe function type
314
+ */
315
+ type Unsubscribe = () => void;
316
+ /**
317
+ * Minimal HTTP server interface for attaching WebSocket
318
+ * Avoids Node.js dependency in types package
319
+ */
320
+ interface MinimalHTTPServer {
321
+ on(event: "upgrade", listener: (request: unknown, socket: unknown, head: unknown) => void): void;
322
+ }
323
+ /**
324
+ * Options for reliable message sending
325
+ */
326
+ interface SendReliableOptions {
327
+ /**
328
+ * Callback when client acknowledges receipt
329
+ */
330
+ onAck?: () => void;
331
+ /**
332
+ * Timeout in milliseconds (default: 5000)
333
+ */
334
+ timeout?: number;
335
+ /**
336
+ * Callback when ACK times out
337
+ */
338
+ onTimeout?: () => void;
339
+ }
340
+ /**
341
+ * ChannelConnection - Server-side representation of a client connection
342
+ */
343
+ interface ChannelConnection {
344
+ /**
345
+ * Unique connection ID
346
+ */
347
+ readonly id: string;
348
+ /**
349
+ * Send message to this client (fire-and-forget)
350
+ */
351
+ send(message: string): void;
352
+ /**
353
+ * Send message with acknowledgment
354
+ *
355
+ * The message is wrapped with a unique ID. Client automatically sends ACK
356
+ * when received. Server triggers onAck callback upon receiving ACK.
357
+ *
358
+ * This is handled transparently by the Network layer.
359
+ */
360
+ sendReliable(message: string, options?: SendReliableOptions): void;
361
+ /**
362
+ * Register message handler
363
+ */
364
+ onMessage(handler: (message: string) => void): Unsubscribe;
365
+ /**
366
+ * Register close handler
367
+ */
368
+ onClose(handler: () => void): Unsubscribe;
369
+ /**
370
+ * Register error handler
371
+ */
372
+ onError(handler: (error: Error) => void): Unsubscribe;
373
+ /**
374
+ * Close this connection
375
+ */
376
+ close(): void;
377
+ }
378
+ /**
379
+ * ChannelServer - Accepts client connections
380
+ */
381
+ interface ChannelServer {
382
+ /**
383
+ * Start listening on a port (standalone mode)
384
+ */
385
+ listen(port: number, host?: string): Promise<void>;
386
+ /**
387
+ * Attach to an existing HTTP server
388
+ */
389
+ attach(server: MinimalHTTPServer, path?: string): void;
390
+ /**
391
+ * Register connection handler
392
+ */
393
+ onConnection(handler: (connection: ChannelConnection) => void): Unsubscribe;
394
+ /**
395
+ * Broadcast message to all connected clients
396
+ */
397
+ broadcast(message: string): void;
398
+ /**
399
+ * Close server and all connections
400
+ */
401
+ close(): Promise<void>;
402
+ /**
403
+ * Dispose resources
404
+ */
405
+ dispose(): Promise<void>;
406
+ }
407
+ /**
408
+ * ChannelServerOptions - Server configuration
409
+ */
410
+ interface ChannelServerOptions {
411
+ /**
412
+ * Enable heartbeat/ping-pong (default: true)
413
+ */
414
+ heartbeat?: boolean;
415
+ /**
416
+ * Heartbeat interval in ms (default: 30000)
417
+ */
418
+ heartbeatInterval?: number;
419
+ /**
420
+ * Enable debug logging (default: false)
421
+ */
422
+ debug?: boolean;
423
+ }
424
+ /**
425
+ * Connection state
426
+ */
427
+ type ConnectionState = "connecting" | "open" | "closing" | "closed";
428
+ /**
429
+ * ChannelClient - Connects to server
430
+ */
431
+ interface ChannelClient {
432
+ /**
433
+ * Connection state
434
+ */
435
+ readonly readyState: ConnectionState;
436
+ /**
437
+ * Connect to server
438
+ */
439
+ connect(): Promise<void>;
440
+ /**
441
+ * Send message to server
442
+ */
443
+ send(message: string): void;
444
+ /**
445
+ * Register message handler
446
+ */
447
+ onMessage(handler: (message: string) => void): Unsubscribe;
448
+ /**
449
+ * Register open handler
450
+ */
451
+ onOpen(handler: () => void): Unsubscribe;
452
+ /**
453
+ * Register close handler
454
+ */
455
+ onClose(handler: () => void): Unsubscribe;
456
+ /**
457
+ * Register error handler
458
+ */
459
+ onError(handler: (error: Error) => void): Unsubscribe;
460
+ /**
461
+ * Close connection
462
+ */
463
+ close(): void;
464
+ /**
465
+ * Dispose resources
466
+ */
467
+ dispose(): void;
468
+ }
469
+ /**
470
+ * ChannelClientOptions - Client configuration
471
+ */
472
+ interface ChannelClientOptions {
473
+ /**
474
+ * Server URL
475
+ */
476
+ serverUrl: string;
477
+ /**
478
+ * Enable auto-reconnect (default: true in browser, false in Node.js)
479
+ */
480
+ autoReconnect?: boolean;
481
+ /**
482
+ * Min reconnection delay in ms (default: 1000)
483
+ */
484
+ minReconnectionDelay?: number;
485
+ /**
486
+ * Max reconnection delay in ms (default: 10000)
487
+ */
488
+ maxReconnectionDelay?: number;
489
+ /**
490
+ * Max retry attempts (default: Infinity)
491
+ */
492
+ maxRetries?: number;
493
+ /**
494
+ * Connection timeout in ms (default: 4000)
495
+ */
496
+ connectionTimeout?: number;
497
+ /**
498
+ * Enable debug logging (default: false)
499
+ */
500
+ debug?: boolean;
501
+ /**
502
+ * Custom headers for WebSocket connection
503
+ *
504
+ * - Node.js: Headers are sent during WebSocket handshake
505
+ * - Browser: Headers are sent in first authentication message
506
+ */
507
+ headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);
508
+ }
509
+ /**
510
+ * ChannelServerProvider - Factory for creating ChannelServer instances
511
+ */
512
+ interface ChannelServerProvider {
513
+ createServer(options?: ChannelServerOptions): ChannelServer;
514
+ }
515
+ /**
516
+ * ChannelClientProvider - Factory for creating ChannelClient instances
517
+ */
518
+ interface ChannelClientProvider {
519
+ createClient(options: ChannelClientOptions): ChannelClient;
520
+ }
521
+
522
+ export { type ChannelClient as A, type ChannelClientOptions as B, type ControlAckParams as C, type ChannelClientProvider as D, type ChannelConnection as E, type ChannelServer as F, type ChannelServerOptions as G, type ChannelServerProvider as H, type ConnectionState as I, type SendReliableOptions as J, type MinimalHTTPServer as M, type NotificationMethod as N, type RpcErrorResponse as R, type StreamEventParams as S, type Unsubscribe as U, type RpcMethod as a, type RpcNotification as b, type RpcRequest as c, type RpcSuccessResponse as d, createAckNotification as e, createErrorResponse as f, createNotification as g, createRequest as h, createStreamEvent as i, createSuccessResponse as j, eventTypeToRpcMethod as k, isControlAck as l, isErrorResponse as m, isInvalid as n, isNotification as o, isRequest as p, isStreamEvent as q, isSuccessResponse as r, parseMessage as s, parseMessageObject as t, RpcErrorCodes as u, rpcMethodToResponseType as v, type ChannelClientFactory as w, type RpcClientConfig as x, type RpcClientState as y, RpcClient as z };
@@ -87,4 +87,4 @@ interface BashProvider {
87
87
  execute(command: string, options?: BashOptions): Promise<BashResult>;
88
88
  }
89
89
 
90
- export type { BashProvider as B, BashResult as a, BashOptions as b };
90
+ export type { BashProvider as B, BashOptions as a, BashResult as b };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentxjs/core",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -13,15 +13,15 @@
13
13
  * - Notify state change subscribers
14
14
  */
15
15
 
16
+ import { createLogger } from "commonxjs/logger";
16
17
  import type {
18
+ AgentOutput,
17
19
  AgentState,
18
20
  StateChange,
19
21
  StateChangeHandler,
20
- AgentOutput,
21
22
  Unsubscribe,
22
23
  } from "./types";
23
24
  import { isStateEvent } from "./types";
24
- import { createLogger } from "commonxjs/logger";
25
25
 
26
26
  const logger = createLogger("agent/AgentStateMachine");
27
27
 
@@ -5,9 +5,9 @@
5
5
  * driven by StateEvents from the MealyMachine.
6
6
  */
7
7
 
8
- import { describe, it, expect, beforeEach } from "bun:test";
8
+ import { beforeEach, describe, expect, it } from "bun:test";
9
9
  import { AgentStateMachine } from "../AgentStateMachine";
10
- import type { AgentState, StateChange, AgentOutput } from "../types";
10
+ import type { AgentOutput, AgentState, StateChange } from "../types";
11
11
 
12
12
  // Helper to create test events
13
13
  function createStateEvent(type: string, data: unknown = {}): AgentOutput {
@@ -5,14 +5,14 @@
5
5
  * Uses MockEventBus to simulate Driver behavior.
6
6
  */
7
7
 
8
- import { describe, it, expect, beforeEach } from "bun:test";
8
+ import { beforeEach, describe, expect, it } from "bun:test";
9
9
  import { createAgent } from "../createAgent";
10
10
  import type {
11
11
  AgentEventBus,
12
- UserMessage,
13
- StreamEvent,
14
12
  AgentOutput,
15
13
  CreateAgentOptions,
14
+ StreamEvent,
15
+ UserMessage,
16
16
  } from "../types";
17
17
 
18
18
  /**
@@ -484,7 +484,7 @@ describe("createAgent", () => {
484
484
  agent.use(async (message, next) => {
485
485
  const modified: UserMessage = {
486
486
  ...message,
487
- content: message.content + " MODIFIED",
487
+ content: `${message.content} MODIFIED`,
488
488
  };
489
489
  await next(modified);
490
490
  });
@@ -5,13 +5,13 @@
5
5
  * from Stream Layer events.
6
6
  */
7
7
 
8
- import { describe, it, expect, beforeEach } from "bun:test";
8
+ import { beforeEach, describe, expect, it } from "bun:test";
9
9
  import {
10
- messageAssemblerProcessor,
11
10
  createInitialMessageAssemblerState,
12
- type MessageAssemblerState,
13
11
  type MessageAssemblerInput,
14
12
  type MessageAssemblerOutput,
13
+ type MessageAssemblerState,
14
+ messageAssemblerProcessor,
15
15
  } from "../../../engine/internal/messageAssemblerProcessor";
16
16
 
17
17
  // Helper to create test events
@@ -251,7 +251,7 @@ describe("messageAssemblerProcessor", () => {
251
251
  expect(newState.pendingContents[0].parsedInput).toEqual({ x: 10, y: 20 });
252
252
 
253
253
  // Should add to pending tool calls
254
- expect(newState.pendingToolCalls["tool_123"]).toEqual({
254
+ expect(newState.pendingToolCalls.tool_123).toEqual({
255
255
  id: "tool_123",
256
256
  name: "calculate",
257
257
  });
@@ -289,7 +289,7 @@ describe("messageAssemblerProcessor", () => {
289
289
  describe("tool_result event", () => {
290
290
  it("should emit tool_result_message event", () => {
291
291
  // Setup: pending tool call
292
- state.pendingToolCalls["tool_123"] = {
292
+ state.pendingToolCalls.tool_123 = {
293
293
  id: "tool_123",
294
294
  name: "calculate",
295
295
  };
@@ -315,11 +315,11 @@ describe("messageAssemblerProcessor", () => {
315
315
  expect(toolResultMessage.toolResult.output.value).toBe("42");
316
316
 
317
317
  // Should remove from pending tool calls
318
- expect(newState.pendingToolCalls["tool_123"]).toBeUndefined();
318
+ expect(newState.pendingToolCalls.tool_123).toBeUndefined();
319
319
  });
320
320
 
321
321
  it("should handle error results", () => {
322
- state.pendingToolCalls["tool_123"] = {
322
+ state.pendingToolCalls.tool_123 = {
323
323
  id: "tool_123",
324
324
  name: "test",
325
325
  };
@@ -410,7 +410,7 @@ describe("messageAssemblerProcessor", () => {
410
410
 
411
411
  it("should preserve pending tool calls when stopReason is tool_use", () => {
412
412
  state.currentMessageId = "msg_123";
413
- state.pendingToolCalls["tool_123"] = { id: "tool_123", name: "test" };
413
+ state.pendingToolCalls.tool_123 = { id: "tool_123", name: "test" };
414
414
  state.pendingContents = [
415
415
  {
416
416
  type: "tool_use",
@@ -434,12 +434,12 @@ describe("messageAssemblerProcessor", () => {
434
434
  expect(content[0].type).toBe("tool-call");
435
435
  expect(content[0].id).toBe("tool_123");
436
436
 
437
- expect(newState.pendingToolCalls["tool_123"]).toBeDefined();
437
+ expect(newState.pendingToolCalls.tool_123).toBeDefined();
438
438
  });
439
439
 
440
440
  it("should clear pending tool calls for non-tool_use stop reason", () => {
441
441
  state.currentMessageId = "msg_123";
442
- state.pendingToolCalls["tool_123"] = { id: "tool_123", name: "test" };
442
+ state.pendingToolCalls.tool_123 = { id: "tool_123", name: "test" };
443
443
  state.pendingContents = [
444
444
  {
445
445
  type: "text",