Conversation
Raw Python callables passed to bind_tools() lack the schema metadata required to generate a valid OpenAI tools[].function spec, causing a 400 "Missing required parameter: 'tools[0].function'" error. Wrapping each callable with StructuredTool.from_function(name=config_key) also ensures the model response carries the config key as the tool name, fixing a separate bug where function.__name__ was being tracked instead of the LaunchDarkly config key. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
_to_openai_name converted hyphens to underscores based on an assumed
restriction that doesn't exist — the OpenAI API allows hyphens in tool
and function names (^[a-zA-Z0-9_-]{1,64}$). Removing it simplifies the
tool name lookup and agent naming.
Also adds model=model.name to the Agent constructor so each node runs
with its configured model rather than the SDK default.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously, tool tracking relied on wrapping custom FunctionTools, which meant native hosted tools (WebSearchTool, FileSearchTool, etc.) were never tracked since they run server-side with no local callback. Instead, parse result.new_items after the run completes. Each ToolCallItem carries the originating agent (node attribution) and raw tool call data, covering both custom and native tools without requiring local execution. Also adds openai-agents as an optional dependency and dev dependency. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
langgraph is required to use LangGraphAgentGraphRunner but was not listed as a dependency. Adding it as an optional extra (graph) and dev dependency, consistent with how openai-agents is handled in the openai provider. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove FileSearchTool, CodeInterpreterTool, ImageGenerationTool from the native tool map; they require mandatory constructor args not available from the LD config and were already broken before. - Move StructuredTool import inside the tools loop so it is only attempted when tools are present, fixing a test that mocks langchain_core without langchain_core.tools. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
main refactored _build_native_tool_map into openai_helper.py as NATIVE_OPENAI_TOOLS and improved get_ai_usage_from_response to handle RunResult objects. Merged with our changes by: - Keeping only WebSearchTool in NATIVE_OPENAI_TOOLS (others require mandatory constructor args not available from config) - Importing NATIVE_OPENAI_TOOLS, get_ai_usage_from_response, and get_tool_calls_from_run_items from the helper - Retaining model=model.name in the Agent constructor - Retaining result-based tool call tracking (no wrapper tracking) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
|
||
| # --- tools --- | ||
| agent_tools: List[Tool] = [] | ||
| agent_tools: List[Any] = [] |
There was a problem hiding this comment.
Would it be too annoying to type this to each tool? Basically Union[FunctionTool, WebSearchTool, ComputerUseTool....] They don't export a "base" tool unfortunately
There was a problem hiding this comment.
It complicates things due to import types. There is a mix of hosted tools and local tools they provide in additional to the function tool. The ComputerTool in particular is a generic which prevents us from doing an easy union.
| log.warning( | ||
| f"Tool '{name}' is defined in the AI config but was not found in " | ||
| "the tool registry; skipping." | ||
| ) |
There was a problem hiding this comment.
Nit: not addressing your PR here but should we re-think the strict linting rule for line length? Seems like we run into it more than just with my long prompts
andrewklatzke
left a comment
There was a problem hiding this comment.
Paid particular attention to the OpenAI path as I know langgraph is still being tweaked, left just one question
packages/ai-providers/server-ai-langchain/src/ldai_langchain/langchain_helper.py
Show resolved
Hide resolved
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
| last = messages[-1] | ||
| if hasattr(last, 'content'): | ||
| output = str(last.content) | ||
| output = extract_last_message_content(messages) |
There was a problem hiding this comment.
Shared helper silently drops non-string langgraph output
Low Severity
The extract_last_message_content helper adds an isinstance(last.content, str) check that the langgraph runner previously did not have. The old langgraph code used str(last.content), which would convert any content type (including lists from multimodal responses) to a string. The new shared function returns '' for non-string content, silently dropping output in cases where AIMessage.content is a list (e.g., multimodal or mixed tool-use responses).
Additional Locations (1)
There was a problem hiding this comment.
We will look into this in a follow up PR.
| 'file_search', | ||
| 'code_interpreter', | ||
| 'tool_search', | ||
| }) |
There was a problem hiding this comment.
Missing image_generation in hosted tool names set
Low Severity
The _OPENAI_HOSTED_TOOL_NAMES set is missing image_generation, which was previously handled via NATIVE_OPENAI_TOOLS. In get_tool_calls_from_run_items, an image_generation_call raw item type won't have its _call suffix stripped to image_generation, so _track_tool_calls in the graph runner won't find a matching entry in _tool_name_map, causing image generation tool calls to go untracked.
There was a problem hiding this comment.
We will look at supporting additional tool calls in future PRs.


Note
Medium Risk
Modifies agent/agent-graph execution and tool wiring for both LangChain and OpenAI integrations, which can affect runtime behavior and telemetry emitted to LaunchDarkly. While covered by new/updated integration tests, changes span multiple providers and tool/usage parsing paths.
Overview
Improves agent and agent-graph support across LangChain and OpenAI providers, with clearer experimental warnings and expanded tracking coverage.
LangChain updates tool handling to pass registry callables directly (replacing
StructuredToolwrapping) and removes tool-binding fromcreate_langchain_model; bothLangChainAgentRunnerandLangGraphAgentGraphRunnernow share a helper to extract the final message content, and LangGraph nodes use the newbuild_toolshelper for binding.OpenAI Agents updates refactor tool construction to support either callables or native
openai-agentsTool instances, add robust token usage extraction from per-request entries, sanitize agent names, and track tool calls by parsingRunResult.new_items.OpenAIRunnerFactorynow normalizes hosted-tooltypefields when creating chat-completions models. New integration tests validate graph/node token, latency, path, handoff, and tool-call event emission for both LangGraph and OpenAI Agents, and both provider packages add optional dependency groups (langgraph,openai-agents).Written by Cursor Bugbot for commit 4a459ee. This will update automatically on new commits. Configure here.