Compare commits

...

11 Commits

Author SHA1 Message Date
Yuge Zhang f301c88702 skip more tests 2025-12-05 18:52:18 +08:00
Yuge Zhang da4819eaed update uv lock 2025-12-05 17:45:10 +08:00
Yuge Zhang 264ce7e18b fix pre-commit 2025-12-05 16:24:37 +08:00
Yuge Zhang 6d24306c39 skip some tests 2025-12-05 16:16:16 +08:00
Leonardo Pinheiro f076b022c9 fix tests 2025-12-05 17:37:57 +10:00
Yuge Zhang 51d7128e79 shrink uv.lock 2025-12-05 15:01:56 +08:00
Leonardo Pinheiro 9e5592107c rm langchain from agents 2025-12-05 16:39:43 +10:00
Leonardo Pinheiro 74597c98bd remove langchain classic 2025-12-05 16:23:51 +10:00
Leonardo Pinheiro df6073034c lint 2025-12-05 16:23:51 +10:00
Leonardo Pinheiro c5a210544b update numpy 2025-12-05 16:23:51 +10:00
Leonardo Pinheiro 3f2afc196d update langchain 2025-12-05 16:02:57 +10:00
8 changed files with 2351 additions and 2729 deletions
+1 -1
View File
@@ -24,6 +24,6 @@ jobs:
script: |
const badgeAggregation = require('./scripts/badge_aggregation.js');
const dependencies = [
{ workflow: 'examples-spider.yml', label: 'spider', variants: ['stable', 'legacy'] },
{ workflow: 'examples-spider.yml', label: 'spider', variants: ['stable'] },
];
await badgeAggregation({ github, context, core, dependencies });
+5 -6
View File
@@ -33,8 +33,7 @@ jobs:
strategy:
matrix:
include:
- python-version: '3.10'
setup-script: 'legacy'
# legacy is omitted because langchain doesn't work with legacy vllm versions
- python-version: '3.12'
setup-script: 'stable'
- python-version: '3.13'
@@ -58,13 +57,13 @@ jobs:
- name: Sync dependencies (latest)
run: |
uv sync --frozen --no-default-groups --extra verl \
--group dev --group experiment --group agents --group torch-gpu-stable
--group dev --group experiment --group agents --group langchain --group torch-gpu-stable
if: matrix.setup-script == 'latest'
- name: Sync dependencies (stable & legacy)
- name: Sync dependencies (stable)
run: |
uv sync --frozen --no-default-groups --extra verl \
--group dev --group experiment --group agents --group torch-gpu-${{ matrix.setup-script }}
if: matrix.setup-script != 'latest'
--group dev --group experiment --group agents --group langchain --group torch-gpu-${{ matrix.setup-script }}
if: matrix.setup-script == 'stable'
- name: Freeze dependencies
run: |
set -ex
+16 -8
View File
@@ -56,11 +56,15 @@ jobs:
run: uv lock --upgrade
if: matrix.setup-script == 'latest'
- name: Sync dependencies (latest)
run: uv sync --frozen --no-default-groups --extra apo --extra mongo --group dev --group agents --group torch-gpu-stable
run: uv sync --frozen --no-default-groups --extra apo --extra mongo --group dev --group agents --group langchain --group torch-gpu-stable
if: matrix.setup-script == 'latest'
- name: Sync dependencies (stable & legacy)
run: uv sync --frozen --no-default-groups --extra apo --extra mongo --group dev --group agents --group torch-gpu-${{ matrix.setup-script }}
if: matrix.setup-script != 'latest'
- name: Sync dependencies (stable)
run: uv sync --frozen --no-default-groups --extra apo --extra mongo --group dev --group agents --group langchain --group torch-gpu-${{ matrix.setup-script }}
if: matrix.setup-script == 'stable'
# Don't install langchain for legacy dependency because it has conflicts with torch.
- name: Sync dependencies (legacy)
run: uv sync --frozen --no-default-groups --extra apo --extra mongo --group dev --group agents --group torch-gpu-legacy
if: matrix.setup-script == 'legacy'
- name: Freeze dependencies
run: |
set -ex
@@ -178,11 +182,15 @@ jobs:
run: uv lock --upgrade
if: matrix.setup-script == 'latest'
- name: Sync dependencies (latest)
run: uv sync --frozen --no-default-groups --extra apo --group dev --group agents --group torch-gpu-stable
run: uv sync --frozen --no-default-groups --extra apo --group dev --group agents --group langchain --group torch-gpu-stable
if: matrix.setup-script == 'latest'
- name: Sync dependencies (stable & legacy)
run: uv sync --frozen --no-default-groups --extra apo --group dev --group agents --group torch-gpu-${{ matrix.setup-script }}
if: matrix.setup-script != 'latest'
- name: Sync dependencies (stable)
run: uv sync --frozen --no-default-groups --extra apo --extra mongo --group dev --group agents --group langchain --group torch-gpu-${{ matrix.setup-script }}
if: matrix.setup-script == 'stable'
# Don't install langchain for legacy dependency because it has conflicts with torch.
- name: Sync dependencies (legacy)
run: uv sync --frozen --no-default-groups --extra apo --extra mongo --group dev --group agents --group torch-gpu-legacy
if: matrix.setup-script == 'legacy'
- name: Freeze dependencies
run: |
set -ex
+3 -2
View File
@@ -44,6 +44,7 @@ jobs:
--group trl \
--group tinker \
--group agents \
--group langchain \
--no-default-groups
if: matrix.setup == 'slow'
# This pre-commit skips JavaScript on purpose.
@@ -139,10 +140,10 @@ jobs:
run: uv lock --upgrade
if: matrix.setup-script == 'latest'
- name: Sync dependencies (latest)
run: uv sync --frozen --no-default-groups --extra apo --group dev --group agents --group core-stable
run: uv sync --frozen --no-default-groups --extra apo --group dev --group agents --group langchain --group core-stable
if: matrix.setup-script == 'latest'
- name: Sync dependencies (stable & legacy)
run: uv sync --frozen --no-default-groups --extra apo --group dev --group agents --group core-${{ matrix.setup-script }}
run: uv sync --frozen --no-default-groups --extra apo --group dev --group agents --group langchain --group core-${{ matrix.setup-script }}
if: matrix.setup-script != 'latest'
- name: Freeze dependencies
run: |
+14 -5
View File
@@ -183,10 +183,10 @@ anthropic = [
"anthropic",
]
langchain = [
"langgraph<1.0",
"langchain[openai]<1.0",
"langchain-community",
"langchain-text-splitters<1.0",
"langgraph>=1.0.0",
"langchain[openai]>=1.0.0",
"langchain-community>=0.4.0",
"langchain-text-splitters>=1.0.0",
]
sql = [
"sqlparse",
@@ -206,10 +206,11 @@ swebench = [
]
# Summarize into large installable groups.
# Note: langchain is excluded from agents to avoid conflicts with torch-legacy.
# Use --group langchain explicitly when needed.
agents = [
{include-group = "autogen"},
{include-group = "openai-agents"},
{include-group = "langchain"},
{include-group = "sql"},
{include-group = "anthropic"},
{include-group = "crewai"},
@@ -231,6 +232,12 @@ conflicts = [
{ group = "torch-stable" },
{ group = "torch-legacy" },
],
# langchain >= 1.0 requires openai >= 1.109.1 (via langchain-openai),
# but torch-legacy uses vllm==0.9.2 which requires openai<=1.90.0
[
{ group = "langchain" },
{ group = "torch-legacy" },
],
]
environments = [
"sys_platform == 'linux'",
@@ -250,6 +257,8 @@ override-dependencies = [
# Conflicts between litellm and fastmcp
"websockets>=15.0.1",
"rich>=13.9.4",
# verl's numpy<2.0.0 constraint is related to Docker images, not code incompatibility
"numpy>=2.0.0,<2.3.0",
]
[tool.uv.sources]
+2
View File
@@ -28,3 +28,5 @@
{"request": {"messages": [{"content": "Return 1.0 if the answer is 8, else 0.0.", "role": "system"}, {"role": "user", "content": "8"}], "model": "gpt-4.1-mini", "response_format": {"type": "json_schema", "json_schema": {"name": "final_output", "strict": true, "schema": {"properties": {"response": {"title": "Response", "type": "number"}}, "required": ["response"], "title": "OutputType", "type": "object", "additionalProperties": false}}}}, "response": {"choices": [{"content_filter_results": {"hate": {"filtered": false, "severity": "safe"}, "protected_material_code": {"filtered": false, "detected": false}, "protected_material_text": {"filtered": false, "detected": false}, "self_harm": {"filtered": false, "severity": "safe"}, "sexual": {"filtered": false, "severity": "safe"}, "violence": {"filtered": false, "severity": "safe"}}, "finish_reason": "stop", "index": 0, "logprobs": null, "message": {"annotations": [], "content": "{\"response\":1.0}", "refusal": null, "role": "assistant"}}], "created": 1763565701, "id": "chatcmpl-CdeI1ifu2oOt06oTodWPpSpNFAqIN", "model": "gpt-4.1-mini-2025-04-14", "object": "chat.completion", "prompt_filter_results": [{"prompt_index": 0, "content_filter_results": {"hate": {"filtered": false, "severity": "safe"}, "jailbreak": {"filtered": false, "detected": false}, "self_harm": {"filtered": false, "severity": "safe"}, "sexual": {"filtered": false, "severity": "safe"}, "violence": {"filtered": false, "severity": "safe"}}}], "system_fingerprint": "fp_3dcd5944f5", "usage": {"completion_tokens": 8, "completion_tokens_details": {"accepted_prediction_tokens": 0, "audio_tokens": 0, "reasoning_tokens": 0, "rejected_prediction_tokens": 0}, "prompt_tokens": 65, "prompt_tokens_details": {"audio_tokens": 0, "cached_tokens": 0}, "total_tokens": 73}}}
{"request": {"messages": [{"content": "If the question is about math, handoff to MathAgent. Otherwise, handoff to HistoryAgent.", "role": "system"}, {"role": "user", "content": "Who was the first president of the US?"}], "model": "gpt-4.1-mini", "tools": [{"type": "function", "function": {"name": "transfer_to_mathagent", "description": "Handoff to the MathAgent agent to handle the request. ", "parameters": {"additionalProperties": false, "type": "object", "properties": {}, "required": []}}}, {"type": "function", "function": {"name": "transfer_to_historyagent", "description": "Handoff to the HistoryAgent agent to handle the request. ", "parameters": {"additionalProperties": false, "type": "object", "properties": {}, "required": []}}}]}, "response": {"choices": [{"content_filter_results": {}, "finish_reason": "tool_calls", "index": 0, "logprobs": null, "message": {"annotations": [], "content": null, "refusal": null, "role": "assistant", "tool_calls": [{"function": {"arguments": "{}", "name": "transfer_to_historyagent"}, "id": "call_tXXmrsNYcFlKrG9hMo2Yk0E3", "type": "function"}]}}], "created": 1763565706, "id": "chatcmpl-CdeI6hxlaAwzbn7Sx4ZTXZs0Hx3E5", "model": "gpt-4.1-mini-2025-04-14", "object": "chat.completion", "prompt_filter_results": [{"prompt_index": 0, "content_filter_results": {"hate": {"filtered": false, "severity": "safe"}, "jailbreak": {"filtered": false, "detected": false}, "self_harm": {"filtered": false, "severity": "safe"}, "sexual": {"filtered": false, "severity": "safe"}, "violence": {"filtered": false, "severity": "safe"}}}], "system_fingerprint": "fp_3dcd5944f5", "usage": {"completion_tokens": 13, "completion_tokens_details": {"accepted_prediction_tokens": 0, "audio_tokens": 0, "reasoning_tokens": 0, "rejected_prediction_tokens": 0}, "prompt_tokens": 97, "prompt_tokens_details": {"audio_tokens": 0, "cached_tokens": 0}, "total_tokens": 110}}}
{"request": {"messages": [{"content": "Answer history questions.", "role": "system"}, {"role": "assistant", "content": "For context, here is the conversation so far between the user and the previous agent:\n<CONVERSATION HISTORY>\n1. user: Who was the first president of the US?\n2. function_call: {\"arguments\": \"{}\", \"call_id\": \"call_tXXmrsNYcFlKrG9hMo2Yk0E3\", \"name\": \"transfer_to_historyagent\", \"id\": \"__fake_id__\"}\n3. function_call_output: {\"call_id\": \"call_tXXmrsNYcFlKrG9hMo2Yk0E3\", \"output\": \"{\\\"assistant\\\": \\\"HistoryAgent\\\"}\"}\n</CONVERSATION HISTORY>"}, {"role": "assistant", "tool_calls": [{"id": "call_tXXmrsNYcFlKrG9hMo2Yk0E3", "type": "function", "function": {"name": "transfer_to_historyagent", "arguments": "{}"}}]}, {"role": "tool", "tool_call_id": "call_tXXmrsNYcFlKrG9hMo2Yk0E3", "content": "{\"assistant\": \"HistoryAgent\"}"}], "model": "gpt-4.1-mini"}, "response": {"choices": [{"content_filter_results": {"hate": {"filtered": false, "severity": "safe"}, "protected_material_text": {"filtered": false, "detected": false}, "self_harm": {"filtered": false, "severity": "safe"}, "sexual": {"filtered": false, "severity": "safe"}, "violence": {"filtered": false, "severity": "safe"}}, "finish_reason": "stop", "index": 0, "logprobs": null, "message": {"annotations": [], "content": "The first president of the United States was George Washington. He served as president from 1789 to 1797. If you have more questions about U.S. history or any other historical events, feel free to ask!", "refusal": null, "role": "assistant"}}], "created": 1763565707, "id": "chatcmpl-CdeI78NuMQmjmeuwLhx3I0Qqcem99", "model": "gpt-4.1-mini-2025-04-14", "object": "chat.completion", "prompt_filter_results": [{"prompt_index": 0, "content_filter_results": {}}], "system_fingerprint": "fp_3dcd5944f5", "usage": {"completion_tokens": 46, "completion_tokens_details": {"accepted_prediction_tokens": 0, "audio_tokens": 0, "reasoning_tokens": 0, "rejected_prediction_tokens": 0}, "prompt_tokens": 179, "prompt_tokens_details": {"audio_tokens": 0, "cached_tokens": 0}, "total_tokens": 225}}}
{"request": {"messages": [{"role": "system", "content": "You are a helpful assistant. Use the multiply tool to answer math questions."}, {"role": "user", "content": "what is 42 * 12"}], "model": "gpt-4.1-mini", "tools": [{"type": "function", "function": {"name": "multiply", "description": "A simple calculator tool that multiplies two integers.", "parameters": {"type": "object", "properties": {"a_and_b": {"type": "string"}}, "required": ["a_and_b"]}}}]}, "response": {"id": "chatcmpl-test1", "model": "gpt-4.1-mini", "object": "chat.completion", "created": 1750758616, "choices": [{"index": 0, "message": {"role": "assistant", "content": null, "tool_calls": [{"id": "call_abc123", "type": "function", "function": {"name": "multiply", "arguments": "{\"a_and_b\": \"42 and 12\"}"}}]}, "finish_reason": "tool_calls"}], "usage": {"prompt_tokens": 100, "completion_tokens": 20, "total_tokens": 120}}}
{"request": {"messages": [{"role": "system", "content": "You are a helpful assistant. Use the multiply tool to answer math questions."}, {"role": "user", "content": "what is 42 * 12"}, {"role": "assistant", "content": null, "tool_calls": [{"id": "call_abc123", "type": "function", "function": {"name": "multiply", "arguments": "{\"a_and_b\": \"42 and 12\"}"}}]}, {"role": "tool", "content": "504", "tool_call_id": "call_abc123"}], "model": "gpt-4.1-mini", "tools": [{"type": "function", "function": {"name": "multiply", "description": "A simple calculator tool that multiplies two integers.", "parameters": {"type": "object", "properties": {"a_and_b": {"type": "string"}}, "required": ["a_and_b"]}}}]}, "response": {"id": "chatcmpl-test2", "model": "gpt-4.1-mini", "object": "chat.completion", "created": 1750758617, "choices": [{"index": 0, "message": {"role": "assistant", "content": "The result of 42 * 12 is 504."}, "finish_reason": "stop"}], "usage": {"prompt_tokens": 150, "completion_tokens": 15, "total_tokens": 165}}}
+53 -23
View File
@@ -30,7 +30,7 @@ import socket
import threading
import time
from contextlib import asynccontextmanager, contextmanager
from typing import Any, Callable, Dict, Iterator, List, Literal, Optional, Tuple
from typing import TYPE_CHECKING, Any, Callable, Dict, Iterator, List, Literal, Optional, Tuple
from unittest.mock import AsyncMock, MagicMock, Mock, patch
import agentops
@@ -50,17 +50,6 @@ from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_ext.models.openai import OpenAIChatCompletionClient
from autogen_ext.tools.mcp import McpWorkbench, StdioServerParams
from fastapi import FastAPI
from langchain import hub
from langchain.agents import AgentExecutor, create_react_agent, tool
from langchain.chat_models import init_chat_model
from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_community.utilities import SQLDatabase
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, ToolMessage
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langgraph.graph import END, START, MessagesState, StateGraph
from langgraph.prebuilt import ToolNode
from openai import AsyncOpenAI, OpenAI
from opentelemetry.sdk.trace import ReadableSpan
from pydantic import BaseModel, Field
@@ -74,6 +63,25 @@ from agentlightning.types import Span, Triplet
from ..common.tracer import clear_agentops_init, clear_tracer_provider
try:
import langchain
LANGCHAIN_INSTALLED = True
except ImportError:
LANGCHAIN_INSTALLED = False
if TYPE_CHECKING or LANGCHAIN_INSTALLED:
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain_community.utilities import SQLDatabase
from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, ToolMessage
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.graph import END, START, MessagesState, StateGraph
USE_OPENAI = os.environ.get("USE_OPENAI", "false").lower() == "true"
OPENAI_BASE_URL = "http://127.0.0.1:58000/v1"
OPENAI_MODEL = "gpt-4.1-mini"
@@ -301,13 +309,16 @@ def agent_langchain_tooluse() -> None:
disable_streaming=True,
)
tools = [multiply]
agent = create_react_agent(llm, tools, hub.pull("hwchase17/react"))
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=False)
result = agent_executor.invoke(
{"input": "what is 42 * 12"},
agent = create_agent(
model=llm,
tools=tools,
system_prompt="You are a helpful assistant. Use the multiply tool to answer math questions.",
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "what is 42 * 12"}]},
{"callbacks": [_langchain_callback_handler]} if _langchain_callback_handler else None,
)
assert "504" in result["output"]
assert "504" in result["messages"][-1].content
def agent_langgraph() -> None:
@@ -321,10 +332,25 @@ def agent_langgraph() -> None:
return next(t for t in tools if t.name == name)
get_schema_tool = next(tool for tool in tools if tool.name == "sql_db_schema")
get_schema_node = ToolNode([get_schema_tool], name="get_schema")
run_query_tool = next(tool for tool in tools if tool.name == "sql_db_query")
run_query_node = ToolNode([run_query_tool], name="run_query")
def get_schema(state: MessagesState):
"""Execute the get_schema tool based on the last message's tool calls."""
last_message = state["messages"][-1]
tool_messages = []
for tool_call in getattr(last_message, "tool_calls", []):
result = get_schema_tool.invoke(tool_call)
tool_messages.append(result)
return {"messages": tool_messages}
def run_query(state: MessagesState):
"""Execute the run_query tool based on the last message's tool calls."""
last_message = state["messages"][-1]
tool_messages = []
for tool_call in getattr(last_message, "tool_calls", []):
result = run_query_tool.invoke(tool_call)
tool_messages.append(result)
return {"messages": tool_messages}
def list_tables(state: MessagesState):
tool_call = {
@@ -381,10 +407,10 @@ def agent_langgraph() -> None:
builder = StateGraph(MessagesState)
builder.add_node(list_tables)
builder.add_node(call_get_schema)
builder.add_node(get_schema_node, "get_schema")
builder.add_node(get_schema)
builder.add_node(generate_query)
builder.add_node(check_query)
builder.add_node(run_query_node, "run_query")
builder.add_node(run_query)
builder.add_edge(START, "list_tables")
builder.add_edge("list_tables", "call_get_schema")
builder.add_edge("call_get_schema", "get_schema")
@@ -797,6 +823,8 @@ def test_run_with_agentops_tracer(agent_func_name: str):
"""AgentOps tracer tests are notoriously problematic and does not work well with other tests."""
if agent_func_name in ["openai_agents_sdk_mcp_tool_use", "agent_autogen_mcp"]:
pytest.skip("Async MCP server is problematic with AgentOps tracer in multiprocessing mode.")
if ("langchain" in agent_func_name or "langgraph" in agent_func_name) and not LANGCHAIN_INSTALLED:
pytest.skip("LangChain is not installed. Skip langchain related tests.")
ctx = multiprocessing.get_context("spawn")
proc = ctx.Process(target=_test_run_with_agentops_tracer_impl, args=(agent_func_name,))
@@ -824,7 +852,9 @@ def _test_run_with_agentops_tracer_impl(agent_func_name: str):
tracer.init_worker(0)
global _langchain_callback_handler
_langchain_callback_handler = tracer.get_langchain_callback_handler()
if LANGCHAIN_INSTALLED:
_langchain_callback_handler = tracer.get_langchain_callback_handler()
try:
tracer.trace_run(
Generated
+2257 -2684
View File
File diff suppressed because one or more lines are too long