managed-deepagents 0.6.2.dev3__py3-none-win_amd64.whl → 0.6.2.dev5__py3-none-win_amd64.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.
Binary file
@@ -9,11 +9,12 @@ and other built-ins are not double-headed.
9
9
  :data:`MDA_PUBLIC_APP_URL_ENV` plus optional :data:`MDA_CORS_ORIGINS_ENV`.
10
10
 
11
11
  Subdomain policy: an allowlisted origin also permits **one** DNS label beneath
12
- it (e.g. Cloudflare Pages previews under a project apex). Deeper nesting is
13
- rejected. With ``allow_credentials=True``, do not put hosts that issue
14
- attacker-reachable subdomains into :data:`MDA_CORS_ORIGINS_ENV` / the public
15
- app URL — a malicious page on such a subdomain could read credentialed
16
- ``/connectors`` and ``/channels`` responses.
12
+ it (e.g. Cloudflare Pages previews under a project apex) **on the same scheme**.
13
+ Deeper nesting is rejected, and ``http://`` is never reflected for an
14
+ ``https://`` allowlist entry (or the reverse). With ``allow_credentials=True``,
15
+ do not put hosts that issue attacker-reachable subdomains into
16
+ :data:`MDA_CORS_ORIGINS_ENV` / the public app URL — a malicious page on such a
17
+ subdomain could read credentialed ``/connectors`` and ``/channels`` responses.
17
18
  """
18
19
 
19
20
  from __future__ import annotations
@@ -96,9 +97,10 @@ def _is_single_subdomain(request_host: str, allowed_host: str) -> bool:
96
97
  def match_cors_origin(request_origin: str, allowlist: list[str]) -> str | None:
97
98
  """Return ``request_origin`` when allowed, otherwise ``None``.
98
99
 
99
- Mirrors TypeScript ``matchCorsOrigin`` (exact host or one subdomain label).
100
- Starlette has no origin callback, so production uses
101
- :func:`_cors_origin_regex` instead; keep this helper for tests / policy parity.
100
+ Mirrors TypeScript ``matchCorsOrigin`` (exact origin, or one subdomain
101
+ label on the same scheme). Starlette has no origin callback, so production
102
+ uses :func:`_cors_origin_regex` instead; keep this helper for tests / policy
103
+ parity.
102
104
  """
103
105
  parsed = urlparse(request_origin)
104
106
  if not parsed.scheme or not parsed.netloc:
@@ -108,8 +110,9 @@ def match_cors_origin(request_origin: str, allowlist: list[str]) -> str | None:
108
110
  return origin
109
111
  request_host = parsed.netloc
110
112
  for allowed in allowlist:
111
- allowed_host = urlparse(allowed).netloc
112
- if not allowed_host:
113
+ allowed_parsed = urlparse(allowed)
114
+ allowed_host = allowed_parsed.netloc
115
+ if not allowed_host or parsed.scheme != allowed_parsed.scheme:
113
116
  continue
114
117
  if request_host == allowed_host or _is_single_subdomain(request_host, allowed_host):
115
118
  return origin
@@ -42,7 +42,7 @@ from managed_deepagents.identity import (
42
42
  RuntimeIdentity,
43
43
  )
44
44
 
45
- CHANNEL_EVENTS_MAX_BODY_BYTES = 1024 * 1024
45
+ EVENTS_MAX_BODY_BYTES = 1024 * 1024
46
46
 
47
47
  RouteResult = object | Awaitable[object]
48
48
  PublicRouteHandler = Callable[[HttpRequestLike], RouteResult]
@@ -204,9 +204,9 @@ def _channel_events_route(
204
204
  if not callable(events):
205
205
  raise TypeError(f'channel "{name}" is missing events')
206
206
  try:
207
- raw_body = await _read_limited_channel_body(request)
207
+ raw_body = await _read_limited_events_body(request)
208
208
  if raw_body is None:
209
- return responses.PlainTextResponse("Payload Too Large", status_code=413)
209
+ return responses.JSONResponse({"error": "payload too large"}, status_code=413)
210
210
  result = events(
211
211
  {
212
212
  "name": name,
@@ -225,12 +225,12 @@ def _channel_events_route(
225
225
  return cast("StarletteRoute", routing.Route(path, events_handler, methods=["POST"]))
226
226
 
227
227
 
228
- async def _read_limited_channel_body(request: HttpRequestLike) -> bytes | None:
228
+ async def _read_limited_events_body(request: HttpRequestLike) -> bytes | None:
229
229
  stream = getattr(request, "stream", None)
230
230
  if not callable(stream):
231
231
  body_method = getattr(request, "body", None)
232
232
  body = await body_method() if callable(body_method) else b""
233
- if isinstance(body, bytes) and len(body) <= CHANNEL_EVENTS_MAX_BODY_BYTES:
233
+ if isinstance(body, bytes) and len(body) <= EVENTS_MAX_BODY_BYTES:
234
234
  return body
235
235
  return None
236
236
 
@@ -238,7 +238,7 @@ async def _read_limited_channel_body(request: HttpRequestLike) -> bytes | None:
238
238
  size = 0
239
239
  async for chunk in stream():
240
240
  size += len(chunk)
241
- if size > CHANNEL_EVENTS_MAX_BODY_BYTES:
241
+ if size > EVENTS_MAX_BODY_BYTES:
242
242
  return None
243
243
  chunks.append(chunk)
244
244
  return b"".join(chunks)
@@ -261,22 +261,28 @@ def _connector_events_route(
261
261
  )
262
262
 
263
263
  async def events_handler(request: HttpRequestLike) -> object:
264
- body_method = getattr(request, "body", None)
265
- raw_body = await body_method() if callable(body_method) else b""
264
+ responses = import_module("starlette.responses")
266
265
  events = getattr(connector, "events", None)
267
266
  if not callable(events):
268
267
  raise TypeError(f'connector "{name}" is missing events')
269
- result = events(
270
- {
271
- "name": name,
272
- "request": request,
273
- "raw_body": raw_body,
274
- "connector": connector,
275
- }
276
- )
277
- if inspect.isawaitable(result):
278
- result = await result
279
- return result
268
+ try:
269
+ raw_body = await _read_limited_events_body(request)
270
+ if raw_body is None:
271
+ return responses.JSONResponse({"error": "payload too large"}, status_code=413)
272
+ result = events(
273
+ {
274
+ "name": name,
275
+ "request": request,
276
+ "raw_body": raw_body,
277
+ "connector": connector,
278
+ }
279
+ )
280
+ if inspect.isawaitable(result):
281
+ result = await result
282
+ return result
283
+ except Exception as error: # noqa: BLE001 - log a safe label, keep the HTTP body opaque
284
+ logger.error("POST %s failed (%s)", path, logger.safe_error_label(error))
285
+ return responses.JSONResponse({"error": "internal error"}, status_code=500)
280
286
 
281
287
  return cast("StarletteRoute", routing.Route(path, events_handler, methods=["POST"]))
282
288
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: managed-deepagents
3
- Version: 0.6.2.dev3
3
+ Version: 0.6.2.dev5
4
4
  Summary: Managed Deep Agents — the define_deep_agent authoring interface plus the CLI that compiles and deploys a code-first Deep Agent repository to a managed LangGraph runtime.
5
5
  Author: LangChain
6
6
  License: MIT
@@ -3,11 +3,11 @@ managed_deepagents/__main__.py,sha256=GcjmqN0Ea5v8OHKMxYToasm3eCX_doSLOlpEzAi1tA
3
3
  managed_deepagents/_channel.py,sha256=-Og7QOM1yvV-yeTDOfv2CxXpR2HLY4xdX1bLrIsPi5k,5272
4
4
  managed_deepagents/_cli.py,sha256=jVaw2i1ysdRoWziMdPFmRXtKry_baYGRspyzyIeGWoU,1688
5
5
  managed_deepagents/_connector.py,sha256=Syp0SRs1oFCUUltIUmZbSNi1Ys_PxObVdiAi-I9GBzs,8040
6
- managed_deepagents/_cors.py,sha256=MKT5DQwIhCpHDOcb6RwR1XIJBsrWRbUwh0t0Q9Ur5oc,7377
6
+ managed_deepagents/_cors.py,sha256=V96RPrqewdRWG5RpEMEBnPuRq9_zF8nf4vf99k5dkuI,7597
7
7
  managed_deepagents/_eval_filesystem.py,sha256=1nuD0yn3gh19JrWNocWyPFyeJW42E7Gse3XRWCUSTAA,1399
8
8
  managed_deepagents/_extension.py,sha256=x2H1S8inkvTZQ_dr7kq0M8o8rre1FjzCDvMzItw4iyk,5318
9
9
  managed_deepagents/_identity_auth.py,sha256=M8SHwh18aQhf8QEgVfLiX0vaH6kBqW3Ic0nmuEffjrE,26866
10
- managed_deepagents/_identity_http.py,sha256=MuqhmBxkW5tnXN_Nv3NJHzIqlOHpFG7JIpMGNbnK76c,15598
10
+ managed_deepagents/_identity_http.py,sha256=aVQfZr7UKQoXF1Dry3p9fzXIj1882sEa668rvhn37i0,16029
11
11
  managed_deepagents/_identity_links.py,sha256=Z1H2Seo2KaI-vcdU3_PGM-F06wOz0IQqUP-28wqiQsA,9172
12
12
  managed_deepagents/_identity_runtime.py,sha256=9-8y7OYn2dbiYiWUjLpv-v9cA_Q3bxoPlJtogdnBdCQ,10500
13
13
  managed_deepagents/_ingress.py,sha256=mPIb1o60G_pCg4Qotwt-SUloCxY1xXfUTSyN_BPZNts,11581
@@ -24,7 +24,7 @@ managed_deepagents/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
24
24
  managed_deepagents/runtime.py,sha256=vRAFLVxoYKW-MA8C8aei-23NpS-0MRgjSn4WhezFAR8,64712
25
25
  managed_deepagents/sandbox.py,sha256=xlpcWa6CoVX6GKip2nK-0Lw-HBCoFGFYm0r4x9eYwcY,2530
26
26
  managed_deepagents/schedules.py,sha256=MtTQN4tlm1NizFDCjZZv_huGfbQx-dj9WP1dIBybCug,5237
27
- managed_deepagents/_binaries/mda.exe,sha256=_NOUU5mwn_jvsSjZsTeaOPjUsnWxnpUi6MuXmDGVydQ,3744768
27
+ managed_deepagents/_binaries/mda.exe,sha256=-wv6PdXRem67zG6ZDNvX9rqwlbVp9qJm_e3kwkY9YLk,3746816
28
28
  managed_deepagents/_channels/__init__.py,sha256=Z6eXmzaLxG09DSyJoY_CX34axcsBo9gSJ0G7pRm2D6M,1216
29
29
  managed_deepagents/_channels/assistant_text.py,sha256=f-Z3J3PlQFXZHztgBxlRoqB2LigU1Hj1YpwoXBMTR18,2171
30
30
  managed_deepagents/_channels/binding.py,sha256=6vAKbWpg-eyLErJ0SsozH4mZc50hA1NhquM63mVmWDQ,3423
@@ -64,9 +64,9 @@ managed_deepagents/identity/__init__.py,sha256=7qfGbOfQf4-5EQT6Ssrf8_CRhkihr-ENf
64
64
  managed_deepagents/identity/claims.py,sha256=prby7r_8Lww3MmoBm8PX6PsSGE3GwSHkr8mVIz_08nU,1180
65
65
  managed_deepagents/identity/options.py,sha256=x_yMbXEFR7zXyehEjDHG2qjAlukXjrRBcQLcM6IndLM,2550
66
66
  managed_deepagents/identity/supabase.py,sha256=8uobl3WCrQL_ieSXG8KTLf1th7Qjim9liZT50HeaJE0,6026
67
- managed_deepagents-0.6.2.dev3.dist-info/licenses/LICENSE,sha256=WnPZQQ608ojZUkXl7BW6VbKloIAibZiGm1K6cjeZOL8,1066
68
- managed_deepagents-0.6.2.dev3.dist-info/METADATA,sha256=XCAP38CV8pG50t8CcpfW_PvDlf48BYDLPYHcByrpCEk,12848
69
- managed_deepagents-0.6.2.dev3.dist-info/WHEEL,sha256=3I5VVWZdsFlU417aCS2bMRuerS8wsfvBq99MyatBV3A,97
70
- managed_deepagents-0.6.2.dev3.dist-info/entry_points.txt,sha256=ziZqkKuaDO3qHCjKmBhrx9cm3ok8bZ9xcEDpUTj4unM,53
71
- managed_deepagents-0.6.2.dev3.dist-info/top_level.txt,sha256=fdBo4O0Hlol_w022tTLB5ftZpamb4yJoQ3MUvjgTGfA,19
72
- managed_deepagents-0.6.2.dev3.dist-info/RECORD,,
67
+ managed_deepagents-0.6.2.dev5.dist-info/licenses/LICENSE,sha256=WnPZQQ608ojZUkXl7BW6VbKloIAibZiGm1K6cjeZOL8,1066
68
+ managed_deepagents-0.6.2.dev5.dist-info/METADATA,sha256=jJk-jx_i4yXR7vlikPQM68V2V-BeU2Ps19FSwlNcsKs,12848
69
+ managed_deepagents-0.6.2.dev5.dist-info/WHEEL,sha256=3I5VVWZdsFlU417aCS2bMRuerS8wsfvBq99MyatBV3A,97
70
+ managed_deepagents-0.6.2.dev5.dist-info/entry_points.txt,sha256=ziZqkKuaDO3qHCjKmBhrx9cm3ok8bZ9xcEDpUTj4unM,53
71
+ managed_deepagents-0.6.2.dev5.dist-info/top_level.txt,sha256=fdBo4O0Hlol_w022tTLB5ftZpamb4yJoQ3MUvjgTGfA,19
72
+ managed_deepagents-0.6.2.dev5.dist-info/RECORD,,