Rosetta CLI
Knowledge base publishing and management tools powered by RAGFlow
🎯 Overview
This directory contains the Python package for publishing knowledge base content to RAGFlow instances. The CLI supports multi-environment workflows with smart change detection and auto-metadata extraction.
Community
Key Features
- 🚀 Smart Publishing - MD5 hash-based change detection (~77% faster republishing)
- 🏗️ Modular Architecture - Command pattern with service layer for maintainability
- 🏷️ Metadata Tags - path-derived tags in document metadata for
--tagsfiltering - 📊 Parse Status Tracking - Monitor document parsing progress with visual indicators
- 🔄 Upsert Semantics - No duplicates, republishing updates existing documents
- ⏱️ Performance Timing - All commands show execution time
- 🌍 Multi-Environment - Switch between local, dev, and production configs
- 🔐 API Key Auth - Secure authentication via RAGFlow API keys
- 🎯 Server-Side Filtering - Reduce network traffic with metadata conditions
Quick Navigation
- Complete Setup Guide: See docs/QUICKSTART.md for detailed setup instructions
- CLI Commands: See CLI Commands for all available commands
- Environment Management: See Environment Management for switching configs
📁 Contents
src/rosetta-cli/
├── pyproject.toml # Package metadata + console entrypoint
├── rosetta_cli/ # Installable Python package
│ ├── cli.py # CLI entry point
│ ├── commands/ # Command implementations
│ ├── services/ # Shared business logic
│ ├── rosetta_config.py # Configuration management
│ ├── rosetta_publisher.py # Publishing orchestration
│ └── ragflow_client.py # RAGFlow SDK wrapper
├── env.template # Environment configuration template
├── tests/ # CLI unit tests
└── README.md # This file
🚀 Quick Start
Complete setup instructions are in docs/QUICKSTART.md. Here's the quick reference:
Prerequisites
- Python 3.12 (required by ragflow-sdk 0.23.1)
- RAGFlow instance (local via Docker Compose or remote)
uvxfor installed CLI usage- Root virtual environment configured for local CLI development
Installed Usage
uvx rosetta-cli@latest version
uvx rosetta-cli@latest verify
Local Development
python3 -m venv venv
venv/bin/pip install -r requirements.txt
cp src/rosetta-cli/.env.dev .env
venv/bin/rosetta-cli verify
🔧 CLI Commands
All commands support --env <environment> flag to override the active environment.
Version
uvx rosetta-cli@latest version
Publishing Commands
Publish Knowledge Base Content
# Publish all instructions (only changed files)
uvx rosetta-cli@latest publish ../../instructions
# Publish business context
uvx rosetta-cli@latest publish ../../business
# Force republish all files (bypass change detection)
uvx rosetta-cli@latest publish ../../instructions --force
# Preview changes without publishing
uvx rosetta-cli@latest publish ../../instructions --dry-run
# Use different environment
uvx rosetta-cli@latest publish ../../instructions --env production
Performance:
- First publish: ~10-15s per file (embedding generation + parsing)
- Subsequent publishes: Only changed files (~77% faster)
- Dry run: Preview in ~2-3s
What gets published:
File: /instructions/agents/r1/agents.md
Published as:
Document ID: b0ec4d56-6cc5-5bbd-9868-5d49afa2a7d8 (UUID from path)
Title: agents.md (path relative to the release folder, no tag prefixes)
Dataset: aia-r1 (from template: aia-{release})
Tags: ["instructions", "agents", "r1", "agents.md"] (in metadata only)
Domain: instructions (first folder)
Release: r1 (auto-detected from path)
Content Hash: abc123... (MD5 of content)
Trigger Document Parsing
Re-parse documents without re-uploading (useful for changing parser settings):
# Parse all unparsed documents
uvx rosetta-cli@latest parse
# Parse specific dataset
uvx rosetta-cli@latest parse --dataset aia-r1
# Force re-parse ALL documents
uvx rosetta-cli@latest parse --dataset aia-r1 --force
# Preview without parsing (dry run)
uvx rosetta-cli@latest parse --dataset aia-r1 --dry-run
List Documents
# List documents in default dataset
uvx rosetta-cli@latest list-dataset
# List specific dataset
uvx rosetta-cli@latest list-dataset --dataset aia-r1
Output shows:
- Document title (path relative to the release folder, no tag prefixes)
- Document ID, file size, parse status, chunk count
- Metadata (tags, domain, release, source path)
Cleanup Dataset
# Preview cleanup without deleting
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --dry-run
# Cleanup documents with specific prefix
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --prefix "aqa-phase" --dry-run
# Cleanup documents with specific tags (space-separated)
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --tags "r1 agents" --dry-run
# Cleanup documents with specific tags (comma-separated)
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --tags "r1,agents" --dry-run
# Force cleanup without confirmation
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --force
# Force cleanup with prefix
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --prefix "aqa-phase" --force
# Force cleanup with tags
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --tags "r1,agents" --force
⚠️ Warning: Without --prefix or --tags, this deletes ALL documents. Use --dry-run first.
Filtering Options:
--prefix: Match documents by literal title prefix (e.g.,"aqa-phase","core/skills")--tags: Match documents by metadata tags (e.g.,"r1 agents"or"r1,agents")- Uses OR logic: finds documents with ANY of the specified tags
- Server-side filtering for efficiency
Verification Commands
Verify Connection
uvx rosetta-cli@latest verify
# Check production environment
uvx rosetta-cli@latest verify --env production
Checks:
- API key validity
- RAGFlow server connectivity
- System health (database, Redis, document engine)
- Available datasets
🌍 Environment Management
Configuration Files
| File | Environment | Purpose |
|---|---|---|
env.template |
Template | Create new environments |
.env |
Active | Current configuration (gitignored) |
.env.local |
Local | Local RAGFlow development |
.env.remote |
Remote | Production RAGFlow instance |
Switch Environments
Method 1: Copy file to .env (recommended)
# Switch to local
cp .env.local .env
# Switch to production
cp .env.remote .env
# Check current environment
grep "ENVIRONMENT=" .env
Method 2: Use --env flag (temporary override)
uvx rosetta-cli@latest list-dataset --env local
uvx rosetta-cli@latest publish ../../instructions --env production
Environment Variables
# Required
RAGFLOW_BASE_URL=http://your-ragflow-instance
RAGFLOW_API_KEY=ragflow-xxx...
ENVIRONMENT=local
# Dataset Configuration
RAGFLOW_DATASET_DEFAULT=aia
RAGFLOW_DATASET_TEMPLATE=aia-{release}
# Embedding Model (optional)
RAGFLOW_EMBEDDING_MODEL=text-embedding-3-small@OpenAI
# Chunking Configuration (optional)
RAGFLOW_CHUNK_METHOD=naive
RAGFLOW_CHUNK_TOKEN_NUM=512
RAGFLOW_DELIMITER=\n
RAGFLOW_AUTO_KEYWORDS=0
RAGFLOW_AUTO_QUESTIONS=0
Creating New Environments
cp env.template .env.staging
nano .env.staging
uvx rosetta-cli@latest verify --env staging
🏗️ Architecture
Key Components
RAGFlowClient (ragflow_client.py)
Wrapper around ragflow-sdk:
from rosetta_cli.ragflow_client import RAGFlowClient, DocumentMetadata
client = RAGFlowClient(api_key="ragflow-xxx", base_url="http://your-ragflow-instance")
# Dataset management
client.create_dataset(name="aia-r1", description="Release 1")
client.get_dataset(name="aia-r1")
client.list_datasets()
# Document upload with change detection
client.upload_document(
file_path=Path("agents.md"),
metadata=DocumentMetadata(...),
dataset_id="dataset-id",
force=False # Skip if unchanged
)
# Health check
client.verify_connection()
client.get_system_health()
RosettaConfig (rosetta_config.py)
Configuration management with smart .env discovery:
from rosetta_cli.rosetta_config import RosettaConfig
# Auto-discover .env (searches cwd, script dir, git root)
config = RosettaConfig.from_env()
# Use specific environment
config = RosettaConfig.from_env(environment="production")
# Validate configuration
config.validate()
ContentPublisher (rosetta_publisher.py)
Publishing logic with metadata extraction:
from rosetta_cli.rosetta_publisher import ContentPublisher
publisher = ContentPublisher(client, config, workspace_root)
results = publisher.publish(
content_path=Path("../../instructions"),
force=False, # Skip unchanged files
dry_run=False, # Preview mode
no_parse=False, # Skip parsing after upload
parse_timeout=1200 # Parse timeout in seconds
)
print(f"Published: {results.published_count}")
print(f"Skipped: {results.skipped_count}")
print(f"Failed: {results.failed_count}")
Metadata Extraction:
File: /instructions/agents/r1/bootstrap.md
Extracted:
Tags: ["instructions", "agents", "r1", "bootstrap.md"]
Domain: instructions
Release: r1
Title: bootstrap.md
Content Hash: abc123... (MD5)
Document ID: uuid-from-path
🎯 Titles and Tags
Document Titles
Titles carry no tag prefixes. A title is the document path relative to its
release folder, or just the filename for files outside an instructions/<release> tree:
File: /instructions/agents/r1/agents.md → Title: agents.md
File: /instructions/r3/core/skills/coding/SKILL.md → Title: core/skills/coding/SKILL.md
File: /business/project/RFP.pdf → Title: RFP.pdf
Where Tags Live
Tags are stored in document metadata (meta_fields.tags) only, never in the title.
How Tags are Generated
Tags come from the file path, plus optional Markdown frontmatter tags:
File: /instructions/r3/core/skills/coding/SKILL.md
Tags: instructions, r3, core, skills, coding, SKILL.md,
coding/SKILL.md, skills/coding/SKILL.md
- Every folder in the path
- The filename, with extension
- The last two and last three path segments, joined with
/ - Any
tags:values from Markdown frontmatter (.md/.markdownonly)
Using Tags for Filtering
# Delete all instruction documents
uvx rosetta-cli@latest cleanup-dataset --tags "instructions"
# Delete documents tagged "agents" OR "r1"
uvx rosetta-cli@latest cleanup-dataset --tags "agents,r1"
Use --prefix for literal title-prefix matching instead, e.g. --prefix "core/skills".
💻 Usage Examples
Example 1: First-Time Setup
python3 -m venv venv
venv/bin/pip install -r requirements.txt
cp src/rosetta-cli/env.template .env
nano .env # Add RAGFLOW_BASE_URL and RAGFLOW_API_KEY
uvx rosetta-cli@latest verify
uvx rosetta-cli@latest publish instructions
Example 2: Daily Publishing Workflow
uvx rosetta-cli@latest publish ../../instructions --dry-run
uvx rosetta-cli@latest publish ../../instructions
uvx rosetta-cli@latest list-dataset
Example 3: Multi-Environment Publishing
# Publish to dev
uvx rosetta-cli@latest publish ../../instructions --env dev
# Verify on dev
uvx rosetta-cli@latest verify --env dev
# Publish to production
uvx rosetta-cli@latest publish ../../instructions --env prod
Example 4: Cleanup and Republish
# Preview deletion
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --dry-run
# Delete all documents
uvx rosetta-cli@latest cleanup-dataset --dataset aia-r1 --force
# Republish everything
uvx rosetta-cli@latest publish ../../instructions --force
Example 5: Programmatic Usage
from pathlib import Path
from rosetta_cli.ragflow_client import RAGFlowClient, DocumentMetadata
from rosetta_cli.rosetta_config import RosettaConfig
from rosetta_cli.rosetta_publisher import ContentPublisher
config = RosettaConfig.from_env()
client = RAGFlowClient(
api_key=config.api_key,
base_url=config.base_url,
embedding_model=config.embedding_model,
chunk_method=config.chunk_method,
parser_config=config.parser_config
)
client.verify_connection()
publisher = ContentPublisher(client, config, Path("/path/to/workspace"))
results = publisher.publish(
content_path=Path("/path/to/workspace") / "instructions",
force=False,
dry_run=False
)
print(f"Published: {results.published_count}, Skipped: {results.skipped_count}")
🔍 Troubleshooting
Error: "api_key cannot be empty"
Set RAGFLOW_API_KEY in .env:
nano .env
# Add: RAGFLOW_API_KEY=ragflow-xxxxxxxxxxxxxxxxxxxx
Error: "Invalid API key or expired token"
Generate new API key:
- Login to RAGFlow
- Profile → API Keys → Generate New Key
- Update
.envfile
Error: "Connection refused"
- Check RAGFlow is running:
docker ps | grep ragflow - Verify URL:
grep RAGFLOW_BASE_URL .env - Test:
curl http://your-ragflow-instance/v1/system/healthz
Error: "Module 'ragflow_sdk' not found"
venv/bin/pip install -r requirements.txt
Error: "No .env file found"
cp src/rosetta-cli/env.template .env
nano .env
Parse Status Shows "FAIL"
- Check document format (PDF, MD, TXT supported)
- Re-trigger parsing:
uvx rosetta-cli@latest parse --dataset aia-r1 --force - Check RAGFlow logs:
docker logs ragflow-server
Slow Publishing Performance
- Use faster embedding model:
RAGFLOW_EMBEDDING_MODEL=text-embedding-3-small@OpenAI - Ensure change detection works (don't use
--force) - Reduce chunk size:
RAGFLOW_CHUNK_TOKEN_NUM=256
Documents Not Showing Tags
Tags live in metadata, not in the title. list-dataset prints them on their own line:
uvx rosetta-cli@latest list-dataset
# Output: 1. agents.md
# Tags: instructions, agents, r1, agents.md
🚦 Performance Tips
1. Use Change Detection
# Good: Only publishes changed files (~77% faster)
uvx rosetta-cli@latest publish ../../instructions
# Bad: Republishes everything
uvx rosetta-cli@latest publish ../../instructions --force
2. Use Dry Run to Preview
# Preview (fast)
uvx rosetta-cli@latest publish ../../instructions --dry-run
# Then publish for real
uvx rosetta-cli@latest publish ../../instructions
3. Optimize Chunking
# Faster parsing
RAGFLOW_CHUNK_TOKEN_NUM=256
# Better context
RAGFLOW_CHUNK_TOKEN_NUM=1024
4. Use Selective Cleanup
# Fast: Delete specific documents
uvx rosetta-cli@latest cleanup-dataset --tags "agents" --force
# Slow: Delete and republish everything
uvx rosetta-cli@latest cleanup-dataset --force
uvx rosetta-cli@latest publish ../../instructions --force
5. Monitor Parse Status
uvx rosetta-cli@latest list-dataset | grep "Parse Status"
📖 Advanced Topics
Custom Dataset Naming
The RAGFLOW_DATASET_TEMPLATE supports {release} placeholder:
RAGFLOW_DATASET_TEMPLATE=aia-{release}
# /instructions/r1/file.md → aia-r1
# /instructions/r2/file.md → aia-r2
# /instructions/file.md → aia (default)
Supported File Types
Text files (extracted and chunked):
- Markdown (
.md) - Plain text (
.txt)
Binary files (uploaded for storage):
- PDF, Excel, Word, PowerPoint
Environment File Discovery
When running commands without specifying config, search order:
- Current directory:
.env.{environment}or.env - Script directory:
.env.{environment}or.env - Git root:
.env.{environment}or.env
📝 Related Documentation
- Complete Setup: docs/QUICKSTART.md - Comprehensive setup guide
- Architecture: docs/CONTEXT.md - System architecture
- Environment Template:
env.template- Configuration options - Requirements:
requirements.txt- Python dependencies
Release files for rosetta-cli 3.0.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rosetta_cli-3.0.6.tar.gz | 56.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rosetta_cli-3.0.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 115.5 kB
Release files / rosetta_cli-3.0.6.tar.gz
| Download URL | rosetta_cli-3.0.6.tar.gz |
|---|---|
| Size | 56.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
44d77ce23ee58b452a067f2fb889c2458021cfc1076c0c5e78fc33f916239e33
|
|
BLAKE2b-256 checksum How to use checksums |
e53efae855708190b9a9bb52d6f4d7780cdd2014546a171f60a27cabf02771a2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / rosetta_cli-3.0.6-py3-none-any.whl
| Download URL | rosetta_cli-3.0.6-py3-none-any.whl |
|---|---|
| Size | 59.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4425d0281d7288252d6a863020f70540c4fbca5e9b18f1d033ad174e39d6beab
|
|
BLAKE2b-256 checksum How to use checksums |
4be7f50050ef7adedf6c5e7a32960b56410fde09f4418a3ae2e3edb93c5917ea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|