Instructions to use LatentForce-ai/Cassini-1.0 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use LatentForce-ai/Cassini-1.0 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("feature-extraction", model="LatentForce-ai/Cassini-1.0")# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("LatentForce-ai/Cassini-1.0") model = AutoModelForCausalLM.from_pretrained("LatentForce-ai/Cassini-1.0") - Notebooks
- Google Colab
- Kaggle
Cassini is a series of small language models fine-tuned for static code feature extraction. Given a source file, it produces the structured symbolic metadata that powers dependency resolution, call graph construction, and type inference at scale.
Model Highlights
- Fine-tuned on Python, JavaScript, and TypeScript for structured code feature extraction
- Purpose-built for extraction. Trained to read code the way a static analyzer does, symbolically and structurally. Outputs valid JSON consumed directly by downstream dependency resolvers and call graph engines
- Extracts six symbolic fields per source file — imports, definitions, references, calls, type assignments, and rich definition metadata — in a single inference pass
- Built for engineering teams who need structured code intelligence at scale. Dependency analysis across large or monorepo codebases, call graph and impact analysis pipelines, and tooling that requires symbolic metadata without the overhead of a full compiler or language server
- State-of-the-art cost efficiency for structured code extraction — Cassini-1.0 achieves 77.6% F1 matching or exceeding general-purpose models that cost 17–43× more: Qwen3.7-Max ($3.03, 77.6%), Gemini 3.5 Flash ($5.84, 74.2%), and Gemini 3.1 Pro ($7.57, 72.5%) — all at a total inference cost of $0.17
What Cassini Extracts
| Field | In plain terms | Example | Used for |
|---|---|---|---|
imports |
Every internal dependency a file pulls in — what is imported, from where, and under what alias | from .utils import helper as h |
Building the file-to-file dependency graph |
definitions |
Every class, function, and constant defined at the top level of the file | class UserService, def get_user, MAX_RETRIES |
Populating the project-wide symbol index |
references |
When a whole module is imported and its attributes are accessed later in code | import pkg then pkg.connect() → records connect on pkg |
Resolving module-level attribute call sites |
calls |
Every function or method invocation — who is calling, what is being called, how it is called, and on what receiver | self.cache.get(key) inside UserService.fetch |
Constructing the call graph, one edge per invocation |
type_assignments |
Every variable binding where the type can be inferred, including factory calls where only the function name is known | self.db = Database() or result = build_result() |
Inferring receiver types so method calls resolve to the right class |
definitions_rich |
Extended metadata per definition — kind, parent class, base classes, parameters, return type, and line number | create is a method on UserService, returns User, takes data: dict |
Inheritance resolution, super() walking, and return-type back-filling for factory functions |
Technical Specifications
| Parameter | Value |
|---|---|
| Framework | Unsloth + TRL SFTTrainer |
| Training method | Supervised Finetuning using LoRA |
| Base model | Qwen/Qwen3-4B |
| Precision | bf16 |
| Max sequence length | 20,480 tokens |
| Epochs | 5 |
| Per-device batch size | 16 |
| Gradient accumulation steps | 2 |
| Effective batch size | 32 |
| Learning rate | 8e-4 |
| LR scheduler | Cosine |
| Warmup steps | 10 |
| Weight decay | 0.01 |
| Optimizer | AdamW 8-bit |
| LoRA rank (r) | 1 |
| LoRA alpha | 2 |
| LoRA dropout | 0 |
| LoRA target modules | q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj |
| Hardware | NVIDIA RTX Pro 9000 (96 GB VRAM) |
Usage
Cassini-1.0 is served via vLLM and queried through its OpenAI-compatible endpoint. The model takes a source file as input and returns a structured JSON object containing six symbolic extraction fields.
Prerequisites
1. Install dependencies
pip install vllm openai pyyaml
2. Download the prompt template
The extraction prompt is shipped as python.yaml and javascript.yaml (for both JS and TS) in this repository. Clone or download it before running inference:
# Clone the full repo
git clone https://huggingface.co/LatentForce-ai/Cassini-1.0
# Or download the prompt file only
wget https://huggingface.co/LatentForce-ai/Cassini-1.0/resolve/main/prompts/javascript.yaml
3. Start the vLLM server
In a separate terminal, serve the model:
vllm serve LatentForce-ai/Cassini-1.0 --max-model-len 20480
The server will be available at
http://127.0.0.1:8000by default. Allow 1–2 minutes for the model to load before sending requests.
Minimal Inference
The following snippet runs inference on a single source file and prints the extracted JSON. Point SOURCE_FILE at any .py file, and run.
import json
import yaml
from openai import OpenAI
# ---------------------------------------------------------------------------
# Config
# ---------------------------------------------------------------------------
VLLM_URL = "http://127.0.0.1:8000/v1"
MODEL_ID = "LatentForce-ai/Cassini-1.0"
PROMPT_YAML = "python.yaml" # path to the prompt template from this repo
SOURCE_FILE = "main.py" # path to the source file to analyze
MAX_TOKENS = 6144
# ---------------------------------------------------------------------------
# Load prompt template
# ---------------------------------------------------------------------------
with open(PROMPT_YAML) as f:
config = yaml.safe_load(f)
prompt_template = config["prompt"]
# ---------------------------------------------------------------------------
# Prepare prompt
# ---------------------------------------------------------------------------
with open(SOURCE_FILE) as f:
source_code = f.read()
prompt = (
prompt_template
.replace("FILEPATH_PLACEHOLDER", SOURCE_FILE)
.replace("CONTENT_PLACEHOLDER", source_code)
)
# ---------------------------------------------------------------------------
# Run inference
# ---------------------------------------------------------------------------
client = OpenAI(base_url=VLLM_URL, api_key="no-key")
response = client.chat.completions.create(
model=MODEL_ID,
messages=[{"role": "user", "content": prompt}],
temperature=0,
max_tokens=MAX_TOKENS,
extra_body={"chat_template_kwargs": {"enable_thinking": False}},
)
# ---------------------------------------------------------------------------
# Parse output
# ---------------------------------------------------------------------------
raw = response.choices[0].message.content
def parse_json_response(text: str) -> dict | None:
"""Strip markdown fences if present and parse JSON."""
text = text.strip()
if text.startswith("```"):
first_newline = text.find("\n")
if first_newline != -1:
inner = text[first_newline + 1:]
close = inner.rfind("```")
if close != -1:
inner = inner[:close]
text = inner.strip()
try:
return json.loads(text)
except json.JSONDecodeError:
pass
# Fallback: find first complete JSON object
start, end = text.find("{"), text.rfind("}")
if start != -1 and end != -1 and end > start:
try:
return json.loads(text[start:end + 1])
except json.JSONDecodeError:
pass
return None
result = parse_json_response(raw)
if result is None:
print("Warning: model output could not be parsed as JSON.")
print("Raw output:", raw)
else:
print(json.dumps(result, indent=2))
Example Output
Suppose for a small Python file given below
"""
Declare and configure the signals for the impress core application
"""
from functools import partial
from django.core.cache import cache
from django.db import transaction
from django.db.models import signals
from django.dispatch import receiver
from core import models
from core.tasks.search import trigger_batch_document_indexer
from core.utils.users import get_users_sharing_documents_with_cache_key
@receiver(signals.post_save, sender=models.Document)
def document_post_save(sender, instance, **kwargs): # pylint: disable=unused-argument
"""
Asynchronous call to the document indexer at the end of the transaction.
Note : Within the transaction we can have an empty content and a serialization
error.
"""
transaction.on_commit(partial(trigger_batch_document_indexer, instance))
@receiver(signals.post_save, sender=models.DocumentAccess)
def document_access_post_save(sender, instance, created, **kwargs): # pylint: disable=unused-argument
"""
Asynchronous call to the document indexer at the end of the transaction.
Clear cache for the affected user.
"""
if not created:
transaction.on_commit(
partial(trigger_batch_document_indexer, instance.document)
)
# Invalidate cache for the user
if instance.user:
cache_key = get_users_sharing_documents_with_cache_key(instance.user)
cache.delete(cache_key)
@receiver(signals.post_delete, sender=models.DocumentAccess)
def document_access_post_delete(sender, instance, **kwargs): # pylint: disable=unused-argument
"""
Clear cache for the affected user when document access is deleted.
"""
if instance.user:
cache_key = get_users_sharing_documents_with_cache_key(instance.user)
cache.delete(cache_key)
Cassini-1.0 produces the following structured JSON
{
"imports": [
{
"module": "core",
"names": [
"models"
],
"alias": {}
},
{
"module": "core.tasks.search",
"names": [
"trigger_batch_document_indexer"
],
"alias": {}
},
{
"module": "core.utils.users",
"names": [
"get_users_sharing_documents_with_cache_key"
],
"alias": {}
}
],
"references": [],
"calls": [
{
"caller": "__module__",
"callee_text": "receiver",
"kind": "free",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 14
},
{
"caller": "document_post_save",
"callee_text": "on_commit",
"kind": "method",
"receiver": "transaction",
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 21
},
{
"caller": "document_post_save",
"callee_text": "partial",
"kind": "free",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 21
},
{
"caller": "document_post_save",
"callee_text": "trigger_batch_document_indexer",
"kind": "hook",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "core/tasks/search.py",
"line": 21
},
{
"caller": "__module__",
"callee_text": "receiver",
"kind": "free",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 24
},
{
"caller": "document_access_post_save",
"callee_text": "on_commit",
"kind": "method",
"receiver": "transaction",
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 31
},
{
"caller": "document_access_post_save",
"callee_text": "partial",
"kind": "free",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 32
},
{
"caller": "document_access_post_save",
"callee_text": "trigger_batch_document_indexer",
"kind": "hook",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "core/tasks/search.py",
"line": 32
},
{
"caller": "document_access_post_save",
"callee_text": "get_users_sharing_documents_with_cache_key",
"kind": "free",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "core/utils/users.py",
"line": 37
},
{
"caller": "document_access_post_save",
"callee_text": "delete",
"kind": "method",
"receiver": "cache",
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 38
},
{
"caller": "__module__",
"callee_text": "receiver",
"kind": "free",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 41
},
{
"caller": "document_access_post_delete",
"callee_text": "get_users_sharing_documents_with_cache_key",
"kind": "free",
"receiver": null,
"receiver_type_hint": null,
"callee_file_hint": "core/utils/users.py",
"line": 47
},
{
"caller": "document_access_post_delete",
"callee_text": "delete",
"kind": "method",
"receiver": "cache",
"receiver_type_hint": null,
"callee_file_hint": "external",
"line": 48
}
],
"type_assignments": [
{
"scope": "document_access_post_save",
"var": "cache_key",
"type": null,
"type_module": null,
"from_call": "get_users_sharing_documents_with_cache_key"
},
{
"scope": "document_access_post_delete",
"var": "cache_key",
"type": null,
"type_module": null,
"from_call": "get_users_sharing_documents_with_cache_key"
}
],
"definitions": [
"document_post_save",
"document_access_post_save",
"document_access_post_delete"
],
"definitions_rich": [
{
"name": "document_post_save",
"kind": "function",
"parent": null,
"bases": [],
"params": [
{
"name": "sender",
"type": null
},
{
"name": "instance",
"type": null
}
],
"returns": null,
"line": 15
},
{
"name": "document_access_post_save",
"kind": "function",
"parent": null,
"bases": [],
"params": [
{
"name": "sender",
"type": null
},
{
"name": "instance",
"type": null
},
{
"name": "created",
"type": null
}
],
"returns": null,
"line": 25
},
{
"name": "document_access_post_delete",
"kind": "function",
"parent": null,
"bases": [],
"params": [
{
"name": "sender",
"type": null
},
{
"name": "instance",
"type": null
}
],
"returns": null,
"line": 42
}
]
}
- Downloads last month
- 5