llama1's picture
Upload 781 files
5da4770 verified
export type DiffType = 'unchanged' | 'added' | 'removed';
export interface LineDiff {
type: DiffType;
oldLine: string | null;
newLine: string | null;
lineNumber: number;
}
export interface CharDiffPart {
text: string;
type: DiffType;
}
export interface DiffStats {
additions: number;
deletions: number;
}
export interface ExtractedData {
filePath: string | null;
oldStr: string | null;
newStr: string | null;
success?: boolean;
timestamp?: string;
}
export const extractFromNewFormat = (content: any): ExtractedData => {
if (!content) {
return { filePath: null, oldStr: null, newStr: null };
}
if (typeof content === 'string') {
// Only try to parse if it looks like JSON
const trimmed = content.trim();
if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
try {
console.debug('StrReplaceToolView: Attempting to parse JSON string:', content.substring(0, 100) + '...');
const parsed = JSON.parse(content);
console.debug('StrReplaceToolView: Successfully parsed JSON:', parsed);
return extractFromNewFormat(parsed);
} catch (error) {
console.error('StrReplaceToolView: JSON parse error:', error, 'Content:', content.substring(0, 200));
return { filePath: null, oldStr: null, newStr: null };
}
} else {
console.debug('StrReplaceToolView: String content does not look like JSON, skipping parse');
return { filePath: null, oldStr: null, newStr: null };
}
}
if (typeof content !== 'object') {
return { filePath: null, oldStr: null, newStr: null };
}
if ('tool_execution' in content && typeof content.tool_execution === 'object') {
const toolExecution = content.tool_execution;
const args = toolExecution.arguments || {};
console.debug('StrReplaceToolView: Extracted from new format:', {
filePath: args.file_path,
oldStr: args.old_str ? `${args.old_str.substring(0, 50)}...` : null,
newStr: args.new_str ? `${args.new_str.substring(0, 50)}...` : null,
success: toolExecution.result?.success
});
return {
filePath: args.file_path || null,
oldStr: args.old_str || null,
newStr: args.new_str || null,
success: toolExecution.result?.success,
timestamp: toolExecution.execution_details?.timestamp
};
}
if ('role' in content && 'content' in content && typeof content.content === 'string') {
console.debug('StrReplaceToolView: Found role/content structure with string content, parsing...');
return extractFromNewFormat(content.content);
}
if ('role' in content && 'content' in content && typeof content.content === 'object') {
console.debug('StrReplaceToolView: Found role/content structure with object content');
return extractFromNewFormat(content.content);
}
return { filePath: null, oldStr: null, newStr: null };
};
export const extractFromLegacyFormat = (content: any, extractToolData: any, extractFilePath: any, extractStrReplaceContent: any): ExtractedData => {
const assistantToolData = extractToolData(content);
if (assistantToolData.toolResult) {
const args = assistantToolData.arguments || {};
console.debug('StrReplaceToolView: Extracted from legacy format (extractToolData):', {
filePath: assistantToolData.filePath || args.file_path,
oldStr: args.old_str ? `${args.old_str.substring(0, 50)}...` : null,
newStr: args.new_str ? `${args.new_str.substring(0, 50)}...` : null
});
return {
filePath: assistantToolData.filePath || args.file_path || null,
oldStr: args.old_str || null,
newStr: args.new_str || null
};
}
const legacyFilePath = extractFilePath(content);
const strReplaceContent = extractStrReplaceContent(content);
console.debug('StrReplaceToolView: Extracted from legacy format (fallback):', {
filePath: legacyFilePath,
oldStr: strReplaceContent.oldStr ? `${strReplaceContent.oldStr.substring(0, 50)}...` : null,
newStr: strReplaceContent.newStr ? `${strReplaceContent.newStr.substring(0, 50)}...` : null
});
return {
filePath: legacyFilePath,
oldStr: strReplaceContent.oldStr,
newStr: strReplaceContent.newStr
};
};
export const parseNewlines = (text: string): string => {
return text.replace(/\\n/g, '\n');
};
export const generateLineDiff = (oldText: string, newText: string): LineDiff[] => {
const parsedOldText = parseNewlines(oldText);
const parsedNewText = parseNewlines(newText);
const oldLines = parsedOldText.split('\n');
const newLines = parsedNewText.split('\n');
const diffLines: LineDiff[] = [];
const maxLines = Math.max(oldLines.length, newLines.length);
for (let i = 0; i < maxLines; i++) {
const oldLine = i < oldLines.length ? oldLines[i] : null;
const newLine = i < newLines.length ? newLines[i] : null;
if (oldLine === newLine) {
diffLines.push({ type: 'unchanged', oldLine, newLine, lineNumber: i + 1 });
} else {
if (oldLine !== null) {
diffLines.push({ type: 'removed', oldLine, newLine: null, lineNumber: i + 1 });
}
if (newLine !== null) {
diffLines.push({ type: 'added', oldLine: null, newLine, lineNumber: i + 1 });
}
}
}
return diffLines;
};
export const generateCharDiff = (oldText: string, newText: string): CharDiffPart[] => {
const parsedOldText = parseNewlines(oldText);
const parsedNewText = parseNewlines(newText);
let prefixLength = 0;
while (
prefixLength < parsedOldText.length &&
prefixLength < parsedNewText.length &&
parsedOldText[prefixLength] === parsedNewText[prefixLength]
) {
prefixLength++;
}
let oldSuffixStart = parsedOldText.length;
let newSuffixStart = parsedNewText.length;
while (
oldSuffixStart > prefixLength &&
newSuffixStart > prefixLength &&
parsedOldText[oldSuffixStart - 1] === parsedNewText[newSuffixStart - 1]
) {
oldSuffixStart--;
newSuffixStart--;
}
const parts: CharDiffPart[] = [];
if (prefixLength > 0) {
parts.push({
text: parsedOldText.substring(0, prefixLength),
type: 'unchanged',
});
}
if (oldSuffixStart > prefixLength) {
parts.push({
text: parsedOldText.substring(prefixLength, oldSuffixStart),
type: 'removed',
});
}
if (newSuffixStart > prefixLength) {
parts.push({
text: parsedNewText.substring(prefixLength, newSuffixStart),
type: 'added',
});
}
if (oldSuffixStart < parsedOldText.length) {
parts.push({
text: parsedOldText.substring(oldSuffixStart),
type: 'unchanged',
});
}
return parts;
};
export const calculateDiffStats = (lineDiff: LineDiff[]): DiffStats => {
return {
additions: lineDiff.filter(line => line.type === 'added').length,
deletions: lineDiff.filter(line => line.type === 'removed').length
};
};