mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-24 00:22:25 +02:00
Bumps the minor-and-patch group with 1 update in the /libs/sdk-py directory: [ty](https://github.com/astral-sh/ty). Updates `ty` from 0.0.23 to 0.0.33 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/astral-sh/ty/releases">ty's releases</a>.</em></p> <blockquote> <h2>0.0.33</h2> <h2>Release Notes</h2> <p>Released on 2026-04-28.</p> <h3>Notable changes</h3> <ul> <li> <p>ty now prefers the declared type of an annotated assignment in more situations (<a href="https://redirect.github.com/astral-sh/ruff/pull/24802">#24802</a>). Consider this example:</p> <pre lang="py"><code>from some_library import untyped_function <p>threshold: int | None = 0 result: str = untyped_function() </code></pre></p> <p>ty previously favored the <em>inferred</em> type of the right hand side expression when <code>threshold</code> and <code>result</code> were used. This is useful for <code>threshold</code>, as it allows something like <code>threshold += 1</code> to work without an error: we know that <code>threshold</code> could later become <code>None</code>, but <em>right now</em>, we see that it is an <code>int</code>. However, for <code>result</code>, the inferred type is <code>Unknown</code>. This is <em>not</em> a useful type and it can lead to false negatives. Starting with this release, ty will therefore prefer the declared type <em>if the inferred and declared types are mutually assignable</em>. In the above example, <code>threshold</code> will still be inferred as <code>int</code> (or rather <code>Literal[1]</code>), but <code>result</code> will now be inferred as <code>str</code>. If you previously added <code>cast</code>s to work around this behavior, you should be able to remove them after upgrading.</p> </li> </ul> <h3>Bug fixes</h3> <ul> <li>Fix reporting of annotation-only locals as unused (<a href="https://redirect.github.com/astral-sh/ruff/pull/24811">#24811</a>)</li> <li>Fix project and workspace selection (<a href="https://redirect.github.com/astral-sh/ruff/pull/24824">#24824</a>)</li> <li>Fix go-to definition for generic classes (<a href="https://redirect.github.com/astral-sh/ruff/pull/24714">#24714</a>)</li> <li>Fix receiver coloring for aliased decorators (<a href="https://redirect.github.com/astral-sh/ruff/pull/24884">#24884</a>)</li> </ul> <h3>LSP server</h3> <ul> <li>Add support for go-to definition in literal enum member inlay hints (<a href="https://redirect.github.com/astral-sh/ruff/pull/24792">#24792</a>)</li> <li>Add support for "baking" keyword argument inlay hints into the source code (<a href="https://redirect.github.com/astral-sh/ruff/pull/24667">#24667</a>)</li> <li>Don't allow inlay hint edits when introducing a non global scope symbol (<a href="https://redirect.github.com/astral-sh/ruff/pull/24797">#24797</a>)</li> <li>Omit semantic highlighting for unresolved symbols (<a href="https://redirect.github.com/astral-sh/ruff/pull/24718">#24718</a>)</li> </ul> <h3>Core type checking</h3> <ul> <li>Support narrowing with aliased conditional expressions (<a href="https://redirect.github.com/astral-sh/ruff/pull/24302">#24302</a>)</li> <li>Model short-circuiting control flow in Boolean expressions (<a href="https://redirect.github.com/astral-sh/ruff/pull/24458">#24458</a>)</li> <li>Handle <code>finally</code> blocks where all <code>try</code>/<code>except</code> blocks are terminal (<a href="https://redirect.github.com/astral-sh/ruff/pull/24882">#24882</a>)</li> <li>Detect invalid <code>ClassVar</code> vs instance-attribute overrides (<a href="https://redirect.github.com/astral-sh/ruff/pull/24767">#24767</a>)</li> <li>Emit diagnostic for invalid uses of <code>Unpack[...]</code> (<a href="https://redirect.github.com/astral-sh/ruff/pull/24868">#24868</a>)</li> <li>Infer lambda parameter types with <code>Callable</code> type context (<a href="https://redirect.github.com/astral-sh/ruff/pull/24317">#24317</a>)</li> <li>Support <code>**</code> unpacking of <code>TypedDict</code> in dict-literal assignments (<a href="https://redirect.github.com/astral-sh/ruff/pull/24703">#24703</a>)</li> <li>Support <code>Unpack[TypedDict]</code> in <code>**kwargs</code> signatures (<a href="https://redirect.github.com/astral-sh/ruff/pull/24653">#24653</a>)</li> <li>Treat <code>[*xs]</code> as an irrefutable pattern when matching on <code>Sequence</code> (<a href="https://redirect.github.com/astral-sh/ruff/pull/24787">#24787</a>)</li> <li>Improve generics solving for unions in invariant positions (<a href="https://redirect.github.com/astral-sh/ruff/pull/24698">#24698</a>)</li> <li>Improve generics solving for unions when matching against protocols (<a href="https://redirect.github.com/astral-sh/ruff/pull/24837">#24837</a>)</li> </ul> <h3>Diagnostics</h3> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/astral-sh/ty/blob/main/CHANGELOG.md">ty's changelog</a>.</em></p> <blockquote> <h2>0.0.33</h2> <p>Released on 2026-04-28.</p> <h3>Notable changes</h3> <ul> <li> <p>ty now prefers the declared type of an annotated assignment in more situations (<a href="https://redirect.github.com/astral-sh/ruff/pull/24802">#24802</a>). Consider this example:</p> <pre lang="py"><code>from some_library import untyped_function <p>threshold: int | None = 0 result: str = untyped_function() </code></pre></p> <p>ty previously favored the <em>inferred</em> type of the right hand side expression when <code>threshold</code> and <code>result</code> were used. This is useful for <code>threshold</code>, as it allows something like <code>threshold += 1</code> to work without an error: we know that <code>threshold</code> could later become <code>None</code>, but <em>right now</em>, we see that it is an <code>int</code>. However, for <code>result</code>, the inferred type is <code>Unknown</code>. This is <em>not</em> a useful type and it can lead to false negatives. Starting with this release, ty will therefore prefer the declared type <em>if the inferred and declared types are mutually assignable</em>. In the above example, <code>threshold</code> will still be inferred as <code>int</code> (or rather <code>Literal[1]</code>), but <code>result</code> will now be inferred as <code>str</code>. If you previously added <code>cast</code>s to work around this behavior, you should be able to remove them after upgrading.</p> </li> </ul> <h3>Bug fixes</h3> <ul> <li>Fix reporting of annotation-only locals as unused (<a href="https://redirect.github.com/astral-sh/ruff/pull/24811">#24811</a>)</li> <li>Fix project and workspace selection (<a href="https://redirect.github.com/astral-sh/ruff/pull/24824">#24824</a>)</li> <li>Fix go-to definition for generic classes (<a href="https://redirect.github.com/astral-sh/ruff/pull/24714">#24714</a>)</li> <li>Fix receiver coloring for aliased decorators (<a href="https://redirect.github.com/astral-sh/ruff/pull/24884">#24884</a>)</li> </ul> <h3>LSP server</h3> <ul> <li>Add support for go-to definition in literal enum member inlay hints (<a href="https://redirect.github.com/astral-sh/ruff/pull/24792">#24792</a>)</li> <li>Add support for "baking" keyword argument inlay hints into the source code (<a href="https://redirect.github.com/astral-sh/ruff/pull/24667">#24667</a>)</li> <li>Don't allow inlay hint edits when introducing a non global scope symbol (<a href="https://redirect.github.com/astral-sh/ruff/pull/24797">#24797</a>)</li> <li>Omit semantic highlighting for unresolved symbols (<a href="https://redirect.github.com/astral-sh/ruff/pull/24718">#24718</a>)</li> </ul> <h3>Core type checking</h3> <ul> <li>Support narrowing with aliased conditional expressions (<a href="https://redirect.github.com/astral-sh/ruff/pull/24302">#24302</a>)</li> <li>Model short-circuiting control flow in Boolean expressions (<a href="https://redirect.github.com/astral-sh/ruff/pull/24458">#24458</a>)</li> <li>Handle <code>finally</code> blocks where all <code>try</code>/<code>except</code> blocks are terminal (<a href="https://redirect.github.com/astral-sh/ruff/pull/24882">#24882</a>)</li> <li>Detect invalid <code>ClassVar</code> vs instance-attribute overrides (<a href="https://redirect.github.com/astral-sh/ruff/pull/24767">#24767</a>)</li> <li>Emit diagnostic for invalid uses of <code>Unpack[...]</code> (<a href="https://redirect.github.com/astral-sh/ruff/pull/24868">#24868</a>)</li> <li>Infer lambda parameter types with <code>Callable</code> type context (<a href="https://redirect.github.com/astral-sh/ruff/pull/24317">#24317</a>)</li> <li>Support <code>**</code> unpacking of <code>TypedDict</code> in dict-literal assignments (<a href="https://redirect.github.com/astral-sh/ruff/pull/24703">#24703</a>)</li> <li>Support <code>Unpack[TypedDict]</code> in <code>**kwargs</code> signatures (<a href="https://redirect.github.com/astral-sh/ruff/pull/24653">#24653</a>)</li> <li>Treat <code>[*xs]</code> as an irrefutable pattern when matching on <code>Sequence</code> (<a href="https://redirect.github.com/astral-sh/ruff/pull/24787">#24787</a>)</li> <li>Improve generics solving for unions in invariant positions (<a href="https://redirect.github.com/astral-sh/ruff/pull/24698">#24698</a>)</li> <li>Improve generics solving for unions when matching against protocols (<a href="https://redirect.github.com/astral-sh/ruff/pull/24837">#24837</a>)</li> </ul> <h3>Diagnostics</h3> <ul> <li>Add error context to <code>invalid-return-type</code> diagnostics, <code>invalid-yield</code> diagnostics, attribute assignment diagnostics (<a href="https://redirect.github.com/astral-sh/ruff/pull/24770">#24770</a>, <a href="https://redirect.github.com/astral-sh/ruff/pull/24771">#24771</a>)</li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/astral-sh/ty/commit/c512d8425418a2170e92aa7fbbd70952d4e04118"><code>c512d84</code></a> Bump version to 0.0.33 (<a href="https://redirect.github.com/astral-sh/ty/issues/3368">#3368</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/4cd7b334b90eba09042700e7b654044c2d6bcd15"><code>4cd7b33</code></a> Upgrade Depot runners from macOS 14 to 15 (<a href="https://redirect.github.com/astral-sh/ty/issues/3363">#3363</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/c78b8324515bf15a662f61e1d74fd85484d67e8c"><code>c78b832</code></a> Update rui314/setup-mold digest to 9c9c13b (<a href="https://redirect.github.com/astral-sh/ty/issues/3342">#3342</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/dea338134aef96d741a48886e414f622dbf10426"><code>dea3381</code></a> Update actions/cache action to v5.0.5 (<a href="https://redirect.github.com/astral-sh/ty/issues/3343">#3343</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/d451af477bd5517e132609c3b016799d697f4182"><code>d451af4</code></a> update typing-features and faqs (<a href="https://redirect.github.com/astral-sh/ty/issues/3335">#3335</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/052d70bc1a7457f50c5acbafe8de7a846f7d5e77"><code>052d70b</code></a> Update prek dependencies (<a href="https://redirect.github.com/astral-sh/ty/issues/3344">#3344</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/66b5e878163ce4ab4810a45a2679a98011932b8b"><code>66b5e87</code></a> Update astral-sh/setup-uv action to v8.1.0 (<a href="https://redirect.github.com/astral-sh/ty/issues/3345">#3345</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/7ec6712a6f02d0255de4c7f0066d5bb23987a9bb"><code>7ec6712</code></a> Add a 'Diagnostics improvements' section to the changelogs (<a href="https://redirect.github.com/astral-sh/ty/issues/3309">#3309</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/978dfdb38dfb568943f73779d769a965c1d5a397"><code>978dfdb</code></a> Add version metadata publishing to the release process (<a href="https://redirect.github.com/astral-sh/ty/issues/3292">#3292</a>)</li> <li><a href="https://github.com/astral-sh/ty/commit/4d1e1fc57ca8bfdcbcee513ba92135d2932eb279"><code>4d1e1fc</code></a> Bump version to 0.0.32 (<a href="https://redirect.github.com/astral-sh/ty/issues/3302">#3302</a>)</li> <li>Additional commits viewable in <a href="https://github.com/astral-sh/ty/compare/0.0.23...0.0.33">compare view</a></li> </ul> </details> <br /> --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: John Kennedy <65985482+jkennedyvz@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
239 lines
8.3 KiB
Python
239 lines
8.3 KiB
Python
from __future__ import annotations
|
|
|
|
import sys
|
|
from dataclasses import dataclass, field
|
|
from typing import TYPE_CHECKING, Generic, Literal, TypeVar
|
|
|
|
if sys.version_info >= (3, 13):
|
|
ContextT = TypeVar("ContextT", default=None)
|
|
else:
|
|
ContextT = TypeVar("ContextT")
|
|
|
|
if sys.version_info >= (3, 12):
|
|
from typing import TypeAliasType
|
|
else:
|
|
from typing_extensions import TypeAliasType
|
|
|
|
from langgraph_sdk.auth.types import BaseUser
|
|
|
|
if TYPE_CHECKING:
|
|
from langgraph.store.base import BaseStore
|
|
|
|
__all__ = [
|
|
"AccessContext",
|
|
"ServerRuntime",
|
|
]
|
|
|
|
|
|
AccessContext = Literal[
|
|
"threads.create_run",
|
|
"threads.update",
|
|
"threads.read",
|
|
"assistants.read",
|
|
]
|
|
|
|
|
|
@dataclass(kw_only=True, slots=True, frozen=True)
|
|
class _ServerRuntimeBase(Generic[ContextT]):
|
|
"""Base for server runtime variants.
|
|
|
|
!!! warning "Beta"
|
|
This API is in beta and may change in future releases.
|
|
"""
|
|
|
|
access_context: AccessContext
|
|
"""Why the graph factory is being called.
|
|
|
|
The server accesses graphs in several contexts beyond just executing runs.
|
|
For example, it calls the graph factory to retrieve schemas, render the
|
|
graph structure, or read state history. This field tells you which
|
|
operation triggered the current call.
|
|
|
|
In all contexts, the returned graph must have the same topology (nodes,
|
|
edges, state schema) as the graph used for execution. Use
|
|
`.execution_runtime` to conditionally set up expensive *resources*
|
|
(MCP servers, DB connections) without changing the graph structure.
|
|
|
|
Write contexts (graph is used to write state):
|
|
|
|
- `threads.create_run` (`graph.astream`) — full graph execution
|
|
(nodes + edges). `context` is available (use `.execution_runtime`
|
|
to narrow).
|
|
- `threads.update` (`graph.aupdate_state`) — does NOT execute node
|
|
functions or evaluate edges. Only runs the node's channel writers
|
|
to apply the provided values to state channels as if the specified
|
|
node had returned them. Reducers are applied and channel triggers
|
|
are set, so the next `invoke`/`stream` call will evaluate edges
|
|
from that node to determine the next step. Does not need access to
|
|
external resources, but a different graph topology will apply
|
|
writes to the wrong channels.
|
|
|
|
Read state contexts (graph used to format the returned
|
|
`StateSnapshot`). A different topology may cause `get_state` to
|
|
report incorrect pending tasks. Note that `useStream` uses the state
|
|
history endpoint to render interrupts and support branching:
|
|
|
|
- `threads.read` (`graph.aget_state`, `graph.aget_state_history`) —
|
|
the graph structure informs which tasks to include in the prepared
|
|
view of the latest checkpoint and how to process subgraphs.
|
|
|
|
Introspection contexts (graph structure only, no execution).
|
|
A different topology may cause schemas and visualizations to not
|
|
match actual execution:
|
|
|
|
- `assistants.read` (`graph.aget_graph`, `graph.aget_subgraphs`,
|
|
`graph.aget_schemas`) — return the graph definition, subgraph
|
|
definitions, and input/output/config schemas. Used for
|
|
visualization in the studio UI and to populate schemas for MCP,
|
|
A2A, and other protocol integrations.
|
|
"""
|
|
|
|
user: BaseUser | None = field(default=None)
|
|
"""The authenticated user, or `None` if no custom auth is configured."""
|
|
|
|
store: BaseStore
|
|
"""Store for the graph run, enabling persistence and memory."""
|
|
|
|
@property
|
|
def execution_runtime(self) -> _ExecutionRuntime[ContextT] | None:
|
|
"""Narrow to the execution runtime, or `None` if not in an execution context.
|
|
|
|
When the server calls the graph factory for `threads.create_run`, the returned
|
|
object provides access to `context` (typed by the graph's
|
|
`context_schema`). For all other access contexts (introspection, state
|
|
reads, state updates), this returns `None`.
|
|
|
|
Use this to conditionally set up expensive resources (MCP tool servers,
|
|
database connections, etc.) that are only needed during execution:
|
|
|
|
```python
|
|
import contextlib
|
|
from langgraph_sdk.runtime import ServerRuntime
|
|
|
|
@contextlib.asynccontextmanager
|
|
async def my_factory(runtime: ServerRuntime[MyCtx]):
|
|
if ert := runtime.execution_runtime:
|
|
# Only connect to MCP servers when actually executing a run.
|
|
# Introspection calls (get_schema, get_graph, ...) skip this.
|
|
mcp_tools = await connect_mcp(ert.context.mcp_endpoint)
|
|
yield create_agent(model, tools=mcp_tools)
|
|
await disconnect_mcp()
|
|
else:
|
|
yield create_agent(model, tools=[])
|
|
```
|
|
"""
|
|
if isinstance(self, _ExecutionRuntime):
|
|
return self
|
|
return None
|
|
|
|
def ensure_user(self) -> BaseUser:
|
|
"""Return the authenticated user, or raise if not available.
|
|
|
|
When custom auth is configured, `user` is set for all access contexts
|
|
(the factory is only called from HTTP handlers where the auth
|
|
middleware has already run). This method raises only when no custom
|
|
auth is configured.
|
|
|
|
Raises:
|
|
PermissionError: If no user is authenticated.
|
|
"""
|
|
if self.user is None:
|
|
raise PermissionError(
|
|
f"No authenticated user available in access_context='{self.access_context}'. "
|
|
"Ensure custom auth is configured for the server."
|
|
)
|
|
return self.user
|
|
|
|
|
|
@dataclass(kw_only=True, slots=True, frozen=True)
|
|
class _ExecutionRuntime(_ServerRuntimeBase[ContextT], Generic[ContextT]):
|
|
"""Runtime for `threads.create_run` — the graph will be fully executed.
|
|
|
|
Access this via `.execution_runtime` on `ServerRuntime`. Do not
|
|
construct directly.
|
|
|
|
!!! warning "Beta"
|
|
This API is in beta and may change in future releases.
|
|
"""
|
|
|
|
context: ContextT = field(default=None) # ty: ignore[invalid-assignment]
|
|
"""The graph run context, typed by the graph's `context_schema`.
|
|
|
|
Only available during `threads.create_run`.
|
|
"""
|
|
|
|
|
|
@dataclass(kw_only=True, slots=True, frozen=True)
|
|
class _ReadRuntime(_ServerRuntimeBase[ContextT], Generic[ContextT]):
|
|
"""Runtime for non-execution access contexts.
|
|
|
|
Used for introspection (`assistants.read`), state operations
|
|
(`threads.read`), and state updates (`threads.update`).
|
|
No `context` is available.
|
|
|
|
!!! warning "Beta"
|
|
This API is in beta and may change in future releases.
|
|
"""
|
|
|
|
|
|
ServerRuntime = TypeAliasType(
|
|
"ServerRuntime",
|
|
_ExecutionRuntime[ContextT] | _ReadRuntime[ContextT],
|
|
type_params=(ContextT,),
|
|
)
|
|
"""Runtime context passed to graph builder factories within the Agent Server.
|
|
|
|
Requires version 0.7.30 or later of the agent server.
|
|
|
|
The server calls your graph factory in multiple contexts: executing runs,
|
|
reading state, fetching schemas, and more. `ServerRuntime` provides
|
|
the authenticated user, store, and access context for every call. Use
|
|
`.execution_runtime` to narrow to the execution variant and access
|
|
`context`.
|
|
|
|
Example — conditionally initialize MCP tools only during execution:
|
|
|
|
```python
|
|
import contextlib
|
|
from dataclasses import dataclass
|
|
|
|
from langchain.agents import create_agent
|
|
from langgraph_sdk.runtime import ServerRuntime
|
|
from my_agent import connect_mcp, disconnect_mcp
|
|
|
|
@dataclass
|
|
class MyCtx:
|
|
mcp_endpoint: str
|
|
|
|
_readonly_agent = create_agent("anthropic:claude-3-5-haiku", tools=[])
|
|
|
|
@contextlib.asynccontextmanager
|
|
async def my_factory(runtime: ServerRuntime[MyCtx]):
|
|
if ert := runtime.execution_runtime:
|
|
# Only connect to MCP servers for actual runs.
|
|
# Schema / graph introspection calls skip this.
|
|
user_id = runtime.ensure_user().identity
|
|
mcp_tools = await connect_mcp(ert.context.mcp_endpoint, user_id)
|
|
yield create_agent("anthropic:claude-3-5-haiku", tools=mcp_tools)
|
|
await disconnect_mcp()
|
|
else:
|
|
yield _readonly_agent
|
|
```
|
|
|
|
Example — simple factory that ignores context:
|
|
|
|
```python
|
|
from langgraph_sdk.runtime import ServerRuntime
|
|
|
|
def build_graph(user: BaseUser) -> CompiledGraph:
|
|
...
|
|
|
|
async def my_factory(runtime: ServerRuntime) -> CompiledGraph:
|
|
# No generic needed if you don't use context.
|
|
return build_graph(runtime.ensure_user())
|
|
```
|
|
|
|
!!! warning "Beta"
|
|
This API is in beta and may change in future releases.
|
|
"""
|