Data Sources¶
Ragdoll supports five data source types, each with a specialised ingestion strategy designed to preserve semantic meaning.
PDF Documents¶
Module: ragdoll.ingest.pdf
Uses PyMuPDF to extract text content from
PDF files. Each page produces a Document with metadata including the source
file path and page number.
Supported Inputs¶
Single PDF files
Directories (recursively finds all
*.pdffiles)
Example¶
pixi run ragdoll ingest pdf ./technical_handbook.pdf
pixi run ragdoll ingest pdf ./documentation/
JIRA Tickets¶
Module: ragdoll.ingest.jira
Fetches issues from a JIRA instance (Data Center or Cloud) via the REST API. Each issue is converted into a structured text document containing:
Issue key, summary, status, type, and priority
Assignee, reporter, created/updated dates
Components, labels, and fix versions
Full description text
All comments with authors and timestamps
Authentication¶
JIRA Type |
Auth Method |
Config |
|---|---|---|
Data Center |
PAT (Bearer token) |
|
Cloud |
Basic auth (user + API token) |
|
Pagination & Incremental Ingestion¶
Issues are fetched in batches (default: 100 per request) with automatic
pagination. Use --max-results to cap the total:
pixi run ragdoll ingest jira --jql "project = MAIN" --max-results 200
Ragdoll automatically compares incoming issue updated timestamps against existing ChromaDB metadata. If an issue has not changed since its last ingestion, Ragdoll skips embedding it, saving CPU/GPU resources. Use -f / --force to bypass this check:
pixi run ragdoll ingest jira --server primary --jql "project = MAIN" --force
Multi-Site Ingestion¶
To ingest from multiple JIRA instances (e.g., an internal Data Center and
a partner’s Cloud instance), you can define named server blocks in your
~/.ragdoll/config.toml:
[jira_servers.primary]
url = "https://primary-jira.example.com"
user = "your.username"
token = "YOUR_PERSONAL_ACCESS_TOKEN"
auth_method = "pat"
[jira_servers.cloud]
url = "https://company.atlassian.net"
user = "you@company.com"
token = "CLOUD_API_TOKEN"
auth_method = "basic"
Then use the --server flag to ingest from a specific configured site:
# Primary site (uses global defaults if --server is omitted)
pixi run ragdoll ingest jira --jql "project = MAIN AND updated >= -30d"
# Secondary Data Center site
pixi run ragdoll ingest jira --server primary --jql "project = EXT AND updated >= -30d"
# Cloud site with basic auth
pixi run ragdoll ingest jira --server cloud --jql "project = CLOUD"
Alternatively, you can manually override settings per-invocation using CLI flags:
Override Flag |
Description |
|---|---|
|
Name of the pre-configured server in config.toml |
|
JIRA server URL |
|
Username (for basic auth) |
|
API token or PAT |
|
|
All issues from all sites are stored in the same vector collection, so queries, summaries, and chat draw from all ingested sources.
Extracted Metadata¶
Every ingested JIRA ticket carries the following metadata fields, available for both auto-retrieval filtering and context display.
From JiraReader (built-in):
Metadata Key |
Type |
Description |
|---|---|---|
|
|
Internal JIRA issue ID |
|
|
Issue summary |
|
|
Permalink to the issue |
|
|
Creation timestamp |
|
|
Last update timestamp |
|
|
Comma-separated labels |
|
|
Workflow status (Open, In Progress, Closed, etc.) |
|
|
Assignee display name |
|
|
Reporter display name |
|
|
Project name |
|
|
Bug, Story, Task, Epic, etc. |
|
|
Critical, Major, Minor, Trivial, etc. |
|
|
Parent epic issue key |
|
|
Parent epic summary |
|
|
Parent epic description |
Enriched from raw JIRA API:
Metadata Key |
Type |
Description |
|---|---|---|
|
|
Issue key (e.g. |
|
|
Comma-separated component names (e.g. |
|
|
Target fix version names |
|
|
Affected version names |
|
|
Resolution status (Fixed, Won’t Fix, Duplicate, etc.) |
|
|
When the issue was resolved |
|
|
Number of subtasks |
|
|
Related issues with relationship (e.g. |
|
|
Vote count |
|
|
Watcher count |
|
|
Sprint name (Jira Software agile boards) |
|
|
Story points estimate |
|
|
Environment field text |
Note:
components,fix_versions,affects_versions, andlinked_issuesare also appended to the document text so they are discoverable via semantic search, not just metadata filtering.
Bitbucket Pull Requests¶
Module: ragdoll.ingest.bitbucket
Fetches pull requests and their activity threads from an on-premise Bitbucket Server (Data Center) via the REST API. Each PR is converted into a structured document containing:
PR Title, description, and status
Author information
A chronological thread of all comments, approvals, and merges
Note
Scope: This module only ingests Pull Request metadata and discussions. It does not clone or ingest the repository’s source code files. To ingest actual codebase files, use the ragdoll ingest code command (see Source Code).
Example¶
# Ingest all PRs (Open, Merged, and Declined) from a specific repo
pixi run ragdoll ingest bitbucket --project PROJ --repo backend --state ALL
# Ingest only Open PRs
pixi run ragdoll ingest bitbucket --project PROJ --repo backend --state OPEN
Multi-Site Ingestion¶
Like JIRA, you can configure multiple Bitbucket instances in ~/.ragdoll/config.toml:
[bitbucket_servers.internal]
url = "https://bitbucket.example.com"
user = "your.username"
token = "YOUR_HTTP_ACCESS_TOKEN"
auth_method = "pat"
Then specify the server during ingestion:
pixi run ragdoll ingest bitbucket --server internal --project PROJ --repo backend
Extracted Metadata¶
Metadata Key |
Type |
Description |
|---|---|---|
|
|
Bitbucket repository slug |
|
|
Pull Request numerical ID |
|
|
Author of the PR |
|
|
PR Title |
|
|
MERGED, OPEN, or DECLINED |
|
|
Unix timestamp of creation |
|
|
Unix timestamp of last update |
GitHub Issues & Pull Requests¶
Module: ragdoll.ingest.github
Fetches issues, pull requests, and discussion threads from public or private GitHub repositories (including GitHub Enterprise Server) via the GitHub REST API. Each issue or PR is converted into a structured document containing:
Issue / PR Title, number, status (
openorclosed), and type label (IssueorPR)Author login name
Creation date and full issue description
A chronological thread of all comments and activity
Note
Scope: This module ingests Issue and Pull Request discussions, descriptions, and comments. To ingest the repository’s actual Python source code files, use ragdoll ingest code after cloning the repository.
Example¶
# Ingest all Issues and PRs (both Open and Closed) with full comment threads
pixi run ragdoll ingest github myorg myrepo --state all
# Ingest only Open issues & PRs
pixi run ragdoll ingest github myorg myrepo --state open
# Pass a token directly via CLI to avoid API rate limits
pixi run ragdoll ingest github myorg myrepo --token "ghp_..."
Multi-Site / Enterprise Ingestion¶
You can configure global or enterprise GitHub instances in ~/.ragdoll/config.toml:
# Default / Public GitHub
github_token = "ghp_YOUR_PERSONAL_ACCESS_TOKEN"
# GitHub Enterprise Server
[github_servers.enterprise]
url = "https://github.internal.mycompany.com/api/v3"
token = "ghp_ENTERPRISE_TOKEN"
Then specify the server during ingestion:
pixi run ragdoll ingest github --server enterprise myorg internal-service --state all
Extracted Metadata¶
Metadata Key |
Type |
Description |
|---|---|---|
|
|
|
|
|
GitHub organization or username |
|
|
GitHub repository name |
|
|
Issue or Pull Request number |
|
|
|
|
|
Author’s GitHub username |
|
|
Issue / PR title |
|
|
Workflow status ( |
|
|
Unix timestamp of creation |
|
|
Unix timestamp of last update |
Source Code (Multi-Language)¶
Module: ragdoll.ingest.code
Ingests source code repositories and directories across multiple programming languages, templates, markup files, and build configurations.
Rather than blindly splitting source files by arbitrary character counts, Ragdoll applies language-aware extraction techniques to preserve structural boundaries (classes, functions, subroutines, modules). This ensures the LLM receives complete, coherent code blocks rather than fragmented snippets.
Complete List of Supported Languages & Formats¶
Category |
Language / Format |
Extensions / Special Filenames |
Extraction Strategy |
|---|---|---|---|
Python |
Python |
|
AST Parser: Extracts discrete |
C / C++ & GPU |
C, C++, CUDA |
|
Semantic Block Parser: Extracts |
Fortran |
Fortran 77 / 90 / 95 |
|
Routine Scanner: Detects and extracts |
Shell & Scripting |
Bash, POSIX Shell, Zsh |
|
Chunks script logic with file path headers and line number annotations. |
Templates & Markup |
XML Tasks & Recipes, Mako Web Templates |
|
Structured chunking preserving XML data/task definitions, workflow procedures, and Mako HTML templates. |
Build & Tooling |
CMake, Make, Docker |
|
Target-aware chunking preserving build targets, flags, and recipe rules. |
Modern Systems |
Rust, Go |
|
Context-aware code chunking with syntax metadata. |
Web & Frontend |
JavaScript, TypeScript |
|
Syntax-aware component and script chunking. |
Database & Config |
SQL, TOML, YAML, JSON |
|
Query and structured configuration chunking. |
LaTeX & Science |
LaTeX, BibTeX |
|
Document Chunking: Ingests research papers, scientific formulas, macros, and bibliography citations. |
Documentation & Specs |
Markdown, reStructuredText, Plain Text |
|
Section & Text Chunking: Ingests technical notes, RFCs, architecture specs, and design documents. |
Small File Handling & Context Headers¶
Small Files (<= 30 lines or <= chunk_size): Kept intact as a single Document (
node_type = "file") to prevent unnecessary fragmentation.Large Files: Sliced into semantic blocks or coherent overlapping chunks (
node_type = "chunk"or"function"/"class").Context Injection: Every extracted chunk is prefixed with a comment header (e.g.
// File: src/engine.cpp (class: Engine, lines 40-120)) so the LLM always knows the origin file path and exact line range for citations.
Extracted Metadata¶
Metadata Key |
Type |
Description |
|---|---|---|
|
|
|
|
|
Relative or absolute path to the source file |
|
|
Normalized language identifier (e.g. |
|
|
Node type ( |
|
|
Name of the function, class, subroutine, or file |
|
|
Starting line number in the source file |
|
|
Ending line number in the source file |
|
|
SHA-256 hash of file contents for incremental delta caching |
|
|
File modification epoch timestamp |
Automatic Ignore Rules¶
During directory traversal, the following directories and binary file extensions are automatically skipped:
Ignored Directories:
__pycache__,.git,.pixi,.tox,.venv,venv,node_modules,build,dist,.mypy_cache,.pytest_cache,*.egg-infoIgnored Artifacts:
.o,.so,.a,.dylib,.dll,.exe,.class,.pyc,.pyo,.tar,.gz,.zip,.bin,.dat,.png,.jpg,.pdf
CLI Usage & Extension Filtering¶
# Ingest all supported source files across a repository (incremental by default)
pixi run ragdoll ingest code /path/to/repo
# Ingest specific source directories
pixi run ragdoll ingest code ./src/ ./include/ ./recipes/
# Filter by specific extensions (e.g. only C++ and Python)
pixi run ragdoll ingest code /path/to/repo --ext cpp,cc,h,hpp,py
# Force re-indexing of all source files even if unmodified
pixi run ragdoll ingest code /path/to/repo --force
# Ingest specific XML task recipes and Mako templates
pixi run ragdoll ingest code ./templates/recipes/ --ext xml,mako
# Customize chunk sizing for non-AST source files
pixi run ragdoll ingest code ./src/ --chunk-size 1200 --chunk-overlap 150
Git Repository History¶
Module: ragdoll.ingest.git
Parses a local git repository to ingest commit history across all branches and tags. This allows the LLM to understand when features were introduced, why code was changed, and how different branches relate to one another.
Extraction Strategy¶
Using standard git CLI commands, it extracts each commit into a Document containing:
Commit Hash and Parent Hashes
Branch and Tag References (e.g.,
HEAD -> main,origin/feature-branch)Author Name and Date
Commit Subject and Body
Tip
Because it uses --all, it automatically covers the entire repository graph, regardless of which branch is currently checked out on your filesystem.
Incremental Ingestion & Change Detection¶
Ragdoll assigns a deterministic ID to each commit based on its SHA-1 hash (git-{repo_name}-{commit_hash}). On repeated invocations:
Existing commits already in ChromaDB are skipped in milliseconds, eliminating redundant Ollama embedding compute.
New commits added since the last run are embedded and upserted.
Use
-f/--forceto force re-indexing of all matching commits.
Extracted Metadata¶
Metadata Key |
Type |
Description |
|---|---|---|
|
|
|
|
|
Repository folder name |
|
|
Absolute path to the local repository |
|
|
SHA-1 commit hash |
|
|
Space-separated parent hashes |
|
|
Associated branch/tag references |
|
|
Author’s name |
|
|
Commit subject line |
|
|
Unix timestamp of the commit |
Example¶
# Ingest the 2,000 most recent commits across all branches (default)
pixi run ragdoll ingest git /path/to/local/repo
# Ingest full repository history (all commits from root to HEAD)
pixi run ragdoll ingest git /path/to/local/repo --all
# Or pass 0 for unlimited commits
pixi run ragdoll ingest git /path/to/local/repo --max-commits 0
# Exclude merge commits for high-signal direct changes
pixi run ragdoll ingest git /path/to/local/repo --no-merges
# Force re-indexing of all matching commits
pixi run ragdoll ingest git /path/to/local/repo --force
Source Filtering¶
All query commands support --source to filter retrieved chunks:
pixi run ragdoll search "memory allocation" --source jira
pixi run ragdoll summarize "database migration" --source pdf
pixi run ragdoll chat --source code
pixi run ragdoll search "bugfix" --source git
pixi run ragdoll search "feature request" --source github
This filters on the source metadata field in ChromaDB, which is set to
"pdf", "jira", "bitbucket", "github", "code", or "git" during ingestion.