diff options
4 files changed, 42 insertions, 31 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 6fd6534a4..22a771a11 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -312,7 +312,6 @@ export class DocumentOptions { title_transform?: STRt = new StrInfo('transformation to apply to title in label box (eg., uppercase)', undefined, undefined, ['uppercase', 'lowercase', 'capitalize']); text_transform?: STRt = new StrInfo('transformation to apply to text in text box (eg., uppercase)', undefined, undefined, ['uppercase', 'lowercase', 'capitalize']); text_placeholder?: BOOLt = new BoolInfo('makes the text act like a placeholder and automatically select when the text box is selected'); - fontSize?: string; _pivotField?: string; // field key used to determine headings for sections in stacking, masonry, pivot views infoWindowOpen?: BOOLt = new BoolInfo('whether info window corresponding to pin is open (on MapDocuments)'); diff --git a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx index f84a4cd2a..acf6870c3 100644 --- a/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx +++ b/src/client/views/nodes/chatbot/chatboxcomponents/ChatBox.tsx @@ -111,13 +111,11 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { super(props); makeObservable(this); - // At mount time, find the DocumentView whose .Document is the collection container. - const parentView = DocumentView.Selected().lastElement(); - if (!parentView) { - console.warn("GPT ChatBox not inside a DocumentView – cannot sort."); - } - - + // At mount time, find the DocumentView whose .Document is the collection container. + const parentView = DocumentView.Selected().lastElement(); + if (!parentView) { + console.warn('GPT ChatBox not inside a DocumentView – cannot sort.'); + } this.messagesRef = React.createRef(); this.docManager = new AgentDocumentManager(this, parentView); @@ -162,7 +160,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { } ); - /* + /* reaction( () => ({ selDoc: DocumentView.Selected().lastElement(), visible: SnappingManager.ChatVisible }), ({ selDoc, visible }) => { @@ -376,15 +374,19 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @action askGPT = async (event: React.FormEvent): Promise<void> => { event.preventDefault(); + if (!this._textInputRef) { + console.log('ERROR: text input ref is undefined'); + return; + } this._inputValue = ''; // Extract the user's message - const textInput = (event.currentTarget as HTMLFormElement).elements.namedItem('messageInput') as HTMLInputElement; - const trimmedText = textInput.value.trim(); + const textInput = this._textInputRef?.value ?? ''; + const trimmedText = textInput.trim(); if (trimmedText) { + this._textInputRef.value = ''; // Clear the input field try { - textInput.value = ''; // Add the user's message to the history this._history.push({ role: ASSISTANT_ROLE.USER, @@ -511,7 +513,7 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { @action public whichDoc = (doc: parsedDoc, insideCol: boolean): Opt<Doc> => { - const options = OmitKeys(doc, ['doct_type', 'data']).omit as DocumentOptions; + const options = OmitKeys(doc, ['doc_type', 'data']).omit as DocumentOptions; const data = (doc as parsedDocData).data; const ndoc = (() => { switch (doc.doc_type) { @@ -1475,20 +1477,20 @@ export class ChatBox extends ViewBoxAnnotatableComponent<FieldViewProps>() { <form onSubmit={this.askGPT} className="chat-input"> <div className="input-container"> - <input + <input // ref={this.setInputRef} type="text" name="messageInput" autoComplete="off" placeholder="Type your message here..." value={this._inputValue} - onChange={action(e => (this._inputValue = e.target.value))} + onChange={e => this.setChatInput(e.target.value)} disabled={this._isLoading} /> </div> <Button // className="submit-button" - onClick={() => this._dictation?.stopDictation()} + onClick={this.askGPT} type={Type.PRIM} tooltip="Send to AI" color={SnappingManager.userVariantColor} diff --git a/src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts b/src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts index da4a4ae29..fd44cc60f 100644 --- a/src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts +++ b/src/client/views/nodes/chatbot/tools/DocumentMetadataTool.ts @@ -1,3 +1,5 @@ +import { OmitKeys } from '../../../../../ClientUtils'; +import { DocumentOptions } from '../../../../documents/Documents'; import { Parameter, ParametersType, supportedDocTypes, ToolInfo } from '../types/tool_types'; import { Observation } from '../types/types'; import { AgentDocumentManager } from '../utils/AgentDocumentManager'; @@ -21,8 +23,7 @@ const parameterDefinitions: ReadonlyArray<Parameter> = [ name: 'fieldEdits', type: 'string', required: false, - description: - 'JSON array of field edits for editing fields. Each item should have fieldName and fieldValue. For single field edits, use an array with one item. Example: [{"fieldName":"layout_autoHeight","fieldValue":false},{"fieldName":"height","fieldValue":300}]', + description: `JSON array of field edits for editing fields. Each item should have fieldName and fieldValue. For single field edits, use an array with one item. fieldName values MUST be in this list: [${Object.keys(DocumentOptions)}]. Example: [{"fieldName":"layout_autoHeight","fieldValue":false},{"fieldName":"height","fieldValue":300}]`, }, { name: 'title', @@ -402,7 +403,8 @@ To CREATE a new document: - title: The title of the document to create - data: The content data for the document (text content, URL, etc.) - doc_type: The type of document to create (text, web, image, etc.) -- Example: {...inputs: { action: "create", title: "My Notes", data: "This is the content", doc_type: "text" }} + - fieldEdits: Optional JSON array of fields to set during creation +- Example: {...inputs: { action: "create", title: "My Notes", data: "This is the content", doc_type: "text", fieldEdits: [{ fieldName: "text", fieldValue: "Hello world" }] }} - After creation, you can edit the document with more specific properties To EDIT document metadata: @@ -694,8 +696,15 @@ export class DocumentMetadataTool extends BaseTool<DocumentMetadataToolParamsTyp const docType = String(args.doc_type); const title = String(args.title); const data = String(args.data); + const json = typeof args.fieldEdits === 'string' ? JSON.parse(args.fieldEdits) : {}; + const docopts = json.length + ? (json as Array<{ fieldName: string; fieldValue: string | number | boolean }>).reduce((opts, opt) => { + opts[opt.fieldName] = opt.fieldValue; + return opts; + }, {} as DocumentOptions) + : {}; - const id = await this._docManager.createDocInDash(docType, data, { title: title }); + const id = await this._docManager.createDocInDash(docType, data, docopts); if (!id) { return [ @@ -715,6 +724,7 @@ export class DocumentMetadataTool extends BaseTool<DocumentMetadataToolParamsTyp Document ID: ${id} Type: ${docType} Title: "${title}" +Options: ${JSON.stringify(OmitKeys(args, ['doc_type', 'data', 'title']).omit, null, 2)} The document has been created with default dimensions and positioning. You can now use the "edit" action to modify additional properties of this document. diff --git a/src/client/views/nodes/chatbot/utils/AgentDocumentManager.ts b/src/client/views/nodes/chatbot/utils/AgentDocumentManager.ts index 857cc859d..088891022 100644 --- a/src/client/views/nodes/chatbot/utils/AgentDocumentManager.ts +++ b/src/client/views/nodes/chatbot/utils/AgentDocumentManager.ts @@ -27,7 +27,7 @@ interface AgentDocument { export class AgentDocumentManager { @observable private documentsById: ObservableMap<string, AgentDocument>; private chatBox: ChatBox; - private parentView : DocumentView + private parentView: DocumentView; private chatBoxDocument: Doc | null = null; private fieldMetadata: Record<string, any> = {}; // bcz: CHANGE any to a proper type! @observable private simplifiedChunks: ObservableMap<string, SimplifiedChunk>; @@ -36,7 +36,7 @@ export class AgentDocumentManager { * Creates a new DocumentManager * @param templateDocument The document that serves as a template for new documents */ - constructor(chatBox: ChatBox, parentView : DocumentView) { + constructor(chatBox: ChatBox, parentView: DocumentView) { makeObservable(this); this.parentView = parentView; const agentDoc = DocCast(chatBox.Document.agentDocument) ?? new Doc(); @@ -857,6 +857,7 @@ export class AgentDocumentManager { try { // Create simple document with just title and data const simpleDoc: parsedDoc = { + ...(options as parsedDoc), // bcz: hack .. why do we need parsedDoc and not DocumentOptions here? doc_type: docType, title: options?.title ?? `Untitled Document ${this.documentsById.size + 1}`, data: data, @@ -1018,19 +1019,18 @@ export class AgentDocumentManager { return docInfo?.dataDoc; } - // In AgentDocumentManager - private descriptionCache = new Map<string,string>(); + // In AgentDocumentManager + private descriptionCache = new Map<string, string>(); public async getDocDescription(id: string): Promise<string> { - if (!this.descriptionCache.has(id)) { - const doc = this.getDocument(id)!; - const desc = await Doc.getDescription(doc); - this.descriptionCache.set(id, desc.replace(/\n/g,' ').trim()); - } - return this.descriptionCache.get(id)!; + if (!this.descriptionCache.has(id)) { + const doc = this.getDocument(id)!; + const desc = await Doc.getDescription(doc); + this.descriptionCache.set(id, desc.replace(/\n/g, ' ').trim()); + } + return this.descriptionCache.get(id)!; } - /** * Adds simplified chunks to a document for citation handling * @param doc The document to add simplified chunks to |