iointel 1.3.3__tar.gz → 1.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {iointel-1.3.3 → iointel-1.3.4}/.github/workflows/tests.yaml +18 -8
- {iointel-1.3.3 → iointel-1.3.4}/PKG-INFO +4 -2
- iointel-1.3.4/docker-compose.yml +33 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/__init__.py +1 -1
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/agents/tool_factory.py +6 -2
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/data_models/datamodels.py +1 -1
- iointel-1.3.4/iointel/src/agent_methods/tools/agno/agentql.py +21 -0
- iointel-1.3.4/iointel/src/agent_methods/tools/agno/airflow.py +22 -0
- iointel-1.3.4/iointel/src/agent_methods/tools/agno/arxiv.py +27 -0
- iointel-1.3.4/iointel/src/agent_methods/tools/agno/aws_lambda.py +20 -0
- iointel-1.3.4/iointel/src/agent_methods/tools/agno/common.py +11 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/duckduckgo.py +13 -1
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/decorators.py +1 -1
- {iointel-1.3.3 → iointel-1.3.4}/pyproject.toml +3 -1
- iointel-1.3.4/tests/conftest.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_with_agents/test_basic_agent_tools.py +1 -1
- iointel-1.3.3/Makefile +0 -38
- {iointel-1.3.3 → iointel-1.3.4}/.gitattributes +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/.github/workflows/codeql.yaml +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/.github/workflows/linting.yaml +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/.github/workflows/release.yaml +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/.gitignore +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/.pre-commit-config.yaml +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/LICENSE +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/README.md +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/creds.env.example +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/client/__init__.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/client/client.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/__init__.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/__init__.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/agents/__init__.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/agents/agents_factory.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/data_models/__init__.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/prompts/__init__.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/prompts/instructions.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/__init__.py +0 -0
- {iointel-1.3.3/iointel/src/code_parsers → iointel-1.3.4/iointel/src/agent_methods/tools/agno}/__init__.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/coinmarketcap.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/firecrawl.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/r2r.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/searxng.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/solscan.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/tools.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/utils.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agent_methods/tools/wolfram.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/agents.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/chainables.py +0 -0
- /iointel-1.3.3/tests/conftest.py → /iointel-1.3.4/iointel/src/code_parsers/__init__.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/code_parsers/jscode_parser.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/code_parsers/pycode_parser.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/memory.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/task.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/constants.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/exceptions.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/func_metadata.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/graph_nodes.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/helpers.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/registries.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/rich.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/runners.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/utilities/stages.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/iointel/src/workflow.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/test-runner +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_agents.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_client.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_stages.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tasks.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_isolated/test_coinmarketcap.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_isolated/test_duckduckgo.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_isolated/test_firecrawl_tool.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_isolated/test_r2r.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_isolated/test_searxng.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_isolated/test_solscan.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_isolated/test_wolfram.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_with_agents/test_coinmarketcap_agent.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_with_agents/test_crawl_agent.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_with_agents/test_duckduckgo_agent.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_with_agents/test_searxng_agent.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_tools_with_agents/test_wolframalpha_agent.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_utilities.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/tests/test_workflows.py +0 -0
- {iointel-1.3.3 → iointel-1.3.4}/uv.lock +0 -0
|
@@ -52,21 +52,31 @@ jobs:
|
|
|
52
52
|
uses: actions/setup-python@v5
|
|
53
53
|
with:
|
|
54
54
|
python-version: ${{ matrix.python-version }}
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
- name: download uv
|
|
57
57
|
run: curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
- name: Install dependencies
|
|
60
60
|
run: uv pip install --system -e ".[dev]"
|
|
61
|
+
|
|
62
|
+
- name: Check readme anchors
|
|
63
|
+
run: |
|
|
64
|
+
pip install pipx
|
|
65
|
+
pipx run hatch-fancy-pypi-readme | grep -vq 'MISSING ANCHOR'
|
|
66
|
+
|
|
67
|
+
- name: Set up Docker Compose
|
|
68
|
+
uses: docker/setup-buildx-action@v3
|
|
61
69
|
|
|
62
|
-
- name:
|
|
63
|
-
run:
|
|
70
|
+
- name: Start services
|
|
71
|
+
run: |
|
|
72
|
+
docker compose up -d
|
|
73
|
+
# Wait for searxng to be healthy by checking the health endpoint directly
|
|
74
|
+
timeout 60s bash -c 'until curl -s -f http://localhost:8080/healthz > /dev/null; do sleep 2; done'
|
|
64
75
|
|
|
65
76
|
- name: Run tests
|
|
66
77
|
run: pytest -vv tests/ --retries 2 --retry-delay 5
|
|
67
78
|
if: ${{ !(github.event.pull_request.head.repo.fork) }}
|
|
68
79
|
|
|
69
|
-
- name:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
pipx run hatch-fancy-pypi-readme | grep -vq 'MISSING ANCHOR'
|
|
80
|
+
- name: Remove containers
|
|
81
|
+
if: always() # This ensures cleanup happens even if tests fail
|
|
82
|
+
run: docker compose down -v
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iointel
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.4
|
|
4
4
|
Summary: A framework to create agents, tasks, and workflows.
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Keywords: AI,Agents,LLM,framework,tools
|
|
7
7
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
8
8
|
Requires-Python: >=3.10
|
|
9
|
-
Requires-Dist:
|
|
9
|
+
Requires-Dist: agno[tools]==1.5.5
|
|
10
|
+
Requires-Dist: backoff==2.2.1
|
|
11
|
+
Requires-Dist: duckduckgo-search==8.0.2
|
|
10
12
|
Requires-Dist: firecrawl-py>=2.2.0
|
|
11
13
|
Requires-Dist: firecrawl>=2.2.0
|
|
12
14
|
Requires-Dist: httpx
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
searxng:
|
|
5
|
+
image: searxng/searxng
|
|
6
|
+
container_name: iointel-searxng
|
|
7
|
+
ports:
|
|
8
|
+
- "8080:8080"
|
|
9
|
+
volumes:
|
|
10
|
+
- searxng_config:/etc/searxng
|
|
11
|
+
environment:
|
|
12
|
+
- BASE_URL=http://localhost:8080/
|
|
13
|
+
- INSTANCE_NAME=my-instance
|
|
14
|
+
healthcheck:
|
|
15
|
+
test: ["CMD", "curl", "-f", "http://localhost:8080/healthz"]
|
|
16
|
+
interval: 30s
|
|
17
|
+
timeout: 10s
|
|
18
|
+
retries: 3
|
|
19
|
+
start_period: 5s
|
|
20
|
+
restart: unless-stopped
|
|
21
|
+
|
|
22
|
+
# Service to modify settings.yml
|
|
23
|
+
setup:
|
|
24
|
+
image: python:3-slim
|
|
25
|
+
volumes:
|
|
26
|
+
- searxng_config:/etc/searxng
|
|
27
|
+
command: ["bash", "-c", "pip install pyyaml && python3 -c 'import yaml; f=\"/etc/searxng/settings.yml\"; d=yaml.safe_load(open(f)); d.setdefault(\"search\",{}).setdefault(\"formats\",[]).append(\"json\"); open(f,\"w\").write(yaml.safe_dump(d))'"]
|
|
28
|
+
depends_on:
|
|
29
|
+
- searxng
|
|
30
|
+
|
|
31
|
+
volumes:
|
|
32
|
+
searxng_config:
|
|
33
|
+
name: iointel-searxng-config
|
|
@@ -63,7 +63,11 @@ def resolve_tools(params: AgentParams) -> List[Optional[Callable]]:
|
|
|
63
63
|
"""
|
|
64
64
|
resolved_tools = []
|
|
65
65
|
for tool_data in params.tools:
|
|
66
|
-
if isinstance(tool_data,
|
|
66
|
+
if isinstance(tool_data, str):
|
|
67
|
+
logger.debug(f"Looking up the registry for tool `{tool_data}`")
|
|
68
|
+
if not (tool_obj := TOOLS_REGISTRY.get(tool_data)):
|
|
69
|
+
raise ValueError(f"Tool {tool_data} is not known")
|
|
70
|
+
elif isinstance(tool_data, dict):
|
|
67
71
|
logger.debug(f"Rehydrating tool from dict: {tool_data}")
|
|
68
72
|
tool_obj = Tool.model_validate(tool_data)
|
|
69
73
|
if "body" in tool_data:
|
|
@@ -82,7 +86,7 @@ def resolve_tools(params: AgentParams) -> List[Optional[Callable]]:
|
|
|
82
86
|
tool_obj = Tool.from_function(tool_data)
|
|
83
87
|
else:
|
|
84
88
|
raise ValueError(
|
|
85
|
-
"Unexpected type for tool_data; expected dict, Tool instance, or callable."
|
|
89
|
+
"Unexpected type for tool_data; expected str, dict, Tool instance, or callable."
|
|
86
90
|
)
|
|
87
91
|
|
|
88
92
|
registered_tool_name, registered_tool = next(
|
|
@@ -400,7 +400,7 @@ class AgentParams(BaseModel):
|
|
|
400
400
|
base_url: Optional[str] = Field(
|
|
401
401
|
None, description="Base URL for the model, if required."
|
|
402
402
|
)
|
|
403
|
-
tools: Optional[List[dict | Tool | Callable]] = Field(default_factory=list)
|
|
403
|
+
tools: Optional[List[str | dict | Tool | Callable]] = Field(default_factory=list)
|
|
404
404
|
context: Optional[Dict[str, Any]] = Field(
|
|
405
405
|
None,
|
|
406
406
|
description="Context to be passed to the agent.",
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from functools import wraps
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from agno.tools.agentql import AgentQLTools as AgnoAgentQLTools
|
|
4
|
+
|
|
5
|
+
from ..utils import register_tool
|
|
6
|
+
from .common import DisableAgnoRegistryMixin
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class AgentQL(DisableAgnoRegistryMixin, AgnoAgentQLTools):
|
|
10
|
+
def __init__(self, api_key: Optional[str] = None, agentql_query: str = ""):
|
|
11
|
+
super().__init__(api_key=api_key, scrape=True, agentql_query=agentql_query)
|
|
12
|
+
|
|
13
|
+
@register_tool(name="agentql_scrape_website")
|
|
14
|
+
@wraps(AgnoAgentQLTools.scrape_website)
|
|
15
|
+
def scrape_website(self, url: str) -> str:
|
|
16
|
+
return super().scrape_website(url)
|
|
17
|
+
|
|
18
|
+
@register_tool(name="agentql_custom_scrape_website")
|
|
19
|
+
@wraps(AgnoAgentQLTools.custom_scrape_website)
|
|
20
|
+
def custom_scrape_website(self, url: str) -> str:
|
|
21
|
+
return super().custom_scrape_website(url)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Optional, Union
|
|
3
|
+
from functools import wraps
|
|
4
|
+
from agno.tools.airflow import AirflowTools as AgnoAirflowTools
|
|
5
|
+
|
|
6
|
+
from ..utils import register_tool
|
|
7
|
+
from .common import DisableAgnoRegistryMixin
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Airflow(DisableAgnoRegistryMixin, AgnoAirflowTools):
|
|
11
|
+
def __init__(self, dags_dir: Optional[Union[Path, str]] = None):
|
|
12
|
+
super().__init__(dags_dir=dags_dir, save_dag=True, read_dag=True)
|
|
13
|
+
|
|
14
|
+
@register_tool(name="airflow_save_dag_file")
|
|
15
|
+
@wraps(AgnoAirflowTools.save_dag_file)
|
|
16
|
+
def save_dag_file(self, contents: str, dag_file: str) -> str:
|
|
17
|
+
return super().save_dag_file(contents=contents, dag_file=dag_file)
|
|
18
|
+
|
|
19
|
+
@register_tool(name="airflow_read_dag_file")
|
|
20
|
+
@wraps(AgnoAirflowTools.read_dag_file)
|
|
21
|
+
def read_dag_file(self, dag_file: str) -> str:
|
|
22
|
+
return super().read_dag_file(dag_file=dag_file)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from functools import wraps
|
|
4
|
+
from agno.tools.arxiv import ArxivTools as AgnoArxivTools
|
|
5
|
+
|
|
6
|
+
from ..utils import register_tool
|
|
7
|
+
from .common import DisableAgnoRegistryMixin
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Arxiv(DisableAgnoRegistryMixin, AgnoArxivTools):
|
|
11
|
+
def __init__(self, download_dir: Optional[Path] = None):
|
|
12
|
+
# TODO: define a better default option for downloading pdfs, agno arxiv has a weird choice
|
|
13
|
+
super().__init__(download_dir=download_dir)
|
|
14
|
+
|
|
15
|
+
@register_tool(name="arxiv_search")
|
|
16
|
+
@wraps(AgnoArxivTools.search_arxiv_and_return_articles)
|
|
17
|
+
def search_arxiv_and_return_articles(
|
|
18
|
+
self, query: str, num_articles: int = 10
|
|
19
|
+
) -> str:
|
|
20
|
+
return super().search_arxiv_and_return_articles(query, num_articles)
|
|
21
|
+
|
|
22
|
+
@register_tool(name="arxiv_read_papers")
|
|
23
|
+
@wraps(AgnoArxivTools.read_arxiv_papers)
|
|
24
|
+
def read_arxiv_papers(
|
|
25
|
+
self, id_list: list[str], pages_to_read: Optional[int] = None
|
|
26
|
+
) -> str:
|
|
27
|
+
return super().read_arxiv_papers(id_list, pages_to_read)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from functools import wraps
|
|
2
|
+
from agno.tools.aws_lambda import AWSLambdaTools as AgnoAWSLambdaTools
|
|
3
|
+
|
|
4
|
+
from ..utils import register_tool
|
|
5
|
+
from .common import DisableAgnoRegistryMixin
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AWSLambda(DisableAgnoRegistryMixin, AgnoAWSLambdaTools):
|
|
9
|
+
def __init__(self, region_name: str = "us-east-1"):
|
|
10
|
+
super().__init__(region_name=region_name)
|
|
11
|
+
|
|
12
|
+
@register_tool(name="aws_lambda_list_functions")
|
|
13
|
+
@wraps(AgnoAWSLambdaTools.list_functions)
|
|
14
|
+
def list_functions(self) -> str:
|
|
15
|
+
return super().list_functions()
|
|
16
|
+
|
|
17
|
+
@register_tool(name="aws_lambda_invoke_function")
|
|
18
|
+
@wraps(AgnoAWSLambdaTools.invoke_function)
|
|
19
|
+
def invoke_function(self, function_name: str, payload: str = "{}") -> str:
|
|
20
|
+
return super().invoke_function(function_name=function_name, payload=payload)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
class DisableAgnoRegistryMixin:
|
|
2
|
+
"""
|
|
3
|
+
Put this as first parent class when inheriting
|
|
4
|
+
from Agno tool to disable Agno registry,
|
|
5
|
+
because we only care about our own registry."""
|
|
6
|
+
|
|
7
|
+
def _register_tools(self):
|
|
8
|
+
"""Disabled in favour of iointel registry."""
|
|
9
|
+
|
|
10
|
+
def register(self, function, name=None):
|
|
11
|
+
"""Disabled in favour of iointel registry."""
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from typing import Any, Dict, List, Optional
|
|
3
|
+
import backoff
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
from duckduckgo import DuckDuckGoSearchException
|
|
7
|
+
except ImportError:
|
|
8
|
+
DuckDuckGoSearchException = Exception
|
|
3
9
|
|
|
4
10
|
from iointel.src.utilities.decorators import register_tool
|
|
5
11
|
from pydantic import BaseModel, ConfigDict, model_validator
|
|
@@ -24,7 +30,7 @@ class DuckDuckGoSearchAPIWrapper(BaseModel):
|
|
|
24
30
|
Options: d, w, m, y
|
|
25
31
|
"""
|
|
26
32
|
max_results: int = 5
|
|
27
|
-
backend: str = "
|
|
33
|
+
backend: str = "html"
|
|
28
34
|
"""
|
|
29
35
|
Options: auto, html, lite
|
|
30
36
|
"""
|
|
@@ -46,6 +52,12 @@ class DuckDuckGoSearchAPIWrapper(BaseModel):
|
|
|
46
52
|
) from e
|
|
47
53
|
return values
|
|
48
54
|
|
|
55
|
+
@backoff.on_exception(
|
|
56
|
+
backoff.expo,
|
|
57
|
+
exception=(DuckDuckGoSearchException,),
|
|
58
|
+
max_tries=5,
|
|
59
|
+
jitter=backoff.random_jitter,
|
|
60
|
+
)
|
|
49
61
|
def _ddgs(
|
|
50
62
|
self, query: str, max_results: Optional[int] = None
|
|
51
63
|
) -> List[Dict[str, str]]:
|
|
@@ -97,7 +97,7 @@ def register_tool(_fn=None, name: Optional[str] = None):
|
|
|
97
97
|
logger.debug(f"Tool '{tool_name}' is already safely registered.")
|
|
98
98
|
return executor_fn
|
|
99
99
|
|
|
100
|
-
TOOLS_REGISTRY[tool_name] = Tool.from_function(executor_fn)
|
|
100
|
+
TOOLS_REGISTRY[tool_name] = Tool.from_function(executor_fn, name=tool_name)
|
|
101
101
|
logger.debug(f"Registered tool '{tool_name}' safely.")
|
|
102
102
|
return executor_fn
|
|
103
103
|
|
|
@@ -10,7 +10,7 @@ dependencies = [
|
|
|
10
10
|
"python-multipart>=0.0.20",
|
|
11
11
|
"pydantic-ai>=0.1.0",
|
|
12
12
|
"pyyaml>=6.0.2",
|
|
13
|
-
"duckduckgo-search==8.0.
|
|
13
|
+
"duckduckgo-search==8.0.2",
|
|
14
14
|
"pgvector>=0.4.0",
|
|
15
15
|
"sqlalchemy-utils>=0.41.2",
|
|
16
16
|
"sqlalchemy>=2.0.36",
|
|
@@ -18,6 +18,8 @@ dependencies = [
|
|
|
18
18
|
# For some reason both firecrawl-py and firecrawl are necessary
|
|
19
19
|
"firecrawl-py>=2.2.0",
|
|
20
20
|
"firecrawl>=2.2.0",
|
|
21
|
+
"backoff==2.2.1",
|
|
22
|
+
"agno[tools]==1.5.5",
|
|
21
23
|
]
|
|
22
24
|
keywords = ["Agents", "LLM", "framework", "AI", "tools"]
|
|
23
25
|
classifiers = [
|
|
File without changes
|
|
@@ -34,7 +34,7 @@ async def test_basic_tools():
|
|
|
34
34
|
Complete tasks to the best of your ability by using the appropriate tool. Follow all instructions carefully.
|
|
35
35
|
When you need to add numbers, call the tool and use its result.
|
|
36
36
|
""",
|
|
37
|
-
tools=[add_two_numbers, get_current_datetime],
|
|
37
|
+
tools=["add_two_numbers", get_current_datetime],
|
|
38
38
|
)
|
|
39
39
|
numbers = [22122837493142, 159864395786239452]
|
|
40
40
|
|
iointel-1.3.3/Makefile
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
prepare_for_tests:
|
|
2
|
-
export PORT=8080
|
|
3
|
-
docker pull searxng/searxng
|
|
4
|
-
docker stop iointel-searxng || true
|
|
5
|
-
|
|
6
|
-
# Run searxng to generate default settings.yml
|
|
7
|
-
# Then edit settings.yml to support json format in the output, and restart docker with updated settings
|
|
8
|
-
docker run --rm -d \
|
|
9
|
-
-p ${PORT}:8080 \
|
|
10
|
-
-v "${PWD}/searxng:/etc/searxng" \
|
|
11
|
-
-e "BASE_URL=http://localhost:${PORT}/" \
|
|
12
|
-
-e "INSTANCE_NAME=my-instance" \
|
|
13
|
-
--name iointel-searxng \
|
|
14
|
-
searxng/searxng
|
|
15
|
-
sleep 5
|
|
16
|
-
docker stop iointel-searxng || true
|
|
17
|
-
|
|
18
|
-
sudo python3 -c "import yaml; f='searxng/settings.yml'; d=yaml.safe_load(open(f)); d.setdefault('search',{}).setdefault('formats',[]).append('json'); open(f,'w').write(yaml.safe_dump(d))"
|
|
19
|
-
|
|
20
|
-
docker run --rm -d \
|
|
21
|
-
-p ${PORT}:8080 \
|
|
22
|
-
-v "${PWD}/searxng:/etc/searxng" \
|
|
23
|
-
-e "BASE_URL=http://localhost:${PORT}/" \
|
|
24
|
-
-e "INSTANCE_NAME=my-instance" \
|
|
25
|
-
--name iointel-searxng \
|
|
26
|
-
searxng/searxng
|
|
27
|
-
sleep 5
|
|
28
|
-
# # Retrieve the response from localhost:8080 silently.
|
|
29
|
-
# @response=$$(curl -s localhost:8080) ; \
|
|
30
|
-
# if [ -n "$$response" ]; then \
|
|
31
|
-
# echo "Success: Server returned output."; \
|
|
32
|
-
# else \
|
|
33
|
-
# echo "Error: No output received from server."; \
|
|
34
|
-
# exit 1; \
|
|
35
|
-
# fi
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
.PHONY: prepare_for_tests
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|