Skip to content

Skelf-Research/savanty

Repository files navigation

Savanty

PyPI version Python Versions CI License: MIT Code style: ruff

Natural language to constraint solver. Describe optimization problems in English, get mathematically guaranteed solutions.

Savanty combines LLM understanding with Answer Set Programming (ASP) to solve scheduling, allocation, and planning problems. The LLM translates your problem into formal constraints; the solver guarantees correctness.

Quick Start

pip install savanty
export OPENAI_API_KEY=your_key_here

Python API

from savanty import solve_optimization_problem

result = solve_optimization_problem("""
    Schedule 4 nurses (Alice, Bob, Carol, Dave) for morning/evening shifts
    over 5 days. Each shift needs 1 nurse. Max 4 shifts per person.
""")

print(result.solution)      # The assignment
print(result.asp_code)      # Generated ASP (for debugging)

CLI

savanty -p "Assign 5 tasks to 3 workers, balance workload"

Web Server

savanty --web  # REST API at http://localhost:8000

Installation

# Core package
pip install savanty

# With desktop GUI
pip install 'savanty[desktop]'

# Development
pip install 'savanty[dev]'

Requirements: Python 3.10+ and an OpenAI API key

API Reference

solve_optimization_problem(problem, additional_info=None)

Returns a ProblemSolverResult with:

Attribute Type Description
solution str The solution if found
asp_code str Generated ASP program
visualization_html str HTML visualization
needs_more_info bool True if clarification needed
questions list[str] Clarifying questions
error str Error message if failed
not_suitable bool True if problem doesn't fit ASP

Handling Results

result = solve_optimization_problem("Schedule my team")

if result.needs_more_info:
    # Solver needs clarification
    print("Questions:", result.questions)
    # Re-call with answers
    result = solve_optimization_problem(
        "Schedule my team",
        additional_info="5 people, morning/evening shifts, 7 days"
    )

elif result.not_suitable:
    # Wrong tool for this problem
    print(f"Try: {result.suggested_tool}")

elif result.error:
    print(f"Error: {result.error}")

else:
    # Success
    print(result.solution)

REST API

savanty --web --port 8000

Endpoints

POST /solve

curl -X POST http://localhost:8000/solve \
  -H "Content-Type: application/json" \
  -d '{"problem_description": "Assign 3 tasks to 2 workers"}'

GET /health — Health check GET /ready — Readiness check (verifies API key)

OpenAPI docs at /docs when server is running.

What It Solves

Savanty excels at discrete constraint satisfaction:

Good Fit Not a Good Fit
Shift scheduling Continuous optimization
Task assignment Machine learning
Route planning Statistical analysis
Resource allocation Real-time streaming
Seating arrangements Simple arithmetic
Timetabling

When a problem doesn't fit, Savanty tells you and suggests alternatives (scipy, sklearn, etc.).

How It Works

English description → LLM extracts constraints → ASP solver → Guaranteed solution
  1. LLM (GPT-4o) parses your problem into entities, constraints, objectives
  2. Gap detection identifies missing info and asks clarifying questions
  3. Code generation produces Answer Set Programming (ASP) code
  4. Clingo solver exhaustively searches for valid solutions
  5. Visualization renders results as tables/charts

The key: LLMs understand language but hallucinate solutions. ASP solvers guarantee correctness but can't parse English. Savanty uses each for what it's good at.

Configuration

# Required
export OPENAI_API_KEY=sk-...

# Optional
export SAVANTY_LLM_MODEL=openai/gpt-4o    # Default model
export SAVANTY_PORT=8000                   # Web server port
export SAVANTY_LOG_LEVEL=INFO              # DEBUG, INFO, WARNING, ERROR
export SAVANTY_SOLVE_TIMEOUT=120           # Timeout in seconds

See .env.example for all options.

Development

git clone https://github.com/skelf-research/savanty.git
cd savanty
uv sync --extra dev

# Run tests
uv run pytest

# Lint
uv run ruff check .
uv run ruff format .

# Run locally
uv run savanty --web

Project Structure

savanty/
├── savanty/
│   ├── solver.py          # Core solver logic
│   ├── dspy_modules.py    # LLM prompts (DSPy signatures)
│   ├── cli.py             # CLI + FastAPI server
│   └── logging_config.py  # Logging setup
├── frontend/              # Vue.js web interface
├── desktop/               # Slint desktop app
├── tests/
└── documentation/         # MkDocs site

Tech Stack

  • Clingo — ASP solver (correctness guarantee)
  • DSPy — LLM orchestration
  • FastAPI — REST API
  • Vue.js — Web frontend
  • Slint — Desktop GUI

License

MIT — see LICENSE

Links