langgraph-api 0.14.0.dev2__py3-none-any.whl → 0.14.0.dev3__py3-none-any.whl

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.
langgraph_api/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.14.0.dev2"
1
+ __version__ = "0.14.0.dev3"
langgraph_api/api/a2a.py CHANGED
@@ -878,6 +878,38 @@ def _create_response_artifact_update(
878
878
  }
879
879
 
880
880
 
881
+ def _tool_result_data(message: dict[str, Any]) -> dict[str, Any] | None:
882
+ """Build the published form of one tool result, or None if not publishable.
883
+
884
+ A tool result is only published when it is correlated to the call that
885
+ produced it: ``tool_call_id`` is what lets a client match the payload back
886
+ to its request. Uncorrelated tool output stays internal.
887
+
888
+ Only the correlation id, content, tool name, and status are copied. Raw
889
+ LangChain internals (``response_metadata``, ``additional_kwargs``,
890
+ ``artifact``) are deliberately excluded.
891
+ """
892
+ tool_call_id = message.get("tool_call_id")
893
+ if not isinstance(tool_call_id, str) or not tool_call_id:
894
+ return None
895
+
896
+ result: dict[str, Any] = {"toolCallId": tool_call_id}
897
+ content = message.get("content")
898
+ if content not in (None, ""):
899
+ result["content"] = content
900
+ for key in ("name", "status"):
901
+ value = message.get(key)
902
+ if isinstance(value, str) and value:
903
+ result[key] = value
904
+ return result
905
+
906
+
907
+ def _tool_results_data_part(tool_results: list[dict[str, Any]]) -> dict[str, Any]:
908
+ """Wrap one or more tool results in a single A2A DataPart."""
909
+
910
+ return {"kind": "data", "data": {"tool_results": tool_results}}
911
+
912
+
881
913
  def _lc_stream_items_to_a2a_message(
882
914
  items: list[dict[str, Any]],
883
915
  *,
@@ -888,8 +920,11 @@ def _lc_stream_items_to_a2a_message(
888
920
  """Convert LangChain stream "messages/*" items into a valid A2A Message.
889
921
 
890
922
  This takes the list found in a messages/* StreamPart's data field and
891
- constructs a single A2A Message object, concatenating textual content and
892
- omitting internal system/tool messages and metadata.
923
+ constructs a single A2A Message object. Only public agent prose becomes
924
+ text; internal system/tool prose and LangChain metadata are omitted.
925
+ Correlated tool results are published separately as a structured DataPart
926
+ so data-consuming clients keep receiving them without tool output ever
927
+ being rendered as agent speech.
893
928
 
894
929
  Args:
895
930
  items: List of LangChain message dicts from stream (e.g., with keys like
@@ -903,8 +938,14 @@ def _lc_stream_items_to_a2a_message(
903
938
  """
904
939
  # Aggregate any text content across items
905
940
  text_parts: list[str] = []
941
+ tool_results: list[dict[str, Any]] = []
906
942
  for it in items:
907
- if not isinstance(it, dict) or _a2a_role_for_message(it) is None:
943
+ if not isinstance(it, dict):
944
+ continue
945
+ if _a2a_role_for_message(it) is None:
946
+ tool_result = _tool_result_data(it)
947
+ if tool_result is not None:
948
+ tool_results.append(tool_result)
908
949
  continue
909
950
  text = _content_to_text(it.get("content"))
910
951
  if text:
@@ -913,6 +954,8 @@ def _lc_stream_items_to_a2a_message(
913
954
  parts: list[dict[str, Any]] = []
914
955
  if text_parts:
915
956
  parts.append({"kind": "text", "text": "".join(text_parts)})
957
+ if tool_results:
958
+ parts.append(_tool_results_data_part(tool_results))
916
959
 
917
960
  # Ensure we always produce a minimally valid A2A Message
918
961
  if not parts:
@@ -1088,6 +1131,12 @@ def _convert_messages_to_a2a_format(
1088
1131
  ) -> list[dict[str, Any]]:
1089
1132
  """Convert LangChain messages to A2A message format.
1090
1133
 
1134
+ Public human/agent turns become text (and file) parts. Internal messages
1135
+ never become prose: a system prompt or uncorrelated tool output is dropped
1136
+ outright, while a tool result correlated by ``tool_call_id`` is published
1137
+ as a data-only agent message so clients can consume the structured payload
1138
+ without it being rendered as agent speech.
1139
+
1091
1140
  Args:
1092
1141
  messages: List of LangChain messages
1093
1142
  task_id: The task ID to assign to all messages
@@ -1103,22 +1152,27 @@ def _convert_messages_to_a2a_format(
1103
1152
  for msg in messages:
1104
1153
  if isinstance(msg, dict):
1105
1154
  a2a_role = _a2a_role_for_message(msg)
1106
- if a2a_role is None:
1107
- continue
1108
1155
 
1109
- content = msg.get("content", "")
1110
- id = msg.get("id") or str(uuid7())
1111
- parts = _content_to_a2a_parts(content)
1112
- if a2a_role == "ROLE_AGENT" and not _a2a_parts_have_content(parts):
1113
- continue
1114
- if not parts:
1115
- parts = [{"kind": "text", "text": ""}]
1156
+ if a2a_role is None:
1157
+ # Internal message: publish a correlated tool result as data,
1158
+ # drop system prompts and uncorrelated output entirely.
1159
+ tool_result = _tool_result_data(msg)
1160
+ if tool_result is None:
1161
+ continue
1162
+ a2a_role = "ROLE_AGENT"
1163
+ parts = [_tool_results_data_part([tool_result])]
1164
+ else:
1165
+ parts = _content_to_a2a_parts(msg.get("content", ""))
1166
+ if a2a_role == "ROLE_AGENT" and not _a2a_parts_have_content(parts):
1167
+ continue
1168
+ if not parts:
1169
+ parts = [{"kind": "text", "text": ""}]
1116
1170
 
1117
1171
  a2a_message = {
1118
1172
  "kind": "message",
1119
1173
  "role": a2a_role,
1120
1174
  "parts": parts,
1121
- "messageId": id,
1175
+ "messageId": msg.get("id") or str(uuid7()),
1122
1176
  "taskId": task_id,
1123
1177
  "contextId": context_id,
1124
1178
  }
@@ -17,7 +17,7 @@
17
17
  "@types/json-schema": "^7.0.15",
18
18
  "dedent": "^1.7.2",
19
19
  "exit-hook": "^5.1.0",
20
- "hono": "^4.12.31",
20
+ "hono": "^4.12.34",
21
21
  "p-queue": "^9.3.1",
22
22
  "p-retry": "^7.1.1",
23
23
  "undici": "^7.28.0",
@@ -1136,10 +1136,10 @@ graceful-fs@^4.2.4:
1136
1136
  resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz"
1137
1137
  integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
1138
1138
 
1139
- hono@^4.12.25, hono@^4.12.31:
1140
- version "4.12.31"
1141
- resolved "https://registry.yarnpkg.com/hono/-/hono-4.12.31.tgz#2ccaaf3ccd82db372f169c5b39c065c31ff36294"
1142
- integrity sha512-zJIHFrl6bq3RDd2YusFNCDlM8qUprxKswyi/OPzPyzKDdyBXDqWx8bZlZ7R+saTdSTatUmb3O7K4SspGPaEOQg==
1139
+ hono@^4.12.25, hono@^4.12.34:
1140
+ version "4.12.34"
1141
+ resolved "https://registry.yarnpkg.com/hono/-/hono-4.12.34.tgz#9d6fb4ff01d6a8fa3a0290b4e120da19ea181b9b"
1142
+ integrity sha512-GqXJqY/xJkJmuloTrnV1ZEXG3fqte+VjkUqoRNZXcrUidiUOP4fMSIHHY4tsqZBK++kVyWmt/AAfSUuy57/eSA==
1143
1143
 
1144
1144
  icss-utils@^5.0.0, icss-utils@^5.1.0:
1145
1145
  version "5.1.0"
@@ -1406,10 +1406,10 @@ mustache@^4.2.0:
1406
1406
  resolved "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz"
1407
1407
  integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==
1408
1408
 
1409
- nanoid@^3.3.12:
1410
- version "3.3.15"
1411
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.15.tgz#36c490fad8c6e86c824c940dfdde999b69ed4316"
1412
- integrity sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==
1409
+ nanoid@^3.3.17:
1410
+ version "3.3.17"
1411
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.17.tgz#f1c3aa253c52547956a52c50bff754316f61037a"
1412
+ integrity sha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g==
1413
1413
 
1414
1414
  node-releases@^2.0.27:
1415
1415
  version "2.0.27"
@@ -1557,11 +1557,11 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
1557
1557
  integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
1558
1558
 
1559
1559
  postcss@^8.4.41, postcss@^8.5.1, postcss@^8.5.16, postcss@^8.5.3:
1560
- version "8.5.19"
1561
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.19.tgz#45ad5cfde499408e20147348237551381a922037"
1562
- integrity sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==
1560
+ version "8.5.26"
1561
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.26.tgz#6e75135780c7e10df3433bf2266c552d35c8c620"
1562
+ integrity sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==
1563
1563
  dependencies:
1564
- nanoid "^3.3.12"
1564
+ nanoid "^3.3.17"
1565
1565
  picocolors "^1.1.1"
1566
1566
  source-map-js "^1.2.1"
1567
1567
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: langgraph-api
3
- Version: 0.14.0.dev2
3
+ Version: 0.14.0.dev3
4
4
  Author-email: Will Fu-Hinthorn <will@langchain.dev>, Josh Rogers <josh@langchain.dev>, Parker Rule <parker@langchain.dev>
5
5
  License: Elastic-2.0
6
6
  License-File: LICENSE
@@ -1,4 +1,4 @@
1
- langgraph_api/__init__.py,sha256=QTSi_3je-8WixS-ecEdOxDhwb5kMgXjXGazJrN3dtCo,28
1
+ langgraph_api/__init__.py,sha256=vqyq3EtKKqDDdFgH50DxuATAgrcKXWr3se6v-d09rh0,28
2
2
  langgraph_api/_factory_utils.py,sha256=_FqW0olMu2PGLsnRq0ylt3a4jDCe12YIFHExMXI6Nyo,5976
3
3
  langgraph_api/asgi_transport.py,sha256=XApY3lIWBZTMbbsl8dDJzl0cLGirmAGE0SifqZUnXvs,11896
4
4
  langgraph_api/asyncio.py,sha256=smqyAoO9nIyPPQRw1IVSCh85fwoZP4PEo-5dDhxGruc,10676
@@ -40,7 +40,7 @@ langgraph_api/_checkpointer/__init__.py,sha256=ofJTJLGy7Hsuzhj-2dpfDvrDloM0BzlhT
40
40
  langgraph_api/_checkpointer/_adapter.py,sha256=1jJi0vXoNKeCwNP26W8bmYrwe-fOWFqepnovYFt14W0,21782
41
41
  langgraph_api/_checkpointer/protocol.py,sha256=udgYKMNtKWG_eLDwYkHXV3b2bZLZg8Rsfm3fjkhU-rU,3635
42
42
  langgraph_api/api/__init__.py,sha256=Zu1ew3dxYZu7cLRAjn-6HcYmtuQBdihlVFMKMJ77Y3c,9269
43
- langgraph_api/api/a2a.py,sha256=dLoqiYut3cKOmAS-BMx8MVwZLhTbMHvefwWwc3E0t7I,111023
43
+ langgraph_api/api/a2a.py,sha256=l2nAmN5qHuYhpyi4ecvvPQDeXgpL3UJkTNe6_7f975k,113469
44
44
  langgraph_api/api/assistants.py,sha256=YelrvQWKNLIoqJheQ1riK2dhCTH3GenbmWyD5fEp-ok,21936
45
45
  langgraph_api/api/event_streaming.py,sha256=jvoBp5qHI92JJHsx4f9LEpb0i0VE31G_qFhS5JQWtlA,17809
46
46
  langgraph_api/api/meta.py,sha256=5s017GfMs-Ghq6Z5K6yW4UjbVFzCsmeXKn4UEJmfs98,4757
@@ -106,14 +106,14 @@ langgraph_api/js/client.http.mts,sha256=ARlTJURLJamgvyaPlBCYEAHFnXQnPpzzUXWKwXie
106
106
  langgraph_api/js/client.mts,sha256=3WiUCSrMSaPxohxBMuwhkZ1B75ZqiIJaDOKOwX1PBcg,39333
107
107
  langgraph_api/js/errors.py,sha256=Cm1TKWlUCwZReDC5AQ6SgNIVGD27Qov2xcgHyf8-GXo,361
108
108
  langgraph_api/js/global.d.ts,sha256=j4GhgtQSZ5_cHzjSPcHgMJ8tfBThxrH-pUOrrJGteOU,196
109
- langgraph_api/js/package.json,sha256=HZR61gyS7f8C9oW9uvWuIHtFsjI6EGBfru0HHDdxsn0,1327
109
+ langgraph_api/js/package.json,sha256=beOLQfLVFo48bgWdTfOoaAclM_hSW0FMgAjCGptZYf0,1327
110
110
  langgraph_api/js/remote.py,sha256=-wwFDbQoj0lW5SGI9wk0Qdpp5eEuQCMDPbeHIIwG5Qw,47969
111
111
  langgraph_api/js/schema.py,sha256=M4fLtr50O1jck8H1hm_0W4cZOGYGdkrB7riLyCes4oY,438
112
112
  langgraph_api/js/sse.py,sha256=IfcEpknyZeqqjYTOWRdijc6o2EBfatbWCZarGQQ0SQI,4088
113
113
  langgraph_api/js/traceblock.mts,sha256=QtGSN5VpzmGqDfbArrGXkMiONY94pMQ5CgzetT_bKYg,761
114
114
  langgraph_api/js/tsconfig.json,sha256=imCYqVnqFpaBoZPx8k1nO4slHIWBFsSlmCYhO73cpBs,341
115
115
  langgraph_api/js/ui.py,sha256=plqcWSmqfc9tY2nCUzNRBSofHTMdYDmVD9A6i5L3pSI,2571
116
- langgraph_api/js/yarn.lock,sha256=Sy9I98WWNBZHHP34a89ZI9StVBXrbVRgW4VVIh28Jyc,91558
116
+ langgraph_api/js/yarn.lock,sha256=9FP-3lhOoByOSR12XhYz4WrHzIrIeFwh6U1cK_P9ubM,91558
117
117
  langgraph_api/js/src/graph.mts,sha256=ccK4UFUkuMQXdCujQWZjZKAk3a3ZDVLpwhYF7pj4eGY,3786
118
118
  langgraph_api/js/src/load.hooks.mjs,sha256=sqgVptq70mJb2EDprRIbMqRmPbCJlT_nHCqZQgg9zw4,2256
119
119
  langgraph_api/js/src/preload.mjs,sha256=WL6MVSeFuxusFscySrDDnloXJNVhkNcMOFwP70UAMbs,4106
@@ -237,8 +237,8 @@ langgraph_grpc_common/proto/store_pb2.py,sha256=thQ5HBLblZ7Adayp1U8ty_lrpn-7XEHn
237
237
  langgraph_grpc_common/proto/store_pb2.pyi,sha256=_dcxyxV8moR6H67qU42r2h2p_Ub-PZSHs3OoS9KMdSY,27782
238
238
  langgraph_grpc_common/proto/store_pb2_grpc.py,sha256=Kyt8eV2NXkjh3be_BYytGdD19kNf74961cruonMvCrw,3300
239
239
  langgraph_grpc_common/proto/store_pb2_grpc.pyi,sha256=oS1h2cDoq2OjyM8xazcmc8LwRDC5oCAD0zto2QUmPQw,2027
240
- langgraph_api-0.14.0.dev2.dist-info/METADATA,sha256=RtvW40iU5HMvxfGWm2CFLSL1WFRXfFpl16KqrucTvVA,4630
241
- langgraph_api-0.14.0.dev2.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
242
- langgraph_api-0.14.0.dev2.dist-info/entry_points.txt,sha256=hGedv8n7cgi41PypMfinwS_HfCwA7xJIfS0jAp8htV8,78
243
- langgraph_api-0.14.0.dev2.dist-info/licenses/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
244
- langgraph_api-0.14.0.dev2.dist-info/RECORD,,
240
+ langgraph_api-0.14.0.dev3.dist-info/METADATA,sha256=H8z7TwUhYG_quvmt92eG_gSZUX2EtrB37wfaL6_cO2s,4630
241
+ langgraph_api-0.14.0.dev3.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
242
+ langgraph_api-0.14.0.dev3.dist-info/entry_points.txt,sha256=hGedv8n7cgi41PypMfinwS_HfCwA7xJIfS0jAp8htV8,78
243
+ langgraph_api-0.14.0.dev3.dist-info/licenses/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
244
+ langgraph_api-0.14.0.dev3.dist-info/RECORD,,