langchain-agent-hints
English | 简体中文
Per-request serving-intent hints for LangChain agents, as middleware.
langchain-agent-hints makes your agent announce how it is running to the
downstream inference layer. On every main-line model request it attaches an
AgentHint object — session identity, lifecycle state, priority, cache
control — as the base64url-encoded X-Agent-Hint HTTP header, and reports
state transitions (tool / running / pause / finalize) through an
out-of-band event sink. The serving side (gateway, router, inference engine)
consumes these signals for scheduling: session-aware KV-cache placement,
priority scheduling, approval-pending demotion, and so on.
The agent signals; the engine decides. The middleware is read-only with
respect to the model-visible request: it never touches messages or the system
prompt — it only extends ModelRequest.model_settings with the transport
header, which reaches OpenAI-compatible chat models as per-request
extra_headers.
How it fits LangChain
Both middlewares subclass the public
AgentMiddleware
base class, so they work anywhere user middleware is accepted: LangChain's
create_agent, and deepagents' create_deep_agent (where user middleware is
placed after the core stack). No harness is modified and no private APIs are
imported.
AgentHintsMiddleware— builds one hint perwrap_model_calland injects theX-Agent-Hintheader (async:awrap_model_call).AgentStatusEventsMiddleware— reports lifecycle transitions to a pluggable sink viawrap_model_call/after_model/wrap_tool_call/after_agentand their async counterparts.
Session identity comes from the LangGraph runtime config:
configurable.thread_id is the session id; deepagents subagent runs
(ls_agent_type == "subagent") self-identify as
{thread_id}:{agent_name} with a parent_session_id back-reference and
derivation: {relation: spawn, join: sync} (deepagents task subagents are
foreground-blocking).
Install
pip install langchain-agent-hints
Requires Python ≥ 3.11 and langchain>=1.4,<2.0. Source install also works:
pip install git+https://github.com/evan7ang/langchain-agent-hints.git.
Quickstart
Plain create_agent
from pathlib import Path
from langchain.agents import create_agent
from langchain_agent_hints import (
AgentHintsMiddleware,
AgentStatusEventsMiddleware,
JsonlStatusEventSink,
)
agent = create_agent(
model="openai:gpt-4o-mini",
tools=[...],
middleware=[
AgentHintsMiddleware(agent_type="my-agent"),
AgentStatusEventsMiddleware(
sink=JsonlStatusEventSink(Path("status-events.jsonl")),
),
],
)
result = agent.invoke(
{"messages": [("user", "Summarize this quarter.")]},
config={"configurable": {"thread_id": "session-42"}}, # identity is mandatory
)
Requests then carry a header such as (base64url-decoded for readability):
{
"session": {"session_id": "session-42", "agent_type": "my-agent", "call_index": 3, "epoch": 0},
"agent_status": {"state": "running", "state_since_ms": 1730000000000},
"priority": {"level": 3, "reason": "user_waiting"},
"cache_control": [{"type": "pin", "range": {"end": 1}}]
}
deepagents
from deepagents import create_deep_agent
from langchain_agent_hints import AgentHintsMiddleware, AgentStatusEventsMiddleware
agent = create_deep_agent(
model="openai:gpt-4o-mini",
tools=[...],
middleware=[
AgentHintsMiddleware(agent_type="my-agent"),
AgentStatusEventsMiddleware(sink=my_sink, interrupt_tools=INTERRUPT_ON.keys()),
],
)
A runnable version lives in examples/deepagents_quickstart.py —
it accepts AGENT_HINTS_EXAMPLE_MODEL (model string override) and
AGENT_HINTS_STATUS_SINK (event file), and works against any OpenAI-compatible
gateway via OPENAI_BASE_URL.
What gets sent
| Block | Content | Source |
|---|---|---|
session |
session_id, agent_type, call_index, epoch, optional parent_session_id + derivation |
thread_id, constructor options, persistent message history |
agent_status |
request-time lifecycle snapshot (always running) |
middleware observation |
priority |
level + audit reason (default {level: 3, reason: user_waiting}; subagents: critical_path) |
constructor options |
cache_control |
pin/ephemeral intent over message ranges (default: pin the system prompt [0, 1)) |
constructor options |
prediction, strict_priority |
defined by the protocol, never emitted in v1 | — |
Full wire contract: docs/PROTOCOL.md.
Key emission rules:
- No
thread_id→ no hint, no status events (identity is mandatory). call_indexis derived from the checkpointer-persisted message history (1 + count(AIMessage)), so it survives process restarts with zero state.epochbumps when the message prefix is rewritten (summarization signal).- Only requests flowing through
wrap_model_callare hinted; auxiliary model calls that bypass the middleware chain are not.
Status events
AgentStatusEventsMiddleware reports transitions as they happen, in protocol
shape {"seq": N, "session": {...}, "agent_status": {...}}:
| Hook | Event | Dedup |
|---|---|---|
wrap_model_call entry |
running |
only if last state ≠ running |
wrap_model_call response |
pause (human_approval, gated tools listed) |
every gated response |
after_model |
running |
only if last state ≠ running |
wrap_tool_call entry |
tool (await_tool, name + call_id) |
every tool call |
wrap_tool_call exit |
running |
only when the last outstanding tool finishes |
after_agent |
finalize |
fires only on real completion (an approval pause suspends without finalize) |
Pass interrupt_tools=INTERRUPT_ON.keys() (the human-approval gate names) so
gated tool calls surface as pause events. Sinks implement the one-method
StatusEventSink protocol; JsonlStatusEventSink persists to a JSONL file
with per-session sequence numbers and retries transient failures. The sink
interface is synchronous — async hooks call it inline, so use a buffered sink
for slow transports.
Disabling
Drop the middlewares from the composition — hints and events are advisory signals and are never required for the agent to function. A common composition-level pattern is an environment kill switch:
import os
from langchain_agent_hints import AgentHintsMiddleware, AgentStatusEventsMiddleware
if os.environ.get("AGENT_HINTS_DISABLE", "").strip().lower() not in {"1", "true", "yes"}:
middleware = [
AgentHintsMiddleware(agent_type="my-agent"),
AgentStatusEventsMiddleware(
sink=JsonlStatusEventSink(
os.environ.get("AGENT_HINTS_STATUS_SINK", "status-events.jsonl")
),
),
]
else:
middleware = []
Compatibility
Verified against langchain 1.4.1 / langchain-core 1.6.4 /
deepagents 0.7.15 / langgraph memory checkpointing. Known limitations and
measured hook-timing facts: docs/COMPATIBILITY.md.
Development
python -m venv .venv && source .venv/bin/activate
pip install -e '.[test,lint]'
pytest # keyless: fake models + a local capture stub
ruff check .
ruff format --check .
mypy # strict, src only
CI runs the same suite on Python 3.11–3.13.
Roadmap
- Publish to PyPI and list under the LangChain middleware integrations.
- Async-friendly (buffered / async) sink interface.
predictionblock: serving-side estimates from observation statistics.
License
Metadata
Release files for langchain-agent-hints 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| langchain_agent_hints-0.1.0.tar.gz | 30.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| langchain_agent_hints-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.0 kB
Release files / langchain_agent_hints-0.1.0.tar.gz
| Download URL | langchain_agent_hints-0.1.0.tar.gz |
|---|---|
| Size | 30.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c5e35a78b2a348c46bc55025a95f9470b630f0d7b8be6c698defad4717c990dd
|
|
BLAKE2b-256 checksum How to use checksums |
f95735f1f6f5740398b497e17bff5b6787a30c02b0f4abeb3efb3fe3bcb106f9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency logRelease files / langchain_agent_hints-0.1.0-py3-none-any.whl
| Download URL | langchain_agent_hints-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5750434a52053bf3119eb1e9414e66e5881f031542f0f0782b941543d979b811
|
|
BLAKE2b-256 checksum How to use checksums |
f9a992b1105fbc294fa908c73a7931d6933801c6041902da9156abd7ddd94317
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency log