1# RFC: Session Import and Export
2
3## Summary
4
5This RFC proposes a comprehensive system for importing and exporting conversation sessions in Crush.
6
7## Background
8
9Crush manages conversations through a hierarchical session system where:
10- Sessions contain metadata (title, token counts, cost, timestamps)
11- Sessions can have parent-child relationships (nested conversations)
12- Messages within sessions have structured content parts (text, tool calls, reasoning, etc.)
13- The current implementation provides export functionality but lacks import capabilities
14
15The latest commit introduced three key commands:
16- `crush sessions list` - List sessions in various formats
17- `crush sessions export` - Export all sessions and metadata
18- `crush sessions export-conversation <session-id>` - Export a single conversation with messages
19
20## Motivation
21
22Users need to:
231. Share conversations with others
242. Use conversation logs for debugging
253. Archive and analyze conversation history
264. Export data for external tools
27
28## Detailed Design
29
30### Core Data Model
31
32The session export format builds on the existing session structure:
33
34```go
35type Session struct {
36 ID string `json:"id"`
37 ParentSessionID string `json:"parent_session_id,omitempty"`
38 Title string `json:"title"`
39 MessageCount int64 `json:"message_count"`
40 PromptTokens int64 `json:"prompt_tokens"`
41 CompletionTokens int64 `json:"completion_tokens"`
42 Cost float64 `json:"cost"`
43 CreatedAt int64 `json:"created_at"`
44 UpdatedAt int64 `json:"updated_at"`
45 SummaryMessageID string `json:"summary_message_id,omitempty"`
46}
47
48type SessionWithChildren struct {
49 Session
50 Children []SessionWithChildren `json:"children,omitempty"`
51}
52```
53
54### Proposed Command Interface
55
56#### Export Commands (Already Implemented)
57```bash
58# List sessions in various formats
59crush sessions list [--format text|json|yaml|markdown]
60
61# Export all sessions with metadata
62crush sessions export [--format json|yaml|markdown]
63
64# Export single conversation with full message history
65crush sessions export-conversation <session-id> [--format markdown|json|yaml]
66```
67
68#### New Import Commands
69
70```bash
71# Import sessions from a file
72crush sessions import <file> [--format json|yaml] [--dry-run]
73
74# Import a single conversation
75crush sessions import-conversation <file> [--format json|yaml|markdown]
76
77```
78
79#### Enhanced Inspection Commands
80
81```bash
82# Search sessions by criteria
83crush sessions search [--title <pattern>] [--text <text>] [--format text|json]
84
85# Show session statistics
86crush sessions stats [--format text|json] [--group-by day|week|month]
87
88# Show statistics for a single session
89crush sessions stats <session-id> [--format text|json]
90```
91
92### Import/Export Formats
93
94#### Full Export Format (JSON)
95```json
96{
97 "version": "1.0",
98 "exported_at": "2025-01-27T10:30:00Z",
99 "total_sessions": 15,
100 "sessions": [
101 {
102 "id": "session-123",
103 "parent_session_id": "",
104 "title": "API Design Discussion",
105 "message_count": 8,
106 "prompt_tokens": 1250,
107 "completion_tokens": 890,
108 "cost": 0.0234,
109 "created_at": 1706356200,
110 "updated_at": 1706359800,
111 "children": [
112 {
113 "id": "session-124",
114 "parent_session_id": "session-123",
115 "title": "Implementation Details",
116 "message_count": 4,
117 "prompt_tokens": 650,
118 "completion_tokens": 420,
119 "cost": 0.0145,
120 "created_at": 1706359900,
121 "updated_at": 1706361200
122 }
123 ]
124 }
125 ]
126}
127```
128
129#### Conversation Export Format (JSON)
130```json
131{
132 "version": "1.0",
133 "session": {
134 "id": "session-123",
135 "title": "API Design Discussion",
136 "created_at": 1706356200,
137 "message_count": 3
138 },
139 "messages": [
140 {
141 "id": "msg-001",
142 "session_id": "session-123",
143 "role": "user",
144 "parts": [
145 {
146 "type": "text",
147 "data": {
148 "text": "Help me design a REST API for user management"
149 }
150 }
151 ],
152 "created_at": 1706356200
153 },
154 {
155 "id": "msg-002",
156 "session_id": "session-123",
157 "role": "assistant",
158 "model": "gpt-4",
159 "provider": "openai",
160 "parts": [
161 {
162 "type": "text",
163 "data": {
164 "text": "I'll help you design a REST API for user management..."
165 }
166 },
167 {
168 "type": "finish",
169 "data": {
170 "reason": "stop",
171 "time": 1706356230
172 }
173 }
174 ],
175 "created_at": 1706356220
176 }
177 ]
178}
179```
180
181### API Implementation
182
183#### Import Service Interface
184```go
185type ImportService interface {
186 // Import sessions from structured data
187 ImportSessions(ctx context.Context, data ImportData, opts ImportOptions) (ImportResult, error)
188
189 // Import single conversation
190 ImportConversation(ctx context.Context, data ConversationData, opts ImportOptions) (Session, error)
191
192 // Validate import data without persisting
193 ValidateImport(ctx context.Context, data ImportData) (ValidationResult, error)
194}
195
196type ImportOptions struct {
197 ConflictStrategy ConflictStrategy // skip, merge, replace
198 DryRun bool
199 ParentSessionID string // For conversation imports
200 PreserveIDs bool // Whether to preserve original IDs
201}
202
203type ConflictStrategy string
204
205const (
206 ConflictSkip ConflictStrategy = "skip" // Skip existing sessions
207 ConflictMerge ConflictStrategy = "merge" // Merge with existing
208 ConflictReplace ConflictStrategy = "replace" // Replace existing
209)
210
211type ImportResult struct {
212 TotalSessions int `json:"total_sessions"`
213 ImportedSessions int `json:"imported_sessions"`
214 SkippedSessions int `json:"skipped_sessions"`
215 Errors []ImportError `json:"errors,omitempty"`
216 SessionMapping map[string]string `json:"session_mapping"` // old_id -> new_id
217}
218```
219
220#### Enhanced Export Service
221```go
222type ExportService interface {
223 // Export sessions with filtering
224 ExportSessions(ctx context.Context, opts ExportOptions) ([]SessionWithChildren, error)
225
226 // Export conversation with full message history
227 ExportConversation(ctx context.Context, sessionID string, opts ExportOptions) (ConversationExport, error)
228
229 // Search and filter sessions
230 SearchSessions(ctx context.Context, criteria SearchCriteria) ([]Session, error)
231
232 // Get session statistics
233 GetStats(ctx context.Context, opts StatsOptions) (SessionStats, error)
234}
235
236type ExportOptions struct {
237 Format string // json, yaml, markdown
238 IncludeMessages bool // Include full message content
239 DateRange DateRange // Filter by date range
240 SessionIDs []string // Export specific sessions
241}
242
243type SearchCriteria struct {
244 TitlePattern string
245 DateRange DateRange
246 MinCost float64
247 MaxCost float64
248 ParentSessionID string
249 HasChildren *bool
250}
251```
252
253## Implementation Status
254
255The proposed session import/export functionality has been implemented as a prototype as of July 2025.
256
257### Implemented Commands
258
259All new commands have been added to `internal/cmd/sessions.go`:
260
261- **Import**: `crush sessions import <file> [--format json|yaml] [--dry-run]`
262 - Supports hierarchical session imports with parent-child relationships
263 - Generates new UUIDs to avoid conflicts
264 - Includes validation and dry-run capabilities
265
266- **Import Conversation**: `crush sessions import-conversation <file> [--format json|yaml]`
267 - Imports single conversations with full message history
268 - Preserves all message content parts and metadata
269
270- **Search**: `crush sessions search [--title <pattern>] [--text <text>] [--format text|json]`
271 - Case-insensitive title search and message content search
272 - Supports combined search criteria with AND logic
273
274- **Stats**: `crush sessions stats [--format text|json] [--group-by day|week|month]`
275 - Comprehensive usage statistics (sessions, messages, tokens, costs)
276 - Time-based grouping with efficient database queries
277
278### Database Changes
279
280Added new SQL queries in `internal/db/sql/sessions.sql`:
281- Search queries for title and message content filtering
282- Statistics aggregation queries with time-based grouping
283- All queries optimized for performance with proper indexing
284
285### Database Schema Considerations
286
287The current schema supports the import/export functionality. Additional indexes may be needed for search performance:
288
289```sql
290-- Optimize session searches by date and cost
291CREATE INDEX idx_sessions_created_at ON sessions(created_at);
292CREATE INDEX idx_sessions_cost ON sessions(cost);
293CREATE INDEX idx_sessions_title ON sessions(title COLLATE NOCASE);
294
295-- Optimize message searches by session
296CREATE INDEX idx_messages_session_created ON messages(session_id, created_at);
297```