@dexto/server 1.2.5
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/LICENSE +44 -0
- package/dist/a2a/adapters/index.cjs +42 -0
- package/dist/a2a/adapters/index.d.ts +10 -0
- package/dist/a2a/adapters/index.d.ts.map +1 -0
- package/dist/a2a/adapters/index.js +12 -0
- package/dist/a2a/adapters/message.cjs +193 -0
- package/dist/a2a/adapters/message.d.ts +50 -0
- package/dist/a2a/adapters/message.d.ts.map +1 -0
- package/dist/a2a/adapters/message.js +167 -0
- package/dist/a2a/adapters/state.cjs +57 -0
- package/dist/a2a/adapters/state.d.ts +36 -0
- package/dist/a2a/adapters/state.d.ts.map +1 -0
- package/dist/a2a/adapters/state.js +32 -0
- package/dist/a2a/adapters/task-view.cjs +85 -0
- package/dist/a2a/adapters/task-view.d.ts +58 -0
- package/dist/a2a/adapters/task-view.d.ts.map +1 -0
- package/dist/a2a/adapters/task-view.js +60 -0
- package/dist/a2a/index.cjs +51 -0
- package/dist/a2a/index.d.ts +15 -0
- package/dist/a2a/index.d.ts.map +1 -0
- package/dist/a2a/index.js +30 -0
- package/dist/a2a/jsonrpc/index.cjs +38 -0
- package/dist/a2a/jsonrpc/index.d.ts +11 -0
- package/dist/a2a/jsonrpc/index.d.ts.map +1 -0
- package/dist/a2a/jsonrpc/index.js +10 -0
- package/dist/a2a/jsonrpc/methods.cjs +183 -0
- package/dist/a2a/jsonrpc/methods.d.ts +110 -0
- package/dist/a2a/jsonrpc/methods.d.ts.map +1 -0
- package/dist/a2a/jsonrpc/methods.js +159 -0
- package/dist/a2a/jsonrpc/server.cjs +199 -0
- package/dist/a2a/jsonrpc/server.d.ts +100 -0
- package/dist/a2a/jsonrpc/server.d.ts.map +1 -0
- package/dist/a2a/jsonrpc/server.js +175 -0
- package/dist/a2a/jsonrpc/types.cjs +47 -0
- package/dist/a2a/jsonrpc/types.d.ts +91 -0
- package/dist/a2a/jsonrpc/types.d.ts.map +1 -0
- package/dist/a2a/jsonrpc/types.js +21 -0
- package/dist/a2a/types.cjs +16 -0
- package/dist/a2a/types.d.ts +250 -0
- package/dist/a2a/types.d.ts.map +1 -0
- package/dist/a2a/types.js +0 -0
- package/dist/approval/approval-coordinator.cjs +87 -0
- package/dist/approval/approval-coordinator.d.ts +52 -0
- package/dist/approval/approval-coordinator.d.ts.map +1 -0
- package/dist/approval/approval-coordinator.js +63 -0
- package/dist/approval/manual-approval-handler.cjs +100 -0
- package/dist/approval/manual-approval-handler.d.ts +32 -0
- package/dist/approval/manual-approval-handler.d.ts.map +1 -0
- package/dist/approval/manual-approval-handler.js +76 -0
- package/dist/events/a2a-sse-subscriber.cjs +271 -0
- package/dist/events/a2a-sse-subscriber.d.ts +94 -0
- package/dist/events/a2a-sse-subscriber.d.ts.map +1 -0
- package/dist/events/a2a-sse-subscriber.js +247 -0
- package/dist/events/types.cjs +16 -0
- package/dist/events/types.d.ts +15 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +0 -0
- package/dist/events/webhook-subscriber.cjs +301 -0
- package/dist/events/webhook-subscriber.d.ts +64 -0
- package/dist/events/webhook-subscriber.d.ts.map +1 -0
- package/dist/events/webhook-subscriber.js +269 -0
- package/dist/events/webhook-types.cjs +16 -0
- package/dist/events/webhook-types.d.ts +91 -0
- package/dist/events/webhook-types.d.ts.map +1 -0
- package/dist/events/webhook-types.js +0 -0
- package/dist/hono/__tests__/test-fixtures.cjs +236 -0
- package/dist/hono/__tests__/test-fixtures.d.ts +65 -0
- package/dist/hono/__tests__/test-fixtures.d.ts.map +1 -0
- package/dist/hono/__tests__/test-fixtures.js +197 -0
- package/dist/hono/index.cjs +166 -0
- package/dist/hono/index.d.ts +2783 -0
- package/dist/hono/index.d.ts.map +1 -0
- package/dist/hono/index.js +141 -0
- package/dist/hono/middleware/auth.cjs +75 -0
- package/dist/hono/middleware/auth.d.ts +3 -0
- package/dist/hono/middleware/auth.d.ts.map +1 -0
- package/dist/hono/middleware/auth.js +51 -0
- package/dist/hono/middleware/cors.cjs +57 -0
- package/dist/hono/middleware/cors.d.ts +9 -0
- package/dist/hono/middleware/cors.d.ts.map +1 -0
- package/dist/hono/middleware/cors.js +33 -0
- package/dist/hono/middleware/error.cjs +131 -0
- package/dist/hono/middleware/error.d.ts +5 -0
- package/dist/hono/middleware/error.d.ts.map +1 -0
- package/dist/hono/middleware/error.js +105 -0
- package/dist/hono/middleware/redaction.cjs +45 -0
- package/dist/hono/middleware/redaction.d.ts +4 -0
- package/dist/hono/middleware/redaction.d.ts.map +1 -0
- package/dist/hono/middleware/redaction.js +20 -0
- package/dist/hono/node/index.cjs +139 -0
- package/dist/hono/node/index.d.ts +19 -0
- package/dist/hono/node/index.d.ts.map +1 -0
- package/dist/hono/node/index.js +115 -0
- package/dist/hono/routes/a2a-jsonrpc.cjs +119 -0
- package/dist/hono/routes/a2a-jsonrpc.d.ts +46 -0
- package/dist/hono/routes/a2a-jsonrpc.d.ts.map +1 -0
- package/dist/hono/routes/a2a-jsonrpc.js +95 -0
- package/dist/hono/routes/a2a-tasks.cjs +315 -0
- package/dist/hono/routes/a2a-tasks.d.ts +530 -0
- package/dist/hono/routes/a2a-tasks.d.ts.map +1 -0
- package/dist/hono/routes/a2a-tasks.js +291 -0
- package/dist/hono/routes/a2a.cjs +36 -0
- package/dist/hono/routes/a2a.d.ts +4 -0
- package/dist/hono/routes/a2a.d.ts.map +1 -0
- package/dist/hono/routes/a2a.js +12 -0
- package/dist/hono/routes/agents.cjs +735 -0
- package/dist/hono/routes/agents.d.ts +650 -0
- package/dist/hono/routes/agents.d.ts.map +1 -0
- package/dist/hono/routes/agents.js +711 -0
- package/dist/hono/routes/approvals.cjs +125 -0
- package/dist/hono/routes/approvals.d.ts +89 -0
- package/dist/hono/routes/approvals.d.ts.map +1 -0
- package/dist/hono/routes/approvals.js +101 -0
- package/dist/hono/routes/greeting.cjs +60 -0
- package/dist/hono/routes/greeting.d.ts +19 -0
- package/dist/hono/routes/greeting.d.ts.map +1 -0
- package/dist/hono/routes/greeting.js +36 -0
- package/dist/hono/routes/health.cjs +45 -0
- package/dist/hono/routes/health.d.ts +17 -0
- package/dist/hono/routes/health.d.ts.map +1 -0
- package/dist/hono/routes/health.js +21 -0
- package/dist/hono/routes/llm.cjs +298 -0
- package/dist/hono/routes/llm.d.ts +294 -0
- package/dist/hono/routes/llm.d.ts.map +1 -0
- package/dist/hono/routes/llm.js +287 -0
- package/dist/hono/routes/mcp.cjs +356 -0
- package/dist/hono/routes/mcp.d.ts +246 -0
- package/dist/hono/routes/mcp.d.ts.map +1 -0
- package/dist/hono/routes/mcp.js +332 -0
- package/dist/hono/routes/memory.cjs +192 -0
- package/dist/hono/routes/memory.d.ts +146 -0
- package/dist/hono/routes/memory.d.ts.map +1 -0
- package/dist/hono/routes/memory.js +168 -0
- package/dist/hono/routes/messages.cjs +320 -0
- package/dist/hono/routes/messages.d.ts +163 -0
- package/dist/hono/routes/messages.d.ts.map +1 -0
- package/dist/hono/routes/messages.js +296 -0
- package/dist/hono/routes/prompts.cjs +228 -0
- package/dist/hono/routes/prompts.d.ts +150 -0
- package/dist/hono/routes/prompts.d.ts.map +1 -0
- package/dist/hono/routes/prompts.js +204 -0
- package/dist/hono/routes/resources.cjs +110 -0
- package/dist/hono/routes/resources.d.ts +76 -0
- package/dist/hono/routes/resources.d.ts.map +1 -0
- package/dist/hono/routes/resources.js +86 -0
- package/dist/hono/routes/search.cjs +109 -0
- package/dist/hono/routes/search.d.ts +137 -0
- package/dist/hono/routes/search.d.ts.map +1 -0
- package/dist/hono/routes/search.js +85 -0
- package/dist/hono/routes/sessions.cjs +366 -0
- package/dist/hono/routes/sessions.d.ts +229 -0
- package/dist/hono/routes/sessions.d.ts.map +1 -0
- package/dist/hono/routes/sessions.js +342 -0
- package/dist/hono/routes/webhooks.cjs +228 -0
- package/dist/hono/routes/webhooks.d.ts +127 -0
- package/dist/hono/routes/webhooks.d.ts.map +1 -0
- package/dist/hono/routes/webhooks.js +204 -0
- package/dist/hono/schemas/responses.cjs +276 -0
- package/dist/hono/schemas/responses.d.ts +1418 -0
- package/dist/hono/schemas/responses.d.ts.map +1 -0
- package/dist/hono/schemas/responses.js +227 -0
- package/dist/hono/types.cjs +16 -0
- package/dist/hono/types.d.ts +6 -0
- package/dist/hono/types.d.ts.map +1 -0
- package/dist/hono/types.js +0 -0
- package/dist/index.cjs +38 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/mcp/mcp-handler.cjs +145 -0
- package/dist/mcp/mcp-handler.d.ts +14 -0
- package/dist/mcp/mcp-handler.d.ts.map +1 -0
- package/dist/mcp/mcp-handler.js +118 -0
- package/package.json +59 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { TaskView } from "../adapters/task-view.js";
|
|
2
|
+
import { a2aToInternalMessage } from "../adapters/message.js";
|
|
3
|
+
class A2AMethodHandlers {
|
|
4
|
+
constructor(agent) {
|
|
5
|
+
this.agent = agent;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* message/send - Send a message to the agent
|
|
9
|
+
*
|
|
10
|
+
* This is the primary method for interacting with an agent.
|
|
11
|
+
* Creates a task if taskId not provided in message, or adds to existing task.
|
|
12
|
+
*
|
|
13
|
+
* @param params Message send parameters
|
|
14
|
+
* @returns Task or Message depending on configuration.blocking
|
|
15
|
+
*/
|
|
16
|
+
async messageSend(params) {
|
|
17
|
+
if (!params?.message) {
|
|
18
|
+
throw new Error("message is required");
|
|
19
|
+
}
|
|
20
|
+
const { message } = params;
|
|
21
|
+
const taskId = message.taskId;
|
|
22
|
+
const session = await this.agent.createSession(taskId);
|
|
23
|
+
const { text, image, file } = a2aToInternalMessage(message);
|
|
24
|
+
await this.agent.run(text, image, file, session.id);
|
|
25
|
+
const taskView = new TaskView(session);
|
|
26
|
+
const task = await taskView.toA2ATask();
|
|
27
|
+
return task;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* tasks/get - Retrieve a task by ID
|
|
31
|
+
*
|
|
32
|
+
* @param params Parameters containing task ID
|
|
33
|
+
* @returns Task details
|
|
34
|
+
* @throws Error if task not found
|
|
35
|
+
*/
|
|
36
|
+
async tasksGet(params) {
|
|
37
|
+
if (!params?.id) {
|
|
38
|
+
throw new Error("id is required");
|
|
39
|
+
}
|
|
40
|
+
const session = await this.agent.getSession(params.id);
|
|
41
|
+
if (!session) {
|
|
42
|
+
throw new Error(`Task not found: ${params.id}`);
|
|
43
|
+
}
|
|
44
|
+
const taskView = new TaskView(session);
|
|
45
|
+
return await taskView.toA2ATask();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* tasks/list - List all tasks (optional filters)
|
|
49
|
+
*
|
|
50
|
+
* Note: This implementation loads all sessions, applies filters, then paginates.
|
|
51
|
+
* For production with many sessions, consider filtering at the session manager level.
|
|
52
|
+
*
|
|
53
|
+
* @param params Optional filter parameters
|
|
54
|
+
* @returns List of tasks with pagination info
|
|
55
|
+
*/
|
|
56
|
+
async tasksList(params) {
|
|
57
|
+
const sessionIds = await this.agent.listSessions();
|
|
58
|
+
const allTasks = [];
|
|
59
|
+
for (const sessionId of sessionIds) {
|
|
60
|
+
const session = await this.agent.getSession(sessionId);
|
|
61
|
+
if (!session) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const taskView = new TaskView(session);
|
|
65
|
+
const task = await taskView.toA2ATask();
|
|
66
|
+
if (params?.status && task.status.state !== params.status) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (params?.contextId && task.contextId !== params.contextId) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
allTasks.push(task);
|
|
73
|
+
}
|
|
74
|
+
const pageSize = Math.min(params?.pageSize ?? 50, 100);
|
|
75
|
+
const offset = 0;
|
|
76
|
+
const paginatedTasks = allTasks.slice(offset, offset + pageSize);
|
|
77
|
+
return {
|
|
78
|
+
tasks: paginatedTasks,
|
|
79
|
+
totalSize: allTasks.length,
|
|
80
|
+
// Total matching tasks before pagination
|
|
81
|
+
pageSize,
|
|
82
|
+
nextPageToken: ""
|
|
83
|
+
// TODO: Implement pagination tokens
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* tasks/cancel - Cancel a running task
|
|
88
|
+
*
|
|
89
|
+
* @param params Parameters containing task ID
|
|
90
|
+
* @returns Updated task (in canceled state)
|
|
91
|
+
* @throws Error if task not found
|
|
92
|
+
*/
|
|
93
|
+
async tasksCancel(params) {
|
|
94
|
+
if (!params?.id) {
|
|
95
|
+
throw new Error("id is required");
|
|
96
|
+
}
|
|
97
|
+
const session = await this.agent.getSession(params.id);
|
|
98
|
+
if (!session) {
|
|
99
|
+
throw new Error(`Task not found: ${params.id}`);
|
|
100
|
+
}
|
|
101
|
+
session.cancel();
|
|
102
|
+
const taskView = new TaskView(session);
|
|
103
|
+
return await taskView.toA2ATask();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* message/stream - Send a message with streaming response
|
|
107
|
+
*
|
|
108
|
+
* This is a streaming variant of message/send. Instead of returning a complete Task,
|
|
109
|
+
* it returns a stream of TaskStatusUpdateEvent and TaskArtifactUpdateEvent as the
|
|
110
|
+
* agent processes the message.
|
|
111
|
+
*
|
|
112
|
+
* **ARCHITECTURE NOTE**: This method is designed as a lightweight handler that returns
|
|
113
|
+
* a taskId immediately. The actual message processing happens at the transport layer:
|
|
114
|
+
*
|
|
115
|
+
* - **JSON-RPC Transport** (packages/server/src/hono/routes/a2a-jsonrpc.ts:72-112):
|
|
116
|
+
* The route intercepts 'message/stream' requests BEFORE calling this handler,
|
|
117
|
+
* processes the message directly (lines 96-99), and returns an SSE stream.
|
|
118
|
+
* This handler is registered but never actually invoked for JSON-RPC streaming.
|
|
119
|
+
*
|
|
120
|
+
* - **REST Transport** (packages/server/src/hono/routes/a2a-tasks.ts:206-244):
|
|
121
|
+
* Similar pattern - route processes message and returns SSE stream directly.
|
|
122
|
+
*
|
|
123
|
+
* This design separates concerns:
|
|
124
|
+
* - Handler provides taskId for API compatibility
|
|
125
|
+
* - Transport layer manages SSE streaming and message processing
|
|
126
|
+
* - Event bus broadcasts updates to connected SSE clients
|
|
127
|
+
*
|
|
128
|
+
* @param params Message send parameters (same as message/send)
|
|
129
|
+
* @returns Task ID for streaming (transport layer handles actual SSE stream and message processing)
|
|
130
|
+
*/
|
|
131
|
+
async messageStream(params) {
|
|
132
|
+
if (!params?.message) {
|
|
133
|
+
throw new Error("message is required");
|
|
134
|
+
}
|
|
135
|
+
const { message } = params;
|
|
136
|
+
const taskId = message.taskId;
|
|
137
|
+
const session = await this.agent.createSession(taskId);
|
|
138
|
+
return { taskId: session.id };
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Get all method handlers as a Record for JsonRpcServer
|
|
142
|
+
*
|
|
143
|
+
* Returns methods with A2A-compliant names (slash notation).
|
|
144
|
+
*
|
|
145
|
+
* @returns Map of method names to handlers
|
|
146
|
+
*/
|
|
147
|
+
getMethods() {
|
|
148
|
+
return {
|
|
149
|
+
"message/send": this.messageSend.bind(this),
|
|
150
|
+
"message/stream": this.messageStream.bind(this),
|
|
151
|
+
"tasks/get": this.tasksGet.bind(this),
|
|
152
|
+
"tasks/list": this.tasksList.bind(this),
|
|
153
|
+
"tasks/cancel": this.tasksCancel.bind(this)
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
export {
|
|
158
|
+
A2AMethodHandlers
|
|
159
|
+
};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var server_exports = {};
|
|
20
|
+
__export(server_exports, {
|
|
21
|
+
JsonRpcServer: () => JsonRpcServer
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(server_exports);
|
|
24
|
+
var import_types = require("./types.js");
|
|
25
|
+
class JsonRpcServer {
|
|
26
|
+
methods;
|
|
27
|
+
onError;
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.methods = options.methods;
|
|
30
|
+
this.onError = options.onError;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Handle a JSON-RPC request (single or batch).
|
|
34
|
+
*
|
|
35
|
+
* @param request Single request or batch array
|
|
36
|
+
* @returns Single response, batch array, or undefined for notifications
|
|
37
|
+
*/
|
|
38
|
+
async handle(request) {
|
|
39
|
+
if (Array.isArray(request)) {
|
|
40
|
+
return await this.handleBatch(request);
|
|
41
|
+
}
|
|
42
|
+
return await this.handleSingle(request);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Handle a batch of JSON-RPC requests.
|
|
46
|
+
*
|
|
47
|
+
* Processes all requests in parallel per JSON-RPC 2.0 spec.
|
|
48
|
+
*
|
|
49
|
+
* @param requests Array of requests
|
|
50
|
+
* @returns Array of responses, or undefined if all were notifications
|
|
51
|
+
*/
|
|
52
|
+
async handleBatch(requests) {
|
|
53
|
+
if (requests.length === 0) {
|
|
54
|
+
return [
|
|
55
|
+
this.createErrorResponse(null, import_types.JsonRpcErrorCode.INVALID_REQUEST, "Empty batch")
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
const responses = await Promise.all(requests.map((req) => this.handleSingle(req)));
|
|
59
|
+
const validResponses = responses.filter((res) => res !== void 0);
|
|
60
|
+
if (validResponses.length === 0) {
|
|
61
|
+
return void 0;
|
|
62
|
+
}
|
|
63
|
+
return validResponses;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Handle a single JSON-RPC request.
|
|
67
|
+
*
|
|
68
|
+
* @param request JSON-RPC request object
|
|
69
|
+
* @returns JSON-RPC response object, or undefined for notifications
|
|
70
|
+
*/
|
|
71
|
+
async handleSingle(request) {
|
|
72
|
+
try {
|
|
73
|
+
if (request.jsonrpc !== "2.0") {
|
|
74
|
+
if (request.id === void 0) {
|
|
75
|
+
return void 0;
|
|
76
|
+
}
|
|
77
|
+
return this.createErrorResponse(
|
|
78
|
+
request.id ?? null,
|
|
79
|
+
import_types.JsonRpcErrorCode.INVALID_REQUEST,
|
|
80
|
+
'Invalid JSON-RPC version (must be "2.0")'
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
if (typeof request.method !== "string") {
|
|
84
|
+
if (request.id === void 0) {
|
|
85
|
+
return void 0;
|
|
86
|
+
}
|
|
87
|
+
return this.createErrorResponse(
|
|
88
|
+
request.id ?? null,
|
|
89
|
+
import_types.JsonRpcErrorCode.INVALID_REQUEST,
|
|
90
|
+
"Method must be a string"
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
const handler = this.methods[request.method];
|
|
94
|
+
if (!handler) {
|
|
95
|
+
if (request.id === void 0) {
|
|
96
|
+
return void 0;
|
|
97
|
+
}
|
|
98
|
+
return this.createErrorResponse(
|
|
99
|
+
request.id ?? null,
|
|
100
|
+
import_types.JsonRpcErrorCode.METHOD_NOT_FOUND,
|
|
101
|
+
`Method not found: ${request.method}`
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
const result = await handler(request.params);
|
|
106
|
+
if (request.id === void 0) {
|
|
107
|
+
return void 0;
|
|
108
|
+
}
|
|
109
|
+
return this.createSuccessResponse(request.id ?? null, result);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
if (this.onError) {
|
|
112
|
+
this.onError(
|
|
113
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
114
|
+
request
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
if (request.id === void 0) {
|
|
118
|
+
return void 0;
|
|
119
|
+
}
|
|
120
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
121
|
+
const errorData = error instanceof Error ? { name: error.name } : void 0;
|
|
122
|
+
return this.createErrorResponse(
|
|
123
|
+
request.id ?? null,
|
|
124
|
+
import_types.JsonRpcErrorCode.INTERNAL_ERROR,
|
|
125
|
+
errorMessage,
|
|
126
|
+
errorData
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
} catch (error) {
|
|
130
|
+
if (request.id === void 0) {
|
|
131
|
+
return void 0;
|
|
132
|
+
}
|
|
133
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
134
|
+
return this.createErrorResponse(null, import_types.JsonRpcErrorCode.INVALID_REQUEST, errorMessage);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Create a success response.
|
|
139
|
+
*/
|
|
140
|
+
createSuccessResponse(id, result) {
|
|
141
|
+
return {
|
|
142
|
+
jsonrpc: "2.0",
|
|
143
|
+
result,
|
|
144
|
+
id
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Create an error response.
|
|
149
|
+
*/
|
|
150
|
+
createErrorResponse(id, code, message, data) {
|
|
151
|
+
const error = { code, message };
|
|
152
|
+
if (data !== void 0) {
|
|
153
|
+
error.data = data;
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
jsonrpc: "2.0",
|
|
157
|
+
error,
|
|
158
|
+
id
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Register a new method handler.
|
|
163
|
+
*
|
|
164
|
+
* @param method Method name
|
|
165
|
+
* @param handler Handler function
|
|
166
|
+
*/
|
|
167
|
+
registerMethod(method, handler) {
|
|
168
|
+
this.methods[method] = handler;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Unregister a method handler.
|
|
172
|
+
*
|
|
173
|
+
* @param method Method name
|
|
174
|
+
*/
|
|
175
|
+
unregisterMethod(method) {
|
|
176
|
+
delete this.methods[method];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Check if a method is registered.
|
|
180
|
+
*
|
|
181
|
+
* @param method Method name
|
|
182
|
+
* @returns True if method exists
|
|
183
|
+
*/
|
|
184
|
+
hasMethod(method) {
|
|
185
|
+
return method in this.methods;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Get list of registered method names.
|
|
189
|
+
*
|
|
190
|
+
* @returns Array of method names
|
|
191
|
+
*/
|
|
192
|
+
getMethods() {
|
|
193
|
+
return Object.keys(this.methods);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
197
|
+
0 && (module.exports = {
|
|
198
|
+
JsonRpcServer
|
|
199
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON-RPC 2.0 Server
|
|
3
|
+
*
|
|
4
|
+
* Handles JSON-RPC 2.0 request parsing, method dispatch, and response formatting.
|
|
5
|
+
* Implements the full JSON-RPC 2.0 specification including batch requests.
|
|
6
|
+
*/
|
|
7
|
+
import type { JsonRpcRequest, JsonRpcResponse, JsonRpcBatchRequest, JsonRpcBatchResponse } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Method handler function type
|
|
10
|
+
*/
|
|
11
|
+
export type JsonRpcMethodHandler = (params: any) => Promise<any>;
|
|
12
|
+
/**
|
|
13
|
+
* JSON-RPC 2.0 Server Options
|
|
14
|
+
*/
|
|
15
|
+
export interface JsonRpcServerOptions {
|
|
16
|
+
/** Method handlers map */
|
|
17
|
+
methods: Record<string, JsonRpcMethodHandler>;
|
|
18
|
+
/** Optional error handler */
|
|
19
|
+
onError?: (error: Error, request?: JsonRpcRequest) => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* JSON-RPC 2.0 Server
|
|
23
|
+
*
|
|
24
|
+
* Parses JSON-RPC requests, dispatches to handlers, and formats responses.
|
|
25
|
+
*
|
|
26
|
+
* Usage:
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const server = new JsonRpcServer({
|
|
29
|
+
* methods: {
|
|
30
|
+
* 'agent.createTask': async (params) => { ... },
|
|
31
|
+
* 'agent.getTask': async (params) => { ... },
|
|
32
|
+
* }
|
|
33
|
+
* });
|
|
34
|
+
*
|
|
35
|
+
* const response = await server.handle(request);
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare class JsonRpcServer {
|
|
39
|
+
private methods;
|
|
40
|
+
private onError;
|
|
41
|
+
constructor(options: JsonRpcServerOptions);
|
|
42
|
+
/**
|
|
43
|
+
* Handle a JSON-RPC request (single or batch).
|
|
44
|
+
*
|
|
45
|
+
* @param request Single request or batch array
|
|
46
|
+
* @returns Single response, batch array, or undefined for notifications
|
|
47
|
+
*/
|
|
48
|
+
handle(request: JsonRpcRequest | JsonRpcBatchRequest): Promise<JsonRpcResponse | JsonRpcBatchResponse | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* Handle a batch of JSON-RPC requests.
|
|
51
|
+
*
|
|
52
|
+
* Processes all requests in parallel per JSON-RPC 2.0 spec.
|
|
53
|
+
*
|
|
54
|
+
* @param requests Array of requests
|
|
55
|
+
* @returns Array of responses, or undefined if all were notifications
|
|
56
|
+
*/
|
|
57
|
+
private handleBatch;
|
|
58
|
+
/**
|
|
59
|
+
* Handle a single JSON-RPC request.
|
|
60
|
+
*
|
|
61
|
+
* @param request JSON-RPC request object
|
|
62
|
+
* @returns JSON-RPC response object, or undefined for notifications
|
|
63
|
+
*/
|
|
64
|
+
private handleSingle;
|
|
65
|
+
/**
|
|
66
|
+
* Create a success response.
|
|
67
|
+
*/
|
|
68
|
+
private createSuccessResponse;
|
|
69
|
+
/**
|
|
70
|
+
* Create an error response.
|
|
71
|
+
*/
|
|
72
|
+
private createErrorResponse;
|
|
73
|
+
/**
|
|
74
|
+
* Register a new method handler.
|
|
75
|
+
*
|
|
76
|
+
* @param method Method name
|
|
77
|
+
* @param handler Handler function
|
|
78
|
+
*/
|
|
79
|
+
registerMethod(method: string, handler: JsonRpcMethodHandler): void;
|
|
80
|
+
/**
|
|
81
|
+
* Unregister a method handler.
|
|
82
|
+
*
|
|
83
|
+
* @param method Method name
|
|
84
|
+
*/
|
|
85
|
+
unregisterMethod(method: string): void;
|
|
86
|
+
/**
|
|
87
|
+
* Check if a method is registered.
|
|
88
|
+
*
|
|
89
|
+
* @param method Method name
|
|
90
|
+
* @returns True if method exists
|
|
91
|
+
*/
|
|
92
|
+
hasMethod(method: string): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Get list of registered method names.
|
|
95
|
+
*
|
|
96
|
+
* @returns Array of method names
|
|
97
|
+
*/
|
|
98
|
+
getMethods(): string[];
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/a2a/jsonrpc/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACR,cAAc,EACd,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EAEvB,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAC9C,6BAA6B;IAC7B,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,cAAc,KAAK,IAAI,CAAC;CAC9D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,OAAO,CAAiE;gBAEpE,OAAO,EAAE,oBAAoB;IAKzC;;;;;OAKG;IACG,MAAM,CACR,OAAO,EAAE,cAAc,GAAG,mBAAmB,GAC9C,OAAO,CAAC,eAAe,GAAG,oBAAoB,GAAG,SAAS,CAAC;IAU9D;;;;;;;OAOG;YACW,WAAW;IAwBzB;;;;;OAKG;YACW,YAAY;IAwF1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAQ7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkB3B;;;;;OAKG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,IAAI;IAInE;;;;OAIG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAItC;;;;;OAKG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIlC;;;;OAIG;IACH,UAAU,IAAI,MAAM,EAAE;CAGzB"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { JsonRpcErrorCode } from "./types.js";
|
|
2
|
+
class JsonRpcServer {
|
|
3
|
+
methods;
|
|
4
|
+
onError;
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.methods = options.methods;
|
|
7
|
+
this.onError = options.onError;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Handle a JSON-RPC request (single or batch).
|
|
11
|
+
*
|
|
12
|
+
* @param request Single request or batch array
|
|
13
|
+
* @returns Single response, batch array, or undefined for notifications
|
|
14
|
+
*/
|
|
15
|
+
async handle(request) {
|
|
16
|
+
if (Array.isArray(request)) {
|
|
17
|
+
return await this.handleBatch(request);
|
|
18
|
+
}
|
|
19
|
+
return await this.handleSingle(request);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Handle a batch of JSON-RPC requests.
|
|
23
|
+
*
|
|
24
|
+
* Processes all requests in parallel per JSON-RPC 2.0 spec.
|
|
25
|
+
*
|
|
26
|
+
* @param requests Array of requests
|
|
27
|
+
* @returns Array of responses, or undefined if all were notifications
|
|
28
|
+
*/
|
|
29
|
+
async handleBatch(requests) {
|
|
30
|
+
if (requests.length === 0) {
|
|
31
|
+
return [
|
|
32
|
+
this.createErrorResponse(null, JsonRpcErrorCode.INVALID_REQUEST, "Empty batch")
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
const responses = await Promise.all(requests.map((req) => this.handleSingle(req)));
|
|
36
|
+
const validResponses = responses.filter((res) => res !== void 0);
|
|
37
|
+
if (validResponses.length === 0) {
|
|
38
|
+
return void 0;
|
|
39
|
+
}
|
|
40
|
+
return validResponses;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Handle a single JSON-RPC request.
|
|
44
|
+
*
|
|
45
|
+
* @param request JSON-RPC request object
|
|
46
|
+
* @returns JSON-RPC response object, or undefined for notifications
|
|
47
|
+
*/
|
|
48
|
+
async handleSingle(request) {
|
|
49
|
+
try {
|
|
50
|
+
if (request.jsonrpc !== "2.0") {
|
|
51
|
+
if (request.id === void 0) {
|
|
52
|
+
return void 0;
|
|
53
|
+
}
|
|
54
|
+
return this.createErrorResponse(
|
|
55
|
+
request.id ?? null,
|
|
56
|
+
JsonRpcErrorCode.INVALID_REQUEST,
|
|
57
|
+
'Invalid JSON-RPC version (must be "2.0")'
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
if (typeof request.method !== "string") {
|
|
61
|
+
if (request.id === void 0) {
|
|
62
|
+
return void 0;
|
|
63
|
+
}
|
|
64
|
+
return this.createErrorResponse(
|
|
65
|
+
request.id ?? null,
|
|
66
|
+
JsonRpcErrorCode.INVALID_REQUEST,
|
|
67
|
+
"Method must be a string"
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
const handler = this.methods[request.method];
|
|
71
|
+
if (!handler) {
|
|
72
|
+
if (request.id === void 0) {
|
|
73
|
+
return void 0;
|
|
74
|
+
}
|
|
75
|
+
return this.createErrorResponse(
|
|
76
|
+
request.id ?? null,
|
|
77
|
+
JsonRpcErrorCode.METHOD_NOT_FOUND,
|
|
78
|
+
`Method not found: ${request.method}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
const result = await handler(request.params);
|
|
83
|
+
if (request.id === void 0) {
|
|
84
|
+
return void 0;
|
|
85
|
+
}
|
|
86
|
+
return this.createSuccessResponse(request.id ?? null, result);
|
|
87
|
+
} catch (error) {
|
|
88
|
+
if (this.onError) {
|
|
89
|
+
this.onError(
|
|
90
|
+
error instanceof Error ? error : new Error(String(error)),
|
|
91
|
+
request
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (request.id === void 0) {
|
|
95
|
+
return void 0;
|
|
96
|
+
}
|
|
97
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
98
|
+
const errorData = error instanceof Error ? { name: error.name } : void 0;
|
|
99
|
+
return this.createErrorResponse(
|
|
100
|
+
request.id ?? null,
|
|
101
|
+
JsonRpcErrorCode.INTERNAL_ERROR,
|
|
102
|
+
errorMessage,
|
|
103
|
+
errorData
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
} catch (error) {
|
|
107
|
+
if (request.id === void 0) {
|
|
108
|
+
return void 0;
|
|
109
|
+
}
|
|
110
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
111
|
+
return this.createErrorResponse(null, JsonRpcErrorCode.INVALID_REQUEST, errorMessage);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Create a success response.
|
|
116
|
+
*/
|
|
117
|
+
createSuccessResponse(id, result) {
|
|
118
|
+
return {
|
|
119
|
+
jsonrpc: "2.0",
|
|
120
|
+
result,
|
|
121
|
+
id
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Create an error response.
|
|
126
|
+
*/
|
|
127
|
+
createErrorResponse(id, code, message, data) {
|
|
128
|
+
const error = { code, message };
|
|
129
|
+
if (data !== void 0) {
|
|
130
|
+
error.data = data;
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
jsonrpc: "2.0",
|
|
134
|
+
error,
|
|
135
|
+
id
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Register a new method handler.
|
|
140
|
+
*
|
|
141
|
+
* @param method Method name
|
|
142
|
+
* @param handler Handler function
|
|
143
|
+
*/
|
|
144
|
+
registerMethod(method, handler) {
|
|
145
|
+
this.methods[method] = handler;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Unregister a method handler.
|
|
149
|
+
*
|
|
150
|
+
* @param method Method name
|
|
151
|
+
*/
|
|
152
|
+
unregisterMethod(method) {
|
|
153
|
+
delete this.methods[method];
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Check if a method is registered.
|
|
157
|
+
*
|
|
158
|
+
* @param method Method name
|
|
159
|
+
* @returns True if method exists
|
|
160
|
+
*/
|
|
161
|
+
hasMethod(method) {
|
|
162
|
+
return method in this.methods;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get list of registered method names.
|
|
166
|
+
*
|
|
167
|
+
* @returns Array of method names
|
|
168
|
+
*/
|
|
169
|
+
getMethods() {
|
|
170
|
+
return Object.keys(this.methods);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
export {
|
|
174
|
+
JsonRpcServer
|
|
175
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var types_exports = {};
|
|
20
|
+
__export(types_exports, {
|
|
21
|
+
JsonRpcErrorCode: () => JsonRpcErrorCode,
|
|
22
|
+
isJsonRpcError: () => isJsonRpcError,
|
|
23
|
+
isJsonRpcSuccess: () => isJsonRpcSuccess
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(types_exports);
|
|
26
|
+
var JsonRpcErrorCode = /* @__PURE__ */ ((JsonRpcErrorCode2) => {
|
|
27
|
+
JsonRpcErrorCode2[JsonRpcErrorCode2["PARSE_ERROR"] = -32700] = "PARSE_ERROR";
|
|
28
|
+
JsonRpcErrorCode2[JsonRpcErrorCode2["INVALID_REQUEST"] = -32600] = "INVALID_REQUEST";
|
|
29
|
+
JsonRpcErrorCode2[JsonRpcErrorCode2["METHOD_NOT_FOUND"] = -32601] = "METHOD_NOT_FOUND";
|
|
30
|
+
JsonRpcErrorCode2[JsonRpcErrorCode2["INVALID_PARAMS"] = -32602] = "INVALID_PARAMS";
|
|
31
|
+
JsonRpcErrorCode2[JsonRpcErrorCode2["INTERNAL_ERROR"] = -32603] = "INTERNAL_ERROR";
|
|
32
|
+
JsonRpcErrorCode2[JsonRpcErrorCode2["SERVER_ERROR_START"] = -32099] = "SERVER_ERROR_START";
|
|
33
|
+
JsonRpcErrorCode2[JsonRpcErrorCode2["SERVER_ERROR_END"] = -32e3] = "SERVER_ERROR_END";
|
|
34
|
+
return JsonRpcErrorCode2;
|
|
35
|
+
})(JsonRpcErrorCode || {});
|
|
36
|
+
function isJsonRpcError(response) {
|
|
37
|
+
return "error" in response;
|
|
38
|
+
}
|
|
39
|
+
function isJsonRpcSuccess(response) {
|
|
40
|
+
return "result" in response;
|
|
41
|
+
}
|
|
42
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
43
|
+
0 && (module.exports = {
|
|
44
|
+
JsonRpcErrorCode,
|
|
45
|
+
isJsonRpcError,
|
|
46
|
+
isJsonRpcSuccess
|
|
47
|
+
});
|