-
Notifications
You must be signed in to change notification settings - Fork 4
Labels
enhancementNew feature or requestNew feature or request
Description
Summary
- Add a native Python LangGraph integration so users do not have to manually wrap each tool with
@control(). - The integration should discover tool metadata from LangGraph/LangChain tool objects, instrument actual tool execution using framework-native hooks, and manage Agent Control registration under the hood.
- Users should not have to call
initAgentdirectly for this integration. The integration can still callinitAgentunder the hood if needed.
Motivation
- The current LangGraph example in the repo is functional, but the user experience is still manual: tools are wrapped individually with
@control()and step registration relies on the existing decorator-based path. - LangGraph/LangChain already expose native tool-call interception seams, so we should be able to support the framework more directly instead of forcing users to adapt their code to the SDK’s decorator model.
- A native integration would make Agent Control feel like a first-class framework integration rather than a generic decorator bolted onto framework tools.
Current behavior
- Python users protect LangGraph/LangChain tools by manually wrapping functions with
@control()and then exposing those wrapped functions as framework tools. - Step metadata is auto-registered today only because the wrapped Python functions participate in the existing
@control()registry. agent_control.init(...)calls/api/v1/agents/initAgent, merges explicit and decorator-discovered steps, and caches returned controls for runtime use.- Runtime enforcement semantics today live in the
@control()path.
Relevant repo examples:
examples/langchain/langgraph_auto_schema_agent.pyexamples/langchain/sql_agent_protection.py
Expected behavior
- A LangGraph integration should allow users to register/protect framework tools natively, without manually slapping
@control()on each tool implementation. - The integration should automatically derive step/tool metadata from framework tool objects and register that metadata with Agent Control.
- The integration should automatically instrument actual tool execution using the framework’s native interception seam.
- The integration should manage registration under the hood so users do not have to explicitly call
initAgentas part of framework setup. - If the integration discovers a previously unseen tool after initial setup, it should be able to re-sync registration by re-running
initAgentunder the hood with the full merged step set before first execution of that unseen tool.
Reproduction (if bug)
- This is an enhancement request, not a bug report.
Proposed solution (optional)
- Add a Python LangGraph/LangChain integration package or module behind an optional install boundary.
- Use framework-native tool interception instead of manual decorator wrapping.
- For LangChain agents, use
wrap_tool_callmiddleware rather than manual per-tool wrapping. - For lower-level LangGraph execution, use the native
ToolNode/ToolCallWrapperseam rather than requiring raw function wrapping.
- For LangChain agents, use
- Under the hood, keep Agent Control semantics in the SDK:
- discover/normalize step metadata from framework tool objects
- call
initAgentunder the hood during setup to register the full step set and load controls - on newly discovered tools, re-run
initAgentwith the full merged step set rather than a delta payload - reuse the core Python runtime evaluation path, including
check_evaluation_with_local(), soexecution="sdk"controls keep working - translate deny/steer outcomes into framework-appropriate propagation instead of assuming raw
ControlViolationErroris always the correct UX
Suggested new-tool detection / resync behavior:
- The adapter should maintain a local registry/fingerprint of the currently known tools, keyed by tool identity plus schema fingerprint.
- During setup, the adapter discovers the initial tool set and registers the full normalized step list via
initAgentunder the hood. - At the tool-call interception seam, such as LangChain’s
wrap_tool_callor LangGraph’sToolCallWrapper, the adapter compares the incoming tool against the known registry. - If the tool is unseen, or if its schema fingerprint changed, the adapter should:
- re-scan the current tool set from the framework runtime
- regenerate the full normalized step list
- re-run
initAgentunder the hood with the full merged list - refresh cached controls from the response
- only then proceed to pre-check / execution for that tool
- If the re-sync fails for an unseen tool, the safest default is fail-closed before executing that tool.
Tradeoffs / constraints:
- The integration should hide manual
initAgentfrom the user, but it probably should not try to eliminateinitAgentinternally in v1 because the current SDK flow uses it for both registration and control loading. - True incremental late-bound step registration without
initAgentis probably follow-up work. - Initial scope should stay tools-only, not generic graph/node abstractions.
- LangChain’s agents docs already discuss dynamic tools / runtime tool registration, so the integration should align with that model rather than assume a fully static tool set forever.
Additional context
- Current parent design discussion in Shortcut:
sc-57847 - Current LangGraph example relying on manual
@control()wrapping:examples/langchain/langgraph_auto_schema_agent.py - Current Python SDK registration flow:
sdks/python/src/agent_control/__init__.py - Current Python runtime enforcement path:
sdks/python/src/agent_control/control_decorators.py - LangChain middleware reference: https://reference.langchain.com/python/langchain/agents/middleware
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request