{"_id":"@drew-foxall/a2a-ai-provider-v3","_rev":"2-ca4e46dcd77b3d00727cf44573ad7d24","name":"@drew-foxall/a2a-ai-provider-v3","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@drew-foxall/a2a-ai-provider-v3","version":"1.0.0","keywords":["a2a","ai-sdk","language-model","v3","agent-to-agent","multi-agent","vercel","streaming","llm","ai","agent","protocol"],"author":{"name":"Drew Foxall"},"license":"Apache-2.0","_id":"@drew-foxall/a2a-ai-provider-v3@1.0.0","maintainers":[{"name":"drew-foxall","email":"drew@foxalltogether.com"}],"homepage":"https://github.com/drew-foxall/a2a-js-sdk-examples/tree/main/packages/a2a-ai-provider-v3","bugs":{"url":"https://github.com/drew-foxall/a2a-js-sdk-examples/issues"},"dist":{"shasum":"e1cdbd2e03a467bd5710e74df052217162bcce8c","tarball":"https://registry.npmjs.org/@drew-foxall/a2a-ai-provider-v3/-/a2a-ai-provider-v3-1.0.0.tgz","fileCount":28,"integrity":"sha512-xMpqZevqKFejVnOTApTkg7MVq0LpWMailWMbwXgFTYVPCAitp9U7a/7YPAXki1BHAhU3sQOjAj4jQ8DPjNCypg==","signatures":[{"sig":"MEUCIA+ipcA119oQXTGQV9kjQh+k1r8sgxxP+QHRhAvay8CmAiEA/mCta5JR1XgzH8TbtQrZhIZbbb2o+ZdEm4Q7tCucbhA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":178866},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=24.0.0","pnpm":">=10.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"f6bc3e17bb19ef62f5ef3be3580ec9f8cf639b16","scripts":{"lint":"pnpm exec biome check .","test":"vitest run","build":"tsc","format":"pnpm exec biome format .","lint:fix":"pnpm exec biome check --write --unsafe .","typecheck":"tsc --noEmit","test:watch":"vitest","format:write":"pnpm exec biome format --write ."},"_npmUser":{"name":"drew-foxall","email":"drew@foxalltogether.com"},"repository":{"url":"git+https://github.com/drew-foxall/a2a-js-sdk-examples.git","type":"git","directory":"packages/a2a-ai-provider-v3"},"_npmVersion":"11.6.4","description":"AI SDK LanguageModelV3 provider for A2A protocol - enables agent-to-agent communication","directories":{},"sideEffects":false,"_nodeVersion":"22.16.0","dependencies":{"@ai-sdk/provider":"3.0.0-beta.16","@ai-sdk/provider-utils":"4.0.0-beta.41","@drew-foxall/a2a-js-sdk":"^0.4.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.23.0","devDependencies":{"vitest":"^4.0.14","typescript":"^5.9.3","@types/node":"^24.10.1","@total-typescript/tsconfig":"1.0.4"},"peerDependencies":{"ai":">=6.0.0-beta.0"},"_npmOperationalInternal":{"tmp":"tmp/a2a-ai-provider-v3_1.0.0_1765877042980_0.498827374267123","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@drew-foxall/a2a-ai-provider-v3","version":"1.1.0","type":"module","description":"AI SDK LanguageModelV3 provider for A2A protocol - enables agent-to-agent communication","author":{"name":"Drew Foxall"},"license":"Apache-2.0","homepage":"https://github.com/drew-foxall/a2a-js-sdk-examples/tree/main/packages/a2a-ai-provider-v3","repository":{"type":"git","url":"git+https://github.com/drew-foxall/a2a-js-sdk-examples.git","directory":"packages/a2a-ai-provider-v3"},"bugs":{"url":"https://github.com/drew-foxall/a2a-js-sdk-examples/issues"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","sideEffects":false,"scripts":{"build":"tsc","typecheck":"tsc --noEmit","test":"vitest run","test:watch":"vitest","lint":"pnpm exec biome check .","lint:fix":"pnpm exec biome check --write --unsafe .","format":"pnpm exec biome format .","format:write":"pnpm exec biome format --write ."},"dependencies":{"@ai-sdk/provider":"3.0.0","@ai-sdk/provider-utils":"4.0.1","@drew-foxall/a2a-js-sdk":"^0.4.2"},"devDependencies":{"@total-typescript/tsconfig":"1.0.4","@types/node":"^24.10.1","typescript":"^5.9.3","vitest":"^4.0.14"},"peerDependencies":{"ai":">=6.0.0"},"packageManager":"pnpm@10.23.0","engines":{"node":"24.x","pnpm":">=10.0.0"},"keywords":["a2a","ai-sdk","language-model","v3","agent-to-agent","multi-agent","vercel","streaming","llm","ai","agent","protocol"],"publishConfig":{"access":"public"},"gitHead":"c836b031af950892a6f6158ed6f563a947199c64","_id":"@drew-foxall/a2a-ai-provider-v3@1.1.0","_nodeVersion":"22.16.0","_npmVersion":"11.6.4","dist":{"integrity":"sha512-VNL0QK2tIV4THFKK8rVySAYDnhCk9MLqN8UWIdJob0AhfCoAHgma9BqBUGGOofxuoEaaniQI8vmCTh18uzSmlQ==","shasum":"ec1367367f4f93b189d31054efc1a2e904b484a4","tarball":"https://registry.npmjs.org/@drew-foxall/a2a-ai-provider-v3/-/a2a-ai-provider-v3-1.1.0.tgz","fileCount":28,"unpackedSize":198001,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDFTz9dQYfhfBCPiqMdjRyGLQQ2tw7K2pbgUgIG0bgrfQIgIc0qw8UOOtLmnZFekGZtgKfAOH+wQhum2dRl/W27MhQ="}]},"_npmUser":{"name":"drew-foxall","email":"drew@foxalltogether.com"},"directories":{},"maintainers":[{"name":"drew-foxall","email":"drew@foxalltogether.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/a2a-ai-provider-v3_1.1.0_1767554327319_0.7134720514051553"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-16T09:24:02.901Z","modified":"2026-01-04T19:18:47.710Z","1.0.0":"2025-12-16T09:24:03.139Z","1.1.0":"2026-01-04T19:18:47.517Z"},"bugs":{"url":"https://github.com/drew-foxall/a2a-js-sdk-examples/issues"},"author":{"name":"Drew Foxall"},"license":"Apache-2.0","homepage":"https://github.com/drew-foxall/a2a-js-sdk-examples/tree/main/packages/a2a-ai-provider-v3","keywords":["a2a","ai-sdk","language-model","v3","agent-to-agent","multi-agent","vercel","streaming","llm","ai","agent","protocol"],"repository":{"type":"git","url":"git+https://github.com/drew-foxall/a2a-js-sdk-examples.git","directory":"packages/a2a-ai-provider-v3"},"description":"AI SDK LanguageModelV3 provider for A2A protocol - enables agent-to-agent communication","maintainers":[{"name":"drew-foxall","email":"drew@foxalltogether.com"}],"readme":"# @drew-foxall/a2a-ai-provider-v3\n\nAI SDK LanguageModelV3 provider for [A2A protocol](https://a2a-protocol.org/). Enables seamless agent-to-agent communication using the latest AI SDK specification.\n\n## Why V3?\n\nThe AI SDK has evolved from `LanguageModelV2` to `LanguageModelV3`, which includes:\n\n- Enhanced multi-modal support (files, images, audio)\n- Improved streaming with better part types\n- Provider metadata for agent context\n- Better tool call handling\n\nThis provider implements `LanguageModelV3` to ensure full compatibility with the latest AI SDK features.\n\n## Installation\n\n```bash\npnpm add @drew-foxall/a2a-ai-provider-v3\n```\n\n## Quick Start\n\n```typescript\nimport { a2aV3 } from '@drew-foxall/a2a-ai-provider-v3';\nimport { generateText, streamText } from 'ai';\n\n// Non-streaming\nconst result = await generateText({\n  model: a2aV3('http://localhost:3001'),\n  prompt: 'What is the weather in Paris?',\n});\n\nconsole.log(result.text);\n\n// Streaming\nconst stream = await streamText({\n  model: a2aV3('http://localhost:3001'),\n  prompt: 'Plan a trip to Tokyo',\n});\n\nfor await (const chunk of stream.textStream) {\n  process.stdout.write(chunk);\n}\n```\n\n## Agent Discovery\n\nThe A2A protocol defines a [standard discovery mechanism](https://a2a-protocol.org/latest/topics/agent-discovery/) using well-known URIs.\n\n### Discover Agent from Domain\n\n```typescript\nimport { discoverAgent, a2aV3 } from '@drew-foxall/a2a-ai-provider-v3';\nimport { generateText } from 'ai';\n\n// Discover agent using well-known URI (/.well-known/agent-card.json)\nconst { agentUrl, agentCard } = await discoverAgent('travel-agent.example.com');\n\nconsole.log(`Discovered: ${agentCard.name}`);\nconsole.log(`Skills: ${agentCard.skills?.map(s => s.name).join(', ')}`);\n\n// Use the discovered agent\nconst result = await generateText({\n  model: a2aV3(agentUrl),\n  prompt: 'Plan a trip to Paris',\n});\n```\n\n### Fetch Agent Card Directly\n\n```typescript\nimport { fetchAgentCard } from '@drew-foxall/a2a-ai-provider-v3';\n\n// When you know the agent card URL\nconst { agentUrl, agentCard } = await fetchAgentCard(\n  'https://api.example.com/agents/travel/card.json'\n);\n```\n\n### Check Agent Capabilities\n\n```typescript\nimport { discoverAgent, supportsCapability, getAuthSchemes } from '@drew-foxall/a2a-ai-provider-v3';\n\nconst { agentCard } = await discoverAgent('agent.example.com');\n\n// Check capabilities\nif (supportsCapability(agentCard, 'streaming')) {\n  console.log('Agent supports streaming');\n}\n\n// Get authentication schemes\nconst schemes = getAuthSchemes(agentCard);\nconsole.log('Auth schemes:', schemes); // e.g., ['bearer', 'oauth2']\n```\n\n## Authentication\n\nA2A agents may require authentication. Configure auth headers in the discovery options or at the provider level.\n\n### Discovery with Authentication\n\n```typescript\nimport { discoverAgent } from '@drew-foxall/a2a-ai-provider-v3';\n\nconst { agentUrl, agentCard } = await discoverAgent('internal-agent.corp.example.com', {\n  headers: {\n    'Authorization': 'Bearer your-access-token',\n  },\n});\n```\n\n### Authentication for Requests\n\nThe A2A SDK's `ClientFactory` handles authentication. Configure auth in your environment or pass headers:\n\n```typescript\nimport { a2aV3 } from '@drew-foxall/a2a-ai-provider-v3';\nimport { generateText } from 'ai';\n\n// Option 1: Environment variable (if supported by the A2A SDK)\n// Set A2A_AUTH_TOKEN or similar in your environment\n\n// Option 2: Use a custom fetch with auth headers\n// This requires configuring the ClientFactory separately\n\n// Option 3: Service bindings (Cloudflare Workers)\n// For Cloudflare Workers, use service bindings instead of HTTP auth\n```\n\n### OAuth 2.0 Authentication\n\nFor agents requiring OAuth 2.0:\n\n```typescript\nimport { discoverAgent, getAuthSchemes, a2aV3 } from '@drew-foxall/a2a-ai-provider-v3';\n\nconst { agentUrl, agentCard } = await discoverAgent('agent.example.com');\nconst schemes = getAuthSchemes(agentCard);\n\nif (schemes.includes('oauth2')) {\n  // Get token from your OAuth provider\n  const token = await getOAuthToken(agentCard.securitySchemes?.oauth2);\n  \n  // The A2A SDK will use this token for requests\n  // Configure via environment or ClientFactory\n}\n```\n\n## Multi-Turn Conversations\n\nUse `contextId` to maintain conversation context across multiple requests:\n\n```typescript\nimport { a2aV3 } from '@drew-foxall/a2a-ai-provider-v3';\nimport { generateText } from 'ai';\n\n// First message\nconst result1 = await generateText({\n  model: a2aV3('http://localhost:3001'),\n  prompt: 'What is the weather in Paris?',\n});\n\n// Get contextId from metadata for follow-up\nconst contextId = result1.providerMetadata?.a2a?.contextId;\n\n// Follow-up message in same conversation\nconst result2 = await generateText({\n  model: a2aV3('http://localhost:3001'),\n  prompt: 'What about tomorrow?',\n  providerOptions: {\n    a2a: { contextId },\n  },\n});\n```\n\n## Handling Input-Required State\n\nA2A agents can signal they need more user input via the `input-required` task state:\n\n```typescript\nimport { a2aV3 } from '@drew-foxall/a2a-ai-provider-v3';\nimport { generateText } from 'ai';\n\nconst result = await generateText({\n  model: a2aV3('http://localhost:3001'),\n  prompt: 'Plan a trip',\n});\n\n// Check if agent needs more input\nif (result.providerMetadata?.a2a?.inputRequired) {\n  console.log('Agent needs more information');\n  \n  // Access the status message for context\n  const statusParts = result.providerMetadata.a2a.statusMessage?.parts;\n  for (const part of statusParts ?? []) {\n    if (part.kind === 'text') {\n      console.log('Agent says:', part.text);\n    }\n  }\n\n  // Send follow-up with taskId to continue\n  const followUp = await generateText({\n    model: a2aV3('http://localhost:3001'),\n    prompt: 'I want to go to Paris for 3 days',\n    providerOptions: {\n      a2a: {\n        taskId: result.providerMetadata.a2a.taskId,\n        contextId: result.providerMetadata.a2a.contextId,\n      },\n    },\n  });\n}\n```\n\n## Custom Events with DataParts\n\nSend structured data to agents using custom parts:\n\n```typescript\nimport { a2aV3 } from '@drew-foxall/a2a-ai-provider-v3';\nimport { generateText } from 'ai';\n\nconst result = await generateText({\n  model: a2aV3('http://localhost:3001'),\n  prompt: 'Process this selection',\n  providerOptions: {\n    a2a: {\n      // Include custom data parts\n      customParts: [\n        {\n          kind: 'data',\n          data: {\n            eventType: 'user-selection',\n            selectedItems: ['item-1', 'item-2'],\n            timestamp: new Date().toISOString(),\n          },\n        },\n      ],\n      // Message-level metadata\n      metadata: {\n        source: 'web-ui',\n        sessionId: 'abc-123',\n      },\n    },\n  },\n});\n```\n\n## Accessing Artifacts\n\nA2A agents can return artifacts (documents, images, structured data):\n\n```typescript\nimport { a2aV3 } from '@drew-foxall/a2a-ai-provider-v3';\nimport { generateText } from 'ai';\n\nconst result = await generateText({\n  model: a2aV3('http://localhost:3001'),\n  prompt: 'Generate a travel itinerary',\n});\n\n// Access artifacts from metadata\nconst artifacts = result.providerMetadata?.a2a?.artifacts ?? [];\n\nfor (const artifact of artifacts) {\n  console.log(`Artifact: ${artifact.name} (${artifact.artifactId})`);\n  \n  for (const part of artifact.parts) {\n    if (part.kind === 'text') {\n      console.log('Content:', part.text);\n    } else if (part.kind === 'file') {\n      console.log('File:', part.file?.name, part.file?.mimeType);\n    } else if (part.kind === 'data') {\n      console.log('Data:', part.data);\n    }\n  }\n}\n```\n\n## Multi-Agent Communication\n\nOrchestrate multiple A2A agents:\n\n```typescript\nimport { a2aV3, discoverAgent } from '@drew-foxall/a2a-ai-provider-v3';\nimport { generateText } from 'ai';\n\n// Discover agents\nconst weather = await discoverAgent('weather-agent.example.com');\nconst hotels = await discoverAgent('hotel-agent.example.com');\nconst flights = await discoverAgent('flight-agent.example.com');\n\n// Weather agent\nconst weatherResult = await generateText({\n  model: a2aV3(weather.agentUrl),\n  prompt: 'Get weather forecast for Paris next week',\n});\n\n// Hotel agent (using weather context)\nconst hotelResult = await generateText({\n  model: a2aV3(hotels.agentUrl),\n  prompt: `Find hotels in Paris. Weather forecast: ${weatherResult.text}`,\n});\n\n// Flight agent\nconst flightResult = await generateText({\n  model: a2aV3(flights.agentUrl),\n  prompt: 'Find flights to Paris departing Monday',\n});\n\nconsole.log('Trip planned!');\nconsole.log('Weather:', weatherResult.text);\nconsole.log('Hotels:', hotelResult.text);\nconsole.log('Flights:', flightResult.text);\n```\n\n## API Reference\n\n### Provider\n\n#### `a2aV3(agentUrl, settings?)`\n\nDefault provider instance.\n\n- `agentUrl`: URL of the A2A agent\n- `settings.contextId`: Context ID for conversation continuity\n- `settings.taskId`: Task ID for resuming tasks\n\n#### `createA2aV3(options?)`\n\nCreate a custom provider.\n\n- `options.generateId`: Custom ID generator function\n\n### Discovery\n\n#### `discoverAgent(domain, options?)`\n\nDiscover an agent via well-known URI (`/.well-known/agent-card.json`).\n\n- `domain`: Domain or base URL\n- `options.headers`: Custom headers (e.g., for auth)\n- `options.timeout`: Request timeout in ms (default: 10000)\n- `options.fetch`: Custom fetch implementation\n\nReturns `{ agentUrl, agentCard }`.\n\n#### `fetchAgentCard(cardUrl, options?)`\n\nFetch an agent card from a direct URL.\n\n#### `supportsCapability(agentCard, capability)`\n\nCheck if an agent supports a capability (`streaming`, `pushNotifications`, `stateTransitionHistory`).\n\n#### `getAuthSchemes(agentCard)`\n\nGet authentication scheme identifiers from an agent card.\n\n### Provider Metadata\n\nAccess A2A-specific information via `result.providerMetadata.a2a`:\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `taskId` | `string \\| null` | Task ID for follow-up messages |\n| `contextId` | `string \\| null` | Context ID for conversation continuity |\n| `taskState` | `TaskState \\| null` | Current task state |\n| `inputRequired` | `boolean` | True when agent needs more input |\n| `authRequired` | `boolean` | True when agent needs authentication |\n| `statusMessage` | `object \\| null` | Full status message with parts |\n| `finalText` | `string \\| null` | Authoritative final text (for streaming) |\n| `artifacts` | `array` | Task artifacts with parts and metadata |\n| `metadata` | `object \\| null` | Task-level extension metadata |\n\n### Provider Options\n\nPass A2A-specific options via `providerOptions.a2a`:\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `contextId` | `string` | Continue a conversation |\n| `taskId` | `string` | Resume an existing task |\n| `customParts` | `array` | Additional data parts to send |\n| `metadata` | `object` | Message-level metadata |\n| `requestMetadata` | `object` | Request-level metadata |\n\n## A2A Protocol Compatibility\n\nThis provider supports the [A2A protocol](https://a2a-protocol.org/):\n\n| Feature | Status | Notes |\n|---------|--------|-------|\n| JSON-RPC transport | ✅ | Full support |\n| Streaming (SSE) | ✅ | With fallback for non-streaming agents |\n| TextPart | ✅ | Full support |\n| FilePart | ✅ | Base64 bytes and URI |\n| DataPart | ✅ | For custom events |\n| Artifacts | ✅ | Exposed via providerMetadata |\n| Task states | ✅ | All states mapped |\n| input-required | ✅ | Explicit `inputRequired` flag |\n| auth-required | ✅ | Explicit `authRequired` flag |\n| contextId | ✅ | Conversation continuity |\n| Agent discovery | ✅ | Well-known URI support |\n| Push notifications | ❌ | AI SDK limitation |\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}