From 9bdff00971b70dacc46709f55f077255b46e38d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Fri, 14 Mar 2025 15:26:58 +0100 Subject: [PATCH 1/8] Add Ollama example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Mayoral Vilches --- examples/agent_patterns/ollama.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 examples/agent_patterns/ollama.py diff --git a/examples/agent_patterns/ollama.py b/examples/agent_patterns/ollama.py new file mode 100644 index 00000000..76425e67 --- /dev/null +++ b/examples/agent_patterns/ollama.py @@ -0,0 +1,28 @@ +from openai import AsyncOpenAI +from agents import OpenAIChatCompletionsModel,Agent,Runner +from agents.model_settings import ModelSettings +from agents import set_default_openai_client, set_tracing_disabled + +external_client = AsyncOpenAI( + base_url = 'http://localhost:8000/v1', + api_key='ollama', # required, but unused +) + +set_default_openai_client(external_client) +set_tracing_disabled(True) + +agent = Agent( + name="Assistant", + instructions="You are a helpful assistant", + model=OpenAIChatCompletionsModel( + model="qwen2.5:14b", + openai_client=external_client, + ) + ) + +result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") +print(result.final_output) + +# Code within the code, +# Functions calling themselves, +# Infinite loop's dance. \ No newline at end of file From 5c551efb23f2d902d2e04a0139a40ec4c8988d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Sun, 16 Mar 2025 21:01:26 +0100 Subject: [PATCH 2/8] Add litellm iterations --- README.md | 15 +++++++++++++ examples/agent_patterns/litellm.py | 35 ++++++++++++++++++++++++++++++ examples/agent_patterns/ollama.py | 3 ++- 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 examples/agent_patterns/litellm.py diff --git a/README.md b/README.md index 210f6f4b..ab033a4b 100644 --- a/README.md +++ b/README.md @@ -176,3 +176,18 @@ We'd like to acknowledge the excellent work of the open-source community, especi - [uv](https://github.com/astral-sh/uv) and [ruff](https://github.com/astral-sh/ruff) We're committed to continuing to build the Agents SDK as an open source framework so others in the community can expand on our approach. + + +## LiteLLM Proxy Server integration + +Testing some basic models: +```bash +# qwen2.5:14b +curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "qwen2.5:14b", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq + +# claude-3-7 +curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "claude-3-7", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq + +# gpt-4o +curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq +``` \ No newline at end of file diff --git a/examples/agent_patterns/litellm.py b/examples/agent_patterns/litellm.py new file mode 100644 index 00000000..b58997df --- /dev/null +++ b/examples/agent_patterns/litellm.py @@ -0,0 +1,35 @@ +from openai import AsyncOpenAI +from agents import OpenAIChatCompletionsModel,Agent,Runner +from agents.model_settings import ModelSettings +from agents import set_default_openai_client, set_tracing_disabled + +external_client = AsyncOpenAI( + base_url = 'http://localhost:4000', + api_key="cai") + +set_default_openai_client(external_client) +set_tracing_disabled(True) + +# llm_model="qwen2.5:14b" +# llm_model="claude-3-7" +llm_model="gpt-4o" + +# For Qwen models, we need to skip system instructions as they're not supported +instructions = None if "qwen" in llm_model.lower() else "You are a helpful assistant" + +agent = Agent( + name="Assistant", + instructions=instructions, + model=OpenAIChatCompletionsModel( + model=llm_model, + openai_client=external_client, + ) +) + + +result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") +print(result.final_output) + +# Code within the code, +# Functions calling themselves, +# Infinite loop's dance. \ No newline at end of file diff --git a/examples/agent_patterns/ollama.py b/examples/agent_patterns/ollama.py index 76425e67..e4247ad6 100644 --- a/examples/agent_patterns/ollama.py +++ b/examples/agent_patterns/ollama.py @@ -18,7 +18,8 @@ model="qwen2.5:14b", openai_client=external_client, ) - ) +) + result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") print(result.final_output) From 012f1caf90b3b7fae0eec2ba8493b0f4c75ad566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Sun, 16 Mar 2025 21:01:51 +0100 Subject: [PATCH 3/8] Add litellm support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Mayoral Vilches --- config.yaml | 23 +++++++++++++++++++++++ examples/agent_patterns/claude.py | 25 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 config.yaml create mode 100644 examples/agent_patterns/claude.py diff --git a/config.yaml b/config.yaml new file mode 100644 index 00000000..e49fe016 --- /dev/null +++ b/config.yaml @@ -0,0 +1,23 @@ +model_list: + - model_name: claude-3-7 + litellm_params: + model: claude-3-7-sonnet-20250219 + api_key: "os.environ/ANTHROPIC_API_KEY" # does os.getenv("ANTHROPIC_API_KEY") + base_url: 'https://api.anthropic.com' + - model_name: gpt-4o + litellm_params: + model: gpt-4o + api_key: "os.environ/OPENAI_API_KEY" + api_base: https://api.openai.com/v1 + - model_name: qwen2.5:14b + litellm_params: + model: ollama/qwen2.5:14b + api_base: http://localhost:8000 + api_key: "os.environ/OLLAMA" + +litellm_settings: # module level litellm settings - https://github.com/BerriAI/litellm/blob/main/litellm/__init__.py + drop_params: True + # set_verbose: True + +general_settings: + port: 4000 \ No newline at end of file diff --git a/examples/agent_patterns/claude.py b/examples/agent_patterns/claude.py new file mode 100644 index 00000000..2c9826b9 --- /dev/null +++ b/examples/agent_patterns/claude.py @@ -0,0 +1,25 @@ +from openai import AsyncOpenAI +from agents import OpenAIChatCompletionsModel,Agent,Runner +from agents.model_settings import ModelSettings +from agents import set_default_openai_client, set_tracing_disabled +import os + +external_client = AsyncOpenAI( + base_url = 'https://api.anthropic.com/v1', + api_key=os.getenv('ANTHROPIC_API_KEY', None) +) + +set_default_openai_client(external_client) +set_tracing_disabled(True) + +agent = Agent( + name="Assistant", + instructions="You are a helpful assistant", + model=OpenAIChatCompletionsModel( + model="claude-3-5-sonnet-20240620", + openai_client=external_client, + ) +) + +result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") +print(result.final_output) From cec4dbe54ac8d082328c0bd852d0bc76352d170a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Mon, 24 Mar 2025 17:26:11 +0100 Subject: [PATCH 4/8] Add some additional bits to README.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Mayoral Vilches --- README.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ab033a4b..69d90c59 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,12 @@ We're committed to continuing to build the Agents SDK as an open source framewor ## LiteLLM Proxy Server integration -Testing some basic models: +```bash +# launch proxy +litellm --config config.yaml +``` + +Testing some basic models against proxy to verify it's operational: ```bash # qwen2.5:14b curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "qwen2.5:14b", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq @@ -190,4 +195,12 @@ curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/ # gpt-4o curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq -``` \ No newline at end of file +``` + +Launch the Agents SDK with the proxy server: +```bash +python3 examples/agent_patterns/litellm.py +``` + +Additional docs: +- LiteLLM admin UI https://docs.litellm.ai/docs/proxy/ui \ No newline at end of file From b47498d8918592e43bc09b1de052290edd99bced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Mon, 24 Mar 2025 18:11:38 +0100 Subject: [PATCH 5/8] Update openai library version to avoid version-related issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In particular: Traceback (most recent call last): File /Users/alias/Alias/research/openai-agents-python/examples/agent_patterns/litellm.py, line 4, in from agents import OpenAIChatCompletionsModel,Agent,Runner File /Users/alias/Alias/research/openai-agents-python/src/agents/__init__.py, line 44, in from .models.openai_chatcompletions import OpenAIChatCompletionsModel File /Users/alias/Alias/research/openai-agents-python/src/agents/models/openai_chatcompletions.py, line 57, in from openai.types.responses.response_usage import InputTokensDetails, OutputTokensDetails ImportError: cannot import name 'InputTokensDetails' from 'openai.types.responses.response_usage' (/Users/alias/Alias/research/openai-agents-python/env/lib/python3.12/site-packages/openai/types/responses/response_usage.py). Did you mean: 'OutputTokensDetails'? Signed-off-by: Víctor Mayoral Vilches --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 667ab355..17cf1366 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ requires-python = ">=3.9" license = "MIT" authors = [{ name = "OpenAI", email = "support@openai.com" }] dependencies = [ - "openai>=1.66.5", + "openai>=1.68.2", "pydantic>=2.10, <3", "griffe>=1.5.6, <2", "typing-extensions>=4.12.2, <5", From bf8c8d96d8c10cb213cb29458187e123ced08a02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Mon, 24 Mar 2025 18:39:17 +0100 Subject: [PATCH 6/8] Restore structure and place litellm integraton under model_providers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Mayoral Vilches --- README.md | 28 ------------------- examples/model_providers/README.md | 26 +++++++++++++++++ .../litellm.py | 21 +++++++------- .../model_providers/litellm_config.yaml | 10 +++---- 4 files changed, 42 insertions(+), 43 deletions(-) rename examples/{agent_patterns => model_providers}/litellm.py (65%) rename config.yaml => examples/model_providers/litellm_config.yaml (100%) diff --git a/README.md b/README.md index b798b170..bbd4a5a0 100644 --- a/README.md +++ b/README.md @@ -178,31 +178,3 @@ We'd like to acknowledge the excellent work of the open-source community, especi - [uv](https://github.com/astral-sh/uv) and [ruff](https://github.com/astral-sh/ruff) We're committed to continuing to build the Agents SDK as an open source framework so others in the community can expand on our approach. - - -## LiteLLM Proxy Server integration - -```bash -# launch proxy -litellm --config config.yaml -``` - -Testing some basic models against proxy to verify it's operational: -```bash -# qwen2.5:14b -curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "qwen2.5:14b", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq - -# claude-3-7 -curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "claude-3-7", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq - -# gpt-4o -curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq -``` - -Launch the Agents SDK with the proxy server: -```bash -python3 examples/agent_patterns/litellm.py -``` - -Additional docs: -- LiteLLM admin UI https://docs.litellm.ai/docs/proxy/ui \ No newline at end of file diff --git a/examples/model_providers/README.md b/examples/model_providers/README.md index f9330c24..bb478367 100644 --- a/examples/model_providers/README.md +++ b/examples/model_providers/README.md @@ -17,3 +17,29 @@ Loops within themselves, Function calls its own being, Depth without ending. ``` + + +## LiteLLM Proxy Server integration + +LiteLLM integration helps out switch between models easily and rapidly. This is easy to integrate via `AsyncOpenAI`: + +```bash +# launch server proxy with your configuration +litellm --config examples/model_providers/litellm_config.yaml + +# then use the proxy via the SDK +python3 examples/agent_patterns/litellm.py +``` + +### Testing the proxy server +Testing some basic models against proxy to verify it's operational: +```bash +# qwen2.5:14b +curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "qwen2.5:14b", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq + +# claude-3-7 +curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "claude-3-7", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq + +# gpt-4o +curl -s http://localhost:4000/v1/chat/completions -H "Content-Type: application/json" -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Say hi"}], "max_tokens": 10}' | jq +``` diff --git a/examples/agent_patterns/litellm.py b/examples/model_providers/litellm.py similarity index 65% rename from examples/agent_patterns/litellm.py rename to examples/model_providers/litellm.py index b58997df..1540a36a 100644 --- a/examples/agent_patterns/litellm.py +++ b/examples/model_providers/litellm.py @@ -1,18 +1,23 @@ +import os +from dotenv import load_dotenv from openai import AsyncOpenAI from agents import OpenAIChatCompletionsModel,Agent,Runner from agents.model_settings import ModelSettings from agents import set_default_openai_client, set_tracing_disabled +# Load environment variables from .env file +load_dotenv() + external_client = AsyncOpenAI( - base_url = 'http://localhost:4000', - api_key="cai") + base_url = os.getenv('LITELLM_BASE_URL', 'http://localhost:4000'), + api_key=os.getenv('LITELLM_API_KEY', 'key')) set_default_openai_client(external_client) set_tracing_disabled(True) -# llm_model="qwen2.5:14b" -# llm_model="claude-3-7" -llm_model="gpt-4o" +llm_model=os.getenv('LLM_MODEL', 'gpt-4o') +# llm_model=os.getenv('LLM_MODEL', 'claude-3-7') +# llm_model=os.getenv('LLM_MODEL', 'qwen2.5:14b') # For Qwen models, we need to skip system instructions as they're not supported instructions = None if "qwen" in llm_model.lower() else "You are a helpful assistant" @@ -28,8 +33,4 @@ result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") -print(result.final_output) - -# Code within the code, -# Functions calling themselves, -# Infinite loop's dance. \ No newline at end of file +print(result.final_output) \ No newline at end of file diff --git a/config.yaml b/examples/model_providers/litellm_config.yaml similarity index 100% rename from config.yaml rename to examples/model_providers/litellm_config.yaml index e49fe016..91caa55d 100644 --- a/config.yaml +++ b/examples/model_providers/litellm_config.yaml @@ -1,14 +1,14 @@ model_list: - - model_name: claude-3-7 - litellm_params: - model: claude-3-7-sonnet-20250219 - api_key: "os.environ/ANTHROPIC_API_KEY" # does os.getenv("ANTHROPIC_API_KEY") - base_url: 'https://api.anthropic.com' - model_name: gpt-4o litellm_params: model: gpt-4o api_key: "os.environ/OPENAI_API_KEY" api_base: https://api.openai.com/v1 + - model_name: claude-3-7 + litellm_params: + model: claude-3-7-sonnet-20250219 + api_key: "os.environ/ANTHROPIC_API_KEY" # does os.getenv("ANTHROPIC_API_KEY") + base_url: 'https://api.anthropic.com' - model_name: qwen2.5:14b litellm_params: model: ollama/qwen2.5:14b From 0113e901d2f90facb588c8b0e29828f79a89c8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Mon, 24 Mar 2025 18:43:46 +0100 Subject: [PATCH 7/8] Remove independent and isolated model tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Mayoral Vilches --- examples/agent_patterns/claude.py | 25 ------------------------- examples/agent_patterns/ollama.py | 29 ----------------------------- 2 files changed, 54 deletions(-) delete mode 100644 examples/agent_patterns/claude.py delete mode 100644 examples/agent_patterns/ollama.py diff --git a/examples/agent_patterns/claude.py b/examples/agent_patterns/claude.py deleted file mode 100644 index 2c9826b9..00000000 --- a/examples/agent_patterns/claude.py +++ /dev/null @@ -1,25 +0,0 @@ -from openai import AsyncOpenAI -from agents import OpenAIChatCompletionsModel,Agent,Runner -from agents.model_settings import ModelSettings -from agents import set_default_openai_client, set_tracing_disabled -import os - -external_client = AsyncOpenAI( - base_url = 'https://api.anthropic.com/v1', - api_key=os.getenv('ANTHROPIC_API_KEY', None) -) - -set_default_openai_client(external_client) -set_tracing_disabled(True) - -agent = Agent( - name="Assistant", - instructions="You are a helpful assistant", - model=OpenAIChatCompletionsModel( - model="claude-3-5-sonnet-20240620", - openai_client=external_client, - ) -) - -result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") -print(result.final_output) diff --git a/examples/agent_patterns/ollama.py b/examples/agent_patterns/ollama.py deleted file mode 100644 index e4247ad6..00000000 --- a/examples/agent_patterns/ollama.py +++ /dev/null @@ -1,29 +0,0 @@ -from openai import AsyncOpenAI -from agents import OpenAIChatCompletionsModel,Agent,Runner -from agents.model_settings import ModelSettings -from agents import set_default_openai_client, set_tracing_disabled - -external_client = AsyncOpenAI( - base_url = 'http://localhost:8000/v1', - api_key='ollama', # required, but unused -) - -set_default_openai_client(external_client) -set_tracing_disabled(True) - -agent = Agent( - name="Assistant", - instructions="You are a helpful assistant", - model=OpenAIChatCompletionsModel( - model="qwen2.5:14b", - openai_client=external_client, - ) -) - - -result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") -print(result.final_output) - -# Code within the code, -# Functions calling themselves, -# Infinite loop's dance. \ No newline at end of file From 3344d317ff9f61fedc2918004d8441c6f821bce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Mayoral=20Vilches?= Date: Mon, 24 Mar 2025 19:47:13 +0100 Subject: [PATCH 8/8] Fix error in example path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Víctor Mayoral Vilches --- examples/model_providers/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/model_providers/README.md b/examples/model_providers/README.md index bb478367..e5fd2dac 100644 --- a/examples/model_providers/README.md +++ b/examples/model_providers/README.md @@ -28,7 +28,7 @@ LiteLLM integration helps out switch between models easily and rapidly. This is litellm --config examples/model_providers/litellm_config.yaml # then use the proxy via the SDK -python3 examples/agent_patterns/litellm.py +python3 examples/model_providers/litellm.py ``` ### Testing the proxy server