diff --git a/docs/sdk/python/core/events.mdx b/docs/sdk/python/core/events.mdx index 6d5cdc93..034c7797 100644 --- a/docs/sdk/python/core/events.mdx +++ b/docs/sdk/python/core/events.mdx @@ -48,15 +48,15 @@ shared across all event types. ```python class BaseEvent(ConfiguredBaseModel): type: EventType - timestamp: Optional[int] = None - raw_event: Optional[Any] = None + timestamp: int | None = None + raw_event: Any = None ``` | Property | Type | Description | | ----------- | --------------- | ----------------------------------------------------- | | `type` | `EventType` | The type of event (discriminator field for the union) | -| `timestamp` | `Optional[int]` | Timestamp when the event was created | -| `raw_event` | `Optional[Any]` | Original event data if this event was transformed | +| `timestamp` | `int | None` | Timestamp when the event was created | +| `raw_event` | `Any` | Original event data if this event was transformed | ## Lifecycle Events @@ -91,14 +91,14 @@ class RunFinishedEvent(BaseEvent): type: Literal[EventType.RUN_FINISHED] thread_id: str run_id: str - result: Optional[Any] = None + result: Any = None ``` | Property | Type | Description | | ----------- | --------------- | ------------------------------ | | `thread_id` | `str` | ID of the conversation thread | | `run_id` | `str` | ID of the agent run | -| `result` | `Optional[Any]` | Result data from the agent run | +| `result` | `Any` | Result data from the agent run | ### RunErrorEvent @@ -110,13 +110,13 @@ Signals an error during an agent run. class RunErrorEvent(BaseEvent): type: Literal[EventType.RUN_ERROR] message: str - code: Optional[str] = None + code: str | None = None ``` | Property | Type | Description | | --------- | --------------- | ------------- | | `message` | `str` | Error message | -| `code` | `Optional[str]` | Error code | +| `code` | `str | None` | Error code | ### StepStartedEvent @@ -225,14 +225,14 @@ class ToolCallStartEvent(BaseEvent): type: Literal[EventType.TOOL_CALL_START] tool_call_id: str tool_call_name: str - parent_message_id: Optional[str] = None + parent_message_id: str | None = None ``` | Property | Type | Description | | ------------------- | --------------- | ----------------------------------- | | `tool_call_id` | `str` | Unique identifier for the tool call | | `tool_call_name` | `str` | Name of the tool being called | -| `parent_message_id` | `Optional[str]` | ID of the parent message | +| `parent_message_id` | `str | None` | ID of the parent message | ### ToolCallArgsEvent @@ -280,7 +280,7 @@ class ToolCallResultEvent(BaseEvent): type: Literal[EventType.TOOL_CALL_RESULT] tool_call_id: str content: str - role: Optional[Literal["tool"]] = None + role: Literal["tool"] | None = None ``` | Property | Type | Description | @@ -288,7 +288,7 @@ class ToolCallResultEvent(BaseEvent): | `message_id` | `str` | ID of the conversation message this result belongs to | | `tool_call_id` | `str` | Matches the ID from the corresponding ToolCallStartEvent | | `content` | `str` | The actual result/output content from the tool execution | -| `role` | `Optional[Literal["tool"]]` | Optional role identifier, typically "tool" for tool results | +| `role` | `Literal["tool"] | None` | Optional role identifier, typically "tool" for tool results | ## State Management Events @@ -354,13 +354,13 @@ Used to pass through events from external systems. class RawEvent(BaseEvent): type: Literal[EventType.RAW] event: Any - source: Optional[str] = None + source: str | None = None ``` | Property | Type | Description | | -------- | --------------- | ------------------- | | `event` | `Any` | Original event data | -| `source` | `Optional[str]` | Source of the event | +| `source` | `str | None` | Source of the event | ### CustomEvent @@ -388,25 +388,27 @@ The SDK uses Pydantic's discriminated unions for event validation: ```python Event = Annotated[ - Union[ - TextMessageStartEvent, - TextMessageContentEvent, - TextMessageEndEvent, - ToolCallStartEvent, - ToolCallArgsEvent, - ToolCallEndEvent, - ToolCallResultEvent, - StateSnapshotEvent, - StateDeltaEvent, - MessagesSnapshotEvent, - RawEvent, - CustomEvent, - RunStartedEvent, - RunFinishedEvent, - RunErrorEvent, - StepStartedEvent, - StepFinishedEvent, - ], + TextMessageStartEvent | + TextMessageContentEvent | + TextMessageEndEvent | + TextMessageChunkEvent | + ToolCallStartEvent | + ToolCallArgsEvent | + ToolCallEndEvent | + ToolCallChunkEvent | + ToolCallResultEvent | + ThinkingStartEvent | + ThinkingEndEvent | + StateSnapshotEvent | + StateDeltaEvent | + MessagesSnapshotEvent | + RawEvent | + CustomEvent | + RunStartedEvent | + RunFinishedEvent | + RunErrorEvent | + StepStartedEvent | + StepFinishedEvent, Field(discriminator="type") ] ``` diff --git a/docs/sdk/python/core/types.mdx b/docs/sdk/python/core/types.mdx index 836570b6..6a2fbfd8 100644 --- a/docs/sdk/python/core/types.mdx +++ b/docs/sdk/python/core/types.mdx @@ -71,7 +71,7 @@ class DeveloperMessage(BaseMessage): | `id` | `str` | Unique identifier for the message | | `role` | `Literal["developer"]` | Role of the message sender, fixed as "developer" | | `content` | `str` | Text content of the message (required) | -| `name` | `Optional[str]` | Optional name of the sender | +| `name` | `str | None` | Optional name of the sender | ### SystemMessage @@ -90,7 +90,7 @@ class SystemMessage(BaseMessage): | `id` | `str` | Unique identifier for the message | | `role` | `Literal["system"]` | Role of the message sender, fixed as "system" | | `content` | `str` | Text content of the message (required) | -| `name` | `Optional[str]` | Optional name of the sender | +| `name` | `str | None` | Optional name of the sender | ### AssistantMessage @@ -101,17 +101,17 @@ Represents a message from an assistant. ```python class AssistantMessage(BaseMessage): role: Literal["assistant"] - content: Optional[str] = None - tool_calls: Optional[List[ToolCall]] = None + content: str | None = None + tool_calls: List[ToolCall] | None = None ``` | Property | Type | Description | | ------------ | -------------------------- | ------------------------------------------------ | | `id` | `str` | Unique identifier for the message | | `role` | `Literal["assistant"]` | Role of the message sender, fixed as "assistant" | -| `content` | `Optional[str]` | Text content of the message | -| `name` | `Optional[str]` | Name of the sender | -| `tool_calls` | `Optional[List[ToolCall]]` | Tool calls made in this message | +| `content` | `str | None`. | Text content of the message | +| `name` | `str | None` | Name of the sender | +| `tool_calls` | `List[ToolCall] | None` | Tool calls made in this message | ### UserMessage @@ -130,7 +130,7 @@ class UserMessage(BaseMessage): | `id` | `str` | Unique identifier for the message | | `role` | `Literal["user"]` | Role of the message sender, fixed as "user" | | `content` | `str` | Text content of the message (required) | -| `name` | `Optional[str]` | Optional name of the sender | +| `name` | `str | None` | Optional name of the sender | ### ToolMessage @@ -161,7 +161,7 @@ A union type representing any type of message in the system. ```python Message = Annotated[ - Union[DeveloperMessage, SystemMessage, AssistantMessage, UserMessage, ToolMessage], + DeveloperMessage | SystemMessage | AssistantMessage | UserMessage | ToolMessage, Field(discriminator="role") ] ``` diff --git a/python-sdk/ag_ui/__init__.py b/python-sdk/ag_ui/__init__.py new file mode 100644 index 00000000..fdf72ee0 --- /dev/null +++ b/python-sdk/ag_ui/__init__.py @@ -0,0 +1,3 @@ +""" +Agent User Interaction Protocol Python SDK +""" diff --git a/python-sdk/ag_ui/core/__init__.py b/python-sdk/ag_ui/core/__init__.py index 7e909ad5..33985d39 100644 --- a/python-sdk/ag_ui/core/__init__.py +++ b/python-sdk/ag_ui/core/__init__.py @@ -2,6 +2,8 @@ This module contains the core types and events for the Agent User Interaction Protocol. """ +from __future__ import annotations + from ag_ui.core.events import ( EventType, BaseEvent, diff --git a/python-sdk/ag_ui/core/events.py b/python-sdk/ag_ui/core/events.py index af1415d7..c1ee3707 100644 --- a/python-sdk/ag_ui/core/events.py +++ b/python-sdk/ag_ui/core/events.py @@ -2,8 +2,10 @@ This module contains the event types for the Agent User Interaction Protocol Python SDK. """ +from __future__ import annotations + from enum import Enum -from typing import Annotated, Any, List, Literal, Optional, Union +from typing import Annotated, Any, List, Literal from pydantic import Field @@ -45,8 +47,8 @@ class BaseEvent(ConfiguredBaseModel): Base event for all events in the Agent User Interaction Protocol. """ type: EventType - timestamp: Optional[int] = None - raw_event: Optional[Any] = None + timestamp: int | None = None + raw_event: Any = None class TextMessageStartEvent(BaseEvent): @@ -79,32 +81,28 @@ class TextMessageChunkEvent(BaseEvent): Event containing a chunk of text message content. """ type: Literal[EventType.TEXT_MESSAGE_CHUNK] = EventType.TEXT_MESSAGE_CHUNK # pyright: ignore[reportIncompatibleVariableOverride] - message_id: Optional[str] = None - role: Optional[Literal["assistant"]] = None - delta: Optional[str] = None + message_id: str | None = None + role: Literal["assistant"] | None = None + delta: str | None = None class ThinkingTextMessageStartEvent(BaseEvent): """ Event indicating the start of a thinking text message. """ - type: Literal[EventType.THINKING_TEXT_MESSAGE_START] + type: Literal[EventType.THINKING_TEXT_MESSAGE_START] = EventType.THINKING_TEXT_MESSAGE_START # pyright: ignore[reportIncompatibleVariableOverride] class ThinkingTextMessageContentEvent(BaseEvent): """ Event indicating a piece of a thinking text message. """ - type: Literal[EventType.THINKING_TEXT_MESSAGE_CONTENT] - delta: str # This should not be an empty string - - def model_post_init(self, __context): - if len(self.delta) == 0: - raise ValueError("Delta must not be an empty string") + type: Literal[EventType.THINKING_TEXT_MESSAGE_CONTENT] = EventType.THINKING_TEXT_MESSAGE_CONTENT # pyright: ignore[reportIncompatibleVariableOverride] + delta: str = Field(min_length=1) class ThinkingTextMessageEndEvent(BaseEvent): """ Event indicating the end of a thinking text message. """ - type: Literal[EventType.THINKING_TEXT_MESSAGE_END] + type: Literal[EventType.THINKING_TEXT_MESSAGE_END] = EventType.THINKING_TEXT_MESSAGE_END # pyright: ignore[reportIncompatibleVariableOverride] class ToolCallStartEvent(BaseEvent): """ @@ -113,7 +111,7 @@ class ToolCallStartEvent(BaseEvent): type: Literal[EventType.TOOL_CALL_START] = EventType.TOOL_CALL_START # pyright: ignore[reportIncompatibleVariableOverride] tool_call_id: str tool_call_name: str - parent_message_id: Optional[str] = None + parent_message_id: str | None = None class ToolCallArgsEvent(BaseEvent): @@ -137,33 +135,33 @@ class ToolCallChunkEvent(BaseEvent): Event containing a chunk of tool call content. """ type: Literal[EventType.TOOL_CALL_CHUNK] = EventType.TOOL_CALL_CHUNK # pyright: ignore[reportIncompatibleVariableOverride] - tool_call_id: Optional[str] = None - tool_call_name: Optional[str] = None - parent_message_id: Optional[str] = None - delta: Optional[str] = None + tool_call_id: str | None = None + tool_call_name: str | None = None + parent_message_id: str | None = None + delta: str | None = None class ToolCallResultEvent(BaseEvent): """ Event containing the result of a tool call. """ message_id: str - type: Literal[EventType.TOOL_CALL_RESULT] + type: Literal[EventType.TOOL_CALL_RESULT] = EventType.TOOL_CALL_RESULT # pyright: ignore[reportIncompatibleVariableOverride] tool_call_id: str content: str - role: Optional[Literal["tool"]] = None + role: Literal["tool"] | None = None class ThinkingStartEvent(BaseEvent): """ Event indicating the start of a thinking step event. """ - type: Literal[EventType.THINKING_START] - title: Optional[str] = None + type: Literal[EventType.THINKING_START] = EventType.THINKING_START # pyright: ignore[reportIncompatibleVariableOverride] + title: str | None = None class ThinkingEndEvent(BaseEvent): """ Event indicating the end of a thinking step event. """ - type: Literal[EventType.THINKING_END] + type: Literal[EventType.THINKING_END] = EventType.THINKING_END # pyright: ignore[reportIncompatibleVariableOverride] class StateSnapshotEvent(BaseEvent): """ @@ -195,7 +193,7 @@ class RawEvent(BaseEvent): """ type: Literal[EventType.RAW] = EventType.RAW # pyright: ignore[reportIncompatibleVariableOverride] event: Any - source: Optional[str] = None + source: str | None = None class CustomEvent(BaseEvent): @@ -223,7 +221,7 @@ class RunFinishedEvent(BaseEvent): type: Literal[EventType.RUN_FINISHED] = EventType.RUN_FINISHED # pyright: ignore[reportIncompatibleVariableOverride] thread_id: str run_id: str - result: Optional[Any] = None + result: Any = None class RunErrorEvent(BaseEvent): @@ -232,7 +230,7 @@ class RunErrorEvent(BaseEvent): """ type: Literal[EventType.RUN_ERROR] = EventType.RUN_ERROR # pyright: ignore[reportIncompatibleVariableOverride] message: str - code: Optional[str] = None + code: str | None = None class StepStartedEvent(BaseEvent): @@ -252,26 +250,26 @@ class StepFinishedEvent(BaseEvent): Event = Annotated[ - Union[ - TextMessageStartEvent, - TextMessageContentEvent, - TextMessageEndEvent, - TextMessageChunkEvent, - ToolCallStartEvent, - ToolCallArgsEvent, - ToolCallEndEvent, - ToolCallChunkEvent, - ToolCallResultEvent, - StateSnapshotEvent, - StateDeltaEvent, - MessagesSnapshotEvent, - RawEvent, - CustomEvent, - RunStartedEvent, - RunFinishedEvent, - RunErrorEvent, - StepStartedEvent, - StepFinishedEvent, - ], + TextMessageStartEvent | + TextMessageContentEvent | + TextMessageEndEvent | + TextMessageChunkEvent | + ToolCallStartEvent | + ToolCallArgsEvent | + ToolCallEndEvent | + ToolCallChunkEvent | + ToolCallResultEvent | + ThinkingStartEvent | + ThinkingEndEvent | + StateSnapshotEvent | + StateDeltaEvent | + MessagesSnapshotEvent | + RawEvent | + CustomEvent | + RunStartedEvent | + RunFinishedEvent | + RunErrorEvent | + StepStartedEvent | + StepFinishedEvent, Field(discriminator="type") ] diff --git a/python-sdk/ag_ui/core/types.py b/python-sdk/ag_ui/core/types.py index 0cbeddc5..ffc54978 100644 --- a/python-sdk/ag_ui/core/types.py +++ b/python-sdk/ag_ui/core/types.py @@ -1,8 +1,9 @@ """ This module contains the types for the Agent User Interaction Protocol Python SDK. """ +from __future__ import annotations -from typing import Annotated, Any, List, Literal, Optional, Union +from typing import Annotated, Any, List, Literal from pydantic import BaseModel, ConfigDict, Field from pydantic.alias_generators import to_camel @@ -42,8 +43,8 @@ class BaseMessage(ConfiguredBaseModel): """ id: str role: str - content: Optional[str] = None - name: Optional[str] = None + content: str | None = None + name: str | None = None class DeveloperMessage(BaseMessage): @@ -51,7 +52,7 @@ class DeveloperMessage(BaseMessage): A developer message. """ role: Literal["developer"] = "developer" # pyright: ignore[reportIncompatibleVariableOverride] - content: str + content: str # pyright: ignore[reportIncompatibleVariableOverride,reportGeneralTypeIssues] class SystemMessage(BaseMessage): @@ -59,7 +60,7 @@ class SystemMessage(BaseMessage): A system message. """ role: Literal["system"] = "system" # pyright: ignore[reportIncompatibleVariableOverride] - content: str + content: str # pyright: ignore[reportIncompatibleVariableOverride,reportGeneralTypeIssues] class AssistantMessage(BaseMessage): @@ -67,7 +68,7 @@ class AssistantMessage(BaseMessage): An assistant message. """ role: Literal["assistant"] = "assistant" # pyright: ignore[reportIncompatibleVariableOverride] - tool_calls: Optional[List[ToolCall]] = None + tool_calls: List[ToolCall] | None = None class UserMessage(BaseMessage): @@ -75,7 +76,7 @@ class UserMessage(BaseMessage): A user message. """ role: Literal["user"] = "user" # pyright: ignore[reportIncompatibleVariableOverride] - content: str + content: str # pyright: ignore[reportIncompatibleVariableOverride,reportGeneralTypeIssues] class ToolMessage(ConfiguredBaseModel): @@ -89,7 +90,7 @@ class ToolMessage(ConfiguredBaseModel): Message = Annotated[ - Union[DeveloperMessage, SystemMessage, AssistantMessage, UserMessage, ToolMessage], + DeveloperMessage | SystemMessage | AssistantMessage | UserMessage | ToolMessage, Field(discriminator="role") ] diff --git a/python-sdk/ag_ui/encoder/__init__.py b/python-sdk/ag_ui/encoder/__init__.py index 030bcc0b..4ae17bc3 100644 --- a/python-sdk/ag_ui/encoder/__init__.py +++ b/python-sdk/ag_ui/encoder/__init__.py @@ -2,6 +2,8 @@ This module contains the EventEncoder class. """ +from __future__ import annotations + from ag_ui.encoder.encoder import EventEncoder, AGUI_MEDIA_TYPE __all__ = ["EventEncoder", "AGUI_MEDIA_TYPE"] diff --git a/python-sdk/ag_ui/encoder/encoder.py b/python-sdk/ag_ui/encoder/encoder.py index f840e3bb..14138cc5 100644 --- a/python-sdk/ag_ui/encoder/encoder.py +++ b/python-sdk/ag_ui/encoder/encoder.py @@ -2,7 +2,13 @@ This module contains the EventEncoder class """ -from ag_ui.core.events import BaseEvent +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from ag_ui.core.events import BaseEvent + AGUI_MEDIA_TYPE = "application/vnd.ag-ui.event+proto" @@ -10,8 +16,11 @@ class EventEncoder: """ Encodes Agent User Interaction events. """ - def __init__(self, accept: str = None): - pass + def __init__(self, accept: str | None = None) -> None: + """ + Initializes the EventEncoder. + """ + self.accept = accept def get_content_type(self) -> str: """ diff --git a/python-sdk/tests/test_encoder.py b/python-sdk/tests/test_encoder.py index 2d466c5a..1be941b9 100644 --- a/python-sdk/tests/test_encoder.py +++ b/python-sdk/tests/test_encoder.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import unittest import json from datetime import datetime diff --git a/python-sdk/tests/test_events.py b/python-sdk/tests/test_events.py index c73a2537..cbe6f165 100644 --- a/python-sdk/tests/test_events.py +++ b/python-sdk/tests/test_events.py @@ -1,9 +1,10 @@ +from __future__ import annotations + import unittest -import json from datetime import datetime -from pydantic import ValidationError, TypeAdapter +from pydantic import TypeAdapter -from ag_ui.core.types import Message, UserMessage, AssistantMessage, FunctionCall, ToolCall +from ag_ui.core.types import UserMessage, AssistantMessage, FunctionCall, ToolCall from ag_ui.core.events import ( EventType, BaseEvent, diff --git a/python-sdk/tests/test_types.py b/python-sdk/tests/test_types.py index e534aa5a..23b3eca3 100644 --- a/python-sdk/tests/test_types.py +++ b/python-sdk/tests/test_types.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import unittest from pydantic import ValidationError from pydantic import TypeAdapter diff --git a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/endpoint.py b/typescript-sdk/integrations/crewai/python/ag_ui_crewai/endpoint.py index 73c492b6..f1df3fb4 100644 --- a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/endpoint.py +++ b/typescript-sdk/integrations/crewai/python/ag_ui_crewai/endpoint.py @@ -1,9 +1,11 @@ """ AG-UI FastAPI server for CrewAI. """ +from __future__ import annotations + import copy import asyncio -from typing import List, Optional +from typing import List from fastapi import FastAPI, Request from fastapi.responses import StreamingResponse @@ -60,7 +62,7 @@ async def create_queue(flow: object) -> asyncio.Queue: return queue -def get_queue(flow: object) -> Optional[asyncio.Queue]: +def get_queue(flow: object) -> asyncio.Queue | None: """Get the queue for a flow.""" queue_id = id(flow) # not using a lock here should be fine diff --git a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/predictive_state_updates.py b/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/predictive_state_updates.py index f933d52d..83b55616 100644 --- a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/predictive_state_updates.py +++ b/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/predictive_state_updates.py @@ -2,9 +2,10 @@ A demo of predictive state updates. """ +from __future__ import annotations + import json import uuid -from typing import Optional from litellm import completion from crewai.flow.flow import Flow, start, router, listen from ..sdk import ( @@ -43,7 +44,7 @@ class AgentState(CopilotKitState): """ The state of the agent. """ - document: Optional[str] = None + document: str | None = None class PredictiveStateUpdatesFlow(Flow[AgentState]): """ diff --git a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/shared_state.py b/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/shared_state.py index ed8dce9e..b3985000 100644 --- a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/shared_state.py +++ b/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/shared_state.py @@ -2,9 +2,11 @@ A demo of shared state between the agent and CopilotKit. """ +from __future__ import annotations + import json from enum import Enum -from typing import List, Optional +from typing import List from litellm import completion from pydantic import BaseModel, Field from crewai.flow.flow import Flow, start, router, listen @@ -119,7 +121,7 @@ class AgentState(CopilotKitState): """ The state of the recipe. """ - recipe: Optional[Recipe] = None + recipe: Recipe | None = None class SharedStateFlow(Flow[AgentState]): """ @@ -132,7 +134,7 @@ async def start_flow(self): """ This is the entry point for the flow. """ - print(f"start_flow") + print("start_flow") print(f"self.state: {self.state}") @router(start_flow) diff --git a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/sdk.py b/typescript-sdk/integrations/crewai/python/ag_ui_crewai/sdk.py index be2c714b..f56333de 100644 --- a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/sdk.py +++ b/typescript-sdk/integrations/crewai/python/ag_ui_crewai/sdk.py @@ -2,8 +2,10 @@ This is a placeholder for the copilotkit_stream function. """ +from __future__ import annotations + import uuid -from typing import List, Any, Optional, Mapping, Dict, Literal, TypedDict +from typing import List, Any, Mapping, Dict, Literal, TypedDict from litellm.types.utils import ( ModelResponse, Choices, @@ -39,7 +41,7 @@ class PredictStateConfig(TypedDict): Predict State Config """ tool_name: str - tool_argument: Optional[str] + tool_argument: str | None async def copilotkit_predict_state( config: Dict[str, PredictStateConfig] @@ -166,7 +168,7 @@ async def copilotkit_stream(response): async def _copilotkit_stream_custom_stream_wrapper(response: CustomStreamWrapper): flow = flow_context.get(None) - message_id: Optional[str] = None + message_id: str | None = None tool_call_id: str = "" content = "" created = 0 diff --git a/typescript-sdk/integrations/langgraph/examples/agents/agentic_chat/agent.py b/typescript-sdk/integrations/langgraph/examples/agents/agentic_chat/agent.py index e09c224a..226c5744 100644 --- a/typescript-sdk/integrations/langgraph/examples/agents/agentic_chat/agent.py +++ b/typescript-sdk/integrations/langgraph/examples/agents/agentic_chat/agent.py @@ -2,14 +2,15 @@ A simple agentic chat flow using LangGraph instead of CrewAI. """ -from typing import Dict, List, Any, Optional +from __future__ import annotations + +from typing import List, Any # Updated imports for LangGraph from langchain_core.runnables import RunnableConfig from langgraph.graph import StateGraph, END, START from langgraph.graph import MessagesState from langgraph.types import Command -from typing_extensions import Literal from langchain_openai import ChatOpenAI from langchain_core.messages import SystemMessage diff --git a/typescript-sdk/integrations/langgraph/examples/agents/agentic_generative_ui/agent.py b/typescript-sdk/integrations/langgraph/examples/agents/agentic_generative_ui/agent.py index c46fb6b9..b1f00140 100644 --- a/typescript-sdk/integrations/langgraph/examples/agents/agentic_generative_ui/agent.py +++ b/typescript-sdk/integrations/langgraph/examples/agents/agentic_generative_ui/agent.py @@ -2,9 +2,10 @@ An example demonstrating agentic generative UI using LangGraph. """ -import json +from __future__ import annotations + import asyncio -from typing import Dict, List, Any, Optional, Literal +from typing import List, Any # LangGraph imports from langchain_core.runnables import RunnableConfig from langgraph.graph import StateGraph, END, START diff --git a/typescript-sdk/integrations/langgraph/examples/agents/human_in_the_loop/agent.py b/typescript-sdk/integrations/langgraph/examples/agents/human_in_the_loop/agent.py index 393d2254..c94ec581 100644 --- a/typescript-sdk/integrations/langgraph/examples/agents/human_in_the_loop/agent.py +++ b/typescript-sdk/integrations/langgraph/examples/agents/human_in_the_loop/agent.py @@ -2,6 +2,8 @@ A LangGraph implementation of the human-in-the-loop agent. """ +from __future__ import annotations + import json from typing import Dict, List, Any @@ -11,7 +13,6 @@ from langgraph.types import Command, interrupt from langgraph.graph import MessagesState -from copilotkit.langgraph import copilotkit_emit_state, copilotkit_interrupt # LLM imports from langchain_openai import ChatOpenAI diff --git a/typescript-sdk/integrations/langgraph/examples/agents/predictive_state_updates/agent.py b/typescript-sdk/integrations/langgraph/examples/agents/predictive_state_updates/agent.py index 325f0014..12d05860 100644 --- a/typescript-sdk/integrations/langgraph/examples/agents/predictive_state_updates/agent.py +++ b/typescript-sdk/integrations/langgraph/examples/agents/predictive_state_updates/agent.py @@ -2,9 +2,10 @@ A demo of predictive state updates using LangGraph. """ -import json +from __future__ import annotations + import uuid -from typing import Dict, List, Any, Optional +from typing import List, Any # LangGraph imports from langchain_core.runnables import RunnableConfig @@ -45,7 +46,7 @@ class AgentState(MessagesState): """ The state of the agent. """ - document: Optional[str] = None + document: str | None = None tools: List[Any] diff --git a/typescript-sdk/integrations/langgraph/examples/agents/shared_state/agent.py b/typescript-sdk/integrations/langgraph/examples/agents/shared_state/agent.py index 02fd4a09..b67b0e09 100644 --- a/typescript-sdk/integrations/langgraph/examples/agents/shared_state/agent.py +++ b/typescript-sdk/integrations/langgraph/examples/agents/shared_state/agent.py @@ -2,9 +2,11 @@ A demo of shared state between the agent and CopilotKit using LangGraph. """ +from __future__ import annotations + import json from enum import Enum -from typing import Dict, List, Any, Optional +from typing import Dict, List, Any # LangGraph imports from langchain_core.runnables import RunnableConfig @@ -113,7 +115,7 @@ class AgentState(MessagesState): """ The state of the recipe. """ - recipe: Optional[Dict[str, Any]] = None + recipe: Dict[str, Any] | None = None tools: List[Any] diff --git a/typescript-sdk/integrations/langgraph/examples/agents/tool_based_generative_ui/agent.py b/typescript-sdk/integrations/langgraph/examples/agents/tool_based_generative_ui/agent.py index a7c025a0..1db59cb3 100644 --- a/typescript-sdk/integrations/langgraph/examples/agents/tool_based_generative_ui/agent.py +++ b/typescript-sdk/integrations/langgraph/examples/agents/tool_based_generative_ui/agent.py @@ -2,7 +2,9 @@ An example demonstrating tool-based generative UI using LangGraph. """ -from typing import Dict, List, Any, Optional +from __future__ import annotations + +from typing import List, Any # LangGraph imports from langchain_core.runnables import RunnableConfig diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/agent.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/agent.py index 310a8543..7712b7f9 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/agent.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/agent.py @@ -1,6 +1,8 @@ +from __future__ import annotations + import uuid import json -from typing import Optional, List, Any, Union, AsyncGenerator, Generator +from typing import List, Any, AsyncGenerator, Generator from langgraph.graph.state import CompiledStateGraph from langchain.schema import BaseMessage, SystemMessage @@ -55,35 +57,34 @@ ThinkingStartEvent, ThinkingEndEvent, ) -from ag_ui.encoder import EventEncoder -ProcessedEvents = Union[ - TextMessageStartEvent, - TextMessageContentEvent, - TextMessageEndEvent, - ToolCallStartEvent, - ToolCallArgsEvent, - ToolCallEndEvent, - StateSnapshotEvent, - StateDeltaEvent, - MessagesSnapshotEvent, - RawEvent, - CustomEvent, - RunStartedEvent, - RunFinishedEvent, - RunErrorEvent, - StepStartedEvent, - StepFinishedEvent, -] +ProcessedEvents = ( + TextMessageStartEvent | + TextMessageContentEvent | + TextMessageEndEvent | + ToolCallStartEvent | + ToolCallArgsEvent | + ToolCallEndEvent | + StateSnapshotEvent | + StateDeltaEvent | + MessagesSnapshotEvent | + RawEvent | + CustomEvent | + RunStartedEvent | + RunFinishedEvent | + RunErrorEvent | + StepStartedEvent | + StepFinishedEvent +) class LangGraphAgent: - def __init__(self, *, name: str, graph: CompiledStateGraph, description: Optional[str] = None, config: Union[Optional[RunnableConfig], dict] = None): + def __init__(self, *, name: str, graph: CompiledStateGraph, description: str | None = None, config: RunnableConfig | dict | None = None): self.name = name self.description = description self.graph = graph self.config = config or {} self.messages_in_process: MessagesInProgressRecord = {} - self.active_run: Optional[RunMetadata] = None + self.active_run: RunMetadata | None = None self.constant_schema_keys = ['messages', 'tools'] def _dispatch_event(self, event: ProcessedEvents) -> str: @@ -358,7 +359,7 @@ async def prepare_regenerate_stream( # pylint: disable=too-many-arguments "config": config } - def get_message_in_progress(self, run_id: str) -> Optional[MessageInProgress]: + def get_message_in_progress(self, run_id: str) -> MessageInProgress | None: return self.messages_in_process.get(run_id) def set_message_in_progress(self, run_id: str, data: MessageInProgress): @@ -604,7 +605,7 @@ async def _handle_single_event(self, event: Any, state: State) -> AsyncGenerator yield self._dispatch_event( StateSnapshotEvent(type=EventType.STATE_SNAPSHOT, snapshot=self.get_state_snapshot(state), raw_event=event) ) - + yield self._dispatch_event( CustomEvent(type=EventType.CUSTOM, name=event["name"], value=event["data"], raw_event=event) ) diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/endpoint.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/endpoint.py index 89c6e06b..519a4cd3 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/endpoint.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/endpoint.py @@ -1,4 +1,6 @@ -from fastapi import FastAPI, HTTPException, Request +from __future__ import annotations + +from fastapi import FastAPI, Request from fastapi.responses import StreamingResponse from ag_ui.core.types import RunAgentInput diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/agentic_chat.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/agentic_chat.py index 30c31a17..b8865ebe 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/agentic_chat.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/agentic_chat.py @@ -2,14 +2,15 @@ A simple agentic chat flow using LangGraph instead of CrewAI. """ -from typing import Dict, List, Any, Optional +from __future__ import annotations + +from typing import List, Any # Updated imports for LangGraph from langchain_core.runnables import RunnableConfig from langgraph.graph import StateGraph, END, START from langgraph.graph import MessagesState from langgraph.types import Command -from typing_extensions import Literal from langchain_openai import ChatOpenAI from langchain_core.messages import SystemMessage from langgraph.checkpoint.memory import MemorySaver diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/agentic_generative_ui.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/agentic_generative_ui.py index d3047220..86ab13e1 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/agentic_generative_ui.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/agentic_generative_ui.py @@ -2,9 +2,10 @@ An example demonstrating agentic generative UI using LangGraph. """ -import json +from __future__ import annotations + import asyncio -from typing import Dict, List, Any, Optional, Literal +from typing import List, Any # LangGraph imports from langchain_core.runnables import RunnableConfig from langgraph.graph import StateGraph, END, START diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/predictive_state_updates.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/predictive_state_updates.py index a7b43574..2901fbc6 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/predictive_state_updates.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/predictive_state_updates.py @@ -2,9 +2,10 @@ A demo of predictive state updates using LangGraph. """ -import json +from __future__ import annotations + import uuid -from typing import Dict, List, Any, Optional +from typing import List, Any # LangGraph imports from langchain_core.runnables import RunnableConfig @@ -46,7 +47,7 @@ class AgentState(MessagesState): """ The state of the agent. """ - document: Optional[str] = None + document: str | None = None tools: List[Any] diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/shared_state.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/shared_state.py index 493bbee0..6d56223a 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/shared_state.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/shared_state.py @@ -2,9 +2,11 @@ A demo of shared state between the agent and CopilotKit using LangGraph. """ +from __future__ import annotations + import json from enum import Enum -from typing import Dict, List, Any, Optional +from typing import Dict, List, Any # LangGraph imports from langchain_core.runnables import RunnableConfig @@ -107,7 +109,7 @@ class AgentState(MessagesState): """ The state of the recipe. """ - recipe: Optional[Dict[str, Any]] = None + recipe: Dict[str, Any] | None = None tools: List[Any] diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/tool_based_generative_ui.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/tool_based_generative_ui.py index b286c4db..21ace5cd 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/tool_based_generative_ui.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/examples/agents/tool_based_generative_ui.py @@ -2,7 +2,9 @@ An example demonstrating tool-based generative UI using LangGraph. """ -from typing import Dict, List, Any, Optional +from __future__ import annotations + +from typing import List, Any # LangGraph imports from langchain_core.runnables import RunnableConfig diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/types.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/types.py index 7d08d6bf..346d7aac 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/types.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/types.py @@ -1,7 +1,11 @@ -from typing import TypedDict, Optional, List, Any, Dict, Union, Literal -from typing_extensions import NotRequired +from __future__ import annotations + +from typing import Any, Dict, List, Literal, TypedDict, Union from enum import Enum +from typing_extensions import NotRequired + + class LangGraphEventTypes(str, Enum): OnChainStart = "on_chain_start" OnChainStream = "on_chain_stream" @@ -23,34 +27,34 @@ class CustomEventNames(str, Enum): State = Dict[str, Any] SchemaKeys = TypedDict("SchemaKeys", { - "input": NotRequired[Optional[List[str]]], - "output": NotRequired[Optional[List[str]]], - "config": NotRequired[Optional[List[str]]] + "input": NotRequired[List[str] | None], + "output": NotRequired[List[str] | None], + "config": NotRequired[List[str] | None], }) ThinkingProcess = TypedDict("ThinkingProcess", { "index": int, - "type": NotRequired[Optional[Literal['text']]], + "type": NotRequired[Literal['text'] | None], }) MessageInProgress = TypedDict("MessageInProgress", { "id": str, - "tool_call_id": NotRequired[Optional[str]], - "tool_call_name": NotRequired[Optional[str]] + "tool_call_id": NotRequired[str | None], + "tool_call_name": NotRequired[str | None] }) RunMetadata = TypedDict("RunMetadata", { "id": str, - "schema_keys": NotRequired[Optional[SchemaKeys]], - "node_name": NotRequired[Optional[str]], - "prev_node_name": NotRequired[Optional[str]], + "schema_keys": NotRequired[SchemaKeys | None], + "node_name": NotRequired[str | None], + "prev_node_name": NotRequired[str | None], "exiting_node": NotRequired[bool], - "manually_emitted_state": NotRequired[Optional[State]], - "thread_id": NotRequired[Optional[ThinkingProcess]], - "thinking_process": NotRequired[Optional[str]] + "manually_emitted_state": NotRequired[State | None], + "thread_id": NotRequired[ThinkingProcess | None], + "thinking_process": NotRequired[str | None], }) -MessagesInProgressRecord = Dict[str, Optional[MessageInProgress]] +MessagesInProgressRecord = Dict[str, MessageInProgress | None] ToolCall = TypedDict("ToolCall", { "id": str, diff --git a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/utils.py b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/utils.py index c1c50466..70559041 100644 --- a/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/utils.py +++ b/typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/utils.py @@ -1,6 +1,8 @@ +from __future__ import annotations + import json import re -from typing import List, Any, Dict, Union +from typing import List, Any, Dict from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, SystemMessage, ToolMessage from ag_ui.core import ( @@ -26,7 +28,7 @@ def get_stream_payload_input( mode: str, state: State, schema_keys: SchemaKeys, -) -> Union[State, None]: +) -> State | None: input_payload = state if mode == "start" else None if input_payload and schema_keys and schema_keys.get("input"): input_payload = filter_object_by_schema_keys(input_payload, [*DEFAULT_SCHEMA_KEYS, *schema_keys["input"]]) diff --git a/typescript-sdk/integrations/llamaindex/server-py/server/routers/shared_state.py b/typescript-sdk/integrations/llamaindex/server-py/server/routers/shared_state.py index a81d5db2..21c6d99f 100644 --- a/typescript-sdk/integrations/llamaindex/server-py/server/routers/shared_state.py +++ b/typescript-sdk/integrations/llamaindex/server-py/server/routers/shared_state.py @@ -1,4 +1,6 @@ -from typing import Literal, List +from __future__ import annotations + +from typing import List from pydantic import BaseModel from llama_index.core.workflow import Context diff --git a/typescript-sdk/integrations/server-starter-all-features/server/python/example_server/agentic_chat.py b/typescript-sdk/integrations/server-starter-all-features/server/python/example_server/agentic_chat.py index 0680d445..d43a070e 100644 --- a/typescript-sdk/integrations/server-starter-all-features/server/python/example_server/agentic_chat.py +++ b/typescript-sdk/integrations/server-starter-all-features/server/python/example_server/agentic_chat.py @@ -1,6 +1,7 @@ """ Agentic chat endpoint for the AG-UI protocol. """ +from __future__ import annotations import uuid import asyncio @@ -23,7 +24,6 @@ ToolCall, AssistantMessage ) -from ag_ui.core.events import TextMessageChunkEvent from ag_ui.encoder import EventEncoder async def agentic_chat_endpoint(input_data: RunAgentInput, request: Request):