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
40 changes: 40 additions & 0 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Linter & Formatter

on:
workflow_dispatch:
pull_request:
types: [opened, synchronize]
paths:
- "**/*.py"
- "pyproject.toml"


concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
ruff_linter:
runs-on: ubuntu-24.04

steps:
- name: Sync repository
uses: eProsima/eProsima-CI/external/checkout@v0

- name: Set up Python
uses: eProsima/eProsima-CI/external/setup-python@v0
with:
python-version: "3.12"

- name: Install Ruff
uses: eProsima/eProsima-CI/ubuntu/install_python_packages@v0
with:
packages: ruff==0.14.13

- name: Ruff format (check)
run: |
ruff format --check .

- name: Ruff lint (check)
run: |
ruff check .
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,20 @@ To do so, source Vulcanexus and then run the following command in the terminal w
```bash
source /opt/vulcanexus/${VULCANEXUS_DISTRO}/setup.bash && \
export PYTHONPATH='/<path/to/vulcanai_venv>/lib/python3.x/site-packages':$PYTHONPATH
```
```

## Developers

This repository uses `ruff` as formatter and linter.
Use the following commands to ensure that any contribution follows the projects style guidelines:

```bash
ruff check --fix .
ruff format .
```

Python package `ruff` can be installed directly with:

```bash
python3 -m pip install ruff==0.14.13
```
12 changes: 12 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@ vulcanai = ["py.typed", "*.pyi", "**/*.pyi"]

[project.scripts]
vulcanai-console = "vulcanai.console.console:main"

# Linter options
[tool.ruff]
line-length = 119
extend-exclude = [".venv", "build", "dist"]

[tool.ruff.lint]
# E: pycodestyle errors, F: pyflakes, I: import sorting
select = ["E", "F", "I"]

[tool.ruff.lint.isort]
known-first-party = ["vulcanai"]
6 changes: 3 additions & 3 deletions src/vulcanai/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@
from types import ModuleType

_SUBPACKAGES = ("core", "tools", "console", "models")
_submods: dict[str, ModuleType] = {
name: import_module(f"{__name__}.{name}") for name in _SUBPACKAGES
}
_submods: dict[str, ModuleType] = {name: import_module(f"{__name__}.{name}") for name in _SUBPACKAGES}

__all__ = sorted({sym for m in _submods.values() for sym in getattr(m, "__all__", ())})

Expand All @@ -28,11 +26,13 @@
for sym in getattr(mod, "__all__", ()):
_MODULE_INDEX.setdefault(sym, mod)


def __getattr__(name: str):
mod = _MODULE_INDEX.get(name)
if not mod:
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
return getattr(mod, name)


def __dir__():
return sorted(list(globals().keys()) + __all__)
23 changes: 18 additions & 5 deletions src/vulcanai/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,28 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from .console import VulcanAILogger, VulcanConsole
from .core import (
ToolManager, PlanManager, IterativeManager, TimelineEvent,
Agent, PlanExecutor, Blackboard,
ArgValue, Step, PlanNode, GlobalPlan, PlanValidator,
Agent,
ArgValue,
Blackboard,
GlobalPlan,
IterativeManager,
PlanExecutor,
PlanManager,
PlanNode,
PlanValidator,
Step,
TimelineEvent,
ToolManager,
)
from .console import VulcanConsole, VulcanAILogger
from .models import GeminiModel, OllamaModel, OpenAIModel
from .tools import (
AtomicTool, CompositeTool, ValidationTool, ToolRegistry, vulcanai_tool,
AtomicTool,
CompositeTool,
ToolRegistry,
ValidationTool,
vulcanai_tool,
)

__all__ = [
Expand Down
4 changes: 3 additions & 1 deletion src/vulcanai/console/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,19 @@

__all__ = list(_EXPORTS.keys())


def __getattr__(name: str):
target = _EXPORTS.get(name)
if not target:
raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
module_name, attr_name = target.split(':')
module_name, attr_name = target.split(":")
if module_name.startswith("."):
module = import_module(module_name, package=__name__)
else:
module = import_module(module_name)
return getattr(module, attr_name)


def __dir__() -> list[str]:
"""Make dir() show the public API."""
return sorted(list(globals().keys()) + __all__)
3 changes: 2 additions & 1 deletion src/vulcanai/console/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ from .console import VulcanConsole
from .logger import VulcanAILogger

__all__ = [
"VulcanConsole", "VulcanAILogger",
"VulcanConsole",
"VulcanAILogger",
]
Loading