/** * * Copyright 2023-2025 InspectorRAGet Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * **/ 'use client'; import { useState, useMemo } from 'react'; import { Modal, RadioTile, CodeSnippet } from '@carbon/react'; import { Metric, Model, Task, TaskEvaluation, Message } from '@/src/types'; import { WarningAlt } from '@carbon/icons-react'; import classes from './TaskCopier.module.scss'; interface Props { models: Model[]; metrics: Metric[]; task: Task; evaluations: TaskEvaluation[]; onClose: Function; open: boolean; } function prepareTextForMessage(message: Message) { // Step 1: Initialize necessary variable let text = ''; // Step 2: Extract text from message object // Step 2.a: If message with "tool" role if (message.role === 'tool') { text += JSON.stringify({ tool_call_id: message['tool_call_id'], content: message.content, }); } // Step 2.b: If message with "assistant" role and with "tool_calls" else if ( message.role === 'assistant' && message.hasOwnProperty('tool_calls') ) { text += JSON.stringify(message['tool_calls']); } // Step 2.c: Default extraction policy else { text += typeof message.content === 'string' ? message.content : JSON.stringify(message.content); } // Step 3: Return return text; } function prepareText( models: Model[], metrics: Metric[], task: Task, evaluations: TaskEvaluation[], ): string { const separator = '=======================================================\n'; let input, responses; // Step 1: Prepare input input = `${separator}Input\n${separator}`; if (Array.isArray(task.input)) { task.input.map( (message) => (input += `${message.role}: ${prepareTextForMessage(message)}\n`), ); } // Step 2: Prepare responses if (evaluations && evaluations.length) { responses = `${separator}Responses\n${separator}`; const responseSeparator = '\n-------------------------------------------------------\n'; evaluations.forEach((evaluation) => { const model = models.find( (entry) => entry.modelId === evaluation.modelId, ); responses += `${model ? model.name.trim() : evaluation.modelId.trim()}${responseSeparator}${evaluation.modelResponse.trim()}\n${separator}`; }); } return `${input.trim()}\n${responses ? responses : ''}`; } function prepareLaTEXT( models: Model[], metrics: Metric[], task: Task, evaluations: TaskEvaluation[], ): string { let input, responses; // Step 1: Prepare input input = '\\multicolumn{1}{|c|}{\\textbf{Conversation}} \\\\ \n\t\\toprule \n\t'; if (Array.isArray(task.input)) { task.input.map( (message) => (input += `\\textbf{${ message.role }}: ${prepareTextForMessage(message)} \\\\ \n\t`), ); } // Step 2: Prepare responses if (evaluations && evaluations.length) { responses = '\\toprule \n\t\\multicolumn{1}{|c|}{\\textbf{Responses}} \\\\ \n\t'; evaluations.forEach((evaluation) => { const model = models.find( (entry) => entry.modelId === evaluation.modelId, ); responses += `\\toprule \n\t\\textbf{${model ? model.name.trim() : evaluation.modelId.trim()}} \\\\ \n\t\\midrule \n\t${evaluation.modelResponse.trim()} \\\\ \n\t`; }); responses += '\\bottomrule \n\t'; } return `\\begin{table*}\n\\small\n\t\\begin{tabular}{p{15.5cm}}\n\t\\toprule\n\t${input}${responses ? responses : ''}\\end{tabular}\n\\end{table*}`; } function prepareJSON( models: Model[], metrics: Metric[], task: Task, evaluations: TaskEvaluation[], ): string { return JSON.stringify( { input: task.input, responses: evaluations.map((evaluation) => { const model = models.find( (entry) => entry.modelId === evaluation.modelId, ); return { model: model ? model.name : evaluation.modelId, response: evaluation.modelResponse, }; }), }, null, 2, ); } export default function ChatTaskCopierModal({ models, metrics, task, evaluations, onClose, open = false, }: Props) { const [format, setFormat] = useState<'Text' | 'JSON' | 'LaTEX'>('Text'); const textToCopy = useMemo(() => { let text; if (format === 'Text') { text = prepareText(models, metrics, task, evaluations); } else if (format === 'LaTEX') { text = prepareLaTEXT(models, metrics, task, evaluations); } else { text = prepareJSON(models, metrics, task, evaluations); } return text; }, [models, metrics, task, evaluations, format]); return ( { //Step 1: Copy to clipboard navigator.clipboard.writeText(textToCopy); // Step 2: Close model onClose(); }} onRequestClose={() => { onClose(); }} >
Select a format
{ setFormat('Text'); }} > Text { setFormat('JSON'); }} > JSON { setFormat('LaTEX'); }} > LaTex
Preview {textToCopy} {format === 'LaTEX' && (
 Please make sure you add booktab package via {'\\usepackage{booktabs}'} to your LaTEX project.
)}
); }