copilotkit 0.1.90__tar.gz → 0.1.91__tar.gz

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 (28) hide show
  1. {copilotkit-0.1.90 → copilotkit-0.1.91}/PKG-INFO +2 -2
  2. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/copilotkit_lg_middleware.py +97 -2
  3. {copilotkit-0.1.90 → copilotkit-0.1.91}/pyproject.toml +1 -1
  4. {copilotkit-0.1.90 → copilotkit-0.1.91}/README.md +0 -0
  5. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/__init__.py +0 -0
  6. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/a2ui.py +0 -0
  7. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/action.py +0 -0
  8. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/agent.py +0 -0
  9. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/crewai/__init__.py +0 -0
  10. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/crewai/copilotkit_integration.py +0 -0
  11. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/crewai/crewai_agent.py +0 -0
  12. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/crewai/crewai_sdk.py +0 -0
  13. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/exc.py +0 -0
  14. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/header_propagation.py +0 -0
  15. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/html.py +0 -0
  16. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/integrations/__init__.py +0 -0
  17. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/integrations/fastapi.py +0 -0
  18. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/langchain.py +0 -0
  19. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/langgraph.py +0 -0
  20. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/langgraph_agui_agent.py +0 -0
  21. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/logging.py +0 -0
  22. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/parameter.py +0 -0
  23. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/protocol.py +0 -0
  24. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/py.typed +0 -0
  25. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/runloop.py +0 -0
  26. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/sdk.py +0 -0
  27. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/types.py +0 -0
  28. {copilotkit-0.1.90 → copilotkit-0.1.91}/copilotkit/utils.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: copilotkit
3
- Version: 0.1.90
3
+ Version: 0.1.91
4
4
  Summary: CopilotKit python SDK
5
5
  License: MIT
6
6
  Keywords: copilot,copilotkit,langgraph,langchain,ai,langsmith,langserve
@@ -16,7 +16,7 @@ Example:
16
16
 
17
17
  import json
18
18
  import re
19
- from typing import Any, Callable, Awaitable, ClassVar, Iterable, List, Union
19
+ from typing import Any, Callable, Awaitable, ClassVar, Iterable, Union
20
20
 
21
21
  from langchain_core.messages import AIMessage, SystemMessage, ToolMessage
22
22
  from langchain.agents.middleware import (
@@ -27,7 +27,7 @@ from langchain.agents.middleware import (
27
27
  )
28
28
  from langgraph.runtime import Runtime
29
29
 
30
- from .header_propagation import install_httpx_hook
30
+ from .header_propagation import install_httpx_hook, set_forwarded_headers
31
31
  from .langgraph import CopilotKitProperties
32
32
 
33
33
  # Track which httpx clients already have the header-propagation hook installed
@@ -35,6 +35,99 @@ from .langgraph import CopilotKitProperties
35
35
  _hooked_clients: set[int] = set()
36
36
 
37
37
 
38
+ def _extract_forwarded_headers_from_config() -> None:
39
+ """Extract raw ``x-*`` headers from the current LangGraph RunnableConfig and
40
+ push them into the header-propagation ContextVar so the httpx hook can
41
+ forward them on outgoing LLM requests.
42
+
43
+ When an agent runs inside **langgraph-api** with
44
+ ``LANGGRAPH_HTTP={"configurable_headers":{"include":["x-*"]}}``,
45
+ the server copies inbound HTTP ``x-*`` headers into
46
+ ``config["configurable"]`` as individual keys (e.g.
47
+ ``configurable["x-aimock-context"] = "value"``). This function reads those
48
+ keys and calls :func:`set_forwarded_headers` so they propagate to the
49
+ underlying LLM provider SDK via the httpx event hook.
50
+
51
+ Precedence: the wrapper dict ``copilotkit_forwarded_headers`` (if present)
52
+ takes priority over raw ``x-*`` keys. Raw keys are only used when the
53
+ wrapper dict is absent or does not contain a given header.
54
+
55
+ Safe to call outside a runnable context (e.g. in unit tests) — silently
56
+ returns without doing anything if ``get_config()`` raises.
57
+ """
58
+ try:
59
+ from langgraph.config import (
60
+ get_config,
61
+ ) # local import to avoid hard dep at module level
62
+
63
+ config = get_config()
64
+ except ImportError:
65
+ return
66
+ except RuntimeError:
67
+ # No active runnable context — clear the ContextVar so stale headers
68
+ # from a prior request in the same async context do not leak through.
69
+ set_forwarded_headers({})
70
+ return
71
+
72
+ try:
73
+ headers: dict[str, str] = {}
74
+
75
+ # Sources to scan: config["context"] (LangGraph >=0.6.0) and
76
+ # config["configurable"] (all versions).
77
+ context = config.get("context") or {}
78
+ configurable = config.get("configurable") or {}
79
+
80
+ # 1) Wrapper-dict path (highest priority): these are headers that
81
+ # CopilotKit explicitly bundled under a known key. Process context
82
+ # first with first-write-wins so context takes precedence over
83
+ # configurable (LangGraph >=0.6.0 introduced context as the newer
84
+ # preferred mechanism).
85
+ for src in (context, configurable):
86
+ if not isinstance(src, dict):
87
+ continue
88
+ wrapper = src.get("copilotkit_forwarded_headers")
89
+ if isinstance(wrapper, dict):
90
+ for k, v in wrapper.items():
91
+ lk = k.lower() if isinstance(k, str) else k
92
+ if isinstance(k, str) and isinstance(v, str) and lk not in headers:
93
+ headers[lk] = v
94
+
95
+ # 2) Raw x-* keys directly on context and configurable. These appear
96
+ # when langgraph-api's configurable_headers mechanism forwards inbound
97
+ # HTTP headers as individual configurable entries.
98
+ for src in (context, configurable):
99
+ if not isinstance(src, dict):
100
+ continue
101
+ for k, v in src.items():
102
+ if (
103
+ isinstance(k, str)
104
+ and k.lower().startswith("x-")
105
+ and isinstance(v, str)
106
+ ):
107
+ # Don't overwrite wrapper-dict values (wrapper > raw).
108
+ # Lowercase at insertion so precedence checks are
109
+ # deterministic regardless of source casing.
110
+ lk = k.lower()
111
+ if lk not in headers:
112
+ headers[lk] = v
113
+
114
+ # Always set the ContextVar — even with an empty dict — so stale
115
+ # headers from previous calls in the same async context do not leak
116
+ # into this one.
117
+ set_forwarded_headers(headers)
118
+ except Exception as e:
119
+ # Header forwarding is best-effort. Never block the LLM call.
120
+ # Clear the ContextVar so stale headers from a prior request do not
121
+ # leak through on failure.
122
+ set_forwarded_headers({})
123
+ import logging
124
+
125
+ logging.getLogger(__name__).debug(
126
+ "Header forwarding extraction failed; continuing without forwarded headers: %s",
127
+ e,
128
+ )
129
+
130
+
38
131
  def _ensure_httpx_hook(model: Any) -> None:
39
132
  """Install the header-propagation httpx hook on a LangChain chat model's
40
133
  underlying HTTP client(s), if present. No-op for models that don't expose
@@ -172,6 +265,7 @@ class CopilotKitMiddleware(AgentMiddleware[StateSchema, Any]):
172
265
  request: ModelRequest,
173
266
  handler: Callable[[ModelRequest], ModelResponse],
174
267
  ) -> ModelResponse:
268
+ _extract_forwarded_headers_from_config()
175
269
  _ensure_httpx_hook(request.model)
176
270
  request = self._apply_state_note(request)
177
271
  frontend_tools = request.state.get("copilotkit", {}).get("actions", [])
@@ -361,6 +455,7 @@ class CopilotKitMiddleware(AgentMiddleware[StateSchema, Any]):
361
455
  request: ModelRequest,
362
456
  handler: Callable[[ModelRequest], Awaitable[ModelResponse]],
363
457
  ) -> ModelResponse:
458
+ _extract_forwarded_headers_from_config()
364
459
  _ensure_httpx_hook(request.model)
365
460
  self._fix_messages_for_bedrock(request.messages)
366
461
  request = self._apply_state_note(request)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "copilotkit"
3
- version = "0.1.90"
3
+ version = "0.1.91"
4
4
  description = "CopilotKit python SDK"
5
5
  authors = ["Markus Ecker <markus.ecker@gmail.com>"]
6
6
  license = "MIT"
File without changes