feat(langchain_v1): injected runtime (#33500)
Goal here is 2 fold
1. Improved devx for injecting args into tools
2. Support runtime injection for Python 3.10 async
One consequence of this PR is that `ToolNode` now expects `config`
available with `runtime`, which only happens in LangGraph execution
contexts. Hence the config patch for tests.
Are we ok reserving `tool_runtime`?
before, eek:
```py
from langchain.agents import create_agent
from langchain.tools import tool, InjectedState, InjectedStore
from langgraph.runtime import get_runtime
from typing_extensions import Annotated
from langgraph.store.base import BaseStore
@tool
def do_something(
arg: int,
state: Annotated[dict, InjectedState],
store: Annotated[BaseStore, InjectedStore],
) -> None:
"""does something."""
print(state)
print(store)
print(get_runtime().context)
...
```
after, woo!
```py
from langchain.agents import create_agent
from langchain.tools import tool, ToolRuntime
@tool
def do_something_better(
arg: int,
tool_runtime: ToolRuntime,
) -> None:
"""does something better."""
print(tool_runtime.state)
print(tool_runtime.store)
print(tool_runtime.context)
...
```
```python
@dataclass
class ToolRuntime(InjectedToolArg, Generic[StateT, ContextT]):
state: StateT
context: ContextT
config: RunnableConfig
tool_call_id: str
stream_writer: StreamWriter
context: ContextT
store: BaseStore | None