agentxjs 2.9.0-dev-20260317060607 → 2.9.0-dev-20260317112104
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.
- package/dist/{chunk-SFWLYRLB.js → chunk-TKYJYJS5.js} +21 -21
- package/dist/{chunk-SFWLYRLB.js.map → chunk-TKYJYJS5.js.map} +1 -1
- package/dist/index.d.ts +15 -15
- package/dist/index.js +28 -28
- package/dist/index.js.map +1 -1
- package/dist/{server-CFC6ONC6.js → server-N3SRHICW.js} +2 -2
- package/package.json +3 -3
- package/src/LocalClient.ts +10 -10
- package/src/handlers/__tests__/workspace-handler.test.ts +34 -34
- package/src/handlers/index.ts +2 -2
- package/src/handlers/workspace.ts +20 -20
- package/src/index.ts +3 -3
- package/src/namespaces/presentations.ts +7 -7
- package/src/presentation/Presentation.ts +16 -16
- package/src/presentation/__tests__/workspace-init.test.ts +20 -20
- package/src/presentation/__tests__/workspace.test.ts +17 -17
- package/src/presentation/index.ts +3 -3
- package/src/presentation/reducer.ts +1 -1
- package/src/presentation/types.ts +10 -10
- /package/dist/{server-CFC6ONC6.js.map → server-N3SRHICW.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/LocalClient.ts","../src/AgentHandle.ts","../src/namespaces/images.ts","../src/namespaces/llm.ts","../src/presentation/types.ts","../src/presentation/reducer.ts","../src/presentation/Presentation.ts","../src/namespaces/presentations.ts","../src/namespaces/sessions.ts","../src/RemoteClient.ts"],"sourcesContent":["/**\n * agentxjs - AgentX Client SDK\n *\n * Fluent API supporting local, remote, and server modes.\n *\n * @example Local mode\n * ```typescript\n * import { createAgentX } from \"agentxjs\";\n * import { nodePlatform } from \"@agentxjs/node-platform\";\n *\n * const ax = createAgentX(nodePlatform({ createDriver }));\n * const agent = await ax.chat.create({ name: \"Aristotle\", model: \"claude-sonnet-4-6\" });\n * await agent.send(\"Hello!\");\n * ```\n *\n * @example Remote mode\n * ```typescript\n * const ax = createAgentX();\n * const client = await ax.connect(\"ws://localhost:5200\");\n * ```\n *\n * @example Server mode\n * ```typescript\n * const ax = createAgentX(nodePlatform({ createDriver }));\n * const server = await ax.serve({ port: 5200 });\n * ```\n */\n\nimport type { CreateDriver } from \"@agentxjs/core/driver\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport { createAgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { LocalClient } from \"./LocalClient\";\nimport { RemoteClient } from \"./RemoteClient\";\nimport type { AgentX, AgentXBuilder, AgentXServer, ConnectOptions, ServeConfig } from \"./types\";\n\nconst poolLogger = createLogger(\"agentx/connection-pool\");\n\n// ============================================================================\n// Connection Pool — module-level singleton for WebSocket connection reuse\n//\n// Solves React 18+ Strict Mode double-mount:\n// mount → connect (refCount=1) → unmount → dispose (refCount=0, deferred)\n// → re-mount → connect (reuse, refCount=1)\n// ============================================================================\n\ninterface PoolEntry {\n client: RemoteClient;\n refCount: number;\n}\n\nconst connectionPool = new Map<string, PoolEntry>();\n\nfunction pooledConnect(serverUrl: string, factory: () => Promise<RemoteClient>): Promise<AgentX> {\n const existing = connectionPool.get(serverUrl);\n if (existing && existing.client.connected) {\n existing.refCount++;\n poolLogger.debug(\"Connection reused\", { serverUrl, refCount: existing.refCount });\n return Promise.resolve(wrapWithRefCount(serverUrl, existing));\n }\n\n return factory().then((client) => {\n const entry: PoolEntry = { client, refCount: 1 };\n connectionPool.set(serverUrl, entry);\n poolLogger.debug(\"Connection created\", { serverUrl });\n return wrapWithRefCount(serverUrl, entry);\n });\n}\n\nfunction wrapWithRefCount(serverUrl: string, entry: PoolEntry): AgentX {\n const client = entry.client;\n const originalDispose = client.dispose.bind(client);\n const originalDisconnect = client.disconnect.bind(client);\n\n // Override dispose — only truly dispose when refCount reaches 0\n client.dispose = async () => {\n entry.refCount--;\n poolLogger.debug(\"Connection released\", { serverUrl, refCount: entry.refCount });\n if (entry.refCount <= 0) {\n connectionPool.delete(serverUrl);\n await originalDispose();\n }\n };\n\n // disconnect follows same refCount logic\n client.disconnect = async () => {\n entry.refCount--;\n if (entry.refCount <= 0) {\n connectionPool.delete(serverUrl);\n await originalDisconnect();\n }\n };\n\n return client;\n}\n\n/**\n * Platform configuration for createAgentX\n */\nexport interface PlatformConfig {\n platform: AgentXPlatform;\n createDriver: CreateDriver;\n}\n\n/**\n * Create an AgentX builder\n *\n * @param config - Platform configuration (optional). Without it, only connect() is available.\n * @returns AgentXBuilder — local AgentX + connect() + serve()\n */\nexport function createAgentX(config?: PlatformConfig): AgentXBuilder {\n let localClient: LocalClient | null = null;\n\n function getLocalClient(): LocalClient {\n if (localClient) return localClient;\n if (!config) {\n throw new Error(\n \"Local mode requires a platform. Pass a PlatformConfig to createAgentX(), or use connect() for remote mode.\"\n );\n }\n const runtime = createAgentXRuntime(config.platform, config.createDriver);\n localClient = new LocalClient(runtime);\n return localClient;\n }\n\n if (config) {\n getLocalClient();\n }\n\n return {\n get connected() {\n return localClient?.connected ?? false;\n },\n\n get events() {\n return getLocalClient().events;\n },\n\n get runtime() {\n return getLocalClient().runtime;\n },\n\n get provider() {\n return getLocalClient().provider;\n },\n\n get chat() {\n return getLocalClient().chat;\n },\n\n on(type, handler) {\n return getLocalClient().on(type, handler);\n },\n\n onAny(handler) {\n return getLocalClient().onAny(handler);\n },\n\n onError(handler) {\n return getLocalClient().onError(handler);\n },\n\n async disconnect() {\n await localClient?.disconnect();\n },\n\n async dispose() {\n await localClient?.dispose();\n localClient = null;\n },\n\n async connect(serverUrl: string, options?: ConnectOptions): Promise<AgentX> {\n return pooledConnect(serverUrl, async () => {\n const remoteClient = new RemoteClient({\n serverUrl,\n headers: options?.headers as Record<string, string> | undefined,\n context: options?.context,\n timeout: options?.timeout,\n autoReconnect: options?.autoReconnect,\n customPlatform: config?.platform,\n });\n await remoteClient.connect();\n return remoteClient;\n });\n },\n\n async serve(serveConfig?: ServeConfig): Promise<AgentXServer> {\n if (!config) {\n throw new Error(\"serve() requires a platform. Pass a PlatformConfig to createAgentX().\");\n }\n if (!config.platform.channelServer) {\n throw new Error(\n \"serve() requires platform.channelServer. Ensure your platform supports server mode.\"\n );\n }\n\n const { createServer } = await import(\"./server\");\n return createServer({\n platform: config.platform,\n createDriver: config.createDriver,\n port: serveConfig?.port,\n host: serveConfig?.host,\n server: serveConfig?.server as any,\n wsPath: serveConfig?.wsPath,\n });\n },\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n return getLocalClient().rpc<T>(method, params);\n },\n };\n}\n\n// Re-export context interfaces\nexport type { Capability, Context, ContextProvider } from \"@agentxjs/core/context\";\n// Re-export driver types\nexport type { SendOptions } from \"@agentxjs/core/driver\";\n// Re-export error types\nexport type { AgentXErrorCategory, AgentXErrorContext } from \"@agentxjs/core/error\";\nexport { AgentXError, AgentXErrorCode } from \"@agentxjs/core/error\";\n// Re-export Presentation\nexport type {\n AssistantConversation,\n Block,\n Conversation,\n ErrorConversation,\n FileBlock,\n FileTreeEntry,\n ImageBlock,\n PresentationMetrics,\n PresentationOptions,\n PresentationState,\n PresentationWorkspace,\n TextBlock,\n ThinkingBlock,\n ToolBlock,\n UserConversation,\n Workspace,\n WorkspaceState,\n} from \"./presentation\";\nexport {\n addUserConversation,\n createInitialState,\n initialMetrics,\n initialPresentationState,\n messagesToConversations,\n Presentation,\n presentationReducer,\n} from \"./presentation\";\n// Re-export types\nexport type {\n AgentConfig,\n AgentHandle,\n AgentX,\n AgentXBuilder,\n AgentXServer,\n BaseResponse,\n ChatNamespace,\n ConnectOptions,\n ImageCreateResponse,\n ImageGetResponse,\n ImageListResponse,\n ImageNamespace,\n ImageRecord,\n ImageUpdateResponse,\n InstanceCreateResponse,\n InstanceGetResponse,\n InstanceInfo,\n InstanceListResponse,\n LLMNamespace,\n LLMProviderCreateResponse,\n LLMProviderDefaultResponse,\n LLMProviderGetResponse,\n LLMProviderListResponse,\n LLMProviderUpdateResponse,\n MaybeAsync,\n MessageSendResponse,\n PresentationNamespace,\n RuntimeNamespace,\n ServeConfig,\n SessionNamespace,\n} from \"./types\";\n","/**\n * LocalClient - AgentX client for local mode\n *\n * Runs an embedded Runtime + Driver directly, without WebSocket.\n * Implements the same AgentX interface as RemoteClient.\n */\n\nimport type { AgentXError } from \"@agentxjs/core/error\";\nimport type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from \"@agentxjs/core/event\";\n\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { AgentHandleImpl } from \"./AgentHandle\";\nimport { registerAll } from \"./handlers\";\nimport { createLocalImages } from \"./namespaces/images\";\nimport { createLocalLLM } from \"./namespaces/llm\";\nimport { createPresentations } from \"./namespaces/presentations\";\nimport { createLocalSessions } from \"./namespaces/sessions\";\nimport { RpcHandlerRegistry } from \"./RpcHandlerRegistry\";\nimport type { AgentX, ChatNamespace, LLMNamespace, RuntimeNamespace } from \"./types\";\n\nconst logger = createLogger(\"agentx/LocalClient\");\n\n/**\n * LocalClient - Embedded runtime implementation\n */\nexport class LocalClient implements AgentX {\n private readonly _runtime: AgentXRuntime;\n private registry: RpcHandlerRegistry | null = null;\n private isDisposed = false;\n\n readonly chat: ChatNamespace;\n readonly runtime: RuntimeNamespace;\n readonly provider: LLMNamespace;\n\n constructor(agentxRuntime: AgentXRuntime) {\n this._runtime = agentxRuntime;\n const platform = agentxRuntime.platform;\n\n const image = createLocalImages(platform, agentxRuntime);\n const session = createLocalSessions(agentxRuntime);\n const llm = createLocalLLM(platform);\n // Workspace resolver: imageId → PresentationWorkspace\n const workspaceResolver = async (imageId: string) => {\n const wp = platform.workspaceProvider;\n if (!wp) return null;\n const img = await platform.imageRepository.findImageById(imageId);\n if (!img?.workspaceId) return null;\n const ws = await wp.create(img.workspaceId);\n return {\n read: (path: string) => ws.read(path),\n write: (path: string, content: string) => ws.write(path, content),\n list: async (path?: string) => {\n const entries = await ws.list(path);\n return entries.map((e) => ({ name: e.name, path: e.path, type: e.type }));\n },\n };\n };\n const present = createPresentations(this, session, workspaceResolver);\n\n this.runtime = { image, session, present, llm };\n this.provider = llm;\n this.chat = this.createChatNamespace();\n\n logger.info(\"LocalClient initialized\");\n }\n\n // ==================== Properties ====================\n\n get connected(): boolean {\n return !this.isDisposed;\n }\n\n get events(): EventBus {\n return this._runtime.platform.eventBus;\n }\n\n // ==================== Event Subscription ====================\n\n on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {\n return this._runtime.platform.eventBus.on(type, handler);\n }\n\n onAny(handler: BusEventHandler): Unsubscribe {\n return this._runtime.platform.eventBus.onAny(handler);\n }\n\n // ==================== Error Handling ====================\n\n onError(handler: (error: AgentXError) => void): Unsubscribe {\n return this._runtime.platform.eventBus.on(\"agentx_error\", (event) => {\n handler(event.data as AgentXError);\n });\n }\n\n // ==================== RPC ====================\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n if (!this.registry) {\n this.registry = new RpcHandlerRegistry();\n registerAll(this.registry);\n }\n const result = await this.registry.handle(this._runtime, method, params);\n if (result.success) {\n return result.data as T;\n }\n throw new Error(result.message);\n }\n\n // ==================== Private ====================\n\n private createChatNamespace(): ChatNamespace {\n const rt = this.runtime;\n return {\n async create(params) {\n const imgRes = await rt.image.create(params);\n const runRes = await rt.image.run(imgRes.record.imageId);\n return new AgentHandleImpl(\n {\n instanceId: runRes.instanceId,\n imageId: runRes.imageId,\n containerId: runRes.containerId,\n sessionId: runRes.sessionId,\n },\n rt\n );\n },\n async list() {\n return rt.image.list();\n },\n async get(id) {\n const res = await rt.image.get(id);\n if (!res.record) return null;\n const runRes = await rt.image.run(res.record.imageId);\n return new AgentHandleImpl(\n {\n instanceId: runRes.instanceId,\n imageId: runRes.imageId,\n containerId: runRes.containerId,\n sessionId: runRes.sessionId,\n },\n rt\n );\n },\n };\n }\n\n // ==================== Lifecycle ====================\n\n async disconnect(): Promise<void> {\n // No-op for local mode\n }\n\n async dispose(): Promise<void> {\n if (this.isDisposed) return;\n await this._runtime.shutdown();\n this.isDisposed = true;\n logger.info(\"LocalClient disposed\");\n }\n}\n","/**\n * AgentHandle — live reference to a created agent.\n *\n * Wraps identity (IDs) + delegates operations to instance namespaces.\n */\n\nimport type { Message } from \"@agentxjs/core/agent\";\nimport type { SendOptions } from \"@agentxjs/core/driver\";\nimport type { Presentation, PresentationOptions } from \"./presentation\";\nimport type {\n AgentConfig,\n AgentHandle,\n BaseResponse,\n MessageSendResponse,\n RuntimeNamespace,\n} from \"./types\";\n\nexport class AgentHandleImpl implements AgentHandle {\n readonly instanceId: string;\n readonly imageId: string;\n readonly containerId: string;\n readonly sessionId: string;\n\n private readonly ns: RuntimeNamespace;\n\n constructor(\n ids: { instanceId: string; imageId: string; containerId: string; sessionId: string },\n ns: RuntimeNamespace\n ) {\n this.instanceId = ids.instanceId;\n this.imageId = ids.imageId;\n this.containerId = ids.containerId;\n this.sessionId = ids.sessionId;\n this.ns = ns;\n }\n\n async send(content: string | unknown[], options?: SendOptions): Promise<MessageSendResponse> {\n return this.ns.session.send(this.instanceId, content, options);\n }\n\n async interrupt(): Promise<BaseResponse> {\n return this.ns.session.interrupt(this.instanceId);\n }\n\n async history(): Promise<Message[]> {\n return this.ns.image.getMessages(this.imageId);\n }\n\n async present(options?: PresentationOptions): Promise<Presentation> {\n return this.ns.present.create(this.instanceId, options);\n }\n\n async update(\n updates: Partial<\n Pick<\n AgentConfig,\n \"name\" | \"description\" | \"model\" | \"systemPrompt\" | \"mcpServers\" | \"customData\"\n >\n >\n ): Promise<void> {\n await this.ns.image.update(this.imageId, updates);\n }\n\n async delete(): Promise<void> {\n await this.ns.image.stop(this.imageId);\n await this.ns.image.delete(this.imageId);\n }\n}\n","/**\n * Image namespace factories\n */\n\nimport type { Message } from \"@agentxjs/core/agent\";\nimport { DEFAULT_CONTAINER_ID } from \"@agentxjs/core/container\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXPlatform, AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport type {\n AgentConfig,\n BaseResponse,\n ImageCreateResponse,\n ImageGetResponse,\n ImageListResponse,\n ImageNamespace,\n ImageUpdateResponse,\n InstanceCreateResponse,\n} from \"../types\";\n\n/**\n * Create local image namespace backed by embedded runtime\n */\nexport function createLocalImages(\n platform: AgentXPlatform,\n runtime?: AgentXRuntime\n): ImageNamespace {\n return {\n async create(params: AgentConfig): Promise<ImageCreateResponse> {\n const { imageRepository, sessionRepository } = platform;\n const { createImage } = await import(\"@agentxjs/core/image\");\n\n const image = await createImage(\n {\n containerId: DEFAULT_CONTAINER_ID,\n ...params,\n mcpServers: params.mcpServers as any,\n thinking: params.thinking,\n },\n { imageRepository, sessionRepository }\n );\n\n return {\n record: image.toRecord(),\n requestId: \"\",\n };\n },\n\n async get(imageId: string): Promise<ImageGetResponse> {\n const record = await platform.imageRepository.findImageById(imageId);\n return {\n record,\n requestId: \"\",\n };\n },\n\n async list(): Promise<ImageListResponse> {\n const records = await platform.imageRepository.findAllImages();\n\n return {\n records,\n requestId: \"\",\n };\n },\n\n async update(\n imageId: string,\n updates: {\n name?: string;\n description?: string;\n customData?: Record<string, unknown>;\n }\n ): Promise<ImageUpdateResponse> {\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (!image) {\n throw new Error(`Image not found: ${imageId}`);\n }\n\n const updated = await image.update(updates);\n return { record: updated.toRecord(), requestId: \"\" };\n },\n\n async delete(imageId: string): Promise<BaseResponse> {\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (image) {\n await image.delete();\n }\n\n return { requestId: \"\" };\n },\n\n async getMessages(imageId: string): Promise<Message[]> {\n const imageRecord = await platform.imageRepository.findImageById(imageId);\n if (!imageRecord) return [];\n return platform.sessionRepository.getMessages(imageRecord.sessionId);\n },\n\n async run(imageId: string): Promise<InstanceCreateResponse> {\n if (!runtime) throw new Error(\"Runtime not available\");\n const existing = runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n if (existing) {\n return {\n instanceId: existing.instanceId,\n imageId: existing.imageId,\n containerId: existing.containerId,\n sessionId: existing.sessionId,\n requestId: \"\",\n };\n }\n const agent = await runtime.createAgent({ imageId });\n return {\n instanceId: agent.instanceId,\n imageId: agent.imageId,\n containerId: agent.containerId,\n sessionId: agent.sessionId,\n requestId: \"\",\n };\n },\n\n async stop(imageId: string): Promise<BaseResponse> {\n if (!runtime) throw new Error(\"Runtime not available\");\n const agent = runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n if (agent) await runtime.stopAgent(agent.instanceId);\n return { requestId: \"\" };\n },\n };\n}\n\n/**\n * Create remote image namespace backed by RPC client\n */\nexport function createRemoteImages(rpcClient: RpcClient): ImageNamespace {\n return {\n async create(params: AgentConfig): Promise<ImageCreateResponse> {\n const result = await rpcClient.call<ImageCreateResponse>(\"image.create\", {\n ...params,\n containerId: DEFAULT_CONTAINER_ID,\n });\n return { ...result, requestId: \"\" };\n },\n\n async get(imageId: string): Promise<ImageGetResponse> {\n const result = await rpcClient.call<ImageGetResponse>(\"image.get\", { imageId });\n return { ...result, requestId: \"\" };\n },\n\n async list(): Promise<ImageListResponse> {\n const result = await rpcClient.call<ImageListResponse>(\"image.list\", {});\n return { ...result, requestId: \"\" };\n },\n\n async update(\n imageId: string,\n updates: {\n name?: string;\n description?: string;\n customData?: Record<string, unknown>;\n }\n ): Promise<ImageUpdateResponse> {\n const result = await rpcClient.call<ImageUpdateResponse>(\"image.update\", {\n imageId,\n updates,\n });\n return { ...result, requestId: \"\" };\n },\n\n async delete(imageId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"image.delete\", { imageId });\n return { ...result, requestId: \"\" };\n },\n\n async getMessages(imageId: string): Promise<Message[]> {\n const result = await rpcClient.call<{ messages: Message[] }>(\"image.messages\", { imageId });\n return result.messages ?? [];\n },\n\n async run(imageId: string): Promise<InstanceCreateResponse> {\n const result = await rpcClient.call<InstanceCreateResponse>(\"image.run\", { imageId });\n return { ...result, requestId: \"\" };\n },\n\n async stop(imageId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"image.stop\", { imageId });\n return { ...result, requestId: \"\" };\n },\n };\n}\n","/**\n * LLM Provider namespace factories\n */\n\nimport { DEFAULT_CONTAINER_ID } from \"@agentxjs/core/container\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { LLMProviderRecord } from \"@agentxjs/core/persistence\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport { generateId } from \"@deepracticex/id\";\nimport type {\n BaseResponse,\n LLMNamespace,\n LLMProviderCreateResponse,\n LLMProviderDefaultResponse,\n LLMProviderGetResponse,\n LLMProviderListResponse,\n LLMProviderUpdateResponse,\n} from \"../types\";\n\n/**\n * Create local LLM namespace backed by platform repository\n */\nexport function createLocalLLM(platform: AgentXPlatform): LLMNamespace {\n const repo = platform.llmProviderRepository;\n if (!repo) {\n throw new Error(\"LLM provider repository not available on this platform\");\n }\n\n return {\n async create(params): Promise<LLMProviderCreateResponse> {\n const now = Date.now();\n const record: LLMProviderRecord = {\n id: generateId(\"llm\"),\n containerId: DEFAULT_CONTAINER_ID,\n name: params.name,\n vendor: params.vendor,\n protocol: params.protocol,\n apiKey: params.apiKey,\n baseUrl: params.baseUrl,\n model: params.model,\n isDefault: false,\n createdAt: now,\n updatedAt: now,\n };\n\n await repo.saveLLMProvider(record);\n return { record, requestId: \"\" };\n },\n\n async get(id: string): Promise<LLMProviderGetResponse> {\n const record = await repo.findLLMProviderById(id);\n return { record, requestId: \"\" };\n },\n\n async list(): Promise<LLMProviderListResponse> {\n const records = await repo.findLLMProvidersByContainerId(DEFAULT_CONTAINER_ID);\n return { records, requestId: \"\" };\n },\n\n async update(id, updates): Promise<LLMProviderUpdateResponse> {\n const existing = await repo.findLLMProviderById(id);\n if (!existing) {\n throw new Error(`LLM provider not found: ${id}`);\n }\n\n const updated: LLMProviderRecord = {\n ...existing,\n ...updates,\n id: existing.id,\n containerId: existing.containerId,\n createdAt: existing.createdAt,\n updatedAt: Date.now(),\n };\n\n await repo.saveLLMProvider(updated);\n return { record: updated, requestId: \"\" };\n },\n\n async delete(id: string): Promise<BaseResponse> {\n await repo.deleteLLMProvider(id);\n return { requestId: \"\" };\n },\n\n async setDefault(id: string): Promise<BaseResponse> {\n await repo.setDefaultLLMProvider(id);\n return { requestId: \"\" };\n },\n\n async getDefault(): Promise<LLMProviderDefaultResponse> {\n const record = await repo.findDefaultLLMProvider(DEFAULT_CONTAINER_ID);\n return { record, requestId: \"\" };\n },\n };\n}\n\n/**\n * Create remote LLM namespace backed by RPC client\n */\nexport function createRemoteLLM(rpcClient: RpcClient): LLMNamespace {\n return {\n async create(params): Promise<LLMProviderCreateResponse> {\n const result = await rpcClient.call<LLMProviderCreateResponse>(\"llm.create\", {\n ...params,\n containerId: DEFAULT_CONTAINER_ID,\n });\n return { ...result, requestId: \"\" };\n },\n\n async get(id: string): Promise<LLMProviderGetResponse> {\n const result = await rpcClient.call<LLMProviderGetResponse>(\"llm.get\", { id });\n return { ...result, requestId: \"\" };\n },\n\n async list(): Promise<LLMProviderListResponse> {\n const result = await rpcClient.call<LLMProviderListResponse>(\"llm.list\", {\n containerId: DEFAULT_CONTAINER_ID,\n });\n return { ...result, requestId: \"\" };\n },\n\n async update(id, updates): Promise<LLMProviderUpdateResponse> {\n const result = await rpcClient.call<LLMProviderUpdateResponse>(\"llm.update\", {\n id,\n updates,\n });\n return { ...result, requestId: \"\" };\n },\n\n async delete(id: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"llm.delete\", { id });\n return { ...result, requestId: \"\" };\n },\n\n async setDefault(id: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"llm.default\", { id });\n return { ...result, requestId: \"\" };\n },\n\n async getDefault(): Promise<LLMProviderDefaultResponse> {\n const result = await rpcClient.call<LLMProviderDefaultResponse>(\"llm.default\", {\n containerId: DEFAULT_CONTAINER_ID,\n });\n return { ...result, requestId: \"\" };\n },\n };\n}\n","/**\n * Presentation Types\n *\n * UI-friendly data model aggregated from stream events.\n * This implements the Presentation Model pattern.\n */\n\n// ============================================================================\n// Block Types - Basic content units\n// ============================================================================\n\n/**\n * Text block\n */\nexport interface TextBlock {\n type: \"text\";\n content: string;\n}\n\n/**\n * Tool block - represents a tool call and its result\n */\nexport interface ToolBlock {\n type: \"tool\";\n toolUseId: string;\n toolName: string;\n toolInput: Record<string, unknown>;\n toolResult?: string;\n /** Partial JSON input being streamed (visible during input-streaming phase) */\n partialInput?: string;\n status: \"pending\" | \"running\" | \"completed\" | \"error\" | \"interrupted\";\n}\n\n/**\n * Image block\n */\nexport interface ImageBlock {\n type: \"image\";\n url: string;\n alt?: string;\n}\n\n/**\n * File block\n */\nexport interface FileBlock {\n type: \"file\";\n filename: string;\n mediaType: string;\n}\n\n/**\n * Thinking/reasoning block — AI's internal reasoning process\n */\nexport interface ThinkingBlock {\n type: \"thinking\";\n content: string;\n}\n\n/**\n * All block types\n */\nexport type Block = TextBlock | ToolBlock | ImageBlock | FileBlock | ThinkingBlock;\n\n// ============================================================================\n// Conversation Types - A single turn in the conversation\n// ============================================================================\n\n/**\n * User conversation\n */\nexport interface UserConversation {\n role: \"user\";\n blocks: Block[];\n}\n\n/**\n * Token usage for a message (one LLM call / step)\n */\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n}\n\n/**\n * Assistant conversation\n */\nexport interface AssistantConversation {\n role: \"assistant\";\n blocks: Block[];\n isStreaming: boolean;\n /** Accumulated token usage across all steps in this conversation */\n usage?: TokenUsage;\n}\n\n/**\n * Error conversation\n */\nexport interface ErrorConversation {\n role: \"error\";\n message: string;\n}\n\n/**\n * All conversation types\n */\nexport type Conversation = UserConversation | AssistantConversation | ErrorConversation;\n\n// ============================================================================\n// Presentation Metrics\n// ============================================================================\n\n/**\n * Turn-level metrics.\n * Reset at the start of each turn, preserved after turn ends.\n */\nexport interface TurnMetrics {\n /** Timestamp when the current turn started (null when idle before first turn) */\n turnStartedAt: number | null;\n /** Input tokens consumed in the current turn */\n inputTokens: number;\n /** Output tokens generated in the current turn */\n outputTokens: number;\n}\n\n/**\n * Session-level context metrics.\n * Tracks the overall context window usage across the entire session.\n */\nexport interface SessionMetrics {\n /** Current context size in tokens (last inputTokens from LLM — includes full history) */\n contextTokens: number;\n /** Model's context window limit (0 = unknown) */\n contextLimit: number;\n /** Context usage ratio 0-1 (0 when limit unknown) */\n contextUsage: number;\n}\n\n/**\n * Combined presentation metrics — turn + session level.\n */\nexport interface PresentationMetrics extends TurnMetrics {\n /** Session-level context window metrics */\n session: SessionMetrics;\n}\n\n// ============================================================================\n// Workspace State\n// ============================================================================\n\n/**\n * File tree entry — recursive structure for rendering directory tree\n */\nexport interface FileTreeEntry {\n /** File or directory name */\n name: string;\n /** Path relative to workspace root */\n path: string;\n /** File or directory */\n type: \"file\" | \"directory\";\n /** Children (only for directories) */\n children?: FileTreeEntry[];\n}\n\n/**\n * Workspace state — real-time workspace view\n */\nexport interface WorkspaceState {\n /**\n * Current file tree (recursive).\n * Frontend just renders this tree directly.\n */\n files: FileTreeEntry[];\n}\n\n// ============================================================================\n// Presentation Workspace Operations\n// ============================================================================\n\n/**\n * PresentationWorkspace — file operations exposed to the consumer.\n * Wraps the underlying Workspace with a simple API.\n */\nexport interface PresentationWorkspace {\n /** Read file content */\n read(path: string): Promise<string>;\n /** Write content to a file */\n write(path: string, content: string): Promise<void>;\n /** List directory entries */\n list(path?: string): Promise<FileTreeEntry[]>;\n}\n\n// ============================================================================\n// Presentation State\n// ============================================================================\n\n/**\n * Connection state\n */\nexport type ConnectionState = \"connected\" | \"connecting\" | \"disconnected\";\n\n/**\n * Presentation state - the complete UI state\n */\nexport interface PresentationState {\n /**\n * All conversations including the currently streaming one.\n * The streaming conversation is the last item with `isStreaming: true`.\n * Frontend just does `conversations.map(...)` — no merging needed.\n */\n conversations: Conversation[];\n\n /**\n * Current agent status\n *\n * - idle: No active request\n * - submitted: Message sent, waiting for first token\n * - thinking: LLM outputting thinking/reasoning content\n * - responding: LLM outputting text content\n * - executing: Tool call in progress\n */\n status: \"idle\" | \"submitted\" | \"thinking\" | \"responding\" | \"executing\";\n\n /**\n * WebSocket connection state\n */\n connection: ConnectionState;\n\n /**\n * Real-time metrics for the current turn\n */\n metrics: PresentationMetrics;\n\n /**\n * Workspace state — real-time file tree.\n * null when agent has no workspace.\n */\n workspace: WorkspaceState | null;\n}\n\n/**\n * Initial presentation metrics\n */\nexport const initialSessionMetrics: SessionMetrics = {\n contextTokens: 0,\n contextLimit: 0,\n contextUsage: 0,\n};\n\nexport const initialMetrics: PresentationMetrics = {\n turnStartedAt: null,\n inputTokens: 0,\n outputTokens: 0,\n session: initialSessionMetrics,\n};\n\n/**\n * Initial presentation state\n */\nexport const initialPresentationState: PresentationState = {\n conversations: [],\n status: \"idle\",\n connection: \"connected\",\n metrics: initialMetrics,\n workspace: null,\n};\n","/**\n * Presentation Reducer\n *\n * Aggregates events into PresentationState.\n * Pure function: (state, event) => newState\n *\n * Event consumption strategy:\n * - Stream layer: message_start, text_delta, tool_use_start, tool_use_stop, message_stop\n * (for real-time streaming display)\n * - Message layer: tool_result_message\n * (for tool execution results — arrives after message_stop)\n *\n * Tool calls are stream-level blocks within the assistant turn,\n * matching the mainstream API pattern (Anthropic, OpenAI).\n */\n\nimport type {\n AssistantMessage,\n ErrorMessage,\n Message,\n ToolCallPart,\n ToolResultMessage,\n ToolResultOutput,\n UserContentPart,\n UserMessage,\n} from \"@agentxjs/core/agent\";\nimport type { BusEvent } from \"@agentxjs/core/event\";\nimport type {\n AssistantConversation,\n Block,\n ConnectionState,\n Conversation,\n FileTreeEntry,\n PresentationState,\n TextBlock,\n TokenUsage,\n ToolBlock,\n} from \"./types\";\nimport { initialMetrics, initialPresentationState } from \"./types\";\n\n// ============================================================================\n// Event Data Types\n// ============================================================================\n\ninterface MessageStartData {\n messageId?: string;\n model?: string;\n}\n\ninterface TextDeltaData {\n text: string;\n}\n\ninterface ToolUseStartData {\n toolCallId: string;\n toolName: string;\n}\n\ninterface ToolUseStopData {\n toolCallId: string;\n toolName: string;\n input: Record<string, unknown>;\n}\n\ninterface MessageDeltaData {\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\ninterface MessageStopData {\n stopReason?: string;\n}\n\ninterface ErrorData {\n message: string;\n code?: string;\n}\n\n// ============================================================================\n// Reducer\n// ============================================================================\n\n/**\n * Reduce an event into presentation state.\n *\n * Consumes:\n * - Stream events: message_start, text_delta, tool_use_start, tool_use_stop, message_stop\n * - Message events: tool_result_message\n * - Error events: error\n */\nexport function presentationReducer(state: PresentationState, event: BusEvent): PresentationState {\n switch (event.type) {\n // Stream layer — real-time display\n case \"message_start\":\n return handleMessageStart(state, event.data as MessageStartData);\n\n case \"thinking_delta\":\n return handleThinkingDelta(state, event.data as TextDeltaData);\n\n case \"text_delta\":\n return handleTextDelta(state, event.data as TextDeltaData);\n\n case \"tool_use_start\":\n return handleToolUseStart(state, event.data as ToolUseStartData);\n\n case \"tool_use_stop\":\n return handleToolUseStop(state, event.data as ToolUseStopData);\n\n case \"input_json_delta\":\n return handleInputJsonDelta(state, event.data as { partialJson: string });\n\n case \"message_delta\":\n return handleMessageDelta(state, event.data as MessageDeltaData);\n\n case \"message_stop\":\n return handleMessageStop(state, event.data as MessageStopData);\n\n // Message layer — tool results from Engine\n case \"tool_result_message\":\n return handleToolResultMessage(state, event.data as ToolResultMessage);\n\n case \"tool_result\":\n return handleToolResult(\n state,\n event.data as { toolCallId: string; result: unknown; isError: boolean }\n );\n\n case \"error\":\n return handleError(state, event.data as ErrorData);\n\n case \"interrupted\":\n return handleInterrupted(state);\n\n // Connection state\n case \"connection_state\":\n return handleConnectionState(state, event.data as { state: string });\n\n // Workspace file tree\n case \"workspace_tree\":\n return handleWorkspaceTree(state, event.data as { files: FileTreeEntry[] });\n\n // Rewind — runtime-level operation\n case \"rewind\":\n return handleRewind(state, event.data as { truncatedCount: number });\n\n default:\n return state;\n }\n}\n\n// ============================================================================\n// Helpers — operate on the last assistant conversation in conversations[]\n// ============================================================================\n\n/**\n * Get the last conversation if it's a streaming assistant conversation.\n */\nfunction getStreamingConv(state: PresentationState): AssistantConversation | null {\n const last = state.conversations[state.conversations.length - 1];\n if (last?.role === \"assistant\" && (last as AssistantConversation).isStreaming) {\n return last as AssistantConversation;\n }\n return null;\n}\n\n/**\n * Update the last conversation in the array (must be streaming assistant).\n */\nfunction updateLastConv(\n state: PresentationState,\n updater: (conv: AssistantConversation) => AssistantConversation,\n extraState?: Partial<PresentationState>\n): PresentationState {\n const conv = getStreamingConv(state);\n if (!conv) return state;\n\n const updated = updater(conv);\n const conversations = [...state.conversations];\n conversations[conversations.length - 1] = updated;\n\n return { ...state, conversations, ...extraState };\n}\n\ninterface InputJsonDeltaData {\n partialJson: string;\n}\n\n// ============================================================================\n// Handlers — all operate on conversations[]\n// ============================================================================\n\nfunction handleMessageStart(state: PresentationState, _data: MessageStartData): PresentationState {\n const newConv: AssistantConversation = {\n role: \"assistant\",\n blocks: [],\n isStreaming: true,\n };\n\n // Only reset metrics at the start of a new turn (idle/submitted → submitted).\n // Mid-turn message_start (after tool_use) should keep accumulating.\n const isNewTurn = state.status === \"idle\" || state.status === \"submitted\";\n const metrics = isNewTurn ? { ...initialMetrics, turnStartedAt: Date.now() } : state.metrics;\n\n return {\n ...state,\n conversations: [...state.conversations, newConv],\n status: \"submitted\",\n metrics,\n };\n}\n\nfunction handleThinkingDelta(state: PresentationState, data: TextDeltaData): PresentationState {\n return updateLastConv(\n state,\n (conv) => {\n const blocks = [...conv.blocks];\n const lastBlock = blocks[blocks.length - 1];\n\n if (lastBlock && lastBlock.type === \"thinking\") {\n blocks[blocks.length - 1] = {\n ...lastBlock,\n content: (lastBlock as any).content + data.text,\n };\n } else {\n blocks.push({ type: \"thinking\", content: data.text } as Block);\n }\n\n return { ...conv, blocks };\n },\n { status: \"thinking\" }\n );\n}\n\nfunction handleTextDelta(state: PresentationState, data: TextDeltaData): PresentationState {\n return updateLastConv(\n state,\n (conv) => {\n const blocks = [...conv.blocks];\n const lastBlock = blocks[blocks.length - 1];\n\n if (lastBlock && lastBlock.type === \"text\") {\n blocks[blocks.length - 1] = {\n ...lastBlock,\n content: lastBlock.content + data.text,\n };\n } else {\n blocks.push({ type: \"text\", content: data.text } as TextBlock);\n }\n\n return { ...conv, blocks };\n },\n { status: \"responding\" }\n );\n}\n\nfunction handleToolUseStart(state: PresentationState, data: ToolUseStartData): PresentationState {\n const toolBlock: ToolBlock = {\n type: \"tool\",\n toolUseId: data.toolCallId,\n toolName: data.toolName,\n toolInput: {},\n status: \"pending\",\n };\n\n return updateLastConv(state, (conv) => ({ ...conv, blocks: [...conv.blocks, toolBlock] }), {\n status: \"executing\",\n });\n}\n\nfunction handleInputJsonDelta(\n state: PresentationState,\n data: InputJsonDeltaData\n): PresentationState {\n return updateLastConv(state, (conv) => {\n const blocks = conv.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.status === \"pending\") {\n return {\n ...block,\n partialInput: ((block as any).partialInput || \"\") + data.partialJson,\n } as ToolBlock;\n }\n return block;\n });\n return { ...conv, blocks };\n });\n}\n\nfunction handleToolUseStop(state: PresentationState, data: ToolUseStopData): PresentationState {\n return updateLastConv(\n state,\n (conv) => {\n const blocks = conv.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === data.toolCallId) {\n return { ...block, toolInput: data.input, status: \"running\" };\n }\n return block;\n });\n return { ...conv, blocks };\n },\n { status: \"executing\" }\n );\n}\n\nfunction handleMessageDelta(state: PresentationState, data: MessageDeltaData): PresentationState {\n if (!data.usage) return state;\n\n const newState = updateLastConv(state, (conv) => {\n const prev = conv.usage;\n const usage: TokenUsage = {\n inputTokens: (prev?.inputTokens ?? 0) + data.usage!.inputTokens,\n outputTokens: (prev?.outputTokens ?? 0) + data.usage!.outputTokens,\n };\n return { ...conv, usage };\n });\n\n // inputTokens from LLM = current context size (full history sent each call)\n const contextTokens = data.usage.inputTokens;\n const contextLimit = newState.metrics.session.contextLimit;\n const contextUsage = contextLimit > 0 ? contextTokens / contextLimit : 0;\n\n return {\n ...newState,\n metrics: {\n ...newState.metrics,\n inputTokens: newState.metrics.inputTokens + data.usage.inputTokens,\n outputTokens: newState.metrics.outputTokens + data.usage.outputTokens,\n session: {\n contextTokens,\n contextLimit,\n contextUsage,\n },\n },\n };\n}\n\nfunction handleMessageStop(state: PresentationState, data: MessageStopData): PresentationState {\n // tool_use stop → keep streaming, tool results are still incoming\n if (data.stopReason === \"tool_use\") {\n return { ...state, status: \"executing\" };\n }\n\n // end_turn / max_tokens → mark completed, clear turnStartedAt\n return updateLastConv(state, (conv) => ({ ...conv, isStreaming: false }), {\n status: \"idle\",\n metrics: { ...state.metrics, turnStartedAt: null },\n });\n}\n\nfunction handleToolResultMessage(\n state: PresentationState,\n data: ToolResultMessage\n): PresentationState {\n const toolCallId = data.toolCallId;\n\n // Find tool block in any conversation (could be in last streaming or already completed)\n const conversations = state.conversations.map((conv): Conversation => {\n if (conv.role !== \"assistant\") return conv;\n const ac = conv as AssistantConversation;\n const hasMatch = ac.blocks.some((b) => b.type === \"tool\" && b.toolUseId === toolCallId);\n if (!hasMatch) return conv;\n\n const blocks = ac.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === toolCallId) {\n return {\n ...block,\n toolResult: formatToolResultOutput(data.toolResult.output),\n status:\n data.toolResult.output.type === \"error-text\" ||\n data.toolResult.output.type === \"error-json\" ||\n data.toolResult.output.type === \"execution-denied\"\n ? \"error\"\n : \"completed\",\n };\n }\n return block;\n });\n return { ...ac, blocks };\n });\n\n return { ...state, conversations, status: \"responding\" };\n}\n\n/**\n * Handle tool_result from stream layer (raw driver event).\n */\nfunction handleToolResult(\n state: PresentationState,\n data: { toolCallId: string; result: unknown; isError: boolean }\n): PresentationState {\n const { toolCallId, result, isError } = data;\n const resultStr =\n typeof result === \"string\"\n ? result\n : result instanceof Error\n ? result.message\n : JSON.stringify(result);\n\n const conversations = state.conversations.map((conv): Conversation => {\n if (conv.role !== \"assistant\") return conv;\n const ac = conv as AssistantConversation;\n const hasMatch = ac.blocks.some((b) => b.type === \"tool\" && b.toolUseId === toolCallId);\n if (!hasMatch) return conv;\n\n const blocks = ac.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === toolCallId) {\n return { ...block, toolResult: resultStr, status: isError ? \"error\" : \"completed\" };\n }\n return block;\n });\n return { ...ac, blocks };\n });\n\n return { ...state, conversations, status: \"responding\" };\n}\n\nfunction handleError(state: PresentationState, data: ErrorData): PresentationState {\n // If there's a streaming conversation with content, keep it\n const conv = getStreamingConv(state);\n let conversations = state.conversations;\n if (conv && conv.blocks.length > 0) {\n // Mark streaming conv as completed before adding error\n conversations = [...state.conversations];\n conversations[conversations.length - 1] = { ...conv, isStreaming: false };\n }\n\n return {\n ...state,\n conversations: [...conversations, { role: \"error\", message: data.message }],\n status: \"idle\",\n };\n}\n\n/**\n * Interrupt handlers per block type.\n * Each handler receives a block and returns the interrupted version.\n * New block types register here — handleInterrupted stays fixed.\n */\nconst interruptHandlers: Partial<Record<Block[\"type\"], (block: Block) => Block>> = {\n tool: (block) => {\n const tb = block as ToolBlock;\n if (tb.status === \"pending\" || tb.status === \"running\") {\n return { ...tb, status: \"interrupted\", toolResult: \"Interrupted\" };\n }\n return block;\n },\n};\n\nfunction handleInterrupted(state: PresentationState): PresentationState {\n return updateLastConv(\n state,\n (conv) => {\n const blocks = conv.blocks.map((block): Block => {\n const handler = interruptHandlers[block.type];\n return handler ? handler(block) : block;\n });\n return { ...conv, blocks, isStreaming: false };\n },\n { status: \"idle\" }\n );\n}\n\nfunction handleConnectionState(\n state: PresentationState,\n data: { state: string }\n): PresentationState {\n const connection = data.state as ConnectionState;\n if (connection === state.connection) return state;\n return { ...state, connection };\n}\n\nfunction handleRewind(\n state: PresentationState,\n data: { truncatedCount: number }\n): PresentationState {\n // Remove the last N conversations (truncatedCount maps roughly to messages, not conversations)\n // Simplest: re-derive from the event — just drop conversations from the end\n const toRemove = Math.max(1, Math.ceil(data.truncatedCount / 2));\n const conversations = state.conversations.slice(\n 0,\n Math.max(0, state.conversations.length - toRemove)\n );\n return { ...state, conversations, status: \"idle\" };\n}\n\nfunction handleWorkspaceTree(\n state: PresentationState,\n data: { files: FileTreeEntry[] }\n): PresentationState {\n return {\n ...state,\n workspace: { files: data.files },\n };\n}\n\n// ============================================================================\n// Helper: Add user conversation\n// ============================================================================\n\nexport function addUserConversation(\n state: PresentationState,\n content: string | UserContentPart[]\n): PresentationState {\n const blocks: Block[] =\n typeof content === \"string\"\n ? [{ type: \"text\", content }]\n : content.map((part) => {\n switch (part.type) {\n case \"text\":\n return { type: \"text\" as const, content: part.text };\n case \"image\":\n return {\n type: \"image\" as const,\n url: `data:${part.mediaType};base64,${part.data}`,\n alt: part.name,\n };\n case \"file\":\n return {\n type: \"file\" as const,\n filename: part.filename ?? \"file\",\n mediaType: part.mediaType,\n };\n default:\n return { type: \"text\" as const, content: String(part) };\n }\n });\n\n return {\n ...state,\n conversations: [...state.conversations, { role: \"user\", blocks }],\n status: \"submitted\",\n };\n}\n\nexport function createInitialState(): PresentationState {\n return { ...initialPresentationState };\n}\n\n// ============================================================================\n// Helper: Format tool result output\n// ============================================================================\n\nfunction formatToolResultOutput(output: ToolResultOutput): string {\n switch (output.type) {\n case \"text\":\n case \"error-text\":\n return output.value;\n case \"json\":\n case \"error-json\":\n return JSON.stringify(output.value);\n case \"execution-denied\":\n return output.reason ?? \"Execution denied\";\n case \"content\":\n return output.value\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\");\n }\n}\n\n// ============================================================================\n// Message → Conversation Converter\n// ============================================================================\n\n/**\n * Convert persisted Messages to Presentation Conversations.\n *\n * Groups consecutive assistant + tool-result messages\n * into a single AssistantConversation.\n *\n * Tool calls are now part of AssistantMessage.content (as ToolCallPart),\n * so we extract them directly from the assistant message.\n */\nexport function messagesToConversations(messages: Message[]): Conversation[] {\n const conversations: Conversation[] = [];\n let currentAssistant: AssistantConversation | null = null;\n\n function flushAssistant() {\n if (currentAssistant && currentAssistant.blocks.length > 0) {\n conversations.push(currentAssistant);\n }\n currentAssistant = null;\n }\n\n for (const msg of messages) {\n switch (msg.subtype) {\n case \"user\": {\n flushAssistant();\n const m = msg as UserMessage;\n const blocks: Block[] =\n typeof m.content === \"string\"\n ? [{ type: \"text\", content: m.content }]\n : m.content.map((part): Block => {\n switch (part.type) {\n case \"text\":\n return { type: \"text\", content: part.text };\n case \"image\":\n return {\n type: \"image\",\n url: `data:${part.mediaType};base64,${part.data}`,\n alt: part.name,\n };\n case \"file\":\n return {\n type: \"file\",\n filename: part.filename ?? \"file\",\n mediaType: part.mediaType,\n };\n default:\n return { type: \"text\", content: String(part) };\n }\n });\n conversations.push({ role: \"user\", blocks });\n break;\n }\n\n case \"assistant\": {\n if (!currentAssistant) {\n currentAssistant = { role: \"assistant\", blocks: [], isStreaming: false };\n }\n const m = msg as AssistantMessage;\n if (typeof m.content === \"string\") {\n if (m.content) {\n currentAssistant.blocks.push({ type: \"text\", content: m.content } as TextBlock);\n }\n } else {\n // Extract all content parts — must match what real-time streaming produces\n for (const part of m.content) {\n if (part.type === \"text\") {\n if (part.text) {\n currentAssistant.blocks.push({ type: \"text\", content: part.text } as TextBlock);\n }\n } else if (part.type === \"thinking\") {\n if (part.reasoning) {\n currentAssistant.blocks.push({\n type: \"thinking\",\n content: part.reasoning,\n } as Block);\n }\n } else if (part.type === \"tool-call\") {\n const tc = part as ToolCallPart;\n currentAssistant.blocks.push({\n type: \"tool\",\n toolUseId: tc.id,\n toolName: tc.name,\n toolInput: tc.input,\n status: \"completed\",\n } as ToolBlock);\n } else if (part.type === \"file\") {\n currentAssistant.blocks.push({\n type: \"file\",\n filename: (part as any).filename ?? \"file\",\n mediaType: (part as any).mediaType ?? \"application/octet-stream\",\n } as Block);\n }\n }\n }\n break;\n }\n\n case \"tool-result\": {\n const m = msg as ToolResultMessage;\n if (currentAssistant) {\n for (const block of currentAssistant.blocks) {\n if (block.type === \"tool\" && block.toolUseId === m.toolResult.id) {\n block.toolResult = formatToolResultOutput(m.toolResult.output);\n block.status =\n m.toolResult.output.type === \"error-text\" ||\n m.toolResult.output.type === \"error-json\" ||\n m.toolResult.output.type === \"execution-denied\"\n ? \"error\"\n : \"completed\";\n break;\n }\n }\n }\n break;\n }\n\n case \"error\": {\n flushAssistant();\n const m = msg as ErrorMessage;\n conversations.push({\n role: \"error\",\n message: m.content,\n });\n break;\n }\n }\n }\n\n flushAssistant();\n return conversations;\n}\n","/**\n * Presentation — a live chat session.\n *\n * Read state directly as properties. Subscribe for re-renders.\n * Take actions with send/interrupt/rewind.\n *\n * @example\n * ```typescript\n * // Read state\n * pres.conversations // message history\n * pres.status // \"idle\" | \"submitted\" | \"thinking\" | \"responding\" | \"executing\"\n * pres.workspace // { files, read, write, list } or null\n *\n * // Subscribe (works with useSyncExternalStore)\n * const unsub = pres.subscribe(() => rerender());\n *\n * // Actions\n * await pres.send(\"Hello\");\n * await pres.interrupt();\n * await pres.rewind(2);\n * ```\n */\n\nimport type { UserContentPart } from \"@agentxjs/core/agent\";\nimport type { SendOptions } from \"@agentxjs/core/driver\";\nimport type { BusEvent } from \"@agentxjs/core/event\";\nimport type { AgentX } from \"../types\";\nimport { addUserConversation, createInitialState, presentationReducer } from \"./reducer\";\nimport type {\n ConnectionState,\n Conversation,\n PresentationMetrics,\n PresentationState,\n PresentationWorkspace,\n} from \"./types\";\nimport { initialPresentationState } from \"./types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Workspace — file tree + operations, unified.\n */\nexport interface Workspace {\n /** Current file tree (real-time updates) */\n readonly files: readonly import(\"./types\").FileTreeEntry[];\n /** Read file content */\n read(path: string): Promise<string>;\n /** Write content to file */\n write(path: string, content: string): Promise<void>;\n /** List directory entries */\n list(path?: string): Promise<import(\"./types\").FileTreeEntry[]>;\n}\n\n/**\n * Options for creating a Presentation\n */\nexport interface PresentationOptions {\n /** Called on every state change (legacy — prefer subscribe) */\n onUpdate?: (state: PresentationState) => void;\n}\n\n// ============================================================================\n// Presentation\n// ============================================================================\n\nexport class Presentation {\n private _agentx: AgentX;\n private _instanceId: string;\n private _state: PresentationState;\n private _listeners = new Set<() => void>();\n private _legacyHandlers = new Set<(state: PresentationState) => void>();\n private _eventUnsubscribe: (() => void) | null = null;\n private _workspaceOps: PresentationWorkspace | null;\n\n constructor(\n agentx: AgentX,\n instanceId: string,\n options?: PresentationOptions,\n initialConversations?: Conversation[],\n workspace?: PresentationWorkspace | null\n ) {\n this._agentx = agentx;\n this._instanceId = instanceId;\n this._workspaceOps = workspace ?? null;\n this._state = initialConversations?.length\n ? { ...initialPresentationState, conversations: initialConversations }\n : createInitialState();\n\n // Legacy onUpdate support\n if (options?.onUpdate) {\n this._legacyHandlers.add(options.onUpdate);\n }\n\n // Subscribe to EventBus\n this._subscribeToEvents();\n\n // Load initial workspace file tree\n if (this._workspaceOps) {\n this._workspaceOps.list(\".\").then((files) => {\n this._state = { ...this._state, workspace: { files } };\n this._notify();\n });\n }\n }\n\n // ==================== State (direct properties) ====================\n\n /** All conversations (user, assistant, error) */\n get conversations(): readonly Conversation[] {\n return this._state.conversations;\n }\n\n /** Current agent status */\n get status(): PresentationState[\"status\"] {\n return this._state.status;\n }\n\n /** WebSocket connection state */\n get connection(): ConnectionState {\n return this._state.connection;\n }\n\n /** Token usage and context metrics */\n get metrics(): PresentationMetrics {\n return this._state.metrics;\n }\n\n /** Workspace — file tree + operations. null if agent has no workspace. */\n get workspace(): Workspace | null {\n if (!this._workspaceOps) return null;\n const ops = this._workspaceOps;\n const wsState = this._state.workspace;\n return {\n get files() {\n return wsState?.files ?? [];\n },\n read: (path: string) => ops.read(path),\n write: (path: string, content: string) => ops.write(path, content),\n list: (path?: string) => ops.list(path),\n };\n }\n\n // ==================== Subscribe ====================\n\n /**\n * Subscribe to state changes.\n * Compatible with React's useSyncExternalStore.\n * Does NOT call listener immediately.\n *\n * @returns Unsubscribe function\n */\n subscribe(listener: () => void): () => void {\n this._listeners.add(listener);\n return () => {\n this._listeners.delete(listener);\n };\n }\n\n /**\n * Get state snapshot.\n * Compatible with React's useSyncExternalStore.\n */\n getSnapshot(): PresentationState {\n return this._state;\n }\n\n // ==================== Actions ====================\n\n /** Send a message */\n async send(content: string | UserContentPart[], options?: SendOptions): Promise<void> {\n this._state = addUserConversation(this._state, content);\n this._notify();\n\n // Yield to allow UI to render submitted state\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n try {\n await this._agentx.runtime.session.send(this._instanceId, content, options);\n } catch (error) {\n console.error(\"Presentation send error:\", error);\n }\n }\n\n /** Interrupt current response */\n async interrupt(): Promise<void> {\n try {\n await this._agentx.runtime.session.interrupt(this._instanceId);\n } catch (error) {\n console.error(\"Presentation interrupt error:\", error);\n }\n }\n\n /** Rewind conversation to a specific index (removes index and everything after) */\n async rewind(index: number): Promise<void> {\n const conversations = this._state.conversations;\n if (index < 0 || index >= conversations.length) return;\n\n try {\n const messages = await this._agentx.runtime.session.getMessages(this._instanceId);\n if (messages.length === 0) return;\n\n if (index === 0) {\n await this._agentx.rpc(\"runtime.rewind\", {\n imageId: this._instanceId,\n messageId: messages[0].id,\n });\n } else {\n let msgIndex = -1;\n let convCount = 0;\n for (let i = 0; i < messages.length; i++) {\n if (messages[i].subtype === \"user\" || messages[i].subtype === \"assistant\") {\n convCount++;\n }\n if (convCount >= index) {\n msgIndex = i;\n break;\n }\n }\n if (msgIndex >= 0 && msgIndex < messages.length) {\n await this._agentx.rpc(\"runtime.rewind\", {\n imageId: this._instanceId,\n messageId: messages[msgIndex].id,\n });\n }\n }\n } catch (error) {\n console.error(\"Presentation rewind error:\", error);\n }\n }\n\n /** Dispose and cleanup all subscriptions */\n dispose(): void {\n if (this._eventUnsubscribe) {\n this._eventUnsubscribe();\n this._eventUnsubscribe = null;\n }\n this._listeners.clear();\n this._legacyHandlers.clear();\n }\n\n // ==================== Private ====================\n\n private _subscribeToEvents(): void {\n this._eventUnsubscribe = this._agentx.onAny((event: BusEvent) => {\n const eventWithContext = event as BusEvent & {\n context?: { instanceId?: string; imageId?: string };\n };\n const eventAgentId = eventWithContext.context?.instanceId;\n\n if (eventAgentId && eventAgentId !== this._instanceId) {\n const eventImageId = eventWithContext.context?.imageId;\n if (!eventImageId || eventImageId !== this._instanceId) {\n return;\n }\n }\n\n const newState = presentationReducer(this._state, event);\n if (newState !== this._state) {\n this._state = newState;\n this._notify();\n }\n });\n }\n\n private _notify(): void {\n // New API: bare listeners (for useSyncExternalStore)\n for (const listener of this._listeners) {\n try {\n listener();\n } catch (error) {\n console.error(\"Presentation listener error:\", error);\n }\n }\n // Legacy API: handlers that receive state\n for (const handler of this._legacyHandlers) {\n try {\n handler(this._state);\n } catch (error) {\n console.error(\"Presentation handler error:\", error);\n }\n }\n }\n}\n","/**\n * Presentation namespace factory\n *\n * Singleton per imageId — same imageId always returns the same Presentation.\n * First call creates from history, subsequent calls return existing instance.\n * Options (onUpdate, onError) are additive — new handlers are merged in.\n */\n\nimport { messagesToConversations, Presentation, type PresentationOptions } from \"../presentation\";\nimport type { PresentationWorkspace } from \"../presentation/types\";\nimport type { AgentX, PresentationNamespace, SessionNamespace } from \"../types\";\n\n/**\n * Workspace resolver — given an imageId, returns a PresentationWorkspace or null.\n * Provided by the client (local or remote) to decouple from runtime internals.\n */\nexport type WorkspaceResolver = (imageId: string) => Promise<PresentationWorkspace | null>;\n\nexport function createPresentations(\n agentx: AgentX,\n sessionNs: SessionNamespace,\n workspaceResolver?: WorkspaceResolver\n): PresentationNamespace {\n const instances = new Map<string, Presentation>();\n\n return {\n async create(imageId: string, options?: PresentationOptions): Promise<Presentation> {\n // Return existing singleton\n const existing = instances.get(imageId);\n if (existing) {\n // Merge new handlers if provided\n if (options?.onUpdate) existing.onUpdate(options.onUpdate);\n if (options?.onError) existing.onError(options.onError);\n return existing;\n }\n\n // Resolve workspace for this image\n const workspace = workspaceResolver ? await workspaceResolver(imageId) : null;\n\n // Create new from history\n const messages = await sessionNs.getMessages(imageId);\n const conversations = messagesToConversations(messages);\n const presentation = new Presentation(agentx, imageId, options, conversations, workspace);\n\n instances.set(imageId, presentation);\n\n // Clean up on dispose\n const originalDispose = presentation.dispose.bind(presentation);\n presentation.dispose = () => {\n instances.delete(imageId);\n originalDispose();\n };\n\n return presentation;\n },\n };\n}\n","/**\n * Session namespace factories (messaging)\n */\n\nimport type { Message, UserContentPart } from \"@agentxjs/core/agent\";\nimport type { SendOptions } from \"@agentxjs/core/driver\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport type { BaseResponse, MessageSendResponse, SessionNamespace } from \"../types\";\n\n/**\n * Create local session namespace backed by embedded runtime\n */\n/**\n * Resolve an imageId or instanceId to a running agent instanceId.\n * If no agent exists for this imageId, auto-creates one.\n */\nasync function resolveLocal(runtime: AgentXRuntime, id: string): Promise<string> {\n // Direct instanceId\n if (id.startsWith(\"inst_\")) {\n const agent = runtime.getAgent(id);\n if (agent) return id;\n }\n\n // imageId — find existing or auto-create\n const imageId = id.startsWith(\"img_\") ? id : id;\n const existing = runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n if (existing) return existing.instanceId;\n\n const agent = await runtime.createAgent({ imageId });\n return agent.instanceId;\n}\n\nexport function createLocalSessions(runtime: AgentXRuntime): SessionNamespace {\n return {\n async send(\n id: string,\n content: string | unknown[],\n options?: SendOptions\n ): Promise<MessageSendResponse> {\n const instanceId = await resolveLocal(runtime, id);\n await runtime.receive(instanceId, content as string | UserContentPart[], undefined, options);\n return { instanceId, requestId: \"\" };\n },\n\n async interrupt(id: string): Promise<BaseResponse> {\n const instanceId = await resolveLocal(runtime, id);\n runtime.interrupt(instanceId);\n return { requestId: \"\" };\n },\n\n async getMessages(id: string): Promise<Message[]> {\n // For imageId, get messages directly from session\n if (id.startsWith(\"img_\")) {\n const image = await runtime.platform.imageRepository.findImageById(id);\n if (!image) return [];\n return runtime.platform.sessionRepository.getMessages(image.sessionId);\n }\n const agent = runtime.getAgent(id);\n if (!agent) return [];\n return runtime.platform.sessionRepository.getMessages(agent.sessionId);\n },\n };\n}\n\n/**\n * Create remote session namespace backed by RPC client\n */\n/**\n * Detect whether an ID is an imageId or instanceId based on prefix.\n * imageId starts with \"img_\", instanceId starts with \"inst_\".\n */\nfunction resolveId(id: string): { imageId?: string; instanceId?: string } {\n if (id.startsWith(\"inst_\")) return { instanceId: id };\n return { imageId: id };\n}\n\nexport function createRemoteSessions(rpcClient: RpcClient): SessionNamespace {\n return {\n async send(\n id: string,\n content: string | unknown[],\n options?: SendOptions\n ): Promise<MessageSendResponse> {\n const result = await rpcClient.call<MessageSendResponse>(\"message.send\", {\n ...resolveId(id),\n content,\n options,\n });\n return { ...result, requestId: \"\" };\n },\n\n async interrupt(id: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"instance.interrupt\", {\n ...resolveId(id),\n });\n return { ...result, requestId: \"\" };\n },\n\n async getMessages(id: string): Promise<Message[]> {\n // For instanceId, resolve to imageId first\n if (id.startsWith(\"inst_\")) {\n const agentRes = await rpcClient.call<{ agent: { imageId: string } | null }>(\n \"instance.get\",\n { instanceId: id }\n );\n if (!agentRes.agent) return [];\n id = agentRes.agent.imageId;\n }\n const msgRes = await rpcClient.call<{ messages: Message[] }>(\"image.messages\", {\n imageId: id,\n });\n return msgRes.messages ?? [];\n },\n };\n}\n","/**\n * RemoteClient - AgentX client for remote server\n *\n * Uses RpcClient from @agentxjs/core/network for JSON-RPC communication.\n * This class focuses on business logic, not protocol details.\n */\n\nimport type { AgentXError } from \"@agentxjs/core/error\";\nimport type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from \"@agentxjs/core/event\";\nimport { EventBusImpl } from \"@agentxjs/core/event\";\nimport { RpcClient } from \"@agentxjs/core/network\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { AgentHandleImpl } from \"./AgentHandle\";\nimport { createRemoteImages } from \"./namespaces/images\";\nimport { createRemoteLLM } from \"./namespaces/llm\";\nimport { createPresentations } from \"./namespaces/presentations\";\nimport { createRemoteSessions } from \"./namespaces/sessions\";\nimport type {\n AgentX,\n ChatNamespace,\n LLMNamespace,\n RemoteClientConfig,\n RuntimeNamespace,\n} from \"./types\";\n\nconst logger = createLogger(\"agentx/RemoteClient\");\n\n/**\n * RemoteClient implementation using JSON-RPC 2.0\n */\nexport class RemoteClient implements AgentX {\n private readonly config: RemoteClientConfig;\n private readonly eventBus: EventBus;\n private readonly rpcClient: RpcClient;\n\n readonly chat: ChatNamespace;\n readonly runtime: RuntimeNamespace;\n readonly provider: LLMNamespace;\n\n constructor(config: RemoteClientConfig) {\n this.config = config;\n this.eventBus = new EventBusImpl();\n\n // Create RPC client (WebSocket factory from platform if available)\n this.rpcClient = new RpcClient({\n url: config.serverUrl,\n createWebSocket: config.customPlatform?.channelClient,\n timeout: config.timeout ?? 30000,\n autoReconnect: config.autoReconnect ?? true,\n headers: config.headers as Record<string, string> | undefined,\n debug: false,\n });\n\n // Forward stream events to internal event bus\n this.rpcClient.onStreamEvent((topic, event) => {\n logger.debug(\"Received stream event\", { topic, type: event.type });\n this.eventBus.emit(event as BusEvent);\n });\n\n // Forward connection state changes to event bus\n this.rpcClient.onStateChange((state) => {\n this.eventBus.emit({\n type: \"connection_state\",\n timestamp: Date.now(),\n data: { state },\n } as BusEvent);\n });\n\n // Assemble namespaces\n const image = createRemoteImages(this.rpcClient);\n const session = createRemoteSessions(this.rpcClient);\n const llm = createRemoteLLM(this.rpcClient);\n // Workspace resolver via RPC — server handles workspace access\n const workspaceResolver = async (imageId: string) => {\n const rpc = this.rpcClient;\n return {\n read: async (path: string) => {\n const res = await rpc.call<{ content: string }>(\"workspace.read\", { imageId, path });\n return res.content;\n },\n write: async (path: string, content: string) => {\n await rpc.call(\"workspace.write\", { imageId, path, content });\n },\n list: async (path?: string) => {\n const res = await rpc.call<{\n files: Array<{ name: string; path: string; type: \"file\" | \"directory\" }>;\n }>(\"workspace.list\", { imageId, path });\n return res.files;\n },\n };\n };\n const present = createPresentations(this, session, workspaceResolver);\n\n this.runtime = { image, session, present, llm };\n this.provider = llm;\n this.chat = this.createChatNamespace();\n }\n\n // ==================== Properties ====================\n\n get connected(): boolean {\n return this.rpcClient.connected;\n }\n\n get events(): EventBus {\n return this.eventBus;\n }\n\n // ==================== Connection ====================\n\n async connect(): Promise<void> {\n await this.rpcClient.connect();\n logger.info(\"Connected to server\", { url: this.config.serverUrl });\n }\n\n async disconnect(): Promise<void> {\n this.rpcClient.disconnect();\n logger.info(\"Disconnected from server\");\n }\n\n async dispose(): Promise<void> {\n this.rpcClient.dispose();\n this.eventBus.destroy();\n logger.info(\"RemoteClient disposed\");\n }\n\n // ==================== Event Subscription ====================\n\n on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {\n return this.eventBus.on(type, handler);\n }\n\n onAny(handler: BusEventHandler): Unsubscribe {\n return this.eventBus.onAny(handler);\n }\n\n // ==================== Error Handling ====================\n\n onError(handler: (error: AgentXError) => void): Unsubscribe {\n return this.eventBus.on(\"agentx_error\", (event) => {\n handler(event.data as AgentXError);\n });\n }\n\n // ==================== RPC ====================\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n return this.rpcClient.call<T>(method, params);\n }\n\n // ==================== Private ====================\n\n private createChatNamespace(): ChatNamespace {\n const rt = this.runtime;\n return {\n async create(params) {\n const imgRes = await rt.image.create(params);\n const runRes = await rt.image.run(imgRes.record.imageId);\n return new AgentHandleImpl(\n {\n instanceId: runRes.instanceId,\n imageId: runRes.imageId,\n containerId: runRes.containerId,\n sessionId: runRes.sessionId,\n },\n rt\n );\n },\n async list() {\n return rt.image.list();\n },\n async get(id) {\n const res = await rt.image.get(id);\n if (!res.record) return null;\n const runRes = await rt.image.run(res.record.imageId);\n return new AgentHandleImpl(\n {\n instanceId: runRes.instanceId,\n imageId: runRes.imageId,\n containerId: runRes.containerId,\n sessionId: runRes.sessionId,\n },\n rt\n );\n },\n };\n }\n}\n"],"mappings":"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","names":["createLogger","DEFAULT_CONTAINER_ID","agent","createLogger","logger","createLogger","createLogger"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/LocalClient.ts","../src/AgentHandle.ts","../src/namespaces/images.ts","../src/namespaces/llm.ts","../src/presentation/types.ts","../src/presentation/reducer.ts","../src/presentation/Presentation.ts","../src/namespaces/presentations.ts","../src/namespaces/sessions.ts","../src/RemoteClient.ts"],"sourcesContent":["/**\n * agentxjs - AgentX Client SDK\n *\n * Fluent API supporting local, remote, and server modes.\n *\n * @example Local mode\n * ```typescript\n * import { createAgentX } from \"agentxjs\";\n * import { nodePlatform } from \"@agentxjs/node-platform\";\n *\n * const ax = createAgentX(nodePlatform({ createDriver }));\n * const agent = await ax.chat.create({ name: \"Aristotle\", model: \"claude-sonnet-4-6\" });\n * await agent.send(\"Hello!\");\n * ```\n *\n * @example Remote mode\n * ```typescript\n * const ax = createAgentX();\n * const client = await ax.connect(\"ws://localhost:5200\");\n * ```\n *\n * @example Server mode\n * ```typescript\n * const ax = createAgentX(nodePlatform({ createDriver }));\n * const server = await ax.serve({ port: 5200 });\n * ```\n */\n\nimport type { CreateDriver } from \"@agentxjs/core/driver\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport { createAgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { LocalClient } from \"./LocalClient\";\nimport { RemoteClient } from \"./RemoteClient\";\nimport type { AgentX, AgentXBuilder, AgentXServer, ConnectOptions, ServeConfig } from \"./types\";\n\nconst poolLogger = createLogger(\"agentx/connection-pool\");\n\n// ============================================================================\n// Connection Pool — module-level singleton for WebSocket connection reuse\n//\n// Solves React 18+ Strict Mode double-mount:\n// mount → connect (refCount=1) → unmount → dispose (refCount=0, deferred)\n// → re-mount → connect (reuse, refCount=1)\n// ============================================================================\n\ninterface PoolEntry {\n client: RemoteClient;\n refCount: number;\n}\n\nconst connectionPool = new Map<string, PoolEntry>();\n\nfunction pooledConnect(serverUrl: string, factory: () => Promise<RemoteClient>): Promise<AgentX> {\n const existing = connectionPool.get(serverUrl);\n if (existing && existing.client.connected) {\n existing.refCount++;\n poolLogger.debug(\"Connection reused\", { serverUrl, refCount: existing.refCount });\n return Promise.resolve(wrapWithRefCount(serverUrl, existing));\n }\n\n return factory().then((client) => {\n const entry: PoolEntry = { client, refCount: 1 };\n connectionPool.set(serverUrl, entry);\n poolLogger.debug(\"Connection created\", { serverUrl });\n return wrapWithRefCount(serverUrl, entry);\n });\n}\n\nfunction wrapWithRefCount(serverUrl: string, entry: PoolEntry): AgentX {\n const client = entry.client;\n const originalDispose = client.dispose.bind(client);\n const originalDisconnect = client.disconnect.bind(client);\n\n // Override dispose — only truly dispose when refCount reaches 0\n client.dispose = async () => {\n entry.refCount--;\n poolLogger.debug(\"Connection released\", { serverUrl, refCount: entry.refCount });\n if (entry.refCount <= 0) {\n connectionPool.delete(serverUrl);\n await originalDispose();\n }\n };\n\n // disconnect follows same refCount logic\n client.disconnect = async () => {\n entry.refCount--;\n if (entry.refCount <= 0) {\n connectionPool.delete(serverUrl);\n await originalDisconnect();\n }\n };\n\n return client;\n}\n\n/**\n * Platform configuration for createAgentX\n */\nexport interface PlatformConfig {\n platform: AgentXPlatform;\n createDriver: CreateDriver;\n}\n\n/**\n * Create an AgentX builder\n *\n * @param config - Platform configuration (optional). Without it, only connect() is available.\n * @returns AgentXBuilder — local AgentX + connect() + serve()\n */\nexport function createAgentX(config?: PlatformConfig): AgentXBuilder {\n let localClient: LocalClient | null = null;\n\n function getLocalClient(): LocalClient {\n if (localClient) return localClient;\n if (!config) {\n throw new Error(\n \"Local mode requires a platform. Pass a PlatformConfig to createAgentX(), or use connect() for remote mode.\"\n );\n }\n const runtime = createAgentXRuntime(config.platform, config.createDriver);\n localClient = new LocalClient(runtime);\n return localClient;\n }\n\n if (config) {\n getLocalClient();\n }\n\n return {\n get connected() {\n return localClient?.connected ?? false;\n },\n\n get events() {\n return getLocalClient().events;\n },\n\n get runtime() {\n return getLocalClient().runtime;\n },\n\n get provider() {\n return getLocalClient().provider;\n },\n\n get chat() {\n return getLocalClient().chat;\n },\n\n on(type, handler) {\n return getLocalClient().on(type, handler);\n },\n\n onAny(handler) {\n return getLocalClient().onAny(handler);\n },\n\n onError(handler) {\n return getLocalClient().onError(handler);\n },\n\n async disconnect() {\n await localClient?.disconnect();\n },\n\n async dispose() {\n await localClient?.dispose();\n localClient = null;\n },\n\n async connect(serverUrl: string, options?: ConnectOptions): Promise<AgentX> {\n return pooledConnect(serverUrl, async () => {\n const remoteClient = new RemoteClient({\n serverUrl,\n headers: options?.headers as Record<string, string> | undefined,\n context: options?.context,\n timeout: options?.timeout,\n autoReconnect: options?.autoReconnect,\n customPlatform: config?.platform,\n });\n await remoteClient.connect();\n return remoteClient;\n });\n },\n\n async serve(serveConfig?: ServeConfig): Promise<AgentXServer> {\n if (!config) {\n throw new Error(\"serve() requires a platform. Pass a PlatformConfig to createAgentX().\");\n }\n if (!config.platform.channelServer) {\n throw new Error(\n \"serve() requires platform.channelServer. Ensure your platform supports server mode.\"\n );\n }\n\n const { createServer } = await import(\"./server\");\n return createServer({\n platform: config.platform,\n createDriver: config.createDriver,\n port: serveConfig?.port,\n host: serveConfig?.host,\n server: serveConfig?.server as any,\n wsPath: serveConfig?.wsPath,\n });\n },\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n return getLocalClient().rpc<T>(method, params);\n },\n };\n}\n\n// Re-export context interfaces\nexport type { Capability, Context, ContextProvider } from \"@agentxjs/core/context\";\n// Re-export driver types\nexport type { SendOptions } from \"@agentxjs/core/driver\";\n// Re-export error types\nexport type { AgentXErrorCategory, AgentXErrorContext } from \"@agentxjs/core/error\";\nexport { AgentXError, AgentXErrorCode } from \"@agentxjs/core/error\";\n// Re-export Presentation\nexport type {\n AssistantConversation,\n Block,\n Conversation,\n ErrorConversation,\n FileBlock,\n FileTreeEntry,\n ImageBlock,\n OS,\n OSState,\n PresentationMetrics,\n PresentationOptions,\n PresentationOS,\n PresentationState,\n TextBlock,\n ThinkingBlock,\n ToolBlock,\n UserConversation,\n} from \"./presentation\";\nexport {\n addUserConversation,\n createInitialState,\n initialMetrics,\n initialPresentationState,\n messagesToConversations,\n Presentation,\n presentationReducer,\n} from \"./presentation\";\n// Re-export types\nexport type {\n AgentConfig,\n AgentHandle,\n AgentX,\n AgentXBuilder,\n AgentXServer,\n BaseResponse,\n ChatNamespace,\n ConnectOptions,\n ImageCreateResponse,\n ImageGetResponse,\n ImageListResponse,\n ImageNamespace,\n ImageRecord,\n ImageUpdateResponse,\n InstanceCreateResponse,\n InstanceGetResponse,\n InstanceInfo,\n InstanceListResponse,\n LLMNamespace,\n LLMProviderCreateResponse,\n LLMProviderDefaultResponse,\n LLMProviderGetResponse,\n LLMProviderListResponse,\n LLMProviderUpdateResponse,\n MaybeAsync,\n MessageSendResponse,\n PresentationNamespace,\n RuntimeNamespace,\n ServeConfig,\n SessionNamespace,\n} from \"./types\";\n","/**\n * LocalClient - AgentX client for local mode\n *\n * Runs an embedded Runtime + Driver directly, without WebSocket.\n * Implements the same AgentX interface as RemoteClient.\n */\n\nimport type { AgentXError } from \"@agentxjs/core/error\";\nimport type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from \"@agentxjs/core/event\";\n\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { AgentHandleImpl } from \"./AgentHandle\";\nimport { registerAll } from \"./handlers\";\nimport { createLocalImages } from \"./namespaces/images\";\nimport { createLocalLLM } from \"./namespaces/llm\";\nimport { createPresentations } from \"./namespaces/presentations\";\nimport { createLocalSessions } from \"./namespaces/sessions\";\nimport { RpcHandlerRegistry } from \"./RpcHandlerRegistry\";\nimport type { AgentX, ChatNamespace, LLMNamespace, RuntimeNamespace } from \"./types\";\n\nconst logger = createLogger(\"agentx/LocalClient\");\n\n/**\n * LocalClient - Embedded runtime implementation\n */\nexport class LocalClient implements AgentX {\n private readonly _runtime: AgentXRuntime;\n private registry: RpcHandlerRegistry | null = null;\n private isDisposed = false;\n\n readonly chat: ChatNamespace;\n readonly runtime: RuntimeNamespace;\n readonly provider: LLMNamespace;\n\n constructor(agentxRuntime: AgentXRuntime) {\n this._runtime = agentxRuntime;\n const platform = agentxRuntime.platform;\n\n const image = createLocalImages(platform, agentxRuntime);\n const session = createLocalSessions(agentxRuntime);\n const llm = createLocalLLM(platform);\n // OS resolver: imageId → PresentationOS (via AgentOS)\n const osResolver = async (imageId: string) => {\n const op = platform.osProvider;\n if (!op) return null;\n const img = await platform.imageRepository.findImageById(imageId);\n if (!img?.osId) return null;\n const os = await op.create(img.osId);\n return {\n read: (path: string) => os.fs.read(path),\n write: (path: string, content: string) => os.fs.write(path, content),\n list: async (path?: string) => {\n const entries = await os.fs.list(path);\n return entries.map((e) => ({ name: e.name, path: e.path, type: e.type }));\n },\n };\n };\n const present = createPresentations(this, session, osResolver);\n\n this.runtime = { image, session, present, llm };\n this.provider = llm;\n this.chat = this.createChatNamespace();\n\n logger.info(\"LocalClient initialized\");\n }\n\n // ==================== Properties ====================\n\n get connected(): boolean {\n return !this.isDisposed;\n }\n\n get events(): EventBus {\n return this._runtime.platform.eventBus;\n }\n\n // ==================== Event Subscription ====================\n\n on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {\n return this._runtime.platform.eventBus.on(type, handler);\n }\n\n onAny(handler: BusEventHandler): Unsubscribe {\n return this._runtime.platform.eventBus.onAny(handler);\n }\n\n // ==================== Error Handling ====================\n\n onError(handler: (error: AgentXError) => void): Unsubscribe {\n return this._runtime.platform.eventBus.on(\"agentx_error\", (event) => {\n handler(event.data as AgentXError);\n });\n }\n\n // ==================== RPC ====================\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n if (!this.registry) {\n this.registry = new RpcHandlerRegistry();\n registerAll(this.registry);\n }\n const result = await this.registry.handle(this._runtime, method, params);\n if (result.success) {\n return result.data as T;\n }\n throw new Error(result.message);\n }\n\n // ==================== Private ====================\n\n private createChatNamespace(): ChatNamespace {\n const rt = this.runtime;\n return {\n async create(params) {\n const imgRes = await rt.image.create(params);\n const runRes = await rt.image.run(imgRes.record.imageId);\n return new AgentHandleImpl(\n {\n instanceId: runRes.instanceId,\n imageId: runRes.imageId,\n containerId: runRes.containerId,\n sessionId: runRes.sessionId,\n },\n rt\n );\n },\n async list() {\n return rt.image.list();\n },\n async get(id) {\n const res = await rt.image.get(id);\n if (!res.record) return null;\n const runRes = await rt.image.run(res.record.imageId);\n return new AgentHandleImpl(\n {\n instanceId: runRes.instanceId,\n imageId: runRes.imageId,\n containerId: runRes.containerId,\n sessionId: runRes.sessionId,\n },\n rt\n );\n },\n };\n }\n\n // ==================== Lifecycle ====================\n\n async disconnect(): Promise<void> {\n // No-op for local mode\n }\n\n async dispose(): Promise<void> {\n if (this.isDisposed) return;\n await this._runtime.shutdown();\n this.isDisposed = true;\n logger.info(\"LocalClient disposed\");\n }\n}\n","/**\n * AgentHandle — live reference to a created agent.\n *\n * Wraps identity (IDs) + delegates operations to instance namespaces.\n */\n\nimport type { Message } from \"@agentxjs/core/agent\";\nimport type { SendOptions } from \"@agentxjs/core/driver\";\nimport type { Presentation, PresentationOptions } from \"./presentation\";\nimport type {\n AgentConfig,\n AgentHandle,\n BaseResponse,\n MessageSendResponse,\n RuntimeNamespace,\n} from \"./types\";\n\nexport class AgentHandleImpl implements AgentHandle {\n readonly instanceId: string;\n readonly imageId: string;\n readonly containerId: string;\n readonly sessionId: string;\n\n private readonly ns: RuntimeNamespace;\n\n constructor(\n ids: { instanceId: string; imageId: string; containerId: string; sessionId: string },\n ns: RuntimeNamespace\n ) {\n this.instanceId = ids.instanceId;\n this.imageId = ids.imageId;\n this.containerId = ids.containerId;\n this.sessionId = ids.sessionId;\n this.ns = ns;\n }\n\n async send(content: string | unknown[], options?: SendOptions): Promise<MessageSendResponse> {\n return this.ns.session.send(this.instanceId, content, options);\n }\n\n async interrupt(): Promise<BaseResponse> {\n return this.ns.session.interrupt(this.instanceId);\n }\n\n async history(): Promise<Message[]> {\n return this.ns.image.getMessages(this.imageId);\n }\n\n async present(options?: PresentationOptions): Promise<Presentation> {\n return this.ns.present.create(this.instanceId, options);\n }\n\n async update(\n updates: Partial<\n Pick<\n AgentConfig,\n \"name\" | \"description\" | \"model\" | \"systemPrompt\" | \"mcpServers\" | \"customData\"\n >\n >\n ): Promise<void> {\n await this.ns.image.update(this.imageId, updates);\n }\n\n async delete(): Promise<void> {\n await this.ns.image.stop(this.imageId);\n await this.ns.image.delete(this.imageId);\n }\n}\n","/**\n * Image namespace factories\n */\n\nimport type { Message } from \"@agentxjs/core/agent\";\nimport { DEFAULT_CONTAINER_ID } from \"@agentxjs/core/container\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXPlatform, AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport type {\n AgentConfig,\n BaseResponse,\n ImageCreateResponse,\n ImageGetResponse,\n ImageListResponse,\n ImageNamespace,\n ImageUpdateResponse,\n InstanceCreateResponse,\n} from \"../types\";\n\n/**\n * Create local image namespace backed by embedded runtime\n */\nexport function createLocalImages(\n platform: AgentXPlatform,\n runtime?: AgentXRuntime\n): ImageNamespace {\n return {\n async create(params: AgentConfig): Promise<ImageCreateResponse> {\n const { imageRepository, sessionRepository } = platform;\n const { createImage } = await import(\"@agentxjs/core/image\");\n\n const image = await createImage(\n {\n containerId: DEFAULT_CONTAINER_ID,\n ...params,\n mcpServers: params.mcpServers as any,\n thinking: params.thinking,\n },\n { imageRepository, sessionRepository }\n );\n\n return {\n record: image.toRecord(),\n requestId: \"\",\n };\n },\n\n async get(imageId: string): Promise<ImageGetResponse> {\n const record = await platform.imageRepository.findImageById(imageId);\n return {\n record,\n requestId: \"\",\n };\n },\n\n async list(): Promise<ImageListResponse> {\n const records = await platform.imageRepository.findAllImages();\n\n return {\n records,\n requestId: \"\",\n };\n },\n\n async update(\n imageId: string,\n updates: {\n name?: string;\n description?: string;\n customData?: Record<string, unknown>;\n }\n ): Promise<ImageUpdateResponse> {\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (!image) {\n throw new Error(`Image not found: ${imageId}`);\n }\n\n const updated = await image.update(updates);\n return { record: updated.toRecord(), requestId: \"\" };\n },\n\n async delete(imageId: string): Promise<BaseResponse> {\n const { loadImage } = await import(\"@agentxjs/core/image\");\n const { imageRepository, sessionRepository } = platform;\n\n const image = await loadImage(imageId, { imageRepository, sessionRepository });\n if (image) {\n await image.delete();\n }\n\n return { requestId: \"\" };\n },\n\n async getMessages(imageId: string): Promise<Message[]> {\n const imageRecord = await platform.imageRepository.findImageById(imageId);\n if (!imageRecord) return [];\n return platform.sessionRepository.getMessages(imageRecord.sessionId);\n },\n\n async run(imageId: string): Promise<InstanceCreateResponse> {\n if (!runtime) throw new Error(\"Runtime not available\");\n const existing = runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n if (existing) {\n return {\n instanceId: existing.instanceId,\n imageId: existing.imageId,\n containerId: existing.containerId,\n sessionId: existing.sessionId,\n requestId: \"\",\n };\n }\n const agent = await runtime.createAgent({ imageId });\n return {\n instanceId: agent.instanceId,\n imageId: agent.imageId,\n containerId: agent.containerId,\n sessionId: agent.sessionId,\n requestId: \"\",\n };\n },\n\n async stop(imageId: string): Promise<BaseResponse> {\n if (!runtime) throw new Error(\"Runtime not available\");\n const agent = runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n if (agent) await runtime.stopAgent(agent.instanceId);\n return { requestId: \"\" };\n },\n };\n}\n\n/**\n * Create remote image namespace backed by RPC client\n */\nexport function createRemoteImages(rpcClient: RpcClient): ImageNamespace {\n return {\n async create(params: AgentConfig): Promise<ImageCreateResponse> {\n const result = await rpcClient.call<ImageCreateResponse>(\"image.create\", {\n ...params,\n containerId: DEFAULT_CONTAINER_ID,\n });\n return { ...result, requestId: \"\" };\n },\n\n async get(imageId: string): Promise<ImageGetResponse> {\n const result = await rpcClient.call<ImageGetResponse>(\"image.get\", { imageId });\n return { ...result, requestId: \"\" };\n },\n\n async list(): Promise<ImageListResponse> {\n const result = await rpcClient.call<ImageListResponse>(\"image.list\", {});\n return { ...result, requestId: \"\" };\n },\n\n async update(\n imageId: string,\n updates: {\n name?: string;\n description?: string;\n customData?: Record<string, unknown>;\n }\n ): Promise<ImageUpdateResponse> {\n const result = await rpcClient.call<ImageUpdateResponse>(\"image.update\", {\n imageId,\n updates,\n });\n return { ...result, requestId: \"\" };\n },\n\n async delete(imageId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"image.delete\", { imageId });\n return { ...result, requestId: \"\" };\n },\n\n async getMessages(imageId: string): Promise<Message[]> {\n const result = await rpcClient.call<{ messages: Message[] }>(\"image.messages\", { imageId });\n return result.messages ?? [];\n },\n\n async run(imageId: string): Promise<InstanceCreateResponse> {\n const result = await rpcClient.call<InstanceCreateResponse>(\"image.run\", { imageId });\n return { ...result, requestId: \"\" };\n },\n\n async stop(imageId: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"image.stop\", { imageId });\n return { ...result, requestId: \"\" };\n },\n };\n}\n","/**\n * LLM Provider namespace factories\n */\n\nimport { DEFAULT_CONTAINER_ID } from \"@agentxjs/core/container\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { LLMProviderRecord } from \"@agentxjs/core/persistence\";\nimport type { AgentXPlatform } from \"@agentxjs/core/runtime\";\nimport { generateId } from \"@deepracticex/id\";\nimport type {\n BaseResponse,\n LLMNamespace,\n LLMProviderCreateResponse,\n LLMProviderDefaultResponse,\n LLMProviderGetResponse,\n LLMProviderListResponse,\n LLMProviderUpdateResponse,\n} from \"../types\";\n\n/**\n * Create local LLM namespace backed by platform repository\n */\nexport function createLocalLLM(platform: AgentXPlatform): LLMNamespace {\n const repo = platform.llmProviderRepository;\n if (!repo) {\n throw new Error(\"LLM provider repository not available on this platform\");\n }\n\n return {\n async create(params): Promise<LLMProviderCreateResponse> {\n const now = Date.now();\n const record: LLMProviderRecord = {\n id: generateId(\"llm\"),\n containerId: DEFAULT_CONTAINER_ID,\n name: params.name,\n vendor: params.vendor,\n protocol: params.protocol,\n apiKey: params.apiKey,\n baseUrl: params.baseUrl,\n model: params.model,\n isDefault: false,\n createdAt: now,\n updatedAt: now,\n };\n\n await repo.saveLLMProvider(record);\n return { record, requestId: \"\" };\n },\n\n async get(id: string): Promise<LLMProviderGetResponse> {\n const record = await repo.findLLMProviderById(id);\n return { record, requestId: \"\" };\n },\n\n async list(): Promise<LLMProviderListResponse> {\n const records = await repo.findLLMProvidersByContainerId(DEFAULT_CONTAINER_ID);\n return { records, requestId: \"\" };\n },\n\n async update(id, updates): Promise<LLMProviderUpdateResponse> {\n const existing = await repo.findLLMProviderById(id);\n if (!existing) {\n throw new Error(`LLM provider not found: ${id}`);\n }\n\n const updated: LLMProviderRecord = {\n ...existing,\n ...updates,\n id: existing.id,\n containerId: existing.containerId,\n createdAt: existing.createdAt,\n updatedAt: Date.now(),\n };\n\n await repo.saveLLMProvider(updated);\n return { record: updated, requestId: \"\" };\n },\n\n async delete(id: string): Promise<BaseResponse> {\n await repo.deleteLLMProvider(id);\n return { requestId: \"\" };\n },\n\n async setDefault(id: string): Promise<BaseResponse> {\n await repo.setDefaultLLMProvider(id);\n return { requestId: \"\" };\n },\n\n async getDefault(): Promise<LLMProviderDefaultResponse> {\n const record = await repo.findDefaultLLMProvider(DEFAULT_CONTAINER_ID);\n return { record, requestId: \"\" };\n },\n };\n}\n\n/**\n * Create remote LLM namespace backed by RPC client\n */\nexport function createRemoteLLM(rpcClient: RpcClient): LLMNamespace {\n return {\n async create(params): Promise<LLMProviderCreateResponse> {\n const result = await rpcClient.call<LLMProviderCreateResponse>(\"llm.create\", {\n ...params,\n containerId: DEFAULT_CONTAINER_ID,\n });\n return { ...result, requestId: \"\" };\n },\n\n async get(id: string): Promise<LLMProviderGetResponse> {\n const result = await rpcClient.call<LLMProviderGetResponse>(\"llm.get\", { id });\n return { ...result, requestId: \"\" };\n },\n\n async list(): Promise<LLMProviderListResponse> {\n const result = await rpcClient.call<LLMProviderListResponse>(\"llm.list\", {\n containerId: DEFAULT_CONTAINER_ID,\n });\n return { ...result, requestId: \"\" };\n },\n\n async update(id, updates): Promise<LLMProviderUpdateResponse> {\n const result = await rpcClient.call<LLMProviderUpdateResponse>(\"llm.update\", {\n id,\n updates,\n });\n return { ...result, requestId: \"\" };\n },\n\n async delete(id: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"llm.delete\", { id });\n return { ...result, requestId: \"\" };\n },\n\n async setDefault(id: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"llm.default\", { id });\n return { ...result, requestId: \"\" };\n },\n\n async getDefault(): Promise<LLMProviderDefaultResponse> {\n const result = await rpcClient.call<LLMProviderDefaultResponse>(\"llm.default\", {\n containerId: DEFAULT_CONTAINER_ID,\n });\n return { ...result, requestId: \"\" };\n },\n };\n}\n","/**\n * Presentation Types\n *\n * UI-friendly data model aggregated from stream events.\n * This implements the Presentation Model pattern.\n */\n\n// ============================================================================\n// Block Types - Basic content units\n// ============================================================================\n\n/**\n * Text block\n */\nexport interface TextBlock {\n type: \"text\";\n content: string;\n}\n\n/**\n * Tool block - represents a tool call and its result\n */\nexport interface ToolBlock {\n type: \"tool\";\n toolUseId: string;\n toolName: string;\n toolInput: Record<string, unknown>;\n toolResult?: string;\n /** Partial JSON input being streamed (visible during input-streaming phase) */\n partialInput?: string;\n status: \"pending\" | \"running\" | \"completed\" | \"error\" | \"interrupted\";\n}\n\n/**\n * Image block\n */\nexport interface ImageBlock {\n type: \"image\";\n url: string;\n alt?: string;\n}\n\n/**\n * File block\n */\nexport interface FileBlock {\n type: \"file\";\n filename: string;\n mediaType: string;\n}\n\n/**\n * Thinking/reasoning block — AI's internal reasoning process\n */\nexport interface ThinkingBlock {\n type: \"thinking\";\n content: string;\n}\n\n/**\n * All block types\n */\nexport type Block = TextBlock | ToolBlock | ImageBlock | FileBlock | ThinkingBlock;\n\n// ============================================================================\n// Conversation Types - A single turn in the conversation\n// ============================================================================\n\n/**\n * User conversation\n */\nexport interface UserConversation {\n role: \"user\";\n blocks: Block[];\n}\n\n/**\n * Token usage for a message (one LLM call / step)\n */\nexport interface TokenUsage {\n inputTokens: number;\n outputTokens: number;\n}\n\n/**\n * Assistant conversation\n */\nexport interface AssistantConversation {\n role: \"assistant\";\n blocks: Block[];\n isStreaming: boolean;\n /** Accumulated token usage across all steps in this conversation */\n usage?: TokenUsage;\n}\n\n/**\n * Error conversation\n */\nexport interface ErrorConversation {\n role: \"error\";\n message: string;\n}\n\n/**\n * All conversation types\n */\nexport type Conversation = UserConversation | AssistantConversation | ErrorConversation;\n\n// ============================================================================\n// Presentation Metrics\n// ============================================================================\n\n/**\n * Turn-level metrics.\n * Reset at the start of each turn, preserved after turn ends.\n */\nexport interface TurnMetrics {\n /** Timestamp when the current turn started (null when idle before first turn) */\n turnStartedAt: number | null;\n /** Input tokens consumed in the current turn */\n inputTokens: number;\n /** Output tokens generated in the current turn */\n outputTokens: number;\n}\n\n/**\n * Session-level context metrics.\n * Tracks the overall context window usage across the entire session.\n */\nexport interface SessionMetrics {\n /** Current context size in tokens (last inputTokens from LLM — includes full history) */\n contextTokens: number;\n /** Model's context window limit (0 = unknown) */\n contextLimit: number;\n /** Context usage ratio 0-1 (0 when limit unknown) */\n contextUsage: number;\n}\n\n/**\n * Combined presentation metrics — turn + session level.\n */\nexport interface PresentationMetrics extends TurnMetrics {\n /** Session-level context window metrics */\n session: SessionMetrics;\n}\n\n// ============================================================================\n// Workspace State\n// ============================================================================\n\n/**\n * File tree entry — recursive structure for rendering directory tree\n */\nexport interface FileTreeEntry {\n /** File or directory name */\n name: string;\n /** Path relative to workspace root */\n path: string;\n /** File or directory */\n type: \"file\" | \"directory\";\n /** Children (only for directories) */\n children?: FileTreeEntry[];\n}\n\n/**\n * OS state — real-time file tree view\n */\nexport interface OSState {\n /**\n * Current file tree (recursive).\n * Frontend just renders this tree directly.\n */\n files: FileTreeEntry[];\n}\n\n// ============================================================================\n// Presentation OS Operations\n// ============================================================================\n\n/**\n * PresentationOS — file operations exposed to the consumer.\n * Wraps the underlying AgentOS with a simple API.\n */\nexport interface PresentationOS {\n /** Read file content */\n read(path: string): Promise<string>;\n /** Write content to a file */\n write(path: string, content: string): Promise<void>;\n /** List directory entries */\n list(path?: string): Promise<FileTreeEntry[]>;\n}\n\n// ============================================================================\n// Presentation State\n// ============================================================================\n\n/**\n * Connection state\n */\nexport type ConnectionState = \"connected\" | \"connecting\" | \"disconnected\";\n\n/**\n * Presentation state - the complete UI state\n */\nexport interface PresentationState {\n /**\n * All conversations including the currently streaming one.\n * The streaming conversation is the last item with `isStreaming: true`.\n * Frontend just does `conversations.map(...)` — no merging needed.\n */\n conversations: Conversation[];\n\n /**\n * Current agent status\n *\n * - idle: No active request\n * - submitted: Message sent, waiting for first token\n * - thinking: LLM outputting thinking/reasoning content\n * - responding: LLM outputting text content\n * - executing: Tool call in progress\n */\n status: \"idle\" | \"submitted\" | \"thinking\" | \"responding\" | \"executing\";\n\n /**\n * WebSocket connection state\n */\n connection: ConnectionState;\n\n /**\n * Real-time metrics for the current turn\n */\n metrics: PresentationMetrics;\n\n /**\n * OS state — real-time file tree.\n * null when agent has no OS.\n */\n os: OSState | null;\n}\n\n/**\n * Initial presentation metrics\n */\nexport const initialSessionMetrics: SessionMetrics = {\n contextTokens: 0,\n contextLimit: 0,\n contextUsage: 0,\n};\n\nexport const initialMetrics: PresentationMetrics = {\n turnStartedAt: null,\n inputTokens: 0,\n outputTokens: 0,\n session: initialSessionMetrics,\n};\n\n/**\n * Initial presentation state\n */\nexport const initialPresentationState: PresentationState = {\n conversations: [],\n status: \"idle\",\n connection: \"connected\",\n metrics: initialMetrics,\n os: null,\n};\n","/**\n * Presentation Reducer\n *\n * Aggregates events into PresentationState.\n * Pure function: (state, event) => newState\n *\n * Event consumption strategy:\n * - Stream layer: message_start, text_delta, tool_use_start, tool_use_stop, message_stop\n * (for real-time streaming display)\n * - Message layer: tool_result_message\n * (for tool execution results — arrives after message_stop)\n *\n * Tool calls are stream-level blocks within the assistant turn,\n * matching the mainstream API pattern (Anthropic, OpenAI).\n */\n\nimport type {\n AssistantMessage,\n ErrorMessage,\n Message,\n ToolCallPart,\n ToolResultMessage,\n ToolResultOutput,\n UserContentPart,\n UserMessage,\n} from \"@agentxjs/core/agent\";\nimport type { BusEvent } from \"@agentxjs/core/event\";\nimport type {\n AssistantConversation,\n Block,\n ConnectionState,\n Conversation,\n FileTreeEntry,\n PresentationState,\n TextBlock,\n TokenUsage,\n ToolBlock,\n} from \"./types\";\nimport { initialMetrics, initialPresentationState } from \"./types\";\n\n// ============================================================================\n// Event Data Types\n// ============================================================================\n\ninterface MessageStartData {\n messageId?: string;\n model?: string;\n}\n\ninterface TextDeltaData {\n text: string;\n}\n\ninterface ToolUseStartData {\n toolCallId: string;\n toolName: string;\n}\n\ninterface ToolUseStopData {\n toolCallId: string;\n toolName: string;\n input: Record<string, unknown>;\n}\n\ninterface MessageDeltaData {\n usage?: {\n inputTokens: number;\n outputTokens: number;\n };\n}\n\ninterface MessageStopData {\n stopReason?: string;\n}\n\ninterface ErrorData {\n message: string;\n code?: string;\n}\n\n// ============================================================================\n// Reducer\n// ============================================================================\n\n/**\n * Reduce an event into presentation state.\n *\n * Consumes:\n * - Stream events: message_start, text_delta, tool_use_start, tool_use_stop, message_stop\n * - Message events: tool_result_message\n * - Error events: error\n */\nexport function presentationReducer(state: PresentationState, event: BusEvent): PresentationState {\n switch (event.type) {\n // Stream layer — real-time display\n case \"message_start\":\n return handleMessageStart(state, event.data as MessageStartData);\n\n case \"thinking_delta\":\n return handleThinkingDelta(state, event.data as TextDeltaData);\n\n case \"text_delta\":\n return handleTextDelta(state, event.data as TextDeltaData);\n\n case \"tool_use_start\":\n return handleToolUseStart(state, event.data as ToolUseStartData);\n\n case \"tool_use_stop\":\n return handleToolUseStop(state, event.data as ToolUseStopData);\n\n case \"input_json_delta\":\n return handleInputJsonDelta(state, event.data as { partialJson: string });\n\n case \"message_delta\":\n return handleMessageDelta(state, event.data as MessageDeltaData);\n\n case \"message_stop\":\n return handleMessageStop(state, event.data as MessageStopData);\n\n // Message layer — tool results from Engine\n case \"tool_result_message\":\n return handleToolResultMessage(state, event.data as ToolResultMessage);\n\n case \"tool_result\":\n return handleToolResult(\n state,\n event.data as { toolCallId: string; result: unknown; isError: boolean }\n );\n\n case \"error\":\n return handleError(state, event.data as ErrorData);\n\n case \"interrupted\":\n return handleInterrupted(state);\n\n // Connection state\n case \"connection_state\":\n return handleConnectionState(state, event.data as { state: string });\n\n // Workspace file tree\n case \"workspace_tree\":\n return handleWorkspaceTree(state, event.data as { files: FileTreeEntry[] });\n\n // Rewind — runtime-level operation\n case \"rewind\":\n return handleRewind(state, event.data as { truncatedCount: number });\n\n default:\n return state;\n }\n}\n\n// ============================================================================\n// Helpers — operate on the last assistant conversation in conversations[]\n// ============================================================================\n\n/**\n * Get the last conversation if it's a streaming assistant conversation.\n */\nfunction getStreamingConv(state: PresentationState): AssistantConversation | null {\n const last = state.conversations[state.conversations.length - 1];\n if (last?.role === \"assistant\" && (last as AssistantConversation).isStreaming) {\n return last as AssistantConversation;\n }\n return null;\n}\n\n/**\n * Update the last conversation in the array (must be streaming assistant).\n */\nfunction updateLastConv(\n state: PresentationState,\n updater: (conv: AssistantConversation) => AssistantConversation,\n extraState?: Partial<PresentationState>\n): PresentationState {\n const conv = getStreamingConv(state);\n if (!conv) return state;\n\n const updated = updater(conv);\n const conversations = [...state.conversations];\n conversations[conversations.length - 1] = updated;\n\n return { ...state, conversations, ...extraState };\n}\n\ninterface InputJsonDeltaData {\n partialJson: string;\n}\n\n// ============================================================================\n// Handlers — all operate on conversations[]\n// ============================================================================\n\nfunction handleMessageStart(state: PresentationState, _data: MessageStartData): PresentationState {\n const newConv: AssistantConversation = {\n role: \"assistant\",\n blocks: [],\n isStreaming: true,\n };\n\n // Only reset metrics at the start of a new turn (idle/submitted → submitted).\n // Mid-turn message_start (after tool_use) should keep accumulating.\n const isNewTurn = state.status === \"idle\" || state.status === \"submitted\";\n const metrics = isNewTurn ? { ...initialMetrics, turnStartedAt: Date.now() } : state.metrics;\n\n return {\n ...state,\n conversations: [...state.conversations, newConv],\n status: \"submitted\",\n metrics,\n };\n}\n\nfunction handleThinkingDelta(state: PresentationState, data: TextDeltaData): PresentationState {\n return updateLastConv(\n state,\n (conv) => {\n const blocks = [...conv.blocks];\n const lastBlock = blocks[blocks.length - 1];\n\n if (lastBlock && lastBlock.type === \"thinking\") {\n blocks[blocks.length - 1] = {\n ...lastBlock,\n content: (lastBlock as any).content + data.text,\n };\n } else {\n blocks.push({ type: \"thinking\", content: data.text } as Block);\n }\n\n return { ...conv, blocks };\n },\n { status: \"thinking\" }\n );\n}\n\nfunction handleTextDelta(state: PresentationState, data: TextDeltaData): PresentationState {\n return updateLastConv(\n state,\n (conv) => {\n const blocks = [...conv.blocks];\n const lastBlock = blocks[blocks.length - 1];\n\n if (lastBlock && lastBlock.type === \"text\") {\n blocks[blocks.length - 1] = {\n ...lastBlock,\n content: lastBlock.content + data.text,\n };\n } else {\n blocks.push({ type: \"text\", content: data.text } as TextBlock);\n }\n\n return { ...conv, blocks };\n },\n { status: \"responding\" }\n );\n}\n\nfunction handleToolUseStart(state: PresentationState, data: ToolUseStartData): PresentationState {\n const toolBlock: ToolBlock = {\n type: \"tool\",\n toolUseId: data.toolCallId,\n toolName: data.toolName,\n toolInput: {},\n status: \"pending\",\n };\n\n return updateLastConv(state, (conv) => ({ ...conv, blocks: [...conv.blocks, toolBlock] }), {\n status: \"executing\",\n });\n}\n\nfunction handleInputJsonDelta(\n state: PresentationState,\n data: InputJsonDeltaData\n): PresentationState {\n return updateLastConv(state, (conv) => {\n const blocks = conv.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.status === \"pending\") {\n return {\n ...block,\n partialInput: ((block as any).partialInput || \"\") + data.partialJson,\n } as ToolBlock;\n }\n return block;\n });\n return { ...conv, blocks };\n });\n}\n\nfunction handleToolUseStop(state: PresentationState, data: ToolUseStopData): PresentationState {\n return updateLastConv(\n state,\n (conv) => {\n const blocks = conv.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === data.toolCallId) {\n return { ...block, toolInput: data.input, status: \"running\" };\n }\n return block;\n });\n return { ...conv, blocks };\n },\n { status: \"executing\" }\n );\n}\n\nfunction handleMessageDelta(state: PresentationState, data: MessageDeltaData): PresentationState {\n if (!data.usage) return state;\n\n const newState = updateLastConv(state, (conv) => {\n const prev = conv.usage;\n const usage: TokenUsage = {\n inputTokens: (prev?.inputTokens ?? 0) + data.usage!.inputTokens,\n outputTokens: (prev?.outputTokens ?? 0) + data.usage!.outputTokens,\n };\n return { ...conv, usage };\n });\n\n // inputTokens from LLM = current context size (full history sent each call)\n const contextTokens = data.usage.inputTokens;\n const contextLimit = newState.metrics.session.contextLimit;\n const contextUsage = contextLimit > 0 ? contextTokens / contextLimit : 0;\n\n return {\n ...newState,\n metrics: {\n ...newState.metrics,\n inputTokens: newState.metrics.inputTokens + data.usage.inputTokens,\n outputTokens: newState.metrics.outputTokens + data.usage.outputTokens,\n session: {\n contextTokens,\n contextLimit,\n contextUsage,\n },\n },\n };\n}\n\nfunction handleMessageStop(state: PresentationState, data: MessageStopData): PresentationState {\n // tool_use stop → keep streaming, tool results are still incoming\n if (data.stopReason === \"tool_use\") {\n return { ...state, status: \"executing\" };\n }\n\n // end_turn / max_tokens → mark completed, clear turnStartedAt\n return updateLastConv(state, (conv) => ({ ...conv, isStreaming: false }), {\n status: \"idle\",\n metrics: { ...state.metrics, turnStartedAt: null },\n });\n}\n\nfunction handleToolResultMessage(\n state: PresentationState,\n data: ToolResultMessage\n): PresentationState {\n const toolCallId = data.toolCallId;\n\n // Find tool block in any conversation (could be in last streaming or already completed)\n const conversations = state.conversations.map((conv): Conversation => {\n if (conv.role !== \"assistant\") return conv;\n const ac = conv as AssistantConversation;\n const hasMatch = ac.blocks.some((b) => b.type === \"tool\" && b.toolUseId === toolCallId);\n if (!hasMatch) return conv;\n\n const blocks = ac.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === toolCallId) {\n return {\n ...block,\n toolResult: formatToolResultOutput(data.toolResult.output),\n status:\n data.toolResult.output.type === \"error-text\" ||\n data.toolResult.output.type === \"error-json\" ||\n data.toolResult.output.type === \"execution-denied\"\n ? \"error\"\n : \"completed\",\n };\n }\n return block;\n });\n return { ...ac, blocks };\n });\n\n return { ...state, conversations, status: \"responding\" };\n}\n\n/**\n * Handle tool_result from stream layer (raw driver event).\n */\nfunction handleToolResult(\n state: PresentationState,\n data: { toolCallId: string; result: unknown; isError: boolean }\n): PresentationState {\n const { toolCallId, result, isError } = data;\n const resultStr =\n typeof result === \"string\"\n ? result\n : result instanceof Error\n ? result.message\n : JSON.stringify(result);\n\n const conversations = state.conversations.map((conv): Conversation => {\n if (conv.role !== \"assistant\") return conv;\n const ac = conv as AssistantConversation;\n const hasMatch = ac.blocks.some((b) => b.type === \"tool\" && b.toolUseId === toolCallId);\n if (!hasMatch) return conv;\n\n const blocks = ac.blocks.map((block): Block => {\n if (block.type === \"tool\" && block.toolUseId === toolCallId) {\n return { ...block, toolResult: resultStr, status: isError ? \"error\" : \"completed\" };\n }\n return block;\n });\n return { ...ac, blocks };\n });\n\n return { ...state, conversations, status: \"responding\" };\n}\n\nfunction handleError(state: PresentationState, data: ErrorData): PresentationState {\n // If there's a streaming conversation with content, keep it\n const conv = getStreamingConv(state);\n let conversations = state.conversations;\n if (conv && conv.blocks.length > 0) {\n // Mark streaming conv as completed before adding error\n conversations = [...state.conversations];\n conversations[conversations.length - 1] = { ...conv, isStreaming: false };\n }\n\n return {\n ...state,\n conversations: [...conversations, { role: \"error\", message: data.message }],\n status: \"idle\",\n };\n}\n\n/**\n * Interrupt handlers per block type.\n * Each handler receives a block and returns the interrupted version.\n * New block types register here — handleInterrupted stays fixed.\n */\nconst interruptHandlers: Partial<Record<Block[\"type\"], (block: Block) => Block>> = {\n tool: (block) => {\n const tb = block as ToolBlock;\n if (tb.status === \"pending\" || tb.status === \"running\") {\n return { ...tb, status: \"interrupted\", toolResult: \"Interrupted\" };\n }\n return block;\n },\n};\n\nfunction handleInterrupted(state: PresentationState): PresentationState {\n return updateLastConv(\n state,\n (conv) => {\n const blocks = conv.blocks.map((block): Block => {\n const handler = interruptHandlers[block.type];\n return handler ? handler(block) : block;\n });\n return { ...conv, blocks, isStreaming: false };\n },\n { status: \"idle\" }\n );\n}\n\nfunction handleConnectionState(\n state: PresentationState,\n data: { state: string }\n): PresentationState {\n const connection = data.state as ConnectionState;\n if (connection === state.connection) return state;\n return { ...state, connection };\n}\n\nfunction handleRewind(\n state: PresentationState,\n data: { truncatedCount: number }\n): PresentationState {\n // Remove the last N conversations (truncatedCount maps roughly to messages, not conversations)\n // Simplest: re-derive from the event — just drop conversations from the end\n const toRemove = Math.max(1, Math.ceil(data.truncatedCount / 2));\n const conversations = state.conversations.slice(\n 0,\n Math.max(0, state.conversations.length - toRemove)\n );\n return { ...state, conversations, status: \"idle\" };\n}\n\nfunction handleWorkspaceTree(\n state: PresentationState,\n data: { files: FileTreeEntry[] }\n): PresentationState {\n return {\n ...state,\n os: { files: data.files },\n };\n}\n\n// ============================================================================\n// Helper: Add user conversation\n// ============================================================================\n\nexport function addUserConversation(\n state: PresentationState,\n content: string | UserContentPart[]\n): PresentationState {\n const blocks: Block[] =\n typeof content === \"string\"\n ? [{ type: \"text\", content }]\n : content.map((part) => {\n switch (part.type) {\n case \"text\":\n return { type: \"text\" as const, content: part.text };\n case \"image\":\n return {\n type: \"image\" as const,\n url: `data:${part.mediaType};base64,${part.data}`,\n alt: part.name,\n };\n case \"file\":\n return {\n type: \"file\" as const,\n filename: part.filename ?? \"file\",\n mediaType: part.mediaType,\n };\n default:\n return { type: \"text\" as const, content: String(part) };\n }\n });\n\n return {\n ...state,\n conversations: [...state.conversations, { role: \"user\", blocks }],\n status: \"submitted\",\n };\n}\n\nexport function createInitialState(): PresentationState {\n return { ...initialPresentationState };\n}\n\n// ============================================================================\n// Helper: Format tool result output\n// ============================================================================\n\nfunction formatToolResultOutput(output: ToolResultOutput): string {\n switch (output.type) {\n case \"text\":\n case \"error-text\":\n return output.value;\n case \"json\":\n case \"error-json\":\n return JSON.stringify(output.value);\n case \"execution-denied\":\n return output.reason ?? \"Execution denied\";\n case \"content\":\n return output.value\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\");\n }\n}\n\n// ============================================================================\n// Message → Conversation Converter\n// ============================================================================\n\n/**\n * Convert persisted Messages to Presentation Conversations.\n *\n * Groups consecutive assistant + tool-result messages\n * into a single AssistantConversation.\n *\n * Tool calls are now part of AssistantMessage.content (as ToolCallPart),\n * so we extract them directly from the assistant message.\n */\nexport function messagesToConversations(messages: Message[]): Conversation[] {\n const conversations: Conversation[] = [];\n let currentAssistant: AssistantConversation | null = null;\n\n function flushAssistant() {\n if (currentAssistant && currentAssistant.blocks.length > 0) {\n conversations.push(currentAssistant);\n }\n currentAssistant = null;\n }\n\n for (const msg of messages) {\n switch (msg.subtype) {\n case \"user\": {\n flushAssistant();\n const m = msg as UserMessage;\n const blocks: Block[] =\n typeof m.content === \"string\"\n ? [{ type: \"text\", content: m.content }]\n : m.content.map((part): Block => {\n switch (part.type) {\n case \"text\":\n return { type: \"text\", content: part.text };\n case \"image\":\n return {\n type: \"image\",\n url: `data:${part.mediaType};base64,${part.data}`,\n alt: part.name,\n };\n case \"file\":\n return {\n type: \"file\",\n filename: part.filename ?? \"file\",\n mediaType: part.mediaType,\n };\n default:\n return { type: \"text\", content: String(part) };\n }\n });\n conversations.push({ role: \"user\", blocks });\n break;\n }\n\n case \"assistant\": {\n if (!currentAssistant) {\n currentAssistant = { role: \"assistant\", blocks: [], isStreaming: false };\n }\n const m = msg as AssistantMessage;\n if (typeof m.content === \"string\") {\n if (m.content) {\n currentAssistant.blocks.push({ type: \"text\", content: m.content } as TextBlock);\n }\n } else {\n // Extract all content parts — must match what real-time streaming produces\n for (const part of m.content) {\n if (part.type === \"text\") {\n if (part.text) {\n currentAssistant.blocks.push({ type: \"text\", content: part.text } as TextBlock);\n }\n } else if (part.type === \"thinking\") {\n if (part.reasoning) {\n currentAssistant.blocks.push({\n type: \"thinking\",\n content: part.reasoning,\n } as Block);\n }\n } else if (part.type === \"tool-call\") {\n const tc = part as ToolCallPart;\n currentAssistant.blocks.push({\n type: \"tool\",\n toolUseId: tc.id,\n toolName: tc.name,\n toolInput: tc.input,\n status: \"completed\",\n } as ToolBlock);\n } else if (part.type === \"file\") {\n currentAssistant.blocks.push({\n type: \"file\",\n filename: (part as any).filename ?? \"file\",\n mediaType: (part as any).mediaType ?? \"application/octet-stream\",\n } as Block);\n }\n }\n }\n break;\n }\n\n case \"tool-result\": {\n const m = msg as ToolResultMessage;\n if (currentAssistant) {\n for (const block of currentAssistant.blocks) {\n if (block.type === \"tool\" && block.toolUseId === m.toolResult.id) {\n block.toolResult = formatToolResultOutput(m.toolResult.output);\n block.status =\n m.toolResult.output.type === \"error-text\" ||\n m.toolResult.output.type === \"error-json\" ||\n m.toolResult.output.type === \"execution-denied\"\n ? \"error\"\n : \"completed\";\n break;\n }\n }\n }\n break;\n }\n\n case \"error\": {\n flushAssistant();\n const m = msg as ErrorMessage;\n conversations.push({\n role: \"error\",\n message: m.content,\n });\n break;\n }\n }\n }\n\n flushAssistant();\n return conversations;\n}\n","/**\n * Presentation — a live chat session.\n *\n * Read state directly as properties. Subscribe for re-renders.\n * Take actions with send/interrupt/rewind.\n *\n * @example\n * ```typescript\n * // Read state\n * pres.conversations // message history\n * pres.status // \"idle\" | \"submitted\" | \"thinking\" | \"responding\" | \"executing\"\n * pres.os // { files, read, write, list } or null\n *\n * // Subscribe (works with useSyncExternalStore)\n * const unsub = pres.subscribe(() => rerender());\n *\n * // Actions\n * await pres.send(\"Hello\");\n * await pres.interrupt();\n * await pres.rewind(2);\n * ```\n */\n\nimport type { UserContentPart } from \"@agentxjs/core/agent\";\nimport type { SendOptions } from \"@agentxjs/core/driver\";\nimport type { BusEvent } from \"@agentxjs/core/event\";\nimport type { AgentX } from \"../types\";\nimport { addUserConversation, createInitialState, presentationReducer } from \"./reducer\";\nimport type {\n ConnectionState,\n Conversation,\n PresentationMetrics,\n PresentationOS,\n PresentationState,\n} from \"./types\";\nimport { initialPresentationState } from \"./types\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * OS view — file tree + operations, unified.\n */\nexport interface OS {\n /** Current file tree (real-time updates) */\n readonly files: readonly import(\"./types\").FileTreeEntry[];\n /** Read file content */\n read(path: string): Promise<string>;\n /** Write content to file */\n write(path: string, content: string): Promise<void>;\n /** List directory entries */\n list(path?: string): Promise<import(\"./types\").FileTreeEntry[]>;\n}\n\n/**\n * Options for creating a Presentation\n */\nexport interface PresentationOptions {\n /** Called on every state change (legacy — prefer subscribe) */\n onUpdate?: (state: PresentationState) => void;\n}\n\n// ============================================================================\n// Presentation\n// ============================================================================\n\nexport class Presentation {\n private _agentx: AgentX;\n private _instanceId: string;\n private _state: PresentationState;\n private _listeners = new Set<() => void>();\n private _legacyHandlers = new Set<(state: PresentationState) => void>();\n private _eventUnsubscribe: (() => void) | null = null;\n private _osOps: PresentationOS | null;\n\n constructor(\n agentx: AgentX,\n instanceId: string,\n options?: PresentationOptions,\n initialConversations?: Conversation[],\n os?: PresentationOS | null\n ) {\n this._agentx = agentx;\n this._instanceId = instanceId;\n this._osOps = os ?? null;\n this._state = initialConversations?.length\n ? { ...initialPresentationState, conversations: initialConversations }\n : createInitialState();\n\n // Legacy onUpdate support\n if (options?.onUpdate) {\n this._legacyHandlers.add(options.onUpdate);\n }\n\n // Subscribe to EventBus\n this._subscribeToEvents();\n\n // Load initial workspace file tree\n if (this._osOps) {\n this._osOps.list(\".\").then((files) => {\n this._state = { ...this._state, os: { files } };\n this._notify();\n });\n }\n }\n\n // ==================== State (direct properties) ====================\n\n /** All conversations (user, assistant, error) */\n get conversations(): readonly Conversation[] {\n return this._state.conversations;\n }\n\n /** Current agent status */\n get status(): PresentationState[\"status\"] {\n return this._state.status;\n }\n\n /** WebSocket connection state */\n get connection(): ConnectionState {\n return this._state.connection;\n }\n\n /** Token usage and context metrics */\n get metrics(): PresentationMetrics {\n return this._state.metrics;\n }\n\n /** OS — file tree + operations. null if agent has no OS. */\n get os(): OS | null {\n if (!this._osOps) return null;\n const ops = this._osOps;\n const osState = this._state.os;\n return {\n get files() {\n return osState?.files ?? [];\n },\n read: (path: string) => ops.read(path),\n write: (path: string, content: string) => ops.write(path, content),\n list: (path?: string) => ops.list(path),\n };\n }\n\n // ==================== Subscribe ====================\n\n /**\n * Subscribe to state changes.\n * Compatible with React's useSyncExternalStore.\n * Does NOT call listener immediately.\n *\n * @returns Unsubscribe function\n */\n subscribe(listener: () => void): () => void {\n this._listeners.add(listener);\n return () => {\n this._listeners.delete(listener);\n };\n }\n\n /**\n * Get state snapshot.\n * Compatible with React's useSyncExternalStore.\n */\n getSnapshot(): PresentationState {\n return this._state;\n }\n\n // ==================== Actions ====================\n\n /** Send a message */\n async send(content: string | UserContentPart[], options?: SendOptions): Promise<void> {\n this._state = addUserConversation(this._state, content);\n this._notify();\n\n // Yield to allow UI to render submitted state\n await new Promise((resolve) => setTimeout(resolve, 0));\n\n try {\n await this._agentx.runtime.session.send(this._instanceId, content, options);\n } catch (error) {\n console.error(\"Presentation send error:\", error);\n }\n }\n\n /** Interrupt current response */\n async interrupt(): Promise<void> {\n try {\n await this._agentx.runtime.session.interrupt(this._instanceId);\n } catch (error) {\n console.error(\"Presentation interrupt error:\", error);\n }\n }\n\n /** Rewind conversation to a specific index (removes index and everything after) */\n async rewind(index: number): Promise<void> {\n const conversations = this._state.conversations;\n if (index < 0 || index >= conversations.length) return;\n\n try {\n const messages = await this._agentx.runtime.session.getMessages(this._instanceId);\n if (messages.length === 0) return;\n\n if (index === 0) {\n await this._agentx.rpc(\"runtime.rewind\", {\n imageId: this._instanceId,\n messageId: messages[0].id,\n });\n } else {\n let msgIndex = -1;\n let convCount = 0;\n for (let i = 0; i < messages.length; i++) {\n if (messages[i].subtype === \"user\" || messages[i].subtype === \"assistant\") {\n convCount++;\n }\n if (convCount >= index) {\n msgIndex = i;\n break;\n }\n }\n if (msgIndex >= 0 && msgIndex < messages.length) {\n await this._agentx.rpc(\"runtime.rewind\", {\n imageId: this._instanceId,\n messageId: messages[msgIndex].id,\n });\n }\n }\n } catch (error) {\n console.error(\"Presentation rewind error:\", error);\n }\n }\n\n /** Dispose and cleanup all subscriptions */\n dispose(): void {\n if (this._eventUnsubscribe) {\n this._eventUnsubscribe();\n this._eventUnsubscribe = null;\n }\n this._listeners.clear();\n this._legacyHandlers.clear();\n }\n\n // ==================== Private ====================\n\n private _subscribeToEvents(): void {\n this._eventUnsubscribe = this._agentx.onAny((event: BusEvent) => {\n const eventWithContext = event as BusEvent & {\n context?: { instanceId?: string; imageId?: string };\n };\n const eventAgentId = eventWithContext.context?.instanceId;\n\n if (eventAgentId && eventAgentId !== this._instanceId) {\n const eventImageId = eventWithContext.context?.imageId;\n if (!eventImageId || eventImageId !== this._instanceId) {\n return;\n }\n }\n\n const newState = presentationReducer(this._state, event);\n if (newState !== this._state) {\n this._state = newState;\n this._notify();\n }\n });\n }\n\n private _notify(): void {\n // New API: bare listeners (for useSyncExternalStore)\n for (const listener of this._listeners) {\n try {\n listener();\n } catch (error) {\n console.error(\"Presentation listener error:\", error);\n }\n }\n // Legacy API: handlers that receive state\n for (const handler of this._legacyHandlers) {\n try {\n handler(this._state);\n } catch (error) {\n console.error(\"Presentation handler error:\", error);\n }\n }\n }\n}\n","/**\n * Presentation namespace factory\n *\n * Singleton per imageId — same imageId always returns the same Presentation.\n * First call creates from history, subsequent calls return existing instance.\n * Options (onUpdate, onError) are additive — new handlers are merged in.\n */\n\nimport { messagesToConversations, Presentation, type PresentationOptions } from \"../presentation\";\nimport type { PresentationOS } from \"../presentation/types\";\nimport type { AgentX, PresentationNamespace, SessionNamespace } from \"../types\";\n\n/**\n * OS resolver — given an imageId, returns a PresentationOS or null.\n * Provided by the client (local or remote) to decouple from runtime internals.\n */\nexport type OSResolver = (imageId: string) => Promise<PresentationOS | null>;\n\nexport function createPresentations(\n agentx: AgentX,\n sessionNs: SessionNamespace,\n osResolver?: OSResolver\n): PresentationNamespace {\n const instances = new Map<string, Presentation>();\n\n return {\n async create(imageId: string, options?: PresentationOptions): Promise<Presentation> {\n // Return existing singleton\n const existing = instances.get(imageId);\n if (existing) {\n // Merge new handlers if provided\n if (options?.onUpdate) existing.onUpdate(options.onUpdate);\n if (options?.onError) existing.onError(options.onError);\n return existing;\n }\n\n // Resolve OS for this image\n const os = osResolver ? await osResolver(imageId) : null;\n\n // Create new from history\n const messages = await sessionNs.getMessages(imageId);\n const conversations = messagesToConversations(messages);\n const presentation = new Presentation(agentx, imageId, options, conversations, os);\n\n instances.set(imageId, presentation);\n\n // Clean up on dispose\n const originalDispose = presentation.dispose.bind(presentation);\n presentation.dispose = () => {\n instances.delete(imageId);\n originalDispose();\n };\n\n return presentation;\n },\n };\n}\n","/**\n * Session namespace factories (messaging)\n */\n\nimport type { Message, UserContentPart } from \"@agentxjs/core/agent\";\nimport type { SendOptions } from \"@agentxjs/core/driver\";\nimport type { RpcClient } from \"@agentxjs/core/network\";\nimport type { AgentXRuntime } from \"@agentxjs/core/runtime\";\nimport type { BaseResponse, MessageSendResponse, SessionNamespace } from \"../types\";\n\n/**\n * Create local session namespace backed by embedded runtime\n */\n/**\n * Resolve an imageId or instanceId to a running agent instanceId.\n * If no agent exists for this imageId, auto-creates one.\n */\nasync function resolveLocal(runtime: AgentXRuntime, id: string): Promise<string> {\n // Direct instanceId\n if (id.startsWith(\"inst_\")) {\n const agent = runtime.getAgent(id);\n if (agent) return id;\n }\n\n // imageId — find existing or auto-create\n const imageId = id.startsWith(\"img_\") ? id : id;\n const existing = runtime\n .getAgents()\n .find((a) => a.imageId === imageId && a.lifecycle === \"running\");\n if (existing) return existing.instanceId;\n\n const agent = await runtime.createAgent({ imageId });\n return agent.instanceId;\n}\n\nexport function createLocalSessions(runtime: AgentXRuntime): SessionNamespace {\n return {\n async send(\n id: string,\n content: string | unknown[],\n options?: SendOptions\n ): Promise<MessageSendResponse> {\n const instanceId = await resolveLocal(runtime, id);\n await runtime.receive(instanceId, content as string | UserContentPart[], undefined, options);\n return { instanceId, requestId: \"\" };\n },\n\n async interrupt(id: string): Promise<BaseResponse> {\n const instanceId = await resolveLocal(runtime, id);\n runtime.interrupt(instanceId);\n return { requestId: \"\" };\n },\n\n async getMessages(id: string): Promise<Message[]> {\n // For imageId, get messages directly from session\n if (id.startsWith(\"img_\")) {\n const image = await runtime.platform.imageRepository.findImageById(id);\n if (!image) return [];\n return runtime.platform.sessionRepository.getMessages(image.sessionId);\n }\n const agent = runtime.getAgent(id);\n if (!agent) return [];\n return runtime.platform.sessionRepository.getMessages(agent.sessionId);\n },\n };\n}\n\n/**\n * Create remote session namespace backed by RPC client\n */\n/**\n * Detect whether an ID is an imageId or instanceId based on prefix.\n * imageId starts with \"img_\", instanceId starts with \"inst_\".\n */\nfunction resolveId(id: string): { imageId?: string; instanceId?: string } {\n if (id.startsWith(\"inst_\")) return { instanceId: id };\n return { imageId: id };\n}\n\nexport function createRemoteSessions(rpcClient: RpcClient): SessionNamespace {\n return {\n async send(\n id: string,\n content: string | unknown[],\n options?: SendOptions\n ): Promise<MessageSendResponse> {\n const result = await rpcClient.call<MessageSendResponse>(\"message.send\", {\n ...resolveId(id),\n content,\n options,\n });\n return { ...result, requestId: \"\" };\n },\n\n async interrupt(id: string): Promise<BaseResponse> {\n const result = await rpcClient.call<BaseResponse>(\"instance.interrupt\", {\n ...resolveId(id),\n });\n return { ...result, requestId: \"\" };\n },\n\n async getMessages(id: string): Promise<Message[]> {\n // For instanceId, resolve to imageId first\n if (id.startsWith(\"inst_\")) {\n const agentRes = await rpcClient.call<{ agent: { imageId: string } | null }>(\n \"instance.get\",\n { instanceId: id }\n );\n if (!agentRes.agent) return [];\n id = agentRes.agent.imageId;\n }\n const msgRes = await rpcClient.call<{ messages: Message[] }>(\"image.messages\", {\n imageId: id,\n });\n return msgRes.messages ?? [];\n },\n };\n}\n","/**\n * RemoteClient - AgentX client for remote server\n *\n * Uses RpcClient from @agentxjs/core/network for JSON-RPC communication.\n * This class focuses on business logic, not protocol details.\n */\n\nimport type { AgentXError } from \"@agentxjs/core/error\";\nimport type { BusEvent, BusEventHandler, EventBus, Unsubscribe } from \"@agentxjs/core/event\";\nimport { EventBusImpl } from \"@agentxjs/core/event\";\nimport { RpcClient } from \"@agentxjs/core/network\";\nimport { createLogger } from \"commonxjs/logger\";\nimport { AgentHandleImpl } from \"./AgentHandle\";\nimport { createRemoteImages } from \"./namespaces/images\";\nimport { createRemoteLLM } from \"./namespaces/llm\";\nimport { createPresentations } from \"./namespaces/presentations\";\nimport { createRemoteSessions } from \"./namespaces/sessions\";\nimport type {\n AgentX,\n ChatNamespace,\n LLMNamespace,\n RemoteClientConfig,\n RuntimeNamespace,\n} from \"./types\";\n\nconst logger = createLogger(\"agentx/RemoteClient\");\n\n/**\n * RemoteClient implementation using JSON-RPC 2.0\n */\nexport class RemoteClient implements AgentX {\n private readonly config: RemoteClientConfig;\n private readonly eventBus: EventBus;\n private readonly rpcClient: RpcClient;\n\n readonly chat: ChatNamespace;\n readonly runtime: RuntimeNamespace;\n readonly provider: LLMNamespace;\n\n constructor(config: RemoteClientConfig) {\n this.config = config;\n this.eventBus = new EventBusImpl();\n\n // Create RPC client (WebSocket factory from platform if available)\n this.rpcClient = new RpcClient({\n url: config.serverUrl,\n createWebSocket: config.customPlatform?.channelClient,\n timeout: config.timeout ?? 30000,\n autoReconnect: config.autoReconnect ?? true,\n headers: config.headers as Record<string, string> | undefined,\n debug: false,\n });\n\n // Forward stream events to internal event bus\n this.rpcClient.onStreamEvent((topic, event) => {\n logger.debug(\"Received stream event\", { topic, type: event.type });\n this.eventBus.emit(event as BusEvent);\n });\n\n // Forward connection state changes to event bus\n this.rpcClient.onStateChange((state) => {\n this.eventBus.emit({\n type: \"connection_state\",\n timestamp: Date.now(),\n data: { state },\n } as BusEvent);\n });\n\n // Assemble namespaces\n const image = createRemoteImages(this.rpcClient);\n const session = createRemoteSessions(this.rpcClient);\n const llm = createRemoteLLM(this.rpcClient);\n // Workspace resolver via RPC — server handles workspace access\n const workspaceResolver = async (imageId: string) => {\n const rpc = this.rpcClient;\n return {\n read: async (path: string) => {\n const res = await rpc.call<{ content: string }>(\"workspace.read\", { imageId, path });\n return res.content;\n },\n write: async (path: string, content: string) => {\n await rpc.call(\"workspace.write\", { imageId, path, content });\n },\n list: async (path?: string) => {\n const res = await rpc.call<{\n files: Array<{ name: string; path: string; type: \"file\" | \"directory\" }>;\n }>(\"workspace.list\", { imageId, path });\n return res.files;\n },\n };\n };\n const present = createPresentations(this, session, workspaceResolver);\n\n this.runtime = { image, session, present, llm };\n this.provider = llm;\n this.chat = this.createChatNamespace();\n }\n\n // ==================== Properties ====================\n\n get connected(): boolean {\n return this.rpcClient.connected;\n }\n\n get events(): EventBus {\n return this.eventBus;\n }\n\n // ==================== Connection ====================\n\n async connect(): Promise<void> {\n await this.rpcClient.connect();\n logger.info(\"Connected to server\", { url: this.config.serverUrl });\n }\n\n async disconnect(): Promise<void> {\n this.rpcClient.disconnect();\n logger.info(\"Disconnected from server\");\n }\n\n async dispose(): Promise<void> {\n this.rpcClient.dispose();\n this.eventBus.destroy();\n logger.info(\"RemoteClient disposed\");\n }\n\n // ==================== Event Subscription ====================\n\n on<T extends string>(type: T, handler: BusEventHandler<BusEvent & { type: T }>): Unsubscribe {\n return this.eventBus.on(type, handler);\n }\n\n onAny(handler: BusEventHandler): Unsubscribe {\n return this.eventBus.onAny(handler);\n }\n\n // ==================== Error Handling ====================\n\n onError(handler: (error: AgentXError) => void): Unsubscribe {\n return this.eventBus.on(\"agentx_error\", (event) => {\n handler(event.data as AgentXError);\n });\n }\n\n // ==================== RPC ====================\n\n async rpc<T = unknown>(method: string, params?: unknown): Promise<T> {\n return this.rpcClient.call<T>(method, params);\n }\n\n // ==================== Private ====================\n\n private createChatNamespace(): ChatNamespace {\n const rt = this.runtime;\n return {\n async create(params) {\n const imgRes = await rt.image.create(params);\n const runRes = await rt.image.run(imgRes.record.imageId);\n return new AgentHandleImpl(\n {\n instanceId: runRes.instanceId,\n imageId: runRes.imageId,\n containerId: runRes.containerId,\n sessionId: runRes.sessionId,\n },\n rt\n );\n },\n async list() {\n return rt.image.list();\n },\n async get(id) {\n const res = await rt.image.get(id);\n if (!res.record) return null;\n const runRes = await rt.image.run(res.record.imageId);\n return new AgentHandleImpl(\n {\n instanceId: runRes.instanceId,\n imageId: runRes.imageId,\n containerId: runRes.containerId,\n sessionId: runRes.sessionId,\n },\n rt\n );\n },\n };\n }\n}\n"],"mappings":"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","names":["createLogger","DEFAULT_CONTAINER_ID","agent","createLogger","logger","createLogger","createLogger"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
RpcHandlerRegistry,
|
|
3
3
|
registerAll
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-TKYJYJS5.js";
|
|
5
5
|
|
|
6
6
|
// src/server.ts
|
|
7
7
|
import {
|
|
@@ -163,4 +163,4 @@ async function createServer(config) {
|
|
|
163
163
|
export {
|
|
164
164
|
createServer
|
|
165
165
|
};
|
|
166
|
-
//# sourceMappingURL=server-
|
|
166
|
+
//# sourceMappingURL=server-N3SRHICW.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentxjs",
|
|
3
|
-
"version": "2.9.0-dev-
|
|
3
|
+
"version": "2.9.0-dev-20260317112104",
|
|
4
4
|
"description": "AgentX Client SDK - Local and remote AI agent management",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -23,12 +23,12 @@
|
|
|
23
23
|
"test": "bun test bdd/"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@agentxjs/core": "2.9.0-dev-
|
|
26
|
+
"@agentxjs/core": "2.9.0-dev-20260317112104",
|
|
27
27
|
"@deepracticex/id": "^0.2.0",
|
|
28
28
|
"@deepracticex/logger": "^1.2.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@agentxjs/devtools": "2.3.0-dev-
|
|
31
|
+
"@agentxjs/devtools": "2.3.0-dev-20260317112104",
|
|
32
32
|
"@deepracticex/bdd": "^0.3.0",
|
|
33
33
|
"tsx": "^4.19.0",
|
|
34
34
|
"typescript": "^5.3.3"
|
package/src/LocalClient.ts
CHANGED
|
@@ -40,23 +40,23 @@ export class LocalClient implements AgentX {
|
|
|
40
40
|
const image = createLocalImages(platform, agentxRuntime);
|
|
41
41
|
const session = createLocalSessions(agentxRuntime);
|
|
42
42
|
const llm = createLocalLLM(platform);
|
|
43
|
-
//
|
|
44
|
-
const
|
|
45
|
-
const
|
|
46
|
-
if (!
|
|
43
|
+
// OS resolver: imageId → PresentationOS (via AgentOS)
|
|
44
|
+
const osResolver = async (imageId: string) => {
|
|
45
|
+
const op = platform.osProvider;
|
|
46
|
+
if (!op) return null;
|
|
47
47
|
const img = await platform.imageRepository.findImageById(imageId);
|
|
48
|
-
if (!img?.
|
|
49
|
-
const
|
|
48
|
+
if (!img?.osId) return null;
|
|
49
|
+
const os = await op.create(img.osId);
|
|
50
50
|
return {
|
|
51
|
-
read: (path: string) =>
|
|
52
|
-
write: (path: string, content: string) =>
|
|
51
|
+
read: (path: string) => os.fs.read(path),
|
|
52
|
+
write: (path: string, content: string) => os.fs.write(path, content),
|
|
53
53
|
list: async (path?: string) => {
|
|
54
|
-
const entries = await
|
|
54
|
+
const entries = await os.fs.list(path);
|
|
55
55
|
return entries.map((e) => ({ name: e.name, path: e.path, type: e.type }));
|
|
56
56
|
},
|
|
57
57
|
};
|
|
58
58
|
};
|
|
59
|
-
const present = createPresentations(this, session,
|
|
59
|
+
const present = createPresentations(this, session, osResolver);
|
|
60
60
|
|
|
61
61
|
this.runtime = { image, session, present, llm };
|
|
62
62
|
this.provider = llm;
|