Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 4 additions & 19 deletions DEVELOP.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,25 +207,10 @@ podman run --rm -it -v /etc/krb5.conf:/etc/krb5.conf -p 9000:9000 localhost/aegi

Aegis uses semantic versioning for stable releases and `hatch-vcs` for development snapshots.

1. **Update Changelog**: Add the release notes to `docs/CHANGELOG.md`.
2. **Sync Lockfile**: Update `uv.lock` by running `make` or `uv lock`.
3. **Submit PR**: Create a pull request, get it reviewed, and merge it into the `main` branch.
1. **Sync Lockfile**: Update `uv.lock` by running `make upgrade-deps`.
2. **Update Changelog**: Add the release notes to `docs/CHANGELOG.md`.
3. **Submit PR**: Create a pull request and get it reviewed.
4. **Merge PR**: Merge the pull request to the `main` branch. This will trigger a new build of a container image that will be tagged into `:latest` and automatically deployed on the staging environment.
5. **Test the release candidate**: Test the automatically deployed image in the staging environment.
6. **Push a git tag**: Create a new signed git tag (e.g. `0.3.0`) and push it to the upstream git repository on GitHub. This will trigger a new build of a container image that will be tagged into `:stable` (and e.g. `:0.3.0`) and automatically deployed on the production environment.
6. **Create a GitHub Release**: Create a new release on GitHub from the git tag.


#### Build and Publish to PyPI

1. **Build the Distribution**:
```bash
make build-dist
```
2. **Publish to PyPI**: Set your credentials and run the publish command.
```bash
export TWINE_USERNAME=__token__
export TWINE_PASSWORD=pypi-your-long-api-token-string-here

make publish-dist
```
7. **Create a GitHub Release**: Create a new release on GitHub from the git tag. This will trigger an automatic build published on PyPI.
21 changes: 21 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ 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).

## [0.7.5] - 2026-06-26

### Changed
- `osidb-bot` now records `data_quality` and `confidence` in `aegis_meta`, including when suggestions are discarded
- migrated MCP servers from deprecated `MCPServerStdio` to `MCPToolset` + `StdioTransport` (pydantic-ai v2)
- treat empty env vars as unset in `get_env_*()` settings helpers

### Added
- added `quality-review` feature with weighted FQI (Flaw Quality Index) rubric and Customer Lens
- added `external_references_tool` for fetching CVE reference URLs
- added `--read-only` option to `osidb-bot` to skip OSIDB data updates
- added `--force` option to `osidb-bot` to skip flaw eligibility validation
- added Maven ecosystem eval cases for `suggest-affected-components` using `groupId/artifactId` format

### Fixed
- handle Mozilla CVEs with sparse `comment_zero`
- bound memory for kernel patch and HTML fetches in the classifier
- resolve specific artifacts instead of umbrella project names in `suggest-affected-components`
- improved tool call logging readability


## [0.7.4] - 2026-06-05

### Fixed
Expand Down
4 changes: 3 additions & 1 deletion src/aegis_ai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,9 @@ def default_llm_model(self):

return GoogleModel(
model_name=self.default_llm_model_name,
provider=GoogleProvider(**provider_kwargs),
provider=GoogleProvider(
**provider_kwargs
), # ty: ignore[no-matching-overload]
)

else:
Expand Down
113 changes: 57 additions & 56 deletions src/aegis_ai/toolsets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,10 @@
import os
import logging
import time
import warnings

from typing import Any

from pydantic_ai.mcp import MCPServerStdio # ty: ignore[deprecated]
from pydantic_ai.mcp import MCPToolset, StdioTransport
from pydantic_ai.toolsets import (
AbstractToolset,
CombinedToolset,
Expand Down Expand Up @@ -60,22 +59,20 @@ async def call_tool(


# register any MCP tools below:
# MCPServerStdio is deprecated in pydantic-ai v2 in favor of MCPToolset, but
# MCPToolset requires fastmcp[client] which is not yet available in our env.
warnings.filterwarnings("ignore", r"`MCPServer\w+` is deprecated", DeprecationWarning)

# mcp-nvd: query NIST National Vulnerability Database (NVD)
# https://github.com/marcoeg/mcp-nvd
#
# requires NVD_API_KEY=
nvd_stdio_server = MCPServerStdio( # ty: ignore[deprecated]
"uv",
args=[
"run",
"mcp-nvd",
],
tool_prefix="mitre_nvd",
)
nvd_mcp_toolset = MCPToolset(
StdioTransport(
"uv",
args=[
"run",
"mcp-nvd",
],
),
).prefixed("mitre_nvd")
Comment thread
kdudka marked this conversation as resolved.

# github-mcp: read only query against github.
# https://hub.docker.com/r/mcp/github-mcp-server
Expand All @@ -86,54 +83,58 @@ async def call_tool(
#
# Use FQIN (ghcr.io/github/github-mcp-server) to avoid Podman short-name
# resolution prompt when running without a TTY (e.g. web server, CI).
github_stdio_server = MCPServerStdio( # ty: ignore[deprecated]
"podman",
args=[
"run",
"-i",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"-e",
"GITHUB_TOOLSETS",
"-e",
"GITHUB_READ_ONLY",
"ghcr.io/github/github-mcp-server",
],
env={
"GITHUB_PERSONAL_ACCESS_TOKEN": f"{os.getenv('GITHUB_PERSONAL_ACCESS_TOKEN', '')}",
"GITHUB_TOOLSETS": "repos,pull_requests", # TODO: expand list of services at some point
"GITHUB_READ_ONLY": "1",
},
tool_prefix="github",
)
github_mcp_toolset = MCPToolset(
StdioTransport(
"podman",
args=[
"run",
"--rm",
"-i",
"-e",
"GITHUB_PERSONAL_ACCESS_TOKEN",
"-e",
"GITHUB_TOOLSETS",
"-e",
"GITHUB_READ_ONLY",
"ghcr.io/github/github-mcp-server",
Comment thread
kdudka marked this conversation as resolved.
],
Comment thread
coderabbitai[bot] marked this conversation as resolved.
env={
"GITHUB_PERSONAL_ACCESS_TOKEN": f"{os.getenv('GITHUB_PERSONAL_ACCESS_TOKEN', '')}",
"GITHUB_TOOLSETS": "repos,pull_requests", # TODO: expand list of services at some point
"GITHUB_READ_ONLY": "1",
},
),
).prefixed("github")

# wikipedia-mcp: query wikipedia
# https://github.com/rudra-ravi/wikipedia-mcp
#
# requires wikipedia PAT
wikipedia_stdio_server = MCPServerStdio( # ty: ignore[deprecated]
"uv",
args=[
"run",
"wikipedia-mcp",
],
tool_prefix="wikipedia",
)
wikipedia_mcp_toolset = MCPToolset(
StdioTransport(
"uv",
args=[
"run",
"wikipedia-mcp",
],
),
).prefixed("wikipedia")

# mcp-pypi: query pypi
# https://github.com/kimasplund/mcp-pypi
#
pypi_stdio_server = MCPServerStdio( # ty: ignore[deprecated]
"uv",
args=[
"run",
"mcp-pypi",
"stdio",
"--cache-dir",
f"{get_settings().config_dir}/pypi-mcp",
],
tool_prefix="pypi-mcp",
)
pypi_mcp_toolset = MCPToolset(
StdioTransport(
"uv",
args=[
"run",
"mcp-pypi",
"stdio",
"--cache-dir",
f"{get_settings().config_dir}/pypi-mcp",
],
),
).prefixed("pypi-mcp")

# Enable public function tools
public_toolset_list = []
Expand All @@ -155,18 +156,18 @@ async def call_tool(
public_toolset_list.append(FunctionToolset(tools=[tavily_tool]))

if get_settings().use_github_mcp_tool:
public_toolset_list.append(github_stdio_server)
public_toolset_list.append(github_mcp_toolset)

if get_settings().use_wikipedia_tool:
from aegis_ai.toolsets.tools.wikipedia import wikipedia_tool

public_toolset_list.append(FunctionToolset(tools=[wikipedia_tool]))

if get_settings().use_wikipedia_mcp_tool:
public_toolset_list.append(wikipedia_stdio_server)
public_toolset_list.append(wikipedia_mcp_toolset)

if get_settings().use_pypi_mcp_tool:
public_toolset_list.append(pypi_stdio_server)
public_toolset_list.append(pypi_mcp_toolset)

if get_settings().use_external_references_tool:
from aegis_ai.toolsets.tools.external_references import external_references_toolset
Expand Down Expand Up @@ -205,7 +206,7 @@ async def call_tool(
]

if get_settings().use_nvd_dev_tool:
public_cve_toolset_list.append(nvd_stdio_server)
public_cve_toolset_list.append(nvd_mcp_toolset)

public_cve_toolset = CombinedToolset(public_cve_toolset_list)

Expand Down
Loading
Loading