@runtypelabs/a2a-aisdk-example 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,11 +7,20 @@ var JSON_RPC_ERRORS = {
7
7
  METHOD_NOT_FOUND: -32601,
8
8
  INVALID_PARAMS: -32602,
9
9
  INTERNAL_ERROR: -32603,
10
- // Custom A2A errors
10
+ // A2A spec error codes
11
11
  TASK_NOT_FOUND: -32001,
12
+ TASK_NOT_CANCELABLE: -32002,
13
+ PUSH_NOTIFICATION_NOT_SUPPORTED: -32003,
14
+ UNSUPPORTED_OPERATION: -32004,
15
+ CONTENT_TYPE_NOT_SUPPORTED: -32005,
16
+ INVALID_AGENT_RESPONSE: -32006,
17
+ /** @deprecated Use TASK_NOT_CANCELABLE */
12
18
  SKILL_NOT_FOUND: -32002,
19
+ /** @deprecated */
13
20
  UNAUTHORIZED: -32003,
21
+ /** @deprecated */
14
22
  RATE_LIMITED: -32004,
23
+ /** @deprecated */
15
24
  TASK_CANCELED: -32005
16
25
  };
17
26
 
@@ -39,10 +48,10 @@ function createResponse(result, source) {
39
48
  }
40
49
  function extractInput(message) {
41
50
  for (const part of message.parts) {
42
- if (part.type === "data" && part.data) {
51
+ if ((part.type === "data" || part.data !== void 0) && part.data) {
43
52
  return part.data;
44
53
  }
45
- if (part.type === "text" && part.text) {
54
+ if ((part.type === "text" || part.text !== void 0) && part.text) {
46
55
  try {
47
56
  return JSON.parse(part.text);
48
57
  } catch {
@@ -262,7 +271,7 @@ var TOOL_STOP_CONDITION = stepCountIs(5);
262
271
  var TOOL_TAG = "tool";
263
272
  var LLM_TAG = "llm";
264
273
  function extractTextFromMessage(message) {
265
- return message.parts.filter((p) => p.type === "text" && p.text).map((p) => p.text).join("\n");
274
+ return message.parts.filter((p) => (p.type === "text" || p.text !== void 0) && p.text).map((p) => p.text).join("\n");
266
275
  }
267
276
  function createLLMProvider(config) {
268
277
  const gatewayKey = process.env.AI_GATEWAY_API_KEY;
@@ -607,6 +616,56 @@ var DEFAULT_LLM_CONFIG = {
607
616
  import express from "express";
608
617
  import { v4 as uuidv4 } from "uuid";
609
618
  var A2A_PROTOCOL_VERSION = "0.3";
619
+ function normalizePart(part) {
620
+ if (part.type) return part;
621
+ if (part.text !== void 0) return { type: "text", text: part.text, mediaType: part.mediaType };
622
+ if (part.data !== void 0) return { type: "data", data: part.data, mediaType: part.mediaType };
623
+ if (part.url !== void 0 || part.raw !== void 0) return { type: "file", uri: part.url ?? part.uri, mimeType: part.mediaType };
624
+ return part;
625
+ }
626
+ function normalizeRole(role) {
627
+ if (role === "ROLE_USER" || role === "user") return "user";
628
+ if (role === "ROLE_AGENT" || role === "agent") return "agent";
629
+ return "user";
630
+ }
631
+ function normalizeMessage(msg) {
632
+ const raw = msg;
633
+ return {
634
+ role: normalizeRole(raw.role || "user"),
635
+ messageId: raw.messageId,
636
+ parts: (raw.parts || []).map(normalizePart),
637
+ contextId: raw.contextId,
638
+ taskId: raw.taskId,
639
+ metadata: raw.metadata
640
+ };
641
+ }
642
+ function extractSendParams(params) {
643
+ const rawMessage = params.message || {};
644
+ const message = normalizeMessage(rawMessage);
645
+ const metadata = params.metadata;
646
+ const skillId = params.skill ?? metadata?.skill;
647
+ const contextId = params.contextId ?? message.contextId;
648
+ return { skillId, message, contextId, metadata };
649
+ }
650
+ function toSpecPart(part) {
651
+ const out = {};
652
+ if (part.type === "text" || part.text !== void 0) out.text = part.text ?? "";
653
+ else if (part.type === "data" || part.data !== void 0) out.data = part.data;
654
+ else if (part.type === "file") {
655
+ out.url = part.uri ?? part.url;
656
+ out.mediaType = part.mimeType ?? part.mediaType;
657
+ }
658
+ if (part.mediaType || part.mimeType) out.mediaType = part.mediaType ?? part.mimeType;
659
+ if (part.metadata) out.metadata = part.metadata;
660
+ return out;
661
+ }
662
+ function toSpecArtifact(a) {
663
+ return {
664
+ artifactId: a.artifactId ?? uuidv4(),
665
+ name: a.name,
666
+ parts: a.parts.map(toSpecPart)
667
+ };
668
+ }
610
669
  var tasks = /* @__PURE__ */ new Map();
611
670
  function generateTaskId() {
612
671
  return `task_${Date.now()}_${uuidv4().substring(0, 8)}`;
@@ -621,52 +680,57 @@ function createA2AServer(options) {
621
680
  const { config, llmConfig = DEFAULT_LLM_CONFIG, echoMode = false } = options;
622
681
  const app = express();
623
682
  app.use(express.json());
624
- app.use((_req, res, next) => {
683
+ app.use((req, res, next) => {
625
684
  res.header("Access-Control-Allow-Origin", "*");
626
685
  res.header("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
627
686
  res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, X-API-Key");
687
+ if (req.method === "OPTIONS") {
688
+ res.sendStatus(204);
689
+ return;
690
+ }
628
691
  next();
629
692
  });
630
- app.options("*", (_req, res) => {
631
- res.sendStatus(204);
632
- });
633
693
  const port = config.port || 9999;
634
694
  const host = config.host || "localhost";
635
695
  const skills = config.skills || DEFAULT_SKILLS;
696
+ const agentUrl = `http://${host}:${port}/a2a`;
636
697
  const agentCard = {
637
698
  name: config.name,
638
699
  description: config.description || `A2A Agent: ${config.name}`,
639
- url: `http://${host}:${port}/a2a`,
700
+ url: agentUrl,
701
+ supportedInterfaces: [
702
+ {
703
+ url: agentUrl,
704
+ protocolBinding: "JSONRPC",
705
+ protocolVersion: A2A_PROTOCOL_VERSION
706
+ }
707
+ ],
640
708
  version: config.version || "1.0.0",
641
709
  protocolVersion: A2A_PROTOCOL_VERSION,
642
- defaultInputModes: config.defaultInputModes || ["text", "data"],
643
- defaultOutputModes: config.defaultOutputModes || ["text", "data"],
710
+ defaultInputModes: config.defaultInputModes || ["text/plain", "application/json"],
711
+ defaultOutputModes: config.defaultOutputModes || ["text/plain", "application/json"],
644
712
  provider: config.provider || {
645
713
  organization: "Runtype",
646
714
  url: "https://runtype.com"
647
715
  },
648
716
  capabilities: {
649
717
  streaming: true,
650
- pushNotifications: false,
651
- statefulness: "task"
718
+ pushNotifications: false
652
719
  },
653
720
  skills: skills.map((s) => ({
654
721
  id: s.id,
655
722
  name: s.name,
656
723
  description: s.description,
657
- inputModes: ["text", "data"],
658
- outputModes: ["text", "data"],
659
724
  tags: s.tags ?? [],
660
- inputSchema: s.inputSchema
661
- })),
662
- authentication: {
663
- type: "none"
664
- }
725
+ examples: []
726
+ }))
665
727
  };
666
- app.get("/.well-known/agent.json", (_req, res) => {
728
+ const agentCardHandler = (_req, res) => {
667
729
  res.setHeader("Cache-Control", "public, max-age=3600");
668
730
  res.json(agentCard);
669
- });
731
+ };
732
+ app.get("/.well-known/agent.json", agentCardHandler);
733
+ app.get("/.well-known/agent-card.json", agentCardHandler);
670
734
  app.get("/health", (_req, res) => {
671
735
  res.json({ status: "healthy", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
672
736
  });
@@ -681,17 +745,27 @@ function createA2AServer(options) {
681
745
  try {
682
746
  switch (method) {
683
747
  case "tasks/send":
748
+ case "message/send":
749
+ case "SendMessage":
684
750
  await handleTasksSend(req, res, id, params, skills, llmConfig, echoMode);
685
751
  break;
686
752
  case "tasks/sendSubscribe":
753
+ case "message/stream":
754
+ case "SendStreamingMessage":
687
755
  await handleTasksSendSubscribe(req, res, id, params, skills, llmConfig, echoMode);
688
756
  break;
689
757
  case "tasks/get":
758
+ case "GetTask":
690
759
  handleTasksGet(res, id, params);
691
760
  break;
692
761
  case "tasks/cancel":
762
+ case "CancelTask":
693
763
  handleTasksCancel(res, id, params);
694
764
  break;
765
+ case "tasks/resubscribe":
766
+ case "SubscribeToTask":
767
+ res.json(jsonRpcError(id, JSON_RPC_ERRORS.UNSUPPORTED_OPERATION, "SubscribeToTask is not supported"));
768
+ break;
695
769
  case "ping":
696
770
  res.json(jsonRpcSuccess(id, { pong: true }));
697
771
  break;
@@ -713,7 +787,7 @@ function createA2AServer(options) {
713
787
  console.log(`A2A Agent Server: ${config.name}`);
714
788
  console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
715
789
  console.log("");
716
- console.log(` Agent Card: http://${host}:${port}/.well-known/agent.json`);
790
+ console.log(` Agent Card: http://${host}:${port}/.well-known/agent-card.json`);
717
791
  console.log(` A2A Endpoint: http://${host}:${port}/a2a`);
718
792
  console.log(` Health Check: http://${host}:${port}/health`);
719
793
  console.log("");
@@ -741,23 +815,24 @@ function createA2AServer(options) {
741
815
  })
742
816
  };
743
817
  }
744
- async function handleTasksSend(_req, res, id, params, skills, llmConfig, echoMode) {
745
- const { skill: skillId, message, contextId, metadata } = params;
746
- const skill = skills.find((s) => s.id === skillId);
747
- if (!skill) {
748
- res.json(
749
- jsonRpcError(id, JSON_RPC_ERRORS.SKILL_NOT_FOUND, `Skill not found: ${skillId}`, {
750
- availableSkills: skills.map((s) => s.id)
751
- })
752
- );
753
- return;
818
+ function resolveSkill(skillId, skills, echoMode) {
819
+ if (skillId) {
820
+ const found = skills.find((s) => s.id === skillId);
821
+ if (found) return found;
754
822
  }
823
+ if (echoMode) return skills.find((s) => s.id === "echo") || skills[0];
824
+ return skills.find((s) => s.id === "chat") || skills[0];
825
+ }
826
+ async function handleTasksSend(_req, res, id, params, skills, llmConfig, echoMode) {
827
+ const { skillId, message, contextId, metadata } = extractSendParams(params);
828
+ const skill = resolveSkill(skillId, skills, echoMode);
829
+ const resolvedContextId = contextId || uuidv4();
755
830
  const taskId = generateTaskId();
756
831
  const task = {
757
832
  id: taskId,
758
- contextId,
833
+ contextId: resolvedContextId,
759
834
  status: "submitted",
760
- skillId,
835
+ skillId: skill.id,
761
836
  requestMessage: message,
762
837
  artifacts: [],
763
838
  metadata,
@@ -769,29 +844,29 @@ async function handleTasksSend(_req, res, id, params, skills, llmConfig, echoMod
769
844
  try {
770
845
  const context = {
771
846
  taskId,
772
- contextId,
847
+ contextId: resolvedContextId,
773
848
  skill,
774
849
  message,
775
850
  metadata
776
851
  };
777
852
  let result;
778
- if (skillId.startsWith("time/")) {
853
+ if (skill.id.startsWith("time/")) {
779
854
  result = await executeTimeSkill(context);
780
- } else if (echoMode || skillId === "echo") {
855
+ } else if (echoMode || skill.id === "echo") {
781
856
  result = await executeEcho(context);
782
857
  } else {
783
858
  result = await executeTask(context, llmConfig, skills);
784
859
  }
785
860
  task.status = "completed";
786
- task.artifacts = result.artifacts;
861
+ task.artifacts = result.artifacts || [];
787
862
  task.history.push({ status: "completed", message: "Task completed", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
788
863
  res.json(
789
864
  jsonRpcSuccess(id, {
790
865
  task: {
791
866
  id: taskId,
792
- contextId,
793
- status: "completed",
794
- artifacts: task.artifacts,
867
+ contextId: resolvedContextId,
868
+ status: { state: "completed", timestamp: (/* @__PURE__ */ new Date()).toISOString() },
869
+ artifacts: task.artifacts.map(toSpecArtifact),
795
870
  metadata
796
871
  }
797
872
  })
@@ -805,22 +880,15 @@ async function handleTasksSend(_req, res, id, params, skills, llmConfig, echoMod
805
880
  }
806
881
  }
807
882
  async function handleTasksSendSubscribe(_req, res, id, params, skills, llmConfig, echoMode) {
808
- const { skill: skillId, message, contextId, metadata } = params;
809
- const skill = skills.find((s) => s.id === skillId);
810
- if (!skill) {
811
- res.json(
812
- jsonRpcError(id, JSON_RPC_ERRORS.SKILL_NOT_FOUND, `Skill not found: ${skillId}`, {
813
- availableSkills: skills.map((s) => s.id)
814
- })
815
- );
816
- return;
817
- }
883
+ const { skillId, message, contextId, metadata } = extractSendParams(params);
884
+ const skill = resolveSkill(skillId, skills, echoMode);
885
+ const resolvedContextId = contextId || uuidv4();
818
886
  const taskId = generateTaskId();
819
887
  const task = {
820
888
  id: taskId,
821
- contextId,
889
+ contextId: resolvedContextId,
822
890
  status: "submitted",
823
- skillId,
891
+ skillId: skill.id,
824
892
  requestMessage: message,
825
893
  artifacts: [],
826
894
  metadata,
@@ -831,72 +899,106 @@ async function handleTasksSendSubscribe(_req, res, id, params, skills, llmConfig
831
899
  res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
832
900
  res.setHeader("Connection", "keep-alive");
833
901
  res.setHeader("X-Accel-Buffering", "no");
834
- const sendEvent = (event, data) => {
835
- res.write(`event: ${event}
836
- data: ${JSON.stringify(data)}
902
+ const sendStreamResponse = (result) => {
903
+ const rpcResponse = { jsonrpc: "2.0", id, result };
904
+ res.write(`data: ${JSON.stringify(rpcResponse)}
837
905
 
838
906
  `);
839
907
  };
840
- sendEvent("task/status", { taskId, contextId, status: "submitted" });
908
+ sendStreamResponse({
909
+ task: {
910
+ id: taskId,
911
+ contextId: resolvedContextId,
912
+ status: { state: "submitted", timestamp: (/* @__PURE__ */ new Date()).toISOString() }
913
+ }
914
+ });
841
915
  task.status = "working";
842
916
  task.history.push({ status: "working", message: "Execution started", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
843
- sendEvent("task/status", { taskId, contextId, status: "working" });
917
+ sendStreamResponse({
918
+ statusUpdate: {
919
+ taskId,
920
+ contextId: resolvedContextId,
921
+ status: { state: "working", timestamp: (/* @__PURE__ */ new Date()).toISOString() }
922
+ }
923
+ });
844
924
  try {
845
925
  const context = {
846
926
  taskId,
847
- contextId,
927
+ contextId: resolvedContextId,
848
928
  skill,
849
929
  message,
850
930
  metadata
851
931
  };
852
- let artifactIndex = 0;
932
+ const artifactId = uuidv4();
933
+ let isFirstChunk = true;
853
934
  let fullText = "";
854
935
  const callbacks = {
855
936
  onChunk: async (text) => {
856
937
  fullText += text;
857
- sendEvent("task/artifact", {
858
- taskId,
859
- artifact: {
860
- name: "response",
861
- parts: [{ type: "text", text }],
862
- index: artifactIndex,
863
- append: artifactIndex > 0,
938
+ sendStreamResponse({
939
+ artifactUpdate: {
940
+ taskId,
941
+ contextId: resolvedContextId,
942
+ artifact: {
943
+ artifactId,
944
+ name: "response",
945
+ parts: [{ text }]
946
+ },
947
+ append: !isFirstChunk,
864
948
  lastChunk: false
865
949
  }
866
950
  });
867
- artifactIndex++;
951
+ isFirstChunk = false;
868
952
  },
869
953
  onComplete: async () => {
870
- sendEvent("task/artifact", {
871
- taskId,
872
- artifact: {
873
- name: "response",
874
- parts: [{ type: "text", text: "" }],
875
- index: artifactIndex,
954
+ sendStreamResponse({
955
+ artifactUpdate: {
956
+ taskId,
957
+ contextId: resolvedContextId,
958
+ artifact: {
959
+ artifactId,
960
+ name: "response",
961
+ parts: [{ text: "" }]
962
+ },
876
963
  append: true,
877
964
  lastChunk: true
878
965
  }
879
966
  });
880
967
  task.status = "completed";
881
- task.artifacts = [{ name: "response", parts: [{ type: "text", text: fullText }] }];
968
+ task.artifacts = [{ artifactId, name: "response", parts: [{ type: "text", text: fullText }] }];
882
969
  task.history.push({ status: "completed", message: "Task completed", timestamp: (/* @__PURE__ */ new Date()).toISOString() });
883
- sendEvent("task/status", { taskId, contextId, status: "completed", final: true });
970
+ sendStreamResponse({
971
+ statusUpdate: {
972
+ taskId,
973
+ contextId: resolvedContextId,
974
+ status: { state: "completed", timestamp: (/* @__PURE__ */ new Date()).toISOString() }
975
+ }
976
+ });
884
977
  res.end();
885
978
  },
886
979
  onError: async (error) => {
887
980
  task.status = "failed";
888
981
  task.error = { message: error.message };
889
982
  task.history.push({ status: "failed", message: error.message, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
890
- sendEvent("task/error", { taskId, error: { code: -32603, message: error.message } });
891
- sendEvent("task/status", { taskId, contextId, status: "failed", message: error.message, final: true });
983
+ sendStreamResponse({
984
+ statusUpdate: {
985
+ taskId,
986
+ contextId: resolvedContextId,
987
+ status: {
988
+ state: "failed",
989
+ message: { role: "agent", parts: [{ text: error.message }] },
990
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
991
+ }
992
+ }
993
+ });
892
994
  res.end();
893
995
  }
894
996
  };
895
- if (skillId.startsWith("time/")) {
997
+ if (skill.id.startsWith("time/")) {
896
998
  const timeResult = await executeTimeSkill(context);
897
999
  await callbacks.onChunk(timeResult.text);
898
1000
  await callbacks.onComplete();
899
- } else if (echoMode || skillId === "echo") {
1001
+ } else if (echoMode || skill.id === "echo") {
900
1002
  await executeEchoStreaming(context, callbacks);
901
1003
  } else {
902
1004
  await executeTaskStreaming(context, llmConfig, callbacks, skills);
@@ -906,53 +1008,70 @@ data: ${JSON.stringify(data)}
906
1008
  task.status = "failed";
907
1009
  task.error = { message: errorMessage };
908
1010
  task.history.push({ status: "failed", message: errorMessage, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
909
- sendEvent("task/error", { taskId, error: { code: -32603, message: errorMessage } });
910
- sendEvent("task/status", { taskId, contextId, status: "failed", message: errorMessage, final: true });
1011
+ sendStreamResponse({
1012
+ statusUpdate: {
1013
+ taskId,
1014
+ contextId: resolvedContextId,
1015
+ status: {
1016
+ state: "failed",
1017
+ message: { role: "agent", parts: [{ text: errorMessage }] },
1018
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1019
+ }
1020
+ }
1021
+ });
911
1022
  res.end();
912
1023
  }
913
1024
  }
914
1025
  function handleTasksGet(res, id, params) {
915
- const { taskId, includeHistory } = params;
916
- const task = tasks.get(taskId);
1026
+ const resolvedTaskId = params.id || params.taskId;
1027
+ if (!resolvedTaskId) {
1028
+ res.json(jsonRpcError(id, JSON_RPC_ERRORS.INVALID_PARAMS, "Missing task id"));
1029
+ return;
1030
+ }
1031
+ const task = tasks.get(resolvedTaskId);
917
1032
  if (!task) {
918
- res.json(jsonRpcError(id, JSON_RPC_ERRORS.TASK_NOT_FOUND, `Task not found: ${taskId}`));
1033
+ res.json(jsonRpcError(id, JSON_RPC_ERRORS.TASK_NOT_FOUND, `Task not found: ${resolvedTaskId}`));
919
1034
  return;
920
1035
  }
921
1036
  const result = {
922
1037
  task: {
923
1038
  id: task.id,
924
1039
  contextId: task.contextId,
925
- status: task.status,
926
- artifacts: task.artifacts,
1040
+ status: { state: task.status, timestamp: (/* @__PURE__ */ new Date()).toISOString() },
1041
+ artifacts: task.artifacts.map(toSpecArtifact),
927
1042
  metadata: task.metadata
928
1043
  }
929
1044
  };
930
- if (task.error) {
931
- result.task.error = task.error;
932
- }
933
- if (includeHistory) {
934
- result.task.history = task.history;
935
- }
936
1045
  res.json(jsonRpcSuccess(id, result));
937
1046
  }
938
1047
  function handleTasksCancel(res, id, params) {
939
- const { taskId, reason } = params;
940
- const task = tasks.get(taskId);
1048
+ const resolvedTaskId = params.id || params.taskId;
1049
+ if (!resolvedTaskId) {
1050
+ res.json(jsonRpcError(id, JSON_RPC_ERRORS.INVALID_PARAMS, "Missing task id"));
1051
+ return;
1052
+ }
1053
+ const task = tasks.get(resolvedTaskId);
941
1054
  if (!task) {
942
- res.json(jsonRpcError(id, JSON_RPC_ERRORS.TASK_NOT_FOUND, `Task not found: ${taskId}`));
1055
+ res.json(jsonRpcError(id, JSON_RPC_ERRORS.TASK_NOT_FOUND, `Task not found: ${resolvedTaskId}`));
943
1056
  return;
944
1057
  }
945
1058
  if (["completed", "failed", "canceled"].includes(task.status)) {
946
- res.json(jsonRpcError(id, JSON_RPC_ERRORS.TASK_CANCELED, `Task cannot be canceled: already ${task.status}`));
1059
+ res.json(jsonRpcError(id, JSON_RPC_ERRORS.TASK_NOT_CANCELABLE, `Task cannot be canceled: already ${task.status}`));
947
1060
  return;
948
1061
  }
949
1062
  task.status = "canceled";
950
1063
  task.history.push({
951
1064
  status: "canceled",
952
- message: reason || "Canceled by request",
1065
+ message: params.reason || "Canceled by request",
953
1066
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
954
1067
  });
955
- res.json(jsonRpcSuccess(id, { task: { id: taskId, status: "canceled" } }));
1068
+ res.json(jsonRpcSuccess(id, {
1069
+ task: {
1070
+ id: resolvedTaskId,
1071
+ contextId: task.contextId,
1072
+ status: { state: "canceled", timestamp: (/* @__PURE__ */ new Date()).toISOString() }
1073
+ }
1074
+ }));
956
1075
  }
957
1076
 
958
1077
  // src/client.ts
@@ -966,13 +1085,10 @@ var A2AClient = class {
966
1085
  this.baseUrl = options.baseUrl.replace(/\/$/, "");
967
1086
  const isA2aBase = this.baseUrl.endsWith("/a2a");
968
1087
  this.rpcUrl = isA2aBase ? this.baseUrl : `${this.baseUrl}/a2a`;
969
- this.agentCardUrl = `${this.baseUrl}/.well-known/agent.json`;
1088
+ this.agentCardUrl = `${this.baseUrl}/.well-known/agent-card.json`;
970
1089
  this.apiKey = options.apiKey;
971
1090
  this.headers = options.headers || {};
972
1091
  }
973
- /**
974
- * Get the agent card for discovery
975
- */
976
1092
  async getAgentCard() {
977
1093
  const response = await fetch(this.agentCardUrl, {
978
1094
  headers: this.getHeaders()
@@ -982,15 +1098,12 @@ var A2AClient = class {
982
1098
  }
983
1099
  return response.json();
984
1100
  }
985
- /**
986
- * Send a task and wait for completion (synchronous)
987
- */
988
1101
  async sendTask(params) {
989
1102
  const request = {
990
1103
  jsonrpc: "2.0",
991
1104
  id: `req_${Date.now()}`,
992
- method: "tasks/send",
993
- params
1105
+ method: "message/send",
1106
+ params: this.toSendMessageRequest(params)
994
1107
  };
995
1108
  const response = await this.sendJsonRpc(request);
996
1109
  if (response.error) {
@@ -998,17 +1111,14 @@ var A2AClient = class {
998
1111
  }
999
1112
  return response.result.task;
1000
1113
  }
1001
- /**
1002
- * Send a task with streaming (SSE)
1003
- */
1004
1114
  async sendTaskStreaming(params, callbacks) {
1005
1115
  const request = {
1006
1116
  jsonrpc: "2.0",
1007
1117
  id: `req_${Date.now()}`,
1008
- method: "tasks/sendSubscribe",
1009
- params
1118
+ method: "message/stream",
1119
+ params: this.toSendMessageRequest(params)
1010
1120
  };
1011
- const response = await fetch(`${this.baseUrl}/a2a`, {
1121
+ const response = await fetch(this.rpcUrl, {
1012
1122
  method: "POST",
1013
1123
  headers: {
1014
1124
  "Content-Type": "application/json",
@@ -1031,43 +1141,37 @@ var A2AClient = class {
1031
1141
  buffer += decoder.decode(value, { stream: true });
1032
1142
  const lines = buffer.split("\n");
1033
1143
  buffer = lines.pop() || "";
1034
- let currentEvent = "";
1035
1144
  for (const line of lines) {
1036
- if (line.startsWith("event: ")) {
1037
- currentEvent = line.substring(7);
1038
- } else if (line.startsWith("data: ")) {
1039
- const data = JSON.parse(line.substring(6));
1040
- switch (currentEvent) {
1041
- case "task/status":
1042
- callbacks.onStatus?.(data.status, data);
1043
- break;
1044
- case "task/artifact":
1045
- callbacks.onArtifact?.(data.artifact);
1046
- if (data.artifact?.parts) {
1047
- for (const part of data.artifact.parts) {
1048
- if (part.type === "text" && part.text) {
1049
- callbacks.onChunk?.(part.text);
1050
- }
1051
- }
1052
- }
1053
- break;
1054
- case "task/error":
1055
- callbacks.onError?.(data.error);
1056
- break;
1145
+ if (!line.startsWith("data: ")) continue;
1146
+ const payload = JSON.parse(line.substring(6));
1147
+ const result = payload.result || payload;
1148
+ if (result.statusUpdate) {
1149
+ const state = result.statusUpdate.status?.state || result.statusUpdate.status;
1150
+ callbacks.onStatus?.(state, result.statusUpdate);
1151
+ } else if (result.artifactUpdate) {
1152
+ const artifact = result.artifactUpdate.artifact;
1153
+ callbacks.onArtifact?.(artifact);
1154
+ if (artifact?.parts) {
1155
+ for (const part of artifact.parts) {
1156
+ const text = part.text ?? (part.type === "text" ? part.text : void 0);
1157
+ if (text) callbacks.onChunk?.(text);
1158
+ }
1057
1159
  }
1160
+ } else if (result.task) {
1161
+ const state = result.task.status?.state || result.task.status;
1162
+ if (state) callbacks.onStatus?.(state, result.task);
1163
+ } else if (result.error || payload.error) {
1164
+ callbacks.onError?.(result.error || payload.error);
1058
1165
  }
1059
1166
  }
1060
1167
  }
1061
1168
  }
1062
- /**
1063
- * Get task status
1064
- */
1065
- async getTask(taskId, includeHistory = false) {
1169
+ async getTask(taskId, historyLength) {
1066
1170
  const request = {
1067
1171
  jsonrpc: "2.0",
1068
1172
  id: `req_${Date.now()}`,
1069
- method: "tasks/get",
1070
- params: { taskId, includeHistory }
1173
+ method: "GetTask",
1174
+ params: { id: taskId, historyLength }
1071
1175
  };
1072
1176
  const response = await this.sendJsonRpc(request);
1073
1177
  if (response.error) {
@@ -1075,15 +1179,12 @@ var A2AClient = class {
1075
1179
  }
1076
1180
  return response.result.task;
1077
1181
  }
1078
- /**
1079
- * Cancel a task
1080
- */
1081
1182
  async cancelTask(taskId, reason) {
1082
1183
  const request = {
1083
1184
  jsonrpc: "2.0",
1084
1185
  id: `req_${Date.now()}`,
1085
- method: "tasks/cancel",
1086
- params: { taskId, reason }
1186
+ method: "CancelTask",
1187
+ params: { id: taskId, metadata: reason ? { reason } : void 0 }
1087
1188
  };
1088
1189
  const response = await this.sendJsonRpc(request);
1089
1190
  if (response.error) {
@@ -1092,8 +1193,23 @@ var A2AClient = class {
1092
1193
  return response.result.task;
1093
1194
  }
1094
1195
  /**
1095
- * Send a JSON-RPC request
1196
+ * Convert legacy TasksSendParams to spec SendMessageRequest format
1096
1197
  */
1198
+ toSendMessageRequest(params) {
1199
+ return {
1200
+ message: {
1201
+ messageId: `msg_${Date.now()}`,
1202
+ role: "user",
1203
+ parts: params.message.parts,
1204
+ contextId: params.contextId,
1205
+ taskId: params.message.taskId
1206
+ },
1207
+ metadata: {
1208
+ ...params.metadata,
1209
+ ...params.skill ? { skill: params.skill } : {}
1210
+ }
1211
+ };
1212
+ }
1097
1213
  async sendJsonRpc(request) {
1098
1214
  const response = await fetch(this.rpcUrl, {
1099
1215
  method: "POST",
@@ -1108,9 +1224,6 @@ var A2AClient = class {
1108
1224
  }
1109
1225
  return response.json();
1110
1226
  }
1111
- /**
1112
- * Get headers for requests
1113
- */
1114
1227
  getHeaders() {
1115
1228
  const headers = { ...this.headers };
1116
1229
  if (this.apiKey) {
@@ -1150,4 +1263,4 @@ export {
1150
1263
  A2AClient,
1151
1264
  createRuntypeA2AClient
1152
1265
  };
1153
- //# sourceMappingURL=chunk-OLB7ZZNY.js.map
1266
+ //# sourceMappingURL=chunk-EY4P4D5Y.js.map