Two silent failures in the Python SDK prevented frontend context from reaching the agent:
1. langgraph_default_merge_state rebuilt copilotkit as {actions} only, dropping the
useCopilotReadable items the TypeScript runtime had placed in state.copilotkit.context.
2. CopilotKitContext.properties were never forwarded through execute_agent → agent.execute(),
so <CopilotKit properties={...} /> values never reached state.copilotkit.properties.
Both fields now land cleanly under state["copilotkit"] on every agent invocation.
Also adds tests, a showcase example, and a new docs page.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
## Summary
- During frontend state merge in LangGraph agent, preserve keys that are
owned by the graph (not set by the frontend)
- Prevents graph-computed state from being overwritten when frontend
state is merged back
Closes#2893
---
*Split from #3847*
## Summary
- Add sanitization pass over LangGraph agent state to replace NaN and
Infinity with null before JSON serialization
- Prevents `ValueError: Out of range float values are not JSON
compliant` in Python SDK
Closes#1955
---
*Split from #3847*
## Summary
Fixes#2158
Pydantic `BaseModel` instances in LangGraph agent state are not
serializable by `langchain_dumps`. This adds a recursive
`_serialize_state` helper that converts `BaseModel` instances to dicts
before serialization, preventing crashes when state contains Pydantic
models.
**Additional fixes (second commit):**
- Also applies `_serialize_state` to the `get_state()` code path, which
was missed in the original fix but has the same bug
- Fixes `filter_state_on_schema_keys` returning `None` implicitly when
schema keys are not set (the `except` branch returned `state` but the
non-matching `if` branch did not)
- Adds 17 tests covering `_serialize_state`, `_emit_state_sync_event`,
and `get_state` with Pydantic models
## Merge order note
This PR and #3851 both modify
`sdk-python/copilotkit/langgraph_agent.py`. Both add a helper function
at module level and call it from `_emit_state_sync_event` and
`get_state`. Whichever merges second will need a trivial rebase. No
semantic conflict — the fixes are complementary (this one handles
Pydantic models, #3851 handles NaN/Infinity).
## Test plan
- [x] 17 unit tests covering both code paths
- [x] Red-green verified: `get_state` tests fail without fix, pass with
it
- [x] Existing test suite (test_emit_filtering) still passes
- [x] Verify LangGraph agent with Pydantic BaseModel state serializes
correctly
- [x] Verify non-Pydantic state is unaffected
The _merge_emit_state call merges emitted state with current_graph_state
into manually_emitted_state, but the `continue` statement skips the
later current_graph_state.update(updated_state). Without this update,
the next manual emit merges against stale current_graph_state and loses
keys from the previous emit.
Also guards the update call against non-dict values from _merge_emit_state
to prevent TypeError on edge-case non-dict emits.
The original fix only covered _emit_state_sync_event but missed the
get_state() code path, which also returns state containing Pydantic
BaseModel instances to callers that will JSON-serialize downstream.
Also fixes filter_state_on_schema_keys returning None implicitly when
schema keys are not set (the except branch returned state but the
non-matching if branch did not).
Adds 17 tests covering _serialize_state, _emit_state_sync_event, and
get_state with Pydantic models (nested, lists, plain dicts, empty).
The _sanitize_for_json function was applied to state sync events and
get_state responses but not to the raw event stream yielded at line 507.
Events with NaN/Infinity float values in their data payloads would
produce invalid JSON (literal NaN) that downstream parsers cannot handle.
Sequential emit_state calls with different keys now preserve all keys
in the snapshot. Previously, each call would replace the entire
manually_emitted_state, losing keys from earlier calls.
* fix: add new langgraph streaming protocol
* fix: go to the next chunk after receiving a manually emitted state
* chore: update all packages
---------
Co-authored-by: Markus Ecker <markus.ecker@gmail.com>
* feat(runtime): rename remoteActions argument to remoteEndpoints
* feat(remote-actions): integrate langgraph-cloud as a remote action for CoAgents
* feat(runtime): rename remoteActions argument to remoteEndpoints
* feat(remote-actions): integrate langgraph-cloud as a remote action for CoAgents
* feat(sdk-js): add SDK for LangGraph JS support
---------
Co-authored-by: Markus Ecker <markus.ecker@gmail.com>
Co-authored-by: Ariel Weinberger <weinberger.ariel@gmail.com>