tooluniverse 1.0.2__py3-none-any.whl → 1.0.4__py3-none-any.whl

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 tooluniverse might be problematic. Click here for more details.

@@ -146,8 +146,8 @@ Examples:
146
146
  # Start with specific categories
147
147
  tooluniverse-stdio --categories uniprot ChEMBL opentarget
148
148
 
149
- # Disable hooks
150
- tooluniverse-stdio --no-hooks
149
+ # Enable hooks
150
+ tooluniverse-stdio --hooks
151
151
 
152
152
  # Use FileSaveHook instead of SummarizationHook
153
153
  tooluniverse-stdio --hook-type FileSaveHook
@@ -272,18 +272,17 @@ Examples:
272
272
  "--verbose", "-v", action="store_true", help="Enable verbose logging"
273
273
  )
274
274
 
275
- # Hook configuration options (default enabled for stdio)
275
+ # Hook configuration options (default disabled for stdio)
276
276
  hook_group = parser.add_argument_group("Hook Configuration")
277
277
  hook_group.add_argument(
278
- "--no-hooks",
278
+ "--hooks",
279
279
  action="store_true",
280
- help="Disable output processing hooks (default: enabled for stdio)",
280
+ help="Enable output processing hooks (default: disabled for stdio)",
281
281
  )
282
282
  hook_group.add_argument(
283
283
  "--hook-type",
284
284
  choices=["SummarizationHook", "FileSaveHook"],
285
- default="SummarizationHook",
286
- help="Hook type to use (default: SummarizationHook)",
285
+ help="Hook type to use (default: SummarizationHook when hooks are enabled)",
287
286
  )
288
287
  hook_group.add_argument(
289
288
  "--hook-config-file",
@@ -493,16 +492,23 @@ Examples:
493
492
  hook_config = json.load(f)
494
493
  print(f"🔗 Hook config loaded from: {args.hook_config_file}")
495
494
 
496
- # Determine hook settings (default enabled for stdio)
497
- hooks_enabled = not args.no_hooks
495
+ # Determine hook settings (default disabled for stdio)
496
+ hooks_enabled = (
497
+ args.hooks or args.hook_type is not None or hook_config is not None
498
+ )
499
+
500
+ # Set default hook type if hooks are enabled but no type specified
501
+ hook_type = args.hook_type
502
+ if hooks_enabled and hook_type is None:
503
+ hook_type = "SummarizationHook"
498
504
  if hooks_enabled:
499
- if args.hook_type:
500
- print(f"🔗 Hooks enabled: {args.hook_type}")
505
+ if hook_type:
506
+ print(f"🔗 Hooks enabled: {hook_type}")
501
507
  elif hook_config:
502
508
  hook_count = len(hook_config.get("hooks", []))
503
509
  print(f"🔗 Hooks enabled: {hook_count} custom hooks")
504
510
  else:
505
- print(f"🔗 Hooks enabled: {args.hook_type} (default)")
511
+ print("🔗 Hooks enabled: default configuration")
506
512
  else:
507
513
  print("🔗 Hooks disabled")
508
514
 
@@ -525,7 +531,7 @@ Examples:
525
531
  stateless_http=True, # Enable stateless mode for MCPAutoLoaderTool compatibility
526
532
  hooks_enabled=hooks_enabled,
527
533
  hook_config=hook_config,
528
- hook_type=args.hook_type,
534
+ hook_type=hook_type,
529
535
  )
530
536
 
531
537
  # Run server with stdio transport (forced)
@@ -0,0 +1,210 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ List Azure OpenAI deployments (deployed models) for the current resource.
4
+
5
+ Environment variables used:
6
+ - AZURE_OPENAI_ENDPOINT (required) e.g., https://<your-resource>.openai.azure.com
7
+ - AZURE_OPENAI_API_KEY (required)
8
+ - AZURE_OPENAI_API_VERSION (optional; default: 2024-12-01-preview)
9
+
10
+ This script queries the Azure OpenAI data-plane deployments endpoint:
11
+ GET {endpoint}/openai/deployments?api-version={api_version}
12
+ It also tries alternative paths and versions if the first attempt fails.
13
+ If REST fails, it falls back to listing models via the SDK (client.models.list()).
14
+
15
+ CLI options:
16
+ --rest-only Only use REST
17
+ --sdk-only Only use SDK fallback
18
+ --raw Print raw JSON result for REST (when available)
19
+ --versions v1 v2 Override API versions to try (space-separated)
20
+ """
21
+
22
+ import argparse
23
+ import json
24
+ import os
25
+ import sys
26
+ from typing import Any, Dict, List, Optional, Tuple
27
+
28
+ import requests
29
+
30
+
31
+ DEFAULT_VERSIONS = [
32
+ # Common recent versions
33
+ "2024-12-01-preview",
34
+ "2024-10-21",
35
+ # Add more if needed
36
+ ]
37
+
38
+
39
+ def try_rest_once(
40
+ endpoint: str, api_key: str, api_version: str, path_variant: str
41
+ ) -> Tuple[Optional[List[Dict[str, Any]]], Optional[Dict[str, Any]], Optional[str]]:
42
+ url = endpoint.rstrip("/") + f"{path_variant}?api-version={api_version}"
43
+ headers = {"api-key": api_key, "Content-Type": "application/json"}
44
+ try:
45
+ resp = requests.get(url, headers=headers, timeout=15)
46
+ resp.raise_for_status()
47
+ data = resp.json()
48
+ items = data.get("data") or data.get("value") or []
49
+ deployments: List[Dict[str, Any]] = []
50
+ for item in items:
51
+ deployments.append(
52
+ {
53
+ "id": item.get("id") or item.get("name"),
54
+ "name": item.get("name") or item.get("id"),
55
+ "model": (
56
+ (item.get("model") or {}).get("name")
57
+ if isinstance(item.get("model"), dict)
58
+ else item.get("model")
59
+ ),
60
+ "model_format": item.get("model_format"),
61
+ "created": item.get("created"),
62
+ "status": item.get("status")
63
+ or item.get("provisioningState")
64
+ or item.get("provisioning_state"),
65
+ "properties": item.get("properties"),
66
+ }
67
+ )
68
+ return deployments, data, None
69
+ except Exception as e:
70
+ return None, None, f"{e} (url: {url})"
71
+
72
+
73
+ def list_deployments_via_rest(
74
+ endpoint: str, api_key: str, versions: List[str]
75
+ ) -> Tuple[List[Dict[str, Any]], Optional[Dict[str, Any]], List[str]]:
76
+ errors: List[str] = []
77
+ raw: Optional[Dict[str, Any]] = None
78
+ # Try two common path variants
79
+ path_variants = ["/openai/deployments", "/deployments"]
80
+ for v in versions:
81
+ for pv in path_variants:
82
+ deployments, raw_json, err = try_rest_once(endpoint, api_key, v, pv)
83
+ if deployments is not None:
84
+ raw = raw_json
85
+ return deployments, raw, errors
86
+ if err:
87
+ errors.append(f"{v} {pv}: {err}")
88
+ return [], raw, errors
89
+
90
+
91
+ def list_models_via_sdk(
92
+ endpoint: str, api_key: str, api_version: str
93
+ ) -> List[Dict[str, Any]]:
94
+ try:
95
+ from openai import AzureOpenAI # type: ignore
96
+ except Exception as e: # pragma: no cover
97
+ raise RuntimeError("Failed to import openai AzureOpenAI client: %s" % e)
98
+
99
+ client = AzureOpenAI(
100
+ azure_endpoint=endpoint,
101
+ api_key=api_key,
102
+ api_version=api_version,
103
+ )
104
+ resp = client.models.list()
105
+ data = getattr(resp, "data", None) or []
106
+ models: List[Dict[str, Any]] = []
107
+ for m in data:
108
+ models.append(
109
+ {
110
+ "id": getattr(m, "id", None) or getattr(m, "root", None),
111
+ "owned_by": getattr(m, "owned_by", None),
112
+ "created": getattr(m, "created", None),
113
+ }
114
+ )
115
+ return models
116
+
117
+
118
+ def main() -> None:
119
+ parser = argparse.ArgumentParser(description="List Azure OpenAI deployments/models")
120
+ parser.add_argument("--rest-only", action="store_true", help="Use REST only")
121
+ parser.add_argument("--sdk-only", action="store_true", help="Use SDK only")
122
+ parser.add_argument(
123
+ "--raw", action="store_true", help="Print raw JSON from REST when available"
124
+ )
125
+ parser.add_argument(
126
+ "--versions", nargs="*", help="API versions to try for REST (override)"
127
+ )
128
+ args = parser.parse_args()
129
+
130
+ endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
131
+ api_key = os.getenv("AZURE_OPENAI_API_KEY")
132
+ env_version = os.getenv("AZURE_OPENAI_API_VERSION")
133
+
134
+ if not endpoint or not api_key:
135
+ print("ERROR: Missing required environment variables.")
136
+ print(" - AZURE_OPENAI_ENDPOINT (current: %s)" % (endpoint or "<unset>"))
137
+ print(
138
+ " - AZURE_OPENAI_API_KEY (current: %s)"
139
+ % ("<set>" if api_key else "<unset>")
140
+ )
141
+ sys.exit(1)
142
+
143
+ versions = (
144
+ args.versions
145
+ if args.versions
146
+ else ([env_version] if env_version else DEFAULT_VERSIONS)
147
+ )
148
+
149
+ print("Listing Azure OpenAI deployments for resource:")
150
+ print(f" - Endpoint : {endpoint}")
151
+ print(f" - Versions : {', '.join([v for v in versions if v])}")
152
+ print()
153
+
154
+ deployments: List[Dict[str, Any]] = []
155
+ rest_errors: List[str] = []
156
+ raw: Optional[Dict[str, Any]] = None
157
+
158
+ if not args.sdk_only:
159
+ deployments, raw, rest_errors = list_deployments_via_rest(
160
+ endpoint, api_key, [v for v in versions if v]
161
+ )
162
+ if deployments:
163
+ print(f"Found {len(deployments)} deployment(s) via REST:")
164
+ for d in deployments:
165
+ print("- Deployment:")
166
+ print(f" name : {d.get('name')}")
167
+ print(f" id : {d.get('id')}")
168
+ print(f" model : {d.get('model')}")
169
+ print(f" status : {d.get('status')}")
170
+ if args.raw and raw is not None:
171
+ print("\nRaw JSON (REST):")
172
+ print(json.dumps(raw, indent=2, ensure_ascii=False))
173
+ print(
174
+ "\nTip: Use the 'name' (deployment name) as model_id in your requests."
175
+ )
176
+ return
177
+ else:
178
+ print("No deployments found via REST or REST not available.")
179
+ if rest_errors:
180
+ print("\nREST attempt details (for debugging):")
181
+ for e in rest_errors[:5]: # limit output
182
+ print(" -", e)
183
+ print()
184
+
185
+ if not args.rest_only:
186
+ api_version_for_sdk = env_version or DEFAULT_VERSIONS[0]
187
+ try:
188
+ models = list_models_via_sdk(endpoint, api_key, api_version_for_sdk)
189
+ if models:
190
+ print(f"Found {len(models)} model(s) via SDK:")
191
+ for m in models[:200]:
192
+ print("- Model (SDK):")
193
+ print(f" id : {m.get('id')}")
194
+ if m.get("owned_by") is not None:
195
+ print(f" owned_by: {m.get('owned_by')}")
196
+ if m.get("created") is not None:
197
+ print(f" created : {m.get('created')}")
198
+ print()
199
+ print(
200
+ "Note: SDK list may show global IDs; real calls require the deployment name."
201
+ )
202
+ else:
203
+ print("No models found via SDK either.")
204
+ except Exception as e:
205
+ print("ERROR: Unable to list models via SDK: %s" % e)
206
+ sys.exit(2)
207
+
208
+
209
+ if __name__ == "__main__":
210
+ main()
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Batch test: AgenticTool with multiple Azure OpenAI deployments.
4
+ - Validates API key during initialization
5
+ - Performs a tiny run call per model (1 token)
6
+ """
7
+
8
+ import os
9
+ import sys
10
+ from typing import List
11
+
12
+ # Ensure src/ is importable
13
+ CURRENT_DIR = os.path.dirname(__file__)
14
+ SRC_DIR = os.path.join(CURRENT_DIR, "src")
15
+ if SRC_DIR not in sys.path:
16
+ sys.path.insert(0, SRC_DIR)
17
+
18
+ try:
19
+ from tooluniverse.agentic_tool import AgenticTool # type: ignore
20
+ except ImportError:
21
+ # Fallback for when running from different directory
22
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
23
+ from tooluniverse.agentic_tool import AgenticTool # type: ignore
24
+
25
+ # Chat-capable deployment IDs to test (skip embeddings)
26
+ MODELS: List[str] = [
27
+ "gpt-4.1",
28
+ "gpt-4.1-mini",
29
+ "gpt-4.1-nano",
30
+ "gpt-4o-1120",
31
+ "gpt-4o-0806",
32
+ "gpt-4o-mini-0718",
33
+ "o4-mini-0416",
34
+ "o3-mini-0131",
35
+ ]
36
+
37
+
38
+ def test_model(model_id: str) -> None:
39
+ print(f"\n=== Testing model: {model_id} ===")
40
+ config = {
41
+ "name": f"agentic_test_{model_id}",
42
+ "description": "AgenticTool model validation",
43
+ "type": "AgenticTool",
44
+ "prompt": "Echo: {q}",
45
+ "input_arguments": ["q"],
46
+ "parameter": {
47
+ "type": "object",
48
+ "properties": {
49
+ "q": {"type": "string", "description": "input", "required": True}
50
+ },
51
+ "required": ["q"],
52
+ },
53
+ "configs": {
54
+ "api_type": "CHATGPT",
55
+ "model_id": model_id,
56
+ "validate_api_key": True,
57
+ "temperature": 0.0,
58
+ "max_new_tokens": 1,
59
+ "return_json": False,
60
+ "return_metadata": False,
61
+ },
62
+ }
63
+
64
+ try:
65
+ tool = AgenticTool(config)
66
+ print("- Init: OK (API key validated)")
67
+ except Exception as e:
68
+ print(f"- Init: FAIL -> {e}")
69
+ return
70
+
71
+ try:
72
+ out = tool.run({"q": "ping"})
73
+ ok = isinstance(out, (str, dict))
74
+ print(
75
+ f"- Run : {'OK' if ok else 'WARN'} -> {str(out)[:120].replace('\n', ' ')}"
76
+ )
77
+ except Exception as e:
78
+ print(f"- Run : FAIL -> {e}")
79
+
80
+
81
+ def main() -> None:
82
+ print("Azure endpoint:", os.getenv("AZURE_OPENAI_ENDPOINT"))
83
+ print("Using per-model versions:")
84
+ print(os.getenv("AZURE_OPENAI_API_VERSION_BY_MODEL", "<none>"))
85
+
86
+ for m in MODELS:
87
+ test_model(m)
88
+
89
+
90
+ if __name__ == "__main__":
91
+ main()
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Minimal test: validate API key during AgenticTool initialization.
4
+ - Success: prints OK and model info
5
+ - Failure: prints the error message (e.g., invalid/missing key or model not deployed)
6
+ """
7
+
8
+ import os
9
+ import sys
10
+
11
+ # Ensure src/ is importable
12
+ CURRENT_DIR = os.path.dirname(__file__)
13
+ SRC_DIR = os.path.join(CURRENT_DIR, "src")
14
+ if SRC_DIR not in sys.path:
15
+ sys.path.insert(0, SRC_DIR)
16
+
17
+ try:
18
+ from tooluniverse.agentic_tool import AgenticTool # type: ignore
19
+ except ImportError:
20
+ # Fallback for when running from different directory
21
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", ".."))
22
+ from tooluniverse.agentic_tool import AgenticTool # type: ignore
23
+
24
+
25
+ def main() -> None:
26
+ config = {
27
+ "name": "api_key_validation_test",
28
+ "description": "Minimal API key validation test",
29
+ "type": "AgenticTool",
30
+ "prompt": "Test: {q}",
31
+ "input_arguments": ["q"],
32
+ "parameter": {
33
+ "type": "object",
34
+ "properties": {
35
+ "q": {
36
+ "type": "string",
37
+ "description": "placeholder",
38
+ "required": True,
39
+ }
40
+ },
41
+ "required": ["q"],
42
+ },
43
+ "configs": {
44
+ "api_type": "CHATGPT", # or "GEMINI" if you prefer
45
+ "model_id": "gpt-4o-1120", # requested model to test
46
+ "validate_api_key": True, # this triggers validation during init
47
+ "temperature": 0.0,
48
+ "max_new_tokens": 1,
49
+ },
50
+ }
51
+
52
+ print("Running minimal API key validation test...")
53
+ try:
54
+ tool = AgenticTool(config)
55
+ info = tool.get_model_info()
56
+ print("OK: initialization succeeded and API key validated.")
57
+ print(f"Model info: {info}")
58
+ except Exception as e:
59
+ print("ERROR: initialization failed during API key validation.")
60
+ print(f"Reason: {e}")
61
+
62
+
63
+ if __name__ == "__main__":
64
+ main()