@runtypelabs/timely-a2a 0.3.3

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,402 @@
1
+ import { Application } from 'express';
2
+
3
+ /**
4
+ * A2A Protocol Types
5
+ *
6
+ * Based on A2A Protocol v0.3
7
+ * https://a2a-protocol.org/v0.3.0/specification/
8
+ */
9
+ interface AgentInterface {
10
+ url: string;
11
+ protocolBinding: string;
12
+ protocolVersion: string;
13
+ tenant?: string;
14
+ }
15
+ interface AgentCard {
16
+ name: string;
17
+ description: string;
18
+ /** @deprecated Use supportedInterfaces */
19
+ url?: string;
20
+ supportedInterfaces?: AgentInterface[];
21
+ version: string;
22
+ /** @deprecated Use supportedInterfaces[].protocolVersion */
23
+ protocolVersion?: string;
24
+ defaultInputModes: string[];
25
+ defaultOutputModes: string[];
26
+ iconUrl?: string;
27
+ provider?: {
28
+ organization: string;
29
+ url?: string;
30
+ };
31
+ capabilities: {
32
+ streaming: boolean;
33
+ pushNotifications: boolean;
34
+ statefulness?: 'none' | 'session' | 'task';
35
+ };
36
+ skills: Skill[];
37
+ authentication?: {
38
+ type: 'none' | 'bearer' | 'api_key';
39
+ bearerAuth?: {
40
+ scopes: string[];
41
+ };
42
+ apiKeyAuth?: {
43
+ headerName: string;
44
+ };
45
+ };
46
+ }
47
+ interface Skill {
48
+ id: string;
49
+ name: string;
50
+ description: string;
51
+ inputModes?: string[];
52
+ outputModes?: string[];
53
+ tags: string[];
54
+ examples?: string[];
55
+ inputSchema?: Record<string, unknown>;
56
+ }
57
+ interface JsonRpcRequest {
58
+ jsonrpc: '2.0';
59
+ id?: string | number;
60
+ method: string;
61
+ params?: unknown;
62
+ }
63
+ interface JsonRpcResponse {
64
+ jsonrpc: '2.0';
65
+ id?: string | number;
66
+ result?: unknown;
67
+ error?: JsonRpcError;
68
+ }
69
+ interface JsonRpcError {
70
+ code: number;
71
+ message: string;
72
+ data?: unknown;
73
+ }
74
+ declare const JSON_RPC_ERRORS: {
75
+ readonly PARSE_ERROR: -32700;
76
+ readonly INVALID_REQUEST: -32600;
77
+ readonly METHOD_NOT_FOUND: -32601;
78
+ readonly INVALID_PARAMS: -32602;
79
+ readonly INTERNAL_ERROR: -32603;
80
+ readonly TASK_NOT_FOUND: -32001;
81
+ readonly TASK_NOT_CANCELABLE: -32002;
82
+ readonly PUSH_NOTIFICATION_NOT_SUPPORTED: -32003;
83
+ readonly UNSUPPORTED_OPERATION: -32004;
84
+ readonly CONTENT_TYPE_NOT_SUPPORTED: -32005;
85
+ readonly INVALID_AGENT_RESPONSE: -32006;
86
+ /** @deprecated Use TASK_NOT_CANCELABLE */
87
+ readonly SKILL_NOT_FOUND: -32002;
88
+ /** @deprecated */
89
+ readonly UNAUTHORIZED: -32003;
90
+ /** @deprecated */
91
+ readonly RATE_LIMITED: -32004;
92
+ /** @deprecated */
93
+ readonly TASK_CANCELED: -32005;
94
+ };
95
+ /**
96
+ * Internal message part representation.
97
+ * `type` is used internally for routing; the A2A spec uses a oneOf model
98
+ * where the presence of `text`, `data`, or `url` determines the kind.
99
+ */
100
+ interface MessagePart {
101
+ type?: 'text' | 'file' | 'data';
102
+ text?: string;
103
+ data?: unknown;
104
+ mimeType?: string;
105
+ mediaType?: string;
106
+ uri?: string;
107
+ url?: string;
108
+ filename?: string;
109
+ metadata?: Record<string, unknown>;
110
+ }
111
+ interface A2AMessage {
112
+ role: 'user' | 'agent';
113
+ messageId?: string;
114
+ parts: MessagePart[];
115
+ contextId?: string;
116
+ taskId?: string;
117
+ metadata?: Record<string, unknown>;
118
+ referenceTaskIds?: string[];
119
+ }
120
+ /**
121
+ * A2A spec SendMessageRequest (the params for message/send and message/stream)
122
+ */
123
+ interface SendMessageRequest {
124
+ message: A2AMessage & {
125
+ role: string;
126
+ };
127
+ configuration?: {
128
+ acceptedOutputModes?: string[];
129
+ historyLength?: number;
130
+ blocking?: boolean;
131
+ };
132
+ metadata?: Record<string, unknown>;
133
+ }
134
+ type TaskState = 'submitted' | 'working' | 'completed' | 'failed' | 'canceled' | 'input-required' | 'rejected' | 'auth-required';
135
+ /** @deprecated Use TaskState */
136
+ type TaskStatus = TaskState;
137
+ interface TaskStatusObject {
138
+ state: TaskState;
139
+ message?: A2AMessage;
140
+ timestamp?: string;
141
+ }
142
+ interface Task {
143
+ id: string;
144
+ contextId?: string;
145
+ status: TaskStatusObject | TaskState;
146
+ artifacts?: Artifact[];
147
+ error?: {
148
+ message: string;
149
+ };
150
+ metadata?: Record<string, unknown>;
151
+ history?: A2AMessage[];
152
+ }
153
+ interface Artifact {
154
+ artifactId?: string;
155
+ name?: string;
156
+ description?: string;
157
+ parts: MessagePart[];
158
+ index?: number;
159
+ append?: boolean;
160
+ lastChunk?: boolean;
161
+ metadata?: Record<string, unknown>;
162
+ }
163
+ interface TaskHistoryEntry {
164
+ status: TaskStatus;
165
+ message: string;
166
+ timestamp: string;
167
+ }
168
+ interface TasksSendParams {
169
+ skill?: string;
170
+ message: A2AMessage & {
171
+ role: string;
172
+ };
173
+ contextId?: string;
174
+ pushNotification?: {
175
+ url: string;
176
+ authentication?: {
177
+ type: 'bearer' | 'api_key';
178
+ token?: string;
179
+ headerName?: string;
180
+ };
181
+ };
182
+ metadata?: Record<string, unknown>;
183
+ configuration?: {
184
+ acceptedOutputModes?: string[];
185
+ historyLength?: number;
186
+ blocking?: boolean;
187
+ };
188
+ }
189
+ interface TasksGetParams {
190
+ id?: string;
191
+ taskId?: string;
192
+ historyLength?: number;
193
+ includeHistory?: boolean;
194
+ }
195
+ interface TasksCancelParams {
196
+ id?: string;
197
+ taskId?: string;
198
+ reason?: string;
199
+ metadata?: Record<string, unknown>;
200
+ }
201
+ interface TaskStatusUpdateEvent {
202
+ taskId: string;
203
+ contextId: string;
204
+ status: TaskStatusObject;
205
+ metadata?: Record<string, unknown>;
206
+ }
207
+ interface TaskArtifactUpdateEvent {
208
+ taskId: string;
209
+ contextId: string;
210
+ artifact: Artifact;
211
+ append?: boolean;
212
+ lastChunk?: boolean;
213
+ metadata?: Record<string, unknown>;
214
+ }
215
+ interface StreamResponse {
216
+ task?: Task;
217
+ message?: A2AMessage;
218
+ statusUpdate?: TaskStatusUpdateEvent;
219
+ artifactUpdate?: TaskArtifactUpdateEvent;
220
+ }
221
+ /** @deprecated Use TaskStatusUpdateEvent */
222
+ type TaskStatusEvent = TaskStatusUpdateEvent;
223
+ /** @deprecated Use TaskArtifactUpdateEvent */
224
+ type TaskArtifactEvent = TaskArtifactUpdateEvent;
225
+ interface TaskErrorEvent {
226
+ taskId: string;
227
+ error: {
228
+ code: number;
229
+ message: string;
230
+ };
231
+ }
232
+ interface AgentConfig {
233
+ name: string;
234
+ description?: string;
235
+ version?: string;
236
+ port?: number;
237
+ host?: string;
238
+ provider?: {
239
+ organization: string;
240
+ url?: string;
241
+ };
242
+ skills?: SkillConfig[];
243
+ defaultInputModes?: Array<'text' | 'file' | 'data'>;
244
+ defaultOutputModes?: Array<'text' | 'file' | 'data'>;
245
+ llm?: LLMConfig;
246
+ }
247
+ interface SkillConfig {
248
+ id: string;
249
+ name: string;
250
+ description: string;
251
+ systemPrompt?: string;
252
+ inputSchema?: Record<string, unknown>;
253
+ tags?: string[];
254
+ }
255
+ interface LLMConfig {
256
+ provider: 'openai' | 'anthropic';
257
+ model: string;
258
+ /** Gateway model string (e.g. alibaba/qwen3.5-flash) when using Vercel AI Gateway */
259
+ gatewayModel?: string;
260
+ apiKey?: string;
261
+ temperature?: number;
262
+ maxOutputTokens?: number;
263
+ }
264
+ interface ExecutorContext {
265
+ taskId: string;
266
+ contextId?: string;
267
+ skill: SkillConfig;
268
+ message: A2AMessage;
269
+ metadata?: Record<string, unknown>;
270
+ }
271
+ interface ExecutorResult {
272
+ text: string;
273
+ artifacts?: Artifact[];
274
+ }
275
+ interface StreamCallbacks {
276
+ onChunk: (text: string) => Promise<void>;
277
+ onComplete: () => Promise<void>;
278
+ onError: (error: Error) => Promise<void>;
279
+ }
280
+
281
+ /**
282
+ * A2A Protocol Server
283
+ *
284
+ * Express server implementing the A2A (Agent-to-Agent) protocol v0.3.
285
+ * Provides agent card discovery and JSON-RPC task execution endpoints.
286
+ *
287
+ * Supports both legacy method names (tasks/send, tasks/sendSubscribe) and
288
+ * spec-compliant names (message/send, message/stream, SendMessage, etc.).
289
+ */
290
+
291
+ interface A2AServerOptions {
292
+ config: AgentConfig;
293
+ llmConfig?: LLMConfig;
294
+ echoMode?: boolean;
295
+ }
296
+ interface A2AServer {
297
+ app: Application;
298
+ start: () => Promise<void>;
299
+ stop: () => Promise<void>;
300
+ }
301
+ declare function createA2AServer(options: A2AServerOptions): A2AServer;
302
+
303
+ /**
304
+ * A2A Client
305
+ *
306
+ * Client for testing A2A protocol endpoints, including Runtype's A2A surfaces.
307
+ * Supports both legacy (tasks/send) and spec-compliant (message/send) method names.
308
+ */
309
+
310
+ interface A2AClientOptions {
311
+ /** Base URL of the A2A endpoint (with or without /a2a suffix) */
312
+ baseUrl: string;
313
+ /** API key for authentication (optional) */
314
+ apiKey?: string;
315
+ /** Custom headers to include in requests */
316
+ headers?: Record<string, string>;
317
+ }
318
+ declare class A2AClient {
319
+ private baseUrl;
320
+ private rpcUrl;
321
+ private agentCardUrl;
322
+ private apiKey?;
323
+ private headers;
324
+ constructor(options: A2AClientOptions);
325
+ getAgentCard(): Promise<AgentCard>;
326
+ sendTask(params: TasksSendParams): Promise<Task>;
327
+ sendTaskStreaming(params: TasksSendParams, callbacks: {
328
+ onStatus?: (status: string, data: TaskStatusUpdateEvent) => void;
329
+ onArtifact?: (artifact: Artifact) => void;
330
+ onError?: (error: JsonRpcError) => void;
331
+ onChunk?: (text: string) => void;
332
+ }): Promise<void>;
333
+ getTask(taskId: string, historyLength?: number): Promise<Task>;
334
+ cancelTask(taskId: string, reason?: string): Promise<Task>;
335
+ /**
336
+ * Convert legacy TasksSendParams to spec SendMessageRequest format
337
+ */
338
+ private toSendMessageRequest;
339
+ private sendJsonRpc;
340
+ private getHeaders;
341
+ }
342
+ /**
343
+ * Create a client for testing a Runtype A2A surface
344
+ */
345
+ declare function createRuntypeA2AClient(options: {
346
+ productId: string;
347
+ surfaceId: string;
348
+ apiKey: string;
349
+ environment?: 'production' | 'staging' | 'local';
350
+ }): A2AClient;
351
+
352
+ /**
353
+ * Agent Executor
354
+ *
355
+ * Executes tasks using the Vercel AI SDK for LLM integration.
356
+ * Supports both streaming and non-streaming responses.
357
+ */
358
+
359
+ /**
360
+ * Execute a task without streaming
361
+ */
362
+ declare function executeTask(context: ExecutorContext, llmConfig: LLMConfig, skillsCatalog?: SkillConfig[]): Promise<ExecutorResult>;
363
+ /**
364
+ * Execute a task with streaming
365
+ */
366
+ declare function executeTaskStreaming(context: ExecutorContext, llmConfig: LLMConfig, callbacks: StreamCallbacks, skillsCatalog?: SkillConfig[]): Promise<void>;
367
+ /**
368
+ * Simple executor for testing (no LLM, just echoes)
369
+ */
370
+ declare function executeEcho(context: ExecutorContext): Promise<ExecutorResult>;
371
+ /**
372
+ * Simple streaming executor for testing
373
+ */
374
+ declare function executeEchoStreaming(context: ExecutorContext, callbacks: StreamCallbacks): Promise<void>;
375
+
376
+ /**
377
+ * Deterministic Time Executor
378
+ *
379
+ * Computes temporal data using date-fns and the system clock.
380
+ * No LLM generation — all results are deterministic.
381
+ */
382
+
383
+ declare function executeTimeSkill(context: ExecutorContext): Promise<ExecutorResult>;
384
+
385
+ /**
386
+ * Default Skills Configuration
387
+ *
388
+ * Shared skill definitions for A2A agents. Import these in your agent
389
+ * configuration to avoid duplication across different deployment targets.
390
+ */
391
+
392
+ /**
393
+ * Default skills available to A2A agents.
394
+ * Includes deterministic time tools and LLM-powered skills.
395
+ */
396
+ declare const DEFAULT_SKILLS: SkillConfig[];
397
+ /**
398
+ * Default LLM configuration for A2A agents.
399
+ */
400
+ declare const DEFAULT_LLM_CONFIG: LLMConfig;
401
+
402
+ export { A2AClient, type A2AClientOptions, type A2AMessage, type A2AServer, type A2AServerOptions, type AgentCard, type AgentConfig, type AgentInterface, type Artifact, DEFAULT_LLM_CONFIG, DEFAULT_SKILLS, type ExecutorContext, type ExecutorResult, JSON_RPC_ERRORS, type JsonRpcError, type JsonRpcRequest, type JsonRpcResponse, type LLMConfig, type MessagePart, type SendMessageRequest, type Skill, type SkillConfig, type StreamCallbacks, type StreamResponse, type Task, type TaskArtifactEvent, type TaskArtifactUpdateEvent, type TaskErrorEvent, type TaskHistoryEntry, type TaskState, type TaskStatus, type TaskStatusEvent, type TaskStatusObject, type TaskStatusUpdateEvent, type TasksCancelParams, type TasksGetParams, type TasksSendParams, createA2AServer, createRuntypeA2AClient, executeEcho, executeEchoStreaming, executeTask, executeTaskStreaming, executeTimeSkill };
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ A2AClient,
4
+ DEFAULT_LLM_CONFIG,
5
+ DEFAULT_SKILLS,
6
+ JSON_RPC_ERRORS,
7
+ createA2AServer,
8
+ createRuntypeA2AClient,
9
+ executeEcho,
10
+ executeEchoStreaming,
11
+ executeTask,
12
+ executeTaskStreaming,
13
+ executeTimeSkill
14
+ } from "./chunk-KIZQKOZR.js";
15
+ export {
16
+ A2AClient,
17
+ DEFAULT_LLM_CONFIG,
18
+ DEFAULT_SKILLS,
19
+ JSON_RPC_ERRORS,
20
+ createA2AServer,
21
+ createRuntypeA2AClient,
22
+ executeEcho,
23
+ executeEchoStreaming,
24
+ executeTask,
25
+ executeTaskStreaming,
26
+ executeTimeSkill
27
+ };
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,149 @@
1
+ interface Skill {
2
+ id: string;
3
+ name: string;
4
+ description: string;
5
+ inputModes?: string[];
6
+ outputModes?: string[];
7
+ tags: string[];
8
+ examples?: string[];
9
+ inputSchema?: Record<string, unknown>;
10
+ }
11
+ interface SkillConfig {
12
+ id: string;
13
+ name: string;
14
+ description: string;
15
+ systemPrompt?: string;
16
+ inputSchema?: Record<string, unknown>;
17
+ tags?: string[];
18
+ }
19
+ interface LLMConfig {
20
+ provider: 'openai' | 'anthropic';
21
+ model: string;
22
+ /** Gateway model string (e.g. alibaba/qwen3.5-flash) when using Vercel AI Gateway */
23
+ gatewayModel?: string;
24
+ apiKey?: string;
25
+ temperature?: number;
26
+ maxOutputTokens?: number;
27
+ }
28
+
29
+ /**
30
+ * Default Skills Configuration
31
+ *
32
+ * Shared skill definitions for A2A agents. Import these in your agent
33
+ * configuration to avoid duplication across different deployment targets.
34
+ */
35
+
36
+ /**
37
+ * Default skills available to A2A agents.
38
+ * Includes deterministic time tools and LLM-powered skills.
39
+ */
40
+ declare const DEFAULT_SKILLS: SkillConfig[];
41
+ /**
42
+ * Default LLM configuration for A2A agents.
43
+ */
44
+ declare const DEFAULT_LLM_CONFIG: LLMConfig;
45
+
46
+ /**
47
+ * Vercel A2A Configuration
48
+ *
49
+ * Configuration types and helpers for deploying A2A agents to Vercel.
50
+ */
51
+
52
+ interface VercelA2AConfig {
53
+ /** Agent name displayed in the agent card */
54
+ name: string;
55
+ /** Agent description */
56
+ description?: string;
57
+ /** Agent version (default: "1.0.0") */
58
+ version?: string;
59
+ /** Custom skills (defaults to time/*, chat, echo) */
60
+ skills?: SkillConfig[];
61
+ /** Provider information */
62
+ provider?: {
63
+ organization: string;
64
+ url?: string;
65
+ };
66
+ /** URL where the agent is deployed (for agent card) */
67
+ agentUrl?: string;
68
+ /** Default input modes for agent card (MIME types) */
69
+ defaultInputModes?: string[];
70
+ /** Default output modes for agent card (MIME types) */
71
+ defaultOutputModes?: string[];
72
+ /** Run in echo mode (no LLM, for testing) */
73
+ echoMode?: boolean;
74
+ /** LLM configuration (required unless echoMode is true) */
75
+ llmConfig?: LLMConfig;
76
+ }
77
+ /**
78
+ * Resolve configuration with defaults
79
+ */
80
+ declare function resolveConfig(config: VercelA2AConfig): Required<Pick<VercelA2AConfig, 'name' | 'description' | 'version' | 'skills' | 'echoMode' | 'defaultInputModes' | 'defaultOutputModes'>> & {
81
+ provider: {
82
+ organization: string;
83
+ url?: string;
84
+ };
85
+ llmConfig: LLMConfig;
86
+ agentUrl?: string;
87
+ };
88
+ /**
89
+ * Convert SkillConfig to A2A Skill format for agent card
90
+ */
91
+ declare function toAgentCardSkills(skills: SkillConfig[]): Skill[];
92
+
93
+ /**
94
+ * Vercel A2A Request Handlers
95
+ *
96
+ * Stateless request handlers for Vercel serverless/edge functions.
97
+ * These handlers implement the A2A protocol v0.3 using Web standard Request/Response APIs.
98
+ */
99
+
100
+ /**
101
+ * Create a handler for the agent card endpoint (GET /.well-known/agent.json)
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * // app/.well-known/agent.json/route.ts (Next.js App Router)
106
+ * import { createAgentCardHandler } from '@runtypelabs/timely-a2a/vercel'
107
+ *
108
+ * export const GET = createAgentCardHandler({
109
+ * name: 'My Agent',
110
+ * echoMode: true,
111
+ * })
112
+ * ```
113
+ */
114
+ declare function createAgentCardHandler(config: VercelA2AConfig): (_request: Request) => Promise<Response>;
115
+ /**
116
+ * Create a handler for the A2A JSON-RPC endpoint (POST /api/a2a)
117
+ *
118
+ * Gateway models (provider/model format like 'alibaba/qwen3.5-flash') require
119
+ * AI_GATEWAY_API_KEY to be set in the environment.
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * // app/api/a2a/route.ts (Next.js App Router)
124
+ * import { createA2AHandler } from '@runtypelabs/timely-a2a/vercel'
125
+ *
126
+ * export const POST = createA2AHandler({
127
+ * name: 'My Agent',
128
+ * llmConfig: { provider: 'openai', model: 'alibaba/qwen3.5-flash' },
129
+ * })
130
+ * ```
131
+ */
132
+ declare function createA2AHandler(config: VercelA2AConfig): (request: Request) => Promise<Response>;
133
+ /**
134
+ * Create both handlers with shared configuration
135
+ *
136
+ * @example
137
+ * ```typescript
138
+ * const { agentCardHandler, a2aHandler } = createHandlers({
139
+ * name: 'My Agent',
140
+ * echoMode: true,
141
+ * })
142
+ * ```
143
+ */
144
+ declare function createHandlers(config: VercelA2AConfig): {
145
+ agentCardHandler: (_request: Request) => Promise<Response>;
146
+ a2aHandler: (request: Request) => Promise<Response>;
147
+ };
148
+
149
+ export { DEFAULT_LLM_CONFIG, DEFAULT_SKILLS, type VercelA2AConfig, createA2AHandler, createAgentCardHandler, createHandlers, resolveConfig, toAgentCardSkills };