{"_id":"@codepre/a2aw-ts","_rev":"3-38ce5360e70dcb02ef2fcacbe40a571a","name":"@codepre/a2aw-ts","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@codepre/a2aw-ts","version":"0.1.0","author":{"name":"liankong","email":"xhsw.new@outlook.com"},"license":"Apache-2.0","_id":"@codepre/a2aw-ts@0.1.0","maintainers":[{"name":"liankong233","email":"xhsw.new@outlook.com"}],"dist":{"shasum":"a4b2e9c007c44ac725f14c1b36978ace6df292ac","tarball":"https://registry.npmjs.org/@codepre/a2aw-ts/-/a2aw-ts-0.1.0.tgz","fileCount":103,"integrity":"sha512-b+RMc8XB2fDpp5p3+yGMU6TjQ1N6e5j2n8mlv4KJ5asCrvw92XwM8YW8HIxZjGx2z4DXzopJzMByESf2TOiE6w==","signatures":[{"sig":"MEUCIQCnxYu5eYWjagD0sUau6C1vkI+OIkOTcjWnY89I69xo7QIgK6TK4PB3Lk5A5RGpJJ4aC+oaf8rsCk5BS5cWok+kl48=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":309780},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"a3537796e0a2c4c27e0c3df317513043093a8f9d","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit -p tsconfig.json","prepublishOnly":"npm run typecheck && npm test && npm run build"},"_npmUser":{"name":"liankong233","email":"xhsw.new@outlook.com"},"_npmVersion":"11.6.2","description":"协议无关的 Agent 能力适配库：A2aImplAdaptor/A2aInvokeAdaptor 完成能力探测与调用，A2aGateway 经可配置的 A2A/ACP/MCP 多协议统一向外暴露，协议细节收拢在内部 binding 层","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@a2a-js/sdk":"^1.0.1","@agentclientprotocol/sdk":"^1.4.0","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.1.11","express":"^5.1.0","typescript":"5.9.3","@types/node":"24.13.3","@types/express":"^5.0.0"},"peerDependencies":{"express":"^4.21.2 || ^5.1.0"},"peerDependenciesMeta":{"express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/a2aw-ts_0.1.0_1787827448066_0.16044735502702823","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@codepre/a2aw-ts","version":"0.1.1","author":{"name":"liankong","email":"xhsw.new@outlook.com"},"license":"Apache-2.0","_id":"@codepre/a2aw-ts@0.1.1","maintainers":[{"name":"liankong233","email":"xhsw.new@outlook.com"}],"dist":{"shasum":"fb7abed301c7f59ab8df6d3817d29f5e96aaceef","tarball":"https://registry.npmjs.org/@codepre/a2aw-ts/-/a2aw-ts-0.1.1.tgz","fileCount":104,"integrity":"sha512-GA/VB+37UyxJlc51wwue24MCLaID1bmo6EFEu1Wmg8f9+/6hD5IYLM6TKqW/2ARUWHzj24kXG9XNck9Zi82kCg==","signatures":[{"sig":"MEUCIGKeHnR2LAI5THHKkvhiOrXQ+f2Bte47I65RUC2H3ytXAiEA56rYW2XMEyG1RXtQGcwCpJKce0CQRcf5RziuiXu8TEY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":320855},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"f515ffef96e02142bea7efaad742c1596d173be1","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit -p tsconfig.json","prepublishOnly":"npm run typecheck && npm test && npm run build"},"_npmUser":{"name":"liankong233","email":"xhsw.new@outlook.com"},"_npmVersion":"11.6.2","description":"协议无关的 Agent 能力适配库：A2aImplAdaptor/A2aInvokeAdaptor 完成能力探测与调用，A2aGateway 经可配置的 A2A/ACP/MCP 多协议统一向外暴露，协议细节收拢在内部 binding 层","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@a2a-js/sdk":"^1.0.1","@agentclientprotocol/sdk":"^1.4.0","@modelcontextprotocol/sdk":"^1.30.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"4.1.11","express":"^5.1.0","typescript":"5.9.3","@types/node":"24.13.3","@types/express":"^5.0.0"},"peerDependencies":{"express":"^4.21.2 || ^5.1.0"},"peerDependenciesMeta":{"express":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/a2aw-ts_0.1.1_1787829443569_0.026334906300655492","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@codepre/a2aw-ts","version":"0.2.0","description":"Agent-to-Agent(A2A) multi-protocol wrapper for TypeScript, support for A2A/ACP/MCP protocols.","license":"Apache-2.0","author":{"name":"liankong","email":"xhsw.new@outlook.com"},"repository":{"type":"git","url":"git+https://github.com/liankong233/a2aw-ts.git"},"type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./package.json":"./package.json"},"publishConfig":{"access":"public"},"engines":{"node":">=20"},"scripts":{"build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit -p tsconfig.json","test":"vitest run","prepublishOnly":"npm run typecheck && npm test && npm run build"},"dependencies":{"@a2a-js/sdk":"^1.0.1","@agentclientprotocol/sdk":"^1.4.0","@modelcontextprotocol/sdk":"^1.30.0"},"peerDependencies":{"express":"^4.21.2 || ^5.1.0"},"peerDependenciesMeta":{"express":{"optional":true}},"devDependencies":{"@fastify/express":"^4.0.7","@types/express":"^5.0.0","@types/node":"24.13.3","express":"^5.1.0","fastify":"^5.12.1","typescript":"5.9.3","vitest":"4.1.11"},"gitHead":"e8d0bc7f25bce0cdda651926654ba535be338663","_id":"@codepre/a2aw-ts@0.2.0","bugs":{"url":"https://github.com/liankong233/a2aw-ts/issues"},"homepage":"https://github.com/liankong233/a2aw-ts#readme","_nodeVersion":"24.11.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-oFzd5ODoDp4sDIi5reXQX1p9R23d43rxUWLcJ1B8MNNhgR2YPIwq++Ss0u+94y5/qblEcBLBHTiLMBjKonhc0A==","shasum":"1e40b7ec9ac51615e1e6a28647cefc051f7aca65","tarball":"https://registry.npmjs.org/@codepre/a2aw-ts/-/a2aw-ts-0.2.0.tgz","fileCount":104,"unpackedSize":349604,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFhe9lcJOQ+jRjJdZfGkw2vPPPZbEYvcxSAINeNRc+EiAiBQz7/MW0Te+xXFAl/4HbCX4BIpiTCCRvPByGDcxjB5Vw=="}]},"_npmUser":{"name":"liankong233","email":"xhsw.new@outlook.com"},"directories":{},"maintainers":[{"name":"liankong233","email":"xhsw.new@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/a2aw-ts_0.2.0_1787995140633_0.2963848878972377"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-27T10:44:07.820Z","modified":"2026-08-29T09:19:00.968Z","0.1.0":"2026-08-27T10:44:08.242Z","0.1.1":"2026-08-27T11:17:23.756Z","0.2.0":"2026-08-29T09:19:00.791Z"},"author":{"name":"liankong","email":"xhsw.new@outlook.com"},"license":"Apache-2.0","description":"Agent-to-Agent(A2A) multi-protocol wrapper for TypeScript, support for A2A/ACP/MCP protocols.","maintainers":[{"name":"liankong233","email":"xhsw.new@outlook.com"}],"readme":"# @codepre/a2aw-ts\n\n**Agent-to-Agent wrapper library for TypeScript**\n\nProtocol-agnostic Agent capability adaptation library: **`A2aImplAdaptor` (implementation side)**, **`A2aInvokeAdaptor` (invocation side)** and **`A2aGateway` (multi-protocol outbound gateway)** together cover all capability discovery, invocation and exposure. Consumers never touch the details of any Agent protocol (A2A / ACP / MCP), and no protocol SDK types ever appear on the public surface; adding a new protocol only requires a same-shaped module in the internal binding layer — the public API stays unchanged.\n\n**[中文文档 (Chinese docs)](./README-zh.md)**\n\n## Install\n\n```bash\nnpm install @codepre/a2aw-ts\n# server-side adaptors additionally require Express (see note below)\nnpm install express\n```\n\n**Requirements**: Node.js ≥ 20 and an ESM project (`\"type\": \"module\"`); TypeScript types ship in the package (`dist/index.d.ts`), no separate `@types` package.\n\n**Express note**: the implementation-side adaptors (`A2aImplAdaptor`, `A2aGateway`) mount HTTP handlers on an Express application, so Express is required to serve them. The package currently exposes a single entry point that loads the server-side bindings, so plain client-side usage (`A2aInvokeAdaptor`, `A2aInvokeAdaptor.invoke`, …) also needs Express installed at runtime — install it alongside unless you mount the handlers on another host via `@fastify/express` yourself.\n\nQuick start:\n\n```ts\nimport { A2aInvokeAdaptor, textMessage, messageText } from '@codepre/a2aw-ts';\n\nconst invoke = new A2aInvokeAdaptor('https://agent.example');\nconst view = await invoke.probe();                       // unified capability view\nconst task = await invoke.invoke({ message: textMessage('hello') });\nconsole.log(task.state, messageText(task.message));\n```\n\n## The three adaptors\n\n| Adaptor | Direction | Responsibility |\n| --- | --- | --- |\n| `A2aImplAdaptor` | external → internal | Exposes internal execution capabilities as a discoverable, callable server: capability declaration → outbound card, executor → task event stream, credential verification → request principal; `mount()` attaches HTTP handlers, `probe()` returns the local capability view |\n| `A2aInvokeAdaptor` | internal → external | Connects to remote Agents: `probe()` discovers capabilities (→ unified capability view), `invoke()` starts a task and waits for a terminal state (or an `input-required` pause, resume via `taskId`), `invokeStream()` subscribes to event streams, `getTask()` / `cancel()` manage tasks |\n| `A2aGateway` | external → internal | **Unified outbound gateway**: one capability implementation exposed simultaneously over configurable multi-protocol transports — A2A (card discovery + task invocation) / ACP (session-style prompt-driven) / MCP (skills → tools) — sharing the executor and credential verifier |\n\n## Quick start\n\n### Implementation side: expose internal capabilities\n\n```ts\nimport express from 'express';\nimport { A2aImplAdaptor, extractBearerToken } from '@codepre/a2aw-ts';\n\nconst impl = new A2aImplAdaptor({\n  capabilities: {\n    name: 'codepre',\n    description: 'Remote Agent exported by Codepre',\n    version: '1.0.0',\n    skills: [{ name: 'run-task', description: 'Run Codepre tasks' }],\n    capabilities: { streaming: true },\n    auth: [{ key: 'bearer', kind: 'http', name: 'bearer' }],\n  },\n  implement: async ({ taskId, message, user }, emit) => {\n    emit.text(`Received: ${message.parts[0]?.text ?? ''} (${user?.userName ?? 'anonymous'})`);\n    emit.status(taskId, 'completed');\n  },\n  auth: { verify: (headers) =>\n    extractBearerToken(headers) ? { userName: 'codepre' } : null },\n});\n\nconst app = express();\nimpl.mount(app); // /.well-known/agent-card.json + /jsonrpc + /api/rest\n```\n\n### Unified gateway: one implementation, multiple protocols\n\n```ts\nimport express from 'express';\nimport { A2aGateway, extractBearerToken } from '@codepre/a2aw-ts';\n\nconst gateway = new A2aGateway({\n  capabilities: {\n    name: 'codepre',\n    description: 'Remote Agent exported by Codepre',\n    skills: [{ name: 'run-task', description: 'Run Codepre tasks' }],\n  },\n  implement: async ({ taskId, message }, emit) => {\n    emit.text(`Received: ${message.parts[0]?.text ?? ''}`);\n    emit.status(taskId, 'completed');\n  },\n  auth: { verify: (headers) =>\n    extractBearerToken(headers) ? { userName: 'codepre' } : null },\n  // Omitting transports enables all three protocols; when given explicitly,\n  // only the listed transports are enabled (whitelist semantics)\n  transports: {\n    a2a: true,                       // /.well-known/agent-card.json + /jsonrpc + /api/rest\n    acp: { path: '/acp' },           // session style: session/prompt drives the executor, chunks stream back\n    mcp: { path: '/mcp' },           // tool style: skills → tools/list + tools/call\n  },\n});\ngateway.mount(app);\n```\n\nGate semantics differ slightly per protocol: A2A lets requests without credentials through to the protocol layer (principal unknown); ACP also admits requests without credentials, but any invalid credentials are rejected with 401; MCP requires valid credentials on every request once `verify` is configured. Note: each binding reads the raw request body itself, so the host must not attach a global `express.json()` middleware before them.\n\n### Invocation side: probe and call remote Agents\n\n```ts\nimport {\n  A2aInvokeAdaptor,\n  bearerTokenProvider,\n  textMessage,\n  messageText,\n} from '@codepre/a2aw-ts';\n\nconst invoke = new A2aInvokeAdaptor('https://agent.example', {\n  fetch: networkClient.fetch,                    // custom fetch replacement (optional)\n  auth: bearerTokenProvider(readSecretRefToken), // credential source (optional)\n});\nconst view = await invoke.probe();               // unified capability view: skills / switches / auth requirements / transport bindings\nconst task = await invoke.invoke({ message: textMessage('hello') }); // waits for a terminal state or an input-required pause\nconsole.log(task.state, messageText(task.message));\n```\n\n## Unified data model (all protocol-agnostic)\n\n- `CapabilityDeclaration`: local capability declaration (name/description/skills/capability switches/auth schemes), the input of `A2aImplAdaptor`;\n- `CapabilityView`: remote discovery view (with `auth.required` / `auth.schemes` and transport bindings), the output of `probe()`;\n- `AgentMessage`: message (`role: 'user' | 'agent'` + parts; text parts are currently supported, see `AgentMessagePart` for extension points); `textMessage()` / `messageText()` conveniences;\n- `AgentTask` / `AgentTaskState`: task snapshot and state machine (terminal states = completed / failed / canceled / rejected);\n- `AgentTaskEvent`: task event stream (task / status / message / artifact).\n\n## Error model\n\n| Error | Scenario | codes |\n| --- | --- | --- |\n| `AuthError` | auth error classification helper (HTTP gate failures surface as 401 and do not throw this type; use it to normalize auth semantics in your own call chains) | `unauthorized` / `forbidden` / `credentials-unavailable` / `challenge` |\n| `AgentInvokeError` | invocation path | `timeout` / `canceled` / `task-failed` / `task-not-found` / `invalid-request` / `unexpected` |\n\n`invoke()` throws `AgentInvokeError('task-failed')` with the final task snapshot attached (`error.task`) when the terminal state is failed / rejected; a timeout while waiting for a terminal state throws `timeout`; aborting via `AbortSignal` throws `canceled`; when the task enters `input-required` (the Agent asks for more input) or `auth-required` (the Agent demands credentials first), it returns the non-terminal snapshot and the caller resumes via `taskId` / `contextId` (the snapshot carries the server-assigned `contextId` for multi-turn mapping). Pass `verifyCardSignature` on the invoke adaptor to enforce AgentCard JWS signature verification during `probe()`.\n\n### Link resilience\n\n- `invoke()` tolerates transient network faults during polling (fetch failures, connection resets, socket hangs) — a jitter mid-task does not kill the call; without a `timeoutMs` it gives up after a bounded number of consecutive failures so a dead remote does not hang forever.\n- `invokeStreaming()` is the stream-first resilient path (per §4.14): it consumes the SSE event stream and, if the stream ends or drops before a terminal state (server shut the stream / proxy timeout), **falls back to polling `getTask`** to finish the task; non-streaming cards degrade gracefully through the SDK and are finished the same way. Use it for long tasks over unstable links.\n- `invokeStream()` stays a low-level subscriber: when the server closes the stream it ends normally without an exception — check the last event yourself, or use `invokeStreaming` for automatic wrap-up.\n\n## Layout\n\n```\nsrc/\n  model/     protocol-agnostic data model (message / task / capability / types)\n  impl/      A2aImplAdaptor (implementation-side adaptor)\n  invoke/    A2aInvokeAdaptor + AgentInvokeError (invocation-side adaptor)\n  gateway/   A2aGateway (multi-protocol outbound gateway)\n  common/    auth header providers (auth.ts), fetch injection (fetch.ts), auth errors (errors.ts)\n  binding/   protocol binding layer (not exported)\n    a2a/       A2A transport, AgentCard, task state machine, model↔SDK conversion (model.ts)\n    acp/       ACP authorization gate + gateway binding (gateway.ts: capability model → AgentApp)\n    mcp/       gateway binding (server.ts: stateless Streamable HTTP on the official @modelcontextprotocol/sdk)\ntests/     vitest tests (real node:http / Express pipelines; public-surface tests import no protocol SDKs)\n```\n\nLayering rule: `model/` and the three adaptors depend on no protocol SDK; only `binding/` depends on `@a2a-js/sdk` / `@agentclientprotocol/sdk` / `@modelcontextprotocol/sdk` (Express is an optional peer). **Adding a protocol = adding one binding module + one entry in the gateway transport config**, public API unchanged.\n\n## Gates\n\n```bash\nnpm run typecheck   # tsc --noEmit\nnpm test            # vitest run\n```\n\n## License\n\n[Apache-2.0](./LICENSE)\n","readmeFilename":"README.md","homepage":"https://github.com/liankong233/a2aw-ts#readme","repository":{"type":"git","url":"git+https://github.com/liankong233/a2aw-ts.git"},"bugs":{"url":"https://github.com/liankong233/a2aw-ts/issues"}}