Skip to content

Commit

Permalink
Merge branch 'VRSEN:main' into dev/improve-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
bonk1t authored Feb 13, 2025
2 parents 5ac2f0a + d6813e2 commit 03c8ce3
Show file tree
Hide file tree
Showing 11 changed files with 93 additions and 27 deletions.
6 changes: 3 additions & 3 deletions agency_swarm/agency/agency.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ def __init__(
settings_callbacks: SettingsCallbacks = None,
threads_callbacks: ThreadsCallbacks = None,
temperature: float = 0.3,
top_p: float = 1.0,
top_p: float = None,
max_prompt_tokens: int = None,
max_completion_tokens: int = None,
truncation_strategy: dict = None,
Expand Down Expand Up @@ -636,7 +636,7 @@ def on_all_streams_end(cls):
cls.message_output = None
chatbot_queue.put("[end]")

def bot(original_message, history):
def bot(original_message, history, dropdown):
nonlocal attachments
nonlocal message_file_names
nonlocal recipient_agent
Expand Down Expand Up @@ -757,7 +757,7 @@ def bot(original_message, history):
dropdown.change(handle_dropdown_change, dropdown)
file_upload.change(handle_file_upload, file_upload)
msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(
bot, [msg, chatbot], [msg, chatbot, dropdown]
bot, [msg, chatbot, dropdown], [msg, chatbot, dropdown]
)

# Enable queuing for streaming intermediate outputs
Expand Down
63 changes: 51 additions & 12 deletions agency_swarm/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def __init__(
file_ids: List[str] = None,
metadata: Dict[str, str] = None,
model: str = "gpt-4o-2024-08-06",
reasoning_effort: Literal["low", "medium", "high"] = "medium",
validation_attempts: int = 1,
max_prompt_tokens: int = None,
max_completion_tokens: int = None,
Expand Down Expand Up @@ -124,6 +125,7 @@ def __init__(
api_params (Dict[str, Dict[str, str]], optional): Extra params to be used for the openapi requests. Each key must be a full filename from schemas_folder. Defaults to an empty dictionary.
metadata (Dict[str, str], optional): Metadata associated with the agent. Defaults to an empty dictionary.
model (str, optional): The model identifier for the OpenAI API. Defaults to "gpt-4o".
reasoning_effort (Literal["low", "medium", "high"], optional): The reasoning effort for the model. Only for o-series models. Defaults to "medium".
validation_attempts (int, optional): Number of attempts to validate the response with response_validator function. Defaults to 1.
max_prompt_tokens (int, optional): Maximum number of tokens allowed in the prompt. Defaults to None.
max_completion_tokens (int, optional): Maximum number of tokens allowed in the completion. Defaults to None.
Expand Down Expand Up @@ -156,6 +158,7 @@ def __init__(
self.api_params = api_params if api_params else {}
self.metadata = metadata if metadata else {}
self.model = model
self.reasoning_effort = reasoning_effort
self.validation_attempts = validation_attempts
self.max_prompt_tokens = max_prompt_tokens
self.max_completion_tokens = max_completion_tokens
Expand Down Expand Up @@ -283,17 +286,43 @@ def init_oai(self):
continue

# create assistant if settings.json does not exist or assistant with the same name does not exist
self.assistant = self.client.beta.assistants.create(
model=self.model,
name=self.name,
description=self.description,
instructions=self.instructions,
tools=self.get_oai_tools(),
tool_resources=self.tool_resources,
metadata=self.metadata,
temperature=self.temperature,
top_p=self.top_p,
response_format=self.response_format,
self.assistant = self._create_assistant()

if self.assistant.tool_resources:
self.tool_resources = self.assistant.tool_resources.model_dump()

self.id = self.assistant.id

self._save_settings()

return self

def _create_assistant(self):
"""Creates a new OpenAI assistant with the agent's current configuration."""
params = {
"model": self.model,
"name": self.name,
"description": self.description,
"instructions": self.instructions,
"tools": self.get_oai_tools(),
"tool_resources": self.tool_resources,
"metadata": self.metadata,
"temperature": self.temperature,
"top_p": self.top_p,
"response_format": self.response_format,
}

extra_body = {}

# o-series models
if params['model'].startswith('o'):
params['temperature'] = None
params['top_p'] = None
extra_body['reasoning_effort'] = self.reasoning_effort

return self.client.beta.assistants.create(
**params,
extra_body=extra_body
)

if self.assistant.tool_resources:
Expand Down Expand Up @@ -331,11 +360,21 @@ def _update_assistant(self):
"metadata": self.metadata,
"model": self.model,
}
params = {k: v for k, v in params.items() if v}

extra_body = {}

# o-series models
if params['model'].startswith('o'):
params['temperature'] = None
params['top_p'] = None
extra_body['reasoning_effort'] = self.reasoning_effort

self.assistant = self.client.beta.assistants.update(
self.id,
**params,
extra_body=extra_body
)

self._update_settings()

def _upload_files(self):
Expand Down
4 changes: 3 additions & 1 deletion agency_swarm/messages/message_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,9 @@ def cprint_update(self, snapshot):
"""
Update the display with new snapshot content.
"""
self.content = snapshot # Update content with the latest snapshot
self.content = (
snapshot or "No content available"
) # Update content with the latest snapshot

header_text = self.formatted_header
md_content = Markdown(self.content)
Expand Down
16 changes: 15 additions & 1 deletion agency_swarm/threads/thread.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import asyncio
import inspect
import json
import logging
import os
import re
import time
Expand All @@ -18,6 +19,8 @@
from agency_swarm.util.oai import get_openai_client
from agency_swarm.util.streaming import AgencyEventHandler

logger = logging.getLogger(__name__)


class Thread:
async_mode: str = None
Expand Down Expand Up @@ -544,7 +547,11 @@ def _submit_tool_outputs(self, tool_outputs, event_handler=None, poll=True):
self._run = stream.get_final_run()

def _cancel_run(self, thread_id=None, run_id=None, check_status=True):
if check_status and self._run.status in self.terminal_states and not run_id:
if (
check_status
and (not self._run or self._run.status in self.terminal_states)
and not run_id
):
return

try:
Expand Down Expand Up @@ -697,6 +704,7 @@ def _await_coroutines(self, tool_outputs):
def _get_sync_async_tool_calls(self, tool_calls, recipient_agent):
async_tool_calls = []
sync_tool_calls = []

for tool_call in tool_calls:
if tool_call.function.name.startswith("SendMessage"):
sync_tool_calls.append(tool_call)
Expand All @@ -711,6 +719,12 @@ def _get_sync_async_tool_calls(self, tool_calls, recipient_agent):
None,
)

if tool is None:
logger.warning(
f"Tool {tool_call.function.name} not found in agent {recipient_agent.name}. Skipping."
)
continue

if (
hasattr(tool.ToolConfig, "async_mode") and tool.ToolConfig.async_mode
) or self.async_mode == "tools_threading":
Expand Down
16 changes: 12 additions & 4 deletions agency_swarm/tools/BaseTool.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,20 @@
from agency_swarm.util.shared_state import SharedState


class classproperty:
def __init__(self, fget):
self.fget = fget

def __get__(self, instance, owner):
return self.fget(owner)


class BaseTool(BaseModel, ABC):
_shared_state: ClassVar[SharedState] = None
_caller_agent: Any = None
_event_handler: Any = None
_tool_call: Any = None
openai_schema: ClassVar[dict[str, Any]]

def __init__(self, **kwargs):
if not self.__class__._shared_state:
Expand All @@ -37,14 +46,13 @@ class ToolConfig:
output_as_result: bool = False
async_mode: Union[Literal["threading"], None] = None

@classmethod
@property
def openai_schema(cls):
@classproperty
def openai_schema(cls) -> dict[str, Any]:
"""
Return the schema in the format of OpenAI's schema as jsonschema
Note:
Its important to add a docstring to describe how to best use this class, it will be included in the description attribute and be part of the prompt.
It's important to add a docstring to describe how to best use this class; it will be included in the description attribute and be part of the prompt.
Returns:
model_json_schema (dict): A dictionary in the format of OpenAI's schema as jsonschema
Expand Down
2 changes: 1 addition & 1 deletion agency_swarm/util/oai.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def get_openai_client():
)
client = openai.OpenAI(
api_key=api_key,
timeout=httpx.Timeout(60.0, read=40, connect=5.0),
timeout=httpx.Timeout(60, read=300, connect=5.0),
max_retries=10,
default_headers={"OpenAI-Beta": "assistants=v2"},
)
Expand Down
2 changes: 2 additions & 0 deletions docs/advanced-usage/open-source-models.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ PERPLEXITYAI_API_KEY=your_perplexityai_api_key
ANTHROPIC_API_KEY=your_anthropic_api_key
TOGETHER_API_KEY=your_together_api_key
GROQ_API_KEY=your_groq_api_key
AIML_API_KEY=your_aiml_api_key
```

**4. Install the Astra Assistants API and gradio:**
Expand Down Expand Up @@ -67,6 +68,7 @@ ceo = Agent(name="ceo",
# model = 'perplexity/llama-3-8b-instruct'
# model = 'anthropic/claude-3-5-sonnet-20240620'
# model = 'groq/mixtral-8x7b-32768'
# model = 'aiml/qwen-turbo'
# model="gpt-4o",
files_folder="path/to/your/files"
)
Expand Down
2 changes: 1 addition & 1 deletion notebooks/os_models_with_astra_assistants_api.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@
"\n",
" return original_user_message, history + [[user_message, None]]\n",
"\n",
" def bot(original_message, history):\n",
" def bot(original_message, history, dropdown):\n",
" nonlocal message_file_ids\n",
" nonlocal message_file_names\n",
" nonlocal recipient_agent\n",
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ dependencies = [
"rich==13.7.1",
"jsonref==1.1.0"
]
requires-python = ">=3.7"
requires-python = ">=3.10"
urls = { homepage = "https://github.com/VRSEN/agency-swarm" }

[project.scripts]
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setup(
name="agency-swarm",
version="0.4.1",
version="0.4.4",
author="VRSEN",
author_email="[email protected]",
description="An opensource agent orchestration framework built on top of the latest OpenAI Assistants API.",
Expand All @@ -23,5 +23,5 @@
entry_points={
"console_scripts": ["agency-swarm=agency_swarm.cli:main"],
},
python_requires=">=3.7",
python_requires=">=3.10",
)
3 changes: 2 additions & 1 deletion tests/demos/demo_gradio.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def run(self, **kwargs):
agency = Agency(
[
ceo,
[ceo, test_agent, test_agent2],
[ceo, test_agent],
[test_agent, test_agent2],
],
shared_instructions="",
settings_path="./test_settings.json",
Expand Down

0 comments on commit 03c8ce3

Please sign in to comment.