optimizely-opal.opal-tools-sdk 0.1.5.dev0__tar.gz → 0.1.6.dev0__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.
Potentially problematic release.
This version of optimizely-opal.opal-tools-sdk might be problematic. Click here for more details.
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/PKG-INFO +1 -1
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/opal_tools_sdk/service.py +26 -27
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/optimizely_opal.opal_tools_sdk.egg-info/PKG-INFO +1 -1
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/pyproject.toml +1 -1
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/README.md +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/opal_tools_sdk/__init__.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/opal_tools_sdk/_registry.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/opal_tools_sdk/auth.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/opal_tools_sdk/decorators.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/opal_tools_sdk/logging.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/opal_tools_sdk/models.py +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/optimizely_opal.opal_tools_sdk.egg-info/SOURCES.txt +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/optimizely_opal.opal_tools_sdk.egg-info/dependency_links.txt +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/optimizely_opal.opal_tools_sdk.egg-info/requires.txt +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/optimizely_opal.opal_tools_sdk.egg-info/top_level.txt +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/setup.cfg +0 -0
- {optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/setup.py +0 -0
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
from typing import Dict, List, Any, Callable,
|
|
1
|
+
from typing import Dict, List, Any, Callable, Optional, get_type_hints
|
|
2
2
|
import inspect
|
|
3
3
|
import logging
|
|
4
|
-
from fastapi import FastAPI, APIRouter,
|
|
4
|
+
from fastapi import FastAPI, APIRouter, HTTPException, Request
|
|
5
5
|
from fastapi.routing import APIRoute
|
|
6
|
-
from pydantic import BaseModel,
|
|
6
|
+
from pydantic import BaseModel, ValidationError
|
|
7
7
|
|
|
8
|
-
from .models import Function, Parameter,
|
|
8
|
+
from .models import Function, Parameter, AuthRequirement
|
|
9
9
|
from . import _registry
|
|
10
10
|
|
|
11
11
|
logger = logging.getLogger(__name__)
|
|
12
12
|
|
|
13
|
+
|
|
13
14
|
class ToolsService:
|
|
14
15
|
"""Main class for managing Opal tools."""
|
|
15
16
|
|
|
@@ -33,15 +34,12 @@ class ToolsService:
|
|
|
33
34
|
routes = []
|
|
34
35
|
for route in app.routes:
|
|
35
36
|
if isinstance(route, APIRoute):
|
|
36
|
-
routes.append({
|
|
37
|
-
"path": route.path,
|
|
38
|
-
"name": route.name,
|
|
39
|
-
"methods": route.methods
|
|
40
|
-
})
|
|
37
|
+
routes.append({"path": route.path, "name": route.name, "methods": route.methods})
|
|
41
38
|
return {"routes": routes}
|
|
42
39
|
|
|
43
40
|
def _init_routes(self) -> None:
|
|
44
41
|
"""Initialize the discovery endpoint."""
|
|
42
|
+
|
|
45
43
|
@self.router.get("/discovery")
|
|
46
44
|
async def discovery() -> Dict[str, Any]:
|
|
47
45
|
"""Return the discovery information for this tools service."""
|
|
@@ -66,21 +64,23 @@ class ToolsService:
|
|
|
66
64
|
# Auth requirements should always be a list
|
|
67
65
|
if isinstance(handler.__auth_requirements__, list):
|
|
68
66
|
for req in handler.__auth_requirements__:
|
|
69
|
-
auth_requirements.append(
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
)
|
|
67
|
+
auth_requirements.append(
|
|
68
|
+
AuthRequirement(
|
|
69
|
+
provider=req.get("provider", ""), scope_bundle=req.get("scope_bundle", ""), required=req.get("required", True)
|
|
70
|
+
)
|
|
71
|
+
)
|
|
74
72
|
|
|
75
73
|
return auth_requirements
|
|
76
74
|
|
|
77
|
-
def register_tool(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
75
|
+
def register_tool(
|
|
76
|
+
self,
|
|
77
|
+
name: str,
|
|
78
|
+
description: str,
|
|
79
|
+
handler: Callable,
|
|
80
|
+
parameters: List[Parameter],
|
|
81
|
+
endpoint: str,
|
|
82
|
+
auth_requirements: Optional[List[AuthRequirement]] = None,
|
|
83
|
+
) -> None:
|
|
84
84
|
"""Register a tool function.
|
|
85
85
|
|
|
86
86
|
Args:
|
|
@@ -101,11 +101,7 @@ class ToolsService:
|
|
|
101
101
|
final_auth_requirements = auth_requirements if auth_requirements else handler_auth_requirements
|
|
102
102
|
|
|
103
103
|
function = Function(
|
|
104
|
-
name=name,
|
|
105
|
-
description=description,
|
|
106
|
-
parameters=parameters,
|
|
107
|
-
endpoint=endpoint,
|
|
108
|
-
auth_requirements=final_auth_requirements
|
|
104
|
+
name=name, description=description, parameters=parameters, endpoint=endpoint, auth_requirements=final_auth_requirements
|
|
109
105
|
)
|
|
110
106
|
|
|
111
107
|
self.functions.append(function)
|
|
@@ -144,7 +140,6 @@ class ToolsService:
|
|
|
144
140
|
param_name = list(sig.parameters.keys())[0]
|
|
145
141
|
param_type = get_type_hints(handler).get(param_name)
|
|
146
142
|
|
|
147
|
-
|
|
148
143
|
args = []
|
|
149
144
|
kwargs = {}
|
|
150
145
|
if param_type:
|
|
@@ -168,8 +163,12 @@ class ToolsService:
|
|
|
168
163
|
|
|
169
164
|
logger.info(f"Tool {name} returned: {result}")
|
|
170
165
|
return result
|
|
166
|
+
except ValidationError as e:
|
|
167
|
+
logger.warning(f"Invalid parameters predicted by LLM for tool {name}: {str(e)}")
|
|
168
|
+
raise HTTPException(status_code=400, detail=str(e))
|
|
171
169
|
except Exception as e:
|
|
172
170
|
import traceback
|
|
171
|
+
|
|
173
172
|
logger.error(f"Error in tool {name}: {str(e)}")
|
|
174
173
|
logger.error(traceback.format_exc())
|
|
175
174
|
raise HTTPException(status_code=500, detail=str(e))
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "optimizely-opal.opal-tools-sdk"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.6-dev"
|
|
8
8
|
description = "SDK for creating Opal-compatible tools services"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "Optimizely", email = "opal-team@optimizely.com"}
|
{optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/README.md
RENAMED
|
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
|
{optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/setup.cfg
RENAMED
|
File without changes
|
{optimizely_opal_opal_tools_sdk-0.1.5.dev0 → optimizely_opal_opal_tools_sdk-0.1.6.dev0}/setup.py
RENAMED
|
File without changes
|