aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/chatbot/tools/SortDocsTool.ts
diff options
context:
space:
mode:
authorsharkiecodes <lanyi_stroud@brown.edu>2025-07-02 20:33:37 -0400
committersharkiecodes <lanyi_stroud@brown.edu>2025-07-02 20:33:37 -0400
commitf0807c6f6c31ac9ae2e6fb581f19a760f8e5687e (patch)
tree2e12315621bb361210ce5b6beaa7165da7ddc5ab /src/client/views/nodes/chatbot/tools/SortDocsTool.ts
parentf49fa5010ac53eb87925d1cd40e3be145d441ea6 (diff)
Implementing replacement of GPTPopup
Diffstat (limited to 'src/client/views/nodes/chatbot/tools/SortDocsTool.ts')
-rw-r--r--src/client/views/nodes/chatbot/tools/SortDocsTool.ts121
1 files changed, 76 insertions, 45 deletions
diff --git a/src/client/views/nodes/chatbot/tools/SortDocsTool.ts b/src/client/views/nodes/chatbot/tools/SortDocsTool.ts
index 741a8f3ce..45d7b4f15 100644
--- a/src/client/views/nodes/chatbot/tools/SortDocsTool.ts
+++ b/src/client/views/nodes/chatbot/tools/SortDocsTool.ts
@@ -2,66 +2,97 @@ import { BaseTool } from './BaseTool';
import { Observation } from '../types/types';
import { ParametersType, ToolInfo } from '../types/tool_types';
import { AgentDocumentManager } from '../utils/AgentDocumentManager';
-import { gptAPICall, GPTCallType } from '../../../../apis/gpt/GPT';
+import { gptAPICall, GPTCallType, DescriptionSeperator } from '../../../../apis/gpt/GPT';
import { ChatSortField } from '../../../collections/CollectionSubView';
import { v4 as uuidv4 } from 'uuid';
+import { DocumentView } from '../../DocumentView';
+import { docSortings } from '../../../collections/CollectionSubView';
+import { collect } from '@turf/turf';
const parameterRules = [
- {
- name: 'sortCriteria',
- type: 'string',
- description: 'Criteria provided by the user to sort the documents.',
- required: true,
- },
+ {
+ name: 'sortCriteria',
+ type: 'string',
+ description: 'Criteria provided by the user to sort the documents.',
+ required: true,
+ },
] as const;
const toolInfo: ToolInfo<typeof parameterRules> = {
- name: 'sortDocs',
- description:
- 'Sorts documents within the current Dash environment based on user-specified criteria. Provide clear sorting criteria, such as by date, title, relevance, or custom metadata fields.',
- parameterRules,
- citationRules: 'No citation needed for sorting operations.',
+ name: 'sortDocs',
+ description:
+ 'Sorts documents within the current Dash environment based on user-specified criteria.',
+ parameterRules,
+ citationRules: 'No citation needed for sorting operations.',
};
export class SortDocsTool extends BaseTool<typeof parameterRules> {
- private _docManager: AgentDocumentManager;
+ private _docManager: AgentDocumentManager;
+ private _collectionView: DocumentView;
- constructor(docManager: AgentDocumentManager) {
- super(toolInfo);
- this._docManager = docManager;
- this._docManager.initializeFindDocsFreeform();
- }
+ constructor(docManager: AgentDocumentManager, collectionView: DocumentView)
+ {
+ super(toolInfo);
+ // Grab the parent collection’s DocumentView (the ChatBox container)
+ // We assume the ChatBox itself is currently selected in its parent view.
+ this._collectionView = collectionView;
+ this._docManager = docManager;
+ this._docManager.initializeFindDocsFreeform();
+ }
+
+ async execute(args: ParametersType<typeof parameterRules>): Promise<Observation[]> {
+ const chunkId = uuidv4();
+
+ // 1) gather metadata & build map from text→id
+ const textToId = new Map<string, string>();
+
+ const chunks = (await Promise.all(
+ this._docManager.docIds.map(async id => {
+ const text = await this._docManager.getDocDescription(id);
+ textToId.set(text,id);
+ return DescriptionSeperator + text + DescriptionSeperator;
+ })
+ ))
+ .join('');
+ try {
+ // 2) call GPT to sort those chunks
+ const gptResponse = await gptAPICall(args.sortCriteria, GPTCallType.SORTDOCS, chunks);
+ console.log('GPT RESP:', gptResponse);
- async execute(args: ParametersType<typeof parameterRules>): Promise<Observation[]> {
- const chunkId = uuidv4();
- try {
- const docs = this._docManager.docIds.map((id) => this._docManager.extractDocumentMetadata(id));
+ // 3) parse & map back to IDs
+ const sortedIds = gptResponse
+ .split(DescriptionSeperator)
+ .filter(s => s.trim() !== '')
+ .map(s => s.replace(/\n/g, ' ').trim())
+ .map(s => textToId.get(s)) // lookup in our map
+ .filter((id): id is string => !!id);
- const descriptions = docs
- .filter((doc): doc is NonNullable<typeof doc> => doc !== null)
- .map(
- (doc) => `${doc.id}: ${doc.title} - ${doc.fields.layout.summary || ''}`
- )
- .join('\n');
+ // 4) write back the ordering
+ sortedIds.forEach((docId, idx) => {
+ this._docManager.editDocumentField(docId, ChatSortField, idx);
+ });
- const sortedIdsResponse = await gptAPICall(args.sortCriteria, GPTCallType.SORTDOCS, descriptions);
- const sortedIds = sortedIdsResponse.trim().split('\n');
- console.log(sortedIdsResponse);
- console.log(sortedIds);
+ const fieldKey = this._collectionView.ComponentView!.fieldKey;
+ this._collectionView.Document[ `${fieldKey}_sort` ] = docSortings.Chat;
- sortedIds.forEach((id, index) => {
- this._docManager.editDocumentField(id, ChatSortField, index);
- });
- return [{
- type: 'text',
- text: `<chunk chunk_id="${chunkId}" chunk_type="sort_status">Successfully sorted ${sortedIds.length} documents based on "${args.sortCriteria}".</chunk>`,
- }];
- } catch (error) {
- return [{
- type: 'text',
- text: `<chunk chunk_id="${chunkId}" chunk_type="error">Sorting failed: ${error instanceof Error ? error.message : String(error)}</chunk>`,
- }];
- }
+ return [
+ {
+ type: 'text',
+ text: `<chunk chunk_id="${chunkId}" chunk_type="sort_status">
+Successfully sorted ${sortedIds.length} documents by "${args.sortCriteria}".
+</chunk>`,
+ },
+ ];
+ } catch (err) {
+ return [
+ {
+ type: 'text',
+ text: `<chunk chunk_id="${chunkId}" chunk_type="error">
+Sorting failed: ${err instanceof Error ? err.message : err}
+</chunk>`,
+ },
+ ];
}
+ }
}