AddSession adds a new session to the store, including any messages
(ctx context.Context, session *Session)
| 592 | |
| 593 | // AddSession adds a new session to the store, including any messages |
| 594 | func (s *SQLiteSessionStore) AddSession(ctx context.Context, session *Session) error { |
| 595 | if session.ID == "" { |
| 596 | return ErrEmptyID |
| 597 | } |
| 598 | |
| 599 | fields, err := sessionPersistedFieldsOf(session) |
| 600 | if err != nil { |
| 601 | return err |
| 602 | } |
| 603 | |
| 604 | // Use a transaction to insert session and its items |
| 605 | tx, err := s.db.BeginTx(ctx, nil) |
| 606 | if err != nil { |
| 607 | return err |
| 608 | } |
| 609 | defer func() { _ = tx.Rollback() }() |
| 610 | |
| 611 | _, err = tx.ExecContext(ctx, |
| 612 | `INSERT INTO sessions ( |
| 613 | id, tools_approved, input_tokens, output_tokens, title, cost, send_user_message, |
| 614 | max_iterations, working_dir, created_at, permissions, agent_model_overrides, |
| 615 | custom_models_used, thinking, parent_id |
| 616 | ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, |
| 617 | session.ID, session.ToolsApproved, session.InputTokens, session.OutputTokens, session.Title, |
| 618 | session.Cost, session.SendUserMessage, session.MaxIterations, session.WorkingDir, |
| 619 | session.CreatedAt.Format(time.RFC3339), fields.PermissionsJSON, fields.AgentModelOverridesJSON, |
| 620 | fields.CustomModelsUsedJSON, false, fields.ParentID) |
| 621 | if err != nil { |
| 622 | return err |
| 623 | } |
| 624 | |
| 625 | // Insert all messages into session_items |
| 626 | for position, item := range session.Messages { |
| 627 | if err := s.addItemTx(ctx, tx, session.ID, position, item); err != nil { |
| 628 | return fmt.Errorf("adding item at position %d: %w", position, err) |
| 629 | } |
| 630 | } |
| 631 | |
| 632 | return tx.Commit() |
| 633 | } |
| 634 | |
| 635 | // scanSession scans a single row into a Session struct. |
| 636 | // Note: Messages are loaded separately from session_items table. |