Commit Graph

82 Commits

Author SHA1 Message Date
Martha Schumann 981734fb99 fix: propagate useCopilotReadable context and CopilotKit properties into Python LangGraph agent state
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>
2026-04-15 18:37:51 -07:00
Markus Ecker 0f02aae198 fix: align A2UI schema format with v0.9 spec and improve path binding prompts
- Replace custom { name, props } schema format with spec-aligned inline
  catalog format (allOf + properties) so the LLM sees the same flat
  structure it must produce — eliminates "props" nesting confusion.
- Restructure generation prompts: inline literal values are the default,
  path binding is a narrow schema-driven exception for form inputs.
- Export InlineCatalogSchema type from a2ui-renderer.
2026-04-15 12:28:13 +02:00
Markus Ecker abd0d5c11c fix: add path binding schema rule to A2UI generation prompts
LLMs sometimes use path bindings (e.g. {"path": "/chartData"}) on
component properties that only accept literal values, causing silent
render failures. The new guideline tells the LLM to check the schema's
anyOf type before using path bindings.
2026-04-15 11:51:05 +02:00
Jordan Ritter bc4a173751 fix: preserve graph-owned state keys during frontend state merge (#3852)
## 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*
2026-04-14 14:06:10 -07:00
Jordan Ritter de78dfdb68 fix: sanitize NaN/Infinity values in LangGraph state before JSON serialization (#3851)
## 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*
2026-04-14 14:06:07 -07:00
Jordan Ritter fe365d3f7f fix: extract all text parts when AIMessage content is a list (#3844)
Partially addresses #1748

When Anthropic models return multi-part content lists, only the first
element was used and the rest discarded. Now iterates all parts and
concatenates text blocks, preserving the full message content.

Split from #3838.
2026-04-14 14:06:04 -07:00
Jordan Ritter 76b1d73bb8 fix: convert Pydantic BaseModel instances to dicts before serialization (#2158) (#3816)
## 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
2026-04-14 14:06:00 -07:00
Jordan Ritter 35705db3c7 fix(sdk-python): update current_graph_state after manual emit to persist across iterations
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.
2026-04-13 08:29:07 -07:00
Jordan Ritter a559406bee fix: also serialize Pydantic state in get_state() and fix implicit None return
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).
2026-04-13 08:24:10 -07:00
Jordan Ritter d0b7b6981c fix: sanitize raw event stream to prevent NaN/Infinity in JSON output
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.
2026-04-13 08:19:35 -07:00
Jordan Ritter 35ee689652 fix: preserve graph-owned state keys during frontend state merge (#2893) 2026-04-12 15:25:10 -07:00
Jordan Ritter 0e57499664 fix: sanitize NaN/Infinity values in LangGraph state before JSON serialization (#1955) 2026-04-12 15:25:03 -07:00
Jordan Ritter 2f3938036e fix: extract all text parts when AIMessage content is a list (#1748)
When Anthropic models return multi-part content lists, only the first
element was used and the rest discarded. Now iterates all parts and
concatenates text blocks, preserving the full message content.
2026-04-12 15:16:36 -07:00
Jordan Ritter eb5b98f296 fix: convert Pydantic BaseModel instances to dicts before langchain_dumps serialization (#2158) 2026-04-12 14:59:36 -07:00
Jordan Ritter ee9e9c37b8 fix(sdk-python): copilotkit_emit_state merges state instead of replacing (#3138)
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.
2026-04-12 13:21:53 -07:00
Markus Ecker 0a11a05772 feat(sdk-python): A2UI helpers and before_agent ID reuse fix
Add copilotkit.a2ui module with operation builders and prompt helpers,
fix SystemMessage ID reuse in before_agent to prevent LangGraph duplication,
add Pydantic model_dump serialization for app_context.
2026-04-08 12:50:28 -07:00
Tyler Slaton 368663dd08 fix(sdk-python): add missing import re in copilotkit_lg_middleware
The re module was used in _fix_messages_for_bedrock (re.compile) but
never imported, causing NameError at runtime when the middleware is
invoked. Bumps version to 0.1.83.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 16:42:56 -07:00
Ran Shem Tov 4073d3d035 fix: deduplicate ToolMessages and tighten adjacent-only validation for Bedrock Converse API 2026-03-20 16:14:49 -07:00
Ran Shem Tov 31a721cdae feat: re-export state streaming langgraph middleware 2026-03-19 12:58:55 +01:00
Markus Ecker d6d2e2c96a Fix Bedrock Converse API compatibility in CopilotKitMiddleware
Add _fix_messages_for_bedrock() to handle three issues caused by
after_agent restoring frontend tool_calls to the checkpoint:

1. Strip unanswered tool_calls without matching ToolMessages (Bedrock
   rejects toolUse without a corresponding toolResult)
2. Sync msg.content tool_use blocks with msg.tool_calls
3. Fix tool_use/tool_call blocks with string input/args (must be dict)
2026-03-13 12:02:05 +01:00
Ran Shemtov de02e9cef0 Merge branch 'main' into fix/2667-langgraph-agui-agent-dict-repr 2026-03-11 16:27:00 +01:00
Maxim c5ec0f8512 fix(sdk-python): guard assistant message with content check
Avoid emitting spurious empty assistant messages for tool-call-only
AIMessages (common with OpenAI models where content is empty string).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:28:26 +04:00
Maxim 3b684d914b fix(sdk-python): always emit assistant message for AIMessages with tool_calls
langchain_messages_to_copilotkit previously skipped creating the assistant
message when an AIMessage had tool_calls, causing missing context in chat
history on reconnect. Also adds ActionExecutionMessage type guard in
copilotkit_messages_to_langchain to prevent KeyError on non-tool messages
with parentMessageId.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:28:26 +04:00
Valen 95fada4490 fix(sdk-python): fix emit_messages and emit_tool_calls config not working
Fixes #2066

## Problem

`copilotkit_customize_config(config, emit_messages=False)` does not work -
TEXT_MESSAGE_* events are still emitted despite the configuration.

## Root Causes

1. **Metadata Reading Bug**: In `langgraph_agui_agent.py`, the code uses
   `getattr(raw_event, 'metadata', {})` to read metadata, but `raw_event`
   is a dict, not an object. This should use `.get()` instead.

2. **Encoder Crash Bug**: When the filtering logic works (after fixing bug #1),
   it returns `""` (empty string) to skip dispatching events. However, this
   empty string gets yielded to the event encoder which expects event objects
   with `model_dump_json()` method, causing an `AttributeError`.

## Fixes

1. Changed metadata reading to handle both dict and object cases.
2. Changed return value from `""` to `None` for filtered events.
3. Added `run()` method override to filter out `None` values before yielding
   to encoder.
2026-03-06 08:29:04 -08:00
Alem Tuzlak f4e8fdf61f Merge branch 'main' into fix/prebuilt-agent-state-streaming 2026-03-02 18:06:02 +01:00
Tyler Slaton cc8c945893 refactor(docs): optimize structure, content and navigability
Signed-off-by: Tyler Slaton <tyler@copilotkit.ai>
2026-03-02 11:30:16 -05:00
Ran Shem Tov b21db3a8fc fix: do not override predict state metadata if no cpk prefixed metadata present 2026-03-02 13:30:33 +01:00
Ran Shemtov f0a0ed5e60 feat: add app context readables to prebuilt LG agent middleware (#3155) 2026-02-06 12:49:04 +01:00
Ran Shemtov 5a24f28894 feat: create copilotkit langgraph middleware (#2928) 2026-01-09 16:46:40 +01:00
Charlie Tonneslan fb613ad07a fix(sdk-python): add dict_repr method to LangGraphAGUIAgent
Adds missing dict_repr() method to LangGraphAGUIAgent class to fix
AttributeError when SDK tries to serialize agent info.

The method was present in the parent LangGraphAgent class but not
overridden in LangGraphAGUIAgent, causing failures when calling
sdk.info() with AGUI agents in FastAPI integrations.

Fixes #2667
2025-10-27 15:37:31 -04:00
alexforrestf 8f76efc384 fix(sdk-python): compatibility with langchain v1 (#2633) (#2634) 2025-10-23 15:47:53 -04:00
Ran Shemtov a0155b03e6 fix: ensure stringified args when emitting tool calls (#2571) 2025-10-03 17:05:25 +02:00
Ran Shemtov 19cae45de6 fix: deprecate lg platform remote endpoint (#2540) 2025-09-30 12:13:30 +02:00
Ran Shemtov b7bc3a03e9 feat: pass copilot readable context to agui agents (#2426) 2025-09-15 12:37:55 +02:00
Ran Shemtov 85e09eea2b fix(sdk-python): preserve state messages on subsequent get_state calls (#2216) 2025-07-23 10:21:38 +02:00
Ran Shemtov ec6969b27a Fix/serializable state py (#2177) 2025-07-23 09:56:02 +02:00
Ran Shemtov a010b323d5 chore: use url from deployment when routing to agent (#2171) 2025-07-17 18:15:58 +02:00
Ran Shemtov df25f34d30 feat: add agui fastAPI compatible langgraph agent (#2117) 2025-07-15 19:49:15 +02:00
Ran Shemtov cf90f85aad fix: reduce checkpointer calls lg events (#2063) 2025-07-08 14:39:42 +02:00
Ran Shemtov bffb410b9f fix: consider empty array content for tool message (#2103) 2025-07-04 12:13:52 +02:00
Ran Shemtov 3f8c575363 fix: time travel regenerate (#2071) 2025-07-01 20:25:12 +02:00
Ran Shemtov c0e799e787 Fix/support langgraph 0.5.0 (#2073) 2025-06-30 23:02:48 +02:00
Suhas Deshpande 1d1c51d2f2 surface every possible errors in clean structured way (#2036) 2025-06-23 15:03:38 -07:00
Ran Shemtov 11b7a29686 fix: use active interrupt from thread instead of saving to global state (python sdk) (#2040) 2025-06-23 14:23:16 +02:00
Ran Shemtov c361a16d31 fix: fix regenerate to rerun tool call on click (#2019) 2025-06-19 18:36:33 +02:00
Suhas Deshpande a188b4f902 adds state update event to crew flow (#1963) 2025-06-09 21:29:27 -07:00
Suhas Deshpande 760db7a405 feat(crewai): Add CopilotKit integration utilities for CrewAI enterprise (#1858) 2025-06-05 14:59:11 -07:00
Ran Shemtov 9bc69d8b99 fix: fix reading and spreading configs in langgraph stream events (#1904) 2025-05-30 11:08:08 +02:00
Nick Stanish 9b26f12ba0 fix:python Invert condition for merge_state deprecation check (#1749) 2025-05-23 13:20:08 -07:00
Suhas Deshpande d40e0027a3 udpates crewai to 0.118.0 (#1743) 2025-05-12 08:29:47 -07:00