userMessageOrdinalToItemIndex maps a 0-based user-message ordinal into an index in the parent's Session.Messages Item slice. Returns ErrForkOutOfRange or ErrForkInSubSession on invalid input.
(s *session.Session, ordinal int)
| 441 | // into an index in the parent's Session.Messages Item slice. Returns |
| 442 | // ErrForkOutOfRange or ErrForkInSubSession on invalid input. |
| 443 | func userMessageOrdinalToItemIndex(s *session.Session, ordinal int) (int, error) { |
| 444 | if ordinal < 0 { |
| 445 | return 0, fmt.Errorf("%w: %d", ErrForkOutOfRange, ordinal) |
| 446 | } |
| 447 | seen := 0 |
| 448 | for i, item := range s.Messages { |
| 449 | switch { |
| 450 | case item.IsMessage(): |
| 451 | // Mirror GetAllMessages: system messages don't count. |
| 452 | if item.Message.Message.Role == chat.MessageRoleSystem { |
| 453 | continue |
| 454 | } |
| 455 | if item.Message.Message.Role != chat.MessageRoleUser { |
| 456 | continue |
| 457 | } |
| 458 | if seen == ordinal { |
| 459 | return i, nil |
| 460 | } |
| 461 | seen++ |
| 462 | case item.IsSubSession(): |
| 463 | subCount := countUserMessages(item.SubSession.GetAllMessages()) |
| 464 | if subCount > 0 && ordinal-seen < subCount { |
| 465 | return 0, fmt.Errorf("%w at ordinal %d", ErrForkInSubSession, ordinal) |
| 466 | } |
| 467 | seen += subCount |
| 468 | } |
| 469 | } |
| 470 | return 0, fmt.Errorf("%w: %d", ErrForkOutOfRange, ordinal) |
| 471 | } |
| 472 | |
| 473 | func countUserMessages(msgs []session.Message) int { |
| 474 | n := 0 |