@saccolabs/tars 1.15.0 → 1.16.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.
@@ -0,0 +1,47 @@
1
+ /**
2
+ * SwarmService — A2A Server for Tars Swarm.
3
+ *
4
+ * Exposes this Tars instance as a remote agent that other Tars instances
5
+ * (or any A2A-compliant agent) can discover and delegate tasks to.
6
+ *
7
+ * Endpoints:
8
+ * GET /.well-known/agent.json → Agent Card (public, no auth)
9
+ * POST /a2a → JSON-RPC handler (authenticated)
10
+ */
11
+ import { Config } from '../config/config.js';
12
+ import type { Supervisor } from '../supervisor/supervisor.js';
13
+ export declare class SwarmService {
14
+ private readonly config;
15
+ private readonly supervisor;
16
+ private server;
17
+ constructor(config: Config, supervisor: Supervisor);
18
+ /**
19
+ * Starts the A2A HTTP server if swarm mode is enabled.
20
+ */
21
+ start(): Promise<void>;
22
+ /**
23
+ * Stops the A2A server gracefully.
24
+ */
25
+ stop(): void;
26
+ /**
27
+ * Main request router.
28
+ */
29
+ private handleRequest;
30
+ /**
31
+ * Serve the agent card. This endpoint is public (no auth required).
32
+ */
33
+ private handleAgentCard;
34
+ /**
35
+ * Handle A2A JSON-RPC requests. Requires authentication.
36
+ */
37
+ private handleA2A;
38
+ /**
39
+ * Validates the API key from the request headers.
40
+ */
41
+ private validateAuth;
42
+ /**
43
+ * Reads the request body up to MAX_BODY_SIZE.
44
+ * Returns null if the body exceeds the limit.
45
+ */
46
+ private readBody;
47
+ }
@@ -0,0 +1,207 @@
1
+ /**
2
+ * SwarmService — A2A Server for Tars Swarm.
3
+ *
4
+ * Exposes this Tars instance as a remote agent that other Tars instances
5
+ * (or any A2A-compliant agent) can discover and delegate tasks to.
6
+ *
7
+ * Endpoints:
8
+ * GET /.well-known/agent.json → Agent Card (public, no auth)
9
+ * POST /a2a → JSON-RPC handler (authenticated)
10
+ */
11
+ import http from 'http';
12
+ import logger from '../utils/logger.js';
13
+ import { buildAgentCard } from './agent-card.js';
14
+ import { parseRPCRequest, handleRPCRequest } from './rpc-handler.js';
15
+ /**
16
+ * Maximum request body size (1MB). Prevents abuse.
17
+ */
18
+ const MAX_BODY_SIZE = 1024 * 1024;
19
+ /**
20
+ * Swarm depth header — prevents infinite delegation loops.
21
+ * If a request arrives with X-Swarm-Depth >= MAX_DEPTH, the worker rejects it.
22
+ */
23
+ const SWARM_DEPTH_HEADER = 'x-swarm-depth';
24
+ const MAX_SWARM_DEPTH = 3;
25
+ export class SwarmService {
26
+ config;
27
+ supervisor;
28
+ server = null;
29
+ constructor(config, supervisor) {
30
+ this.config = config;
31
+ this.supervisor = supervisor;
32
+ }
33
+ /**
34
+ * Starts the A2A HTTP server if swarm mode is enabled.
35
+ */
36
+ async start() {
37
+ if (!this.config.swarm.enabled) {
38
+ logger.debug('[Swarm] Swarm mode disabled, skipping.');
39
+ return;
40
+ }
41
+ if (!this.config.swarm.apiKey) {
42
+ logger.warn('⚠️ [Swarm] Swarm mode is enabled but SWARM_API_KEY is not set. Run `tars setup` to configure.');
43
+ return;
44
+ }
45
+ return new Promise((resolve) => {
46
+ this.server = http.createServer((req, res) => this.handleRequest(req, res));
47
+ this.server.listen(this.config.swarm.port, () => {
48
+ logger.info(`🌐 [Swarm] A2A server listening on port ${this.config.swarm.port}`);
49
+ logger.info(`🌐 [Swarm] Agent card: http://localhost:${this.config.swarm.port}/.well-known/agent.json`);
50
+ resolve();
51
+ });
52
+ this.server.on('error', (err) => {
53
+ if (err.code === 'EADDRINUSE') {
54
+ logger.error(`❌ [Swarm] Port ${this.config.swarm.port} is already in use. Swarm server not started.`);
55
+ }
56
+ else {
57
+ logger.error(`❌ [Swarm] Server error: ${err.message}`);
58
+ }
59
+ resolve();
60
+ });
61
+ });
62
+ }
63
+ /**
64
+ * Stops the A2A server gracefully.
65
+ */
66
+ stop() {
67
+ if (this.server) {
68
+ this.server.close();
69
+ this.server = null;
70
+ logger.info('🛑 [Swarm] A2A server stopped.');
71
+ }
72
+ }
73
+ /**
74
+ * Main request router.
75
+ */
76
+ async handleRequest(req, res) {
77
+ // CORS headers for broad compatibility
78
+ res.setHeader('Access-Control-Allow-Origin', '*');
79
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
80
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-API-Key, X-Swarm-Depth');
81
+ if (req.method === 'OPTIONS') {
82
+ res.writeHead(204);
83
+ res.end();
84
+ return;
85
+ }
86
+ const url = req.url || '/';
87
+ try {
88
+ if (req.method === 'GET' && url === '/.well-known/agent.json') {
89
+ return this.handleAgentCard(req, res);
90
+ }
91
+ if (req.method === 'POST' && url === '/a2a') {
92
+ return await this.handleA2A(req, res);
93
+ }
94
+ // Health check
95
+ if (req.method === 'GET' && url === '/health') {
96
+ res.writeHead(200, { 'Content-Type': 'application/json' });
97
+ res.end(JSON.stringify({ status: 'ok', agent: this.config.assistantName }));
98
+ return;
99
+ }
100
+ res.writeHead(404, { 'Content-Type': 'application/json' });
101
+ res.end(JSON.stringify({ error: 'Not found' }));
102
+ }
103
+ catch (error) {
104
+ logger.error(`❌ [Swarm] Request handler error: ${error.message}`);
105
+ res.writeHead(500, { 'Content-Type': 'application/json' });
106
+ res.end(JSON.stringify({ error: 'Internal server error' }));
107
+ }
108
+ }
109
+ /**
110
+ * Serve the agent card. This endpoint is public (no auth required).
111
+ */
112
+ handleAgentCard(_req, res) {
113
+ const card = buildAgentCard(this.config);
114
+ res.writeHead(200, { 'Content-Type': 'application/json' });
115
+ res.end(JSON.stringify(card, null, 2));
116
+ }
117
+ /**
118
+ * Handle A2A JSON-RPC requests. Requires authentication.
119
+ */
120
+ async handleA2A(req, res) {
121
+ // Auth check
122
+ if (!this.validateAuth(req)) {
123
+ res.writeHead(401, { 'Content-Type': 'application/json' });
124
+ res.end(JSON.stringify({
125
+ jsonrpc: '2.0',
126
+ id: 0,
127
+ error: { code: -32000, message: 'Unauthorized: invalid or missing API key' }
128
+ }));
129
+ return;
130
+ }
131
+ // Swarm depth check (loop prevention)
132
+ const depthStr = req.headers[SWARM_DEPTH_HEADER];
133
+ const depth = depthStr ? parseInt(depthStr, 10) : 0;
134
+ if (depth >= MAX_SWARM_DEPTH) {
135
+ logger.warn(`⚠️ [Swarm] Rejecting request: swarm depth ${depth} >= max ${MAX_SWARM_DEPTH}`);
136
+ res.writeHead(429, { 'Content-Type': 'application/json' });
137
+ res.end(JSON.stringify({
138
+ jsonrpc: '2.0',
139
+ id: 0,
140
+ error: {
141
+ code: -32000,
142
+ message: `Swarm delegation depth limit reached (max=${MAX_SWARM_DEPTH})`
143
+ }
144
+ }));
145
+ return;
146
+ }
147
+ // Read body
148
+ const body = await this.readBody(req);
149
+ if (body === null) {
150
+ res.writeHead(413, { 'Content-Type': 'application/json' });
151
+ res.end(JSON.stringify({
152
+ jsonrpc: '2.0',
153
+ id: 0,
154
+ error: { code: -32000, message: 'Request body too large' }
155
+ }));
156
+ return;
157
+ }
158
+ // Parse JSON-RPC
159
+ const parsed = parseRPCRequest(body);
160
+ if ('error' in parsed) {
161
+ res.writeHead(400, { 'Content-Type': 'application/json' });
162
+ res.end(JSON.stringify(parsed.error));
163
+ return;
164
+ }
165
+ // Handle the RPC request
166
+ const result = await handleRPCRequest(parsed.request, this.supervisor);
167
+ const statusCode = result.error ? 400 : 200;
168
+ res.writeHead(statusCode, { 'Content-Type': 'application/json' });
169
+ res.end(JSON.stringify(result));
170
+ }
171
+ /**
172
+ * Validates the API key from the request headers.
173
+ */
174
+ validateAuth(req) {
175
+ const apiKey = req.headers['x-api-key'] ||
176
+ req.headers['authorization']?.replace(/^Bearer\s+/i, '');
177
+ if (!apiKey)
178
+ return false;
179
+ return apiKey === this.config.swarm.apiKey;
180
+ }
181
+ /**
182
+ * Reads the request body up to MAX_BODY_SIZE.
183
+ * Returns null if the body exceeds the limit.
184
+ */
185
+ readBody(req) {
186
+ return new Promise((resolve) => {
187
+ const chunks = [];
188
+ let totalSize = 0;
189
+ req.on('data', (chunk) => {
190
+ totalSize += chunk.length;
191
+ if (totalSize > MAX_BODY_SIZE) {
192
+ req.destroy();
193
+ resolve(null);
194
+ return;
195
+ }
196
+ chunks.push(chunk);
197
+ });
198
+ req.on('end', () => {
199
+ resolve(Buffer.concat(chunks).toString('utf-8'));
200
+ });
201
+ req.on('error', () => {
202
+ resolve(null);
203
+ });
204
+ });
205
+ }
206
+ }
207
+ //# sourceMappingURL=swarm-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swarm-service.js","sourceRoot":"","sources":["../../src/swarm/swarm-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGrE;;GAEG;AACH,MAAM,aAAa,GAAG,IAAI,GAAG,IAAI,CAAC;AAElC;;;GAGG;AACH,MAAM,kBAAkB,GAAG,eAAe,CAAC;AAC3C,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,MAAM,OAAO,YAAY;IAIA;IACA;IAJb,MAAM,GAAuB,IAAI,CAAC;IAE1C,YACqB,MAAc,EACd,UAAsB;QADtB,WAAM,GAAN,MAAM,CAAQ;QACd,eAAU,GAAV,UAAU,CAAY;IACxC,CAAC;IAEJ;;OAEG;IACI,KAAK,CAAC,KAAK;QACd,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAC7B,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACvD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,IAAI,CACP,+FAA+F,CAClG,CAAC;YACF,OAAO;QACX,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;YAE5E,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE;gBAC5C,MAAM,CAAC,IAAI,CAAC,2CAA2C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;gBACjF,MAAM,CAAC,IAAI,CACP,2CAA2C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,yBAAyB,CAC7F,CAAC;gBACF,OAAO,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAA0B,EAAE,EAAE;gBACnD,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBAC5B,MAAM,CAAC,KAAK,CACR,kBAAkB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,+CAA+C,CAC1F,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,MAAM,CAAC,KAAK,CAAC,2BAA2B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC3D,CAAC;gBACD,OAAO,EAAE,CAAC;YACd,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACI,IAAI;QACP,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACpB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;YACnB,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAClD,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CACvB,GAAyB,EACzB,GAAwB;QAExB,uCAAuC;QACvC,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QAClD,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,oBAAoB,CAAC,CAAC;QACpE,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,wCAAwC,CAAC,CAAC;QAExF,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAC3B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,EAAE,CAAC;YACV,OAAO;QACX,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC;QAE3B,IAAI,CAAC;YACD,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,yBAAyB,EAAE,CAAC;gBAC5D,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC1C,CAAC;YAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;gBAC1C,OAAO,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAC1C,CAAC;YAED,eAAe;YACf,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBAC5C,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;gBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;gBAC5E,OAAO;YACX,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,MAAM,CAAC,KAAK,CAAC,oCAAoC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YAClE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC;QAChE,CAAC;IACL,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,IAA0B,EAAE,GAAwB;QACxE,MAAM,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CAAC,GAAyB,EAAE,GAAwB;QACvE,aAAa;QACb,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CACH,IAAI,CAAC,SAAS,CAAC;gBACX,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,0CAA0C,EAAE;aAC/E,CAAC,CACL,CAAC;YACF,OAAO;QACX,CAAC;QAED,sCAAsC;QACtC,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAuB,CAAC;QACvE,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,IAAI,KAAK,IAAI,eAAe,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CACP,6CAA6C,KAAK,WAAW,eAAe,EAAE,CACjF,CAAC;YACF,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CACH,IAAI,CAAC,SAAS,CAAC;gBACX,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE;oBACH,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,6CAA6C,eAAe,GAAG;iBAC3E;aACJ,CAAC,CACL,CAAC;YACF,OAAO;QACX,CAAC;QAED,YAAY;QACZ,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YAChB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CACH,IAAI,CAAC,SAAS,CAAC;gBACX,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,CAAC;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,wBAAwB,EAAE;aAC7D,CAAC,CACL,CAAC;YACF,OAAO;QACX,CAAC;QAED,iBAAiB;QACjB,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;YACpB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtC,OAAO;QACX,CAAC;QAED,yBAAyB;QACzB,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEvE,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAC5C,GAAG,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAClE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,GAAyB;QAC1C,MAAM,MAAM,GACP,GAAG,CAAC,OAAO,CAAC,WAAW,CAAY;YACnC,GAAG,CAAC,OAAO,CAAC,eAAe,CAAY,EAAE,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QAEzE,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC1B,OAAO,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACK,QAAQ,CAAC,GAAyB;QACtC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,IAAI,SAAS,GAAG,CAAC,CAAC;YAElB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBAC7B,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;gBAC1B,IAAI,SAAS,GAAG,aAAa,EAAE,CAAC;oBAC5B,GAAG,CAAC,OAAO,EAAE,CAAC;oBACd,OAAO,CAAC,IAAI,CAAC,CAAC;oBACd,OAAO;gBACX,CAAC;gBACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACf,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACjB,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;CACJ"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * A2A Protocol types for Tars Swarm
3
+ * Minimal subset of the Agent-to-Agent (A2A) protocol data model.
4
+ * @see https://a2a-protocol.org/latest/specification/
5
+ */
6
+ export interface JSONRPCRequest {
7
+ jsonrpc: '2.0';
8
+ id: string | number;
9
+ method: string;
10
+ params?: Record<string, unknown>;
11
+ }
12
+ export interface JSONRPCResponse {
13
+ jsonrpc: '2.0';
14
+ id: string | number;
15
+ result?: unknown;
16
+ error?: JSONRPCError;
17
+ }
18
+ export interface JSONRPCError {
19
+ code: number;
20
+ message: string;
21
+ data?: unknown;
22
+ }
23
+ export declare const RPC_PARSE_ERROR = -32700;
24
+ export declare const RPC_INVALID_REQUEST = -32600;
25
+ export declare const RPC_METHOD_NOT_FOUND = -32601;
26
+ export declare const RPC_INTERNAL_ERROR = -32603;
27
+ export declare const A2A_TASK_NOT_FOUND = -32001;
28
+ export declare const A2A_CONTENT_TYPE_NOT_SUPPORTED = -32002;
29
+ export declare const A2A_UNSUPPORTED_OPERATION = -32003;
30
+ export type TaskState = 'submitted' | 'working' | 'input-required' | 'completed' | 'canceled' | 'failed' | 'rejected';
31
+ export interface TaskStatus {
32
+ state: TaskState;
33
+ message?: Message;
34
+ timestamp?: string;
35
+ }
36
+ export interface Part {
37
+ text?: string;
38
+ data?: string;
39
+ mimeType?: string;
40
+ }
41
+ export interface Message {
42
+ role: 'user' | 'agent';
43
+ parts: Part[];
44
+ metadata?: Record<string, unknown>;
45
+ }
46
+ export interface Artifact {
47
+ name?: string;
48
+ description?: string;
49
+ parts: Part[];
50
+ index?: number;
51
+ }
52
+ export interface Task {
53
+ id: string;
54
+ contextId?: string;
55
+ status: TaskStatus;
56
+ artifacts?: Artifact[];
57
+ history?: Message[];
58
+ metadata?: Record<string, unknown>;
59
+ }
60
+ export interface SendMessageParams {
61
+ message: Message;
62
+ configuration?: {
63
+ acceptedOutputModes?: string[];
64
+ blocking?: boolean;
65
+ };
66
+ metadata?: Record<string, unknown>;
67
+ }
68
+ export interface TaskQueryParams {
69
+ id: string;
70
+ historyLength?: number;
71
+ }
72
+ export interface TaskCancelParams {
73
+ id: string;
74
+ }
75
+ export interface AgentCardSkill {
76
+ id: string;
77
+ name: string;
78
+ description: string;
79
+ tags?: string[];
80
+ examples?: string[];
81
+ inputModes?: string[];
82
+ outputModes?: string[];
83
+ }
84
+ export interface AgentCardCapabilities {
85
+ streaming: boolean;
86
+ pushNotifications: boolean;
87
+ stateTransitionHistory: boolean;
88
+ }
89
+ export interface AgentCardInterface {
90
+ url: string;
91
+ protocolBinding: string;
92
+ protocolVersion: string;
93
+ }
94
+ export interface AgentCard {
95
+ name: string;
96
+ description: string;
97
+ supportedInterfaces: AgentCardInterface[];
98
+ provider?: {
99
+ organization: string;
100
+ url?: string;
101
+ };
102
+ version: string;
103
+ capabilities: AgentCardCapabilities;
104
+ securitySchemes: Record<string, unknown>;
105
+ security: Array<Record<string, string[]>>;
106
+ defaultInputModes: string[];
107
+ defaultOutputModes: string[];
108
+ skills: AgentCardSkill[];
109
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * A2A Protocol types for Tars Swarm
3
+ * Minimal subset of the Agent-to-Agent (A2A) protocol data model.
4
+ * @see https://a2a-protocol.org/latest/specification/
5
+ */
6
+ // Standard JSON-RPC error codes
7
+ export const RPC_PARSE_ERROR = -32700;
8
+ export const RPC_INVALID_REQUEST = -32600;
9
+ export const RPC_METHOD_NOT_FOUND = -32601;
10
+ export const RPC_INTERNAL_ERROR = -32603;
11
+ // A2A-specific error codes
12
+ export const A2A_TASK_NOT_FOUND = -32001;
13
+ export const A2A_CONTENT_TYPE_NOT_SUPPORTED = -32002;
14
+ export const A2A_UNSUPPORTED_OPERATION = -32003;
15
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/swarm/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwBH,gCAAgC;AAChC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAK,CAAC;AACtC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAK,CAAC;AAC1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAK,CAAC;AAEzC,2BAA2B;AAC3B,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAK,CAAC;AACzC,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,KAAK,CAAC;AACrD,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,KAAK,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saccolabs/tars",
3
- "version": "1.15.0",
3
+ "version": "1.16.0",
4
4
  "description": "Tars — Your personal AI assistant",
5
5
  "publishConfig": {
6
6
  "access": "public"