aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/chatbot/tools/SortDocsTool.ts
blob: 9eb0cf4d1af855cba2ea21dcbb5b787f83896144 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import { BaseTool } from './BaseTool';
import { Observation } from '../types/types';
import { ParametersType, ToolInfo } from '../types/tool_types';
import { AgentDocumentManager } from '../utils/AgentDocumentManager';
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';


const parameterRules = [
  {
    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.',
  parameterRules,
  citationRules: 'No citation needed for sorting operations.',
};

export class SortDocsTool extends BaseTool<typeof parameterRules> {
  private _docManager: AgentDocumentManager;
  private _collectionView: DocumentView;

  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.initializeDocuments();
  }

  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);

      // 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);

      // 4) write back the ordering
      sortedIds.forEach((docId, idx) => {
        this._docManager.editDocumentField(docId, ChatSortField, idx);
      });

       const fieldKey = this._collectionView.ComponentView!.fieldKey;
         this._collectionView.Document[ `${fieldKey}_sort` ] = docSortings.Chat;


      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>`,
        },
      ];
    }
  }
}