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