-
Notifications
You must be signed in to change notification settings - Fork 3
feat: add meta tools for dynamic tool discovery and execution #84
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
Conversation
… execution - Add metaTools() method to Tools class for getting meta tools - Implement meta_filter_relevant_tools using Orama BM25 search algorithm - Implement meta_execute_tool for dynamic tool execution - Fix async initialization of Orama database - Add MetaToolSearchResult interface for type safety - Include tool configurations in search results for LLM usage - Add comprehensive documentation comments and JSDoc BREAKING CHANGE: metaRelevantTools() renamed to metaTools() and now returns Promise<Tools>
- Add meta_filter_relevant_tools for searching tools using Orama BM25 - Add meta_execute_tool for executing discovered tools dynamically - Filter tool returns full parameter schemas for LLM usage - Use synchronous Orama initialization (not async)
- AI SDK integration example with dynamic tool discovery - OpenAI integration example for agent workflows - Direct usage example without AI frameworks - Dynamic tool router pattern for flexible workflows
- Add beta warning for meta tools feature - Explain how meta tools enable dynamic tool discovery - Provide usage examples with AI SDK and OpenAI - Document the workflow and benefits
commit: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces meta tools functionality to enable dynamic tool discovery and execution in the StackOne AI SDK. Meta tools allow AI agents to search for relevant tools using natural language queries and execute them without hardcoding tool names. This feature uses Orama's BM25 algorithm for high-quality tool relevance ranking.
- Adds
meta_filter_relevant_toolsfor discovering relevant tools using natural language queries - Adds
meta_execute_toolfor executing discovered tools dynamically with provided parameters - Implements comprehensive test coverage and example usage patterns
Reviewed Changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/tool.ts | Implements meta tools functionality with Orama BM25 search for tool discovery and dynamic execution |
| src/tests/meta-tools.spec.ts | Comprehensive test suite covering meta tools functionality, format conversion, and integration workflows |
| package.json | Adds Orama dependency for BM25 search functionality |
| mocks/handlers.ts | Adds mock HTTP handlers for meta tools testing |
| examples/meta-tools.ts | Detailed examples demonstrating meta tools usage with AI SDK, OpenAI, and direct usage patterns |
| README.md | Documents meta tools functionality with beta warning and usage examples |
| .mcp.json | Adds Orama documentation reference for development |
| const results = await orama.search(oramaDb, { | ||
| term: params.query || '', | ||
| limit: params.limit || 5, | ||
| } as Parameters<typeof orama.search>[1]); |
Copilot
AI
Aug 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type assertion as Parameters<typeof orama.search>[1] should be avoided. Consider creating a proper interface for the search parameters or using a more explicit type definition.
| } as Parameters<typeof orama.search>[1]); | |
| } as OramaSearchParams); |
| }; | ||
| return result; | ||
| }) | ||
| .filter(Boolean); |
Copilot
AI
Aug 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Using .filter(Boolean) can be unclear. Consider using an explicit filter function like .filter((result): result is MetaToolSearchResult => result !== null) for better type safety and readability.
| .filter(Boolean); | |
| .filter((result): result is MetaToolSearchResult => result !== null); |
| const atsTools = toolset.getStackOneTools('ats_*', accountId); | ||
|
|
||
| // Combine tools | ||
| const combinedTools = new (await import('../src')).Tools([ |
Copilot
AI
Aug 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dynamic import inside a function creates unclear dependencies. Consider importing Tools at the top of the file for better readability and static analysis.
| const combinedTools = new (await import('../src')).Tools([ | |
| const combinedTools = new Tools([ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cubic analysis
3 issues found across 8 files • Review in cubic
React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| async function initializeOramaDb(tools: BaseTool[]): Promise<OramaDb> { | ||
| // Create Orama database schema with BM25 scoring algorithm | ||
| // BM25 provides better relevance ranking for natural language queries | ||
| const oramaDb = orama.create({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The result of orama.create is never awaited, so a promise is treated as the database instance and later passed to orama.search, which will throw at runtime.
Prompt for AI agents
Address the following comment on src/tool.ts at line 346:
<comment>The result of `orama.create` is never awaited, so a promise is treated as the database instance and later passed to `orama.search`, which will throw at runtime.</comment>
<file context>
@@ -309,3 +321,223 @@ export class Tools implements Iterable<BaseTool> {
this.tools.forEach(callback);
}
}
+
+/**
+ * Result from meta_filter_relevant_tools
+ */
+export interface MetaToolSearchResult {
+ name: string;
</file context>
| const oramaDb = orama.create({ | |
| const oramaDb = await orama.create({ |
| http.get('https://api.example.com/hris/employees', ({ request }) => { | ||
| const url = new URL(request.url); | ||
| const limit = url.searchParams.get('limit'); | ||
| return HttpResponse.json({ limit: limit ? Number(limit) : undefined }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the query parameter "limit" is "0" the truthiness check treats it as falsy, so the handler incorrectly returns undefined instead of 0; use an explicit null-check instead.
Prompt for AI agents
Address the following comment on mocks/handlers.ts at line 51:
<comment>If the query parameter "limit" is "0" the truthiness check treats it as falsy, so the handler incorrectly returns undefined instead of 0; use an explicit null-check instead.</comment>
<file context>
@@ -39,6 +39,39 @@ export const handlers = [
});
}),
+ // Meta tools test endpoints
+ http.post('https://api.example.com/hris/employees', async ({ request }) => {
+ const body = await request.json();
+ return HttpResponse.json(body);
+ }),
+
</file context>
| return HttpResponse.json({ limit: limit ? Number(limit) : undefined }); | |
| return HttpResponse.json({ limit: limit !== null ? Number(limit) : undefined }); |
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
mattzcarey
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
|
merged!!! |
Summary
This PR introduces meta tools functionality to enable dynamic tool discovery and execution in the StackOne AI SDK. Meta tools allow AI agents to search for relevant tools using natural language queries and execute them without hardcoding tool names.
Features Added
🔍 Meta Tools (Beta)
meta_filter_relevant_tools: Discovers relevant tools using natural language queries with BM25 relevance rankingmeta_execute_tool: Executes discovered tools dynamically with provided parametersKey Improvements
Implementation Details
Tool Discovery
Developer Experience
await tools.metaTools()to get meta toolsTesting
Documentation
examples/meta-tools.tsBeta Status
These features are marked as beta as the API may evolve based on user feedback. The core functionality is stable and well-tested.
Example Usage
Test Plan
bun run test:unitSummary by cubic
Added meta tools for dynamic tool discovery and execution, allowing agents to search for relevant tools using natural language and run them without hardcoding tool names.
meta_filter_relevant_toolsfor searching tools with BM25 relevance ranking.meta_execute_toolfor running discovered tools dynamically.