diff --git a/example/AutoAgent.ipynb b/example/AutoAgent.ipynb index 7cb1ba8..291700e 100644 --- a/example/AutoAgent.ipynb +++ b/example/AutoAgent.ipynb @@ -12,13 +12,13 @@ "\n", "base_url= \"\" # use your own base_url from api provider or local provider like ollama.\n", "api_key = \"\" # use your own api_key.\n", - "provider = \"openai\" # openai for openai like provider (vLLM or openrouter) and ollama for local use.\n", + "# provider = \"openai\" # Deprecated No need for provider any more\n", "model = \"gpt-4o-mini\"" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "6057cd04", "metadata": {}, "outputs": [ @@ -46,7 +46,7 @@ "source": [ "from iragent.tools import get_time_now, simple_termination\n", "\n", - "factory = AgentFactory(base_url,api_key, model, provider)\n", + "factory = AgentFactory(base_url,api_key, model)\n", "\n", "agent1 = factory.create_agent(name=\"time_reader\",\n", " system_prompt=\"You are that one who can read time. there is a fucntion named get_time_now(), you can call it whether user ask about time or date.\",\n", diff --git a/example/BaseMemory.ipynb b/example/BaseMemory.ipynb index 4a7c3db..59bed6f 100644 --- a/example/BaseMemory.ipynb +++ b/example/BaseMemory.ipynb @@ -12,7 +12,7 @@ "\n", "base_url= \"\" # use your own base_url from api provider or local provider like ollama.\n", "api_key = \"\" # use your own api_key.\n", - "provider = \"openai\" # openai for openai like provider (vLLM or openrouter) and ollama for local use.\n", + "# provider = \"openai\" # Deprecated No need for provider any more\n", "model = \"gpt-4o-mini\"\n" ] }, @@ -59,7 +59,7 @@ "from iragent.memory import BaseMemory\n", "from iragent.tools import get_time_now, simple_termination\n", "\n", - "factory = AgentFactory(base_url,api_key, model, provider)\n", + "factory = AgentFactory(base_url,api_key, model)\n", "\n", "agent1 = factory.create_agent(name=\"time_reader\",\n", " system_prompt=\"You are that one who can read time. there is a fucntion named get_time_now(), you can call it whether user ask about time or date.\",\n", diff --git a/example/InternetSearch.ipynb b/example/InternetSearch.ipynb index d719a3a..f710204 100644 --- a/example/InternetSearch.ipynb +++ b/example/InternetSearch.ipynb @@ -11,13 +11,13 @@ "\n", "base_url= \"\" # use your own base_url from api provider or local provider like ollama.\n", "api_key = \"\" # use your own api_key.\n", - "provider = \"openai\" # openai for openai like provider (vLLM or openrouter) and ollama for local use.\n", + "# provider = \"openai\" # Deprecated No need for provider any more\n", "model = \"gpt-4o-mini\"\n" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "id": "10412d76", "metadata": {}, "outputs": [], @@ -29,7 +29,6 @@ " api_key=api_key,\n", " temperature=0.1,\n", " max_token=512,\n", - " provider=\"openai\" # or ollama for local use \n", ")\n" ] }, diff --git a/example/SmartAgentBuilder.ipynb b/example/SmartAgentBuilder.ipynb index 42691c6..f1e7a7d 100644 --- a/example/SmartAgentBuilder.ipynb +++ b/example/SmartAgentBuilder.ipynb @@ -19,13 +19,13 @@ "source": [ "base_url= \"\" # use your own base_url from api provider or local provider like ollama.\n", "api_key = \"\" # use your own api_key.\n", - "provider = \"openai\" # openai for openai like provider (vLLM or openrouter) and ollama for local use.\n", + "# provider = \"openai\" # Deprecated No need for provider any more\n", "model = \"gpt-4o-mini\"" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "10561d55", "metadata": {}, "outputs": [ @@ -47,7 +47,6 @@ " base_url=base_url,\n", " api_key=api_key,\n", " model=model,\n", - " provider=\"openai\"\n", ")\n", "\n", "sab = SmartAgentBuilder(\n", diff --git a/example/SmartPrompt.ipynb b/example/SmartPrompt.ipynb index b6b7c4e..44f7bc1 100644 --- a/example/SmartPrompt.ipynb +++ b/example/SmartPrompt.ipynb @@ -9,13 +9,13 @@ "source": [ "base_url= \"\" # use your own base_url from api provider or local provider like ollama.\n", "api_key = \"\" # use your own api_key.\n", - "provider = \"openai\" # openai for openai like provider (vLLM or openrouter) and ollama for local use.\n", + "# provider = \"openai\" # Deprecated No need for provider any more\n", "model = \"gpt-4o-mini\"" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "id": "686c8d4a", "metadata": {}, "outputs": [ @@ -89,7 +89,6 @@ " base_url=base_url,\n", " api_key=api_key,\n", " model=model,\n", - " provider=\"openai\"\n", ")\n", "\n", "sp = SmartPrompt(agent_factory=agent_factory)\n", diff --git a/example/StructuredOutput.ipynb b/example/StructuredOutput.ipynb index f9d75f0..8ad41d3 100644 --- a/example/StructuredOutput.ipynb +++ b/example/StructuredOutput.ipynb @@ -12,7 +12,7 @@ "\n", "base_url= \"\" # use your own base_url from api provider or local provider like ollama.\n", "api_key = \"\" # use your own api_key.\n", - "provider = \"openai\" # openai for openai like provider (vLLM or openrouter) and ollama for local use.\n", + "# provider = \"openai\" # Deprecated No need for provider any more.\n", "model = \"gpt-4o-mini\"" ] }, @@ -39,7 +39,6 @@ " base_url=base_url,\n", " api_key=api_key,\n", " model=model,\n", - " provider=provider\n", ")\n", "\n", "PROMPT = \"\"\"\n", diff --git a/example/SummarizerMemory.ipynb b/example/SummarizerMemory.ipynb index ea457f3..58bd1fa 100644 --- a/example/SummarizerMemory.ipynb +++ b/example/SummarizerMemory.ipynb @@ -17,7 +17,7 @@ "source": [ "base_url= \"\" # use your own base_url from api provider or local provider like ollama.\n", "api_key = \"\" # use your own api_key.\n", - "provider = \"openai\" # openai for openai like provider (vLLM or openrouter) and ollama for local use.\n", + "# provider = \"openai\" # Deprecated No need for provider any more\n", "model = \"gpt-4o-mini\"" ] }, @@ -31,7 +31,7 @@ "from iragent.agent import AgentFactory\n", "from iragent.memory import SummarizerMemory\n", "\n", - "factory = AgentFactory(base_url, api_key, model, provider)\n", + "factory = AgentFactory(base_url, api_key, model)\n", "\n", "def log_task(task: str) -> str:\n", " return f\"Task '{task}' logged successfully.\"\n", diff --git a/iragent/__pycache__/agent.cpython-312.pyc b/iragent/__pycache__/agent.cpython-312.pyc index 341f358..b7ca1fa 100644 Binary files a/iragent/__pycache__/agent.cpython-312.pyc and b/iragent/__pycache__/agent.cpython-312.pyc differ diff --git a/iragent/__pycache__/models.cpython-312.pyc b/iragent/__pycache__/models.cpython-312.pyc index 15dd947..f8117ba 100644 Binary files a/iragent/__pycache__/models.cpython-312.pyc and b/iragent/__pycache__/models.cpython-312.pyc differ diff --git a/iragent/__pycache__/prompts.cpython-312.pyc b/iragent/__pycache__/prompts.cpython-312.pyc index 0f3c12b..ebcf1fe 100644 Binary files a/iragent/__pycache__/prompts.cpython-312.pyc and b/iragent/__pycache__/prompts.cpython-312.pyc differ diff --git a/iragent/agent.py b/iragent/agent.py index d7ff45f..3354633 100644 --- a/iragent/agent.py +++ b/iragent/agent.py @@ -1,6 +1,7 @@ import inspect import json import re +import warnings from typing import Any, Callable, Dict, List, get_type_hints import requests @@ -79,13 +80,26 @@ def call_message(self, message: Message, **kwargs) -> str: # Add to memory if it is first time if self.memory: self.memory.add_history(user_msg) + # Provider will be removed in v0.1.8 + # TODO: Remove provider and use just one of them. + if self.provider: + warnings.warn( + "'provider' is deprecated and will be removed in the next release. " + "You no longer need to define 'provider' — the package will automatically " + "select the appropriate backend.", + FutureWarning, # or DeprecationWarning if you want it hidden by default + stacklevel=2 + ) - if self.provider == "openai": - res = self._call_openai(msgs=msgs, message=message, **kwargs) - elif self.provider == "ollama": - res = self._call_ollama_v2(msgs=msgs, message=message) + if self.provider == "openai": + res = self._call_openai(msgs=msgs, message=message, **kwargs) + elif self.provider == "ollama": + res = self._call_ollama_v2(msgs=msgs, message=message) + else: + raise ValueError(f"Unsupported provider: {self.provider}") + else: - raise ValueError(f"Unsupported provider: {self.provider}") + res = self._call_ollama_v2(msgs=msgs, message=message) if self.memory: @@ -183,7 +197,8 @@ def _call_ollama_v2(self, msgs: List[Dict], message: Message) -> Message: max_tokens=self.max_token, temperature=self.temprature, ) - + if self.response_format: + kwargs["response_format"] = self.response_format if self.fn: kwargs["tools"] = [{"type": "function", "function": f} for f in self.fn] response = self.client.chat.completions.create(**kwargs) @@ -198,7 +213,7 @@ def _call_ollama_v2(self, msgs: List[Dict], message: Message) -> Message: followup = self.client.chat.completions.create( model=self.model, messages=msgs - + [msg, {"role": "tool", "name": fn_name, "content": str(result)}], + + [msg, {"role": "tool","tool_call_id": msg.tool_calls[0].id, "name": fn_name, "content": str(result)}], max_tokens=self.max_token, temperature=self.temprature, ) @@ -208,6 +223,18 @@ def _call_ollama_v2(self, msgs: List[Dict], message: Message) -> Message: content=followup.choices[0].message.content.strip(), metadata={"reply_to": message.metadata.get("message_id")}, ) + # Handle response format + if self.response_format: + try: + parsed_content = json.loads(msg.content) + except json.JSONDecodeError: + parsed_content = {"error": "Invalid JSON response", "raw": msg.content} + return Message( + sender=self.name, + reciever=self.next_agent or message.sender, + content=parsed_content, + metadata={"reply_to": message.metadata.get("message_id")}, + ) return Message( sender=self.name, @@ -242,7 +269,7 @@ def _call_openai(self, msgs: List[Dict], message: Message, **kwargs) -> Message: messages=msgs + [ msg, - {"role": "function", "name": fn_name, "content": str(result)}, + {"role": "function", "tool_call_id": msg.tool_calls[0].id, "name": fn_name, "content": str(result)}, ], max_tokens=self.max_token, temperature=self.temprature, @@ -366,7 +393,7 @@ class AgentFactory: Creates and returns a new Agent instance using the shared configuration and any additional keyword arguments. """ - def __init__(self, base_url: str, api_key: str, model: str, provider: str = "openai") -> Agent: + def __init__(self, base_url: str, api_key: str, model: str, provider: str = None) -> Agent: self.base_url = base_url self.api_key = api_key self.model = model diff --git a/pyproject.toml b/pyproject.toml index 4aaa3fb..3fec020 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "iragent" -version = "0.1.6" +version = "0.1.7" description = "A simple multi-agent framework" authors = [{ name = "Parsa Bakhtiari", email = "spacenavard1@gmail.com" }] readme = "README.md" @@ -13,21 +13,19 @@ dependencies = [ "beautifulsoup4", "lxml", "nltk", - "pytest" + "pytest", + "tiktoken", + "numpy" ] # For RAG usage [project.optional-dependencies] rag = [ "faiss-cpu", "sentence-transformers", - "numpy", - "tiktoken" ] rag-gpu = [ "faiss-gpu", "sentence-transformers", - "numpy", - "tiktoken" ] [build-system]