isage-tooluse 0.1.0.0__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.
@@ -0,0 +1,208 @@
1
+ Metadata-Version: 2.4
2
+ Name: isage-tooluse
3
+ Version: 0.1.0.0
4
+ Summary: Tool retrieval and ranking algorithms for LLM agents
5
+ Author-email: IntelliStream Team <shuhao_zhang@hust.edu.cn>
6
+ Project-URL: Homepage, https://github.com/intellistream/sage-tooluse
7
+ Project-URL: Documentation, https://intellistream.github.io/SAGE-Pub/
8
+ Project-URL: Repository, https://github.com/intellistream/sage-tooluse
9
+ Project-URL: Issues, https://github.com/intellistream/sage-tooluse/issues
10
+ Keywords: sage,tool-selection,tool-use,tool-retrieval,tool-ranking,llm,agents,intellistream
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: numpy<2.3.0,>=1.26.0
26
+ Requires-Dist: typing-extensions>=4.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
29
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
30
+ Requires-Dist: ruff>=0.8.4; extra == "dev"
31
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
32
+ Provides-Extra: embedding
33
+ Requires-Dist: sentence-transformers>=2.0.0; extra == "embedding"
34
+ Requires-Dist: faiss-cpu>=1.7.0; extra == "embedding"
35
+ Provides-Extra: all
36
+ Requires-Dist: isage-tooluse[dev,embedding]; extra == "all"
37
+ Dynamic: license-file
38
+
39
+ # SAGE Tool Use
40
+
41
+ **Tool retrieval and ranking algorithms for LLM agents**
42
+
43
+ [![PyPI version](https://badge.fury.io/py/isage-tooluse.svg)](https://badge.fury.io/py/isage-tooluse)
44
+ [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
45
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
46
+
47
+ ## 🎯 Overview
48
+
49
+ `sage-tooluse` provides a comprehensive suite of tool selection and ranking algorithms for LLM agents:
50
+
51
+ - **Keyword Selector**: Fast matching based on keyword overlap
52
+ - **Embedding Selector**: Semantic similarity using embeddings
53
+ - **Hybrid Selector**: Combines keyword and embedding approaches
54
+ - **DFS-DT Selector**: Decision tree-based tool selection
55
+ - **Gorilla Adapter**: Gorilla-style tool retrieval
56
+
57
+ ## 📦 Installation
58
+
59
+ ```bash
60
+ # Basic installation
61
+ pip install isage-tooluse
62
+
63
+ # With embedding support
64
+ pip install isage-tooluse[embedding]
65
+
66
+ # Development installation
67
+ pip install isage-tooluse[dev]
68
+ ```
69
+
70
+ ## 🚀 Quick Start
71
+
72
+ ### Keyword-based Tool Selection
73
+
74
+ ```python
75
+ from sage_libs.sage_tooluse import KeywordToolSelector
76
+
77
+ # Create selector
78
+ selector = KeywordToolSelector(tools=available_tools)
79
+
80
+ # Select tools for a query
81
+ selected = selector.select(
82
+ query="Get current weather in New York",
83
+ top_k=5
84
+ )
85
+
86
+ for tool in selected:
87
+ print(f"Tool: {tool.name}, Score: {tool.score}")
88
+ ```
89
+
90
+ ### Embedding-based Tool Selection
91
+
92
+ ```python
93
+ from sage_libs.sage_tooluse import EmbeddingToolSelector
94
+
95
+ # Create selector with embedding model
96
+ selector = EmbeddingToolSelector(
97
+ tools=available_tools,
98
+ model_name="sentence-transformers/all-MiniLM-L6-v2"
99
+ )
100
+
101
+ # Select tools based on semantic similarity
102
+ selected = selector.select(
103
+ query="What's the weather like?",
104
+ top_k=5
105
+ )
106
+ ```
107
+
108
+ ### Hybrid Tool Selection
109
+
110
+ ```python
111
+ from sage_libs.sage_tooluse import HybridToolSelector
112
+
113
+ # Combine keyword and embedding approaches
114
+ selector = HybridToolSelector(
115
+ tools=available_tools,
116
+ keyword_weight=0.3,
117
+ embedding_weight=0.7
118
+ )
119
+
120
+ selected = selector.select(query="...", top_k=5)
121
+ ```
122
+
123
+ ## 📚 Key Components
124
+
125
+ ### Selectors
126
+
127
+ - **KeywordToolSelector**: Fast keyword-based matching
128
+ - **EmbeddingToolSelector**: Semantic similarity using embeddings
129
+ - **HybridToolSelector**: Weighted combination of multiple selectors
130
+ - **DFSDTToolSelector**: Decision tree-based selection
131
+ - **GorillaAdapter**: Gorilla-style API-centric retrieval
132
+
133
+ ### Base Classes
134
+
135
+ - **BaseToolSelector**: Abstract base for all selectors
136
+ - **ToolRegistry**: Central registry for selector implementations
137
+
138
+ ### Schemas
139
+
140
+ - **Tool**: Tool representation with metadata
141
+ - **ToolSelection**: Selection result with scores
142
+ - **SelectionContext**: Context for tool selection
143
+
144
+ ## 🏗️ Architecture
145
+
146
+ ```
147
+ sage_libs.sage_tooluse/
148
+ ├── __init__.py # Public API exports
149
+ ├── base.py # Base selector interface
150
+ ├── keyword_selector.py # Keyword-based selection
151
+ ├── embedding_selector.py # Embedding-based selection
152
+ ├── hybrid_selector.py # Hybrid selection strategy
153
+ ├── dfsdt_selector.py # Decision tree selector
154
+ ├── gorilla_selector.py # Gorilla-style retrieval
155
+ ├── registry.py # Selector registry
156
+ ├── schemas.py # Data schemas
157
+ └── retriever/ # Retrieval utilities
158
+ ```
159
+
160
+ ## 🎓 Use Cases
161
+
162
+ 1. **Agent Tool Selection**: Help agents choose the right tools
163
+ 2. **API Discovery**: Find relevant APIs for a task
164
+ 3. **Function Calling**: Select appropriate functions for LLMs
165
+ 4. **Tool Recommendation**: Recommend tools to users
166
+ 5. **Multi-step Planning**: Select tool sequences for complex tasks
167
+
168
+ ## 🔗 Integration with SAGE
169
+
170
+ This package is part of the SAGE ecosystem and can be used with SAGE agents:
171
+
172
+ ```python
173
+ # Standalone usage
174
+ from sage_libs.sage_tooluse import HybridToolSelector
175
+
176
+ # With SAGE (when available, through interface layer)
177
+ from sage.libs.tooluse import create_selector
178
+
179
+ selector = create_selector("hybrid", tools=available_tools)
180
+ ```
181
+
182
+ ## 📖 Documentation
183
+
184
+ - **Repository**: https://github.com/intellistream/sage-tooluse
185
+ - **SAGE Documentation**: https://intellistream.github.io/SAGE-Pub/
186
+ - **Issues**: https://github.com/intellistream/sage-tooluse/issues
187
+
188
+ ## 🤝 Contributing
189
+
190
+ Contributions are welcome! Please feel free to submit a Pull Request.
191
+
192
+ ## 📄 License
193
+
194
+ MIT License - see [LICENSE](LICENSE) file for details.
195
+
196
+ ## 🙏 Acknowledgments
197
+
198
+ Originally part of the [sage-agentic](https://github.com/intellistream/sage-agentic) package, now maintained as an independent repository for focused development and research.
199
+
200
+ ## 📧 Contact
201
+
202
+ - **Team**: IntelliStream Team
203
+ - **Email**: shuhao_zhang@hust.edu.cn
204
+ - **GitHub**: https://github.com/intellistream
205
+
206
+ ---
207
+
208
+ **Part of the SAGE ecosystem** - Stream Analytics for Generative AI Engines
@@ -0,0 +1,14 @@
1
+ isage_tooluse-0.1.0.0.dist-info/licenses/LICENSE,sha256=FviS_SBgJ3MCvV517X_20AfytowsiItMOu_l3GJWFnI,1080
2
+ sage_libs/sage_tooluse/__init__.py,sha256=bA6hLvDnMNvxwAoeLjMIXFPMizrYW6Vy1t1iBUFXC-4,2014
3
+ sage_libs/sage_tooluse/base.py,sha256=5iLmJ5_oiqcEX7DqcHGgVhrNsQK5B_YRmVZU2eDLWl8,5953
4
+ sage_libs/sage_tooluse/dfsdt_selector.py,sha256=NJ4JojxUGCqCzCSxcti6x3pv-iYNvHnohbvvb5lxcN8,13625
5
+ sage_libs/sage_tooluse/embedding_selector.py,sha256=l8YduV_ikJbZkXHdOfVEHrfhED8eyM-zweJrX6o9Jws,9599
6
+ sage_libs/sage_tooluse/gorilla_selector.py,sha256=CZsF4toPpD0eGijI_uW9RvX4H-M22x0TQKA9a7d_Iko,18466
7
+ sage_libs/sage_tooluse/hybrid_selector.py,sha256=3Bsm4glYrHIBTCV3Yttl-dQIgLv7EEn50hbdOG5EwaY,7370
8
+ sage_libs/sage_tooluse/keyword_selector.py,sha256=0sus1-pbX9NCaIvwIMOhrAE4n3rtUPnZVEFe5TvMAis,7801
9
+ sage_libs/sage_tooluse/registry.py,sha256=xvq__KzoKcdJuys6WKaDgkuU9mI3sA4ne9lYF7VR51Y,5125
10
+ sage_libs/sage_tooluse/schemas.py,sha256=bIvhnP5WqVuJUpYuwGhUR6p4hDWn5e-ZVJCOw-yW82U,7266
11
+ isage_tooluse-0.1.0.0.dist-info/METADATA,sha256=ioD9ce2JRE8Qbjc-OsEqNGPWAvn-obvfcnzxP5SSnn8,6631
12
+ isage_tooluse-0.1.0.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
13
+ isage_tooluse-0.1.0.0.dist-info/top_level.txt,sha256=_xtJhEYnKsvxmrqAlXqhVS4DzJcuU_VhAU_z6LOAGho,10
14
+ isage_tooluse-0.1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 IntelliStream Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ sage_libs
@@ -0,0 +1,75 @@
1
+ """
2
+ Tool selection module.
3
+
4
+ Provides tool selector strategies for choosing relevant tools based on queries.
5
+ """
6
+
7
+ __version__ = "0.1.0.0"
8
+ __author__ = "IntelliStream Team"
9
+ __email__ = "shuhao_zhang@hust.edu.cn"
10
+
11
+ from .base import BaseToolSelector, SelectorResources, ToolSelectorProtocol
12
+ from .dfsdt_selector import DFSDTSelector
13
+ from .embedding_selector import EmbeddingSelector
14
+ from .gorilla_selector import GorillaSelector, GorillaSelectorConfig
15
+ from .hybrid_selector import HybridSelector, HybridSelectorConfig
16
+ from .keyword_selector import KeywordSelector
17
+ from .registry import (
18
+ SelectorRegistry,
19
+ create_selector_from_config,
20
+ get_selector,
21
+ register_selector,
22
+ )
23
+ from .schemas import (
24
+ CONFIG_TYPES,
25
+ AdaptiveSelectorConfig,
26
+ DFSDTSelectorConfig,
27
+ EmbeddingSelectorConfig,
28
+ KeywordSelectorConfig,
29
+ SelectorConfig,
30
+ ToolPrediction,
31
+ ToolSelectionQuery,
32
+ TwoStageSelectorConfig,
33
+ create_selector_config,
34
+ )
35
+ from .schemas import (
36
+ GorillaSelectorConfig as GorillaSelectorConfigSchema,
37
+ )
38
+
39
+ # Auto-register built-in selectors
40
+ register_selector("keyword", KeywordSelector)
41
+ register_selector("embedding", EmbeddingSelector)
42
+ register_selector("hybrid", HybridSelector)
43
+ register_selector("gorilla", GorillaSelector)
44
+ register_selector("dfsdt", DFSDTSelector)
45
+
46
+ __all__ = [
47
+ # Base classes
48
+ "BaseToolSelector",
49
+ "SelectorResources",
50
+ "ToolSelectorProtocol",
51
+ # Selector implementations
52
+ "KeywordSelector",
53
+ "EmbeddingSelector",
54
+ "HybridSelector",
55
+ "HybridSelectorConfig",
56
+ "GorillaSelector",
57
+ "GorillaSelectorConfig",
58
+ "DFSDTSelector",
59
+ "DFSDTSelectorConfig",
60
+ # Registry
61
+ "SelectorRegistry",
62
+ "register_selector",
63
+ "get_selector",
64
+ "create_selector_from_config",
65
+ # Schemas
66
+ "SelectorConfig",
67
+ "KeywordSelectorConfig",
68
+ "EmbeddingSelectorConfig",
69
+ "TwoStageSelectorConfig",
70
+ "AdaptiveSelectorConfig",
71
+ "ToolSelectionQuery",
72
+ "ToolPrediction",
73
+ "CONFIG_TYPES",
74
+ "create_selector_config",
75
+ ]
@@ -0,0 +1,203 @@
1
+ """
2
+ Base classes and protocols for tool selection.
3
+
4
+ Defines the ToolSelector protocol and abstract base class.
5
+ """
6
+
7
+ import logging
8
+ from abc import ABC, abstractmethod
9
+ from typing import TYPE_CHECKING, Any, Optional, Protocol
10
+
11
+ from .schemas import SelectorConfig, ToolPrediction, ToolSelectionQuery
12
+
13
+ if TYPE_CHECKING:
14
+ from sage.common.components.sage_embedding.protocols import EmbeddingProtocol
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class SelectorResources:
20
+ """
21
+ Container for shared resources needed by selectors.
22
+
23
+ Attributes:
24
+ tools_loader: DataLoader for tool metadata
25
+ embedding_client: Optional embedding service client (must conform to EmbeddingProtocol)
26
+ logger: Logger instance
27
+ cache: Optional cache instance
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ tools_loader: Any,
33
+ embedding_client: Optional["EmbeddingProtocol"] = None,
34
+ logger: Optional[logging.Logger] = None,
35
+ cache: Optional[Any] = None,
36
+ ):
37
+ """
38
+ Initialize resources.
39
+
40
+ Args:
41
+ tools_loader: Tool metadata loader (from DataManager)
42
+ embedding_client: Optional embedding service (must have embed(texts, model) interface)
43
+ logger: Optional logger instance
44
+ cache: Optional cache instance
45
+ """
46
+ self.tools_loader = tools_loader
47
+ self.embedding_client = embedding_client
48
+ self.logger = logger or logging.getLogger(__name__)
49
+ self.cache = cache
50
+
51
+
52
+ class ToolSelectorProtocol(Protocol):
53
+ """Protocol defining the tool selector interface."""
54
+
55
+ name: str
56
+
57
+ @classmethod
58
+ def from_config(
59
+ cls, config: SelectorConfig, resources: SelectorResources
60
+ ) -> "ToolSelectorProtocol":
61
+ """
62
+ Create selector instance from config and resources.
63
+
64
+ Args:
65
+ config: Selector configuration
66
+ resources: Shared resources
67
+
68
+ Returns:
69
+ Initialized selector instance
70
+ """
71
+ ...
72
+
73
+ def select(
74
+ self, query: ToolSelectionQuery, top_k: Optional[int] = None
75
+ ) -> list[ToolPrediction]:
76
+ """
77
+ Select top-k relevant tools for the given query.
78
+
79
+ Args:
80
+ query: Tool selection query
81
+ top_k: Number of tools to select (overrides config if provided)
82
+
83
+ Returns:
84
+ List of tool predictions, sorted by score (descending)
85
+ """
86
+ ...
87
+
88
+
89
+ class BaseToolSelector(ABC):
90
+ """
91
+ Abstract base class for tool selectors.
92
+
93
+ Provides common functionality and enforces the protocol.
94
+ """
95
+
96
+ def __init__(self, config: SelectorConfig, resources: SelectorResources):
97
+ """
98
+ Initialize base selector.
99
+
100
+ Args:
101
+ config: Selector configuration
102
+ resources: Shared resources
103
+ """
104
+ self.config = config
105
+ self.resources = resources
106
+ self.logger = resources.logger
107
+ self.name = config.name
108
+
109
+ # Statistics
110
+ self._query_count = 0
111
+ self._cache_hits = 0
112
+
113
+ @classmethod
114
+ @abstractmethod
115
+ def from_config(
116
+ cls, config: SelectorConfig, resources: SelectorResources
117
+ ) -> "BaseToolSelector":
118
+ """
119
+ Create selector from config.
120
+
121
+ Args:
122
+ config: Selector configuration
123
+ resources: Shared resources
124
+
125
+ Returns:
126
+ Initialized selector instance
127
+ """
128
+ return cls(config, resources)
129
+
130
+ @abstractmethod
131
+ def _select_impl(self, query: ToolSelectionQuery, top_k: int) -> list[ToolPrediction]:
132
+ """
133
+ Implementation-specific selection logic.
134
+
135
+ Args:
136
+ query: Tool selection query
137
+ top_k: Number of tools to select
138
+
139
+ Returns:
140
+ List of tool predictions
141
+ """
142
+ pass
143
+
144
+ def select(
145
+ self, query: ToolSelectionQuery, top_k: Optional[int] = None
146
+ ) -> list[ToolPrediction]:
147
+ """
148
+ Select top-k relevant tools.
149
+
150
+ Args:
151
+ query: Tool selection query
152
+ top_k: Number of tools to select (overrides config)
153
+
154
+ Returns:
155
+ List of tool predictions, sorted by score (descending)
156
+ """
157
+ k = top_k if top_k is not None else self.config.top_k
158
+ self._query_count += 1
159
+
160
+ try:
161
+ # Check cache if enabled
162
+ if self.config.cache_enabled and self.resources.cache:
163
+ cache_key = self._get_cache_key(query, k)
164
+ cached = self.resources.cache.get(cache_key)
165
+ if cached is not None:
166
+ self._cache_hits += 1
167
+ self.logger.debug(f"Cache hit for query {query.sample_id}")
168
+ return cached
169
+
170
+ # Perform selection
171
+ predictions = self._select_impl(query, k)
172
+
173
+ # Filter by minimum score
174
+ if self.config.min_score > 0:
175
+ predictions = [p for p in predictions if p.score >= self.config.min_score]
176
+
177
+ # Sort by score descending
178
+ predictions = sorted(predictions, key=lambda p: p.score, reverse=True)
179
+
180
+ # Limit to top-k
181
+ predictions = predictions[:k]
182
+
183
+ # Cache result if enabled
184
+ if self.config.cache_enabled and self.resources.cache:
185
+ self.resources.cache.set(cache_key, predictions)
186
+
187
+ return predictions
188
+
189
+ except Exception as e:
190
+ self.logger.error(f"Error in tool selection for {query.sample_id}: {e}")
191
+ raise
192
+
193
+ def _get_cache_key(self, query: ToolSelectionQuery, top_k: int) -> str:
194
+ """Generate cache key for query."""
195
+ return f"{self.name}:{query.sample_id}:{top_k}:{hash(query.instruction)}"
196
+
197
+ def get_stats(self) -> dict:
198
+ """Get selector statistics."""
199
+ return {
200
+ "query_count": self._query_count,
201
+ "cache_hits": self._cache_hits,
202
+ "cache_hit_rate": self._cache_hits / max(self._query_count, 1),
203
+ }