fix: improve regex handling and preview limits in TeamMemberLogsFinder and MemberLogsTab

- Enhanced regex patterns in TeamMemberLogsFinder to allow for escaped sequences and increased character limits for text and content previews.
- Updated the MemberLogsTab component to prioritize recent previews over fallback mechanisms, ensuring more relevant message displays for lead users.
- Adjusted the length limit for returned previews to 1500 characters for better context in log summaries.
This commit is contained in:
iliya 2026-03-15 22:17:53 +02:00
parent 457dc13ef9
commit de205b13d7
2 changed files with 18 additions and 9 deletions

View file

@ -1508,25 +1508,29 @@ export class TeamMemberLogsFinder {
* Looks for the first text block content via regex (avoids full JSON parse).
*/
private static extractAssistantPreview(line: string): string | null {
// Match {"type":"text","text":"..."} blocks
const textMatch = /"type"\s*:\s*"text"[^}]*"text"\s*:\s*"([^"]{1,200})/.exec(line);
// Match {"type":"text","text":"..."} blocks — allow escaped sequences
const textMatch = /"type"\s*:\s*"text"[^}]*"text"\s*:\s*"((?:[^"\\]|\\.){1,400})/.exec(line);
if (textMatch?.[1]) {
const raw = textMatch[1]
.replace(/\\"/g, '"')
.replace(/\\n/g, ' ')
.replace(/\\t/g, ' ')
.replace(/\\\\/g, '\\')
.replace(/\s+/g, ' ')
.trim();
return raw.length > 120 ? raw.slice(0, 120) + '...' : raw;
return raw.length > 1500 ? raw.slice(0, 1500) + '...' : raw;
}
// Fallback: top-level string content
const contentMatch = /"content"\s*:\s*"([^"]{1,200})/.exec(line);
const contentMatch = /"content"\s*:\s*"((?:[^"\\]|\\.){1,400})/.exec(line);
if (contentMatch?.[1]) {
const raw = contentMatch[1]
.replace(/\\"/g, '"')
.replace(/\\n/g, ' ')
.replace(/\\t/g, ' ')
.replace(/\\\\/g, '\\')
.replace(/\s+/g, ' ')
.trim();
return raw.length > 120 ? raw.slice(0, 120) + '...' : raw;
return raw.length > 1500 ? raw.slice(0, 1500) + '...' : raw;
}
return null;
}
@ -1536,14 +1540,17 @@ export class TeamMemberLogsFinder {
* Thinking blocks use {"type":"thinking","thinking":"..."}.
*/
private static extractThinkingPreview(line: string): string | null {
const match = /"thinking"\s*:\s*"([^"]{1,200})/.exec(line);
// Allow escaped sequences (e.g. \" \n \\) inside the captured string value
const match = /"thinking"\s*:\s*"((?:[^"\\]|\\.){1,400})/.exec(line);
if (match?.[1]) {
const raw = match[1]
.replace(/\\"/g, '"')
.replace(/\\n/g, ' ')
.replace(/\\t/g, ' ')
.replace(/\\\\/g, '\\')
.replace(/\s+/g, ' ')
.trim();
return raw.length > 120 ? raw.slice(0, 120) + '...' : raw;
return raw.length > 1500 ? raw.slice(0, 1500) + '...' : raw;
}
return null;
}

View file

@ -338,10 +338,12 @@ export const MemberLogsTab = ({
// Show only AI outputs — the actual work results.
// If no outputs found, fall back to summary previews.
if (showLeadPreview) {
// Prefer recentPreviews (task-scoped thinking + output) over chunk extraction
// because chunks don't capture thinking blocks.
const fromPreviews = buildLeadPreviewMessages();
if (fromPreviews.length > 0) return fromPreviews;
const outputs = raw.filter((m) => m.kind !== 'user');
if (outputs.length > 0) return outputs;
const fallback = buildLeadPreviewMessages();
if (fallback.length > 0) return fallback;
return raw; // ultimate fallback: show everything including user messages
}
return raw;