Element selection
Element selection#
To select the elements in the model based on the LLM response
Use the AiPrompt component's onResponse callback to catch the response.
<PlatformProvider> <AiPrompt onResponse={({response, error }) => { myCallback(response.message) }} /> </PlatformProvider>In a parent component, pass the response message to a handler function.
<ModelElemChat myCallback={(message) => { extractEntities(message); }} />The
extractEntitieshandler function completes the following steps: a. The function callsgetModelElementsByLlmResponse.```js const extractEntities = async (message) => { try { const modelElemsToSelect = await aiChat.getModelElementsByLlmResponse( message, IafScriptEngine, PlatformApi, ctx ) //hidden code } catch (error) { console.error('Error extracting entities:', error); } }```This script scrapes the response for source or object ids using regular expressions:
async function getModelElementsByLlmResponse(llmResponse, IafScriptEngine, libraries, ctx) { const sourceIdRegex = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}(?:-[0-9a-f]+)?\b/gi; const objectIdRegex = /\b[a-f0-9]{24}\b/g; let isSourceIds = false; let fetchedIds; if (!llmResponse) { return; } let ids = Array.from(llmResponse.matchAll(sourceIdRegex), m => m[0]); if (Array.isArray(ids)) { if (ids.length === 0) { ids = Array.from(llmResponse.matchAll(objectIdRegex), m => m[0]); isSourceIds = false; } console.log("ids", ids); if (ids.length > 0) fetchedIds = ids; } //hidden code }The scraped ids are used to form a findWithRelated query that finds the elements by their id in the
rvt_elementscollection, then fetches their related properties and type information from thervt_element_propsandrvt_type_elementscollections.let iaf_ext_elements_collection = IafScriptEngine.getVar( "iaf_ext_elements_collection" ); //determines to search by source id or object id const parentQuery = isSourceIds ? { source_id: { $in: fetchedIds } } : { _id: { $in: fetchedIds } }; //constructs the query const elemQuery = { parent: { query: parentQuery, collectionDesc: { _userType: "rvt_elements", _userItemId: iaf_ext_elements_collection._userItemId, }, options: { page: { _pageSize: 200, }, }, sort: { _id: 1, }, }, related: [ { relatedDesc: { _relatedUserType: "rvt_type_elements", }, as: "Revit Type Properties", }, { relatedDesc: { _relatedUserType: "rvt_element_props", }, as: "Revit Element Properties", }, ], } if (fetchedIds && fetchedIds.length > 0) { let elements; await IafScriptEngine.findWithRelated(elemQuery, ctx).then((res) => { elements = res._list; }) //hidden code }Finally, the relavent data is mapped to construct an array of entities in the same manner as the getModelElements script which is used when fetching model elements by category and type. For more information, see Mapping elements.
b. The resulting entities are passed to the
onSetEntitiescallback:if (modelElemsToSelect && modelElemsToSelect.length > 0) { onSetEntities(modelElemsToSelect); }In the NavigatorView component, the entities are set in the props with
this.props.setEntities:<div className="navigator-drawer-content-ai-chat"> <AiChatPane onSetEntities={(entities) => { this.props.setEntities({ entities: entities }); }} ctx={{ _namespaces: this.props.selectedItems.selectedProject._namespaces }} onPaneExpanded={() => { this.setState({ isChatDrawerExpanded: !this.state.isChatDrawerExpanded }); }} /> </div>