aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/chatbot/tools/TutorialTool.ts166
1 files changed, 166 insertions, 0 deletions
diff --git a/src/client/views/nodes/chatbot/tools/TutorialTool.ts b/src/client/views/nodes/chatbot/tools/TutorialTool.ts
new file mode 100644
index 000000000..69ae9c618
--- /dev/null
+++ b/src/client/views/nodes/chatbot/tools/TutorialTool.ts
@@ -0,0 +1,166 @@
+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<typeof generateTutorialNodeToolParams> = {
+ 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<typeof generateTutorialNodeToolParams> {
+ 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<typeof generateTutorialNodeToolParams>): Promise<Observation[]> {
+ const chunkId = uuidv4();
+ try {
+ console.log('Executing with args:', args);
+ const query = args.query;
+ if (typeof query !== 'string' || !query.trim()) {
+ return [{
+ type: 'text',
+ text: `<chunk chunk_id="${chunkId}" chunk_type="error">Invalid input: Query must be a non-empty string.</chunk>`
+ }];
+ }
+
+ 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: `<chunk chunk_id="${chunkId}" chunk_type="tutorial_node_creation">Created tutorial node with ID ${createdDoc[Id]}.</chunk>`
+ }];
+ } catch (error) {
+ console.error('Error in GPTTutorialTool:', error);
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
+ return [{
+ type: 'text',
+ text: `<chunk chunk_id="${chunkId}" chunk_type="error">Error generating tutorial node: ${errorMessage}</chunk>`
+ }];
+ }
+ }
+} \ No newline at end of file