Skip to main content

Local-first AI workflow engine for chaining inputs, transforms, and local LLM steps.

Project description

Solux

Local-first AI workflow engine — chain inputs, transforms, and AI steps into automated workflows. Everything runs on your machine.

pip install solux
solux init
solux https://example.com/any-article

That's it. In 60 seconds you go from zero to a working AI pipeline that fetches a webpage, cleans the text, and summarizes it with your local LLM via Ollama.


What is Solux?

Solux is a local-first AI workflow engine that chains inputs → transforms → local LLM steps → outputs using simple YAML definitions. Think of it as a workflow automation tool designed for local AI inference — no cloud APIs, no vendor lock-in, no data leaving your machine.

You define workflows as YAML files. Each workflow is a pipeline of steps: fetch a webpage, clean the text, summarize with Ollama, write the result to a file or send it to Slack. Solux comes with 30+ built-in modules and you can add your own by dropping a .py file into a directory.

Solux is CLI-first — every feature is available from the terminal. A web UI is included for convenience but is entirely optional. Workflows can be triggered manually, on a schedule (cron), by watching a folder, polling an RSS feed or email inbox, or via inbound webhooks.


Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                        solux workflow run                            │
│                                                                      │
│  Source (URL / file / folder)                                        │
│         │                                                            │
│         ▼                                                            │
│  ┌─────────────┐    enqueue    ┌──────────────────────────────────┐ │
│  │  CLI / API  │──────────────▶│  SQLite Queue  (WAL mode)        │ │
│  │  Triggers   │               │  pending → processing → done     │ │
│  └─────────────┘               └──────────────┬───────────────────┘ │
│                                               │ claim (atomic)       │
│                                               ▼                      │
│                                    ┌──────────────────┐             │
│                                    │  Worker Thread   │             │
│                                    │  (poll / retry / │             │
│                                    │   dead-letter)   │             │
│                                    └────────┬─────────┘             │
│                                             │                        │
│                                             ▼                        │
│                                  ┌──────────────────┐               │
│                                  │ Workflow Loader   │               │
│                                  │ YAML + secrets   │               │
│                                  │ interpolation    │               │
│                                  └────────┬─────────┘               │
│                                           │                         │
│                                           ▼                         │
│                              ┌────────────────────────┐             │
│                              │   Workflow Engine       │             │
│                              │  for each Step:         │             │
│                              │  validate → when? →     │             │
│                              │  foreach? → timeout →   │             │
│                              │  run → on_error? →      │             │
│                              │  record timing          │             │
│                              └───────────┬────────────┘             │
│                                          │                          │
│              ┌───────────────────────────┼──────────────────┐       │
│              ▼               ▼           ▼          ▼        ▼      │
│         ┌────────┐    ┌───────────┐  ┌──────┐  ┌────────┐  ┌──────┐ │
│         │ input  │    │ transform │  │  ai  │  │ output │  │ meta │ │
│         │ fetch  │    │ split /   │  │ llm  │  │ file / │  │ sub- │ │
│         │ rss /  │    │ clean /   │  │ whis-│  │ web-   │  │ work-│ │
│         │ email  │    │ ocr       │  │ per  │  │ hook / │  │ flow/│ │
│         └────────┘    └───────────┘  └──────┘  │ email  │  │branch│ │
│                                                 └────────┘  └──────┘ │
│                                                 └────────┘           │
└─────────────────────────────────────────────────────────────────────┘

Feature Highlights

Built-in Modules (30+)

Category Modules
Input source_fetch, webpage_fetch, rss_feed, folder_watch, parse_pdf, email_inbox, youtube_playlist, s3_watcher
Transform audio_normalize, text_split, text_clean, metadata_extract, ocr
AI whisper_transcribe, llm_summarize, llm_prompt, llm_classify, llm_extract, llm_sentiment, embeddings
Output file_write, webhook, local_db, vector_store, email_send, obsidian_vault, slack_notify, solux_node
Meta workflow (sub-workflows), branch (conditional routing)

Workflow Features

Feature Description
Conditional steps when: expressions with safe AST evaluation
Iteration foreach: with optional parallel concurrency
Sub-workflows Compose workflows by calling one inside another
Branching Route to different workflows based on context values
Error handling on_error: fallback workflows per step
Step timeouts Per-step timeout guards with dead-letter on expiry
Secrets ${env:VAR_NAME} interpolation in any config field

Trigger Types (5)

Trigger Description
Folder watch Enqueue new files matching a glob pattern
RSS poll Enqueue new feed items on an interval
Cron Standard 5-field cron expressions or simple intervals
Email poll IMAP inbox polling with at-least-once delivery
Inbound webhooks POST /api/trigger/{workflow} with HMAC verification and rate limiting

Example Workflow

name: webpage_sentiment
description: "Fetch a page, clean it, and analyze sentiment."
steps:
  - name: fetch
    type: input.webpage_fetch         # fetch and extract text from URL
    config: {}

  - name: clean
    type: transform.text_clean        # strip HTML, normalize whitespace
    config:
      input_key: webpage_text
      output_key: cleaned_text
      strip_html: true
      max_chars: 4000

  - name: sentiment
    type: ai.llm_sentiment            # classify sentiment via Ollama
    config:
      input_key: cleaned_text
      scale: pos_neg_neu

  - name: notify
    type: output.slack_notify          # send result to Slack
    when: "sentiment != 'neutral'"     # conditional: skip if neutral
    config:
      webhook_url: "${env:SLACK_WEBHOOK}"
      message_template: "Sentiment: {sentiment[label]} ({sentiment[score]:.2f})"

Save this as ~/.config/solux/workflows.d/webpage_sentiment.yaml and run:

solux --workflow webpage_sentiment https://example.com/article

CLI Reference

Solux is terminal-first — every web UI action has a CLI equivalent.

# Run workflows
solux <URL>                              # run default workflow on a URL
solux run --workflow audio_summary ep.mp3 # explicit workflow + source
solux run --dry-run <URL>                # show execution plan without running

# Workflow management
solux workflows list                     # list all workflows
solux workflows show <name>              # print workflow YAML
solux workflows validate <name>          # validate pipeline wiring
solux workflows examples                 # print example YAML templates

# Triggers
solux triggers list | show | validate | examples

# Modules
solux modules list                       # list all discovered modules
solux modules inspect <name>             # show module metadata

# Queue and workers
solux ingest url1 url2 --workflow <name> # queue sources for async processing
solux worker start [--workers 4]         # start background worker(s)
solux worker status                      # show queue counts
solux log                                # monitor queue and worker logs

# Setup and maintenance
solux init                               # guided first-run setup
solux doctor [--fix]                     # check dependencies
solux config [edit]                      # show or edit config.toml
solux serve                              # start web UI (localhost:8765)
solux cleanup --dry-run                  # preview cached artifact removal
solux retry                              # reset failed jobs to pending
solux repair                             # recover stuck jobs from filesystem

# MCP server (AI agent integration)
solux mcp                                # start MCP server over stdio

Web UI

Start with solux serve (default: http://localhost:8765). The web UI provides:

  • Dashboard — job queue status, source browser, output viewer
  • YAML editors — create and edit workflows and triggers with inline validation
  • Module catalog — browse all discovered modules with metadata
  • Job history — paginated history with bulk retry and dead-letter management
  • Live updates — SSE-based queue count badges
  • OIDC authentication — integrate with Keycloak, Auth0, Dex, etc.
  • RBAC — admin / operator / viewer roles

Every web UI action has a terminal equivalent. The UI is a convenience layer, not a requirement.


Security

Security Modes

Solux supports trusted and untrusted modes via config.toml:

[security]
mode = "trusted"   # or "untrusted"
  • Trusted: all modules can run.
  • Untrusted: modules marked trusted_only or network=true are blocked. External modules are disabled.

Additional Security Features

  • OIDC + RBAC — protect the web UI with external identity providers and role-based access
  • Audit logging — optional SQLCipher encryption at rest with HMAC chain signing
  • Webhook HMACX-Solux-Signature header verification on inbound webhooks
  • Rate limiting — per-IP sliding window on webhook endpoints (default: 60/min)
  • XML safetydefusedxml for all RSS/Atom parsing (prevents XXE, billion laughs)
  • Secrets interpolation${env:VAR_NAME} keeps credentials out of YAML files; strict_env_vars = true for production

Deployment

pip (recommended for development)

pip install solux           # core
pip install 'solux[pdf]'    # + PDF extraction
pip install 'solux[ocr]'    # + Tesseract OCR
pip install 'solux[s3]'     # + S3/MinIO input
pip install 'solux[vector]' # + ChromaDB vector store
pip install 'solux[oidc]'   # + OIDC JWT auth
pip install 'solux[mcp]'    # + MCP server mode

Docker

docker compose up -d   # starts Ollama + Solux server + worker

Services bind to 127.0.0.1 by default. Enable oidc_require_auth before exposing ports.

systemd

Hardened unit files in contrib/systemd/ with NoNewPrivileges, ProtectSystem=strict, and PrivateTmp.

sudo cp contrib/systemd/solux-{server,worker}.service /etc/systemd/system/
sudo systemctl enable --now solux-server solux-worker

License

Solux is licensed under the Apache License 2.0.

See LICENSE for full terms.


Contributing

Contributions are welcome. See CONTRIBUTING.md for guidelines.

Development

pip install -e '.[dev]'              # pytest, ruff, mypy
pytest                                # run tests with coverage
ruff check src/ tests/               # lint
mypy src/solux/                      # type check

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solux-0.5.0.tar.gz (271.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

solux-0.5.0-py3-none-any.whl (184.5 kB view details)

Uploaded Python 3

File details

Details for the file solux-0.5.0.tar.gz.

File metadata

  • Download URL: solux-0.5.0.tar.gz
  • Upload date:
  • Size: 271.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for solux-0.5.0.tar.gz
Algorithm Hash digest
SHA256 9a47583b35259ff648802945d975bd8082aee878f60ebedd882e31c17ef64554
MD5 c9cb233c33b36aa1ff1bd93bf33ad64b
BLAKE2b-256 2d5a51cd015476d889b8ede37ba92f80f36f481c7ffbc738e19b4dd799c8d15f

See more details on using hashes here.

File details

Details for the file solux-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: solux-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 184.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for solux-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 99719710c5bb5bc3573f477bfc21ca6289ae02aae382d37fdc2eec4f8ea258a0
MD5 fd6e22033b9578fc970381b283b17b30
BLAKE2b-256 d941f2f7e4d39d838b8aea4730d08fb80cebd4efcebd4213d7d4910be7c59875

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page