{"version":3,"sources":["/Users/shyun/comcom/ain-enterprise/ain-adk/dist/cjs/chunk-I6IE4GVJ.cjs","../../src/modules/a2a/a2a.module.ts"],"names":[],"mappings":"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","file":"/Users/shyun/comcom/ain-enterprise/ain-adk/dist/cjs/chunk-I6IE4GVJ.cjs","sourcesContent":[null,"import { randomUUID } from \"node:crypto\";\nimport type {\n\tAgentCard,\n\tMessage,\n\tMessageSendParams,\n\tTask,\n\tTaskStatusUpdateEvent,\n\tTextPart,\n} from \"@a2a-js/sdk\";\nimport { type Client as A2AClient, ClientFactory } from \"@a2a-js/sdk/client\";\nimport {\n\tCONNECTOR_PROTOCOL_TYPE,\n\ttype ConnectorTool,\n} from \"@/types/connector.js\";\nimport { ThreadType } from \"@/types/memory.js\";\nimport type { StreamEvent } from \"@/types/stream.js\";\nimport { loggers } from \"@/utils/logger.js\";\nimport { sanitizeThinkingData, withAdkThinkingArg } from \"@/utils/tool-args.js\";\nimport { A2AConnector } from \"./a2a.connector.js\";\n\n/**\n * Module for managing Agent-to-Agent (A2A) protocol connections.\n *\n * This module handles connections to other A2A-compatible agents, manages\n * conversation sessions, and provides an interface for inter-agent communication.\n * Supports multi-turn conversations with task and context tracking.\n */\n// JSON.stringify(new Error(...)) is \"{}\" — message/stack are non-enumerable —\n// which erases the failure cause from logs and tool results. Extract them.\nconst describeA2AError = (\n\terror: unknown,\n): { message: string; stack?: string } =>\n\terror instanceof Error\n\t\t? { message: error.message, stack: error.stack }\n\t\t: { message: typeof error === \"string\" ? error : JSON.stringify(error) };\n\nexport class A2AModule {\n\t/** Communication attempts per send: the first call plus one retry. */\n\tprivate static readonly MAX_SEND_ATTEMPTS = 2;\n\n\t/** Map of A2A server URLs to their corresponding tool instances */\n\tprivate a2aConnectors: Map<string, A2AConnector> = new Map();\n\t/** Map of session IDs to their A2A session state */\n\tprivate a2aTasks: Map<string, string> = new Map();\n\tprivate agentId: string = randomUUID(); /* FIXME */\n\n\t/**\n\t * Registers a new A2A peer server URL for connection.\n\t *\n\t * @param conns - Set of name, url pair\n\t */\n\tpublic async addA2AConnector(conns: {\n\t\t[name: string]: string;\n\t}): Promise<void> {\n\t\tfor (const [name, url] of Object.entries(conns)) {\n\t\t\tconst conn = new A2AConnector(name, url);\n\t\t\tthis.a2aConnectors.set(name, conn);\n\t\t}\n\t}\n\n\tpublic getA2AConnectors(): Array<{ name: string; url: string }> {\n\t\tconst connectors: Array<{ name: string; url: string }> = [];\n\t\tfor (const [name, connector] of this.a2aConnectors.entries()) {\n\t\t\tconnectors.push({ name, url: connector.url });\n\t\t}\n\t\treturn connectors;\n\t}\n\n\tpublic hasConnector(connectorName: string): boolean {\n\t\treturn this.a2aConnectors.has(connectorName);\n\t}\n\n\tprivate async getOrCreateClient(connector: A2AConnector): Promise<A2AClient> {\n\t\tif (!connector.client) {\n\t\t\tconnector.client = await new ClientFactory().createFromUrl(connector.url);\n\t\t}\n\t\treturn connector.client;\n\t}\n\n\t/**\n\t * Retrieves tools from all registered A2A peer servers.\n\t *\n\t * Attempts to connect to each registered server, fetch their agent cards,\n\t * and create tool instances. Disables tools for unreachable servers.\n\t *\n\t * @returns Promise resolving to array of available A2A tools\n\t */\n\tpublic async getTools(prompt: string): Promise<ConnectorTool[]> {\n\t\tconst tools: ConnectorTool[] = [];\n\t\tfor (const [name, conn] of this.a2aConnectors.entries()) {\n\t\t\tif (!conn.enabled) {\n\t\t\t\tcontinue; // skip disabled agent\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst client = await this.getOrCreateClient(conn);\n\t\t\t\tconst card: AgentCard = await client.getAgentCard();\n\t\t\t\t/* TODO: add each skill as tool? */\n\t\t\t\tconst tool: ConnectorTool = {\n\t\t\t\t\ttoolName: card.name.replaceAll(\" \", \"-\"),\n\t\t\t\t\tconnectorName: name,\n\t\t\t\t\tprotocol: CONNECTOR_PROTOCOL_TYPE.A2A,\n\t\t\t\t\tdescription: card.description,\n\t\t\t\t\tinputSchema: withAdkThinkingArg(undefined, prompt),\n\t\t\t\t};\n\n\t\t\t\ttools.push(tool);\n\t\t\t} catch (_error: unknown) {\n\t\t\t\t// Agent not responded, just skip\n\t\t\t}\n\t\t}\n\t\treturn tools;\n\t}\n\n\t/**\n\t * Constructs a message payload for A2A communication.\n\t *\n\t * Includes session context (task ID and context ID) if available\n\t * for maintaining conversation continuity.\n\t *\n\t * @param query - The message content to send\n\t * @param threadId - The session identifier\n\t * @returns Formatted Message object for A2A protocol\n\t */\n\tpublic getMessagePayload(\n\t\tquery: string,\n\t\tthreadId: string,\n\t\tmetadata?: Record<string, unknown>,\n\t): Message {\n\t\tconst messagePayload: Message = {\n\t\t\tmessageId: randomUUID(),\n\t\t\tkind: \"message\",\n\t\t\trole: \"user\", // FIXME: it could be 'agent'\n\t\t\tmetadata: {\n\t\t\t\tagentId: this.agentId,\n\t\t\t\ttype: ThreadType.CHAT,\n\t\t\t\t...metadata,\n\t\t\t},\n\t\t\tparts: [\n\t\t\t\t{\n\t\t\t\t\tkind: \"text\",\n\t\t\t\t\ttext: query,\n\t\t\t\t},\n\t\t\t],\n\t\t\tcontextId: threadId,\n\t\t};\n\n\t\tif (this.a2aTasks.has(threadId)) {\n\t\t\tmessagePayload.taskId = this.a2aTasks.get(threadId);\n\t\t}\n\n\t\treturn messagePayload;\n\t}\n\n\tprivate async *sendMessageToConnector(\n\t\tconnector: A2AConnector,\n\t\ttoolName: string,\n\t\tquery: string,\n\t\tthreadId: string,\n\t\tmetadata?: Record<string, unknown>,\n\t): AsyncGenerator<StreamEvent, string, unknown> {\n\t\tconst finalText: string[] = [];\n\t\tconst messagePayload = this.getMessagePayload(query, threadId, metadata);\n\t\tconst params: MessageSendParams = {\n\t\t\tmessage: messagePayload,\n\t\t};\n\n\t\tconst client = await this.getOrCreateClient(connector);\n\t\tconst stream = client.sendMessageStream(params);\n\t\tfor await (const event of stream) {\n\t\t\tif (event.kind === \"status-update\") {\n\t\t\t\tconst typedEvent = event as TaskStatusUpdateEvent;\n\t\t\t\tif (typedEvent.final && typedEvent.status.state !== \"input-required\") {\n\t\t\t\t\tthis.a2aTasks.delete(threadId);\n\t\t\t\t}\n\n\t\t\t\tif (typedEvent.status.state === \"working\") {\n\t\t\t\t\tconst text = (typedEvent.status.message?.parts[0] as TextPart)?.text;\n\t\t\t\t\tif (!text) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tlet thinkingData: {\n\t\t\t\t\t\ttitle: string;\n\t\t\t\t\t\tdescription: string;\n\t\t\t\t\t\tmetadata?: Record<string, unknown>;\n\t\t\t\t\t};\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthinkingData = JSON.parse(text);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tloggers.a2a.warn(\n\t\t\t\t\t\t\t\"Failed to parse A2A working status as JSON; using plain text fallback\",\n\t\t\t\t\t\t\t{ error, text },\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthinkingData = { title: text, description: \"\" };\n\t\t\t\t\t}\n\n\t\t\t\t\tyield {\n\t\t\t\t\t\tevent: \"thinking_process\",\n\t\t\t\t\t\tdata: sanitizeThinkingData(thinkingData),\n\t\t\t\t\t};\n\t\t\t\t} else if (typedEvent.status.state === \"completed\") {\n\t\t\t\t\tconst texts = typedEvent.status.message?.parts\n\t\t\t\t\t\t.filter((part) => part.kind === \"text\")\n\t\t\t\t\t\t.map((part: TextPart) => part.text)\n\t\t\t\t\t\t.join(\"\\n\");\n\t\t\t\t\tif (texts) {\n\t\t\t\t\t\tfinalText.push(texts);\n\t\t\t\t\t\tyield {\n\t\t\t\t\t\t\tevent: \"text_chunk\",\n\t\t\t\t\t\t\tdata: { delta: texts },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if (event.kind === \"message\") {\n\t\t\t\tconst msg = event as Message;\n\t\t\t\tconst taskId = this.a2aTasks.get(threadId);\n\t\t\t\tif (msg.taskId && msg.taskId !== taskId) {\n\t\t\t\t\tthis.a2aTasks.set(threadId, msg.taskId);\n\t\t\t\t}\n\t\t\t} else if (event.kind === \"task\") {\n\t\t\t\tconst task = event as Task;\n\t\t\t\tif (task.id !== this.a2aTasks.get(threadId)) {\n\t\t\t\t\tthis.a2aTasks.set(threadId, task.id);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tloggers.a2a.warn(\"Received unknown event structure from stream:\", {\n\t\t\t\t\tevent,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn `[Bot Called A2A Tool ${toolName}]\\n${finalText.join(\"\\n\")}`;\n\t}\n\n\t/**\n\t * Sends a message through the connector, retrying once on communication\n\t * failure (network error, stream timeout, connection reset). A failed\n\t * attempt may have left a broken task mapping for the thread, so it is\n\t * dropped to let the retry start a fresh task.\n\t *\n\t * Retries ONLY when the failed attempt delivered no events: once the\n\t * consumer has seen output, the remote agent is already executing, and\n\t * re-sending would both run the task twice and replay the delivered\n\t * events. Throws the last error when no (further) attempt is allowed.\n\t */\n\tprivate async *sendWithRetry(\n\t\tconnector: A2AConnector,\n\t\ttoolName: string,\n\t\tquery: string,\n\t\tthreadId: string,\n\t\tmetadata?: Record<string, unknown>,\n\t): AsyncGenerator<StreamEvent, string, unknown> {\n\t\tlet lastError: unknown;\n\t\tfor (let attempt = 1; attempt <= A2AModule.MAX_SEND_ATTEMPTS; attempt++) {\n\t\t\tlet yielded = false;\n\t\t\ttry {\n\t\t\t\tconst stream = this.sendMessageToConnector(\n\t\t\t\t\tconnector,\n\t\t\t\t\ttoolName,\n\t\t\t\t\tquery,\n\t\t\t\t\tthreadId,\n\t\t\t\t\tmetadata,\n\t\t\t\t);\n\t\t\t\tlet step = await stream.next();\n\t\t\t\twhile (!step.done) {\n\t\t\t\t\tyielded = true;\n\t\t\t\t\tyield step.value;\n\t\t\t\t\tstep = await stream.next();\n\t\t\t\t}\n\t\t\t\treturn step.value;\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error;\n\t\t\t\tconst { message, stack } = describeA2AError(error);\n\t\t\t\tloggers.a2a.error(\n\t\t\t\t\t`Error communicating with agent (attempt ${attempt}/${A2AModule.MAX_SEND_ATTEMPTS}):`,\n\t\t\t\t\t{ toolName, threadId, error: message, stack },\n\t\t\t\t);\n\t\t\t\tthis.a2aTasks.delete(threadId);\n\t\t\t\tif (yielded) throw error;\n\t\t\t}\n\t\t}\n\t\tthrow lastError;\n\t}\n\n\tpublic async *sendTask(params: {\n\t\tconnectorName: string;\n\t\tmessage: string;\n\t\tthreadId: string;\n\t\tmetadata?: Record<string, unknown>;\n\t}): AsyncGenerator<StreamEvent, string, unknown> {\n\t\tconst connector = this.a2aConnectors.get(params.connectorName);\n\t\tif (!connector) {\n\t\t\tloggers.a2a.error(\"Unknown agent connector:\", {\n\t\t\t\tconnectorName: params.connectorName,\n\t\t\t});\n\t\t\treturn `[Bot Called A2A Tool ${params.connectorName}]\\n\"Unknown agent connector\"`;\n\t\t}\n\n\t\t// No catch: after the retry is exhausted the error propagates, so\n\t\t// callers (e.g. workflow tasks) record a real failure instead of\n\t\t// mistaking the error text for a completed result.\n\t\treturn yield* this.sendWithRetry(\n\t\t\tconnector,\n\t\t\tparams.connectorName,\n\t\t\tparams.message,\n\t\t\tparams.threadId,\n\t\t\tparams.metadata,\n\t\t);\n\t}\n\n\t/**\n\t * Executes an A2A tool by sending a message to the remote agent.\n\t *\n\t * Handles streaming responses, maintains session state, and extracts\n\t * text content from various event types in the response stream.\n\t *\n\t * @param tool - The A2ATool instance to use\n\t * @param query - The message to send to the agent\n\t * @param threadId - The session identifier for context tracking\n\t * @yields StreamEvent objects for intermediate events\n\t * @returns Final text response from the agent\n\t */\n\tpublic async *useTool(\n\t\ttool: ConnectorTool,\n\t\tquery: string,\n\t\tthreadId: string,\n\t): AsyncGenerator<StreamEvent, string, unknown> {\n\t\tconst connector = this.a2aConnectors.get(tool.connectorName);\n\t\tif (!connector) {\n\t\t\tloggers.a2a.error(\"Unknown agent:\", { tool });\n\t\t\tconst toolResult = `[Bot Called A2A Tool ${tool.connectorName}]\\n\"Unknown agent connector\"`;\n\t\t\treturn toolResult;\n\t\t}\n\n\t\ttry {\n\t\t\treturn yield* this.sendWithRetry(\n\t\t\t\tconnector,\n\t\t\t\ttool.toolName,\n\t\t\t\tquery,\n\t\t\t\tthreadId,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// Interactive tool-calling path: surface the failure to the model\n\t\t\t// as tool output (with the actual cause) instead of throwing, so\n\t\t\t// the LLM can react to it mid-conversation.\n\t\t\treturn `[Bot Called A2A Tool ${tool.toolName}]\\n${describeA2AError(error).message}`;\n\t\t}\n\t}\n}\n"]}