@artinet/sdk 0.5.17 → 0.5.18

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.
Files changed (151) hide show
  1. package/README.md +101 -26
  2. package/dist/browser/browser.d.ts +9 -0
  3. package/dist/browser/browser.js +10 -0
  4. package/dist/browser/client/a2a-client.d.ts +126 -0
  5. package/dist/browser/client/a2a-client.js +221 -0
  6. package/dist/browser/client/index.d.ts +1 -0
  7. package/dist/browser/client/index.js +1 -0
  8. package/dist/browser/services/a2a/helpers/message-builder.d.ts +12 -0
  9. package/dist/browser/services/a2a/helpers/message-builder.js +61 -0
  10. package/dist/browser/transport/rpc/parser.d.ts +15 -0
  11. package/dist/browser/transport/rpc/parser.js +48 -0
  12. package/dist/browser/transport/rpc/rpc-client.d.ts +80 -0
  13. package/dist/browser/transport/rpc/rpc-client.js +189 -0
  14. package/dist/browser/transport/streaming/event-stream.d.ts +25 -0
  15. package/dist/browser/transport/streaming/event-stream.js +99 -0
  16. package/dist/browser/types/ext.d.ts +13 -0
  17. package/dist/browser/types/ext.js +10 -0
  18. package/dist/browser/types/index.d.ts +4 -0
  19. package/dist/browser/types/index.js +4 -0
  20. package/dist/browser/types/interfaces/client.d.ts +135 -0
  21. package/dist/browser/types/interfaces/client.js +5 -0
  22. package/dist/browser/types/interfaces/index.d.ts +3 -0
  23. package/dist/browser/types/interfaces/index.js +3 -0
  24. package/dist/browser/types/interfaces/services/a2a/builder.d.ts +37 -0
  25. package/dist/browser/types/interfaces/services/a2a/builder.js +5 -0
  26. package/dist/browser/types/interfaces/services/a2a/context.d.ts +162 -0
  27. package/dist/browser/types/interfaces/services/a2a/context.js +5 -0
  28. package/dist/browser/types/interfaces/services/a2a/engine.d.ts +7 -0
  29. package/dist/browser/types/interfaces/services/a2a/engine.js +5 -0
  30. package/dist/browser/types/interfaces/services/a2a/index.d.ts +5 -0
  31. package/dist/browser/types/interfaces/services/a2a/index.js +5 -0
  32. package/dist/browser/types/interfaces/services/a2a/legacy.d.ts +93 -0
  33. package/dist/browser/types/interfaces/services/a2a/legacy.js +5 -0
  34. package/dist/browser/types/interfaces/services/a2a/service.d.ts +413 -0
  35. package/dist/browser/types/interfaces/services/a2a/service.js +5 -0
  36. package/dist/browser/types/interfaces/services/core/context/command.d.ts +25 -0
  37. package/dist/browser/types/interfaces/services/core/context/command.js +5 -0
  38. package/dist/browser/types/interfaces/services/core/context/context.d.ts +207 -0
  39. package/dist/browser/types/interfaces/services/core/context/context.js +5 -0
  40. package/dist/browser/types/interfaces/services/core/context/index.d.ts +3 -0
  41. package/dist/browser/types/interfaces/services/core/context/index.js +3 -0
  42. package/dist/browser/types/interfaces/services/core/context/types.d.ts +11 -0
  43. package/dist/browser/types/interfaces/services/core/context/types.js +5 -0
  44. package/dist/browser/types/interfaces/services/core/execution/engine.d.ts +106 -0
  45. package/dist/browser/types/interfaces/services/core/execution/engine.js +5 -0
  46. package/dist/browser/types/interfaces/services/core/execution/environment.d.ts +11 -0
  47. package/dist/browser/types/interfaces/services/core/execution/environment.js +5 -0
  48. package/dist/browser/types/interfaces/services/core/execution/execute.d.ts +7 -0
  49. package/dist/browser/types/interfaces/services/core/execution/execute.js +5 -0
  50. package/dist/browser/types/interfaces/services/core/execution/index.d.ts +3 -0
  51. package/dist/browser/types/interfaces/services/core/execution/index.js +3 -0
  52. package/dist/browser/types/interfaces/services/core/index.d.ts +4 -0
  53. package/dist/browser/types/interfaces/services/core/index.js +4 -0
  54. package/dist/browser/types/interfaces/services/core/managers/cancellation.d.ts +9 -0
  55. package/dist/browser/types/interfaces/services/core/managers/cancellation.js +5 -0
  56. package/dist/browser/types/interfaces/services/core/managers/connection.d.ts +9 -0
  57. package/dist/browser/types/interfaces/services/core/managers/connection.js +5 -0
  58. package/dist/browser/types/interfaces/services/core/managers/context.d.ts +17 -0
  59. package/dist/browser/types/interfaces/services/core/managers/context.js +5 -0
  60. package/dist/browser/types/interfaces/services/core/managers/event.d.ts +328 -0
  61. package/dist/browser/types/interfaces/services/core/managers/event.js +5 -0
  62. package/dist/browser/types/interfaces/services/core/managers/index.d.ts +6 -0
  63. package/dist/browser/types/interfaces/services/core/managers/index.js +6 -0
  64. package/dist/browser/types/interfaces/services/core/managers/stream.d.ts +217 -0
  65. package/dist/browser/types/interfaces/services/core/managers/stream.js +5 -0
  66. package/dist/browser/types/interfaces/services/core/managers/task.d.ts +9 -0
  67. package/dist/browser/types/interfaces/services/core/managers/task.js +1 -0
  68. package/dist/browser/types/interfaces/services/core/service.d.ts +115 -0
  69. package/dist/browser/types/interfaces/services/core/service.js +5 -0
  70. package/dist/browser/types/interfaces/services/index.d.ts +4 -0
  71. package/dist/browser/types/interfaces/services/index.js +4 -0
  72. package/dist/browser/types/interfaces/services/mcp/index.d.ts +1 -0
  73. package/dist/browser/types/interfaces/services/mcp/index.js +1 -0
  74. package/dist/browser/types/interfaces/services/mcp/service.d.ts +49 -0
  75. package/dist/browser/types/interfaces/services/mcp/service.js +5 -0
  76. package/dist/browser/types/interfaces/services/protocol.d.ts +33 -0
  77. package/dist/browser/types/interfaces/services/protocol.js +34 -0
  78. package/dist/browser/types/interfaces/storage.d.ts +8 -0
  79. package/dist/browser/types/interfaces/storage.js +5 -0
  80. package/dist/browser/types/schemas/a2a/agent.d.ts +2583 -0
  81. package/dist/browser/types/schemas/a2a/agent.js +323 -0
  82. package/dist/browser/types/schemas/a2a/auth.d.ts +908 -0
  83. package/dist/browser/types/schemas/a2a/auth.js +283 -0
  84. package/dist/browser/types/schemas/a2a/error.d.ts +396 -0
  85. package/dist/browser/types/schemas/a2a/error.js +163 -0
  86. package/dist/browser/types/schemas/a2a/index.d.ts +11 -0
  87. package/dist/browser/types/schemas/a2a/index.js +11 -0
  88. package/dist/browser/types/schemas/a2a/kind.d.ts +11 -0
  89. package/dist/browser/types/schemas/a2a/kind.js +20 -0
  90. package/dist/browser/types/schemas/a2a/message.d.ts +10343 -0
  91. package/dist/browser/types/schemas/a2a/message.js +130 -0
  92. package/dist/browser/types/schemas/a2a/notification.d.ts +1517 -0
  93. package/dist/browser/types/schemas/a2a/notification.js +203 -0
  94. package/dist/browser/types/schemas/a2a/parameters.d.ts +956 -0
  95. package/dist/browser/types/schemas/a2a/parameters.js +241 -0
  96. package/dist/browser/types/schemas/a2a/protocol.d.ts +14363 -0
  97. package/dist/browser/types/schemas/a2a/protocol.js +59 -0
  98. package/dist/browser/types/schemas/a2a/rpc.d.ts +182 -0
  99. package/dist/browser/types/schemas/a2a/rpc.js +126 -0
  100. package/dist/browser/types/schemas/a2a/task.d.ts +5886 -0
  101. package/dist/browser/types/schemas/a2a/task.js +134 -0
  102. package/dist/browser/types/schemas/a2a/transport.d.ts +31 -0
  103. package/dist/browser/types/schemas/a2a/transport.js +28 -0
  104. package/dist/browser/types/schemas/index.d.ts +1 -0
  105. package/dist/browser/types/schemas/index.js +1 -0
  106. package/dist/browser/types/utils/index.d.ts +1 -0
  107. package/dist/browser/types/utils/index.js +1 -0
  108. package/dist/browser/types/utils/transform.d.ts +64 -0
  109. package/dist/browser/types/utils/transform.js +35 -0
  110. package/dist/browser/utils/common/constants.d.ts +11 -0
  111. package/dist/browser/utils/common/constants.js +38 -0
  112. package/dist/browser/utils/common/errors.d.ts +24 -0
  113. package/dist/browser/utils/common/errors.js +42 -0
  114. package/dist/browser/utils/common/utils.d.ts +9 -0
  115. package/dist/browser/utils/common/utils.js +11 -0
  116. package/dist/browser/utils/logging/index.d.ts +2 -0
  117. package/dist/browser/utils/logging/index.js +2 -0
  118. package/dist/browser/utils/logging/log.d.ts +33 -0
  119. package/dist/browser/utils/logging/log.js +75 -0
  120. package/dist/browser/utils/logging/logger.d.ts +18 -0
  121. package/dist/browser/utils/logging/logger.js +18 -0
  122. package/dist/client/a2a-client.d.ts +2 -1
  123. package/dist/client/a2a-client.js +13 -4
  124. package/dist/server/express/errors.js +1 -1
  125. package/dist/server/express/middeware.d.ts +2 -2
  126. package/dist/server/express/middeware.js +26 -6
  127. package/dist/server/express/server.d.ts +2 -1
  128. package/dist/server/express/server.js +32 -6
  129. package/dist/services/a2a/factory/builder.js +6 -1
  130. package/dist/services/a2a/factory/service.js +1 -1
  131. package/dist/services/a2a/helpers/agentcard-builder.js +1 -0
  132. package/dist/services/a2a/helpers/history.d.ts +2 -0
  133. package/dist/services/a2a/helpers/history.js +3 -0
  134. package/dist/services/a2a/helpers/index.d.ts +2 -0
  135. package/dist/services/a2a/helpers/index.js +2 -0
  136. package/dist/services/a2a/methods/get-task.js +2 -0
  137. package/dist/services/a2a/methods/send-message.js +18 -1
  138. package/dist/services/a2a/service.d.ts +2 -1
  139. package/dist/services/a2a/service.js +20 -6
  140. package/dist/services/mcp/service.js +0 -1
  141. package/dist/transport/rpc/parser.js +2 -2
  142. package/dist/transport/rpc/rpc-client.js +2 -2
  143. package/dist/types/interfaces/services/a2a/service.d.ts +4 -0
  144. package/dist/utils/common/constants.js +1 -1
  145. package/dist/utils/common/errors.d.ts +2 -1
  146. package/dist/utils/common/errors.js +2 -1
  147. package/dist/utils/common/schema-validation.d.ts +2 -0
  148. package/dist/utils/common/schema-validation.js +12 -0
  149. package/dist/utils/index.d.ts +1 -0
  150. package/dist/utils/index.js +1 -0
  151. package/package.json +20 -17
@@ -2,9 +2,10 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { executeJsonRpcRequest, executeGetRequest, executeStreamEvents, } from "../transport/index.js";
6
- import { INTERNAL_ERROR } from "../utils/index.js";
7
- import { logError } from "../utils/logging/index.js";
5
+ import { executeJsonRpcRequest, executeGetRequest, } from "../transport/rpc/rpc-client.js";
6
+ import { executeStreamEvents } from "../transport/streaming/event-stream.js";
7
+ import { INTERNAL_ERROR } from "../utils/common/errors.js";
8
+ import { logError } from "../utils/logging/log.js";
8
9
  import { createMessageSendParams } from "../services/a2a/helpers/message-builder.js";
9
10
  /**
10
11
  * A2AClient is the main client class for interacting with Agent2Agent (A2A) protocol-compliant services.
@@ -16,6 +17,7 @@ export class A2AClient {
16
17
  customHeaders = {};
17
18
  fallbackPath;
18
19
  agentUrl;
20
+ mergePath;
19
21
  /**
20
22
  * Creates a new A2AClient instance.
21
23
  * @param baseUrl The base URL for the A2A server.
@@ -30,11 +32,12 @@ export class A2AClient {
30
32
  * const card = await client.agentCard();
31
33
  * console.log(card);
32
34
  */
33
- constructor(baseUrl, headers = {}, fallbackPath) {
35
+ constructor(baseUrl, headers = {}, fallbackPath, mergePath = false) {
34
36
  this.baseUrl = typeof baseUrl === "string" ? new URL(baseUrl) : baseUrl;
35
37
  this.customHeaders = headers;
36
38
  this.fallbackPath = fallbackPath ?? "/agent-card";
37
39
  this.agentUrl = this.baseUrl;
40
+ this.mergePath = mergePath;
38
41
  }
39
42
  /**
40
43
  * Retrieves the AgentCard from the A2A server.
@@ -47,6 +50,9 @@ export class A2AClient {
47
50
  }
48
51
  // Standard location for agent cards
49
52
  const wellKnownUrl = new URL("/.well-known/agent-card.json", this.baseUrl);
53
+ if (this.mergePath) {
54
+ wellKnownUrl.pathname = this.baseUrl.pathname + wellKnownUrl.pathname;
55
+ }
50
56
  try {
51
57
  try {
52
58
  if (!URL.canParse(wellKnownUrl)) {
@@ -60,6 +66,9 @@ export class A2AClient {
60
66
  }
61
67
  catch (error) {
62
68
  const fallbackUrl = new URL(this.fallbackPath, this.baseUrl);
69
+ if (this.mergePath) {
70
+ fallbackUrl.pathname = this.baseUrl.pathname + fallbackUrl.pathname;
71
+ }
63
72
  const fallbackCard = await executeGetRequest(fallbackUrl, this.customHeaders, "agent card (fallback)");
64
73
  if (!fallbackCard.name ||
65
74
  fallbackCard.name === null ||
@@ -13,7 +13,7 @@ export const errorHandler = (err, req, res, _) => {
13
13
  if (res.headersSent) {
14
14
  headersSent = true;
15
15
  }
16
- logError("errorHandler", JSON.stringify(err), err);
16
+ logError("errorHandler", JSON.stringify(err, null, 2), err);
17
17
  let reqId = null;
18
18
  try {
19
19
  if (req.body && typeof req.body === "object" && "id" in req.body) {
@@ -3,5 +3,5 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { NextFunction, Request, Response } from "express";
6
- import { A2AServiceInterface } from "../../types/index.js";
7
- export declare function jsonRPCMiddleware(service: A2AServiceInterface, req: Request, res: Response, next: NextFunction): Promise<void>;
6
+ import { A2AServiceInterface, AgentCard } from "../../types/index.js";
7
+ export declare function jsonRPCMiddleware(service: A2AServiceInterface, req: Request, res: Response, next: NextFunction, extendedAgentCard?: AgentCard): Promise<void>;
@@ -2,7 +2,7 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { PUSH_NOTIFICATION_NOT_SUPPORTED, INVALID_REQUEST, INVALID_PARAMS, METHOD_NOT_FOUND, } from "../../utils/index.js";
5
+ import { PUSH_NOTIFICATION_NOT_SUPPORTED, INVALID_REQUEST, INVALID_PARAMS, METHOD_NOT_FOUND, AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED, } from "../../utils/index.js";
6
6
  import { logError } from "../../utils/logging/index.js";
7
7
  const isValidMethod = (method) => {
8
8
  return (method &&
@@ -12,8 +12,15 @@ const isValidMethod = (method) => {
12
12
  typeof method === "string");
13
13
  };
14
14
  const checkParams = (params, method) => {
15
- if (!params ||
16
- (typeof params === "object" && Object.keys(params).length === 0)) {
15
+ if (!params || (typeof params !== "object" && !Array.isArray(params))) {
16
+ throw INVALID_PARAMS({
17
+ data: {
18
+ message: "Invalid params",
19
+ method,
20
+ },
21
+ });
22
+ }
23
+ else if (typeof params === "object" && Object.keys(params).length === 0) {
17
24
  throw INVALID_PARAMS({
18
25
  data: {
19
26
  message: "No params provided",
@@ -22,10 +29,10 @@ const checkParams = (params, method) => {
22
29
  });
23
30
  }
24
31
  };
25
- export async function jsonRPCMiddleware(service, req, res, next) {
32
+ export async function jsonRPCMiddleware(service, req, res, next, extendedAgentCard) {
26
33
  const { method, params, id, jsonrpc } = req.body;
27
- // Validate JSON-RPC format
28
- if (jsonrpc !== "2.0" || !id) {
34
+ if (jsonrpc !== "2.0" ||
35
+ (id && typeof id !== "string" && typeof id !== "number" && id !== null)) {
29
36
  res.json({
30
37
  jsonrpc: "2.0",
31
38
  id: id || null,
@@ -98,6 +105,19 @@ export async function jsonRPCMiddleware(service, req, res, next) {
98
105
  },
99
106
  });
100
107
  }
108
+ case "agent/getAuthenticatedExtendedCard": {
109
+ if (!extendedAgentCard ||
110
+ service.agentCard.supportsAuthenticatedExtendedCard !== true) {
111
+ throw AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED({
112
+ data: {
113
+ message: "Authenticated Extended Card is not configured",
114
+ method,
115
+ },
116
+ });
117
+ }
118
+ result = extendedAgentCard;
119
+ break;
120
+ }
101
121
  default:
102
122
  throw METHOD_NOT_FOUND({
103
123
  data: {
@@ -3,12 +3,13 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import express from "express";
6
- import { Agent, FactoryParams as CreateAgentParams } from "../../types/index.js";
6
+ import { Agent, AgentCard, FactoryParams as CreateAgentParams } from "../../types/index.js";
7
7
  import { CorsOptions } from "cors";
8
8
  export interface ServerParams {
9
9
  app?: express.Express;
10
10
  corsOptions?: CorsOptions;
11
11
  basePath?: string;
12
+ extendedAgentCard?: AgentCard;
12
13
  }
13
14
  export declare function createAgentServer(params: ServerParams & {
14
15
  agent: Agent | CreateAgentParams;
@@ -3,11 +3,27 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import express from "express";
6
- import { INVALID_REQUEST } from "../../utils/index.js";
6
+ import { INVALID_REQUEST, PARSE_ERROR } from "../../utils/index.js";
7
7
  import { createAgent } from "../../services/index.js";
8
8
  import cors from "cors";
9
9
  import { jsonRPCMiddleware } from "./middeware.js";
10
10
  import { errorHandler } from "./errors.js";
11
+ function rpcParser(req, res, next) {
12
+ express.json()(req, res, (err) => {
13
+ if (err) {
14
+ if (err instanceof SyntaxError &&
15
+ "status" in err &&
16
+ err.status === 400 &&
17
+ "body" in err) {
18
+ return next(PARSE_ERROR({
19
+ data: err.message,
20
+ }));
21
+ }
22
+ return next(err);
23
+ }
24
+ next();
25
+ });
26
+ }
11
27
  function ensureAgent(agentOrParams) {
12
28
  if (agentOrParams &&
13
29
  typeof agentOrParams === "object" &&
@@ -40,9 +56,19 @@ function ensureAgent(agentOrParams) {
40
56
  export function createAgentServer(params) {
41
57
  const { app = express(), basePath = "/", agentCardPath = "/.well-known/agent-card.json", agent, } = params;
42
58
  const agentInstance = ensureAgent(agent);
43
- app.use(express.json());
44
59
  app.use(cors(params.corsOptions));
45
- app.get(agentCardPath, (_, res) => {
60
+ if (agentCardPath !== "/.well-known/agent-card.json") {
61
+ // mount at the root for compliance with RFC8615 standard
62
+ app.use("/.well-known/agent-card.json", (_, res) => {
63
+ res.json(agentInstance.agentCard);
64
+ });
65
+ }
66
+ app.use(agentCardPath, (_, res) => {
67
+ // mount at the custom path
68
+ res.json(agentInstance.agentCard);
69
+ });
70
+ // mount at the old agent card path for backwards compatibility
71
+ app.use("/.well-known/agent.json", (_, res) => {
46
72
  res.json(agentInstance.agentCard);
47
73
  });
48
74
  /**
@@ -51,10 +77,10 @@ export function createAgentServer(params) {
51
77
  * transport layer.
52
78
  */
53
79
  //a standard express middleware to handle json-rpc requests
54
- app.post(basePath, express.json(), async (req, res, next) => {
80
+ app.post(basePath, rpcParser, async (req, res, next) => {
55
81
  const { jsonrpc } = req.body;
56
82
  if (jsonrpc === "2.0") {
57
- return await jsonRPCMiddleware(agentInstance, req, res, next);
83
+ return await jsonRPCMiddleware(agentInstance, req, res, next, params.extendedAgentCard);
58
84
  }
59
85
  next(INVALID_REQUEST({ data: { message: "Invalid JSON-RPC request" } }));
60
86
  });
@@ -73,7 +99,7 @@ export function createAgentServer(params) {
73
99
  },
74
100
  })
75
101
  );
76
- * we could also just use trpc directly or any other transport layer
102
+ * we could also use trpc directly or any other transport layer
77
103
  */
78
104
  return { app, agent: agentInstance };
79
105
  }
@@ -299,6 +299,7 @@ export function createAgentExecutor(stepsList) {
299
299
  }
300
300
  const taskStarted = SUBMITTED_UPDATE(taskId, contextId);
301
301
  yield taskStarted;
302
+ let finalState = TaskState.completed;
302
303
  const finalMessage = {
303
304
  taskId: taskId,
304
305
  contextId: contextId,
@@ -308,6 +309,10 @@ export function createAgentExecutor(stepsList) {
308
309
  parts: [],
309
310
  };
310
311
  for (const step of stepsList) {
312
+ if (context.isCancelled()) {
313
+ finalState = TaskState.canceled;
314
+ break;
315
+ }
311
316
  const ret = await step.step({ ...stepArgs });
312
317
  let parts = [];
313
318
  if (Array.isArray(ret)) {
@@ -350,7 +355,7 @@ export function createAgentExecutor(stepsList) {
350
355
  id: taskId,
351
356
  contextId: contextId,
352
357
  status: {
353
- state: TaskState.completed,
358
+ state: finalState,
354
359
  timestamp: new Date().toISOString(),
355
360
  message: finalMessage,
356
361
  },
@@ -7,6 +7,6 @@ import { ContextManager, ConnectionManager, CancellationManager, TaskManager, }
7
7
  import { createMethods } from "./method.js";
8
8
  import { createAgentCard } from "../helpers/agentcard-builder.js";
9
9
  export function createService(params) {
10
- return new A2AService(createAgentCard(params.agentCard), params.engine, params.contexts ?? new ContextManager(), params.connections ?? new ConnectionManager(), params.cancellations ?? new CancellationManager(), params.tasks ?? new TaskManager(), createMethods(params.methods), params.events);
10
+ return new A2AService(createAgentCard(params.agentCard), params.engine, params.contexts ?? new ContextManager(), params.connections ?? new ConnectionManager(), params.cancellations ?? new CancellationManager(), params.tasks ?? new TaskManager(), createMethods(params.methods), params.events, params.enforceParamValidation ?? false);
11
11
  }
12
12
  export const createAgent = createService;
@@ -11,6 +11,7 @@ export class AgentCardBuilder {
11
11
  defaultInputModes: agentCard.defaultInputModes ?? [],
12
12
  defaultOutputModes: agentCard.defaultOutputModes ?? [],
13
13
  skills: agentCard.skills ?? [],
14
+ preferredTransport: agentCard.preferredTransport ?? "JSONRPC",
14
15
  };
15
16
  }
16
17
  valueOf() {
@@ -0,0 +1,2 @@
1
+ import { Message, Task } from "../../../types/index.js";
2
+ export declare function getLatestHistory(task: Task, length?: number): Message[];
@@ -0,0 +1,3 @@
1
+ export function getLatestHistory(task, length) {
2
+ return length ? task.history?.slice(-length) ?? [] : task.history ?? [];
3
+ }
@@ -2,3 +2,5 @@ export * from "./part.js";
2
2
  export * from "./content.js";
3
3
  export * from "./message-builder.js";
4
4
  export * from "./agentcard-builder.js";
5
+ export * from "./history.js";
6
+ export * from "../../../utils/common/schema-validation.js";
@@ -2,3 +2,5 @@ export * from "./part.js";
2
2
  export * from "./content.js";
3
3
  export * from "./message-builder.js";
4
4
  export * from "./agentcard-builder.js";
5
+ export * from "./history.js";
6
+ export * from "../../../utils/common/schema-validation.js";
@@ -3,6 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { TASK_NOT_FOUND } from "../../../utils/index.js";
6
+ import { getLatestHistory } from "../helpers/index.js";
6
7
  export async function getTask(input, params) {
7
8
  const { service } = params;
8
9
  const state = await service.getState(input.id);
@@ -10,5 +11,6 @@ export async function getTask(input, params) {
10
11
  if (!task) {
11
12
  throw TASK_NOT_FOUND({ taskId: input.id });
12
13
  }
14
+ task.history = getLatestHistory(task, input.historyLength);
13
15
  return task;
14
16
  }
@@ -3,6 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { createContext } from "../factory/context.js";
6
+ import { getLatestHistory } from "../helpers/index.js";
6
7
  export async function sendMessage(input, params) {
7
8
  const { service, engine, contextManager, signal } = params;
8
9
  const contextId = input.message.contextId;
@@ -13,7 +14,23 @@ export async function sendMessage(input, params) {
13
14
  context.events.on("error", () => {
14
15
  context.events.onComplete();
15
16
  });
17
+ if (input.configuration?.blocking === false) {
18
+ const result = await Promise.race([
19
+ service.execute(engine, context).then(() => {
20
+ const state = context.events.getState();
21
+ return state.task ?? state;
22
+ }),
23
+ new Promise((resolve) => {
24
+ context.events.on("start", (_, state) => {
25
+ resolve(state.task ?? state);
26
+ });
27
+ }),
28
+ ]);
29
+ return result;
30
+ }
16
31
  await service.execute(engine, context);
17
32
  const state = context.events.getState();
18
- return state.task ?? state;
33
+ const task = state.task ?? state;
34
+ task.history = getLatestHistory(task, input.configuration?.historyLength);
35
+ return task;
19
36
  }
@@ -12,7 +12,8 @@ export declare class A2AService implements A2AServiceInterface {
12
12
  private contexts;
13
13
  private methods;
14
14
  readonly eventOverrides: EventManagerOptions<Command, State, Update> | undefined;
15
- constructor(agentCard: AgentCard, engine: A2AEngine, contexts: ContextManagerInterface<Command, State, Update>, connections: ConnectionManagerInterface, cancellations: CancellationManagerInterface, tasks: TaskManagerInterface<TaskAndHistory>, methods: MethodOptions, eventOverrides?: EventManagerOptions<Command, State, Update>);
15
+ private enforceParamValidation;
16
+ constructor(agentCard: AgentCard, engine: A2AEngine, contexts: ContextManagerInterface<Command, State, Update>, connections: ConnectionManagerInterface, cancellations: CancellationManagerInterface, tasks: TaskManagerInterface<TaskAndHistory>, methods: MethodOptions, eventOverrides?: EventManagerOptions<Command, State, Update>, enforceParamValidation?: boolean);
16
17
  execute(engine: A2AEngine, context: CoreContext<Command, State, Update>): Promise<void>;
17
18
  stop(): Promise<void>;
18
19
  addConnection(id: string): void;
@@ -2,8 +2,10 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
+ import { MessageSendParamsSchema, TaskQueryParamsSchema, TaskIdParamsSchema, } from "../../types/index.js";
5
6
  import { coreExecute } from "../core/execution/execute.js";
6
7
  import { createMessageSendParams } from "./helpers/message-builder.js";
8
+ import { validateSchema } from "../../utils/common/schema-validation.js";
7
9
  export class A2AService {
8
10
  agentCard;
9
11
  engine;
@@ -13,7 +15,8 @@ export class A2AService {
13
15
  contexts;
14
16
  methods;
15
17
  eventOverrides;
16
- constructor(agentCard, engine, contexts, connections, cancellations, tasks, methods, eventOverrides) {
18
+ enforceParamValidation = false;
19
+ constructor(agentCard, engine, contexts, connections, cancellations, tasks, methods, eventOverrides, enforceParamValidation = false) {
17
20
  this.engine = engine;
18
21
  this.agentCard = agentCard;
19
22
  this.contexts = contexts;
@@ -22,6 +25,7 @@ export class A2AService {
22
25
  this.tasks = tasks;
23
26
  this.methods = methods;
24
27
  this.eventOverrides = eventOverrides;
28
+ this.enforceParamValidation = enforceParamValidation;
25
29
  }
26
30
  async execute(engine, context) {
27
31
  await coreExecute(engine ?? this.engine, context);
@@ -55,16 +59,22 @@ export class A2AService {
55
59
  await this.tasks.setState(id, data);
56
60
  }
57
61
  async getTask(input) {
58
- return await this.methods.getTask(input, { service: this });
62
+ return await this.methods.getTask(this.enforceParamValidation
63
+ ? await validateSchema(TaskQueryParamsSchema, input)
64
+ : input, { service: this });
59
65
  }
60
66
  async cancelTask(input) {
61
- return await this.methods.cancelTask(input, {
67
+ return await this.methods.cancelTask(this.enforceParamValidation
68
+ ? await validateSchema(TaskIdParamsSchema, input)
69
+ : input, {
62
70
  service: this,
63
71
  contextManager: this.contexts,
64
72
  });
65
73
  }
66
74
  async sendMessage(message, params) {
67
- return await this.methods.sendMessage(createMessageSendParams(message), {
75
+ return await this.methods.sendMessage(this.enforceParamValidation
76
+ ? await validateSchema(MessageSendParamsSchema, message)
77
+ : createMessageSendParams(message), {
68
78
  ...params, //we may include additional params in the future that may not need to be handled by the service
69
79
  service: this,
70
80
  engine: params?.engine ?? this.engine,
@@ -73,7 +83,9 @@ export class A2AService {
73
83
  });
74
84
  }
75
85
  async *streamMessage(message, params) {
76
- yield* this.methods.streamMessage(createMessageSendParams(message), {
86
+ yield* this.methods.streamMessage(this.enforceParamValidation
87
+ ? await validateSchema(MessageSendParamsSchema, message)
88
+ : createMessageSendParams(message), {
77
89
  ...params,
78
90
  service: this,
79
91
  engine: params?.engine ?? this.engine,
@@ -82,7 +94,9 @@ export class A2AService {
82
94
  });
83
95
  }
84
96
  async *resubscribe(input, params) {
85
- yield* this.methods.resubscribe(input, {
97
+ yield* this.methods.resubscribe(this.enforceParamValidation
98
+ ? await validateSchema(TaskIdParamsSchema, input)
99
+ : input, {
86
100
  ...params,
87
101
  service: this,
88
102
  engine: params?.engine ?? this.engine,
@@ -61,7 +61,6 @@ export class BaseMCPService extends McpServer {
61
61
  this.registerResource("agent-card", uri, {
62
62
  title: "Agent Card",
63
63
  description: AgentCardSchema.description,
64
- outputSchema: AgentCardSchema.shape,
65
64
  mimeType: "application/json",
66
65
  }, async (uri) => {
67
66
  return {
@@ -3,8 +3,8 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { JSONRPCErrorSchema, } from "../../types/index.js";
6
- import { SystemError, PARSE_ERROR } from "../../utils/index.js";
7
- import { logError } from "../../utils/logging/index.js";
6
+ import { SystemError, PARSE_ERROR } from "../../utils/common/errors.js";
7
+ import { logError } from "../../utils/logging/log.js";
8
8
  /**
9
9
  * Parses a JSON-RPC response string and validates its structure.
10
10
  * If the response contains an error, it is thrown as an A2AError.
@@ -7,9 +7,9 @@
7
7
  * Handles the common pattern of sending JSON-RPC requests and processing responses.
8
8
  */
9
9
  import { v4 as uuidv4 } from "uuid";
10
- import { SystemError, INTERNAL_ERROR, PARSE_ERROR } from "../../utils/index.js";
10
+ import { SystemError, INTERNAL_ERROR, PARSE_ERROR, } from "../../utils/common/errors.js";
11
11
  import { parseResponse } from "./parser.js";
12
- import { logError, logWarn } from "../../utils/logging/index.js";
12
+ import { logError, logWarn } from "../../utils/logging/log.js";
13
13
  /**
14
14
  * Creates a JSON-RPC request body with the specified method and parameters.
15
15
  *, ErrorCodeParseError
@@ -67,6 +67,8 @@ export interface FactoryParams {
67
67
  methods?: Partial<MethodOptions>;
68
68
  /** Optional event manager configuration overrides */
69
69
  events?: EventManagerOptions<Command, State, Update>;
70
+ /** Enforce parameter validation */
71
+ enforceParamValidation?: boolean;
70
72
  }
71
73
  /**
72
74
  * Parameters passed to A2A method implementations.
@@ -109,6 +111,8 @@ export interface MethodParams {
109
111
  contextManager: ContextManagerInterface<Command, State, Update>;
110
112
  /** Abort signal for cancellation handling */
111
113
  signal: AbortSignal;
114
+ /** Enforce input validation */
115
+ enforceValidation?: boolean;
112
116
  }
113
117
  /**
114
118
  * Custom method implementation options for A2A services.
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { TaskState } from "../../types/index.js";
6
- import { getCurrentTimestamp } from "../index.js";
6
+ import { getCurrentTimestamp } from "./utils.js";
7
7
  //todo: protocol specific so move to a2a folder
8
8
  export const STATUS_UPDATE = (taskId, contextId, status, message, timestamp = getCurrentTimestamp(), final = false) => {
9
9
  return {
@@ -2,7 +2,7 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { A2AError, InvalidParamsError, InvalidRequestError, JSONRPCError, MethodNotFoundError, InternalError, TaskNotFoundError, TaskNotCancelableError, ContentTypeNotSupportedError, InvalidAgentResponseError, TaskStatusUpdateEvent, JSONParseError } from "../../types/index.js";
5
+ import { A2AError, InvalidParamsError, InvalidRequestError, JSONRPCError, MethodNotFoundError, InternalError, TaskNotFoundError, TaskNotCancelableError, ContentTypeNotSupportedError, InvalidAgentResponseError, TaskStatusUpdateEvent, JSONParseError, AuthenticatedExtendedCardNotConfiguredError } from "../../types/index.js";
6
6
  export declare class SystemError<T extends JSONRPCError> extends Error {
7
7
  message: string;
8
8
  code: T["code"];
@@ -17,6 +17,7 @@ export declare const INTERNAL_ERROR: <T extends InternalError>(data: T["data"])
17
17
  export declare const TASK_NOT_FOUND: <T extends TaskNotFoundError>(data: T["data"]) => SystemError<T>;
18
18
  export declare const TASK_NOT_CANCELABLE: <T extends TaskNotCancelableError>(data: T["data"]) => SystemError<T>;
19
19
  export declare const PUSH_NOTIFICATION_NOT_SUPPORTED: <T extends A2AError>(data: T["data"]) => SystemError<T>;
20
+ export declare const AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED: <T extends AuthenticatedExtendedCardNotConfiguredError>(data: T["data"]) => SystemError<T>;
20
21
  export declare const UNSUPPORTED_OPERATION: <T extends A2AError>(data: T["data"]) => SystemError<T>;
21
22
  export declare const CONTENT_TYPE_NOT_SUPPORTED: <T extends ContentTypeNotSupportedError>(data: T["data"]) => SystemError<T>;
22
23
  export declare const INVALID_AGENT_RESPONSE: <T extends InvalidAgentResponseError>(data: T["data"]) => SystemError<T>;
@@ -2,7 +2,7 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { ErrorCodeInternalError, ErrorCodeInvalidRequest, ErrorCodeMethodNotFound, ErrorCodeParseError, ErrorCodeInvalidParams, ErrorCodeTaskNotFound, ErrorCodeTaskNotCancelable, ErrorCodeUnsupportedOperation, ErrorCodePushNotificationNotSupported, ErrorCodeContentTypeNotSupported, ErrorCodeInvalidAgentResponse, TaskState, } from "../../types/index.js";
5
+ import { ErrorCodeInternalError, ErrorCodeInvalidRequest, ErrorCodeMethodNotFound, ErrorCodeParseError, ErrorCodeInvalidParams, ErrorCodeTaskNotFound, ErrorCodeTaskNotCancelable, ErrorCodeUnsupportedOperation, ErrorCodePushNotificationNotSupported, ErrorCodeContentTypeNotSupported, ErrorCodeInvalidAgentResponse, TaskState, ErrorCodeAuthenticatedExtendedCardNotConfigured, } from "../../types/index.js";
6
6
  export class SystemError extends Error {
7
7
  message;
8
8
  code;
@@ -24,6 +24,7 @@ export const INTERNAL_ERROR = (data) => new SystemError("Internal error", ErrorC
24
24
  export const TASK_NOT_FOUND = (data) => new SystemError("Task not found", ErrorCodeTaskNotFound, data);
25
25
  export const TASK_NOT_CANCELABLE = (data) => new SystemError("Task cannot be canceled", ErrorCodeTaskNotCancelable, data);
26
26
  export const PUSH_NOTIFICATION_NOT_SUPPORTED = (data) => new SystemError("Push Notifications is not supported", ErrorCodePushNotificationNotSupported, data);
27
+ export const AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED = (data) => new SystemError("Authenticated Extended Card is not configured", ErrorCodeAuthenticatedExtendedCardNotConfigured, data);
27
28
  export const UNSUPPORTED_OPERATION = (data) => new SystemError("This operation is not supported", ErrorCodeUnsupportedOperation, data);
28
29
  export const CONTENT_TYPE_NOT_SUPPORTED = (data) => new SystemError("Content type not supported", ErrorCodeContentTypeNotSupported, data);
29
30
  export const INVALID_AGENT_RESPONSE = (data) => new SystemError("Invalid agent response", ErrorCodeInvalidAgentResponse, data);
@@ -0,0 +1,2 @@
1
+ import { z } from "zod/v3";
2
+ export declare function validateSchema<T extends z.ZodSchema>(schema: T, data: unknown): Promise<z.infer<T>>;
@@ -0,0 +1,12 @@
1
+ import { INVALID_PARAMS } from "../index.js";
2
+ import { logError } from "../logging/index.js";
3
+ export async function validateSchema(schema, data) {
4
+ return await schema.parseAsync(data).catch((error) => {
5
+ logError("Schema validation failed", error.message, error);
6
+ throw INVALID_PARAMS({
7
+ data: {
8
+ message: error.message,
9
+ },
10
+ });
11
+ });
12
+ }
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export * from "./common/constants.js";
6
6
  export * from "./common/errors.js";
7
+ export * from "./common/schema-validation.js";
7
8
  export * from "./common/utils.js";
8
9
  export * from "./common/zAsyncIterable-v3.js";
9
10
  export * from "./logging/index.js";
@@ -4,6 +4,7 @@
4
4
  */
5
5
  export * from "./common/constants.js";
6
6
  export * from "./common/errors.js";
7
+ export * from "./common/schema-validation.js";
7
8
  export * from "./common/utils.js";
8
9
  export * from "./common/zAsyncIterable-v3.js";
9
10
  export * from "./logging/index.js";