Skip to content

Commit

Permalink
SAS-464: merged pgvector branch to main
Browse files Browse the repository at this point in the history
  • Loading branch information
liamsommer-mx committed Apr 30, 2024
2 parents ea47215 + ed12fcf commit dc44d97
Show file tree
Hide file tree
Showing 8 changed files with 19,743 additions and 19,464 deletions.
Binary file modified OpenAI Showcase App.mpr
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// This file was generated by Mendix Studio Pro.
//
// WARNING: Only the following code will be retained when actions are regenerated:
// - the import list
// - the code between BEGIN USER CODE and END USER CODE
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
// Other code you write will be lost the next time you deploy the project.
// Special characters, e.g., é, ö, à, etc. are supported in comments.

package pgvectorknowledgebase.actions;

import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.webui.CustomJavaAction;
import pgvectorknowledgebase.impl.ChunkUtils;
import pgvectorknowledgebase.impl.MxLogger;
import pgvectorknowledgebase.proxies.Chunk;

/**
* Use this operation to retrieve chunks from the knowledge base and set associations to the related mendix objects (if applicable). The retrieval is based on similarity with respect to the input vector provided. This operation returns a list of the same type of the TargetChunk input variable. The returned list is sorted on similarity.
* Additional filtering can be done by specifying the optional input parameters:
* -MinimumSimilarity (in the range 0-1.0): acts as a cut-off: chunks are not retrieved if they have a similarity below this value.
* -MaxNumberOfResults: determines the max number of similar chunks that are returned.
* -LabelList: when provided, this operation only returns chunks that are conform with all of the labels in the list.
*
* The DatabaseConfiguration that is passed must contain the connection details to a PostgreSQL database server with the PgVector extension installed. This entity is typically configured at runtime or in after-startup logic.
* By providing the KnowledgeBaseName parameter, you determine the knowledge base that was used for population earlier.
* The TargetChunk entity (type parameter) must be a specialization of the Chunk entity from this module. If it contains associations to (specializations of) the related mendix object for which the chunk was created, this will be set by this operation for easy processing afterwards.
*/
public class ChunkList_RetrieveNearestNeighbors_SetAssociation extends CustomJavaAction<java.util.List<IMendixObject>>
{
private IMendixObject __DatabaseConfiguration;
private pgvectorknowledgebase.proxies.DatabaseConfiguration DatabaseConfiguration;
private java.lang.String KnowledgeBaseName;
private IMendixObject TargetChunk;
private java.lang.String Vector;
private java.util.List<IMendixObject> __LabelList;
private java.util.List<pgvectorknowledgebase.proxies.Label> LabelList;
private java.lang.Long MaxNumberOfResults;
private java.math.BigDecimal MinimumSimilarity;

public ChunkList_RetrieveNearestNeighbors_SetAssociation(IContext context, IMendixObject DatabaseConfiguration, java.lang.String KnowledgeBaseName, IMendixObject TargetChunk, java.lang.String Vector, java.util.List<IMendixObject> LabelList, java.lang.Long MaxNumberOfResults, java.math.BigDecimal MinimumSimilarity)
{
super(context);
this.__DatabaseConfiguration = DatabaseConfiguration;
this.KnowledgeBaseName = KnowledgeBaseName;
this.TargetChunk = TargetChunk;
this.Vector = Vector;
this.__LabelList = LabelList;
this.MaxNumberOfResults = MaxNumberOfResults;
this.MinimumSimilarity = MinimumSimilarity;
}

@java.lang.Override
public java.util.List<IMendixObject> executeAction() throws Exception
{
this.DatabaseConfiguration = this.__DatabaseConfiguration == null ? null : pgvectorknowledgebase.proxies.DatabaseConfiguration.initialize(getContext(), __DatabaseConfiguration);

this.LabelList = java.util.Optional.ofNullable(this.__LabelList)
.orElse(java.util.Collections.emptyList())
.stream()
.map(__LabelListElement -> pgvectorknowledgebase.proxies.Label.initialize(getContext(), __LabelListElement))
.collect(java.util.stream.Collectors.toList());

// BEGIN USER CODE

try {
ChunkUtils.validateTargetChunk(this.TargetChunk);

// call a microflow to retrieve chunks
java.util.List<Chunk> chunkList = pgvectorknowledgebase.proxies.microflows.Microflows.chunkList_RetrieveNearestNeighbors(
getContext(), DatabaseConfiguration, KnowledgeBaseName, Vector, MinimumSimilarity, MaxNumberOfResults, LabelList);

//map to target chunks to return
return ChunkUtils.getTargetChunkList(getContext(), chunkList, TargetChunk, LOGGER);

} catch (Exception e) {
LOGGER.error(e.getMessage());
throw e;
}
// END USER CODE
}

/**
* Returns a string representation of this action
* @return a string representation of this action
*/
@java.lang.Override
public java.lang.String toString()
{
return "ChunkList_RetrieveNearestNeighbors_SetAssociation";
}

// BEGIN EXTRA CODE
private static final MxLogger LOGGER = new MxLogger(ChunkList_RetrieveNearestNeighbors_SetAssociation.class);
// END EXTRA CODE
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// This file was generated by Mendix Studio Pro.
//
// WARNING: Only the following code will be retained when actions are regenerated:
// - the import list
// - the code between BEGIN USER CODE and END USER CODE
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
// Other code you write will be lost the next time you deploy the project.
// Special characters, e.g., é, ö, à, etc. are supported in comments.

package pgvectorknowledgebase.actions;

import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.webui.CustomJavaAction;
import pgvectorknowledgebase.impl.ChunkUtils;
import pgvectorknowledgebase.impl.MxLogger;
import pgvectorknowledgebase.proxies.Chunk;

/**
* Use this operation to retrieve chunks from the knowledge base and set associations to the related mendix objects (if applicable). This operation returns a list of the same type of the TargetChunk input variable.
* Additional selection and filtering can be done by specifying the optional input parameters:
* -Offset: number of records to skip (for batching purposes)
* -MaxNumberOfResults: limit of the amount of records returned
* -LabelList: when provided, this operation only returns chunks that are conform with all of the labels in the list.
*
* The DatabaseConfiguration that is passed must contain the connection details to a PostgreSQL database server with the PgVector extension installed. This entity is typically configured at runtime or in after-startup logic.
* By providing the KnowledgeBaseName parameter, you determine the knowledge base that was used for population earlier.
* The TargetChunk entity (type parameter) must be a specialization of the Chunk entity from this module. If it contains associations to (specializations of) the related mendix object for which the chunk was created, this will be set by this operation for easy processing afterwards.
*/
public class ChunkList_Retrieve_SetAssociation extends CustomJavaAction<java.util.List<IMendixObject>>
{
private IMendixObject __DatabaseConfiguration;
private pgvectorknowledgebase.proxies.DatabaseConfiguration DatabaseConfiguration;
private java.lang.String KnowledgeBaseName;
private IMendixObject TargetChunk;
private java.util.List<IMendixObject> __LabelList;
private java.util.List<pgvectorknowledgebase.proxies.Label> LabelList;
private java.lang.Long MaxNumberOfResults;
private java.lang.Long Offset;

public ChunkList_Retrieve_SetAssociation(IContext context, IMendixObject DatabaseConfiguration, java.lang.String KnowledgeBaseName, IMendixObject TargetChunk, java.util.List<IMendixObject> LabelList, java.lang.Long MaxNumberOfResults, java.lang.Long Offset)
{
super(context);
this.__DatabaseConfiguration = DatabaseConfiguration;
this.KnowledgeBaseName = KnowledgeBaseName;
this.TargetChunk = TargetChunk;
this.__LabelList = LabelList;
this.MaxNumberOfResults = MaxNumberOfResults;
this.Offset = Offset;
}

@java.lang.Override
public java.util.List<IMendixObject> executeAction() throws Exception
{
this.DatabaseConfiguration = this.__DatabaseConfiguration == null ? null : pgvectorknowledgebase.proxies.DatabaseConfiguration.initialize(getContext(), __DatabaseConfiguration);

this.LabelList = java.util.Optional.ofNullable(this.__LabelList)
.orElse(java.util.Collections.emptyList())
.stream()
.map(__LabelListElement -> pgvectorknowledgebase.proxies.Label.initialize(getContext(), __LabelListElement))
.collect(java.util.stream.Collectors.toList());

// BEGIN USER CODE

try {

ChunkUtils.validateTargetChunk(TargetChunk);

// call a microflow to retrieve chunks
java.util.List<Chunk> chunkList = pgvectorknowledgebase.proxies.microflows.Microflows.chunkList_Retrieve(
getContext(), DatabaseConfiguration, KnowledgeBaseName, MaxNumberOfResults, LabelList, Offset);

//map to target chunks to return
return ChunkUtils.getTargetChunkList(getContext(), chunkList, TargetChunk, LOGGER);

} catch (Exception e) {
LOGGER.error(e.getMessage());
throw e;
}
// END USER CODE
}

/**
* Returns a string representation of this action
* @return a string representation of this action
*/
@java.lang.Override
public java.lang.String toString()
{
return "ChunkList_Retrieve_SetAssociation";
}

// BEGIN EXTRA CODE
private static final MxLogger LOGGER = new MxLogger(ChunkList_RetrieveNearestNeighbors_SetAssociation.class);
// END EXTRA CODE
}
6 changes: 2 additions & 4 deletions javasource/pgvectorknowledgebase/actions/Chunk_Create.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@
package pgvectorknowledgebase.actions;

import static java.util.Objects.requireNonNull;
import java.util.ArrayList;
import java.util.List;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.webui.CustomJavaAction;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.webui.CustomJavaAction;
import communitycommons.StringUtils;
import pgvectorknowledgebase.proxies.Chunk;
import pgvectorknowledgebase.impl.MxLogger;
import pgvectorknowledgebase.proxies.Chunk;

/**
* This action can be used for instantiating Chunk objects to create the input for the knowledge base based on your own data structure. A ChunkList must be passed to which the new Chunk object will be added.
Expand Down
87 changes: 87 additions & 0 deletions javasource/pgvectorknowledgebase/impl/ChunkUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package pgvectorknowledgebase.impl;

import static java.util.Objects.requireNonNull;

import java.util.ArrayList;
import java.util.stream.Collectors;

import com.mendix.core.Core;
import com.mendix.systemwideinterfaces.core.IContext;
import com.mendix.systemwideinterfaces.core.IMendixObject;
import com.mendix.systemwideinterfaces.core.meta.IMetaAssociation;

import communitycommons.ORM;
import pgvectorknowledgebase.proxies.Chunk;

public class ChunkUtils {


public static void validateTargetChunk(IMendixObject TargetChunk) throws Exception {
// verify target chunk on non-null, subclass of chunk,
requireNonNull(TargetChunk, "Target Chunk must be specified");
if (! TargetChunk.getMetaObject().isSubClassOf("PgVectorKnowledgeBase.Chunk")){
throw new Exception("Target Chunk must be a specialization of PgVectorKnowledgeBase.Chunk");
}
};




public static java.util.List<IMendixObject> getTargetChunkList(
IContext context, java.util.List<Chunk> chunkList, IMendixObject targetChunk, MxLogger LOGGER) {
// create list to return
java.util.List<IMendixObject> targetChunkList = new ArrayList<IMendixObject>();

// per chunk create a TargetChunk (custom specialization)
chunkList.forEach(c -> {
// - instantiate Target Chunk (custom specialization)
IMendixObject targetChunkSpecialization = Core.instantiate(context, targetChunk.getMetaObject().getName());
// copy values from Chunk to Target Chunk (custom specialization)
ORM.cloneObject(context, c.getMendixObject(), targetChunkSpecialization, true);
try {
// - retrieve Mendix target object
String MxObjectID = c.getMxObjectID(context);
IMendixObject targetObject = MxObjectID == null ? null : Core.retrieveId(
context, Core.createMendixIdentifier(
MxObjectID
)
);

// find matching association based on meta object name
Long assocationsSetCount= targetChunk
.getMetaObject()
.getMetaAssociationsParent()
.stream()
.filter(a -> assocationMatchesTarget(a, targetObject))
.peek(a -> setAssociationToTarget(context, targetChunkSpecialization, targetObject, a))
.collect(Collectors.counting());

// set association if found, otherwise log a warning
if (assocationsSetCount == 0){
LOGGER.warn("No eligible association found for target object " + targetObject.getMetaObject().getName()
+ " on entity " + targetChunk.getMetaObject().getName());
}

} catch (Exception e) {
LOGGER.error(e.getMessage());
}

targetChunkList.add(targetChunkSpecialization);

});
return targetChunkList;
}




public static void setAssociationToTarget(IContext context,IMendixObject chunk,IMendixObject targetObject, IMetaAssociation association){
if (targetObject != null) {
chunk.setValue(context, association.getName(), targetObject.getId());
}
}

public static boolean assocationMatchesTarget(IMetaAssociation asssociation, IMendixObject targetObject){
return targetObject == null ? false : targetObject.getMetaObject().isSubClassOf(asssociation.getChild());
}
}
1 change: 1 addition & 0 deletions theme-cache/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text eol=lf
Loading

0 comments on commit dc44d97

Please sign in to comment.