@artinet/sdk 0.6.0-preview.1 → 0.6.0-preview.2

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 (113) hide show
  1. package/README.md +1 -1
  2. package/dist/browser/client/a2a-client.js +4 -4
  3. package/dist/browser/config/index.d.ts +1 -1
  4. package/dist/browser/config/index.js +1 -1
  5. package/dist/browser/create/agentcard-builder.d.ts +47 -0
  6. package/dist/browser/create/agentcard-builder.js +65 -0
  7. package/dist/browser/create/base.d.ts +4 -0
  8. package/dist/browser/create/base.js +1 -0
  9. package/dist/browser/create/describe.d.ts +8 -0
  10. package/dist/browser/create/describe.js +8 -0
  11. package/dist/browser/create/message-builder.d.ts +78 -0
  12. package/dist/browser/create/message-builder.js +108 -0
  13. package/dist/browser/create/part-builder.d.ts +60 -0
  14. package/dist/browser/create/part-builder.js +81 -0
  15. package/dist/browser/create/task-builder.d.ts +251 -0
  16. package/dist/browser/create/task-builder.js +379 -0
  17. package/dist/browser/transport/rpc/parser.d.ts +1 -1
  18. package/dist/browser/transport/rpc/parser.js +2 -1
  19. package/dist/browser/types/a2a/a2a.d.ts +7 -3
  20. package/dist/browser/types/a2a/index.d.ts +3 -1
  21. package/dist/browser/types/a2a/index.js +0 -1
  22. package/dist/browser/utils/common/constants.d.ts +0 -5
  23. package/dist/browser/utils/common/constants.js +0 -27
  24. package/dist/browser/utils/common/errors.d.ts +57 -1
  25. package/dist/browser/utils/common/errors.js +68 -15
  26. package/dist/client/a2a-client.js +4 -4
  27. package/dist/config/default.d.ts +1 -1
  28. package/dist/config/default.js +1 -1
  29. package/dist/config/index.d.ts +1 -1
  30. package/dist/config/index.js +1 -1
  31. package/dist/create/agent-builder.d.ts +77 -0
  32. package/dist/create/agent-builder.js +20 -0
  33. package/dist/create/agentcard-builder.d.ts +47 -0
  34. package/dist/create/agentcard-builder.js +66 -0
  35. package/dist/create/base.d.ts +4 -0
  36. package/dist/create/base.js +1 -0
  37. package/dist/create/create.d.ts +762 -0
  38. package/dist/create/create.js +556 -0
  39. package/dist/create/describe.d.ts +8 -0
  40. package/dist/create/describe.js +8 -0
  41. package/dist/create/index.d.ts +4 -0
  42. package/dist/create/index.js +4 -0
  43. package/dist/create/message-builder.d.ts +78 -0
  44. package/dist/create/message-builder.js +110 -0
  45. package/dist/create/part-builder.d.ts +60 -0
  46. package/dist/create/part-builder.js +84 -0
  47. package/dist/create/status-builder.d.ts +26 -0
  48. package/dist/create/status-builder.js +46 -0
  49. package/dist/create/task-builder.d.ts +251 -0
  50. package/dist/create/task-builder.js +384 -0
  51. package/dist/create/transform.d.ts +16 -0
  52. package/dist/create/transform.js +106 -0
  53. package/dist/index.d.ts +2 -0
  54. package/dist/index.js +2 -0
  55. package/dist/server/express/errors.js +4 -8
  56. package/dist/server/express/middeware.js +17 -38
  57. package/dist/server/express/server.d.ts +6 -1
  58. package/dist/server/express/server.js +30 -12
  59. package/dist/services/a2a/execute.d.ts +5 -0
  60. package/dist/services/a2a/execute.js +7 -0
  61. package/dist/services/a2a/factory/context.d.ts +1 -1
  62. package/dist/services/a2a/factory/context.js +2 -3
  63. package/dist/services/a2a/factory/handler.js +3 -3
  64. package/dist/services/a2a/factory/index.d.ts +0 -1
  65. package/dist/services/a2a/factory/index.js +0 -1
  66. package/dist/services/a2a/factory/service.d.ts +2 -2
  67. package/dist/services/a2a/factory/service.js +2 -2
  68. package/dist/services/a2a/factory/state-machine.d.ts +1 -1
  69. package/dist/services/a2a/factory/state-machine.js +30 -8
  70. package/dist/services/a2a/handlers/artifact.d.ts +2 -5
  71. package/dist/services/a2a/handlers/artifact.js +21 -32
  72. package/dist/services/a2a/handlers/cancel-task.js +7 -5
  73. package/dist/services/a2a/handlers/resubscribe-task.d.ts +10 -2
  74. package/dist/services/a2a/handlers/resubscribe-task.js +21 -18
  75. package/dist/services/a2a/handlers/send-message.js +6 -10
  76. package/dist/services/a2a/handlers/stream-message.d.ts +10 -2
  77. package/dist/services/a2a/handlers/stream-message.js +5 -1
  78. package/dist/services/a2a/handlers/update.js +11 -6
  79. package/dist/services/a2a/helpers/content.d.ts +5 -1
  80. package/dist/services/a2a/helpers/content.js +5 -1
  81. package/dist/services/a2a/helpers/index.d.ts +2 -2
  82. package/dist/services/a2a/helpers/index.js +2 -2
  83. package/dist/services/a2a/index.d.ts +1 -1
  84. package/dist/services/a2a/index.js +1 -1
  85. package/dist/services/a2a/managers.js +7 -1
  86. package/dist/services/a2a/service.d.ts +6 -2
  87. package/dist/services/a2a/service.js +52 -59
  88. package/dist/services/a2a/state-machine.d.ts +3 -3
  89. package/dist/services/a2a/state-machine.js +2 -0
  90. package/dist/transport/rpc/parser.d.ts +1 -1
  91. package/dist/transport/rpc/parser.js +2 -1
  92. package/dist/types/a2a/a2a.d.ts +7 -3
  93. package/dist/types/a2a/index.d.ts +3 -1
  94. package/dist/types/a2a/index.js +0 -1
  95. package/dist/utils/common/constants.d.ts +0 -5
  96. package/dist/utils/common/constants.js +0 -27
  97. package/dist/utils/common/errors.d.ts +57 -1
  98. package/dist/utils/common/errors.js +68 -15
  99. package/dist/utils/common/parse.d.ts +1 -1
  100. package/dist/utils/common/schema-validation.d.ts +1 -1
  101. package/package.json +7 -4
  102. package/dist/browser/services/a2a/helpers/message-builder.d.ts +0 -17
  103. package/dist/browser/services/a2a/helpers/message-builder.js +0 -66
  104. package/dist/browser/types/a2a/builder.d.ts +0 -43
  105. package/dist/browser/types/a2a/builder.js +0 -5
  106. package/dist/services/a2a/factory/builder.d.ts +0 -292
  107. package/dist/services/a2a/factory/builder.js +0 -370
  108. package/dist/services/a2a/helpers/agentcard-builder.d.ts +0 -11
  109. package/dist/services/a2a/helpers/agentcard-builder.js +0 -27
  110. package/dist/services/a2a/helpers/message-builder.d.ts +0 -17
  111. package/dist/services/a2a/helpers/message-builder.js +0 -66
  112. package/dist/types/a2a/builder.d.ts +0 -43
  113. package/dist/types/a2a/builder.js +0 -5
@@ -3,26 +3,24 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import express from "express";
6
- import { INVALID_REQUEST, PARSE_ERROR } from "../../utils/index.js";
7
6
  import { createAgent, Service, } from "../../services/index.js";
8
7
  import cors from "cors";
9
8
  import { jsonRPCMiddleware } from "./middeware.js";
10
9
  import { errorHandler } from "./errors.js";
10
+ import { logger } from "../../config/index.js";
11
+ import { A2AError } from "@a2a-js/sdk/server";
12
+ import { formatJson } from "../../utils/common/utils.js";
11
13
  export function rpcParser(req, res, next) {
12
14
  express.json()(req, res, (err) => {
13
15
  if (!req.body || typeof req.body !== "object") {
14
- return next(PARSE_ERROR({
15
- data: { message: "Invalid request body" },
16
- }));
16
+ return next(A2AError.parseError(`Invalid request body: ${formatJson(req.body)}`));
17
17
  }
18
18
  if (err) {
19
19
  if (err instanceof SyntaxError &&
20
20
  "status" in err &&
21
21
  err.status === 400 &&
22
22
  "body" in err) {
23
- return next(PARSE_ERROR({
24
- data: err.message,
25
- }));
23
+ return next(A2AError.parseError(`Invalid request body: ${formatJson(req.body)}`));
26
24
  }
27
25
  return next(err);
28
26
  }
@@ -46,7 +44,11 @@ const ensureAgent = (agentOrParams) => {
46
44
  }
47
45
  throw new Error("invalid agent or params");
48
46
  };
49
- export function createAgentServer({ app = express(), basePath = "/", agentCardPath = "/.well-known/agent-card.json", agent, corsOptions, extendedAgentCard, }) {
47
+ const registerAgent = async (agentCard) => {
48
+ logger.debug("registerAgent: not implemented", { agentCard });
49
+ return Promise.resolve(agentCard);
50
+ };
51
+ export function createAgentServer({ app = express(), basePath = "/", agentCardPath = "/.well-known/agent-card.json", agent, corsOptions, extendedAgentCard, register = false, port, }) {
50
52
  const agentInstance = ensureAgent(agent);
51
53
  app.use(cors(corsOptions));
52
54
  if (agentCardPath !== "/.well-known/agent-card.json") {
@@ -72,10 +74,10 @@ export function createAgentServer({ app = express(), basePath = "/", agentCardPa
72
74
  //a standard express middleware to handle json-rpc requests
73
75
  app.post(basePath, rpcParser, async (req, res, next) => {
74
76
  const { jsonrpc } = req.body;
75
- if (jsonrpc === "2.0") {
76
- return await jsonRPCMiddleware(agentInstance, req, res, next, extendedAgentCard);
77
+ if (jsonrpc !== "2.0") {
78
+ return next(A2AError.invalidRequest("Invalid JSON-RPC request"));
77
79
  }
78
- next(INVALID_REQUEST({ data: { message: "Invalid JSON-RPC request" } }));
80
+ return await jsonRPCMiddleware(agentInstance, req, res, next, extendedAgentCard);
79
81
  });
80
82
  app.use(errorHandler);
81
83
  /** this is an example of using trpc as express middleware
@@ -94,5 +96,21 @@ export function createAgentServer({ app = express(), basePath = "/", agentCardPa
94
96
  );
95
97
  * we could also use trpc directly or any other transport layer
96
98
  */
97
- return { app, agent: agentInstance };
99
+ const start = (_port) => {
100
+ try {
101
+ const listenPort = _port ?? port;
102
+ const server = app.listen(listenPort, () => {
103
+ logger.info(`Agent server started on port ${listenPort}`);
104
+ });
105
+ if (register) {
106
+ registerAgent(agentInstance.agentCard);
107
+ }
108
+ return server;
109
+ }
110
+ catch (error) {
111
+ logger.error(`Failed to start agent server`, error);
112
+ throw error;
113
+ }
114
+ };
115
+ return { app, agent: agentInstance, start };
98
116
  }
@@ -3,4 +3,9 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { A2A } from "../../types/index.js";
6
+ /**
7
+ * Our universal executor for {@link A2A.Engine}.
8
+ * @param engine - {@link A2A.Engine} to execute.
9
+ * @param context - {@link A2A.Context} provided to the engine.
10
+ */
6
11
  export declare const execute: (engine: A2A.Engine, context: A2A.Context) => Promise<void>;
@@ -2,6 +2,11 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
+ /**
6
+ * Our universal executor for {@link A2A.Engine}.
7
+ * @param engine - {@link A2A.Engine} to execute.
8
+ * @param context - {@link A2A.Context} provided to the engine.
9
+ */
5
10
  export const execute = async (engine, context) => {
6
11
  try {
7
12
  if (context.publisher.onStart) {
@@ -16,7 +21,9 @@ export const execute = async (engine, context) => {
16
21
  }
17
22
  }
18
23
  catch (error) {
24
+ /* onError triggers completion internally */
19
25
  await context.publisher.onError(error);
26
+ /* rethrow the error to be handled by the caller */
20
27
  throw error;
21
28
  }
22
29
  finally {
@@ -6,7 +6,7 @@ import { A2A } from "../../../types/index.js";
6
6
  export declare function createBaseContext({ contextId, service, task, overrides, abortSignal, }: {
7
7
  contextId: string;
8
8
  service: A2A.Service;
9
- task?: A2A.Task;
9
+ task: A2A.Task;
10
10
  overrides?: Partial<Omit<A2A.EventConsumer, "contextId">>;
11
11
  abortSignal?: AbortSignal;
12
12
  }): A2A.BaseContext;
@@ -17,8 +17,7 @@
17
17
  import { createStateMachine } from "./state-machine.js";
18
18
  import { v4 as uuidv4 } from "uuid";
19
19
  export function createBaseContext({ contextId = uuidv4(), service, task, overrides, abortSignal = new AbortController().signal, }) {
20
- const isCancelled = async () => (await service.cancellations.has(task?.id ?? contextId)) ||
21
- abortSignal.aborted;
20
+ const isCancelled = async () => (await service.cancellations.has(task.id)) || abortSignal.aborted;
22
21
  const getState = async (args) => args ? await service.tasks.get(args) : task;
23
22
  const context = {
24
23
  contextId: contextId,
@@ -34,7 +33,7 @@ export function createContext({ baseContext, taskId, messenger, extensions, refe
34
33
  const getTask = async () => baseContext.publisher.currentTask;
35
34
  const context = {
36
35
  ...baseContext,
37
- taskId: baseContext.publisher.currentTask.id ?? taskId,
36
+ taskId,
38
37
  userMessage: messenger.message,
39
38
  messages: messenger,
40
39
  getTask,
@@ -2,13 +2,13 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { getTask, cancelTask, sendMessage, streamMessage, resubscribe, } from "../handlers/index.js";
5
+ import { getTask, cancelTask, sendMessage, sendMessageStream, subscribeToTask, } from "../handlers/index.js";
6
6
  export function createHandler(methods) {
7
7
  return {
8
8
  getTask: methods?.getTask ?? getTask,
9
9
  cancelTask: methods?.cancelTask ?? cancelTask,
10
10
  sendMessage: methods?.sendMessage ?? sendMessage,
11
- streamMessage: methods?.streamMessage ?? streamMessage,
12
- resubscribe: methods?.resubscribe ?? resubscribe,
11
+ streamMessage: methods?.streamMessage ?? sendMessageStream,
12
+ resubscribe: methods?.resubscribe ?? subscribeToTask,
13
13
  };
14
14
  }
@@ -1,4 +1,3 @@
1
1
  export * from "./context.js";
2
- export * from "./builder.js";
3
2
  export * from "./state-machine.js";
4
3
  export * from "./service.js";
@@ -1,4 +1,3 @@
1
1
  export * from "./context.js";
2
- export * from "./builder.js";
3
2
  export * from "./state-machine.js";
4
3
  export * from "./service.js";
@@ -1,8 +1,8 @@
1
+ import * as describe from "../../../create/agentcard-builder.js";
1
2
  import { A2A } from "../../../types/index.js";
2
3
  import { Service } from "../service.js";
3
- export type AgentCardParams = (Partial<A2A.AgentCard> & Required<Pick<A2A.AgentCard, "name">>) | string;
4
4
  export interface ServiceParams {
5
- agentCard: AgentCardParams;
5
+ agentCard: describe.AgentCardParams;
6
6
  engine: A2A.Engine;
7
7
  contexts?: A2A.Contexts;
8
8
  streams?: A2A.Streams;
@@ -3,10 +3,10 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { createHandler } from "./handler.js";
6
- import { createAgentCard } from "../helpers/agentcard-builder.js";
6
+ import * as describe from "../../../create/agentcard-builder.js";
7
7
  import { Service } from "../service.js";
8
8
  import { Contexts, Streams, Connections, Cancellations, Tasks, } from "../managers.js";
9
9
  export function createService(params) {
10
- return new Service(createAgentCard(params.agentCard), params.engine, params.connections ?? new Connections(), params.cancellations ?? new Cancellations(), params.tasks ?? new Tasks(), params.contexts ?? new Contexts(), params.streams ?? new Streams(), createHandler(params.methods), params.overrides);
10
+ return new Service(describe.card(params.agentCard), params.engine, params.connections ?? new Connections(), params.cancellations ?? new Cancellations(), params.tasks ?? new Tasks(), params.contexts ?? new Contexts(), params.streams ?? new Streams(), createHandler(params.methods), params.overrides);
11
11
  }
12
12
  export const createAgent = createService;
@@ -6,6 +6,6 @@ import { A2A } from "../../../types/index.js";
6
6
  export declare function createStateMachine({ contextId, service, task: currentTask, overrides, }: {
7
7
  contextId: string;
8
8
  service: A2A.Service;
9
- task?: A2A.Task;
9
+ task: A2A.Task;
10
10
  overrides?: Partial<Omit<A2A.EventConsumer, "contextId">>;
11
11
  }): A2A.EventPublisher;
@@ -4,7 +4,8 @@
4
4
  */
5
5
  import { StateMachine } from "../state-machine.js";
6
6
  import { logger } from "../../../config/index.js";
7
- import { TASK_NOT_FOUND, CANCEL_UPDATE, FAILED_UPDATE } from "../../../utils/index.js";
7
+ import * as describe from "../../../create/describe.js";
8
+ import { TASK_NOT_FOUND } from "../../../utils/index.js";
8
9
  import assert from "assert";
9
10
  export function createStateMachine({ contextId, service, task: currentTask, overrides, }) {
10
11
  const handler = {
@@ -25,7 +26,11 @@ export function createStateMachine({ contextId, service, task: currentTask, over
25
26
  logger.info(`onCancel[ctx:${contextId}]:`, "cancellation triggered");
26
27
  logger.debug(`onCancel[ctx:${contextId}]:`, "arguments", update, task);
27
28
  await service.cancellations.set(task.id);
28
- const cancellation = CANCEL_UPDATE(task.id, task.contextId, update.status?.message);
29
+ const cancellation = describe.update.canceled({
30
+ taskId: task.id,
31
+ contextId: task.contextId,
32
+ message: update.status?.message,
33
+ });
29
34
  await service.tasks.update((await service.contexts.get(contextId)), cancellation);
30
35
  },
31
36
  onUpdate: async (update, task) => {
@@ -43,17 +48,34 @@ export function createStateMachine({ contextId, service, task: currentTask, over
43
48
  logger.error(`onError[ctx:${contextId}]:`, new Error("task not found"));
44
49
  return;
45
50
  }
46
- const errorUpdate = FAILED_UPDATE(task.id, contextId, undefined, error instanceof Error ? error.message : String(error));
47
- await service.tasks
48
- .update((await service.contexts.get(contextId)), errorUpdate)
49
- .catch((error) => {
51
+ const errorUpdate = describe.update.failed({
52
+ taskId: task.id,
53
+ contextId,
54
+ message: describe.message({
55
+ messageId: "failed-update",
56
+ parts: [
57
+ {
58
+ kind: "text",
59
+ text: error instanceof Error ? error.message : String(error),
60
+ },
61
+ ],
62
+ }),
63
+ });
64
+ const context = await service.contexts.get(contextId);
65
+ if (!context) {
66
+ logger.error(`onError[ctx:${contextId}]:`, new Error("context not found"));
67
+ return;
68
+ }
69
+ await service.tasks.update(context, errorUpdate).catch((error) => {
50
70
  //we capture errors thrown during error handling to ensure we trigger completion gracefully
51
- logger.error(`onError[ctx:${contextId}]:`, error);
71
+ logger.error(`onError: task update error[ctx:${contextId}]:`, error);
52
72
  });
73
+ // we trigger completion here to ensure the context is cleaned up
74
+ await context.publisher.onComplete();
53
75
  },
54
76
  onComplete: async (task) => {
55
77
  assert(task.contextId === contextId, "context mismatch");
56
- logger.info(`onComplete[ctx:${contextId}]:`, { taskId: task.id });
78
+ logger.info(`onComplete[ctx:${contextId}]: `, { taskId: task.id });
57
79
  await service.cancellations.delete(task.id);
58
80
  await service.connections.delete(task.contextId);
59
81
  await service.contexts.delete(task.contextId);
@@ -3,8 +3,5 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { A2A } from "../../../types/index.js";
6
- export declare function updateByIndex(append: boolean, artifacts: A2A.Artifact[], index: number, artifactUpdate: A2A.Artifact): {
7
- artifacts: A2A.Artifact[];
8
- replaced: boolean;
9
- };
10
- export declare function processArtifactUpdate(append: boolean, artifacts: A2A.Artifact[], artifactUpdate: A2A.Artifact): A2A.Artifact[];
6
+ export declare function updateArtifact(_artifact: A2A.Artifact, update: A2A.TaskArtifactUpdateEvent): A2A.Artifact;
7
+ export declare function upsertArtifact(artifacts: A2A.Artifact[], update: A2A.TaskArtifactUpdateEvent): A2A.Artifact[];
@@ -2,38 +2,27 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- export function updateByIndex(append, artifacts, index, artifactUpdate) {
6
- if (append) {
7
- const existingArtifact = artifacts[index];
8
- existingArtifact.parts.push(...artifactUpdate.parts);
9
- if (artifactUpdate.metadata) {
10
- existingArtifact.metadata = {
11
- ...(existingArtifact.metadata || {}),
12
- ...artifactUpdate.metadata,
13
- };
14
- }
15
- if (artifactUpdate.description) {
16
- existingArtifact.description = artifactUpdate.description;
17
- }
18
- if (artifactUpdate.name) {
19
- existingArtifact.name = artifactUpdate.name;
20
- }
21
- artifacts[index] = existingArtifact;
22
- }
23
- else {
24
- artifacts[index] = { ...artifactUpdate };
25
- }
26
- return { artifacts, replaced: true };
5
+ export function updateArtifact(_artifact, update) {
6
+ if (!update.append)
7
+ return update.artifact;
8
+ const artifactUpdate = update.artifact;
9
+ const artifact = _artifact;
10
+ artifact.metadata = {
11
+ ...(artifact.metadata || {}),
12
+ ...artifactUpdate.metadata,
13
+ };
14
+ artifact.description = artifactUpdate.description;
15
+ artifact.name = artifactUpdate.name;
16
+ artifact.parts.push(...artifactUpdate.parts);
17
+ return artifact;
27
18
  }
28
- export function processArtifactUpdate(append, artifacts, artifactUpdate) {
29
- const existingIndex = artifacts.findIndex((a) => a.artifactId === artifactUpdate.artifactId);
30
- let replaced = false;
31
- let newArtifacts = artifacts;
32
- if (existingIndex !== -1) {
33
- ({ artifacts: newArtifacts, replaced } = updateByIndex(append, artifacts, existingIndex, artifactUpdate));
34
- }
35
- if (!replaced) {
36
- newArtifacts.push({ ...artifactUpdate });
19
+ export function upsertArtifact(artifacts, update) {
20
+ const updateId = update.artifact.artifactId;
21
+ const index = artifacts.findIndex((a) => a.artifactId === updateId);
22
+ if (index === -1) {
23
+ artifacts.push({ ...update.artifact });
24
+ return artifacts;
37
25
  }
38
- return newArtifacts;
26
+ artifacts[index] = updateArtifact(artifacts[index], update);
27
+ return artifacts;
39
28
  }
@@ -16,7 +16,13 @@ export const cancelTask = async ({ id: taskId }, context) => {
16
16
  if (FINAL_STATES.includes(task.status.state)) {
17
17
  throw TASK_NOT_CANCELABLE("Task is in a final state: " + task.status.state);
18
18
  }
19
- service.cancellations.set(taskId);
19
+ /**
20
+ * By triggering onCancel, we're guaranteed that:
21
+ * - No further updates will be processed other than errors
22
+ * - The task will be cancelled
23
+ * - The task will be completed
24
+ * - The cancellations will be cleaned up
25
+ */
20
26
  const cancelledTask = {
21
27
  ...task,
22
28
  status: {
@@ -24,10 +30,6 @@ export const cancelTask = async ({ id: taskId }, context) => {
24
30
  state: A2A.TaskState.canceled,
25
31
  },
26
32
  };
27
- context.publisher?.on("complete", async () => {
28
- await service.cancellations.delete(taskId);
29
- await service.contexts.delete(context.contextId);
30
- });
31
33
  await context.publisher.onCancel(cancelledTask);
32
34
  return cancelledTask;
33
35
  };
@@ -3,9 +3,17 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { A2A } from "../../../types/index.js";
6
- export declare const resubscribe: A2A.RequestHandler["resubscribe"];
6
+ export declare const subscribeToTask: A2A.RequestHandler["resubscribe"];
7
+ export type SubscribeToTaskHandler = typeof subscribeToTask;
8
+ /**
9
+ * @deprecated Use SubscribeToTaskHandler instead
10
+ */
11
+ export declare const resubscribe: (input: A2A.TaskIdParams, context?: A2A.Context, options?: A2A.ServiceOptions) => AsyncGenerator<A2A.Update>;
12
+ /**
13
+ * @deprecated Use SubscribeToTaskHandler instead
14
+ */
7
15
  export type TaskResubscribeHandler = typeof resubscribe;
8
16
  /**
9
- * @deprecated Use ResubscribeTaskHandler instead
17
+ * @deprecated Use SubscribeToTaskHandler instead
10
18
  */
11
19
  export type ResubscribeTaskMethod = TaskResubscribeHandler;
@@ -5,22 +5,22 @@
5
5
  import { A2A } from "../../../types/index.js";
6
6
  import { FINAL_STATES, INTERNAL_ERROR, TASK_NOT_FOUND } from "../../../utils/index.js";
7
7
  const flush = (task, stream) => {
8
- if (task.artifacts && task.artifacts.length > 0) {
9
- for (const artifact of task.artifacts) {
10
- const artifactUpdate = {
11
- kind: A2A.Kind["artifact-update"],
12
- taskId: task.id,
13
- contextId: task.contextId,
14
- artifact,
15
- lastChunk: task.artifacts.length === 1,
16
- metadata: task.metadata,
17
- };
18
- stream.updates.push(artifactUpdate);
19
- task.artifacts.shift();
20
- }
8
+ if (!task.artifacts || task.artifacts.length === 0)
9
+ return;
10
+ for (const artifact of task.artifacts) {
11
+ const artifactUpdate = {
12
+ kind: A2A.Kind["artifact-update"],
13
+ taskId: task.id,
14
+ contextId: task.contextId,
15
+ artifact,
16
+ lastChunk: task.artifacts.length === 1,
17
+ metadata: task.metadata,
18
+ };
19
+ stream.updates.push(artifactUpdate);
20
+ task.artifacts.shift();
21
21
  }
22
22
  };
23
- export const resubscribe = async function* ({ id: taskId }, context) {
23
+ export const subscribeToTask = async function* ({ id: taskId }, context) {
24
24
  if (!context) {
25
25
  throw INTERNAL_ERROR({ error: { message: "Context is required" } });
26
26
  }
@@ -33,9 +33,7 @@ export const resubscribe = async function* ({ id: taskId }, context) {
33
33
  contextId: context.contextId,
34
34
  context,
35
35
  }));
36
- // since we already checked if the task exists
37
- // then we dont care about the upsert in onStart
38
- // so we can just push the update and continue
36
+ // onStart no longer inserts a new task, so we can safely push the update and continue
39
37
  context.publisher.on("start", async (_, task) => {
40
38
  stream.updates.push({
41
39
  kind: "status-update",
@@ -46,7 +44,8 @@ export const resubscribe = async function* ({ id: taskId }, context) {
46
44
  metadata: task.metadata,
47
45
  });
48
46
  if (FINAL_STATES.includes(task.status.state)) {
49
- flush(task, stream);
47
+ /* We create a new task object to avoid mutating the original task */
48
+ flush({ ...task }, stream);
50
49
  await stream.kill();
51
50
  }
52
51
  });
@@ -54,3 +53,7 @@ export const resubscribe = async function* ({ id: taskId }, context) {
54
53
  service: service,
55
54
  });
56
55
  };
56
+ /**
57
+ * @deprecated Use SubscribeToTaskHandler instead
58
+ */
59
+ export const resubscribe = subscribeToTask;
@@ -8,15 +8,10 @@ export const sendMessage = async ({ configuration }, context) => {
8
8
  if (!context) {
9
9
  throw INTERNAL_ERROR({ error: { message: "Context is required" } });
10
10
  }
11
- context.publisher.on("complete", () => {
12
- context.service.contexts.delete(context.contextId);
13
- });
14
- context.publisher.on("error", () => {
15
- context.publisher.onComplete();
16
- });
17
11
  const service = context.service;
12
+ let task;
18
13
  if (configuration?.blocking === false) {
19
- const result = await Promise.race([
14
+ task = await Promise.race([
20
15
  service.execute({ engine: service.engine, context }).then(async () => {
21
16
  return await context.getTask();
22
17
  }),
@@ -26,10 +21,11 @@ export const sendMessage = async ({ configuration }, context) => {
26
21
  });
27
22
  }),
28
23
  ]);
29
- return result;
30
24
  }
31
- await service.execute({ engine: service.engine, context });
32
- const task = await context.getTask();
25
+ else {
26
+ await service.execute({ engine: service.engine, context });
27
+ task = await context.getTask();
28
+ }
33
29
  task.history = getLatestHistory(task, configuration?.historyLength);
34
30
  return task;
35
31
  };
@@ -3,8 +3,16 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { A2A } from "../../../types/index.js";
6
- export declare const streamMessage: A2A.RequestHandler["streamMessage"];
7
- export type StreamMessageHandler = typeof streamMessage;
6
+ export declare const sendMessageStream: A2A.RequestHandler["streamMessage"];
7
+ export type SendMessageStreamHandler = typeof sendMessageStream;
8
+ /**
9
+ * @deprecated Use sendMessageStream instead
10
+ */
11
+ export declare const streamMessage: (message: A2A.MessageSendParams, context?: A2A.Context, options?: A2A.ServiceOptions) => AsyncGenerator<A2A.Update>;
12
+ /**
13
+ * @deprecated Use SendMessageStreamHandler instead
14
+ */
15
+ export type StreamMessageHandler = SendMessageStreamHandler;
8
16
  /**
9
17
  * @deprecated Use StreamMessageHandler instead
10
18
  */
@@ -3,7 +3,7 @@
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
5
  import { INTERNAL_ERROR } from "../../../utils/index.js";
6
- export const streamMessage = async function* (_, context) {
6
+ export const sendMessageStream = async function* (_, context) {
7
7
  if (!context) {
8
8
  throw INTERNAL_ERROR({ error: { message: "Context is required" } });
9
9
  }
@@ -17,3 +17,7 @@ export const streamMessage = async function* (_, context) {
17
17
  });
18
18
  yield* stream.run({ service });
19
19
  };
20
+ /**
21
+ * @deprecated Use sendMessageStream instead
22
+ */
23
+ export const streamMessage = sendMessageStream;
@@ -2,8 +2,9 @@
2
2
  * Copyright 2025 The Artinet Project
3
3
  * SPDX-License-Identifier: Apache-2.0
4
4
  */
5
- import { getCurrentTimestamp, validateSchema } from "../../../utils/index.js";
6
- import { processArtifactUpdate } from "./artifact.js";
5
+ import { getCurrentTimestamp, formatJson } from "../../../utils/common/utils.js";
6
+ import { validateSchema } from "../../../utils/common/schema-validation.js";
7
+ import { upsertArtifact } from "./artifact.js";
7
8
  import { A2A } from "../../../types/index.js";
8
9
  import { logger } from "../../../config/index.js";
9
10
  const isMessageInHistory = (task, message) => {
@@ -17,9 +18,13 @@ const updateHistory = (task, updateMessage) => {
17
18
  export const handleMessageUpdate = async ({ task, update, }) => {
18
19
  const validated = await validateSchema(A2A.MessageSchema, update);
19
20
  if (validated.taskId && task.id !== validated.taskId) {
20
- throw new Error(`updateMessage: Invalid task id: ${validated.taskId}`, {
21
- cause: validated,
22
- });
21
+ throw new Error(`updateMessage: Invalid task id: ${validated.taskId} ${formatJson({
22
+ cause: {
23
+ validated,
24
+ actual: task.id,
25
+ task,
26
+ },
27
+ })}`);
23
28
  }
24
29
  updateHistory(task, validated);
25
30
  return task;
@@ -59,7 +64,7 @@ export const handleArtifactUpdate = async ({ task, update }) => {
59
64
  else {
60
65
  validated.taskId = task.id;
61
66
  }
62
- task.artifacts = processArtifactUpdate(update.append ?? false, task.artifacts ?? [], update.artifact);
67
+ task.artifacts = upsertArtifact(task.artifacts ?? [], validated);
63
68
  return task;
64
69
  };
65
70
  // The onus is now on the caller to handle errors when processing updates
@@ -8,4 +8,8 @@ import { A2A } from "../../../types/index.js";
8
8
  * @param input - The input event.
9
9
  * @returns The content of the input event.
10
10
  */
11
- export declare function getContent(input: A2A.Update): string | undefined;
11
+ export declare function extractTextContent(input: A2A.Update): string | undefined;
12
+ /**
13
+ * @deprecated Use extractTextContent instead.
14
+ */
15
+ export declare const getContent: typeof extractTextContent;
@@ -8,7 +8,7 @@ import { getParts } from "./part.js";
8
8
  * @param input - The input event.
9
9
  * @returns The content of the input event.
10
10
  */
11
- export function getContent(input) {
11
+ export function extractTextContent(input) {
12
12
  const parts = getParts(input?.parts ??
13
13
  input?.status?.message?.parts ??
14
14
  input?.status?.message?.parts ??
@@ -20,3 +20,7 @@ export function getContent(input) {
20
20
  parts.data.map((data) => JSON.stringify(data)).join("\n") ??
21
21
  undefined);
22
22
  }
23
+ /**
24
+ * @deprecated Use extractTextContent instead.
25
+ */
26
+ export const getContent = extractTextContent;
@@ -1,6 +1,6 @@
1
1
  export * from "./part.js";
2
2
  export * from "./content.js";
3
- export * from "./agentcard-builder.js";
4
- export * from "./message-builder.js";
3
+ export { AgentCardBuilder } from "../../../create/agentcard-builder.js";
4
+ export { MessageBuilder, MessageSendConfigurationBuilder, } from "../../../create/message-builder.js";
5
5
  export * from "./history.js";
6
6
  export * from "./references.js";
@@ -1,6 +1,6 @@
1
1
  export * from "./part.js";
2
2
  export * from "./content.js";
3
- export * from "./agentcard-builder.js";
4
- export * from "./message-builder.js";
3
+ export { AgentCardBuilder } from "../../../create/agentcard-builder.js";
4
+ export { MessageBuilder, MessageSendConfigurationBuilder, } from "../../../create/message-builder.js";
5
5
  export * from "./history.js";
6
6
  export * from "./references.js";
@@ -1,4 +1,4 @@
1
- export * from "./factory/builder.js";
1
+ export * from "../../create/create.js";
2
2
  export * from "./factory/service.js";
3
3
  export * from "./managers.js";
4
4
  export * from "./messenger.js";
@@ -1,4 +1,4 @@
1
- export * from "./factory/builder.js";
1
+ export * from "../../create/create.js";
2
2
  export * from "./factory/service.js";
3
3
  export * from "./managers.js";
4
4
  export * from "./messenger.js";