-
Notifications
You must be signed in to change notification settings - Fork 55
feat: Add pagination support to SearchIndexTool and GetSegmentsTool to prevent token overflow #114
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,10 +45,28 @@ def get_index_mapping(args: GetIndexMappingArgs) -> json: | |
|
|
||
|
|
||
| def search_index(args: SearchIndexArgs) -> json: | ||
| """Search an index with pagination support. | ||
|
|
||
| Args: | ||
| args: SearchIndexArgs containing index, query, and optional pagination params | ||
|
|
||
| Returns: | ||
| json: Search results from OpenSearch | ||
| """ | ||
| from .client import initialize_client | ||
|
|
||
| client = initialize_client(args) | ||
| response = client.search(index=args.index, body=args.query) | ||
|
|
||
| # Ensure query is a dict for merging | ||
| query_body = args.query if isinstance(args.query, dict) else {} | ||
|
|
||
| # Apply pagination parameters (override any user-provided values) | ||
| # Cap size at maximum of 100 to prevent token overflow | ||
| effective_size = min(args.size, 100) if args.size else 10 | ||
| query_body['size'] = effective_size | ||
| query_body['from'] = args.from_ if args.from_ is not None else 0 | ||
|
|
||
| response = client.search(index=args.index, body=query_body) | ||
| return response | ||
|
|
||
|
|
||
|
|
@@ -62,21 +80,26 @@ def get_shards(args: GetShardsArgs) -> json: | |
|
|
||
| def get_segments(args: GetSegmentsArgs) -> json: | ||
| """Get information about Lucene segments in indices. | ||
|
|
||
| Args: | ||
| args: GetSegmentsArgs containing optional index filter | ||
| args: GetSegmentsArgs containing optional index filter and limit | ||
|
|
||
| Returns: | ||
| json: Segment information for the specified indices or all indices | ||
| """ | ||
| from .client import initialize_client | ||
|
|
||
| client = initialize_client(args) | ||
|
|
||
| # If index is provided, filter by that index | ||
| index_param = args.index if args.index else None | ||
|
|
||
| response = client.cat.segments(index=index_param, format='json') | ||
|
|
||
| # Apply limit to prevent token overflow | ||
| if args.limit and isinstance(response, list): | ||
| return response[:args.limit] | ||
|
|
||
|
Comment on lines
+99
to
+102
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When we apply the max limit, perhaps adding the information that the size has been truncated in the response message sent back to the MCP client would help? The same thing can be applied for the Search Index tool response as well |
||
| return response | ||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -499,7 +499,7 @@ async def get_long_running_tasks_tool(args: GetLongRunningTasksArgs) -> list[dic | |
| }, | ||
| 'SearchIndexTool': { | ||
| 'display_name': 'SearchIndexTool', | ||
| 'description': 'Searches an index using a query written in query domain-specific language (DSL) in OpenSearch', | ||
| 'description': 'Searches an index using a query written in query domain-specific language (DSL) in OpenSearch. Supports pagination with size (default: 10, max: 100) and from parameters to limit response size and prevent token overflow.', | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This new information about the parameters is sent to the LLM as parameter description. Maybe we can limit the tool description to just it's function and not describe its parameters? |
||
| 'input_schema': SearchIndexArgs.model_json_schema(), | ||
| 'function': search_index_tool, | ||
| 'args_model': SearchIndexArgs, | ||
|
|
@@ -524,7 +524,7 @@ async def get_long_running_tasks_tool(args: GetLongRunningTasksArgs) -> list[dic | |
| }, | ||
| 'GetSegmentsTool': { | ||
| 'display_name': 'GetSegmentsTool', | ||
| 'description': 'Gets information about Lucene segments in indices, including memory usage, document counts, and segment sizes. Can be filtered by specific indices.', | ||
| 'description': 'Gets information about Lucene segments in indices, including memory usage, document counts, and segment sizes. Can be filtered by specific indices. Supports limit parameter (default: 1000) to prevent token overflow.', | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same concern as above |
||
| 'input_schema': GetSegmentsArgs.model_json_schema(), | ||
| 'function': get_segments_tool, | ||
| 'args_model': GetSegmentsArgs, | ||
|
|
||
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.
Can we make the max limit variable configurable? Either via CLI parameter or config file? We can default to a maximum of 100 if the variable is not provided