Skip to content

Commit 3b8d597

Browse files
feat(a2a): publish shared schema package (#123)
* feat(a2a): publish shared schema package * fix(a2a): allow empty package test suite * fix(release): publish a2a package
1 parent 6690671 commit 3b8d597

7 files changed

Lines changed: 219 additions & 131 deletions

File tree

.github/workflows/publish-npm.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ on:
99
type: choice
1010
options:
1111
- all
12+
- a2a
1213
- types
1314
- server
1415
- sdk-typescript
@@ -184,6 +185,7 @@ jobs:
184185
max-parallel: 5
185186
matrix:
186187
package:
188+
- a2a
187189
- types
188190
- server
189191
- sdk-typescript
@@ -313,6 +315,7 @@ jobs:
313315
314316
### Install
315317
```bash
318+
npm install @relaycast/a2a@${{ needs.build.outputs.new_version }}
316319
npm install @relaycast/sdk@${{ needs.build.outputs.new_version }}
317320
npm install relaycast@${{ needs.build.outputs.new_version }}
318321
npm install @relaycast/react@${{ needs.build.outputs.new_version }}
@@ -323,6 +326,7 @@ jobs:
323326
### Packages
324327
| Package | Version |
325328
|---------|---------|
329+
| @relaycast/a2a | ${{ needs.build.outputs.new_version }} |
326330
| @relaycast/types | ${{ needs.build.outputs.new_version }} |
327331
| @relaycast/server | ${{ needs.build.outputs.new_version }} |
328332
| @relaycast/sdk | ${{ needs.build.outputs.new_version }} |

package-lock.json

Lines changed: 12 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/a2a/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "@relaycast/a2a",
3+
"version": "1.1.3",
4+
"type": "module",
5+
"main": "dist/index.js",
6+
"types": "dist/index.d.ts",
7+
"scripts": {
8+
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc",
9+
"test": "vitest run --passWithNoTests",
10+
"lint": "eslint src/"
11+
},
12+
"repository": {
13+
"type": "git",
14+
"url": "git+https://github.com/AgentWorkforce/relaycast.git",
15+
"directory": "packages/a2a"
16+
},
17+
"dependencies": {
18+
"zod": "^4.3.6"
19+
},
20+
"files": [
21+
"dist"
22+
]
23+
}

packages/a2a/src/index.ts

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
import { z } from 'zod';
2+
3+
export const A2aSkillSchema = z.object({
4+
id: z.string().min(1).optional(),
5+
name: z.string().min(1),
6+
description: z.string().optional(),
7+
tags: z.array(z.string()).optional(),
8+
});
9+
10+
export const A2aAgentCardSchema = z.object({
11+
name: z.string().min(1),
12+
description: z.string().optional(),
13+
url: z.string().url(),
14+
version: z.string().min(1),
15+
skills: z.array(A2aSkillSchema).min(1),
16+
provider: z.record(z.string(), z.unknown()).optional(),
17+
capabilities: z.record(z.string(), z.unknown()).optional(),
18+
default_input_modes: z.array(z.string()).optional(),
19+
default_output_modes: z.array(z.string()).optional(),
20+
documentation_url: z.string().url().optional(),
21+
});
22+
23+
export const A2aFilePartSchema = z.object({
24+
kind: z.literal('file'),
25+
file: z.object({
26+
name: z.string().min(1),
27+
mime_type: z.string().min(1).optional(),
28+
uri: z.string().min(1).optional(),
29+
bytes: z.number().int().nonnegative().optional(),
30+
}),
31+
});
32+
33+
export const A2aDataPartSchema = z.object({
34+
kind: z.literal('data'),
35+
data: z.record(z.string(), z.unknown()),
36+
});
37+
38+
export const A2aTextPartSchema = z.object({
39+
kind: z.literal('text'),
40+
text: z.string(),
41+
});
42+
43+
export const A2aPartSchema = z.discriminatedUnion('kind', [
44+
A2aTextPartSchema,
45+
A2aFilePartSchema,
46+
A2aDataPartSchema,
47+
]);
48+
49+
export const A2aMessageSchema = z.object({
50+
message_id: z.string(),
51+
role: z.enum(['user', 'agent', 'system']).default('user'),
52+
context_id: z.string().optional(),
53+
parts: z.array(A2aPartSchema).min(1),
54+
});
55+
56+
export const A2aArtifactSchema = z.object({
57+
name: z.string(),
58+
description: z.string().optional(),
59+
parts: z.array(A2aPartSchema).min(1),
60+
});
61+
62+
export const A2aTaskStateSchema = z.enum([
63+
'submitted',
64+
'working',
65+
'input-required',
66+
'completed',
67+
'failed',
68+
'canceled',
69+
'unknown',
70+
]);
71+
72+
export const A2aTaskSchema = z.object({
73+
id: z.string(),
74+
context_id: z.string().optional(),
75+
status: z.object({
76+
state: A2aTaskStateSchema,
77+
message: z.string().optional(),
78+
}),
79+
artifacts: z.array(A2aArtifactSchema).optional(),
80+
history: z.array(A2aMessageSchema).optional(),
81+
metadata: z.record(z.string(), z.unknown()).optional(),
82+
});
83+
84+
export const JsonRpcRequestSchema = z.object({
85+
jsonrpc: z.literal('2.0'),
86+
id: z.union([z.string(), z.number()]).optional(),
87+
method: z.string().min(1),
88+
params: z.object({
89+
message: A2aMessageSchema.optional(),
90+
}).passthrough().optional(),
91+
});
92+
93+
export const JsonRpcErrorSchema = z.object({
94+
code: z.number(),
95+
message: z.string(),
96+
data: z.unknown().optional(),
97+
});
98+
99+
export const JsonRpcResponseSchema = z.object({
100+
jsonrpc: z.literal('2.0'),
101+
id: z.union([z.string(), z.number()]).optional(),
102+
result: z.object({
103+
task: A2aTaskSchema.optional(),
104+
message: A2aMessageSchema.optional(),
105+
}).passthrough().optional(),
106+
error: JsonRpcErrorSchema.optional(),
107+
});
108+
109+
export const A2aResponseSchema = z.object({
110+
task: A2aTaskSchema.optional(),
111+
message: A2aMessageSchema.optional(),
112+
response: JsonRpcResponseSchema.optional(),
113+
});
114+
115+
export type A2aSkill = z.infer<typeof A2aSkillSchema>;
116+
export type A2aAgentCard = z.infer<typeof A2aAgentCardSchema>;
117+
export type A2aFilePart = z.infer<typeof A2aFilePartSchema>;
118+
export type A2aDataPart = z.infer<typeof A2aDataPartSchema>;
119+
export type A2aTextPart = z.infer<typeof A2aTextPartSchema>;
120+
export type A2aPart = z.infer<typeof A2aPartSchema>;
121+
export type A2aMessage = z.infer<typeof A2aMessageSchema>;
122+
export type A2aArtifact = z.infer<typeof A2aArtifactSchema>;
123+
export type A2aTaskState = z.infer<typeof A2aTaskStateSchema>;
124+
export type A2aTask = z.infer<typeof A2aTaskSchema>;
125+
export type A2aJsonRpcRequest = z.infer<typeof JsonRpcRequestSchema>;
126+
export type A2aJsonRpcResponse = z.infer<typeof JsonRpcResponseSchema>;
127+
export type A2aResponse = z.infer<typeof A2aResponseSchema>;

packages/a2a/tsconfig.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "../../tsconfig.base.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"rootDir": "src",
6+
"declaration": true,
7+
"declarationMap": true,
8+
"sourceMap": true,
9+
"tsBuildInfoFile": "tsconfig.tsbuildinfo"
10+
},
11+
"include": ["src/**/*.ts"]
12+
}

packages/server/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"drizzle-orm": "^0.45.1",
1919
"hono": "^4.11.9",
2020
"posthog-node": "^5.29.2",
21-
"zod": "^4.3.6"
21+
"zod": "^4.3.6",
22+
"@relaycast/a2a": "1.1.3"
2223
},
2324
"repository": {
2425
"type": "git",

0 commit comments

Comments
 (0)