import { BaseTool } from './BaseTool'; import { Observation } from '../types/types'; import { Parameter, ParametersType, ToolInfo } from '../types/tool_types'; // import { gptAPICall } from '../../../../apis/gpt/GPT'; import { schema } from '../../../../views/nodes/formattedText/schema_rts'; import { RichTextField } from '../../../../../fields/RichTextField'; import { Docs } from '../../../../documents/Documents'; import { DocumentViewInternal } from '../../../nodes/DocumentView'; import { v4 as uuidv4 } from 'uuid'; import { OpenWhere } from '../../../../views/nodes/OpenWhere'; import { gptAPICall } from '../../../../apis/gpt/GPT'; import { parsedDoc } from '../chatboxcomponents/ChatBox'; import { Id } from '../../../../../fields/FieldSymbols'; import { Doc } from '../../../../../fields/Doc'; const generateTutorialNodeToolParams = [ { name: 'query', type: 'string', description: 'The user\'s query about Dash functionality.', required: true, }, ] as const; const generateTutorialNodeToolInfo: ToolInfo = { name: 'generateTutorialNode', description: 'Generates a tutorial text node based on the user\'s query about Dash functionality. Use this when the user asks for help or tutorials on how to use Dash features.', parameterRules: generateTutorialNodeToolParams, citationRules: 'No citation needed for this tool\'s output.', }; export class GPTTutorialTool extends BaseTool { private _createDocInDash: (doc: parsedDoc) => Doc | undefined; constructor(createDocInDash: (doc: parsedDoc) => Doc | undefined) { super(generateTutorialNodeToolInfo); this._createDocInDash = createDocInDash; } // private applyFormatting(markdownText: string): { doc: any; plainText: string } { // const lines = markdownText.split('\n'); // const nodes: any[] = []; // let plainText = ''; // let i = 0; // let currentListItems: any[] = []; // const processBoldText = (text: string) => { // const boldRegex = /\*\*(.*?)\*\*/g; // const parts = []; // let lastIndex = 0; // let match; // while ((match = boldRegex.exec(text)) !== null) { // if (match.index > lastIndex) { // parts.push(schema.text(text.substring(lastIndex, match.index))); // } // parts.push(schema.text(match[1], [schema.marks.strong.create()])); // lastIndex = match.index + match[0].length; // } // if (lastIndex < text.length) { // parts.push(schema.text(text.substring(lastIndex))); // } // return parts.length > 0 ? parts : [schema.text(text)]; // }; // const flushListItems = () => { // if (currentListItems.length > 0) { // nodes.push(schema.nodes.ordered_list.create({ mapStyle: 'bullet' }, currentListItems)); // currentListItems = []; // } // }; // while (i < lines.length) { // const line = lines[i].trim(); // if (line) { // if (line.startsWith('## ')) { // flushListItems(); // const textContent = line.replace('## ', ''); // nodes.push(schema.nodes.heading.create({ level: 1 }, processBoldText(textContent))); // plainText += textContent + '\n'; // } else if (line.startsWith('- ')) { // const textContent = line.replace('- ', ''); // currentListItems.push( // schema.nodes.list_item.create( // {}, // schema.nodes.paragraph.create({}, processBoldText(textContent)) // ) // ); // plainText += textContent + '\n'; // } else { // flushListItems(); // nodes.push(schema.nodes.paragraph.create({}, processBoldText(line))); // plainText += line + '\n'; // } // } else { // flushListItems(); // nodes.push(schema.nodes.paragraph.create()); // plainText += '\n'; // } // i++; // } // flushListItems(); // const doc = schema.nodes.doc.create({}, nodes); // return { doc, plainText: plainText.trim() }; // } async execute(args: ParametersType): Promise { const chunkId = uuidv4(); try { console.log('Executing with args:', args); const query = args.query; if (typeof query !== 'string' || !query.trim()) { return [{ type: 'text', text: `Invalid input: Query must be a non-empty string.` }]; } const markdownResponse = await gptAPICall(query); if (!markdownResponse || typeof markdownResponse !== 'string') { throw new Error('Invalid GPT API response'); } console.log('Markdown response:', markdownResponse); // const { doc } = this.applyFormatting(markdownResponse); // const rtfData = { // doc: doc.toJSON(), // selection: { type: 'text', anchor: 1, head: 1 }, // storedMarks: [], // }; // const serializedData = JSON.stringify(rtfData); // console.log('Serialized data:', serializedData); const tutorialDoc: parsedDoc = { doc_type: 'text', data: markdownResponse, title: 'Tutorial Node', _width: 600, _layout_fitWidth: true, _layout_autoHeight: true, text_fontSize: '16px', }; const createdDoc = this._createDocInDash(tutorialDoc); console.log('Created doc:', createdDoc); if (!createdDoc || !createdDoc[Id]) { throw new Error('Failed to create tutorial node'); } return [{ type: 'text', text: `Created tutorial node with ID ${createdDoc[Id]}.` }]; } catch (error) { console.error('Error in GPTTutorialTool:', error); const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return [{ type: 'text', text: `Error generating tutorial node: ${errorMessage}` }]; } } }