Open
Conversation
Adds uipath context-grounding command group with four subcommands: retrieve --index NAME --folder PATH search QUERY --index NAME --folder PATH [--results N] ingest --index NAME --folder PATH delete --index NAME --folder PATH [--confirm] [--dry-run] All commands use --index (named option) and --folder (alias for --folder-path) consistently. Strictly wraps the existing ContextGroundingService without any service-layer changes. search truncates content to 120 chars in table format for readability; JSON and CSV output receives full content. IngestionInProgressException is surfaced as a clean CLI error on both search and ingest.
Integration tests (tests/cli/integration/test_context_grounding_commands.py): - 29 tests covering retrieve, search, ingest, delete commands - Tests for all options (--index, --folder, --folder-key, --results, --format) - Error paths: not-found, ingestion-in-progress, missing required flags - Table truncation vs JSON full-content for search output - Confirmation prompt and --dry-run for delete - Help text for all commands Contract tests (tests/cli/contract/test_sdk_cli_alignment.py): - 4 new parametrized cases for context-grounding retrieve/search/ingest/delete - Param mappings: CLI --index (index_name) → SDK name - SDK exclusions: ingest/delete take an index object, not a name - CLI exclusions: index_name on ingest/delete is a lookup key with no SDK counterpart Fix: use spec=ContextGroundingIndex / spec=ContextGroundingQueryResponse on mocks so MagicMock.__iter__ doesn't cause format_output to treat a single model as an empty iterator.
- Use --folder-path consistently (matches buckets; was --folder) and reuse common_service_options directly instead of a duplicate decorator - Replace bare 'raise' after 'except Exception' with _not_found() helper that always produces a ClickException (clean message or not-found), no raw tracebacks ever escape to the user - Extract _not_found() helper used by retrieve/search/ingest/delete - Remove redundant confirm/dry_run from CLI_EXCLUSIONS (already in global CLI_ONLY_OPTIONS) - Add test_ingest_with_folder_key and test_delete_with_folder_key integration tests (ingest/delete were the only commands missing folder-key coverage) - Update all integration test invocations to use --folder-path
The ECS search API rejects numberOfResults=0 with a 400. Add click.IntRange(min=1) on the --results option so the error is caught immediately with a clean usage message instead of an HTTP 400.
- ruff format all three changed files - Add complete type annotations to all command functions: ctx: click.Context, typed params, -> Any / -> None return types - Import Optional and Any from typing - context_grounding group annotated -> None - ingest/delete return bare (no 'return None') for cleaner style - Under project mypy config: 0 errors - Under strict mypy: only 4 pre-existing get_client() untyped-call errors (same infrastructure gap as cli_buckets.py which has 17)
The full model_dump() produced an unreadably wide table with all 9 fields
(metadata dict, reference URL, source_document_id, caption, id).
Table mode now projects to {score, source, page, content} only — the
four columns useful for human inspection at the terminal. JSON and CSV
still return the full objects so no data is lost for scripting.
Also rounds score to 3 decimal places in table mode for cleaner output.
_not_found: - Change return type -> NoReturn (unconditionally raises; None was a false-negative for type checkers and caused 'index possibly unbound' warnings at call sites in ingest/delete) - Update docstring to accurately describe the single responsibility: classify not-found vs other, re-raise as ClickException search: - Rename --results to --limit (-n) — more conventional (az/gcloud/aws all use --limit for a max-count option) - Update all examples in docstring and help text ingest: - Check index.in_progress_ingestion() immediately after retrieve() to fail fast without a redundant HTTP round-trip (issue #4) - Add test_ingest_already_in_progress_fast_fail covering this path and asserting ingest_data is never called delete: - Wrap delete_index() in try/except to surface 403/404 race conditions as clean ClickException rather than raw error (issue #5) contract tests: - Replace fragile 'not service.startswith(context)' heuristic with an explicit NESTED_SERVICES set — adding future services can't silently break the navigation logic (issue #6) tests: - Remove dead mock_client.context_grounding.retrieve.return_value from test_search_basic and test_search_with_results_option (search doesn't call retrieve; issue #11) - Rename test_search_with_results_option -> test_search_with_limit_option - Add comment in test_search_empty_results explaining err=True / CliRunner stderr mixing (issue #12) - _make_index now configures in_progress_ingestion.return_value = False so the new fast-fail guard doesn't trip in unrelated tests
ingest: merge retrieve + ingest_data into a single try block so index
is always bound when used. Exception ordering:
1. click.ClickException re-raised immediately (from in_progress check)
2. IngestionInProgressException → clean ClickException
3. Any other exception → _not_found() (NoReturn, converts to
ClickException with not-found or generic message)
This also ensures the success echo is only reached on a clean path —
previously a generic exception from ingest_data would bubble past the
echo through service_command's handler, giving the user an error
message but no success confirmation either.
delete: keep retrieve and delete_index in separate try blocks (because
dry-run/confirm prompts must happen in between), but remove the
type: ignore comment — mypy correctly infers index is bound because
_not_found is -> NoReturn, so no suppression needed.
Also fix page key name: 'page' -> 'page_number' in table rows so
column names are identical across table/json/csv formats.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add
uipath context-groundingCLI commandsSummary
Adds a new
uipath context-groundingcommand group to the CLI, giving developers direct access to the Context Grounding (ECS) service from the terminalCommands
All commands support
--folder-path,--folder-key,--format [json|table|csv], and-o <file>— consistent withuipath buckets.Examples
Verified against live environment
Tested against
https://alpha.uipath.com/goldenagents/DefaultTenant,Athena_Chatbotindex inSharedfolder: