API Documentation
CTK (Conversation Toolkit) is a plugin-based system for managing AI conversations from multiple providers. This document covers the core architecture, database schema, and Python API.
Architecture Overview
CTK is built around three core concepts:
- ConversationTree: All conversations are stored as trees, preserving branching history
- Plugin System: Auto-discovered importers/exporters for different formats
- SQLite Backend: Local, searchable database with full-text search
Core Classes
ConversationTree
The primary data structure representing a conversation.
from ctk.core.models import ConversationTree, Message, MessageContent, MessageRole
# Create a new conversation
tree = ConversationTree(
id="conv_123",
title="Python Discussion"
)
# Add messages
user_msg = Message(
role=MessageRole.USER,
content=MessageContent(text="What is Python?")
)
tree.add_message(user_msg)
# Get all paths (for branching conversations)
paths = tree.get_all_paths()
# Get longest path
longest = tree.get_longest_path()
ConversationDB
Database interface for storing and querying conversations.
from ctk import ConversationDB
with ConversationDB("chats.db") as db:
# Save conversation
db.save_conversation(tree)
# Load by ID
conv = db.load_conversation("conv_123")
# Search
results = db.search_conversations("python async")
# Get statistics
stats = db.get_statistics()
Message Types
| Class | Description |
|---|---|
Message | Single message with role, content, and metadata |
MessageContent | Text content with optional media attachments |
MessageRole | Enum: USER, ASSISTANT, SYSTEM, TOOL |
ConversationMetadata | Title, tags, timestamps, source info |
Database Schema
CTK uses SQLite with the following structure:
| Table | Description |
|---|---|
conversations | Metadata, title, timestamps, source, model |
messages | Content, role, parent/child relationships |
tags | Searchable tags per conversation |
paths | Cached conversation paths for fast retrieval |
Key Indexes
- Full-text search on message content
- Source and model filtering
- Date range queries
- Tag-based filtering
Plugin System
Registry
Plugins are auto-discovered at startup:
from ctk import registry
# List available plugins
print(registry.list_importers())
print(registry.list_exporters())
# Import file
conversations = registry.import_file("export.json", format="openai")
# Export conversations
registry.export_conversations(conversations, "output.jsonl", format="jsonl")
Available Importers
| Format | Description |
|---|---|
openai | ChatGPT exports (preserves tree structure) |
anthropic | Claude exports |
gemini | Google Gemini/Bard |
copilot | GitHub Copilot from VS Code |
jsonl | Generic JSONL for local LLMs |
filesystem_coding | Auto-detect coding agent data |
Available Exporters
| Format | Description |
|---|---|
jsonl | JSONL for fine-tuning |
json | Native CTK, OpenAI, or Anthropic format |
markdown | Human-readable with tree visualization |
html | Interactive HTML5 app |
hugo | Hugo page bundles for static sites |
CLI Reference
Core Commands
| Command | Description |
|---|---|
ctk import <file> | Import conversations from file |
ctk list | List conversations with filtering |
ctk search <query> | Full-text search |
ctk ask <query> | Natural language query (LLM-powered) |
ctk show <id> | Display specific conversation |
ctk tree <id> | View tree structure |
ctk export <output> | Export conversations |
ctk chat | Launch interactive TUI |
Organization Commands
| Command | Description |
|---|---|
ctk star <id> | Star conversation |
ctk pin <id> | Pin conversation |
ctk archive <id> | Archive conversation |
ctk title <id> <title> | Rename conversation |
Database Commands
| Command | Description |
|---|---|
ctk stats | Show database statistics |
ctk merge <db1> <db2> | Merge databases |
ctk diff <db1> <db2> | Compare databases |
ctk filter | Create filtered database |
ctk plugins | List available plugins |
Sanitization
CTK can remove sensitive data before sharing:
from ctk.core.sanitizer import Sanitizer, SanitizationRule
import re
sanitizer = Sanitizer(enabled=True)
# Add custom pattern
sanitizer.add_rule(SanitizationRule(
name="internal_urls",
pattern=re.compile(r'https://internal\.company\.com/[^\s]+'),
replacement="[INTERNAL_URL]"
))
Built-in Patterns
- API keys (OpenAI, Anthropic, AWS, etc.)
- Passwords and tokens
- SSH keys
- Database URLs
- Credit card numbers
Full Reference
For complete documentation: