langgraph-api 0.0.37__py3-none-any.whl → 0.0.38__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.

Potentially problematic release.


This version of langgraph-api might be problematic. Click here for more details.

langgraph_api/api/mcp.py CHANGED
@@ -351,7 +351,9 @@ async def handle_tools_list(
351
351
 
352
352
  # Get assistants from the API
353
353
  # For now set a large limit to get all assistants
354
- assistants = await client.assistants.search(offset=cursor, limit=DEFAULT_PAGE_SIZE)
354
+ assistants = await client.assistants.search(
355
+ offset=cursor, limit=DEFAULT_PAGE_SIZE, headers=request.headers
356
+ )
355
357
 
356
358
  if len(assistants) == DEFAULT_PAGE_SIZE:
357
359
  next_cursor = cursor + DEFAULT_PAGE_SIZE
@@ -370,7 +372,7 @@ async def handle_tools_list(
370
372
  else:
371
373
  seen_names.add(name)
372
374
 
373
- schemas = await client.assistants.get_schemas(id_)
375
+ schemas = await client.assistants.get_schemas(id_, headers=request.headers)
374
376
  tools.append(
375
377
  {
376
378
  "name": name,
@@ -408,7 +410,9 @@ async def handle_tools_call(
408
410
  }
409
411
 
410
412
  arguments = params.get("arguments", {})
411
- assistants = await client.assistants.search(limit=MAX_ASSISTANTS)
413
+ assistants = await client.assistants.search(
414
+ limit=MAX_ASSISTANTS, headers=request.headers
415
+ )
412
416
  matching_assistant = [
413
417
  assistant for assistant in assistants if assistant["name"] == tool_name
414
418
  ]
@@ -437,7 +441,11 @@ async def handle_tools_call(
437
441
  tool_name = matching_assistant[0]["assistant_id"]
438
442
 
439
443
  value = await client.runs.wait(
440
- thread_id=None, assistant_id=tool_name, input=arguments, raise_error=False
444
+ thread_id=None,
445
+ assistant_id=tool_name,
446
+ input=arguments,
447
+ raise_error=False,
448
+ headers=request.headers,
441
449
  )
442
450
 
443
451
  if "__error__" in value:
@@ -379,13 +379,16 @@ def _depends() -> Any:
379
379
  return None
380
380
 
381
381
 
382
+ _EXCLUDED = ("values", "keys", "items", "dict")
383
+
384
+
382
385
  class DotDict:
383
386
  def __init__(self, dictionary: dict[str, Any]):
384
387
  self._dict = dictionary
385
388
  for key, value in dictionary.items():
386
389
  if isinstance(value, dict):
387
390
  setattr(self, key, DotDict(value))
388
- else:
391
+ elif key not in _EXCLUDED:
389
392
  setattr(self, key, value)
390
393
 
391
394
  def __getattr__(self, name):
@@ -393,6 +396,9 @@ class DotDict:
393
396
  raise AttributeError(f"'DotDict' object has no attribute '{name}'")
394
397
  return self._dict[name]
395
398
 
399
+ def __contains__(self, key: str) -> bool:
400
+ return key in self._dict
401
+
396
402
  def __getitem__(self, key):
397
403
  return self._dict[key]
398
404
 
@@ -409,6 +415,21 @@ class DotDict:
409
415
  def dict(self):
410
416
  return self._dict
411
417
 
418
+ def items(self):
419
+ return self._dict.items()
420
+
421
+ def values(self):
422
+ return self._dict.values()
423
+
424
+ def keys(self):
425
+ return self._dict.keys()
426
+
427
+ def __iter__(self):
428
+ return iter(self._dict)
429
+
430
+ def __len__(self):
431
+ return len(self._dict)
432
+
412
433
 
413
434
  class ProxyUser(BaseUser):
414
435
  """A proxy that wraps a user object to ensure it has all BaseUser properties.
@@ -462,6 +483,9 @@ class ProxyUser(BaseUser):
462
483
  **d,
463
484
  }
464
485
 
486
+ def __contains__(self, key: str) -> bool:
487
+ return key in self._user
488
+
465
489
  def __getitem__(self, key):
466
490
  return self._user[key]
467
491
 
@@ -1,9 +1,11 @@
1
1
  import asyncio
2
+ import urllib.parse
2
3
  import uuid
3
4
  from collections.abc import Mapping, Sequence
4
5
  from typing import Any, NamedTuple, TypedDict
5
6
  from uuid import UUID
6
7
 
8
+ import orjson
7
9
  from langgraph.checkpoint.base.id import uuid6
8
10
  from starlette.authentication import BaseUser
9
11
  from starlette.exceptions import HTTPException
@@ -152,6 +154,11 @@ def get_user_id(user: BaseUser | None) -> str | None:
152
154
  pass
153
155
 
154
156
 
157
+ LANGSMITH_METADATA = "langsmith-metadata"
158
+ LANGSMITH_TAGS = "langsmith-tags"
159
+ LANGSMITH_PROJECT = "langsmith-project"
160
+
161
+
155
162
  async def create_valid_run(
156
163
  conn: AsyncConnectionProto,
157
164
  thread_id: str | None,
@@ -174,14 +181,13 @@ async def create_valid_run(
174
181
  stream_mode, multitask_strategy, prevent_insert_if_inflight = assign_defaults(
175
182
  payload
176
183
  )
177
-
178
184
  # assign custom headers and checkpoint to config
179
185
  config = payload.get("config") or {}
180
- config.setdefault("configurable", {})
186
+ configurable = config.setdefault("configurable", {})
181
187
  if checkpoint_id:
182
- config["configurable"]["checkpoint_id"] = str(checkpoint_id)
188
+ configurable["checkpoint_id"] = str(checkpoint_id)
183
189
  if checkpoint := payload.get("checkpoint"):
184
- config["configurable"].update(checkpoint)
190
+ configurable.update(checkpoint)
185
191
  for key, value in headers.items():
186
192
  if key.startswith("x-"):
187
193
  if key in (
@@ -190,14 +196,27 @@ async def create_valid_run(
190
196
  "x-service-key",
191
197
  ):
192
198
  continue
193
- config["configurable"][key] = value
199
+ configurable[key] = value
200
+ elif key == "langsmith-trace":
201
+ configurable[key] = value
202
+ if baggage := headers.get("baggage"):
203
+ for item in baggage.split(","):
204
+ key, value = item.split("=")
205
+ if key == LANGSMITH_METADATA and key not in configurable:
206
+ configurable[key] = orjson.loads(urllib.parse.unquote(value))
207
+ elif key == LANGSMITH_TAGS:
208
+ configurable[key] = urllib.parse.unquote(value).split(",")
209
+ elif key == LANGSMITH_PROJECT:
210
+ configurable[key] = urllib.parse.unquote(value)
211
+ elif key == "user-agent":
212
+ configurable[key] = value
194
213
  ctx = get_auth_ctx()
195
214
  if ctx:
196
215
  user = ctx.user
197
216
  user_id = get_user_id(user)
198
- config["configurable"]["langgraph_auth_user"] = user
199
- config["configurable"]["langgraph_auth_user_id"] = user_id
200
- config["configurable"]["langgraph_auth_permissions"] = ctx.permissions
217
+ configurable["langgraph_auth_user"] = user
218
+ configurable["langgraph_auth_user_id"] = user_id
219
+ configurable["langgraph_auth_permissions"] = ctx.permissions
201
220
  else:
202
221
  user_id = None
203
222
  run_coro = Runs.put(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: langgraph-api
3
- Version: 0.0.37
3
+ Version: 0.0.38
4
4
  Summary:
5
5
  License: Elastic-2.0
6
6
  Author: Nuno Campos
@@ -17,7 +17,7 @@ Requires-Dist: jsonschema-rs (>=0.20.0,<0.30)
17
17
  Requires-Dist: langchain-core (>=0.2.38,<0.4.0)
18
18
  Requires-Dist: langgraph (>=0.2.56,<0.4.0)
19
19
  Requires-Dist: langgraph-checkpoint (>=2.0.23,<3.0)
20
- Requires-Dist: langgraph-sdk (>=0.1.58,<0.2.0)
20
+ Requires-Dist: langgraph-sdk (>=0.1.59,<0.2.0)
21
21
  Requires-Dist: langsmith (>=0.1.63,<0.4.0)
22
22
  Requires-Dist: orjson (>=3.9.7)
23
23
  Requires-Dist: pyjwt (>=2.9.0,<3.0.0)
@@ -2,7 +2,7 @@ LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
2
2
  langgraph_api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  langgraph_api/api/__init__.py,sha256=iDxgg0arqzZ0-roCSuWo3f8zXmKcl4fuU3Jw0-lqtZs,5447
4
4
  langgraph_api/api/assistants.py,sha256=nU6tnbgdr_6Utlq0A9nw2a6xxpUM_DNuCFI42_Kcs_o,14233
5
- langgraph_api/api/mcp.py,sha256=dpKT9DgIoLERTmYZ4sSOPyHbfGbm7hCyb2MrMS_ol18,13593
5
+ langgraph_api/api/mcp.py,sha256=KbR19dtFCpJEiKYj3IfepAuJij8YZVELuVp7JY_yu_o,13754
6
6
  langgraph_api/api/meta.py,sha256=ifJ_Ki0Qf2DYbmY6OKlqKhLGxbt55gm0lEqH1A0cJbw,2790
7
7
  langgraph_api/api/openapi.py,sha256=f9gfmWN2AMKNUpLCpSgZuw_aeOF9jCXPdOtFT5PaTWM,10960
8
8
  langgraph_api/api/runs.py,sha256=uijgtrw_FSf1lZHsx8pM-CIj_ur2O88Y7ys-CJZ4SNQ,17988
@@ -11,7 +11,7 @@ langgraph_api/api/threads.py,sha256=kvv8pmRoUIvPFEuAhJpMC6qMv7Xo5itrzb5EzJFyWMg,
11
11
  langgraph_api/api/ui.py,sha256=LiOZVewKOPbKEykCm30hCEaOA7vuS_Ti5hB32EEy4vw,2082
12
12
  langgraph_api/asyncio.py,sha256=hVuAxWTHoUyNqTzcIEKTkAvh7HFrdGK6WIDowDxORAE,8397
13
13
  langgraph_api/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- langgraph_api/auth/custom.py,sha256=Gays0bYwZmRQA8-LSmQSNp1zS2_NG_xybG2cW79YweU,20890
14
+ langgraph_api/auth/custom.py,sha256=sPYkF-xTdGIn_WMSE2tfR_azg_azzXPRWwUfCye6GQ8,21401
15
15
  langgraph_api/auth/langsmith/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  langgraph_api/auth/langsmith/backend.py,sha256=InScaL-HYCnxYEauhxU198gRZV9pJn9SzzBoR9Edn7g,2654
17
17
  langgraph_api/auth/langsmith/client.py,sha256=eKchvAom7hdkUXauD8vHNceBDDUijrFgdTV8bKd7x4Q,3998
@@ -67,7 +67,7 @@ langgraph_api/middleware/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
67
67
  langgraph_api/middleware/http_logger.py,sha256=yuFPNFIWwn-4AE1CogBfWlo8KytzywLi_Bd4ccsyVQE,3150
68
68
  langgraph_api/middleware/private_network.py,sha256=eYgdyU8AzU2XJu362i1L8aSFoQRiV7_aLBPw7_EgeqI,2111
69
69
  langgraph_api/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
70
- langgraph_api/models/run.py,sha256=J1DpfMwv7W3zX9WtCANyObaCuZWBVfz2JWgdIBa9VzU,10180
70
+ langgraph_api/models/run.py,sha256=85-pyyvosFAot8WrWl2QjCje-2c4lhattYvoAEMqztA,11000
71
71
  langgraph_api/patch.py,sha256=82xjuFqY7tgrUm-k1XWHI6k8S6QovSD0zhe--8_xW4o,1296
72
72
  langgraph_api/queue_entrypoint.py,sha256=4xICUxXarNV8DhnaqAMhVi3xCmyVKCL3J5NzHxPA9Xc,1835
73
73
  langgraph_api/route.py,sha256=fM4qYCGbmH0a3_cV8uKocb1sLklehxO6HhdRXqLK6OM,4421
@@ -96,8 +96,8 @@ langgraph_storage/store.py,sha256=JB9jZ87GE19MVN9wgl3-esgR2eIkeipws9q6qsPWkgc,33
96
96
  langgraph_storage/ttl_dict.py,sha256=FlpEY8EANeXWKo_G5nmIotPquABZGyIJyk6HD9u6vqY,1533
97
97
  logging.json,sha256=3RNjSADZmDq38eHePMm1CbP6qZ71AmpBtLwCmKU9Zgo,379
98
98
  openapi.json,sha256=-25y3NRQ88e_944UXo76Goa34HJhC7pj6I9tjYUwvuE,131492
99
- langgraph_api-0.0.37.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
100
- langgraph_api-0.0.37.dist-info/METADATA,sha256=zawmEdZt_TgVBU6iHpMFrfdREjAYy9PqXU6lyy1dBb8,4071
101
- langgraph_api-0.0.37.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
102
- langgraph_api-0.0.37.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
103
- langgraph_api-0.0.37.dist-info/RECORD,,
99
+ langgraph_api-0.0.38.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
100
+ langgraph_api-0.0.38.dist-info/METADATA,sha256=kv_c0bBL9Vp6pM0NQOUv1uyruDkf5K67X74nSICrekw,4071
101
+ langgraph_api-0.0.38.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
102
+ langgraph_api-0.0.38.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
103
+ langgraph_api-0.0.38.dist-info/RECORD,,