-
Notifications
You must be signed in to change notification settings - Fork 21
Cross-collection agentic retrieval + live schema discovery #150
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 19 commits
970dd29
53db022
9db5640
905acc0
43eb203
03aa2e0
dc0d8fc
a7d8b2f
2bb468a
4e2499d
6f4a799
ab601aa
0be3253
a45e09d
cda73a5
d25a17b
3f920b5
d1145f2
438c296
b53242f
36b8553
a4d71f3
0351bdd
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 |
|---|---|---|
|
|
@@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file. | |
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
| and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
|
||
| ## [1.2.0] - 2026-06-18 | ||
|
|
||
| ### Added | ||
| - **`agentic_search` tool**: Runs a multi-turn retrieval agent — built from | ||
| scratch for this toolkit — against a Cosmos DB corpus and | ||
| returns ranked, curated documents that best answer the query. The agent | ||
|
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.
Author
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. Apologies, the readme and changelog are an extremely old version from the research side of things so needed to be updated. Pushed all the updates necessary to make sure it is up to date. |
||
| issues hybrid (vector + full-text) RRF searches, optionally reranks with | ||
| Qwen3-Reranker-8B, reads full documents, and prunes its context across | ||
| multiple turns. Implemented as a subprocess call into the companion | ||
| [`cosmos-retriever`](https://github.com/your-org/cosmos-retriever) | ||
| Python package; see [`docs/AGENTIC_SEARCH.md`](docs/AGENTIC_SEARCH.md) for | ||
| the deployment story. | ||
| - Optional `database` and `container` arguments on `agentic_search` so a | ||
| single MCP server can target multiple Cosmos corpora at request time. When | ||
| the corpus registry (`CORPUS_REGISTRY` / `CORPUS_REGISTRY_FILE`) is set | ||
| in the host environment, the matching account, database, and embedding | ||
| model are picked automatically per call. | ||
| - New service: `AgenticSearchExecutor` (subprocess lifecycle, timeout, error | ||
| envelope generation). | ||
| - New env vars: `COSMOS_RETRIEVER_PYTHON`, `COSMOS_RETRIEVER_DIR`, | ||
| `COSMOS_RETRIEVER_TIMEOUT_S` — see [`.env.example`](.env.example). | ||
|
|
||
| ### Changed | ||
| - `AppState` now also exposes `ILoggerFactory` so static `[McpServerTool]` | ||
| methods can obtain a properly-named logger. | ||
|
|
||
| ## [1.1.2] - 2026-05-29 | ||
|
|
||
| ### Added | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,7 @@ This toolkit provides: | |
| | `text_search` | Search for documents where a property contains a search phrase | | ||
| | `vector_search` | Perform vector search using Azure OpenAI embeddings | | ||
| | `hybrid_search` | Perform hybrid search combining vector similarity and full-text keyword search using Reciprocal Rank Fusion (RRF) | | ||
| | `agentic_search` | Run a multi-turn retrieval agent (built from scratch for this toolkit) against a Cosmos DB corpus. Backed by the bundled [`cosmos-retriever/`](cosmos-retriever/) FastAPI service; see [docs/AGENTIC_SEARCH.md](docs/AGENTIC_SEARCH.md) for setup and per-corpus configuration. | | ||
|
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. "Perform multi-turn retrieval with the help of a configurable agent: An agent rewrites the queries, issues tool calls against the configured corpus/containers and returns responses. See docs[] for config" We don't need to have sentences like "build from scratch for this toolkit", "backed by bundled fast API service" etc. This is just llm bleeding context. A readme at the repo root should not assume context -- in fact it should be defining/providing context. 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. The additional details added here can go into the chagelog for instance, as changelog is typically for people who have context of the repo. (Not that you need to add them -- just trying to scope out README vs changelog) |
||
|
|
||
| ## Project Structure | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # ----- Inference backend ----- | ||
|
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. There is an Also expose defaults like prune budget here -- up to you
Author
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. yes, there are two separate .env.example files because they configure two separate services. the top-level file is for the .net mcp server, while cosmos-retriever/.env.example is for the python retriever service. there is also a separate one for the sample client. i updated the python .env.example to make it a complete reference for the service rather than only showing the minimum required variables. it now includes every configurable setting, grouped by llm, cosmos, embeddings, corpus registry, reranking, budgets, cache, and server settings, with the defaults documented alongside them. this includes the threshold and token budgets, search limits, max turns, cache sizing, schema overrides, and the other settings that were previously missing. i also corrected a few stale examples that referenced variables the python service does not actually read. the lower-level prune settings, such as the per-tool output budget and spillage fraction, were previously code-only constants. i have exposed those as config settings as well so the .env.example can serve as the single place people refer to for all defaults instead of having to inspect the implementation. 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. Have you done end-to-end testing with all three APIs?
Author
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. yes! 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. Do we have a repro/test files for these? |
||
| # "openai_responses" (default): any OpenAI-compatible /responses model | ||
| # (reasoning models such as gpt-5.x). | ||
| # "openai_chat": any OpenAI-compatible /chat/completions model (Azure AI Foundry | ||
| # deployment, OpenAI, local server, ...). | ||
| # "anthropic_messages": any Anthropic Messages API endpoint (e.g. Claude on | ||
| # Azure AI Foundry, served over the Messages API). | ||
| INFERENCE_BACKEND=openai_responses | ||
|
|
||
| # ----- LLM endpoint (openai_responses / openai_chat / anthropic_messages) ----- | ||
| # For Azure AI Foundry, CHAT_BASE_URL is the endpoint URL and CHAT_MODEL is the | ||
| # deployment name. Set CHAT_API_VERSION to use the Azure OpenAI client. | ||
| # CHAT_BASE_URL=https://your-resource.services.ai.azure.com/openai/v1 | ||
| # CHAT_API_KEY= | ||
| # CHAT_MODEL=gpt-5.2 | ||
| # CHAT_API_VERSION= | ||
| # For anthropic_messages, optionally override the version / auth header: | ||
| # ANTHROPIC_VERSION=2023-06-01 | ||
| # ANTHROPIC_AUTH_HEADER=x-api-key | ||
| # CHAT_TEMPERATURE=0.7 | ||
| # CHAT_MAX_TOKENS=4096 | ||
| # CHAT_MAX_TURNS=20 | ||
|
|
||
| # ----- Cosmos DB (required) ----- | ||
| # The corpus container must already be ingested with `id`, `docid`, `chunk_idx`, | ||
| # `text`, and `embedding` fields. | ||
| ACCOUNT_URI=https://your-cosmos-account.documents.azure.com:443/ | ||
| COSMOS_DATABASE=your-database-name | ||
| COSMOS_CORPUS_CONTAINER=your-corpus-container | ||
| # Optional: leave unset to use AzureCliCredential / DefaultAzureCredential. | ||
| # COSMOS_KEY= | ||
|
|
||
| # ----- Embeddings for SearchCorpusTool (required) ----- | ||
| # OpenAI by default; set AZURE_OPENAI_* to route through Azure OpenAI instead. | ||
| OPENAI_API_KEY=sk-... | ||
| OPENAI_EMBEDDING_MODEL=text-embedding-3-small | ||
| # AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com | ||
| # AZURE_OPENAI_API_KEY= | ||
| # Optional instruction prepended to embedding queries (used by some Qwen embedders). | ||
| # EMBED_QUERY_INSTRUCTION= | ||
|
|
||
| # ----- Reranker (optional) ----- | ||
| # Pick at most one of these. Leave both unset to disable reranking. | ||
| # Baseten: | ||
| # BASETEN_API_KEY= | ||
| # BASETEN_MODEL_URL=https://model-xyz.api.baseten.co/environments/production/sync | ||
| # Local vLLM Qwen3-Reranker-8B (run on a separate port): | ||
| # VLLM_RERANKER_URL=http://127.0.0.1:8011 | ||
|
|
||
| # ----- Retriever budget knobs (optional) ----- | ||
| # COSMOS_RETRIEVER_MAX_TURNS=35 | ||
| # COSMOS_RETRIEVER_THRESHOLD_BUDGET=16384 | ||
| # COSMOS_RETRIEVER_TOKEN_BUDGET=32268 | ||
|
|
||
| # ----- HTTP server ----- | ||
| HOST=0.0.0.0 | ||
| PORT=9000 | ||
| LOG_LEVEL=info | ||
|
Author
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. Sajeetharan (@sajeetharan) not sure if this github workflows file needs to be present in the MCP repo. Usually, if this was a monolithic repo I would include it as it is needed for replication of venvs but if it is being merged to this MCP Toolkit I am not sure if it should be included. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| name: ci | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
|
|
||
| concurrency: | ||
| group: ci-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| lint-and-test: | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| matrix: | ||
| python-version: ["3.11", "3.12"] | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
|
|
||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ matrix.python-version }} | ||
|
|
||
| - name: Install uv | ||
| uses: astral-sh/setup-uv@v3 | ||
| with: | ||
| enable-cache: true | ||
|
|
||
| - name: Install package with dev extras | ||
| run: uv pip install --system -e ".[dev]" | ||
|
|
||
| - name: Ruff lint | ||
| run: ruff check src tests | ||
|
|
||
| - name: Pytest | ||
| run: pytest -q |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # --- Python --- | ||
| __pycache__/ | ||
| *.py[cod] | ||
| *$py.class | ||
| *.egg-info/ | ||
| .eggs/ | ||
| build/ | ||
| dist/ | ||
| .coverage | ||
| .coverage.* | ||
| htmlcov/ | ||
| .pytest_cache/ | ||
| .mypy_cache/ | ||
| .ruff_cache/ | ||
|
|
||
| # --- Virtual envs --- | ||
| .venv/ | ||
| venv/ | ||
| env/ | ||
|
|
||
| # --- IDE --- | ||
| .vscode/ | ||
| .idea/ | ||
| *.swp | ||
|
|
||
| # --- Secrets / local config --- | ||
| .env | ||
| .env.local | ||
| .env.*.local | ||
| .env.* | ||
| !.env.example | ||
|
|
||
| # --- Logs / scratch --- | ||
| *.log | ||
| tmp/ | ||
| runs/ | ||
|
|
||
| # --- Build artefacts --- | ||
| src/*.egg-info/ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 3.11 | ||
|
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. I'm a bit confused as to why this is pinned here. It seems like this PR is to be merged into an existing repo, in which case the PR should not pin versions and dependencies ?
Author
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. good point. .python-version was only a local pyenv/uv hint for choosing the default interpreter in this directory. it was not used by ci, did not affect package consumers, and did not pin any dependencies. the actual compatibility requirement is requires-python = ">=3.11" in pyproject.toml. ci also tests both python 3.11 and 3.12 explicitly through setup-python, so .python-version was redundant and could give the impression that the project only supports 3.11. i removed .python-version. the authoritative version range remains in pyproject.toml, ci continues to cover both supported versions, and the readme still shows how to create a local 3.11 environment explicitly. |
||
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 Harness-1 multi-turn retrieval agent"
What is "the" harness-1 here? This is an example env config -- please don't assume context.
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.
Otherwise this doc string is good. Explains clearly what the config options are, what the defaults are and what they do.