-
Notifications
You must be signed in to change notification settings - Fork 80
Add GibsonAI toolkit #493
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Boburmirzo
wants to merge
3
commits into
ArcadeAI:main
Choose a base branch
from
Boburmirzo:main
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Add GibsonAI toolkit #493
Changes from 1 commit
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| files: ^.*/gibsonai/.* | ||
| repos: | ||
| - repo: https://github.com/pre-commit/pre-commit-hooks | ||
| rev: "v4.4.0" | ||
| hooks: | ||
| - id: check-case-conflict | ||
| - id: check-merge-conflict | ||
| - id: check-toml | ||
| - id: check-yaml | ||
| - id: end-of-file-fixer | ||
| - id: trailing-whitespace | ||
|
|
||
| - repo: https://github.com/astral-sh/ruff-pre-commit | ||
| rev: v0.6.7 | ||
| hooks: | ||
| - id: ruff | ||
| args: [--fix] | ||
| - id: ruff-format |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| target-version = "py310" | ||
| line-length = 100 | ||
| fix = true | ||
|
|
||
| [lint] | ||
| select = [ | ||
| # flake8-2020 | ||
| "YTT", | ||
| # flake8-bandit | ||
| "S", | ||
| # flake8-bugbear | ||
| "B", | ||
| # flake8-builtins | ||
| "A", | ||
| # flake8-comprehensions | ||
| "C4", | ||
| # flake8-debugger | ||
| "T10", | ||
| # flake8-simplify | ||
| "SIM", | ||
| # isort | ||
| "I", | ||
| # mccabe | ||
| "C90", | ||
| # pycodestyle | ||
| "E", "W", | ||
| # pyflakes | ||
| "F", | ||
| # pygrep-hooks | ||
| "PGH", | ||
| # pyupgrade | ||
| "UP", | ||
| # ruff | ||
| "RUF", | ||
| # tryceratops | ||
| "TRY", | ||
| ] | ||
|
|
||
| [lint.per-file-ignores] | ||
| "*" = ["TRY003", "B904"] | ||
| "**/tests/*" = ["S101", "E501"] | ||
| "**/evals/*" = ["S101", "E501"] | ||
|
|
||
|
|
||
| [format] | ||
| preview = true | ||
| skip-magic-trailing-comma = false |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| .PHONY: help | ||
|
|
||
| help: | ||
| @echo "🛠️ github Commands:\n" | ||
| @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' | ||
|
|
||
| .PHONY: install | ||
| install: ## Install the uv environment and install all packages with dependencies | ||
| @echo "🚀 Creating virtual environment and installing all packages using uv" | ||
| @uv sync --active --all-extras --no-sources | ||
| @if [ -f .pre-commit-config.yaml ]; then uv run --no-sources pre-commit install; fi | ||
| @echo "✅ All packages and dependencies installed via uv" | ||
|
|
||
| .PHONY: install-local | ||
| install-local: ## Install the uv environment and install all packages with dependencies with local Arcade sources | ||
| @echo "🚀 Creating virtual environment and installing all packages using uv" | ||
| @uv sync --active --all-extras | ||
| @if [ -f .pre-commit-config.yaml ]; then uv run pre-commit install; fi | ||
| @echo "✅ All packages and dependencies installed via uv" | ||
|
|
||
| .PHONY: build | ||
| build: clean-build ## Build wheel file using poetry | ||
| @echo "🚀 Creating wheel file" | ||
| uv build | ||
|
|
||
| .PHONY: clean-build | ||
| clean-build: ## clean build artifacts | ||
| @echo "🗑️ Cleaning dist directory" | ||
| rm -rf dist | ||
|
|
||
| .PHONY: test | ||
| test: ## Test the code with pytest | ||
| @echo "🚀 Testing code: Running pytest" | ||
| @uv run --no-sources pytest -W ignore -v --cov --cov-config=pyproject.toml --cov-report=xml | ||
|
|
||
| .PHONY: coverage | ||
| coverage: ## Generate coverage report | ||
| @echo "coverage report" | ||
| @uv run --no-sources coverage report | ||
| @echo "Generating coverage report" | ||
| @uv run --no-sources coverage html | ||
|
|
||
| .PHONY: bump-version | ||
| bump-version: ## Bump the version in the pyproject.toml file by a patch version | ||
| @echo "🚀 Bumping version in pyproject.toml" | ||
| uv version --no-sources --bump patch | ||
|
|
||
| .PHONY: check | ||
| check: ## Run code quality tools. | ||
| @if [ -f .pre-commit-config.yaml ]; then\ | ||
| echo "🚀 Linting code: Running pre-commit";\ | ||
| uv run --no-sources pre-commit run -a;\ | ||
| fi | ||
| @echo "🚀 Static type checking: Running mypy" | ||
| @uv run --no-sources mypy --config-file=pyproject.toml |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| """GibsonAI Database Tools for Arcade.""" | ||
|
|
||
| from arcade_gibsonai.tools.query import execute_query | ||
|
|
||
| __all__ = ["execute_query"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| from typing import Any, Dict, List, Optional | ||
| import httpx | ||
| from pydantic import BaseModel | ||
|
|
||
| from .constants import API_BASE_URL, API_VERSION, MAX_ROWS_RETURNED | ||
|
|
||
|
|
||
| class GibsonAIResponse(BaseModel): | ||
| """Response model for GibsonAI API.""" | ||
|
|
||
| data: List[Dict[str, Any]] | ||
| success: bool | ||
| error: Optional[str] = None | ||
|
|
||
|
|
||
| class GibsonAIClient: | ||
| """Client for interacting with GibsonAI Data API.""" | ||
|
|
||
| def __init__(self, api_key: str): | ||
| self.api_key = api_key | ||
| self.base_url = f"{API_BASE_URL}/{API_VERSION}" | ||
| self.headers = {"Content-Type": "application/json", "X-Gibson-API-Key": api_key} | ||
|
|
||
| async def execute_query( | ||
| self, query: str, params: Optional[List[Any]] = None | ||
| ) -> List[str]: | ||
| """Execute a query against GibsonAI database.""" | ||
| if params is None: | ||
| params = [] | ||
|
|
||
| payload = {"array_mode": False, "params": params, "query": query} | ||
|
|
||
| try: | ||
| async with httpx.AsyncClient() as client: | ||
| response = await client.post( | ||
| f"{self.base_url}/-/query", | ||
| headers=self.headers, | ||
| json=payload, | ||
| timeout=30.0, | ||
| ) | ||
|
|
||
| if response.status_code != 200: | ||
| error_msg = f"HTTP {response.status_code}: {response.text}" | ||
| raise Exception(f"GibsonAI API error: {error_msg}") | ||
|
|
||
| result = response.json() | ||
|
|
||
| # Handle different response formats | ||
| if isinstance(result, dict): | ||
| if "error" in result and result["error"]: | ||
| raise Exception(f"GibsonAI query error: {result['error']}") | ||
| elif "data" in result: | ||
| results = [str(row) for row in result["data"]] | ||
| else: | ||
| results = [str(result)] | ||
| elif isinstance(result, list): | ||
| results = [str(row) for row in result] | ||
| else: | ||
| results = [str(result)] | ||
|
|
||
| # Limit results to avoid memory issues | ||
| return results[:MAX_ROWS_RETURNED] | ||
|
|
||
| except httpx.TimeoutException: | ||
| raise Exception("Request timeout - GibsonAI API took too long to respond") | ||
| except httpx.RequestError as e: | ||
| raise Exception(f"Network error connecting to GibsonAI API: {e}") | ||
| except Exception as e: | ||
| # Re-raise if it's already our custom exception | ||
| if "GibsonAI" in str(e): | ||
| raise | ||
| else: | ||
| raise Exception(f"Unexpected error: {e}") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| """Constants for GibsonAI API configuration.""" | ||
|
|
||
| # API configuration | ||
| API_BASE_URL = "https://api.gibsonai.com" | ||
| API_VERSION = "v1" | ||
|
|
||
| # Maximum number of rows to return from queries | ||
| MAX_ROWS_RETURNED = 1000 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| """GibsonAI database query tools.""" | ||
|
|
||
| from arcade_gibsonai.tools.query import execute_query | ||
|
|
||
| __all__ = ["execute_query"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| from typing import Annotated | ||
|
|
||
| from arcade_tdk import ToolContext, tool | ||
| from arcade_tdk.errors import RetryableToolError | ||
|
|
||
| from ..api_client import GibsonAIClient | ||
|
|
||
|
|
||
| @tool(requires_secrets=["GIBSONAI_API_KEY"]) | ||
| async def execute_query( | ||
| context: ToolContext, | ||
| query: Annotated[ | ||
| str, | ||
| "The SQL query to execute against GibsonAI project database. Supports all SQL operations including SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, etc.", | ||
| ], | ||
| ) -> list[str]: | ||
| """ | ||
| Execute a SQL query and return the results from the GibsonAI project relational database. | ||
|
|
||
| This tool supports all SQL operations including: | ||
| * SELECT queries for data retrieval | ||
| * INSERT, UPDATE, DELETE for data manipulation | ||
| * CREATE, ALTER, DROP for schema management | ||
| * Any other valid SQL statements | ||
|
|
||
| When running queries, follow these rules which will help avoid errors: | ||
| * First discover the database schema in the GibsonAI project database when schema is not known. | ||
| * Discover all the tables in the database when the list of tables is not known. | ||
| * Always use case-insensitive queries to match strings in the query. | ||
| * Always trim strings in the query. | ||
| * Prefer LIKE queries over direct string matches or regex queries. | ||
| * Only join on columns that are indexed or the primary key. | ||
|
|
||
| For SELECT queries, unless otherwise specified, ensure that query has a LIMIT of 100 for all results. | ||
| """ | ||
| api_key = context.get_secret("GIBSONAI_API_KEY") | ||
| client = GibsonAIClient(api_key) | ||
|
|
||
| try: | ||
| results = await client.execute_query(query) | ||
| return results | ||
| except Exception as e: | ||
| raise RetryableToolError( | ||
| f"Query failed: {e}", | ||
| developer_message=f"Query '{query}' failed against GibsonAI database.", | ||
| additional_prompt_content="Please check your query syntax and try again.", | ||
| retry_after_ms=10, | ||
| ) from e | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.