apcore-a2a 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +234 -0
- package/dist/adapters/agent-card.d.ts +32 -0
- package/dist/adapters/agent-card.d.ts.map +1 -0
- package/dist/adapters/agent-card.js +49 -0
- package/dist/adapters/agent-card.js.map +1 -0
- package/dist/adapters/errors.d.ts +10 -0
- package/dist/adapters/errors.d.ts.map +1 -0
- package/dist/adapters/errors.js +48 -0
- package/dist/adapters/errors.js.map +1 -0
- package/dist/adapters/index.d.ts +6 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +6 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/parts.d.ts +10 -0
- package/dist/adapters/parts.d.ts.map +1 -0
- package/dist/adapters/parts.js +53 -0
- package/dist/adapters/parts.js.map +1 -0
- package/dist/adapters/schema.d.ts +15 -0
- package/dist/adapters/schema.d.ts.map +1 -0
- package/dist/adapters/schema.js +77 -0
- package/dist/adapters/schema.js.map +1 -0
- package/dist/adapters/skill-mapper.d.ts +20 -0
- package/dist/adapters/skill-mapper.d.ts.map +1 -0
- package/dist/adapters/skill-mapper.js +46 -0
- package/dist/adapters/skill-mapper.js.map +1 -0
- package/dist/auth/index.d.ts +5 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +4 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/jwt.d.ts +30 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +76 -0
- package/dist/auth/jwt.js.map +1 -0
- package/dist/auth/middleware.d.ts +10 -0
- package/dist/auth/middleware.d.ts.map +1 -0
- package/dist/auth/middleware.js +33 -0
- package/dist/auth/middleware.js.map +1 -0
- package/dist/auth/storage.d.ts +5 -0
- package/dist/auth/storage.d.ts.map +1 -0
- package/dist/auth/storage.js +6 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/auth/types.d.ts +6 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +174 -0
- package/dist/cli.js.map +1 -0
- package/dist/client/card-fetcher.d.ts +13 -0
- package/dist/client/card-fetcher.d.ts.map +1 -0
- package/dist/client/card-fetcher.js +34 -0
- package/dist/client/card-fetcher.js.map +1 -0
- package/dist/client/client.d.ts +30 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +155 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/exceptions.d.ts +20 -0
- package/dist/client/exceptions.d.ts.map +1 -0
- package/dist/client/exceptions.js +32 -0
- package/dist/client/exceptions.js.map +1 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +4 -0
- package/dist/client/index.js.map +1 -0
- package/dist/explorer/handler.d.ts +4 -0
- package/dist/explorer/handler.d.ts.map +1 -0
- package/dist/explorer/handler.js +28 -0
- package/dist/explorer/handler.js.map +1 -0
- package/dist/explorer/index.d.ts +2 -0
- package/dist/explorer/index.d.ts.map +1 -0
- package/dist/explorer/index.html +760 -0
- package/dist/explorer/index.js +2 -0
- package/dist/explorer/index.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/serve.d.ts +38 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/serve.js +98 -0
- package/dist/serve.js.map +1 -0
- package/dist/server/executor.d.ts +26 -0
- package/dist/server/executor.d.ts.map +1 -0
- package/dist/server/executor.js +191 -0
- package/dist/server/executor.js.map +1 -0
- package/dist/server/factory.d.ts +33 -0
- package/dist/server/factory.d.ts.map +1 -0
- package/dist/server/factory.js +177 -0
- package/dist/server/factory.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -0
- package/package.json +80 -0
package/README.md
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/aipartnerup/apcore-a2a/main/apcore-a2a-logo.svg" alt="apcore-a2a logo" width="200"/>
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
# apcore-a2a (TypeScript)
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/apcore-a2a)
|
|
8
|
+
[](https://www.npmjs.com/package/apcore-a2a)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://github.com/aipartnerup/apcore-a2a-typescript)
|
|
11
|
+
|
|
12
|
+
## What is apcore-a2a?
|
|
13
|
+
|
|
14
|
+
**apcore-a2a** is the [A2A (Agent-to-Agent)](https://google.github.io/A2A/) protocol adapter for the [apcore](https://github.com/aipartnerup/apcore-typescript) ecosystem.
|
|
15
|
+
|
|
16
|
+
It solves a common problem: **you've built AI capabilities with apcore modules, but you need them to talk to other AI agents over a standard protocol.** apcore-a2a bridges that gap — it reads your existing module metadata (schemas, descriptions, examples) and automatically exposes them as a standards-compliant A2A server. No hand-written Agent Cards, no JSON-RPC boilerplate, no manual task lifecycle management.
|
|
17
|
+
|
|
18
|
+
**In short:** `apcore modules` + `apcore-a2a` = a fully functional A2A agent, ready to be discovered and invoked by any A2A-compatible client.
|
|
19
|
+
|
|
20
|
+
Built on [`@a2a-js/sdk`](https://www.npmjs.com/package/@a2a-js/sdk) and [Express 5](https://expressjs.com/).
|
|
21
|
+
|
|
22
|
+
> **Also available in Python:** [`apcore-a2a` (PyPI)](https://github.com/aipartnerup/apcore-a2a-python)
|
|
23
|
+
|
|
24
|
+
## Features
|
|
25
|
+
|
|
26
|
+
- **One-call server** — launch a compliant A2A server with `serve(registry)`
|
|
27
|
+
- **Automatic Agent Card** — `/.well-known/agent-card.json` generated from module metadata
|
|
28
|
+
- **Skill mapping** — apcore modules become A2A Skills with names, descriptions, tags, and examples
|
|
29
|
+
- **Full task lifecycle** — submitted, working, completed, failed, canceled, input-required
|
|
30
|
+
- **SSE streaming** — `message/stream` with real-time status and artifact updates
|
|
31
|
+
- **JWT authentication** — tokens bridged to apcore's Identity context
|
|
32
|
+
- **A2A Explorer UI** — browser UI for discovering and testing skills
|
|
33
|
+
- **Built-in client** — `A2AClient` for calling remote A2A agents
|
|
34
|
+
- **CLI support** — `npx apcore-a2a serve` for zero-code startup
|
|
35
|
+
- **Pluggable storage** — swap in Redis or PostgreSQL via the `TaskStore` interface
|
|
36
|
+
- **Observability** — `/health`, `/metrics` endpoints
|
|
37
|
+
- **Dynamic registration** — add/remove modules at runtime without restart
|
|
38
|
+
|
|
39
|
+
## Requirements
|
|
40
|
+
|
|
41
|
+
- Node.js >= 18.0.0
|
|
42
|
+
- `apcore-js` >= 0.8.0
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## For Users: Getting Started
|
|
47
|
+
|
|
48
|
+
### Installation
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npm install apcore-a2a
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Expose your modules as an A2A Agent
|
|
55
|
+
|
|
56
|
+
If you already have apcore modules, three lines turn them into a discoverable agent:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { Registry } from "apcore-js";
|
|
60
|
+
import { serve } from "apcore-a2a";
|
|
61
|
+
|
|
62
|
+
const registry = new Registry({ extensionsDir: "./extensions" });
|
|
63
|
+
|
|
64
|
+
serve(registry); // Starts on http://0.0.0.0:8000
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Your agent is now live at `http://localhost:8000/.well-known/agent-card.json`.
|
|
68
|
+
|
|
69
|
+
### CLI (zero-code)
|
|
70
|
+
|
|
71
|
+
No code needed — use the CLI to serve modules directly:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx apcore-a2a serve --extensions-dir ./extensions
|
|
75
|
+
npx apcore-a2a serve --extensions-dir ./extensions --port 3000 --explorer --metrics
|
|
76
|
+
npx apcore-a2a serve --extensions-dir ./extensions --auth-type bearer --auth-key mysecret
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Call a remote A2A Agent
|
|
80
|
+
|
|
81
|
+
Use the built-in client to discover and invoke any A2A-compliant agent:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { A2AClient } from "apcore-a2a";
|
|
85
|
+
|
|
86
|
+
const client = new A2AClient("http://agent.example.com", {
|
|
87
|
+
auth: "Bearer my-token",
|
|
88
|
+
timeout: 30_000,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Discover what the agent can do
|
|
92
|
+
const card = await client.discover();
|
|
93
|
+
console.log(`Agent: ${card.name}, Skills: ${card.skills.length}`);
|
|
94
|
+
|
|
95
|
+
// Send a message
|
|
96
|
+
const task = await client.sendMessage(
|
|
97
|
+
{ role: "user", parts: [{ kind: "text", text: "hello" }] },
|
|
98
|
+
{ contextId: "ctx-1" },
|
|
99
|
+
);
|
|
100
|
+
console.log(`Result: ${task.status.state}`);
|
|
101
|
+
|
|
102
|
+
// Or stream the response
|
|
103
|
+
for await (const event of client.streamMessage(message)) {
|
|
104
|
+
console.log(event);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
client.close();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Add authentication
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { JWTAuthenticator } from "apcore-a2a";
|
|
114
|
+
|
|
115
|
+
const auth = new JWTAuthenticator("your-secret-key", {
|
|
116
|
+
algorithms: ["HS256"],
|
|
117
|
+
issuer: "https://auth.example.com",
|
|
118
|
+
audience: "my-agent",
|
|
119
|
+
claimMapping: {
|
|
120
|
+
idClaim: "sub",
|
|
121
|
+
typeClaim: "type",
|
|
122
|
+
rolesClaim: "roles",
|
|
123
|
+
attrsClaims: ["org", "dept"],
|
|
124
|
+
},
|
|
125
|
+
requireClaims: ["sub"],
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
serve(registry, { auth });
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## For Developers: API Reference
|
|
134
|
+
|
|
135
|
+
### `serve()`
|
|
136
|
+
|
|
137
|
+
Blocking call — starts an HTTP server and serves until SIGINT/SIGTERM.
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
import { serve } from "apcore-a2a";
|
|
141
|
+
|
|
142
|
+
serve(registryOrExecutor, {
|
|
143
|
+
host: "0.0.0.0", // Bind host (default: "0.0.0.0")
|
|
144
|
+
port: 8000, // Bind port (default: 8000)
|
|
145
|
+
name: "my-agent", // Agent name (fallback: registry config)
|
|
146
|
+
description: "...", // Agent description
|
|
147
|
+
version: "1.0.0", // Agent version
|
|
148
|
+
url: "https://...", // Public URL (default: http://{host}:{port})
|
|
149
|
+
auth: authenticator, // Authenticator instance
|
|
150
|
+
taskStore: store, // TaskStore instance (default: InMemoryTaskStore)
|
|
151
|
+
corsOrigins: ["http://localhost:3000"],
|
|
152
|
+
explorer: true, // Enable A2A Explorer UI
|
|
153
|
+
explorerPrefix: "/explorer",
|
|
154
|
+
executionTimeout: 300_000, // ms (default: 300000)
|
|
155
|
+
metrics: true, // Enable /metrics endpoint
|
|
156
|
+
shutdownTimeout: 30, // Graceful shutdown timeout in seconds
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### `asyncServe()`
|
|
161
|
+
|
|
162
|
+
Returns the Express app without starting a server — use for embedding in larger applications or testing.
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
import { asyncServe } from "apcore-a2a";
|
|
166
|
+
|
|
167
|
+
const app = await asyncServe(registryOrExecutor, options);
|
|
168
|
+
// app is an Express application — mount it or start your own server
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### `TaskStore`
|
|
172
|
+
|
|
173
|
+
Default in-memory task store. Implement the `TaskStore` interface (`save`, `load`) for persistent backends.
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { InMemoryTaskStore } from "apcore-a2a/storage";
|
|
177
|
+
|
|
178
|
+
const store = new InMemoryTaskStore();
|
|
179
|
+
serve(registry, { taskStore: store });
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Architecture
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
apcore Registry
|
|
186
|
+
|
|
|
187
|
+
v
|
|
188
|
+
+---------------------------------------------+
|
|
189
|
+
| apcore-a2a |
|
|
190
|
+
| +----------+ +-----------+ +----------+ |
|
|
191
|
+
| | Adapters | | Server | | Auth | |
|
|
192
|
+
| | SkillMap | | Executor | | JWT | |
|
|
193
|
+
| | Schema | | Factory | | Middle | |
|
|
194
|
+
| | Parts | | Health | | Storage | |
|
|
195
|
+
| | ErrorMap | | Metrics | | | |
|
|
196
|
+
| | AgentCard| | | | | |
|
|
197
|
+
| +----------+ +-----------+ +----------+ |
|
|
198
|
+
| +----------+ +-----------+ |
|
|
199
|
+
| | Client | | Explorer | |
|
|
200
|
+
| | A2AClient| | HTML UI | |
|
|
201
|
+
| | CardFetch| | | |
|
|
202
|
+
| +----------+ +-----------+ |
|
|
203
|
+
+---------------------------------------------+
|
|
204
|
+
|
|
|
205
|
+
v
|
|
206
|
+
@a2a-js/sdk + Express 5
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
| A2A Concept | apcore Mapping |
|
|
210
|
+
| -------------- | ----------------------------------------- |
|
|
211
|
+
| **Agent Card** | Derived from Registry configuration |
|
|
212
|
+
| **Skill** | Maps 1:1 to an apcore Module |
|
|
213
|
+
| **Task** | Managed execution of `Executor.callAsync()` |
|
|
214
|
+
| **Streaming** | Wrapped `Executor.stream()` via SSE |
|
|
215
|
+
| **Security** | Bridged to apcore's `Identity` context |
|
|
216
|
+
|
|
217
|
+
### Contributing
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
git clone https://github.com/aipartnerup/apcore-a2a-typescript.git
|
|
221
|
+
cd apcore-a2a-typescript
|
|
222
|
+
npm install
|
|
223
|
+
npm test
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Documentation
|
|
227
|
+
|
|
228
|
+
- [Product Requirements (PRD)](https://github.com/aipartnerup/apcore-a2a/blob/main/docs/apcore-a2a/prd.md)
|
|
229
|
+
- [Technical Design](https://github.com/aipartnerup/apcore-a2a/blob/main/docs/apcore-a2a/tech-design.md)
|
|
230
|
+
- [Software Requirements (SRS)](https://github.com/aipartnerup/apcore-a2a/blob/main/docs/apcore-a2a/srs.md)
|
|
231
|
+
|
|
232
|
+
## License
|
|
233
|
+
|
|
234
|
+
Apache 2.0 — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AgentCapabilities, AgentCard } from "@a2a-js/sdk";
|
|
2
|
+
import { SkillMapper, type ModuleDescriptor } from "./skill-mapper.js";
|
|
3
|
+
export interface Registry {
|
|
4
|
+
list(): string[];
|
|
5
|
+
getDefinition(moduleId: string): ModuleDescriptor | null;
|
|
6
|
+
register?(moduleId: string, descriptor: unknown): void;
|
|
7
|
+
}
|
|
8
|
+
export declare class AgentCardBuilder {
|
|
9
|
+
private skillMapper;
|
|
10
|
+
private cachedCard;
|
|
11
|
+
constructor(skillMapper: SkillMapper);
|
|
12
|
+
build(registry: Registry, opts: {
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
version: string;
|
|
16
|
+
url: string;
|
|
17
|
+
capabilities: AgentCapabilities;
|
|
18
|
+
securitySchemes?: Record<string, unknown>;
|
|
19
|
+
}): AgentCard;
|
|
20
|
+
getCachedOrBuild(registry: Registry, opts: {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
version: string;
|
|
24
|
+
url: string;
|
|
25
|
+
capabilities: AgentCapabilities;
|
|
26
|
+
securitySchemes?: Record<string, unknown>;
|
|
27
|
+
}): AgentCard;
|
|
28
|
+
buildExtended(baseCard: AgentCard): AgentCard;
|
|
29
|
+
invalidateCache(): void;
|
|
30
|
+
private buildSkills;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=agent-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-card.d.ts","sourceRoot":"","sources":["../../src/adapters/agent-card.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAc,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEvE,MAAM,WAAW,QAAQ;IACvB,IAAI,IAAI,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAAC;IACzD,QAAQ,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;CACxD;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,UAAU,CAA0B;gBAEhC,WAAW,EAAE,WAAW;IAIpC,KAAK,CACH,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,YAAY,EAAE,iBAAiB,CAAC;QAChC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC3C,GACA,SAAS;IAqBZ,gBAAgB,CACd,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,GAAG,EAAE,MAAM,CAAC;QACZ,YAAY,EAAE,iBAAiB,CAAC;QAChC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC3C,GACA,SAAS;IAKZ,aAAa,CAAC,QAAQ,EAAE,SAAS,GAAG,SAAS;IAI7C,eAAe,IAAI,IAAI;IAIvB,OAAO,CAAC,WAAW;CAUpB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export class AgentCardBuilder {
|
|
2
|
+
skillMapper;
|
|
3
|
+
cachedCard = null;
|
|
4
|
+
constructor(skillMapper) {
|
|
5
|
+
this.skillMapper = skillMapper;
|
|
6
|
+
}
|
|
7
|
+
build(registry, opts) {
|
|
8
|
+
const skills = this.buildSkills(registry);
|
|
9
|
+
const card = {
|
|
10
|
+
name: opts.name,
|
|
11
|
+
description: opts.description,
|
|
12
|
+
version: opts.version,
|
|
13
|
+
url: opts.url,
|
|
14
|
+
protocolVersion: "0.2.1",
|
|
15
|
+
skills,
|
|
16
|
+
capabilities: opts.capabilities,
|
|
17
|
+
defaultInputModes: ["text/plain", "application/json"],
|
|
18
|
+
defaultOutputModes: ["text/plain", "application/json"],
|
|
19
|
+
securitySchemes: opts.securitySchemes,
|
|
20
|
+
supportsAuthenticatedExtendedCard: opts.securitySchemes != null,
|
|
21
|
+
};
|
|
22
|
+
this.cachedCard = card;
|
|
23
|
+
return card;
|
|
24
|
+
}
|
|
25
|
+
getCachedOrBuild(registry, opts) {
|
|
26
|
+
if (this.cachedCard)
|
|
27
|
+
return this.cachedCard;
|
|
28
|
+
return this.build(registry, opts);
|
|
29
|
+
}
|
|
30
|
+
buildExtended(baseCard) {
|
|
31
|
+
return structuredClone(baseCard);
|
|
32
|
+
}
|
|
33
|
+
invalidateCache() {
|
|
34
|
+
this.cachedCard = null;
|
|
35
|
+
}
|
|
36
|
+
buildSkills(registry) {
|
|
37
|
+
const skills = [];
|
|
38
|
+
for (const moduleId of registry.list()) {
|
|
39
|
+
const descriptor = registry.getDefinition(moduleId);
|
|
40
|
+
if (!descriptor?.description)
|
|
41
|
+
continue;
|
|
42
|
+
const skill = this.skillMapper.toSkill(descriptor);
|
|
43
|
+
if (skill)
|
|
44
|
+
skills.push(skill);
|
|
45
|
+
}
|
|
46
|
+
return skills;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=agent-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-card.js","sourceRoot":"","sources":["../../src/adapters/agent-card.ts"],"names":[],"mappings":"AASA,MAAM,OAAO,gBAAgB;IACnB,WAAW,CAAc;IACzB,UAAU,GAAqB,IAAI,CAAC;IAE5C,YAAY,WAAwB;QAClC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,KAAK,CACH,QAAkB,EAClB,IAOC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE1C,MAAM,IAAI,GAAc;YACtB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,eAAe,EAAE,OAAO;YACxB,MAAM;YACN,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,iBAAiB,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC;YACrD,kBAAkB,EAAE,CAAC,YAAY,EAAE,kBAAkB,CAAC;YACtD,eAAe,EAAE,IAAI,CAAC,eAA+C;YACrE,iCAAiC,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI;SAChE,CAAC;QAEF,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gBAAgB,CACd,QAAkB,EAClB,IAOC;QAED,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,aAAa,CAAC,QAAmB;QAC/B,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,eAAe;QACb,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IACzB,CAAC;IAEO,WAAW,CAAC,QAAkB;QACpC,MAAM,MAAM,GAAiB,EAAE,CAAC;QAChC,KAAK,MAAM,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YACpD,IAAI,CAAC,UAAU,EAAE,WAAW;gBAAE,SAAS;YACvC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACnD,IAAI,KAAK;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface JsonRpcError {
|
|
2
|
+
code: number;
|
|
3
|
+
message: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class ErrorMapper {
|
|
6
|
+
toJsonRpcError(error: unknown): JsonRpcError;
|
|
7
|
+
private handleApcoreError;
|
|
8
|
+
sanitizeMessage(message: string): string;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/adapters/errors.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,WAAW;IACtB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;IAgB5C,OAAO,CAAC,iBAAiB;IAmCzB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;CAGzC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const CODE_METHOD_NOT_FOUND = -32601;
|
|
2
|
+
const CODE_INVALID_PARAMS = -32602;
|
|
3
|
+
const CODE_INTERNAL_ERROR = -32603;
|
|
4
|
+
const CODE_TASK_NOT_FOUND = -32001;
|
|
5
|
+
export class ErrorMapper {
|
|
6
|
+
toJsonRpcError(error) {
|
|
7
|
+
if (error instanceof Error) {
|
|
8
|
+
const code = error.code;
|
|
9
|
+
if (code) {
|
|
10
|
+
return this.handleApcoreError(error, code);
|
|
11
|
+
}
|
|
12
|
+
if (error.name === "TimeoutError" || error.constructor.name === "TimeoutError") {
|
|
13
|
+
return { code: CODE_INTERNAL_ERROR, message: "Execution timeout" };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return { code: CODE_INTERNAL_ERROR, message: "Internal server error" };
|
|
17
|
+
}
|
|
18
|
+
handleApcoreError(error, errorCode) {
|
|
19
|
+
if (errorCode === "MODULE_NOT_FOUND") {
|
|
20
|
+
const message = this.sanitizeMessage(error.message);
|
|
21
|
+
return { code: CODE_METHOD_NOT_FOUND, message };
|
|
22
|
+
}
|
|
23
|
+
if (errorCode === "SCHEMA_VALIDATION_ERROR") {
|
|
24
|
+
const message = this.sanitizeMessage(error.message);
|
|
25
|
+
return { code: CODE_INVALID_PARAMS, message };
|
|
26
|
+
}
|
|
27
|
+
if (errorCode === "ACL_DENIED") {
|
|
28
|
+
return { code: CODE_TASK_NOT_FOUND, message: "Task not found" };
|
|
29
|
+
}
|
|
30
|
+
if (errorCode === "MODULE_TIMEOUT" || errorCode === "EXECUTION_TIMEOUT") {
|
|
31
|
+
return { code: CODE_INTERNAL_ERROR, message: "Execution timeout" };
|
|
32
|
+
}
|
|
33
|
+
if (errorCode === "CALL_DEPTH_EXCEEDED" ||
|
|
34
|
+
errorCode === "CIRCULAR_CALL" ||
|
|
35
|
+
errorCode === "CALL_FREQUENCY_EXCEEDED") {
|
|
36
|
+
return { code: CODE_INTERNAL_ERROR, message: "Safety limit exceeded" };
|
|
37
|
+
}
|
|
38
|
+
if (errorCode === "INVALID_INPUT") {
|
|
39
|
+
const description = this.sanitizeMessage(error.message);
|
|
40
|
+
return { code: CODE_INVALID_PARAMS, message: `Invalid input: ${description}` };
|
|
41
|
+
}
|
|
42
|
+
return { code: CODE_INTERNAL_ERROR, message: "Internal server error" };
|
|
43
|
+
}
|
|
44
|
+
sanitizeMessage(message) {
|
|
45
|
+
return message.replace(/~?\/\S*/g, "").replace(/\s+/g, " ").trim().slice(0, 500);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/adapters/errors.ts"],"names":[],"mappings":"AAAA,MAAM,qBAAqB,GAAG,CAAC,KAAK,CAAC;AACrC,MAAM,mBAAmB,GAAG,CAAC,KAAK,CAAC;AACnC,MAAM,mBAAmB,GAAG,CAAC,KAAK,CAAC;AACnC,MAAM,mBAAmB,GAAG,CAAC,KAAK,CAAC;AAOnC,MAAM,OAAO,WAAW;IACtB,cAAc,CAAC,KAAc;QAC3B,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAI,KAA2B,CAAC,IAAI,CAAC;YAE/C,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC7C,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,IAAI,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBAC/E,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;YACrE,CAAC;QACH,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACzE,CAAC;IAEO,iBAAiB,CAAC,KAAY,EAAE,SAAiB;QACvD,IAAI,SAAS,KAAK,kBAAkB,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAE,KAA6B,CAAC,OAAO,CAAC,CAAC;YAC7E,OAAO,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,CAAC;QAClD,CAAC;QAED,IAAI,SAAS,KAAK,yBAAyB,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAE,KAA6B,CAAC,OAAO,CAAC,CAAC;YAC7E,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAC;QAChD,CAAC;QAED,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;YAC/B,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;QAClE,CAAC;QAED,IAAI,SAAS,KAAK,gBAAgB,IAAI,SAAS,KAAK,mBAAmB,EAAE,CAAC;YACxE,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;QACrE,CAAC;QAED,IACE,SAAS,KAAK,qBAAqB;YACnC,SAAS,KAAK,eAAe;YAC7B,SAAS,KAAK,yBAAyB,EACvC,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;QACzE,CAAC;QAED,IAAI,SAAS,KAAK,eAAe,EAAE,CAAC;YAClC,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAE,KAA6B,CAAC,OAAO,CAAC,CAAC;YACjF,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,kBAAkB,WAAW,EAAE,EAAE,CAAC;QACjF,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;IACzE,CAAC;IAED,eAAe,CAAC,OAAe;QAC7B,OAAO,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACnF,CAAC;CACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AgentCardBuilder } from "./agent-card.js";
|
|
2
|
+
export { ErrorMapper } from "./errors.js";
|
|
3
|
+
export { PartConverter } from "./parts.js";
|
|
4
|
+
export { SchemaConverter } from "./schema.js";
|
|
5
|
+
export { SkillMapper } from "./skill-mapper.js";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { AgentCardBuilder } from "./agent-card.js";
|
|
2
|
+
export { ErrorMapper } from "./errors.js";
|
|
3
|
+
export { PartConverter } from "./parts.js";
|
|
4
|
+
export { SchemaConverter } from "./schema.js";
|
|
5
|
+
export { SkillMapper } from "./skill-mapper.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Artifact, Part } from "@a2a-js/sdk";
|
|
2
|
+
import { SchemaConverter } from "./schema.js";
|
|
3
|
+
import type { ModuleDescriptor } from "./skill-mapper.js";
|
|
4
|
+
export declare class PartConverter {
|
|
5
|
+
private schemaConverter;
|
|
6
|
+
constructor(schemaConverter?: SchemaConverter);
|
|
7
|
+
partsToInput(parts: Part[], descriptor: ModuleDescriptor | null): Record<string, unknown> | string;
|
|
8
|
+
outputToParts(output: unknown, taskId?: string): Artifact;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=parts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../../src/adapters/parts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,qBAAa,aAAa;IACxB,OAAO,CAAC,eAAe,CAAkB;gBAE7B,eAAe,CAAC,EAAE,eAAe;IAI7C,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,gBAAgB,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAkClG,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ;CAqB1D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { SchemaConverter } from "./schema.js";
|
|
2
|
+
export class PartConverter {
|
|
3
|
+
schemaConverter;
|
|
4
|
+
constructor(schemaConverter) {
|
|
5
|
+
this.schemaConverter = schemaConverter ?? new SchemaConverter();
|
|
6
|
+
}
|
|
7
|
+
partsToInput(parts, descriptor) {
|
|
8
|
+
if (!parts || parts.length === 0) {
|
|
9
|
+
throw new Error("Message must contain at least one Part");
|
|
10
|
+
}
|
|
11
|
+
if (parts.length > 1) {
|
|
12
|
+
throw new Error("Multiple parts are not supported; expected exactly one Part");
|
|
13
|
+
}
|
|
14
|
+
const part = parts[0];
|
|
15
|
+
if (part.kind === "text") {
|
|
16
|
+
const inputSchema = descriptor?.input_schema ?? null;
|
|
17
|
+
const rootType = this.schemaConverter.detectRootType(inputSchema);
|
|
18
|
+
if (rootType === "object") {
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(part.text);
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
throw new Error(`TextPart text is not valid JSON: ${e}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return part.text;
|
|
27
|
+
}
|
|
28
|
+
if (part.kind === "data") {
|
|
29
|
+
return part.data;
|
|
30
|
+
}
|
|
31
|
+
if (part.kind === "file") {
|
|
32
|
+
throw new Error("FilePart is not supported");
|
|
33
|
+
}
|
|
34
|
+
throw new Error(`Unsupported part type: ${part.kind}`);
|
|
35
|
+
}
|
|
36
|
+
outputToParts(output, taskId) {
|
|
37
|
+
const artifactId = `art-${taskId || crypto.randomUUID()}`;
|
|
38
|
+
if (output === null || output === undefined) {
|
|
39
|
+
return { artifactId, parts: [] };
|
|
40
|
+
}
|
|
41
|
+
if (typeof output === "string") {
|
|
42
|
+
return { artifactId, parts: [{ kind: "text", text: output }] };
|
|
43
|
+
}
|
|
44
|
+
if (Array.isArray(output)) {
|
|
45
|
+
return { artifactId, parts: [{ kind: "text", text: JSON.stringify(output) }] };
|
|
46
|
+
}
|
|
47
|
+
if (typeof output === "object") {
|
|
48
|
+
return { artifactId, parts: [{ kind: "data", data: output }] };
|
|
49
|
+
}
|
|
50
|
+
return { artifactId, parts: [{ kind: "text", text: String(output) }] };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=parts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.js","sourceRoot":"","sources":["../../src/adapters/parts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,MAAM,OAAO,aAAa;IAChB,eAAe,CAAkB;IAEzC,YAAY,eAAiC;QAC3C,IAAI,CAAC,eAAe,GAAG,eAAe,IAAI,IAAI,eAAe,EAAE,CAAC;IAClE,CAAC;IAED,YAAY,CAAC,KAAa,EAAE,UAAmC;QAC7D,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;QACjF,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,WAAW,GAAG,UAAU,EAAE,YAAY,IAAI,IAAI,CAAC;YACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC;YAClE,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAA4B,CAAC;gBAC1D,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,EAAE,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC,IAAI,CAAC;QACnB,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,0BAA2B,IAAa,CAAC,IAAI,EAAE,CAAC,CAAC;IACnE,CAAC;IAED,aAAa,CAAC,MAAe,EAAE,MAAe;QAC5C,MAAM,UAAU,GAAG,OAAO,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC;QAE1D,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC5C,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACnC,CAAC;QAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACjE,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QACjF,CAAC;QAED,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAiC,EAAE,CAAC,EAAE,CAAC;QAC5F,CAAC;QAED,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;IACzE,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type JsonSchema = Record<string, unknown>;
|
|
2
|
+
export declare class SchemaConverter {
|
|
3
|
+
convertInputSchema(descriptor: {
|
|
4
|
+
input_schema?: JsonSchema;
|
|
5
|
+
}): JsonSchema;
|
|
6
|
+
convertOutputSchema(descriptor: {
|
|
7
|
+
output_schema?: JsonSchema;
|
|
8
|
+
}): JsonSchema;
|
|
9
|
+
detectRootType(schema: JsonSchema | null | undefined): "string" | "object" | "unknown";
|
|
10
|
+
private convertSchema;
|
|
11
|
+
private inlineRefs;
|
|
12
|
+
private resolveRef;
|
|
13
|
+
private ensureObjectType;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/adapters/schema.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAIjD,qBAAa,eAAe;IAC1B,kBAAkB,CAAC,UAAU,EAAE;QAAE,YAAY,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,UAAU;IAIzE,mBAAmB,CAAC,UAAU,EAAE;QAAE,aAAa,CAAC,EAAE,UAAU,CAAA;KAAE,GAAG,UAAU;IAI3E,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS;IAOtF,OAAO,CAAC,aAAa;IAgBrB,OAAO,CAAC,UAAU;IAqClB,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,gBAAgB;CASzB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const MAX_REF_DEPTH = 32;
|
|
2
|
+
export class SchemaConverter {
|
|
3
|
+
convertInputSchema(descriptor) {
|
|
4
|
+
return this.convertSchema(descriptor.input_schema);
|
|
5
|
+
}
|
|
6
|
+
convertOutputSchema(descriptor) {
|
|
7
|
+
return this.convertSchema(descriptor.output_schema);
|
|
8
|
+
}
|
|
9
|
+
detectRootType(schema) {
|
|
10
|
+
if (!schema)
|
|
11
|
+
return "unknown";
|
|
12
|
+
if (schema.type === "string")
|
|
13
|
+
return "string";
|
|
14
|
+
if (schema.type === "object" || "properties" in schema)
|
|
15
|
+
return "object";
|
|
16
|
+
return "unknown";
|
|
17
|
+
}
|
|
18
|
+
convertSchema(schema) {
|
|
19
|
+
let s = structuredClone(schema);
|
|
20
|
+
if (!s || Object.keys(s).length === 0) {
|
|
21
|
+
return { type: "object", properties: {} };
|
|
22
|
+
}
|
|
23
|
+
if ("$defs" in s) {
|
|
24
|
+
const defs = s.$defs;
|
|
25
|
+
s = this.inlineRefs(s, defs, new Set(), 0);
|
|
26
|
+
delete s.$defs;
|
|
27
|
+
}
|
|
28
|
+
return this.ensureObjectType(s);
|
|
29
|
+
}
|
|
30
|
+
inlineRefs(schema, defs, seen, depth) {
|
|
31
|
+
if (depth > MAX_REF_DEPTH) {
|
|
32
|
+
throw new Error(`Schema $ref depth limit exceeded (max ${MAX_REF_DEPTH})`);
|
|
33
|
+
}
|
|
34
|
+
if (Array.isArray(schema)) {
|
|
35
|
+
return schema.map((item) => this.inlineRefs(item, defs, seen, depth + 1));
|
|
36
|
+
}
|
|
37
|
+
if (schema !== null && typeof schema === "object") {
|
|
38
|
+
const obj = schema;
|
|
39
|
+
if ("$ref" in obj && typeof obj.$ref === "string") {
|
|
40
|
+
const refPath = obj.$ref;
|
|
41
|
+
if (seen.has(refPath)) {
|
|
42
|
+
throw new Error(`Circular $ref detected: ${refPath}`);
|
|
43
|
+
}
|
|
44
|
+
const resolved = this.resolveRef(refPath, defs);
|
|
45
|
+
return this.inlineRefs(resolved, defs, new Set([...seen, refPath]), depth + 1);
|
|
46
|
+
}
|
|
47
|
+
const result = {};
|
|
48
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
49
|
+
if (key === "$defs")
|
|
50
|
+
continue;
|
|
51
|
+
result[key] = this.inlineRefs(value, defs, seen, depth + 1);
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
return schema;
|
|
56
|
+
}
|
|
57
|
+
resolveRef(refPath, defs) {
|
|
58
|
+
if (!refPath.startsWith("#/$defs/")) {
|
|
59
|
+
throw new Error(`Unsupported $ref format: ${refPath}`);
|
|
60
|
+
}
|
|
61
|
+
const defName = refPath.slice(8);
|
|
62
|
+
if (!(defName in defs)) {
|
|
63
|
+
throw new Error(`Definition not found: ${defName}`);
|
|
64
|
+
}
|
|
65
|
+
return structuredClone(defs[defName]);
|
|
66
|
+
}
|
|
67
|
+
ensureObjectType(schema) {
|
|
68
|
+
if (!("type" in schema)) {
|
|
69
|
+
schema.type = "object";
|
|
70
|
+
}
|
|
71
|
+
if ("properties" in schema && schema.type !== "object") {
|
|
72
|
+
schema.type = "object";
|
|
73
|
+
}
|
|
74
|
+
return schema;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/adapters/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AgentSkill } from "@a2a-js/sdk";
|
|
2
|
+
export interface ModuleDescriptor {
|
|
3
|
+
module_id: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
input_schema?: Record<string, unknown>;
|
|
6
|
+
output_schema?: Record<string, unknown>;
|
|
7
|
+
tags?: string[];
|
|
8
|
+
examples?: Array<{
|
|
9
|
+
title?: string;
|
|
10
|
+
}>;
|
|
11
|
+
annotations?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export declare class SkillMapper {
|
|
14
|
+
toSkill(descriptor: ModuleDescriptor): AgentSkill | null;
|
|
15
|
+
humanizeModuleId(moduleId: string): string;
|
|
16
|
+
private computeInputModes;
|
|
17
|
+
private computeOutputModes;
|
|
18
|
+
buildExamples(descriptor: ModuleDescriptor): string[];
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=skill-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-mapper.d.ts","sourceRoot":"","sources":["../../src/adapters/skill-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,EAAE,gBAAgB,GAAG,UAAU,GAAG,IAAI;IAexD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAO1C,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,kBAAkB;IAM1B,aAAa,CAAC,UAAU,EAAE,gBAAgB,GAAG,MAAM,EAAE;CAQtD"}
|