Skip to content

OpenModelica/ModeliacRag.jl

Repository files navigation

ModelicaRag.jl

Semantic search over Modelica libraries via a local RAG (Retrieval-Augmented Generation) pipeline. Parses Modelica source files using OMParser.jl, embeds each class with a local embedding model, stores the index in SQLite, and exposes search through an MCP server that Claude Code can query.

How it works

  1. ParseOMParser.jl parses each .mo file into an Absyn AST. The walker extracts every non-package class (model, function, record, block, connector, type, ...) as a chunk with its fully qualified name (e.g. Modelica.Electrical.Analog.Basic.Resistor) and source lines.
  2. Embed — chunks are sent to an embedding backend (GitHub Models, Ollama, or llama-server). Only files that changed since the last run are re-indexed.
  3. Store — embeddings are stored as binary blobs in SQLite alongside chunk metadata. Cosine similarity search is computed in Julia at query time.
  4. Serve — an MCP stdio server exposes three tools: search_codebase, lookup_symbol, and rebuild_index.

Requirements

  • Julia 1.9+
  • OMParser.jl (from the OM.jl monorepo)
  • One of:
    • A GitHub personal access token — uses the GitHub Models free embedding API (no local server required)
    • Ollama with an embedding model (e.g. nomic-embed-text, mxbai-embed-large)
    • llama.cpp llama-server with a GGUF embedding model

Installation

import Pkg

# Develop the OM.jl local dependencies (adjust path as needed)
Pkg.develop(path="/path/to/OM.jl/OMParser.jl")

# Develop this package — runs setup.jl automatically via deps/build.jl
Pkg.develop(path="/path/to/ModelicaRag.jl")

setup.jl detects Ollama and llama-server on your system and writes a config.toml. If the Modelica library path is not found automatically, edit config.toml and set [codebase] root.

You can also run setup manually at any time (it will not overwrite an existing config.toml):

julia setup.jl

Configuration

config.toml is machine-specific and not tracked by git. Copy the provided example and edit the paths:

cp config.toml.example config.toml

Then open config.toml and fill in the paths for your system. The key fields:

Three backends are supported. Choose one in config.toml:

GitHub Models (recommended — no local server required):

[embeddings]
backend    = "github_models"
model      = "text-embedding-3-small"   # or "text-embedding-3-large"
batch_size = 32

Set your token in the environment before running. Do not put it in config.toml:

export GITHUB_TOKEN=github_pat_...

GitHub Models is free for all GitHub users: 150 embedding requests/day per token.

Ollama:

[embeddings]
backend    = "ollama"
url        = "http://localhost:11434"
model      = "nomic-embed-text"
batch_size = 32

Pull the model first: ollama pull nomic-embed-text

llama-server:

[embeddings]
backend    = "llama"
url        = "http://localhost:8080"
batch_size = 32

[server]
llama_server = "/path/to/llama.cpp/build/bin/llama-server"
model_path   = "/path/to/models/some-embedding-model.gguf"

Julia starts llama-server automatically when this backend is selected.

The remaining fields are the same for all backends:

[store]
path = "data/index.db"

[codebase]
root       = "/path/to/Modelica/library"
extensions = [".mo"]

Playground

The quickest way to see the tool in action is the included playground script. It indexes the Modelica Standard Library and runs a set of example searches, lookups, and fuzzy queries.

export GITHUB_TOKEN=github_pat_...
julia --project playground.jl

# or pass the library path explicitly:
julia --project playground.jl /usr/share/openmodelica/libraries/Modelica\ 4.0.0

The playground writes its own index to data/playground.db (separate from the main index). Subsequent runs are incremental — only changed files are re-embedded, so re-runs are fast. The four semantic searches use four API requests from the free tier (150/day).

No local installation needed — try it in a Codespace:

Click "Code > Open with Codespaces" on the repository page. The devcontainer installs Julia, clones the Modelica Standard Library into data/msl/, and runs Pkg.instantiate() automatically. GITHUB_TOKEN is provided by Codespaces, so the playground works with no extra configuration:

julia --project playground.jl

Usage

using ModelicaRag

# Build or update the index (incremental by default)
ModelicaRag.main(["index"])

# Force a full rebuild
ModelicaRag.main(["index", "--force"])

# Search from the REPL
ModelicaRag.main(["search", "thermal resistor", "--top-k", "5"])

# Find symbols by partial name (no embedding cost)
ModelicaRag.main(["fuzzy", "HeatTransfer"])
ModelicaRag.main(["fuzzy", "sin", "--top-k", "20"])

# Start the MCP stdio server
ModelicaRag.main(["serve"])

A custom config path can be passed with --config path/to/config.toml.

MCP integration (Claude Code)

Add .mcp.json to your Claude Code MCP settings, or symlink the included .mcp.json into a project:

{
  "mcpServers": {
    "modelica-rag": {
      "command": "julia",
      "args": [
        "--project=/path/to/ModelicaRag.jl",
        "-e",
        "using ModelicaRag; ModelicaRag.main([\"serve\"])"
      ]
    }
  }
}

Once connected, four tools are available:

Tool Description
search_codebase Semantic search over indexed Modelica classes
lookup_symbol Exact lookup by qualified name (case-insensitive)
fuzzy_lookup Substring match on symbol name — finds all classes whose name contains the pattern
rebuild_index Incremental or full index rebuild

Project structure

ModelicaRag.jl/
├── Project.toml
├── config.toml.example  # template — copy to config.toml and fill in paths
├── setup.jl             # auto-detects backend and library, writes config.toml
├── deps/build.jl        # local dev only: Pkg.develop local copies of OM packages
├── data/             # SQLite index (created on first run)
└── src/
    ├── ModelicaRag.jl   # package entry point
    ├── Parser.jl        # Absyn AST walker
    ├── Embedder.jl      # GitHub Models, Ollama, and llama-server backends
    ├── Store.jl         # SQLite storage and cosine similarity search
    ├── MCP.jl           # MCP stdio server
    └── CLI.jl           # index / serve / search / fuzzy commands

About

A rag system for Modelica

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors