|
1248 | 1248 | return; |
1249 | 1249 |
|
1250 | 1250 | sessions = CopilotService.GetAllSessions().ToList(); |
| 1251 | + _cachedAllSessionNames = null; |
1251 | 1252 |
|
1252 | 1253 | if (!_initialGridSet && sessions.Count > 1) |
1253 | 1254 | { |
|
1592 | 1593 | // Cross-session routing: check for @SessionName mentions matching other PolyPilot sessions. |
1593 | 1594 | // Build a lookup of normalized-token → session name for all sessions except the current one. |
1594 | 1595 | var crossSessionTargets = RouteToMentionedSessions(sessionName, finalPrompt); |
1595 | | - Console.WriteLine($"[CROSS-SESSION] source={sessionName} prompt={finalPrompt.Substring(0, Math.Min(50, finalPrompt.Length))} targets={crossSessionTargets.Count}"); |
| 1596 | + Console.WriteLine($"[CROSS-SESSION] source={sessionName} targets={crossSessionTargets.Count}"); |
1596 | 1597 | if (crossSessionTargets.Count > 0) |
1597 | 1598 | { |
| 1599 | + // Clear pending images — they cannot be forwarded cross-session. |
| 1600 | + if (hasImages) pendingImagesBySession.Remove(sessionName); |
| 1601 | + |
1598 | 1602 | // Add the user message to the current session's history |
1599 | 1603 | var sourceSession = sessions.FirstOrDefault(s => s.Name == sessionName); |
1600 | 1604 | sourceSession?.History.Add(ChatMessage.UserMessage(finalPrompt)); |
|
3402 | 3406 | private IReadOnlyList<string> availableModels => |
3403 | 3407 | CopilotService.AvailableModels.Count > 0 ? CopilotService.AvailableModels : ModelHelper.FallbackModels; |
3404 | 3408 |
|
| 3409 | + private IReadOnlyList<string>? _cachedAllSessionNames; |
3405 | 3410 | private IReadOnlyList<string> allSessionNames => |
3406 | | - CopilotService.GetAllSessionNames().ToList(); |
| 3411 | + _cachedAllSessionNames ??= CopilotService.GetAllSessionNames().ToList(); |
3407 | 3412 |
|
3408 | 3413 | /// <summary> |
3409 | 3414 | /// Parses @Mention tokens from the prompt and matches them against active session names. |
|
3424 | 3429 | .GroupBy(NormalizeToken, StringComparer.OrdinalIgnoreCase) |
3425 | 3430 | .ToDictionary(g => g.Key, g => g.First(), StringComparer.OrdinalIgnoreCase); |
3426 | 3431 |
|
3427 | | - Console.WriteLine($"[CROSS-SESSION] sessionLookup has {sessionLookup.Count} entries, looking for @mention in: {prompt.Substring(0, Math.Min(60, prompt.Length))}"); |
| 3432 | + Console.WriteLine($"[CROSS-SESSION] sessionLookup has {sessionLookup.Count} entries"); |
3428 | 3433 | if (sessionLookup.Count == 0) return result; |
3429 | 3434 |
|
3430 | 3435 | // Scan the entire message for @SessionName mentions (not just at start). |
3431 | | - // Matches: @word where word is alphanumeric, dot, underscore, or hyphen. |
3432 | | - var atMentionRegex = new System.Text.RegularExpressions.Regex(@"@([\w.\-]+)"); |
| 3436 | + // Requires @ to be at start-of-string or preceded by whitespace to avoid |
| 3437 | + // matching email addresses (user@host), code annotations (@override), etc. |
| 3438 | + var atMentionRegex = new System.Text.RegularExpressions.Regex(@"(?<!\S)@([\w.\-]+)"); |
3433 | 3439 | var matched = new HashSet<string>(StringComparer.OrdinalIgnoreCase); |
3434 | 3440 |
|
3435 | 3441 | foreach (System.Text.RegularExpressions.Match m in atMentionRegex.Matches(prompt)) |
|
0 commit comments